Monday 10 December 2018

default settings.xml

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
      <localRepository/>
      <interactiveMode/>
      <usePluginRegistry/>
      <offline/>
      <pluginGroups/>
      <servers/>
      <mirrors/>
      <proxies/>
      <profiles/>
      <activeProfiles/>
    </settings>

Monday 26 November 2018

Zuul/Eureka configurations

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mrm.inttris.api</groupId>
    <artifactId>ApiRouter</artifactId>
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <jackson.version>2.8.4</jackson.version>
        <commons-lang3.version>3.5</commons-lang3.version>
        <zuul.route.health.version>1.1.0</zuul.route.health.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.1.RELEASE</version>
    </parent>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.version}</version>
        </dependency>

        <dependency>
            <groupId>io.jmnarloch</groupId>
            <artifactId>zuul-route-health-spring-cloud-starter</artifactId>
            <version>${zuul.route.health.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${commons-lang3.version}</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20140107</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <executable>true</executable>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
            <plugin>
                <groupId>pl.project13.maven</groupId>
                <artifactId>git-commit-id-plugin</artifactId>
                <configuration>
                    <generateGitPropertiesFile>true</generateGitPropertiesFile>
                    <failOnNoGitDirectory>false</failOnNoGitDirectory>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>




server:
  port: 8080

management:
    contextPath: /devops
    port : 8280
    info:
        git:
          mode: full

spring:
  application:
    name: ApiRouter

zuul:
  routes:
    APIAUTHSERVICE:
      path: /**/token
      serviceId: APIAUTHSERVICE
      stripPrefix: false

    APIADMINSERVICE:
      path: /**/admin/**
      serviceId: APIADMINSERVICE
      stripPrefix: false

    APIBEHAVIOURSERVICE:
      path: /**/behaviour/**
      serviceId: APIBEHAVIOURSERVICE
      stripPrefix: false

    APIMEALSSERVICE:
      path: /**/meals/**
      serviceId: APIMEALSSERVICE
      stripPrefix: false

  trace-request-body: true
  sensitive-headers: Cookie,Set-Cookie

ribbon:
  ReadTimeout: 60000
  ConnectTimeout: 60000

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 60000

eureka:
  health:
    enable: true
  instance:
    instance-id: ${spring.application.name}:${random.value}
    statusPageUrlPath: ${management.contextPath}/info
    healthCheckUrlPath: ${management.contextPath}/health
    preferIpAddress: true
    leaseRenewalIntervalInSeconds: 3
  client:
    registerWithEureka: true
    fetchRegistry: true
    registryFetchIntervalSeconds: 5
    instanceInfoReplicationIntervalSeconds: 5
    initialInstanceInfoReplicationIntervalSeconds: 5
    serviceUrl:
      defaultZone: http://localhost:8010/eureka

endpoints:
  health:
    sensitive: false

auth:
  hmac:
    validity:
      plusSeconds: 180
      minusSeconds: 120

services:
  apiAuthService:
    id: APIAUTHSERVICE
    URI_TOKEN: /v1/token

info:
   app:
      name: ${spring.application.name}
      encoding: @project.build.sourceEncoding@
      java-version: @java.version@

accessLogValve:
  directory: D:/Logging/${spring.application.name}
  pattern: date time c-ip s-ip s-dns cs-method cs-uri-stem cs-uri-query sc-status bytes time-taken cs(User-Agent) cs(Referer) cs(HOST)
  suffix: .log
  prefix: ex
  rotatable: true
  fileDateFormat: yyMMdd.HH
 
 
  <?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>
                %d{yyyy-MM-dd HH:mm:ss.SSS} %highlight([%level]) [%X{CONSUMER_KEY}] [%class{0}:%line] %msg %ex{3} %n
            </pattern>
        </encoder>
    </appender>

    <logger name="com.rm.integris.api" level="INFO"/>

    <logger name="com.netflix" level="INFO"/>

    <root level="INFO">
        <appender-ref ref="STDOUT"/>
    </root>

</configuration>


Friday 12 October 2018

Sunday 5 August 2018

Spring Boot with Docker

Assuming demo is the project name and navigated into demo folder:

===========================================

Dockerfile (no extension)

FROM openjdk:8-jdk-alpine
VOLUME C:\\temp
ARG JAR_FILE=target/demo-0.0.1-SNAPSHOT.jar
EXPOSE 8080
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

===========================================

mvnw package ==> to build project

docker build -t demo .  ==> to create image
docker image ls
docker run -p 5000:8080 demo  ==> to run image

==========================================

Access instance using : http://localhost:5000/

==========================================

Remove Docker containers and images:
-----------------------------------------------

docker container ls
docker stop <container_id>   ==> To stop container
docker rm <container_id>     ==> to remove container

docker images -a
docker rmi <all image_ids>     ==> to remove image

Friday 3 August 2018

Spring Boot Restful services - req/resp compression (zip)

In Spring Boot :

https://docs.spring.io/spring-boot/docs/1.4.3.RELEASE/reference/html/howto-embedded-servlet-containers.html#how-to-enable-http-response-compression

application.properties
server.compression.enabled=true
#if response if greater than or equal to 2048 bytes
server.compression.min-response-size=2048server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain


#if response if less than 2048 bytes, response looks like this:




==========================================================================
For additional info:
------------------------


To PUT data to the server compressed you must compress the request body and set the Content-Encoding: gzip header. The header itself must be uncompressed. It's documented in mod_deflate:
The mod_deflate module also provides a filter for decompressing a gzip compressed request body. In order to activate this feature you have to insert the DEFLATE filter into the input filter chain using SetInputFilter or AddInputFilter.
...
Now if a request contains a Content-Encoding: gzip header, the body will be automatically decompressed. Few browsers have the ability to gzip request bodies. However, some special applications actually do support request compression, for instance some WebDAV clients.
And an article describing it is here:
So how do you do it? Here is a blurb, again from the mod_deflate source code: only work on main request/no subrequests. This means that the whole body of the request must be gzip compressed if we chose to use this, it is not possible to compress only the part containing the file for example in a multipart request.
Separately, a browser can request server response content to be compressed by setting Accept-Encoding header as per here:
GET /index.html HTTP/1.1
Host: www.http-compression.com
Accept-Encoding: gzip
User-Agent: Firefox/1.0
This will return compressed data to the browser.

Wednesday 1 August 2018

CircuitBreaker/Hystrix - Microservices - Spring Boot

Hystrix

If you have, let’s say 3 services, A calls → B, and B calls → C service. What if, a failure happened at B? The error will cascade down to service C, right?.
A -> B (failure) -> C
Another example, lets say a service A calls a remote service R, and for some reason the remote service is down. How can we handle such a situation?
What we would like to do is stop failures from cascading down, and provide a way to self-heal, which improves the system’s overall resiliency.
Hystrix is the implementation of Circuit Breaker pattern, which gives a control over latency and failure between distributed services.
The main idea is to stop cascading failures by failing fast and recover as soon as possible — Important aspects of fault-tolerant systems that self-heal.
So, we’ll add Hystrix to gallery service, and we’ll simulate a failure at image service. In the pom.xml file
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
In the spring boot main class
// ...@EnableCircuitBreaker      // Enable circuit breakers
public class SpringEurekaGalleryApp {
  public static void main(String[] args) {
    SpringApplication.run(SpringEurekaGalleryApp.class, args);
  }
}
Spring looks for any method annotated with the @HystrixCommandannotation, and wraps that method so that Hystrix can monitor it.
Hystrix watches for failures in that method, and if failures reached a threshold (limit), Hystrix opens the circuit so that subsequent calls will automatically fail. Therefore, and while the circuit is open, Hystrix redirects calls to the fallback method.
So, In the controller class, update getGallery(), add annotation and fallback method.

package com.eureka.gallery.controllers;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.core.env.Environment;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;
import com.eureka.gallery.entities.Gallery;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

@RestController
@RequestMapping("/")public class HomeController {
    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "fallback")
    @RequestMapping("/{id}")
    public Gallery getGallery(@PathVariable final int id) {
        // create gallery object        Gallery gallery = new Gallery();
        gallery.setId(id);

        // get list of available images         @SuppressWarnings("unchecked")    // we'll throw an exception from image service to simulate a failure                List<Object> images = restTemplate.getForObject("http://image-service/images/", List.class);
        gallery.setImages(images);

        return gallery;
    }

    // a fallback method to be called if failure happened    public Gallery fallback(int galleryId, Throwable hystrixCommand) {
        return new Gallery(galleryId);
    }
}
In the controller class of image service, throw an exception in getImages()
throw new Exception("Images can't be fetched");
Now, go to the browser, and hit localhost:8762/gallery/1. You should get an empty gallery object (no images).
{
    "id": 1,
    "images": null
}

Monday 30 July 2018

Redis vs Memcached

One major difference is that Memcache has an upper memory limit at all times, while Redis does not by default (but can be configured to). If you would always like to store a key/value for certain amount of time (and never evict it because of low memory) you want to go with Redis. Of course, you also risk the issue of running out of memory

======================================================================

Memcached is good at being a simple key/value store and is good at doing key => STRING. This makes it really good for session storage.
Redis is good at doing key => SOME_OBJECT.
=======================================================================




Prototype pattern

Prototype pattern can be achieved by deep cloning of an object.

For example:
Problem:
1) I have invoked the DB for an employee details, assign the object to X reference
2) I need one more object of the same employee, we can reuse the X reference, like Employee Y = X;
3) But there is a problem here. If any value is changed in X reference, that will get reflected on Y reference as well.

Problem:
To avoid this, we need to invoke the DB again at step 2, that would be an expensive call.

Solution:
To avoid all these issues, we can go with an Deep Cloning of an Employee object. Hence we are creating a prototype of an X object.

Employee Y = X.clone();

If we use Shallow Cloning, we may not get values of the inner most objects. 
For example, Empoyee ==> Address details.

To achieve this, we need to go with Deep cloning. 

Builder Pattern

We can build the object as per our convenience, 
there is no hard rule to pass certain amount of parameters.

For example, if we have a constructor with 3 parameters, 
and if we need to create an object, 
we need to pass the values to the constructors even if we don't know what is age. 

To avoid it, we can use Builder pattern. 
Where we can build the object based on the values we have.

public class Employee {
    private String empname;
    private String age;
    private String department;

    public String getEmpname() {
        return empname;
    }

    public Employee setEmpname(String empname) {
        this.empname = empname;
        return this;
    }

    public String getAge() {
        return age;
    }

    public Employee setAge(String age) {
        this.age = age;
        return this;
    }

    public String getDepartment() {
        return department;
    }

    public Employee setDepartment(String department) {
        this.department = department;
        return this;
    }
}

public class EmployeeTest {
    public static void main(String[] args) {
        Employee emp = new Employee();
        emp.setAge("10").setDepartment("IT").setEmpname("Doll");

        System.out.println(emp.getDepartment());
    }
}

Friday 27 July 2018

Java 9 - New features

JShell : 
It's an editor where users can quickly test/learn the Java skills.
To test even System.out.println("Hello.."); --> we need to create class, public static void main(String st[]) etc....
We need to know what is Class/String/Object/System classes....
To avoid all these, Java has released JShell, it's an editor, it just allows user to enter print("hello....");
To start jshell, we just need to enter C:/> jshell PRINTING
This command opens editor jshell> 
Now user can just enter jshell>print("hello"); ==> This prints out hello
Can also calculate jshell> 10+20 ==> prints 30
Can also test the operators jshell> 10 > 20 ==> print false.


JPMS (Java Platform Module System):
From Java 9 onwards, JDK has become Modularized.
Till Java 8, Java is completely runs on Jar file approach.
These are few problems till Java 8 (with Jar file approach):
1) NoClassDefNotFoundError Exception
2) Version conflicts
3) Anybody can access jar files code (Security issues)
4) To execute 'hello world' code, we require 400 MB JRE (includes rt.jar) - its completely a monolithic approach
All these issues combinely called "Jar Hell" issue
From Java 9, there is no tools.jar/rt.jar, rt.jar is several modules.
Only required modules we can use at runtime, no need to load the entire rt.jar

JLINK (Java Linker):
It's a tool create our own customized JRE with small size. No need to load complete rt.jar/tools.jar
Till Java8, to execute 'hello world' code, we require 400 MB JRE (includes rt.jar/tools.jar).
By using Java9, we can use only required classes (Class/String/Object/System classes....) we can run "Hello world" code, and create our own JRE.
Once we get our own JRE, we can deploy that JRE and run our small JRE on IOT devices/Micro Chips etc.
To create our own JRE use this command : $ jlink --module-path <modulepath> --add-modules <modules> --limit-modules <modules> --output <path>

HTTP/2 Client:
To send and receive HTTP request/responses we need use Browsers. 
To send HTTP request from Java application we need to use HTTP Client.
Problems with current HTTP class till Java 8:
1) To send HTTP request  we use HttpURLConnection, but this is released in 1997. 
As per the current standards we are still using legacy classes, it's not good for the performances.
2) At a time only one request we can send per TCP/IP connection, if we try to send more requests performance will automatically come down.
3) Supports only for text, not for Binary data.
4) Always works in Blocking mode, Synchronous mode, until we get response client will be in a blocking mode.
HTTP/2 client can fix all the above issues.
1) Can send multiple requests
2) Supports Binary/Text data
3) It supports Synchronous/Asynchronous modes

Process API Updates:
Until Java 8, it's difficult to communication with Processor is very difficult.
To get Processor level data, we need to write huge amount of code. 
With a single line of code we can get Process ID.
To get process id, System.out.println(ProcessHandle.current().pid()); ==> ProcessHandle is included in java.lang package itself. Not required of any imports.
From Java 9 onwards communication with Processor level as become very easy.

Private methods inside 'interfaces' :
This features has been introduced to make a reusable methods inside interface itself.
Until Java 8, we have - default and static methods in interface. 
If there is any common code with in multiple default methods, we can keep those common code inside private method.
Without effecting implementation classes if we want code re-usability we need to go for private methods. 
So that it's not going to impact the implemented classes.

'try' with resources :
Till Java 8, we can use syntax like : 
try(FileWriter fw = new FileWriter("writer.txt"); FileReader fr = new FileReader("reader.txt")){
}

From Java 9 ,we can declare them outside and use references with in try(...).
FileWriter fw = new FileWriter("writer.txt"); 
FileReader fr = new FileReader("reader.txt")
try(fw; fr){
}

Factory methods to create Unmodified collections:
Until Java 8:
List<String> li = new ArrayList<>();
li.add("A");li.add("B");li.add("C");
List<String> unmodif = Collections.unModifiableList(li);

Java 9:
List<String> li = List.of("A","B","C");

Stream  API Enhancements:
Stream we use to process the collection objects.
Few methods added in Java 9:
1) takeWhile() --> Object method
2) dropWhile() --> Object method
3) Stream.iterate() --> static method
4) Stream.ofNullable() --> To check the null values --> static method

<> operator:
Until Java 8, we can declare <> operator for all Classes.
From Java 9, we can use it for Anonymous inner classes: 
example:
List<String> al = new ArrayList<>(){
//This is an annonymous inner class.
};

SafeVarargs Annotation:
Until Java 8:
We can use this annotation for static methods/ final methods/ constructor
From Java 9: 
We can use for private methods also.

Until Java 8:
method(String... st);
methodL(List<String>... li){
// This method will generate "Heap Pollution" WARNINGS.


From Java 9:
If we are sure that Heap Pollution doesn't occur, we can suppress these warnings using an Annotation.
@SafeVarargs
methodL(List<String>... li){
//No warnings now.


G1GC(Garbage First Garbage Collector):
Different Types of Garbage Collectors:
Serial GC
Parallel GC
Concurrent Mark Sweep(CMS) GC
G1 GC -> is introduced in Java 6 itself.

Until Java 8 : 
Default Garbage Collector is 'Parallel GC'

From Java 9:
G1 GC has become the default GarbageCollector. 
Total Heap is divided into multiple regions and G1GC always chooses region which are having highest number of objects eligible for GC, then it clears that region.

Tuesday 24 July 2018

Architect Topics



Continuous Integration (http://java-wcs-development.blogspot.com/2018/07/continuous-integration-ci.html)

Continuous Delivery/Deployment (http://java-wcs-development.blogspot.com/2018/07/continuous-delivery-vs-continuous.html)

Blue Green Deployment (https://www.thoughtworks.com/insights/blog/implementing-blue-green-deployments-aws)

Finally, another way to perform the blue-green switch with Route53 is using Weighted Round-Robin. This works for both regular resource record sets as well as alias resource record sets. You have to associate multiple answers for the same domain/sub-domainand assign a weight between 0-255 to each entry. When processing a DNS query,Route53 will select one answer using a probability calculated based on those weights. To perform the blue-green switch you need to have an existing entry for the current “blue” environment with weight 255 and a new entry for the “green” environment with weight 0. Then, simply swap those weights to redirect traffic from blue to green.






Continuous Integration (CI)

Continuous Integration (CI) is a development practice that requires developers to integrate code into a shared repository several times a day. Each check-in is then verified by an automated build, allowing teams to detect problems early.

By integrating regularly, you can detect errors quickly, and locate them more easily.

Continuous Integration doesn’t get rid of bugs, but it does make them dramatically easier to find and remove. — Martin Fowler, Chief Scientist, ThoughtWorks

Team responsibilities:
==================
Check in frequently
Don’t check in broken code
Don’t check in untested code
Don’t check in when the build is broken
Don’t go home after checking in until the system builds

Continuous Delivery vs Continuous Deployment

Puppet/GoCD/Bamboo/Jenkins


While continuous deployment may not be right for every company, continuous delivery is an absolute requirement of DevOps practices. Only when you continuously deliver your code can you have true confidence that your changes will be serving value to your customers within minutes of pushing the "go" button, and that you can actually push that button any time the business is ready for it.

Thursday 19 July 2018

AWS - Scripts to execute while creating the EC2 instance


#!/bin/bash
yum install httpd -y
yum update -y
aws s3 cp s3://bucketname/index.html /var/www/html/
service httpd start
chkconfig httpd on

Monday 16 July 2018

java enum vs interface vs class constants

public enum EnumEx {

    MALE("male"),FEMALE("");
    private String value;

    EnumEx(String value){
        this.value = value;
    };

    public String value() {
        return value;
    }
}


public class TestEx {
    public static void main(String[] args) {
        System.out.println(EnumEx.MALE.value()); // custom method value()
        System.out.println(EnumEx.MALE.name()); // predefined method name()
    }
}

output:

male
MALE

=============================================

Can avoid using:

public interface Constants{
  String MALE = "male";
  .....
}

Enum by default is Singleton and it's threadsafe.

Thursday 5 July 2018

AWS - Generate signed url for S3 objects

package com;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.HttpMethod;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicSessionCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;

import java.io.IOException;
import java.net.URL;

public class GeneratePresignedURL {

    private static BasicSessionCredentials sessionCredentials;

    public static void main(String[] args) throws IOException {
        String clientRegion = "us-east-1";
        String bucketName = "bucketname";
        String objectKey = "CloudServices.png";

        String AccessKeyID = "ASIAIPORVHUBITG7";
        String SecretAccessKey = "WYOrynMz20B5ORHpu9f/m+ufH2t4+fkTjnb";
        String SessionToken = "XdzEIj//////////wEaDBx8AUTyX+PoMuFXUiLrARdFmJCz0ffbywapf9EPCzmy960mugqjVfy1uSoN4+iaSn/GjdE0x5kDGJ330foAe2XxvkbjVzpl4CN7ui6Z/oOiJC25H5/Y3vrV9qmDT/5MoT/CVnUz8vcxGtoDF/UyR5znoy5BlyqkagCaB/RmO6MdzTf9bqh4lPqU8ASn4yQ0YlVdQGvQvDZtsts0hits2pPdvwXKGOmX5zENFTscldFA1fCGK2fOmJp+UbaU+C7KzSNq4io48VdPEYBqSQZxl4W9ZIcdSkrVSzq7q17LCkpB6fVg6bSqmN/0Q3Ej0o0CfLhdIwiEMcfhH2wo4/b22QU=";

        try {

            sessionCredentials = new BasicSessionCredentials(AccessKeyID, SecretAccessKey, SessionToken);

            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withRegion(clientRegion)
                    .withCredentials(new AWSStaticCredentialsProvider(sessionCredentials))
                    .build();


            // Set the presigned URL to expire after one hour.            java.util.Date expiration = new java.util.Date();
            long expTimeMillis = expiration.getTime();
            expTimeMillis += 1000 * 60 * 60;
            expiration.setTime(expTimeMillis);

            // Generate the presigned URL.            System.out.println("Generating pre-signed URL.");
            GeneratePresignedUrlRequest generatePresignedUrlRequest =
                    new GeneratePresignedUrlRequest(bucketName, objectKey)
                            .withMethod(HttpMethod.GET)
                            .withExpiration(expiration);
            URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);

            System.out.println("Pre-Signed URL: " + url.toString());
        }
        catch(AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process            // it, so it returned an error response.            e.printStackTrace();
        }
        catch(SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client            // couldn't parse the response from Amazon S3.            e.printStackTrace();
        }
    }
}


output:

https://bucketname.s3.amazonaws.com/CloudServices.png?
X-Amz-Security-Token=XdzEIj//////////wEaDBx8AUTyX+PoMuFXUiLrARdFmJCz0ffbywapf9EPCzmy960mugqjVfy1uSoN4+iaSn/GjdE0x5kDGJ330foAe2XxvkbjVzpl4CN7ui6Z/oOiJC25H5/Y3vrV9qmDT/5MoT/CVnUz8vcxGtoDF/UyR5znoy5BlyqkagCaB/RmO6MdzTf9bqh4lPqU8ASn4yQ0YlVdQGvQvDZtsts0hits2pPdvwXKGOmX5zENFTscldFA1fCGK2fOmJp+UbaU+C7KzSNq4io48VdPEYBqSQZxl4W9ZIcdSkrVSzq7q17LCkpB6fVg6bSqmN/0Q3Ej0o0CfLhdIwiEMcfhH2wo4/b22QU=
&X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Date=20180705T064708Z
&X-Amz-SignedHeaders=host
&X-Amz-Expires=3599
&X-Amz-Credential=ASIAIPORVHUBITG7%2F20180705%2Fus-east-1%2Fs3%2Faws4_request
&X-Amz-Signature=39a033db5db1acd7ce579c7cf66adf3b14117676834345a0acdfa0fd1c42c364