<?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: Marks Duarte</title>
    <description>The latest articles on Forem by Marks Duarte (@marksduarte).</description>
    <link>https://forem.com/marksduarte</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%2F230761%2Fbcc3822f-d209-4956-ba85-f575d1f0f350.png</url>
      <title>Forem: Marks Duarte</title>
      <link>https://forem.com/marksduarte</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/marksduarte"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Marks Duarte</dc:creator>
      <pubDate>Sun, 20 Apr 2025 12:08:31 +0000</pubDate>
      <link>https://forem.com/marksduarte/-305a</link>
      <guid>https://forem.com/marksduarte/-305a</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/hugaomarques/parallelstream-aninhado-mais-concorrencia-menos-performance-1en5" class="crayons-story__hidden-navigation-link"&gt;parallelStream() Aninhado: Mais Concorrência, Menos Performance&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/hugaomarques" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F32258%2F86d4a086-97a9-4aea-a9ad-457835d72bfe.png" alt="hugaomarques profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/hugaomarques" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Hugo Marques
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Hugo Marques
                
              
              &lt;div id="story-author-preview-content-2405520" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/hugaomarques" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F32258%2F86d4a086-97a9-4aea-a9ad-457835d72bfe.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Hugo Marques&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/hugaomarques/parallelstream-aninhado-mais-concorrencia-menos-performance-1en5" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 15 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/hugaomarques/parallelstream-aninhado-mais-concorrencia-menos-performance-1en5" id="article-link-2405520"&gt;
          parallelStream() Aninhado: Mais Concorrência, Menos Performance
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/java"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;java&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/performance"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;performance&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/concurrency"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;concurrency&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/braziliandevs"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;braziliandevs&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/hugaomarques/parallelstream-aninhado-mais-concorrencia-menos-performance-1en5" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;13&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/hugaomarques/parallelstream-aninhado-mais-concorrencia-menos-performance-1en5#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              5&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>java</category>
      <category>performance</category>
      <category>concurrency</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>ASSINANDO COMMITS NO WINDOWS E PUBLICANDO NO GITHUB</title>
      <dc:creator>Marks Duarte</dc:creator>
      <pubDate>Wed, 21 Feb 2024 02:57:48 +0000</pubDate>
      <link>https://forem.com/marksduarte/assinando-commits-no-windows-e-publicando-no-github-12me</link>
      <guid>https://forem.com/marksduarte/assinando-commits-no-windows-e-publicando-no-github-12me</guid>
      <description>&lt;p&gt;Como segurança nunca é demais, vamos aprender como assinar nossos commits usando chaves GPG para garantir a integridade e confiabilidade do autor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalando GPG no Windows
&lt;/h2&gt;

&lt;p&gt;Para facilitar a criação das nossas chaves, podemos instalar um cli chamado gnupg.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.gnupg.org/download/"&gt;https://www.gnupg.org/download/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Gerando uma nova chave GPG
&lt;/h2&gt;

&lt;p&gt;O GitHub, GitLab e Azure Devops suportam vários formatos de chaves, tais como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RSA&lt;/li&gt;
&lt;li&gt;ElGamal&lt;/li&gt;
&lt;li&gt;DSA&lt;/li&gt;
&lt;li&gt;ECDH&lt;/li&gt;
&lt;li&gt;ECDSA&lt;/li&gt;
&lt;li&gt;EdDSA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feita a instalação do gnupg na versão 2.1.17+, execute o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg --full-generate-key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Especifique qual tipo de chave deseja gerar, seu tamanho e o tempo de validade, nome de usuário, e-mail e senha de criptografia.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Atente-se ao fato de que o e-mail informado deve ser o mesmo utilizado no GitHub e etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Liste as chaves armazenadas e copie o ID da chave que desejada:&lt;br&gt;
&lt;em&gt;O ID é o código 3AA5C34371567BD2, como no exemplo abaixo.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg --list-secret-keys --keyid-format=long

$ gpg --list-secret-keys --keyid-format=long
/Users/marks/.gnupg/secring.gpg
------------------------------------
sec   4096R/3AA5C34371567BD2 2024-02-20 [expires: 2024-03-20]
uid                          Marks &amp;lt;marks@example.com&amp;gt;
ssb   4096R/4BB6D45482678BE3 2024-02-20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Passe o ID copiado como parâmetro do comando que imprime a chave pública que deverá ser informada no GitHub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpg --armor --export 3AA5C34371567BD2
# Imprime a chave GPG em formato ASCII
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copie todo o texto começando com&lt;br&gt;&lt;br&gt;
&lt;code&gt;-----BEGIN PGP PUBLIC KEY BLOCK-----&lt;/code&gt;&lt;br&gt;&lt;br&gt;
e terminando com&lt;br&gt;&lt;br&gt;
&lt;code&gt;----END PGP PUBLIC KEY BLOCK-----&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora acesse sua conta no github, vá até &lt;code&gt;configurações &amp;gt; SSH and GPG keys&lt;/code&gt; e adicione a chave ASCII gerada.  &lt;/p&gt;
&lt;h2&gt;
  
  
  Configurando o GIT
&lt;/h2&gt;

&lt;p&gt;Antes de configurar o git, vamos garantir que não exista um formato de assinatura previamente informado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global --unset gpg.format
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora podemos configurá-lo para assinar nossos commits de forma global ou local:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global user.signingkey 3AA5C34371567BD2
git config --local user.signingkey 3AA5C34371567BD2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Lembre-se de copiar o ID da chave ou listar novamente com &lt;code&gt;gpg --list-secret-keys --keyid-format=long&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agora faça um commit assinado com o comando:&lt;br&gt;&lt;br&gt;
&lt;code&gt;git commit -S -m "message"&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Opcionalmente, podemos configurar o Git para assinar todos os commits por padrão, com o comando: &lt;em&gt;&lt;strong&gt;git config --global commit.gpgsign true&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Caso ocorra o erro &lt;em&gt;&lt;strong&gt;signing failed: No secret key&lt;/strong&gt;&lt;/em&gt;, informe para o git o path do gpg instalado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpgconf
gpg:OpenPGP:C%3a\Program Files (x86)\gnupg\bin\gpg.exe
gpgsm:S/MIME:C%3a\Program Files (x86)\gnupg\bin\gpgsm.exe
keyboxd:Public Keys:C%3a\Program Files (x86)\gnupg\bin\keyboxd.exe
gpg-agent:Private Keys:C%3a\Program Files (x86)\gnupg\bin\gpg-agent.exe
scdaemon:Smartcards:C%3a\Program Files (x86)\gnupg\bin\scdaemon.exe
dirmngr:Network:C%3a\Program Files (x86)\gnupg\bin\dirmngr.exe
pinentry:Passphrase Entry:C%3a\Program Files (x86)\gnupg\bin\pinentry-basic.exe


git config --global gpg.program "C:\Program Files (x86)\gnupg\bin\gpg.exe"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agradeço a leitura e até a próxima. 😎&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>tutorial</category>
      <category>windows</category>
    </item>
    <item>
      <title>Como habilitar para que as portas USB acordem o computador</title>
      <dc:creator>Marks Duarte</dc:creator>
      <pubDate>Mon, 01 May 2023 18:06:02 +0000</pubDate>
      <link>https://forem.com/marksduarte/como-habilitar-para-que-as-portas-usb-acordem-o-computador-5c53</link>
      <guid>https://forem.com/marksduarte/como-habilitar-para-que-as-portas-usb-acordem-o-computador-5c53</guid>
      <description>&lt;h2&gt;
  
  
  Testado no Ubuntu 23.04
&lt;/h2&gt;

&lt;p&gt;Liste os dispositivos que podem acordar o sistema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;grep . /sys/bus/usb/devices/*/power/wakeup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O resultado será uma lista de dispositivos com a indicação de habilitado ou desabilitado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/sys/bus/usb/devices/usb1/power/wakeup:disabled
/sys/bus/usb/devices/usb2/power/wakeup:disabled
/sys/bus/usb/devices/usb3/power/wakeup:disabled
/sys/bus/usb/devices/usb4/power/wakeup:disabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos editar o arquivo &lt;strong&gt;rc.local&lt;/strong&gt; para habilitar os dispositivos mesmo após o reinicio do sistema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/rc.local
&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;echo enabled &amp;gt; /sys/bus/usb/devices/usb1/power/wakeup
echo enabled &amp;gt; /sys/bus/usb/devices/usb2/power/wakeup
echo enabled &amp;gt; /sys/bus/usb/devices/usb3/power/wakeup
echo enabled &amp;gt; /sys/bus/usb/devices/usb4/power/wakeup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Salve o arquivo e pronto.&lt;/p&gt;

&lt;p&gt;Espero ter ajudado.&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>linux</category>
    </item>
    <item>
      <title>Configurando o Spring Boot Admin: Server e Client</title>
      <dc:creator>Marks Duarte</dc:creator>
      <pubDate>Sat, 08 Apr 2023 02:28:06 +0000</pubDate>
      <link>https://forem.com/marksduarte/configurando-o-spring-boot-admin-server-e-client-hld</link>
      <guid>https://forem.com/marksduarte/configurando-o-spring-boot-admin-server-e-client-hld</guid>
      <description>&lt;p&gt;Existem várias formas de se monitorar sistemas distribuídos e uma que me agrada bastante pela simplicidade de configuração e confiabilidade é o Spring Boot Admin.&lt;/p&gt;

&lt;p&gt;Nesse tutorial criaremos duas aplicações utilizando o Spring Boot, uma que será o servidor de monitoramento e a outra, o cliente que deverá se registrar para ser monitorado. &lt;/p&gt;

&lt;p&gt;Também vamos aproveitar para implementar uma camada de segurança utilizando o Spring Security e com o #Maven, poderemos fazer o build das aplicações para serem executadas individualmente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Versões utilizadas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Spring Boot: 2.7.10&lt;/li&gt;
&lt;li&gt;Spring Boot Admin Server: 2.7.10&lt;/li&gt;
&lt;li&gt;Spring Boot Admin Client: 2.7.10&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Configurando o Servidor
&lt;/h2&gt;

&lt;p&gt;Crie um projeto utilizando o &lt;a href="https://start.spring.io/" rel="noopener noreferrer"&gt;Spring Initilizr&lt;/a&gt; com as seguintes dependências:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Starter Web&lt;/li&gt;
&lt;li&gt;Starter Security&lt;/li&gt;
&lt;li&gt;Admin Starter Server&lt;/li&gt;
&lt;/ul&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%2F8oyux0tnsibtnw4s5wbx.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%2F8oyux0tnsibtnw4s5wbx.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Confira se as dependências relacionadas ao Spring Boot Admin foram adicionadas:&lt;/p&gt;

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

...
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;de.codecentric&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-admin-starter-server&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;de.codecentric&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-admin-server-ui&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
...


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

&lt;/div&gt;

&lt;p&gt;Adicione a anotação @EnableAdminServer em alguma classe de configuração:&lt;/p&gt;

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

...

@EnableAdminServer
@SpringBootApplication
public class SpringBootAdminServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootAdminServerApplication.class, args);
    }

}



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

&lt;/div&gt;

&lt;p&gt;Configure o comportamento da aplicação utilizando o arquivo application.yaml. Como adicionamos uma camada de segurança, devemos criar um nome de usuário e senha para logarmos no servidor e também será necessário configurar o login para comunicação entre servidor e cliente.&lt;/p&gt;

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

server:
  port: 8081
  servlet:
    context-path: /admin-console
spring:
  security:
    user:
      # Configura o login do servidor.
      name: ${SBA_SERVER_USERNAME}
      password: ${SBA_SERVER_PASSWORD}
  boot:
    admin:
      client:
        # Necessários para que o cliente possa se registrar na api do servidor protegido.
        username: ${SBA_SERVER_USERNAME}
        password: ${SBA_SERVER_PASSWORD}
        instance:
          metadata:
            user:
              # Necessários para que o servidor possa acessar os endpoints protegidos do cliente.
              name: ${SBA_CLIENT_USERNAME}
              password: ${SBA_CLIENT_PASSWORD}

# LOG
logging:
  file:
    name: ${user.home}/logs/admin/sba-server.log
  level:
    root: info
    web: info
    dev.marksduarte: info
    org.springframework: info
  charset:
    file: utf-8



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

&lt;/div&gt;

&lt;p&gt;Agora vamos configurar o Spring Security criando uma classe e desabilitando o proxy dos beans na anotação @Configuration(proxyBeanMethods = false), pois como vamos trabalhar com &lt;a class="mentioned-user" href="https://dev.to/bean"&gt;@bean&lt;/a&gt; autocontido, podemos evitar o processamento da subclasse CGLIB.&lt;/p&gt;

&lt;p&gt;Também vamos permitir os acessos às rotas de &lt;strong&gt;login&lt;/strong&gt; e &lt;strong&gt;assets&lt;/strong&gt; e desabilitar a proteção &lt;strong&gt;CSRF&lt;/strong&gt; paras o métodos &lt;strong&gt;HTTP POST&lt;/strong&gt; e &lt;strong&gt;HTTP DELETE&lt;/strong&gt; nas instâncias dos clientes.&lt;/p&gt;

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

package dev.marksduarte.springbootadminserver;

import de.codecentric.boot.admin.server.config.AdminServerProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

@Configuration(proxyBeanMethods = false)
public class SecurityConfig {

    private final AdminServerProperties adminServer;

    public SecurityConfig(AdminServerProperties adminServer) {
        this.adminServer = adminServer;
    }

    @Bean
    protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");
        successHandler.setDefaultTargetUrl(this.adminServer.path("/"));

        http.authorizeHttpRequests(authorizeRequests -&amp;gt; authorizeRequests
                        .requestMatchers(new AntPathRequestMatcher(this.adminServer.path("/assets/**")))
                        .permitAll()
                        .requestMatchers(new AntPathRequestMatcher(this.adminServer.path("/login")))
                        .permitAll()
                        .anyRequest()
                        .authenticated())
                .formLogin(formLogin -&amp;gt; formLogin.loginPage(this.adminServer.path("/login"))
                        .successHandler(successHandler))
                .logout(logout -&amp;gt; logout.logoutUrl(this.adminServer.path("/logout")))
                .httpBasic(Customizer.withDefaults())
                .csrf(csrf -&amp;gt; csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                        .ignoringRequestMatchers(
                                new AntPathRequestMatcher(this.adminServer.path("/instances"), HttpMethod.POST.toString()),
                                new AntPathRequestMatcher(this.adminServer.path("/instances/*"), HttpMethod.DELETE.toString()),
                                new AntPathRequestMatcher(this.adminServer.path("/actuator/**"))));

        return http.build();
    }
}



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

&lt;/div&gt;

&lt;p&gt;Pronto, agora é só rodar a aplicação e conferir se o Admin Server está acessível através do endereço &lt;a href="http://localhost:8081/admin-console" rel="noopener noreferrer"&gt;http://localhost:8081/admin-console&lt;/a&gt; e logar com o usuário e senha informados na configuração.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurando o Cliente
&lt;/h2&gt;

&lt;p&gt;Crie um projeto utilizando o &lt;a href="https://start.spring.io/" rel="noopener noreferrer"&gt;Spring Initilizr&lt;/a&gt; com as seguintes dependências:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Starter Web&lt;/li&gt;
&lt;li&gt;Starter Actuator&lt;/li&gt;
&lt;li&gt;Starter Security&lt;/li&gt;
&lt;li&gt;Admin Starter Client&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Confira no seu arquivo pom.xml, se a dependência do Spring Boot Admin Client e Spring Actuator foram adicionadas:&lt;/p&gt;

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

...
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-actuator&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;

&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;de.codecentric&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-admin-starter-client&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.7.10&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
...


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

&lt;/div&gt;

&lt;p&gt;Agora vamos configurar o sistema começando pelo arquivo application.yaml:&lt;/p&gt;

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

## INFO ENDPOINT
## Aqui configuramos as informações sobre o sistema, como nome, descrição, versão e etc.
info:
  name: Spring Boot Admin Client
  description: Sistema Cliente
  version: @project.version@

server:
  port: 8080
  servlet:
    context-path: /admin-client

spring:
  # Configuração básica do Spring Security.
  security:
    user:
      name: ${SBA_CLIENT_USERNAME}
      password: ${SBA_CLIENT_PASSWORD}
  boot:
    admin:
      client:
        enabled: true
        # URL do servidor que o cliente deve se registrar.
        url: http://localhost:8081/admin-console
        username: ${SBA_SERVER_USERNAME}
        password: ${SBA_SERVER_PASSWORD}
        instance:
          # URL base para calcular o service-url com o qual se registrar. O caminho é inferido em tempo de execução e anexado à url base.
          service-base-url: http://localhost:8080
          # Essas informações são passadas ao servidor para que ele possa fazer o acesso aos endpoints do sistema cliente.
          metadata:
            user:
              name: ${SBA_SERVER_USERNAME}
              password: ${SBA_SERVER_PASSWORD}
        auto-deregistration: true

## APP
app:
  cors-origins:
    - http://localhost
  cors-methods:
    - GET
    - POST
    - PUT
    - DELETE
    - OPTIONS
  cors-headers:
    - Authorization
    - Content-Type
    - Content-Length
    - X-Requested-With

## ACTUATOR
management:
  info:
    env:
      # Desde o Spring Boot 2.6, o env info é desabilitado por padrão.
      enabled: true
  endpoint:
    health:
      show-details: ALWAYS
      enabled: true
    shutdown:
      enabled: true
    logfile:
      enabled: true
      external-file: logs/sba-client.log
  endpoints:
    web:
      exposure:
        # Liberamos todos os endpoints, mas lembre-se, em produção não se deve fazer isso.
        include: "*"
      cors:
        allowed-headers: ${app.cors-headers}
        allowed-methods: ${app.cors-methods}
        allowed-origins: ${app.cors-origins}

## LOG
logging:
  file:
    name: logs/sba-client.log
    path: logs
  level:
    root: info
    web: info
    dev.marksduarte: info
  charset:
    file: utf-8
  logback:
    rollingpolicy:
      clean-history-on-start: true
      max-file-size: 10MB



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

&lt;/div&gt;

&lt;p&gt;Para simplificar, vamos habilitar todas as requisições para os endpoints do "/actuator/**":&lt;/p&gt;

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

...

@EnableWebSecurity
@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf()
                .disable()
                .authorizeHttpRequests()
                .antMatchers("/actuator/**")
                .permitAll();
        return http.build();
    }
}


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

&lt;/div&gt;

&lt;p&gt;Bom, isso já é suficiente para registar nossa aplicação cliente no servidor.&lt;/p&gt;

&lt;p&gt;Mas caso aconteça alguma exceção do tipo: &lt;em&gt;HttpMessageNotWritableException&lt;/em&gt; ou um response error HTTP 416 ao tentar acessar o arquivo de log, não se assuste, isso pode acontecer caso seu sistema tenha alguma classe de configuração do Jackson que estenda &lt;em&gt;WebMvcConfigurationSupport&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Nesse caso, essa classe pode estar desativando a instanciação dos &lt;em&gt;Beans&lt;/em&gt; com as configurações padrões do Spring Boot.&lt;/p&gt;

&lt;p&gt;Para corrigir esse tipo de problema, podemos criar um Bean customizado e substituir a configuração padrão criada na inicialização do sistema.&lt;/p&gt;

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

@Configuration
public class JacksonConfig extends WebMvcConfigurationSupport {

    private final Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.json();

    private static final List&amp;lt;MediaType&amp;gt; MEDIA_TYPE_LIST = List.of(
            MediaType.ALL,
            MediaType.parseMediaType("application/vnd.spring-boot.actuator.v2+json")
    );

    @Bean
    public MappingJackson2HttpMessageConverter customMappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter converter = actuatorConverter();
        converter.setSupportedMediaTypes(MEDIA_TYPE_LIST);
        return converter;
    }

    private MappingJackson2HttpMessageConverter actuatorConverter() {
        return new MappingJackson2HttpMessageConverter(builder.build()) {
            @Override
            protected boolean canWrite(MediaType mediaType) {
                // O método super, retorna true se for null.
                // Assim evitamos a exceção _HttpMessageNotWritableException_ caso o Content-Type 'null' seja enviado.
                return mediaType != null &amp;amp;&amp;amp; super.canWrite(mediaType);
            }
        };
    }

    @Override
    protected void extendMessageConverters(List&amp;lt;HttpMessageConverter&amp;lt;?&amp;gt;&amp;gt; converters) {
        /*
        Remove somente o MappingJackson2HttpMessageConverter
padrão e substitui pelo customMappingJackson2HttpMessageConverter.
         */
        var defaultHttpConverterOpt = converters.stream()
                .filter(MappingJackson2HttpMessageConverter.class::isInstance)
                .findFirst();

        defaultHttpConverterOpt.ifPresent(converters::remove);
        converters.add(customMappingJackson2HttpMessageConverter());
    }
}


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

&lt;/div&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%2F73vncstpk358zck8vevt.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%2F73vncstpk358zck8vevt.png" alt="Image description"&gt;&lt;/a&gt;&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%2Fyqr410afl7poewinad5z.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%2Fyqr410afl7poewinad5z.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Código disponível em &lt;a href="https://github.com/marksduarte/spring-boot-admin" rel="noopener noreferrer"&gt;GitHub Marks Duarte&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Por enquanto é só. Até mais! ;)&lt;/p&gt;

</description>
      <category>springboot</category>
      <category>java</category>
      <category>client</category>
      <category>server</category>
    </item>
    <item>
      <title>Como limitar o consumo de memória e processamento do WSL2</title>
      <dc:creator>Marks Duarte</dc:creator>
      <pubDate>Mon, 20 Mar 2023 14:16:35 +0000</pubDate>
      <link>https://forem.com/marksduarte/como-limitar-o-consumo-de-memoria-do-wsl2-1c1i</link>
      <guid>https://forem.com/marksduarte/como-limitar-o-consumo-de-memoria-do-wsl2-1c1i</guid>
      <description>&lt;p&gt;Ao utilizarmos o WSL2 no Windows, por padrão, o consumo de memória e de processamento fica sem restrição e esse comportamento pode acabar afetando o desempenho do Host.&lt;/p&gt;

&lt;p&gt;Para contornarmos tal situação, podemos criar um arquivo de configuração chamado '.wslconfig' na pasta de usuário localizada em: &lt;code&gt;c:\users\&amp;lt;username&amp;gt;\.wslconfig&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora informe as restrições desejadas conforme exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[wsl2]
memory=4GB # limita a memória da VM.
processors=2 # limita o uso da VM para 2 processadores virtuais
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após salvar as alterações, reinicie o serviço executando o seguinte comando como Administrador:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Para mais informações, consulte a documentação em: &lt;a href="https://learn.microsoft.com/pt-br/windows/wsl/wsl-config#wslconfig"&gt;Microsoft&lt;/a&gt;&lt;/p&gt;

</description>
      <category>windows</category>
      <category>wsl2</category>
      <category>linux</category>
    </item>
    <item>
      <title>Como mover os discos virtuais do WSL2</title>
      <dc:creator>Marks Duarte</dc:creator>
      <pubDate>Thu, 16 Mar 2023 20:42:52 +0000</pubDate>
      <link>https://forem.com/marksduarte/movendo-a-distribuicao-linux-do-wsl-para-outro-local-369c</link>
      <guid>https://forem.com/marksduarte/movendo-a-distribuicao-linux-do-wsl-para-outro-local-369c</guid>
      <description>&lt;p&gt;Para quem gosta de manter seus arquivos em partições ou mesmo em discos separados, o Windows não ajuda muito na hora da instalação das distribuições Linux utilizando o WSL, e para fazermos essa migração só precisamos seguir alguns passos bem simples.&lt;/p&gt;

&lt;p&gt;Mas antes, vamos listar as distribuições instaladas para escolhermos quais serão movidas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wsl -l
Distribuições do Subsistema do Windows para Linux:
docker-desktop (Padrão)
Ubuntu-22.04
docker-desktop-data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Agora vamos fazer o processo de exportação da distribuição para um arquivo .tar.&lt;/p&gt;

&lt;p&gt;Depois será necessário remover o registro dessa distribuição do WSL e por fim, reimportar informando o novo local de destino.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wsl --export Ubuntu-22.04 Ubuntu-22.04.tar
wsl --unregister Ubuntu-22.04
wsl --import Ubuntu-22.04 .\path\destino .\Ubuntu-22.04.tar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Atenção: a nova instância será redefinida para o usuário root. Caso tenha criado algum usuário antes, e queira continuar usando o mesmo, faça o seguinte:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd HKCU:\

set-location -path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss\

Get-childitem -recurse -ErrorAction SilentlyContinue | Get-ItemProperty | Where-Object {$_.DistributionName -like "Ubuntu-22.04"} | Set-Itemproperty -Name DefaultUid -Value 1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;E assim finalizamos essa primeira, de muitas, dicas.&lt;/p&gt;

&lt;p&gt;Espero ter ajudado e até a próxima.&lt;/p&gt;

&lt;p&gt;Ops! Já ia me esquecendo... Você também pode usar o script do #PowerShell que fiz para agilizar esse processo. ;)&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



</description>
      <category>wsl2</category>
      <category>windows</category>
      <category>ubuntu</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
