<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: kgoedert</title>
    <description>The latest articles on Forem by kgoedert (@kgoedert).</description>
    <link>https://forem.com/kgoedert</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F175259%2F383d702d-7d52-4c4c-a031-a9b6b05c494b.jpeg</url>
      <title>Forem: kgoedert</title>
      <link>https://forem.com/kgoedert</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kgoedert"/>
    <language>en</language>
    <item>
      <title>My Deliberate Practice Journey - month 2</title>
      <dc:creator>kgoedert</dc:creator>
      <pubDate>Wed, 10 Jun 2020 19:35:58 +0000</pubDate>
      <link>https://forem.com/kgoedert/my-deliberate-practice-journey-month-2-2hkc</link>
      <guid>https://forem.com/kgoedert/my-deliberate-practice-journey-month-2-2hkc</guid>
      <description>&lt;p&gt;Month 2 on my journey in practicing programming deliberately. This past month I got to work with &lt;a href="//www.quarkus.io"&gt;quarkus&lt;/a&gt; a lit bit more and with &lt;a href="https://spring.io/projects/spring-boot"&gt;spring boot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Quarkus really feels very comfortable if you are experienced in the JEE world. The community really seems very active. There's a new version I still have to test.&lt;br&gt;
I started my project using the yasson serializer for JSON. Things didn't go so well. I changed to jackson, and everything started to look better. The &lt;a href="https://github.com/FasterXML/jackson"&gt;jackson&lt;/a&gt; ability to choose if a property is read only or write only is really useful. I was also able to integrate open api and swagger ui and create a really nice documentation for my project.&lt;br&gt;
It sure is something I will try to use more from now on.&lt;/p&gt;

&lt;p&gt;You can read a post about it &lt;a href="https://dev.to/kgoedert/jackson-readonly-properties-and-swagger-ui-3kfg"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I was also able to spend some time writing integrated tests. And the database part of it is still painful. I cannot see a lot of value using a database for testing that is not the same one used in production as so many seem to recommend. I tried using &lt;a href="https://www.testcontainers.org/"&gt;test containers&lt;/a&gt;, and it seems to work well. But since I am working alone, and exploring test containers can become part of my studies, I can create another database for testing without major problems. In a bigger team, where it developer may need one database to test, it can come in handy.&lt;/p&gt;

&lt;p&gt;Since I had all this setup made with quarkus, I took a detour and created another little project to help me on my language learning. A popular tool among people that learn languages is &lt;a href="https://apps.ankiweb.net/"&gt;anki&lt;/a&gt; where you can create your own flashcards and work with spaced repetion. I decided to add some audio to my cards, and used &lt;a href="http://www.voicerss.org/default.aspx"&gt;voice RSS&lt;/a&gt; for that which as text to speech API. If you would like to check the project, it is &lt;a href="https://github.com/kgoedert/sentence-mining-quarkus"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On the spring boot side, the project I worked on was with a friend, since the code is not mine, there is no link on github.&lt;br&gt;
There were no technical challenges on the project, so there is not much to talk about.&lt;/p&gt;

&lt;p&gt;I am still using &lt;a href="https://code.visualstudio.com/"&gt;VSCode&lt;/a&gt; as my primary editor for development, but something buggy seems to be happening with test classes. Code completion is too slow. The discovery of the methods annotated with tests, that with the test plugin enabled should show a link over the method name to be able to run the test, is also very slow. To the point that I almost gave up on it. Some tickets seem to be open on github concerning these issues.&lt;/p&gt;

&lt;p&gt;This reminded me of how important it is to feel productive with the tools you are using. I don't have much time to devote to this practice, if a part of this time is spent fighting with my tools... it is really a waste of time and does not help with the motivation part of things at all.&lt;/p&gt;

&lt;p&gt;Also, two people got inspired by the previous post, and started something similiar. Hope that are enjoying and learning as much as I am. One of them even asked for some mentoring. Super cool, to be able to share what you learned.&lt;/p&gt;

&lt;p&gt;If you would like to check what I worked on, comment on it, suggest some improvement, it is &lt;a href="https://github.com/kgoedert/hello-quarkus/tree/practice-3"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>practice</category>
    </item>
    <item>
      <title>Jackson Readonly properties and swagger UI</title>
      <dc:creator>kgoedert</dc:creator>
      <pubDate>Sat, 06 Jun 2020 13:50:23 +0000</pubDate>
      <link>https://forem.com/kgoedert/jackson-readonly-properties-and-swagger-ui-3kfg</link>
      <guid>https://forem.com/kgoedert/jackson-readonly-properties-and-swagger-ui-3kfg</guid>
      <description>&lt;p&gt;Sometimes when you are building a REST API, you don't want the user to be able to set some specific property. If he decides to send it anyway, you want to discard it. Or, not even receive it. &lt;a href="https://github.com/FasterXML/jackson" rel="noopener noreferrer"&gt;Jackson&lt;/a&gt; can help with that.&lt;/p&gt;

&lt;p&gt;But it would be even nicer if the developer that is using your API, has site where he can test your API, and besides that have some documentation showing what is required and what is not. Here, &lt;a href="https://swagger.io/tools/swagger-ui/" rel="noopener noreferrer"&gt;swagger ui&lt;/a&gt;. But say the developer using your api doesn't like GUIs much, and prefers the command line. There is a solution for that too.&lt;/p&gt;

&lt;p&gt;To show all this tools working together I am going to use &lt;a href="//quarkus.io"&gt;quarkus&lt;/a&gt; and build upon on one of their &lt;a href="https://quarkus.io/guides/rest-json" rel="noopener noreferrer"&gt;examples&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The full code is available on &lt;a href="https://github.com/kgoedert/rest-json-post" rel="noopener noreferrer"&gt;github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The code
&lt;/h2&gt;

&lt;p&gt;The example has enpoint where the user can post some fruits, and the class that represent the fruits.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

@Path("/fruits")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class FruitResource {

    @POST
    @Operation(summary = "POSTs a new fruit to the list")
    @APIResponse(responseCode = "200", description = "Fruit registration successful")
    @APIResponse(responseCode = "500", description = "Server unavailable")
    public Response save(Fruit fruit) {
        if (fruit.getCreated() == null) {
            fruit.addCreationDate();
        }

        if (fruit.getUuid() == null) {
            fruit.addUUID();
        }
        return Response.ok(fruit).build();
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

@Schema(name = "Fruit", description = "Represents a fruit")
@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
public class Fruit {
    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    @Schema(required = false, readOnly = true)
    private String uuid;

    @Schema(required = true, example = "The name of the fruit you want to save")
    private String name;

    @Schema(required = false, example = "Some description for the fruit")
    private String description;

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    @JsonFormat(shape = Shape.STRING, pattern = "MM/dd/yyyy HH:mm:ss")
    @Schema(required = false, readOnly = true, pattern = "MM/dd/yyyy HH:mm:ss")
    private LocalDateTime created;

    public void addCreationDate() {
        this.created = LocalDateTime.now();
    }

    public void addUUID() {
        this.uuid = UUID.randomUUID().toString();
    }

    public LocalDateTime getCreated() {
        return created;
    }

    public String getUuid() {
        return uuid;
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here, you can see the use of swagger open api annotations, &lt;code&gt;@Operation&lt;/code&gt; and &lt;code&gt;@APIResponse&lt;/code&gt;. Their purpose is to document the endpoint. It will be shown in swagger-ui and when you access the open api URL of the application.&lt;/p&gt;

&lt;p&gt;In the fruit class, the &lt;code&gt;@Schema&lt;/code&gt; annotations serve the purpose of documenting and marking if the property is required, its pattern, as in the case of the date field, and setting it as readonly. This annotation is used by swagger and open api. It means that when the user receives the result of the post, the result will have this field present, but when trying to post a fruit, this field will be ignored.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;@JsonAutoDetect&lt;/code&gt;, &lt;code&gt;@JsonProperty&lt;/code&gt; and &lt;code&gt;@JsonFormat&lt;/code&gt; do the same for jackson, that is responsible for parsing the results. If the property is marking as readonly, it will be ignored when something is posted, but it will be available on the response.&lt;/p&gt;

&lt;p&gt;There is also the writeonly version of the property, that you can use for example to send something when you post, like  a password, the you do not want it shown, when the user makes a get request.&lt;/p&gt;

&lt;p&gt;You can see the swagger UI on &lt;code&gt;http://localhost:8080/swagger-ui&lt;/code&gt; and it will show you something like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhaz20a011gc7kyfvevwa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhaz20a011gc7kyfvevwa.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And in the open api url you should see something like this&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

curl http://localhost:8080/openapi
---
openapi: 3.0.1
info:
  title: Generated API
  version: "1.0"
paths:
  /fruits:
    post:
      summary: POSTs a new fruit to the list
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Fruit'
      responses:
        "500":
          description: Server unavailable
        "200":
          description: Fruit registration successful
components:
  schemas:
    Fruit:
      description: Represents a fruit
      required:
      - name
      type: object
      properties:
        created:
          allOf:
          - $ref: '#/components/schemas/LocalDateTime'
          - pattern: MM/dd/yyyy HH:mm:ss
            readOnly: true
        description:
          type: string
          example: Some description for the fruit
        name:
          type: string
          example: The name of the fruit you want to save
        uuid:
          type: string
          readOnly: true
    LocalDateTime:
      format: date-time
      type: string


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This makes it very easy to document your APIs.&lt;/p&gt;

</description>
      <category>quarkus</category>
      <category>jackson</category>
      <category>swaggerui</category>
      <category>openapi</category>
    </item>
    <item>
      <title>My deliberate practice journey</title>
      <dc:creator>kgoedert</dc:creator>
      <pubDate>Sun, 10 May 2020 21:50:21 +0000</pubDate>
      <link>https://forem.com/kgoedert/my-deliberate-practice-journey-2dfc</link>
      <guid>https://forem.com/kgoedert/my-deliberate-practice-journey-2dfc</guid>
      <description>&lt;p&gt;I was searching the internet for articles about "how do I improve as a software engineer". I am always looking for ways to improve, and all the articles I found mainly said, it doesn't matter what you build, just build something. And I always thought, build what? I had no idea what to build. &lt;/p&gt;

&lt;p&gt;Another thing that came up again and again, was deliberate practice. I have used in other areas, like music, have read books about it, but I couldn't see how to apply it to software engineering.&lt;/p&gt;

&lt;p&gt;Deliberate practice basically consists of a practice that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is designed to improve performance&lt;/li&gt;
&lt;li&gt;Can be repeated a lot&lt;/li&gt;
&lt;li&gt;Feedback on results is continually available&lt;/li&gt;
&lt;li&gt;It's highly demanding mentally&lt;/li&gt;
&lt;li&gt;It isn't much fun&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Well, I decided to stop procrastinating, and start doing. Trying to put this two things together. The concepts of deliberate practice, and the idea of "just build something". &lt;/p&gt;

&lt;h2&gt;
  
  
  Frameworks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Quarkus&lt;/li&gt;
&lt;li&gt;Springboot&lt;/li&gt;
&lt;li&gt;Django&lt;/li&gt;
&lt;li&gt;NodeJS&lt;/li&gt;
&lt;li&gt;Golang&lt;/li&gt;
&lt;li&gt;Angular&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vue&lt;/li&gt;
&lt;li&gt;ReactNative&lt;/li&gt;
&lt;li&gt;Flutter&lt;/li&gt;
&lt;li&gt;Kotlin&lt;/li&gt;
&lt;li&gt;Swift&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to practice
&lt;/h2&gt;

&lt;p&gt;I set some rules to follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one hour a day, everyday&lt;/li&gt;
&lt;li&gt;at the end of every month I will write a post about what happened, struggles, things I learned, etc..&lt;/li&gt;
&lt;li&gt;I will just go to the next practice, when the current one is finished in all the frameworks&lt;/li&gt;
&lt;li&gt;I will treat every project, apart from hello, world, as if it was a real life project. Meaning: version control, tests, code coverage, build, deploy as if there were different environments, monitoring, etc..&lt;/li&gt;
&lt;li&gt;I will just skip something if I get stuck, to the point I tried every I found on the internet&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to practice
&lt;/h2&gt;

&lt;p&gt;My first practice was setting up my development environment for all these tools. If possible, I wanted to use one editor for everything. Except for swift and kotlin, I was able to set everything up in VS Code, which is at the moment, my editor of choice. To make sure everything was correct, I built the famous hello, world project. I tried to use as much as possible the tools provided by the framework itself. The only framework I had a problem with, was react. I had to downgrade the version to make it work.&lt;/p&gt;

&lt;p&gt;The second practice, was to use hello world, write a unit test for it, and see the code coverage of it. &lt;br&gt;
The only environment I couldn't get this working was on swift. I couldn't get my tests working at all.&lt;/p&gt;

&lt;p&gt;The next idea after that was to build a simple crm. With products, customers and orders. So far, I am still working on the quarkus version of it. I am really taking my time to explore the framework here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So far, so good. Was it worth it? Yes, absolutely. On my day to day job I get to work with some of these frameworks more than others. And it hit me hard how easily you forget some things. Doing these simple projects brings all this to mind.&lt;br&gt;
Since the idea is to practice, I can really try various things until I am satisfied and maybe explore parts of the frameworks and languages I haven't taken the time to before.&lt;br&gt;
I was even able to contribute to a project finding bugs.&lt;/p&gt;

&lt;p&gt;I would love to get some feedback on how I can improve on the projects, ideas for practices and other tools to learn.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links to repositories
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/kgoedert/ultralearning/blob/master/deliberate/practices.md"&gt;Here&lt;/a&gt; is a link to the ideas I had so far for practicing.&lt;/p&gt;

&lt;p&gt;And I list of all the repositories I created. The different practices will be different tags.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kgoedert/hello-quarkus"&gt;Quarkus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kgoedert/hello-spring"&gt;Springboot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kgoedert/hello-django"&gt;Django&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kgoedert/hello-go"&gt;Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kgoedert/hello-angular"&gt;Angular&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kgoedert/hello-react"&gt;React&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kgoedert/hello-vuejs"&gt;VueJs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kgoedert/hello-reactnative"&gt;ReactNative&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kgoedert/hello-flutter"&gt;Flutter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kgoedert/hello-kotlin"&gt;Kotlin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kgoedert/hello-swift"&gt;Swift&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kgoedert/infrastructure"&gt;Infrastructure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>deliberatepractice</category>
      <category>programming</category>
    </item>
    <item>
      <title>Setup python 3 environment on mac with zsh</title>
      <dc:creator>kgoedert</dc:creator>
      <pubDate>Tue, 14 Apr 2020 16:25:13 +0000</pubDate>
      <link>https://forem.com/kgoedert/setup-python-3-environment-on-mac-with-zsh-4jhp</link>
      <guid>https://forem.com/kgoedert/setup-python-3-environment-on-mac-with-zsh-4jhp</guid>
      <description>&lt;p&gt;Trying to setup my development enviroment on a mac, I had some problems, specially integrating my virtual environment information on my shell. On zsh specifically, with &lt;a href="https://github.com/ohmyzsh/ohmyzsh"&gt;oh my zsh&lt;/a&gt;. The theme am I using is &lt;a href="https://github.com/Powerlevel9k/powerlevel9k"&gt;PowerLevel9k&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The steps that worked:&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install &lt;a href="https://brew.sh/"&gt;homebrew&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install python 3 and pip 3 with brew. Installing python 3 also installs pip3&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install python3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install &lt;a href="https://virtualenvwrapper.readthedocs.io/en/latest/"&gt;virtualenvwrapper&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo pip3 install virtualenvwrapper
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Usually in python projects you do not install packages with sudo, but this way virtualenvwrapper will be installed globally and available to all the projects&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ZSH Configuration
&lt;/h2&gt;

&lt;p&gt;Edit your &lt;code&gt;~/.zshrc&lt;/code&gt;and:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable virtualenv plugin on .zshrc
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; plugins=(...virtualenv)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Set python 3 as the default for virtualenvwrapper
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export VIRTUALENVWRAPPER_PYTHON='/usr/bin/python3'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Load virtualenvwrapper script
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source /usr/local/bin/virtualenvwrapper.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To be able to show the active virtualenv on the prompt add (I just added the virtualenv, the others are the default ones)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(context dir vcs virtualenv)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Edit your &lt;code&gt;~/.oh-my-zsh/plugins/virtualenv/virtualenv.plugin.zsh&lt;/code&gt; and comment out the line
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export VIRTUAL_ENV_DISABLE_PROMPT=1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;source your zsh
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;source ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>python</category>
      <category>mac</category>
      <category>zsh</category>
    </item>
    <item>
      <title>Getting started with quarkus and panache</title>
      <dc:creator>kgoedert</dc:creator>
      <pubDate>Fri, 10 Apr 2020 13:20:56 +0000</pubDate>
      <link>https://forem.com/kgoedert/getting-started-with-quarkus-and-panache-5b5b</link>
      <guid>https://forem.com/kgoedert/getting-started-with-quarkus-and-panache-5b5b</guid>
      <description>&lt;p&gt;&lt;a href="https://quarkus.io/"&gt;Quarkus&lt;/a&gt; is an open source framework, that uses well stabilished java libraries like hibernate, and adds something extra to them. &lt;/p&gt;

&lt;p&gt;Having a solid background in projects using J2EE and JEE (or now JakartaEE), I wanted to see how easy it would be to setup a project and having a simple crud application running. And also, since I am so familiar with application servers, is there any benefit in using quarkus? Wouldn't it be the same as using the application server?&lt;/p&gt;

&lt;p&gt;One of quarkus' features is the ability to run on graalvm. I didn't test this here. It is a test for another day.&lt;br&gt;
All the code is available on &lt;a href="https://github.com/kgoedert/quarkus-panache"&gt;github&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  First Impressions
&lt;/h2&gt;

&lt;p&gt;My first impression was very good. There is a lot of simple tutorials to get you started. And the code on it, worked. It seems to have a lot of extensions based on well known frameworks and libraries which is also very good. Looking at the github repo it seems to be very active.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;Very easy to get started. You basically need java 8+, maven 3.6.2+ and graalvm(if you want the native compilation).&lt;/p&gt;

&lt;p&gt;You can follow their getting started guide &lt;a href="https://quarkus.io/guides/getting-started"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For my test I also added the extensions for hibernate orm, panache, postgres driver and liquibase.&lt;/p&gt;
&lt;h2&gt;
  
  
  Development experience
&lt;/h2&gt;

&lt;p&gt;The boot time is really fast. I boot it in development mode, a debug port is available. The hot reload worked pretty well. So I see this as an advantage over the application server. Even if the servers these days boot really fast, quarkus was faster.&lt;/p&gt;

&lt;p&gt;With panache they added a nice layer on top of hibernate, that has a lot of cool features on building queries. I myself never liked the criteria api. Over the years other libraries like querydsl, that seems abandoned now, and deltaspike data tried to accomplish this query writing functionality. &lt;/p&gt;

&lt;p&gt;It also implements two patterns the repository pattern, and the active record pattern. Both work, but in this test I chose to go with the repository pattern, that I seem to use more frequently.&lt;/p&gt;

&lt;p&gt;One thing I did not like, was that the panache API encapsulated methods like persist and delete, but not merge. To be able to do a merge I had to create a method that would set every attribute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@PUT
@Path("/{id}")
@Transactional
 public Response update(@PathParam("id") Long id, Movie movie) {
    if (this.isValid(movie, id)) {
        Movie m = movieRepo.findById(id);
        if(m == null){
            throw new WebApplicationException(Status.NOT_FOUND);
        }
        m.update(movie);
        return Response.status(Status.OK).entity(movie).build();
    } else {
        return Response.status(Status.BAD_REQUEST).entity("Movie already exists").build();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void update(Movie updated) {
    this.director = updated.getDirector();
    this.genre = updated.getGenre();
    this.title = updated.getTitle();
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Another thing that I don't really quite like is to have the attributes as public or default on classes. Having them public makes the serialization easier, and the framework allows you to create your regular getters and setters, and if you do, it will use them.&lt;/p&gt;

&lt;p&gt;But I still prefer to have them private, and create getters and setters only if I need them. So, I created a JsonbConfigCustomizer, and was able to use the entities the way I wanted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Singleton
public class JsonConfigurator implements JsonbConfigCustomizer {
    public void customize(JsonbConfig config) {
        config.withPropertyVisibilityStrategy(new PrivateVisibilityStrategy());
    }
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The liquibase integration also worked really well. Had no issues here, every worked as it usually does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I liked the framework and the experience of using it overall. I will test other features as soon as possible. If anyone has experience using it on a production environment I would like to hear about it.&lt;br&gt;
Would I try it in production? Yes, after testing the other extensions that would be needed for the project. &lt;br&gt;
If you have experience in the JEE/JakartaEE stack, it is really easy to pick up.&lt;/p&gt;

</description>
      <category>quarkus</category>
      <category>panache</category>
    </item>
    <item>
      <title>Create a command line tool with go and cobra</title>
      <dc:creator>kgoedert</dc:creator>
      <pubDate>Tue, 05 Nov 2019 17:06:13 +0000</pubDate>
      <link>https://forem.com/kgoedert/create-a-command-line-tool-with-go-and-cobra-eel</link>
      <guid>https://forem.com/kgoedert/create-a-command-line-tool-with-go-and-cobra-eel</guid>
      <description>&lt;p&gt;Every now and then, I like to start playing with a new programming language. The one I picked this was &lt;a href="//www.golang.org"&gt;go&lt;/a&gt;. To start simple, I decided to build a simple command line utility that would do some simple tasks, which I usually do with bash scripts. Reading about how to implement this, I discovered a very cool project called &lt;a href="https://github.com/spf13/cobra"&gt;cobra&lt;/a&gt;, that would make the task a lot easier. And apparently is used by a lot of big projects.&lt;/p&gt;

&lt;p&gt;If my bash scripts are working, why rewrite them? Because with go it is easy to generate an executable. Which means I can distribute them easily in my team, without worrying about their setup. &lt;/p&gt;

&lt;h2&gt;
  
  
  The development environment
&lt;/h2&gt;

&lt;p&gt;Since I don't want to install go in my machine, and I loved working with VS Code remote containers, I will create one with go. If you don't know what I am talking about, &lt;a href="https://code.visualstudio.com/docs/remote/containers"&gt;check it out&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I will create a folder called uc (this will be the root of my project), and initialize the container inside it.&lt;/p&gt;

&lt;p&gt;Once my container is ready, I need to install cobra.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go get -u github.com/spf13/cobra/cobra
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Cobra has a nice utility to help you get started, called cobra generator. &lt;/p&gt;

&lt;p&gt;To create the initial structure of the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cobra init --pkg-name github.com/kgoedert/uc . 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you want to create your project somewhere else, other than the current directory, just pass it as a parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cobra init --pkg-name github.com/kgoedert/uc /path/to/some/folder
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Which will give me an output like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your Cobra applicaton is ready at
/workspaces/uc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You should get an output close to this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uc
├── LICENSE
└── src
    └── github.com
        └── kgoedert
            └── uc
                ├── cmd
                │   └── root.go
                └── main.go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You already have something you can build and run.&lt;/p&gt;

&lt;p&gt;Since I am working inside the container, I can build and install my package with:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Ctrl + Shift + P &amp;gt; Go: Install Current Package&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Just remember to execute this with the main.go file open and selected.&lt;/p&gt;

&lt;p&gt;A binary will be generated on a bin directory. You can open a terminal and run it with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./uc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You should see an output like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@10b479f71c07:/workspaces/uc/bin# ./uc 
A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.

subcommand is required
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Since I am using visual code inside a container, my GOPATH is different, if I am using the terminal than if I am using the plugin commands from the go extension menu. More informations here &lt;a href="https://github.com/Microsoft/vscode-go/wiki/GOPATH-in-the-VS-Code-Go-extension"&gt;https://github.com/Microsoft/vscode-go/wiki/GOPATH-in-the-VS-Code-Go-extension&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding commands
&lt;/h2&gt;

&lt;p&gt;I will add a command called &lt;em&gt;createFolder&lt;/em&gt;, that will simply create an empty folder.&lt;/p&gt;

&lt;p&gt;To do that, open a terminal go to the directory that has the &lt;em&gt;main.go&lt;/em&gt; file in it, in my case it is &lt;em&gt;uc&lt;/em&gt;, and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cobra add createFolder
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will allow me to have the command &lt;em&gt;uc createFolder&lt;/em&gt; in my project. I will also add a parameter to specify the name of the folder I want to create. &lt;/p&gt;

&lt;p&gt;Cobra add a file called &lt;em&gt;createFolder.go&lt;/em&gt; in my &lt;em&gt;cmd&lt;/em&gt; folder. At this point, my project structure, looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;uc
├── bin
│   └── uc
├── LICENSE
└── src
    └── github.com
        └── kgoedert
            └── uc
                ├── cmd
                │   ├── createFolder.go
                │   └── root.go
                └── main.go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Command implementation
&lt;/h2&gt;

&lt;p&gt;In the &lt;em&gt;createFolder.go&lt;/em&gt;, cobra created some templates to get you started. There is a variable to represent your command. What it will do, its name, and some help to your users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var createFolderCmd = &amp;amp;cobra.Command{
    Use:   "createFolder",
    Short: "Creates a folder",
    Long:  `Creates a folder with a name as parameter`,
    Run: func(cmd *cobra.Command, args []string) {
        createFolder(cmd)
    },
}

func createFolder(cmd *cobra.Command) error {
    name, _ := cmd.Flags().GetString("name")

    if name == "" {
        return errors.New("Your folder needs a name")
    }

    err := os.MkdirAll(name, os.ModePerm)
    if err != nil {
        fmt.Printf("Could not create the directory %v", err)
    }
    fmt.Println("Folder " + name + " created.")

    return nil
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can see my implementation is very simple. In the function called &lt;em&gt;init&lt;/em&gt; is where you are going to determine to which other command your command is a subcommand to, and add parameters to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func init() {
    rootCmd.AddCommand(createFolderCmd)

    createFolderCmd.Flags().StringP("name", "", false, "Name of the folder you want to create.")
}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;My &lt;em&gt;createFolder&lt;/em&gt; command will be a subcommand to the root command, and will have one parameter, which will be &lt;em&gt;n&lt;/em&gt;, for the folder name. So when called it will look like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./uc createFolder -n newFolder
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, let's add another simple command. Initializing a git repository inside a given folder.&lt;/p&gt;

&lt;p&gt;My code on the &lt;em&gt;gitInit.go&lt;/em&gt; file, looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var gitInitCmd = &amp;amp;cobra.Command{
    Use:   "gitInit",
    Short: "Initializes a git repository on a given path",
    Run: func(cmd *cobra.Command, args []string) {
        gitInit(cmd)
    },
}

func gitInit(cmd *cobra.Command) error {
    folder, _ := cmd.Flags().GetString("folder")

    if folder == "" {
        return errors.New("Your need to inform a path to initialize the git repository")
    }

    command := exec.Command("git", "init", folder)
    err := command.Run()
    if err != nil {
        fmt.Printf("Could not create the directory %v", err)
    }
    fmt.Println("Git repository initialized in " + folder)

    return nil
}

func init() {
    rootCmd.AddCommand(gitInitCmd)

    gitInitCmd.Flags().StringP("folder", "f", "", "Path where the git repository will be initialized.")
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;My command will again, be a subcommand of the root command. And will take a &lt;em&gt;-f&lt;/em&gt; as a parameter for the name of the folder.&lt;/p&gt;

&lt;p&gt;Now, suppose you want to make a command that will aggregate some of the commands you have previously created. One possible solution would be to create a command called for example, &lt;em&gt;all&lt;/em&gt;, that would execute the other two. Like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var allCmd = &amp;amp;cobra.Command{
    Use:   "all",
    Short: "Executes both commands",
    RunE: func(cmd *cobra.Command, args []string) error {
        createFolder(cmd)
        gitInit(cmd)

        return nil
    },
}

func init() {
    rootCmd.AddCommand(allCmd)

    allCmd.Flags().StringP("folder", "f", "", "Path where the git repository will be initialized.")
    allCmd.Flags().StringP("name", "n", "", "Name of the folder you want to create.")
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To use your &lt;em&gt;all&lt;/em&gt; command, you would:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./uc all -n newProject -f newProject
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This would create a folder and initialize a git repository on it.&lt;/p&gt;

&lt;p&gt;Although the commands I used were very simple, I hope I was able to show how you can compose your commands to create something very powerful.&lt;/p&gt;

&lt;p&gt;You can find the source code &lt;a href="https://github.com/kgoedert/uc"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>cobra</category>
    </item>
    <item>
      <title>Creating Docker Container to Develop a Sails.JS Application with VSCode</title>
      <dc:creator>kgoedert</dc:creator>
      <pubDate>Thu, 31 Oct 2019 15:42:06 +0000</pubDate>
      <link>https://forem.com/kgoedert/creating-docker-container-to-develop-a-sails-js-application-with-vscode-1c43</link>
      <guid>https://forem.com/kgoedert/creating-docker-container-to-develop-a-sails-js-application-with-vscode-1c43</guid>
      <description>&lt;p&gt;Before I start a new project, just for fun or for a client, I like to have some basics set up. My editor of choice with its appropriate plugins, docker, so I don’t have to install things directly on the machine, and one very important thing, debugging has to be possible, with a proper tool, not prints.&lt;br&gt;
At this moment, my editor of choice is VS Code.&lt;/p&gt;

&lt;p&gt;Right now, I need to do some tests for a potential project with SailsJS. This project will not use, at least right now, the latest version of node or sails, so, this is one other point that docker will help me with.&lt;br&gt;
I will also create a docker compose for the project, because the first thing I will try to do with sails in this setup is a simple crud.&lt;br&gt;
So, if you want to follow along, you will need docker and docker compose installed. And also, visual code with the docker extension.&lt;/p&gt;

&lt;p&gt;The code can be found here: (&lt;a href="https://github.com/kgoedert/posts_code/tree/master/sails_docker)%5Bhttps://github.com/kgoedert/posts_code/tree/master/sails_docker%5D"&gt;https://github.com/kgoedert/posts_code/tree/master/sails_docker)[https://github.com/kgoedert/posts_code/tree/master/sails_docker]&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Docker Structure
&lt;/h2&gt;

&lt;p&gt;The initial Dockerfile is this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:6.16.0
VOLUME [ "/opt/app" ]
WORKDIR /opt/app
RUN chown -R node:node /opt/app
USER root
RUN cd /opt/app &amp;amp;&amp;amp; npm install -g sails@0.11.2  &amp;amp;&amp;amp; npm install -g node-inspect
USER node
EXPOSE 1337
EXPOSE 9229
CMD [ "tail", "-f", "/dev/null" ]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can see that as I said before, the node version is not the latest, and sails version is an specific version I need to use. I also installed node-inspect that I will use to setup debugging later.&lt;/p&gt;

&lt;p&gt;The ports that are exposed are for the application server and the debug port respectively.&lt;/p&gt;

&lt;p&gt;The command at the end, is just so the docker container does not exit, because no process is running, and we can log in the container and create the project itself.&lt;/p&gt;

&lt;p&gt;The docker compose is also simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '2'
networks:
   sails:
   driver: bridge
services:
  node:
    build: node
    volumes:
      - '${NODE_APP}:/opt/app:rw'
    ports:
       - '1337:1337'
       - '9229:9229'
    networks:
      - sails
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that I the build parameter is building from node, which is the folder where my Dockerfile is.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;NODE_APP&lt;/em&gt; variable, is set a .env file, and is the path on the host machine where the project will be kept.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


With that set up, we should be able to start the container.

## Creating the SailsJS project

If you want to use a project you already have, skip this. Once you log into the container, type:



```sails new test-project```



Let’s now create a very simple controller. The purpose of creating this, is just so I can check that the debugging configuration I am going to do next is working.
So to create a controller:



```sails generate api user```



This will create a *UserController.js* file inside of the */api/controllers* folder. To have something we can debug, inside the controller let’s create a function:



&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;module.exports = {&lt;br&gt;
   list: function(req, res) {&lt;br&gt;
      res.view('list');&lt;br&gt;
   }&lt;br&gt;
};&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


This will simple redirect me to a view, or page, called list. So in the views folder of your project, create a *list.ejs* file, with some content, it can be as simple as a string.



```LIST```



For the routing to work, in the *config/routes.js* file, add this:



```'get /user/list': 'UserController.list'```



Which translates to, when a get is made to */user/list*, call the function *list* in the *UserController*.

To avoid receiving a message about the database migration every time the server is started, and also to not allow automatic migrations in the *config/model.js* file add the following line:



```migrate: 'safe'```



Now to start the server inside your docker container:



&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;sails lift&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


The server will start on port 1337, and if you go to *http://localhost:1337/user/list*, you should see a page with the word *LIST* on it.
The only thing left to do now, is setup the debugging.

## Debugging

To be able to debug, in visual studio code, you should have the docker extension installed, and a debug configuration like the following:



&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;{&lt;br&gt;
    "type": "node",&lt;br&gt;
    "request": "attach",&lt;br&gt;
    "name": "Docker: Attach to Node",&lt;br&gt;
    "port": 9229,&lt;br&gt;
    "address": "localhost",&lt;br&gt;
    "localRoot": "${workspaceFolder}",&lt;br&gt;
    "remoteRoot": "/opt/app",&lt;br&gt;
    "protocol": "inspector"&lt;br&gt;
}&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Now, one last step: start the docker container with the appropriate command to boot the application ready to be debugged. To do this, replace the command in the docker file. Delete this line:



&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;CMD [ "tail", "-f", "/dev/null" ]&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


And add this one:



&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;CMD [ "node", "--inspect=0.0.0.0", "/opt/app/app.js" ]&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Rebuild and restart your container, and you should be ready to start debugging.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

</description>
      <category>docker</category>
      <category>vscode</category>
      <category>sailsjs</category>
    </item>
    <item>
      <title>Setup MySQL with Sails.JS</title>
      <dc:creator>kgoedert</dc:creator>
      <pubDate>Thu, 31 Oct 2019 15:41:31 +0000</pubDate>
      <link>https://forem.com/kgoedert/setup-mysql-with-sails-js-3ni7</link>
      <guid>https://forem.com/kgoedert/setup-mysql-with-sails-js-3ni7</guid>
      <description>&lt;p&gt;MySQL is a very widely used database, so to continue my tests with sails.js, I will add it to my project.&lt;br&gt;
The explanation of how to configure a docker container for the sails.js part is here.&lt;br&gt;
The code to this example can be found here.&lt;br&gt;
First, I will add to my docker-compose a service to build the mysql image. I will not, make any volume mapping, since this is just for a simple test and I don’t care about keeping the data.&lt;/p&gt;
&lt;h2&gt;
  
  
  Dockerfile and Docker Compose
&lt;/h2&gt;

&lt;p&gt;The Dockerfile for mysql will be on a folder called mysql, and its contents are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM mysql:8.0.13
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;the compose configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mysql:
    build: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3306:3306'
    networks:
      - sails
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With this, I will have a mysql running locally on port 3306.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Dependencies and Configuration
&lt;/h2&gt;

&lt;p&gt;The first thing I need to do, is to add the sails-mysql dependency to my project. To do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install sails-mysql --save
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, we need to configure the datasource on the project. To do that, in the file &lt;em&gt;config/connections.js&lt;/em&gt;, you will find a commented out example like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// someMysqlServer: {
//    adapter: 'sails-mysql',
//    host: 'YOUR_MYSQL_SERVER_HOSTNAME_OR_IP_ADDRESS',
//    user: 'YOUR_MYSQL_USER', //optional
//    password: 'YOUR_MYSQL_PASSWORD', //optional
//    database: 'YOUR_MYSQL_DB' //optional
// },
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Uncomment the lines, and set the values according to your setup. The password, should be the same one you have set on your docker compose.&lt;br&gt;
For the host, you can use your host machine address.&lt;br&gt;
With this, you should have all you need to start storing data into a mysql database with your sails.js app.&lt;/p&gt;

</description>
      <category>mysql</category>
      <category>sailsjs</category>
      <category>docker</category>
    </item>
    <item>
      <title>Checking for vulnerabilities on your Java projects</title>
      <dc:creator>kgoedert</dc:creator>
      <pubDate>Thu, 31 Oct 2019 15:41:26 +0000</pubDate>
      <link>https://forem.com/kgoedert/checking-for-vulnerabilities-on-your-java-projects-2h7a</link>
      <guid>https://forem.com/kgoedert/checking-for-vulnerabilities-on-your-java-projects-2h7a</guid>
      <description>&lt;p&gt;A lot of developers I talk to, seem to think that security is someone else responsibility. The network guy, the security guy, someone that is not him or her.&lt;br&gt;
I am no expert in security, but when I work on project, I like to believe that security is my responsibility too. And one small thing I can do, is to check the libraries I am using on my project against known vulnerabilities. I one is found, I try to upgrade it right away. If it is not possible for some reason, I am at least aware of the problem.&lt;/p&gt;

&lt;p&gt;In a java project, you can add an owasp plugin, to your maven pom.xml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;org.owasp&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;dependency-check-maven&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;4.0.2&amp;lt;/version&amp;gt;
    &amp;lt;configuration&amp;gt;
        &amp;lt;cveValidForHours&amp;gt;12&amp;lt;/cveValidForHours&amp;gt;
    &amp;lt;/configuration&amp;gt;
    &amp;lt;executions&amp;gt;
        &amp;lt;execution&amp;gt;
            &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;check&amp;lt;/goal&amp;gt;
            &amp;lt;/goals&amp;gt;
        &amp;lt;/execution&amp;gt;
    &amp;lt;/executions&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That will show you an output like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;One or more dependencies were identified with known vulnerabilities in test-project:

microprofile-rest-client-api-1.0.jar (org.eclipse.microprofile.rest.client:microprofile-rest-client-api:1.0, cpe:/a:rest-client_project:rest-client:1.0) : CVE-2015-1820, CVE-2015-3448
deltaspike-core-api-1.8.0.jar (cpe:/a:apache:deltaspike:1.8.0, org.apache.deltaspike.core:deltaspike-core-api:1.8.0) : CVE-2017-17837
libthrift-0.9.2.jar (cpe:/a:apache:thrift:0.9.2, org.apache.thrift:libthrift:0.9.2) : CVE-2015-3254
stagemonitor-tracing-elasticsearch-0.87.6.jar (org.stagemonitor:stagemonitor-tracing-elasticsearch:0.87.6, cpe:/a:elasticsearch:elasticsearch:0.87.6) : CVE-2014-3120, CVE-2015-1427, CVE-2015-5531, CVE-2014-6439, CVE-2015-3337
jaeger-core-0.22.0-RC1-okhttp381.jar/META-INF/maven/org.apache.httpcomponents/httpclient/pom.xml (cpe:/a:apache:httpclient:4.2.5, org.apache.httpcomponents:httpclient:4.2.5) : CVE-2015-5262, CVE-2014-3577
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And that’s it.&lt;/p&gt;

</description>
      <category>java</category>
      <category>security</category>
    </item>
    <item>
      <title>Debugging C code with VSCode</title>
      <dc:creator>kgoedert</dc:creator>
      <pubDate>Thu, 31 Oct 2019 15:41:17 +0000</pubDate>
      <link>https://forem.com/kgoedert/debugging-c-code-with-vscode-1j0p</link>
      <guid>https://forem.com/kgoedert/debugging-c-code-with-vscode-1j0p</guid>
      <description>&lt;p&gt;Using a linux machine to write c code makes the process a little bit easier because the c compiler and debugger probably are already installed.&lt;br&gt;
To be able to debug c code it is necessary to compile the code with the necessary parameters, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gcc -g hello.c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After that, you need the appropriate configuration on your &lt;em&gt;launch.json&lt;/em&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
      "name": "Debug c",
      "type": "cppdbg",
      "request": "launch",
      "program": "${workspaceFolder}/a.out",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${workspaceFolder}",
      "environment": [],
      "externalConsole": true,
      "MIMode": "gdb",
      "setupCommands": [
        {
          "description": "Enable pretty-printing for gdb",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ]
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is the most basic configuration. If you change the output name during compilation, don’t forget to change it on the file too.&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>c</category>
    </item>
    <item>
      <title>Monitoring REST requests with Stagemonitor and Elasticsearch</title>
      <dc:creator>kgoedert</dc:creator>
      <pubDate>Thu, 31 Oct 2019 15:41:07 +0000</pubDate>
      <link>https://forem.com/kgoedert/monitoring-rest-requests-with-stagemonitor-and-elasticsearch-opd</link>
      <guid>https://forem.com/kgoedert/monitoring-rest-requests-with-stagemonitor-and-elasticsearch-opd</guid>
      <description>&lt;p&gt;&lt;a href="https://www.stagemonitor.org/"&gt;Stagemonitor&lt;/a&gt; is a solution to let you monitor your java application in a very simple way. And it is free. While you may not have all the information some of the paid tools will give you, it still gives you a lot of useful information.&lt;br&gt;
The application I am going to use as an example, is very simple, all it has is this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import java.time.LocalDateTime;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.stagemonitor.tracing.Traced;

@Path("/user")
public class UserResource {

    @GET
    @Path("/hi")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @Traced
    public Response sayHi() {
        String result = "Hi world @ " + LocalDateTime.now();

        return Response.status(Response.Status.OK).entity(result).build();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It will be compiled with jdk 11, and will be deployed to wildfly 15.&lt;br&gt;
To initialize the application monitoring, you need to startup stagemonitor yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Singleton;
import javax.ejb.Startup;

import org.stagemonitor.core.Stagemonitor;

@Singleton
@Startup
public class StageMonitorHandler {
    @PostConstruct
    public void init() {
        Stagemonitor.init();
    }

    @PreDestroy
    public void shutDownStagemonitor() {
        Stagemonitor.shutDown();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Since the application will run on a application server, you have to add the bytebuddy agent library to the classpath. To do this, you can override your $JAVA_OPTS, with something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;JAVA_OPTS="$JAVA_OPTS -javaagent:/opt/bytebuddy/byte-buddy-agent-1.8.11.jar -Dstagemonitor.property.overrides=stagemonitor.properties
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The version of the bytebuddy agent has to be the same as the one used by stagemonitor. In this example, the stagemonitor version is 0.88.9.&lt;br&gt;
The properties file that was added above, is packaged with the application and contains some stagemonitor configurations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stagemonitor.applicationName=stagemonitor
stagemonitor.instrument.include=com.github
stagemonitor.instanceName=stagemonitor-dev
stagemonitor.reporting.elasticsearch.url=http://elasticsearch:9200
stagemonitor.tracing.reporting.log=true
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the project pom.xml file, you need to add at least this dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;properties&amp;gt;
  &amp;lt;stagemonitor.version&amp;gt;0.88.9&amp;lt;/stagemonitor.version&amp;gt;
&amp;lt;/properties&amp;gt;
...
&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;org.stagemonitor&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;stagemonitor-tracing-elasticsearch&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;${stagemonitor.version}&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;org.stagemonitor&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;stagemonitor-web-servlet&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;${stagemonitor.version}&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;org.stagemonitor&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;stagemonitor-tracing&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;${stagemonitor.version}&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;org.stagemonitor&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;stagemonitor-logging&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;${stagemonitor.version}&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;org.stagemonitor&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;stagemonitor-jvm&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;${stagemonitor.version}&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;org.stagemonitor&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;stagemonitor-os&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;${stagemonitor.version}&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;org.stagemonitor&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;stagemonitor-dispatcher&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;${stagemonitor.version}&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And of course, you will need to have elasticsearch running on (&lt;a href="http://elasticsearch:9200)%5Bhttp://elasticsearch:9200%5D"&gt;http://elasticsearch:9200)[http://elasticsearch:9200]&lt;/a&gt; and also kibana.&lt;br&gt;
The versions used for this test were 6.5.4.&lt;br&gt;
After all this is setup, you can start making requests and start to see some cool charts in kibana.&lt;/p&gt;

</description>
      <category>monitoring</category>
      <category>stagemonitor</category>
    </item>
    <item>
      <title>Edit docker /etc/hosts</title>
      <dc:creator>kgoedert</dc:creator>
      <pubDate>Thu, 31 Oct 2019 15:40:58 +0000</pubDate>
      <link>https://forem.com/kgoedert/edit-docker-etc-hosts-4ohg</link>
      <guid>https://forem.com/kgoedert/edit-docker-etc-hosts-4ohg</guid>
      <description>&lt;p&gt;If you ever need to edit the &lt;em&gt;/etc/hosts&lt;/em&gt; of your docker container, using the docker compose, you can use the &lt;em&gt;extra_hosts&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight docker"&gt;&lt;code&gt;wildfly:
    build: wildfly
    ports:
      - "8080:8080"
      - "8787:8787"
    extra_hosts:
      - "first:162.0.1.5"
      - "secondhost:1.1.1.1"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>docker</category>
    </item>
  </channel>
</rss>
