<?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: Gyowanny (Geo) Queiroz</title>
    <description>The latest articles on DEV Community by Gyowanny (Geo) Queiroz (@gyohub).</description>
    <link>https://dev.to/gyohub</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%2F825415%2F0ab008c5-01ce-4586-80b3-29d481965cc4.png</url>
      <title>DEV Community: Gyowanny (Geo) Queiroz</title>
      <link>https://dev.to/gyohub</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gyohub"/>
    <language>en</language>
    <item>
      <title>Using LocalStack in your Java Project - Part 1</title>
      <dc:creator>Gyowanny (Geo) Queiroz</dc:creator>
      <pubDate>Thu, 29 Feb 2024 23:58:34 +0000</pubDate>
      <link>https://dev.to/gyohub/using-localstack-in-your-java-project-part-1-3984</link>
      <guid>https://dev.to/gyohub/using-localstack-in-your-java-project-part-1-3984</guid>
      <description>&lt;p&gt;I've been away from the Java world for a while, but I recently helped an old friend with a payment gateway project that required integration with certain AWS services. Unfortunately, the DevOps team didn't provide him with a test account in time to meet his deadline. To solve this issue, we decided to try &lt;a href="https://github.com/localstack/localstack" rel="noopener noreferrer"&gt;LocalStack&lt;/a&gt; and we were pleasantly surprised by how easy it was to set up and use. &lt;br&gt;
Our mission was to use &lt;a href="https://aws.amazon.com/sqs/" rel="noopener noreferrer"&gt;SQS&lt;/a&gt; for payment processing logic to publish and consume messages asynchronously within the payment journey.&lt;br&gt;
In this post I will show you how we configured, used and tested the code with LocalStack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;First of all, make sure you have Docker installed.&lt;/p&gt;

&lt;p&gt;The project uses Spring Boot 3 with Maven, so the required dependencies are:&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;io.awspring.cloud&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;spring-cloud-aws-starter&amp;lt;/artifactId&amp;gt;
    &amp;lt;/dependency&amp;gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;io.awspring.cloud&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;spring-cloud-aws-starter-sqs&amp;lt;/artifactId&amp;gt;
    &amp;lt;/dependency&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;A Spring configuration class was created to set things up&lt;/p&gt;

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

@Configuration
@Slf4j // Using Lombok
public class AwsSqsLocalstackConfiguration {
  @Value("${spring.cloud.aws.credentials.access-key}")
  protected String awsAccessKey;

  @Value("${spring.cloud.aws.credentials.secret-key}")
  protected String awsSecretKey;

  @Value("${spring.cloud.aws.region.static:us-east-1}")
  protected String awsRegion;

  protected AwsCredentialsProvider amazonAWSCredentialsProvider() {
    return StaticCredentialsProvider.create(AwsBasicCredentials.create(awsAccessKey, awsSecretKey));
  }

  static LocalStackContainer localStack =
      new LocalStackContainer(DockerImageName.parse("localstack/localstack"));

  @Bean
  @Primary
  SqsAsyncClient sqsClient() {
    //startLocalStack();
    localStack.start();
    return SqsAsyncClient.builder()
        .endpointOverride(URI.create(localStack.getEndpointOverride(SQS).toString()))
        .credentialsProvider(amazonAWSCredentialsProvider()).region(Region.of(awsRegion)).build();
  }

  @Bean
  SqsTemplate sqsTemplate(SqsAsyncClient sqsAsyncClient) {
    return SqsTemplate.builder().sqsAsyncClient(sqsAsyncClient).build();
  }

  // Telling SQSListener to use object mapper for obj serialization.
  @Bean
  SqsListenerConfigurer configurer(ObjectMapper objectMapper) {
    return registrar -&amp;gt; registrar.setObjectMapper(objectMapper);
  }
}


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

&lt;/div&gt;

&lt;p&gt;To save time and initialize LocalStack with queues, simply add the following code to the configuration class above. Otherwise, you can execute shell commands directly in the container to add it manually.&lt;/p&gt;

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

  @Autowired
  private LocalstackQueues localstackQeues;

  private void startLocalStack() {
    localStack.start();
    // Creating the queues
    localstackQeues.queues().forEach(queue -&amp;gt; {
      try {
        localStack.execInContainer("awslocal", "sqs", "create-queue", "--queue-name", queue);
        log.info("Queue {} created", queue);
      } catch (IOException e) {
        throw new RuntimeException(e);
      } catch (InterruptedException e) {
        throw new RuntimeException(e);
      }
    });
    log.info("LOCALSTACK RUNNING AT {}", localStack.getEndpointOverride(SQS).toString());
  }

  // Add the queues in your application.yml e.g.
  // localstack:
  //   queues:
  //     - my.queue.1
  //     - my.queue.2  
  @Component
  @ConfigurationProperties(prefix = "localstack.queues")
  record LocalstackQueues(List&amp;lt;String&amp;gt; queues) {

  }


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

&lt;/div&gt;

&lt;p&gt;Ensure that LocalStack's Docker container is running without any errors during initialization by executing your Spring Boot application.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Docker desktop&lt;/code&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%2Finzeb157vm5yoxo9zidq.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%2Finzeb157vm5yoxo9zidq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stay tuned for part 2, where we'll write both an SQS Publisher and an SQS Listener. And make no mistake, part 3 will show you how to write tests with LocalStack.&lt;/p&gt;

</description>
      <category>java</category>
      <category>springboot</category>
      <category>localstack</category>
      <category>aws</category>
    </item>
    <item>
      <title>Mock constants in Ruby tests</title>
      <dc:creator>Gyowanny (Geo) Queiroz</dc:creator>
      <pubDate>Thu, 23 Jun 2022 14:41:44 +0000</pubDate>
      <link>https://dev.to/gyohub/mock-constants-in-ruby-tests-31ee</link>
      <guid>https://dev.to/gyohub/mock-constants-in-ruby-tests-31ee</guid>
      <description>&lt;p&gt;Here's a quick and dirty way to mock class constants in unit tests without using any gems.&lt;/p&gt;

&lt;p&gt;Given this class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module Query
   class Paginator
     PAGE_SIZE = 1000

     def paginate(page:)
         offset = if page &amp;gt; 1
           per_page * (page.to_i - 1)
         else
           0
         end
         Person.order(:created_at)
               .offset(offset)
               .limit(PAGE_SIZE)
     end
   end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Given PAGE_SIZE is set to 1000 records, I think it's a bit of a lift to run a test with that much records so why not set the constant with a lower value in our tests?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module Query
   class PaginatorTest &amp;lt; ActiveSupport::TestCase
     setup do
        # We change the constant value
        Query::Paginator.send(:const_set, 'PAGE_SIZE', 1)
     end

     teardown do
       # We restore the original value to avoid issues with other tests
       Query::Paginator.send(:remove_const, "PAGE_SIZE")   
     end

     ...
   end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can set and unset the constant value in the test case body as well.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>test</category>
      <category>minitest</category>
    </item>
    <item>
      <title>Display current folder + git branch in the macOS terminal prompt</title>
      <dc:creator>Gyowanny (Geo) Queiroz</dc:creator>
      <pubDate>Mon, 11 Apr 2022 18:12:51 +0000</pubDate>
      <link>https://dev.to/gyohub/display-current-folder-git-branch-in-the-macos-terminal-prompt-305b</link>
      <guid>https://dev.to/gyohub/display-current-folder-git-branch-in-the-macos-terminal-prompt-305b</guid>
      <description>&lt;p&gt;Tested on macOS Monterey 12.3.1 &lt;/p&gt;

&lt;p&gt;Add the snippet below to the bottom of the file according to your terminal version.&lt;/p&gt;

&lt;h3&gt;
  
  
  iTerm
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;~/.bash_profile&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Terminal
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;~/.zshrc&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Git branch in prompt.

function parse_git_branch() {
    git branch 2&amp;gt; /dev/null | sed -n -e 's/^\* \(.*\)/[\1]/p'
}

setopt PROMPT_SUBST
export PROMPT='%F{grey}%n%f %F{cyan}%~%f %F{green}$(parse_git_branch)%f %F{normal}$%f '
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxpgav2viueg8us0ygvv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxpgav2viueg8us0ygvv.png" alt="Image description" width="800" height="30"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Add custom CSS to Rails app with Bootstrap</title>
      <dc:creator>Gyowanny (Geo) Queiroz</dc:creator>
      <pubDate>Fri, 04 Mar 2022 14:30:13 +0000</pubDate>
      <link>https://dev.to/gyohub/add-custom-css-to-rails-app-with-bootstrap-5emm</link>
      <guid>https://dev.to/gyohub/add-custom-css-to-rails-app-with-bootstrap-5emm</guid>
      <description>&lt;h3&gt;
  
  
  Quick Rails tip for beginners
&lt;/h3&gt;

&lt;p&gt;I'm using Rails 7 with Bootstrap 5. &lt;a href="https://www.bootrails.com/blog/rails-7-bootstrap-5-tutorial/"&gt;Here's a nice tutorial&lt;/a&gt; on how to generate a Rails 7 app with Bootstrap 5.&lt;/p&gt;

&lt;p&gt;Say that you want to add custom CSS files in your Rails app. Here are the steps that worked for me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Place your CSS file in &lt;code&gt;app/assets/stylesheets&lt;/code&gt; folder&lt;/li&gt;
&lt;li&gt;Reference the file in &lt;code&gt;app/assets/stylesheets/application.bootstrap.scss&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//= link_tree ../images
//= link_tree ../builds
//= link my_custom.css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now you have to put the following line inside the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag in the &lt;code&gt;app/layouts/application.html.erb&lt;/code&gt; :
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;%= stylesheet_link_tag "navbar", media: 'all', 'data-turbolinks-track' =&amp;gt; true %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it. You don't even need to restart the server jut refresh the page. If you want to make sure the CSS file has been recognized/loaded, you can inspect the page and look for the loaded resources.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I'm learning Rails as I go so improvement suggestions are welcomed&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>webdev</category>
      <category>bootstrap</category>
    </item>
  </channel>
</rss>
