Thursday, 28 November 2019

JUnit 5

JUPITER

Juipter - For newer test cases
Vintage package -- Older
EXT - JAp

Core platform, Jupiter dependecies to be added
junit-jupiter-api
junit-jupiter-engine
junit-vintage-engine //optional for prev versions of junit  ex: junit 4

@Test annotation: It marks the method that we want to test
@Test
    void testDivide() {       
        assertThrows(ArithmeticException.class, () -> mUtils.divide(1, 0), "divide by Zero exception");
     }

assertEquals(expected, actual) // provided by junit framework matches the expected &actual values.
assertArrayEquals(expectedArray, actualArray) //verify each item in array are equal in the right position
assertIterableEquals(expectedArray, actualArray)//verify each item in iterable are equal in the corresponding position
assertFalse()
assertTrue()

Maven Surefire plugin

When a method is throwing exceptions we use : assertThrows

Test Life Cycle:: Project instance created, managed & destroyed
Junit creates new class instance for every method / test run

Junit provides a mechanism which can be run before every test
@BeforeEach to get rid of multiple class instantiation, please run this before anything else
@BeforeEach
    void init() {
        mUtils = new MathUtils();
    }


@AfterEach


    void cleanup() {
        System.out.println("Cleaning up.....");
    }


@BeforeAll, @AfterAll needs to be defined static class level as there could be some methods which would be instantiating objects. Without instantiating if you want to access class these methods have to be static.

@TestInstance

@DisplayName  -> method name how it is displayed in test results
@Disabled ->If we want to some test method from being executed, to prevent it from blocking the program. Skip the test. Make it disabled

Conditional Execution:
@EnabledOnOs(OS>LINUX) -> Enable test on only particular OS.
@EnabledOnJre(JRE.JAVA_11)


assertAll -> Way to run bunch of assertions altogether
@Test
    @DisplayName("Multiple Addition ")
    void testAdd() {
        //Using lambdas multiple assert statements
        assertAll(
                () -> assertEquals(4, mUtils.add(2, 2)),
                () -> assertEquals(2, mUtils.add(2, 0)),
                () -> assertEquals(1, mUtils.add(2, -1))
                );
    }

@Nested -> Create a bunch of tests and group them together
@Nested
    class AddTest {
       
        @Test
        @DisplayName("Multiple Addition ")
        void testAdd() {
            //assertEquals(4, mUtils.add(2, 2),"Addition");
            //Using lambdas multiple assert statements
            assertAll(
                    () -> assertEquals(4, mUtils.add(2, 2)),
                    () -> assertEquals(2, mUtils.add(2, 0)),
                    () -> assertEquals(1, mUtils.add(2, -1))
                    );
        }
        @Test
        @DisplayName("Multiple Addition ")
        void testAddPositive() {
            assertAll(
                    () -> assertEquals(4, mUtils.add(2, 2))
                    );
        }
       
    }

Lazy Assert messages:

Tuesday, 26 November 2019

RabbitMQ

RabbitMQ is one of the most popular open source message brokers. Use the below link to download it.
https://www.rabbitmq.com/download.html
>Click on Windows installer
>Save the exe file. Before installing Rabbitmq, it will prompt us to install Erlang/OTP.

>Enable management center so that you can access the console through browser:
rabbitmq-plugins enable rabbitmq_management

>Url to access RabbitMq console
http://localhost:15672/
guest/guest - default userid & password


Sample Sender:
package rabbitmq;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.nio.charset.StandardCharsets;

public class Sender {

    private final static String QUEUE_NAME = "hello";

    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {
            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
            String message = "Hello World!";
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));
            System.out.println(" [x] Sent '" + message + "'");
        }
    }
}




Sample Receiver:

package rabbitmq;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;

public class Receiver {

    private final static String QUEUE_NAME = "hello";

    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println(" [x] Received '" + message + "'");
        };
        channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });
    }
}




Reference:
https://www.cloudamqp.com/blog/2015-05-18-part1-rabbitmq-for-beginners-what-is-rabbitmq.html

Friday, 27 September 2019

Spring Boot Microservices

Spring Boot Microservices Demonstration:::

Consider we have 3 services which give info about Movie information and user ratings:

1)   Movie Info Service - i/p: MovieID,    o/p:Movie details
2)   Ratings Data Service - i/p:userId,    o/p:MovieId & ratings & i/p:movieId,    o/p:MovieId & ratings
3)   Movie Catalog service - i/p:userId   o/p:Movie list with details(mname, descr, details)

Steps to create individual APIs and their communication::
  • Using "start.spring.io" create 3 Maven web projects.
  • Extract downloaded projects and import them into workspace.
  • Each project will have:                                                                                                                      >A bean to hold data  (Getters, setters, default constructor, parameterized constructor)              >Resource class which will handle input requests. (@RestController, @RequestMapping with get methods)
  • In each project search for application.properties file and assign separate port number for each service. Foe ex: server.port = 8082 //catalog service
  • 3 services are buil independently with some data and can be accessed as:
http://localhost:8082/catalog/ss
http://localhost:8081/movies/ss
http://localhost:8083/ratingsdata/sam
  •  Now we will have to make these servicescommunicate to each other. This can be done by using RestTemplate / WebClient
  • In the movie catalog service we can do below steps
  1. Using userId get the movieId
  2. Using  movieId get the ratings from ratings service.
  3. Using movieId get movie name from movie info services.
Note: These calls are synchronous
  • Since RestTemplateis called everytime we hot the individual webservice url, why can't we make it singleton> This can be achieved by @Bean anootation. In MovieCatalogServiceApplication clss add below code:
@Bean
public RestTemplate getRestTemplate() {
 return new RestTemplate();
}                                                                                                                                    
  •  In the catalog resource class use it as @Autowired
@Autowired
private RestTemplate restTemplate //inject me the bean created by container

*Use Eureka server for service URL registration and discovery.
1) Create Maven project with Eureka server dependency in "start.spring.io" and add it in workspace
   >change properties so that eureka is not client and trying to find any other server
Update application.properties as:
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

2) Register the client by including eureka client in pom.xml and required update project to get spring cloud jar. This service will be registered as client. Do this for all the 3 services.

3) @LoadBalanced -- does service discovery in load balanced way
@LoadBalanced
    public RestTemplate getRestTemplate() {
                return new RestTemplate();
    }
   
The created jars with the deployed paths are as below::

cf push testSam -p ratings-data-service-0.0.1-SNAPSHOT.jar
https://testsam.cfapps.io/ratingsdata/users/sam

cf push testSam -p movie-info-service-0.0.1-SNAPSHOT.jar
https://testsam.cfapps.io/movies/sam

cf push testSam -p discovery-server-0.0.1-SNAPSHOT.jar

cf push testSam -p movie-catalog-service-0.0.1-SNAPSHOT.jar
https://testsam.cfapps.io/catalog/sam - This is the integrated service which calls
http://ratings-data-service/ratingsdata/users/sam
http://movie-info-service/movies/1111

Friday, 6 September 2019

Spring Boot course API

::Welcome to Course API::

Actions to be performed

1) Get All the available topics

2) Get a particular topic from the list
    Java course details
    C++ course details

3) POST, DELETE, PUT operations are included in the below postman project



The relevant screens:


GET

POST

PUT

DELETE