<?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: irena-sayv</title>
    <description>The latest articles on DEV Community by irena-sayv (@irenasayv).</description>
    <link>https://dev.to/irenasayv</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%2F643685%2F77e1ab47-e7b4-441d-a289-fd620f0300e6.png</url>
      <title>DEV Community: irena-sayv</title>
      <link>https://dev.to/irenasayv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/irenasayv"/>
    <language>en</language>
    <item>
      <title>Spring Bean annotation: What, How, and Why?</title>
      <dc:creator>irena-sayv</dc:creator>
      <pubDate>Sun, 18 Dec 2022 18:39:23 +0000</pubDate>
      <link>https://dev.to/irenasayv/spring-bean-annotation-what-how-and-why-3a23</link>
      <guid>https://dev.to/irenasayv/spring-bean-annotation-what-how-and-why-3a23</guid>
      <description>&lt;p&gt;@Bean is a method-level annotation that is used to create a spring managed bean. The object returned from the annotated method is registered as a bean in the Spring container. To simplify understanding, bean annotation is analogous to  definition in XML configuration. In this blog, we will cover a basic understanding of @Bean with code examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to create a bean using @Bean?
&lt;/h2&gt;

&lt;p&gt;Bean annotated methods are generally placed in a @Configuration annotated class. During bootstrap, Spring reads the bean definition from the @Configuration class, and instantiates and initializes the bean. Bean definition methods can also be declared within a plain class or @Component annotated class but the processing of beans is different. We will touch base upon this concept a little later (See section — Bean Lite mode).&lt;/p&gt;

&lt;p&gt;By default, the name of the method is the name of the created bean. You can give a custom name by using the name property of @Bean&lt;br&gt;
&lt;/p&gt;

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

public String getEmployeeName(String employeeCode) {
  // logic to return employee name based on employeeCode
 }
}
@Configuration
public class ApplicationConfig {

 @Bean(name = "customEmployeeService")
 public EmployeeService employeeServiceBean() {
  return new EmployeeService();
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here ApplicationConfig is a configuration class where we have provided definition for customEmployeeService bean&lt;/p&gt;

&lt;p&gt;To use this bean, we can either&lt;/p&gt;

&lt;p&gt;a) get the instance of the bean using the getBean method of ApplicationContext and use it in the consumer class&lt;/p&gt;

&lt;p&gt;b) auto-wire it in the consumer class using @Autowire&lt;/p&gt;

&lt;h2&gt;
  
  
  Bean dependencies
&lt;/h2&gt;

&lt;p&gt;Suppose EmployeeService has a dependency on EmployeeDao type. This is called inter-bean dependency which can be fulfilled through constructor injection or setter injection by directly invoking the bean method of the dependency in the dependent bean method.&lt;/p&gt;

&lt;p&gt;Let's modify EmployeeService to include a constructor&lt;br&gt;
&lt;/p&gt;

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

  public String getEmployeeName(String employeeCode) {
  // code to fetch employee name from databse and return from this method
 }
}

public class EmployeeService {

 private EmployeeDao employeeDao;

 public EmployeeService(EmployeeDao employeeDao) {
  this.employeeDao = employeeDao;
 }

 public String getEmployeeName(String employeeCode) {
  return employeeDao.getEmployeeName(employeeCode);
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we define a bean of type EmployeeDao in ApplicationConfig and inject it in EmployeeService by calling the employeeDao() method in EmployeeService constructor&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Configuration
public class ApplicationConfig {

 @Bean
 public EmployeeDao employeeDao() {
  return new EmployeeDao();
 }

 @Bean(name = "customEmployeeBean")
 public EmployeeService employeeServiceBean() {
  return new EmployeeService(employeeDao());
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Bean Lite mode
&lt;/h2&gt;

&lt;p&gt;When a bean method is declared in a non @Configuration class — a @Component annotated class or even a plain class, the bean is said to be processed in ‘lite’ mode (‘full’ mode is when the method is declared within a @Configuration annotated class). The bean is still added to the context by component scan but the @Bean method simply acts as a factory method.&lt;/p&gt;

&lt;p&gt;In the full mode example that we discussed in the Bean dependencies section, we declared inter-bean dependency in one @Bean method by calling another @Bean method. In lite mode, @Bean methods can not declare inter-dependencies. Invoking another @Bean method does not return the bean from the context, rather it is a normal java method invocation that returns a new instance.&lt;/p&gt;

&lt;p&gt;The following code blocks illustrate the comparison between the full mode and lite mode of bean processing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Configuration
public class ApplicationConfig {

 @Bean
 public EmployeeDao employeeDao() {
  System.out.println("Creating employeeDao bean");
  return new EmployeeDao();
 }

 @Bean(name = "customEmployeeBean")
 public EmployeeService employeeServiceBean() {
  return new EmployeeService(employeeDao());
 }
}


public class Application {

 public static void main(String[] args) {

  ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
  EmployeeService employeeService1 = context.getBean(EmployeeService.class);
  EmployeeService employeeService2 = context.getBean(EmployeeService.class);

 }
}

Output:
Creating employeeDao bean
&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;@Component
public class ApplicationConfig {

 @Bean
 public EmployeeDao employeeDao() {
  System.out.println("Creating employeeDao bean");
  return new EmployeeDao();
 }

 @Bean(name = "customEmployeeBean")
 public EmployeeService employeeServiceBean() {
  return new EmployeeService(employeeDao());
 }
}

public class Application {

 public static void main(String[] args) {

  ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
  EmployeeService employeeService1 = context.getBean(EmployeeService.class);
  EmployeeService employeeService2 = context.getBean(EmployeeService.class);

 }
}

Output:
Creating employeeDao bean
Creating employeeDao bean
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why do we need @Bean when there is @Component?
&lt;/h2&gt;

&lt;p&gt;In the above example, we created a @Configuration annotated class and manually defined our bean with @Bean. Why? We could have just annotated EmployeeService class with @Component (or @Service annotation to be more specific) for Spring to auto-detect and auto-configure it&lt;/p&gt;

&lt;p&gt;@Bean can be used to create a bean of a class that is outside of the Spring container, which can be the case when the class is part of a library and you can not edit source code to add @Component annotation&lt;/p&gt;

&lt;p&gt;@Bean also allows you to customize the instance before being used. For example, a RestTemplate configured with a custom timeout configuration to be used across the Spring boot application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Configuration
public class ApplicationConfig {

 @Bean
    public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) 
    {
        return restTemplateBuilder
           .setConnectTimeout(Duration.ofSeconds(5))
           .setReadTimeout(Duration.ofSeconds(5))
           .build();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hope this article helped to get a basic understanding of @Bean and how and when it can be used.&lt;/p&gt;

</description>
      <category>beanlitemode</category>
      <category>beanvscomponent</category>
      <category>springbeanannotation</category>
      <category>springbean</category>
    </item>
    <item>
      <title>Google Cloud Monitoring: Monitoring and Alerting on number of kubernetes pod replicas in GKE</title>
      <dc:creator>irena-sayv</dc:creator>
      <pubDate>Mon, 07 Mar 2022 18:36:04 +0000</pubDate>
      <link>https://dev.to/irenasayv/google-cloud-monitoring-monitoring-and-alerting-on-number-of-pod-replicas-in-gke-3lnp</link>
      <guid>https://dev.to/irenasayv/google-cloud-monitoring-monitoring-and-alerting-on-number-of-pod-replicas-in-gke-3lnp</guid>
      <description>&lt;p&gt;Monitoring and Alerting is critical for operations and cost management of business applications.&lt;/p&gt;

&lt;p&gt;As part of the Operations team, we were required to create a mechanism to get automated alerts when the pod replicas for a deployment goes down the expected number or a pod is not available for a business critical deployment, or when the count of pod replicas goes up beyond the expected number pointing towards unusual traffic.&lt;/p&gt;

&lt;p&gt;There is no built-in metric available for getting the count of replicas for a Kubernetes Pod in Cloud Monitoring. In this blog, we will look at how we can enable alerting policy based on the pod replicas count.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using container/uptime metric
&lt;/h2&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%2F977atfgswxwncnpw0hcw.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%2F977atfgswxwncnpw0hcw.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Containers are encapsulated in a Pod. We can leverage container Uptime metric for determining the count of pod replicas with below configurations&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%2Fdq8noax84m56qmqfha8x.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%2Fdq8noax84m56qmqfha8x.png" alt="Alert policy configuration for pod replicas count"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We have used resource label container_name along with the cluster name in Filter, you may need additional filters such as namespace to identify a container. The Aggregate function 'count' reduces the multiple timeseries data to a single value giving us the count of containers that are up at the given time&lt;/p&gt;

&lt;p&gt;Here, sum is used as Aligner, but any of the available aligner options can be used as we do not care about the intermediate value&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%2F2lsj9f6x41oscwmt6zww.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%2F2lsj9f6x41oscwmt6zww.png" alt="Alert policy configuration for pod replicas count"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Policy Conditions
&lt;/h4&gt;

&lt;p&gt;Condition for checking when number of containers is below 5&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%2Frtlqb4ihnctsqi4bytki.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%2Frtlqb4ihnctsqi4bytki.png" alt="Alert policy configuration for pod replicas count"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There will be no record for a container when it is not up. So we need an additional condition that will trigger an alert if a container is missing in the metric output&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%2Fdmevsoa0usz3z45bovt9.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%2Fdmevsoa0usz3z45bovt9.png" alt="Alert policy configuration for pod replicas count"&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%2Fe1wqrvuwuvf0qyoxls31.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%2Fe1wqrvuwuvf0qyoxls31.png" alt="Alert policy configuration for pod replicas count"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An alert is triggered when any of the above conditions is met&lt;/p&gt;

</description>
      <category>googlecloudmonitoring</category>
      <category>count</category>
      <category>podreplicas</category>
      <category>alerting</category>
    </item>
    <item>
      <title>Move files from Google Cloud Storage to Azure Blob Storage programmatically</title>
      <dc:creator>irena-sayv</dc:creator>
      <pubDate>Fri, 04 Jun 2021 18:59:15 +0000</pubDate>
      <link>https://dev.to/irenasayv/move-files-from-google-cloud-storage-to-azure-blob-storage-programmatically-591n</link>
      <guid>https://dev.to/irenasayv/move-files-from-google-cloud-storage-to-azure-blob-storage-programmatically-591n</guid>
      <description>&lt;p&gt;Copying files from Google Cloud Storage to Azure Blob Storage programmatically can be achieved by streaming the data directly from cloud storage to blob storage. We will be using google cloud storage and azure storage client libraries for java in this blog.&lt;/p&gt;

&lt;p&gt;Streaming allows to transfer the data without requiring the file to be saved first. Saving the entire file in memory and then writing it to the destination can exhaust the memory leading to OutOfMemoryError if the file is large. Instead, we will iterate through and read some bytes at a time, do some processing and clear them.&lt;/p&gt;

&lt;h3&gt;
  
  
  ReadChannel
&lt;/h3&gt;

&lt;p&gt;ReadChannel, extended from java.nio.channels.ReadableByteChannel, is a reading channel for reading object’s content. Cloud storage client library comes with a reader method which returns ReadChannel to read blob’s content&lt;/p&gt;

&lt;h3&gt;
  
  
  BlobOutputStream
&lt;/h3&gt;

&lt;p&gt;BlobOutputStream is a stream for writing into azure blob storage. It is extended from java.io.OutputStream&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Maven dependencies&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;&amp;lt;dependency&amp;gt;&lt;br&gt;
&amp;lt;groupId&amp;gt;com.google.cloud&amp;lt;/groupId&amp;gt;&lt;br&gt;
&amp;lt;artifactId&amp;gt;google-cloud-storage&amp;lt;/artifactId&amp;gt;&lt;br&gt;
&amp;lt;version&amp;gt;1.70.0&amp;lt;/version&amp;gt;&lt;br&gt;
&amp;lt;/dependency&amp;gt;&lt;br&gt;
&amp;lt;dependency&amp;gt;&lt;br&gt;
&amp;lt;groupId&amp;gt;com.microsoft.azure&amp;lt;/groupId&amp;gt;&lt;br&gt;
&amp;lt;artifactId&amp;gt;azure-storage&amp;lt;/artifactId&amp;gt;&lt;br&gt;
&amp;lt;version&amp;gt;8.4.0&amp;lt;/version&amp;gt;&lt;br&gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;br&gt;
(keyvault and azure active directory dependencies will be required for retrieving sas token)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get Storage service object&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;StorageOptions options = StorageOptions.newBuilder().setProjectId(projectId).setCredentials(GoogleCredentials.fromStream(new FileInputStream(jsonKeyPath))).build();&lt;br&gt;
Storage storage = options.getService();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get CloudBlockBlob instance&lt;/strong&gt;&lt;br&gt;
// assuming sas token is retrieved from Azure keyVault&lt;br&gt;
&lt;code&gt;CloudBlockBlob cloudBlob = new CloudBlockBlob(new URI(contentUri + sasToken));&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stream data&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;try (ReadChannel reader = storage.reader(bucketName, blobPath);&lt;br&gt;
BlobOutputStream outputStream = blob.openOutputStream()) {&lt;br&gt;
ByteBuffer bytes = ByteBuffer.allocate(64 * 1024);&lt;br&gt;
while (reader.read(bytes) &amp;gt; 0) {&lt;br&gt;
bytes.flip();&lt;br&gt;
outputStream.write(bytes.array());&lt;br&gt;
bytes.clear();&lt;br&gt;
}&lt;br&gt;
} catch (Exception e) {&lt;br&gt;
// handle&lt;br&gt;
}&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

</description>
      <category>azureblobstorage</category>
      <category>googlecloudstorage</category>
      <category>file</category>
      <category>movedata</category>
    </item>
  </channel>
</rss>
