<?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>DEV Community: Felipe Lima</title>
    <description>The latest articles on DEV Community by Felipe Lima (@flflima).</description>
    <link>https://dev.to/flflima</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%2F464248%2F5abc9f58-50b4-4be9-86cd-51564c017e49.jpeg</url>
      <title>DEV Community: Felipe Lima</title>
      <link>https://dev.to/flflima</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/flflima"/>
    <language>en</language>
    <item>
      <title>Rodando SQS localmente com LocalStack</title>
      <dc:creator>Felipe Lima</dc:creator>
      <pubDate>Sun, 16 Oct 2022 19:27:05 +0000</pubDate>
      <link>https://dev.to/flflima/rodando-sqs-localmente-com-localstack-3nap</link>
      <guid>https://dev.to/flflima/rodando-sqs-localmente-com-localstack-3nap</guid>
      <description>&lt;p&gt;O &lt;a href="https://docs.localstack.cloud/overview/"&gt;LocalStack&lt;/a&gt; é um emulador de serviços na nuvem que permite que serviços AWS sejam testados localmente, sem que seja necessário se conectar a uma conta remota.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que iremos fazer:
&lt;/h2&gt;

&lt;p&gt;Vou documentar aqui como executei o LocalStack pela primeira vez. &lt;br&gt;
Os passos que segui foram:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;iniciar um container com o LocalStack usado &lt;code&gt;docker-compose&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;configurar o &lt;code&gt;aws cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;criar e consumir uma fila SQS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Vou utilizar o &lt;code&gt;docker-compose&lt;/code&gt;, conforme a documentação disponível na página &lt;a href="https://docs.localstack.cloud/get-started/#docker-compose"&gt;https://docs.localstack.cloud/get-started/#docker-compose&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Requisitos:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/get-docker/"&gt;&lt;code&gt;docker&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.docker.com/compose/install/"&gt;&lt;code&gt;docker-compose&lt;/code&gt;&lt;/a&gt; versão &amp;gt;= 1.9.0&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html"&gt;AWS Cli&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Iniciando o container
&lt;/h2&gt;

&lt;p&gt;Iremos utilizar o arquivo disponibilizado na própria página do LocalStack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/localstack/localstack/blob/master/docker-compose.yml"&gt;https://github.com/localstack/localstack/blob/master/docker-compose.yml&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.8"&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;localstack&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${LOCALSTACK_DOCKER_NAME-localstack_main}"&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localstack/localstack&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:4566:4566"&lt;/span&gt; &lt;span class="c1"&gt;# LocalStack Gateway&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:4510-4559:4510-4559"&lt;/span&gt; &lt;span class="c1"&gt;# external services port range&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:53:53"&lt;/span&gt; &lt;span class="c1"&gt;# DNS config (only required for Pro)&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:53:53/udp"&lt;/span&gt; &lt;span class="c1"&gt;# DNS config (only required for Pro)&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:443:443"&lt;/span&gt; &lt;span class="c1"&gt;# LocalStack HTTPS Gateway (only required for Pro)&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DEBUG=${DEBUG-}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PERSISTENCE=${PERSISTENCE-}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR-}&lt;/span&gt;
      &lt;span class="c1"&gt;# - LOCALSTACK_API_KEY=${LOCALSTACK_API_KEY-} # only required for Pro&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DOCKER_HOST=unix:///var/run/docker.sock&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;E iniciar o container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Configurando AWS Cli
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Caso não tenha o Cli da AWS pode seguir essa documentação: &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html"&gt;https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;aws &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"test"&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"test"&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_DEFAULT_REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;aws configure &lt;span class="nt"&gt;--profile&lt;/span&gt; localstack
&lt;span class="nv"&gt;$ &lt;/span&gt;aws configure list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Criando uma fila
&lt;/h2&gt;

&lt;p&gt;Criando uma fila chamada "teste", utilizando o profile "localstack":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;aws sqs create-queue &lt;span class="nt"&gt;--endpoint-url&lt;/span&gt; http://localhost:4566 &lt;span class="nt"&gt;--queue-name&lt;/span&gt; teste &lt;span class="nt"&gt;--profile&lt;/span&gt; localstack

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"QueueUrl"&lt;/span&gt;: &lt;span class="s2"&gt;"http://localhost:4566/000000000000/teste"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Listando filas
&lt;/h2&gt;

&lt;p&gt;Conferindo as filas criadas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;aws sqs list-queues &lt;span class="nt"&gt;--endpoint-url&lt;/span&gt; http://localhost:4566 &lt;span class="nt"&gt;--profile&lt;/span&gt; localstack

&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"QueueUrls"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"http://localhost:4566/000000000000/teste"&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Enviando uma mensagem à fila
&lt;/h2&gt;

&lt;p&gt;Antes de mais nada vamos criar um arquivo &lt;code&gt;message.json&lt;/code&gt; contendo os atributos da mensagem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"DataType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"StringValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"e8f50240-be67-463a-a479-d540697931c0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"DataType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"StringValue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"blue-car-toy"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após isso irei enviar a nossa fila "teste" a mensagem "Mensagem de Teste":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;aws sqs send-message &lt;span class="nt"&gt;--endpoint-url&lt;/span&gt; http://localhost:4566 &lt;span class="nt"&gt;--queue-url&lt;/span&gt; http://localhost:4566/000000000000/teste &lt;span class="nt"&gt;--message-body&lt;/span&gt; &lt;span class="s2"&gt;"Mensagem de Teste"&lt;/span&gt; &lt;span class="nt"&gt;--message-attributes&lt;/span&gt; file://./message.json &lt;span class="nt"&gt;--profile&lt;/span&gt; localstack
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"MD5OfMessageBody"&lt;/span&gt;: &lt;span class="s2"&gt;"90a9cc3ce1350489e33ee38d19bf287a"&lt;/span&gt;,
    &lt;span class="s2"&gt;"MD5OfMessageAttributes"&lt;/span&gt;: &lt;span class="s2"&gt;"16894947ed19d2117e32efdb4f734250"&lt;/span&gt;,
    &lt;span class="s2"&gt;"MessageId"&lt;/span&gt;: &lt;span class="s2"&gt;"bc406501-3632-4f87-934b-11a1c909f8c6"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Recebendo as mensagens da fila
&lt;/h2&gt;

&lt;p&gt;Lendo a mensagem da fila, uma a uma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;aws sqs receive-message &lt;span class="nt"&gt;--endpoint-url&lt;/span&gt; http://localhost:4566 &lt;span class="nt"&gt;--queue-url&lt;/span&gt; http://localhost:4566/000000000000/teste &lt;span class="nt"&gt;--attribute-names&lt;/span&gt; All &lt;span class="nt"&gt;--message-attribute-names&lt;/span&gt; All  &lt;span class="nt"&gt;--profile&lt;/span&gt; localstack
&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"Messages"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"MessageId"&lt;/span&gt;: &lt;span class="s2"&gt;"bc406501-3632-4f87-934b-11a1c909f8c6"&lt;/span&gt;,
            &lt;span class="s2"&gt;"ReceiptHandle"&lt;/span&gt;: &lt;span class="s2"&gt;"N2VkNDdhZGQtMmUxZS00NmVjLWE5NzYtNGQzM2
ExNWZmODVlIGFybjphd3M6c3FzOnVzLWVhc3QtMTowMDAwMDAwMDAwMDA6dGVzdGUgYm
M0MDY1MDEtMzYzMi00Zjg3LTkzNGItMTFhMWM5MDlmOGM2IDE2NjU5MzkyODIuNDQ3NTc4NA=="&lt;/span&gt;,
            &lt;span class="s2"&gt;"MD5OfBody"&lt;/span&gt;: &lt;span class="s2"&gt;"90a9cc3ce1350489e33ee38d19bf287a"&lt;/span&gt;,
            &lt;span class="s2"&gt;"Body"&lt;/span&gt;: &lt;span class="s2"&gt;"Mensagem de Teste"&lt;/span&gt;,
            &lt;span class="s2"&gt;"Attributes"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"SenderId"&lt;/span&gt;: &lt;span class="s2"&gt;"000000000000"&lt;/span&gt;,
                &lt;span class="s2"&gt;"SentTimestamp"&lt;/span&gt;: &lt;span class="s2"&gt;"1665939195032"&lt;/span&gt;,
                &lt;span class="s2"&gt;"ApproximateReceiveCount"&lt;/span&gt;: &lt;span class="s2"&gt;"1"&lt;/span&gt;,
                &lt;span class="s2"&gt;"ApproximateFirstReceiveTimestamp"&lt;/span&gt;: &lt;span class="s2"&gt;"1665939282447"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;,
            &lt;span class="s2"&gt;"MD5OfMessageAttributes"&lt;/span&gt;: &lt;span class="s2"&gt;"16894947ed19d2117e32efdb4f734250"&lt;/span&gt;,
            &lt;span class="s2"&gt;"MessageAttributes"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"id"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"StringValue"&lt;/span&gt;: &lt;span class="s2"&gt;"e8f50240-be67-463a-a479-d540697931c0"&lt;/span&gt;,
                    &lt;span class="s2"&gt;"DataType"&lt;/span&gt;: &lt;span class="s2"&gt;"String"&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;,
                &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"StringValue"&lt;/span&gt;: &lt;span class="s2"&gt;"blue-car-toy"&lt;/span&gt;,
                    &lt;span class="s2"&gt;"DataType"&lt;/span&gt;: &lt;span class="s2"&gt;"String"&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;É isso! 😉&lt;/p&gt;




&lt;h2&gt;
  
  
  Referências:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/flflima/localstack-docker"&gt;https://github.com/flflima/localstack-docker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;LocalStack&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.localstack.cloud/overview/"&gt;https://docs.localstack.cloud/overview/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/localstack/localstack"&gt;https://github.com/localstack/localstack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;AWS Cli&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/reference/sqs/"&gt;https://docs.aws.amazon.com/cli/latest/reference/sqs/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>sqs</category>
      <category>localstack</category>
      <category>docker</category>
    </item>
    <item>
      <title>Integrando Gradle + Jacoco + SonarQube</title>
      <dc:creator>Felipe Lima</dc:creator>
      <pubDate>Sun, 18 Apr 2021 21:16:41 +0000</pubDate>
      <link>https://dev.to/flflima/integrando-gradle-jacoco-sonarqube-2a9g</link>
      <guid>https://dev.to/flflima/integrando-gradle-jacoco-sonarqube-2a9g</guid>
      <description>&lt;p&gt;Cobertura de testes é um assunto polêmico. Se meu código tem 100% de cobertura de código, significa que ele está a prova de falhas? Não exatamente. Mas é essencial ter uma boa noção da cobertura dos teste no nosso código e ter em mãos ferramentas de análise que nos ajudem a ter uma noção melhor dos pontos de atenção no código (seja quanto a sua complexididade, tamanho de classes, dependências etc).&lt;/p&gt;

&lt;p&gt;Em alguns projetos que trabalhei muitas vezes utilizava apenas o &lt;a href="https://www.eclemma.org/jacoco" rel="noopener noreferrer"&gt;Jacoco&lt;/a&gt; para analisar a cobertura dos meus testes a partir dos relatórios gerados por ele. &lt;/p&gt;

&lt;p&gt;Com o SonarQube podemos dar um passo adiante, já que a partir do relatório gerado pelo Jacoco ele consegue dar um complemento na análise e saúde do nosso código, gerando um dashboard com várias informações. Ele complementa esse relatório de cobertura, trazendo informações de violações de boas práticas no código, potênciais bugs, duplicações, falhas de segurança e entre outras coisas...&lt;/p&gt;

&lt;h1&gt;
  
  
  Rodando SonarQube localmente
&lt;/h1&gt;

&lt;p&gt;Nesta demonstração utilizei a versão &lt;em&gt;&lt;strong&gt;8.8-community&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Antes de mais nada é preciso seguir as recomendações da página do &lt;a href="https://hub.docker.com/_/sonarqube/" rel="noopener noreferrer"&gt;Dockerhub&lt;/a&gt;, que sugerem ajustar a quantidade de memória virtual: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For example, on Linux, you can set the recommended values for the current session by running the following commands as root on the host:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; vm.max_map_count&lt;span class="o"&gt;=&lt;/span&gt;262144
sysctl &lt;span class="nt"&gt;-w&lt;/span&gt; fs.file-max&lt;span class="o"&gt;=&lt;/span&gt;65536
&lt;span class="nb"&gt;ulimit&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 65536
&lt;span class="nb"&gt;ulimit&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; 4096
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após isso criar um docker-compose.yml seguindo as orientações fornecidas na &lt;a href="https://docs.sonarqube.org/latest/setup/install-server/" rel="noopener noreferrer"&gt;documentação para Docker&lt;/a&gt; do SonarQube e subir o container localmente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No navegador acessar &lt;code&gt;http://localhost:9000/&lt;/code&gt; e entrar na tela de login, como abaixo:&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%2Fuploads%2Farticles%2Fj2mixtq91qlq8oszsnv0.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%2Fuploads%2Farticles%2Fj2mixtq91qlq8oszsnv0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neste primeiro acesso conectei com login e senha &lt;em&gt;admin/admin&lt;/em&gt;. Em seguida será solicitada uma nova senha:&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%2Fuploads%2Farticles%2Fpfc9xr32q8oq7m56uhx5.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%2Fuploads%2Farticles%2Fpfc9xr32q8oq7m56uhx5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pronto! Podemos acessar nosso SonarQube:&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%2Fuploads%2Farticles%2Flmxl5ojtlpzdeg5pu80t.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%2Fuploads%2Farticles%2Flmxl5ojtlpzdeg5pu80t.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Configurando meu projeto
&lt;/h1&gt;

&lt;p&gt;Para fazer essa integração utilizei um projeto pessoal desenvolvido em Kotlin: &lt;a href="https://github.com/flflima/shopping-cart" rel="noopener noreferrer"&gt;https://github.com/flflima/shopping-cart&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Primeiramente no SonarQube criei e configurei um projeto manualmente:&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%2Fuploads%2Farticles%2Fkcsw2mvrvoq7wavy213u.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%2Fuploads%2Farticles%2Fkcsw2mvrvoq7wavy213u.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&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%2Fuploads%2Farticles%2Fo4c9osg5vphvdlwau3jw.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%2Fuploads%2Farticles%2Fo4c9osg5vphvdlwau3jw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Foi gerado um código para adicionar no meu arquivo de configuração do projeto. No meu caso, estou utilizando o Gradle como gerenciador de dependência:&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%2Fuploads%2Farticles%2Ftkayxu17dzpnvkhmb2eg.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%2Fuploads%2Farticles%2Ftkayxu17dzpnvkhmb2eg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após adicionar o plugin conforme sugerido, bastou executar o comando que gera meus relatórios via Jacoco e integra com o SonarQube:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./gradlew clean &lt;span class="nb"&gt;test &lt;/span&gt;sonarqube &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-Dsonar&lt;/span&gt;.projectKey&lt;span class="o"&gt;=&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;your&lt;/span&gt;&lt;span class="sh"&gt;-project-key-configured&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
  -Dsonar.host.url=http://localhost:9000 &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="sh"&gt;
  -Dsonar.login=&amp;lt;&amp;lt;the-login&amp;gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na primeira vez que executei, o report marcou &lt;strong&gt;0%&lt;/strong&gt; de cobertura, o que não deveria ter acontecido já que o relatório do Jacoco marcava uma cobertura acima de &lt;strong&gt;80%&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Mais precisamente &lt;strong&gt;99%&lt;/strong&gt; para cobertura por linha e &lt;strong&gt;86%&lt;/strong&gt; para cobertura por branches:&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%2Fuploads%2Farticles%2Fwn1sytqxcwnsqwcgny6g.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%2Fuploads%2Farticles%2Fwn1sytqxcwnsqwcgny6g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Já no SonarQube:&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%2Fuploads%2Farticles%2Fdqruetk82cuzi5yy7dnq.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%2Fuploads%2Farticles%2Fdqruetk82cuzi5yy7dnq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após algumas pesquisas, descobri que precisava fazer alguns ajustes para que o Sonarqube pudesse enxergar o relatório gerado pelo Jacoco:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;habilitar a flag &lt;strong&gt;xml.enabled&lt;/strong&gt;, para que o SonarQube pudesse ler o relatório gerado em formato XML (a partir da versão 8 ele deixou de suportar o arquivo &lt;strong&gt;.exec&lt;/strong&gt; gerado pelo Jacoco - mais &lt;a href="https://community.sonarsource.com/t/sonarqube-community-version-8-3-is-showing-0-code-coverage-however-with-the-same-configurations-i-am-able-to-get-coverage-in-community-version-8-1/28007" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;jacocoTestReport&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;reports&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;xml&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enabled&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// a flag anteriormente era false&lt;/span&gt;
        &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;enabled&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
        &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;destination&lt;/span&gt; &lt;span class="nf"&gt;file&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"${buildDir}/jacocoHtml"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;afterEvaluate&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;excludeFiles&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;classDirectories&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;coverageExclusions&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;incluí uma configuração para o SonarQube localizar o relatório em XML e mapeei os mesmos arquivos excluídos da verificação do Jacoco:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;sonarqube&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;properties&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;property&lt;/span&gt; &lt;span class="s"&gt;"sonar.coverage.jacoco.xmlReportPaths"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"${buildDir}/reports/jacoco/test/*.xml"&lt;/span&gt;
        &lt;span class="n"&gt;property&lt;/span&gt; &lt;span class="s"&gt;"sonar.java.coveragePlugin"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"jacoco"&lt;/span&gt;
        &lt;span class="n"&gt;property&lt;/span&gt; &lt;span class="s"&gt;"sonar.coverage.exclusions"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;coverageExclusions&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;na verificação da cobertura de código, removi a flag &lt;strong&gt;enabled = false&lt;/strong&gt;, para que o relatório fosse gerado sempre, mesmo que a cobertura de código não fosse atingida:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;jacocoTestCoverageVerification&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;violationRules&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;limit&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// enabled = false&lt;/span&gt;
                &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="no"&gt;BRANCH&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
                &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="no"&gt;COVEREDRATIO&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
                &lt;span class="n"&gt;minimum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;afterEvaluate&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;excludeFiles&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;classDirectories&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após essas alterações o SonarQube começou a apresentar os valores de cobetura. Na aba 'Measures' podemos ver que o mesmo valor (ou uma aproximação) é marcado, tanto para cobertura por linhas como por branches:&lt;br&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%2Fuploads%2Farticles%2Fo7rln65v1heh385lrgx9.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%2Fuploads%2Farticles%2Fo7rln65v1heh385lrgx9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&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%2Fuploads%2Farticles%2Ffc5dipzipogqqmf5bm91.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%2Fuploads%2Farticles%2Ffc5dipzipogqqmf5bm91.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&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%2Fuploads%2Farticles%2Fwn1sytqxcwnsqwcgny6g.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%2Fuploads%2Farticles%2Fwn1sytqxcwnsqwcgny6g.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E como cobertura geral do SonarQube temos:&lt;br&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%2Fuploads%2Farticles%2F52nxk0iy9i0bl98u5tjv.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%2Fuploads%2Farticles%2F52nxk0iy9i0bl98u5tjv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Como comentei no início do texto, essas são ferramentas que agregam nossa busca em qualidade de código. &lt;/p&gt;

&lt;p&gt;É claro que precisamos estar sempre atentos porque até mesmos os testes podem estar sujeitos a bugs e nos dar a falsa sensação de que por termos uma alta cobertura nosso código está protegido. &lt;/p&gt;

&lt;p&gt;Mas como toda ferramenta de apoio é bem vinda, acredito que seja extremamente interessante que um desenvolvedor tenha conhecimento delas e ao longo do tempo vá usando todas com consciência.&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%2Fuploads%2Farticles%2Fl6r2zqi6u71h8ean0fo7.gif" 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%2Fuploads%2Farticles%2Fl6r2zqi6u71h8ean0fo7.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Referências
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.eclemma.org/jacoco/" rel="noopener noreferrer"&gt;https://www.eclemma.org/jacoco/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.sonarqube.org/" rel="noopener noreferrer"&gt;https://www.sonarqube.org/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://hub.docker.com/_/sonarqube" rel="noopener noreferrer"&gt;https://hub.docker.com/_/sonarqube&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.sonarqube.org/latest/setup/install-server/" rel="noopener noreferrer"&gt;https://docs.sonarqube.org/latest/setup/install-server/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Referência ao erro:&lt;/em&gt; &lt;a href="https://github.com/SonarSource/docker-sonarqube/issues/317" rel="noopener noreferrer"&gt;https://github.com/SonarSource/docker-sonarqube/issues/317&lt;/a&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>gradle</category>
      <category>jacoco</category>
      <category>sonarqube</category>
    </item>
    <item>
      <title>"Hello World" com Kotlin e Javalin</title>
      <dc:creator>Felipe Lima</dc:creator>
      <pubDate>Fri, 02 Apr 2021 18:07:48 +0000</pubDate>
      <link>https://dev.to/flflima/hello-world-com-kotlin-e-javalin-1p01</link>
      <guid>https://dev.to/flflima/hello-world-com-kotlin-e-javalin-1p01</guid>
      <description>&lt;p&gt;Eu lembro que a primeira vez que me ofereceram uma oportunidade para trabalhar com Kotlin achei estranho e acabei perguntando na hora: &lt;em&gt;"Ah conhecço Kotlin, mas não serve pra desenvolvimento de apps?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Bem, sim e muito mais!&lt;/p&gt;

&lt;p&gt;Kotlin é uma linguagem multiplataforma desenvolvida pela JetBrains, que combina programação orientada a objetos com funcional, podendo ser utilizada para desenvolvimento de aplicações no lado do servidor, desenvolvimento Android, compilar JavaScript e código nativo. &lt;/p&gt;

&lt;p&gt;Sua principal vantagem está em ter um código mais conciso e expressivo, mantendo compatibilidade com outros códigos em Java além de ter uma boa curva de aprendizagem.&lt;/p&gt;

&lt;p&gt;Dito isso, como seria uma aplicação web desenvolvida em Kotlin. É o que irei demonstrar neste texto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando um servidor web
&lt;/h2&gt;

&lt;p&gt;Neste exemplo que eu fiz eu irei trabalhar com o Javalin.&lt;br&gt;
Javalin é um framework leve que serve tanto para Java como para Kotlin. &lt;/p&gt;

&lt;p&gt;Existem vários outros frameworks para Kotlin, mas acho que pra uma rápida demonstração ele serve, principalmente para quem está começando a programar nessa linguagem, já que não é necessário aprender muitos conceitos do framework para poder usá-lo e subir uma aplicação.&lt;/p&gt;
&lt;h2&gt;
  
  
  Olá Mundo!
&lt;/h2&gt;

&lt;p&gt;Uma vez que você criou e configurou seu projeto, basta começar a adicionar as dependências para por nosso servidor em pé.&lt;/p&gt;

&lt;p&gt;No meu exemplo eu utilizo o Gradle.&lt;/p&gt;

&lt;p&gt;Primeiramente eu adicionei a biblioteca do Javalin e algumas outras dependências.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'io.javalin:javalin:3.13.4'&lt;/span&gt;
&lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'org.slf4j:slf4j-simple:1.7.30'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após isso criei um arquivo &lt;code&gt;Main.kt&lt;/code&gt; e adicionei o seguinte conteúdo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.javalin.Javalin&lt;/span&gt;

&lt;span class="n"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Javalin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7000&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/hello"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;result&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basicamente estou dizendo para que seja criada uma aplicação que escute na porta &lt;strong&gt;7000&lt;/strong&gt;, e que ao acessar o recurso &lt;strong&gt;/hello&lt;/strong&gt; (GET &lt;a href="http://localhost:7000/hello" rel="noopener noreferrer"&gt;http://localhost:7000/hello&lt;/a&gt;) retorne a mensagem "Hello World".&lt;/p&gt;

&lt;p&gt;Executando a chamada no Postman temos o seguinte:&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%2Fuploads%2Farticles%2F8yhsy7tb3hlpxoxcymux.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%2Fuploads%2Farticles%2F8yhsy7tb3hlpxoxcymux.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simples, não?&lt;/p&gt;

&lt;p&gt;A partir disso podemos evoluir cada vez mais a nossa aplicação (incluir outros endpoints, integração com banco de dados, segurança) mas isso pode ficar para um próxima ;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://kotlinlang.org/docs/server-overview.html" rel="noopener noreferrer"&gt;https://kotlinlang.org/docs/server-overview.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javalin.io/" rel="noopener noreferrer"&gt;https://javalin.io/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>rest</category>
      <category>javalin</category>
      <category>backend</category>
    </item>
  </channel>
</rss>
