Integration tests

Integration tests are checking if your microservices are communicating properly and they are doing their job fine. That means during this type of testing your code is communicating with microservices running on JLupin Platform. It is including using built-in load balancers and all other JLupin Platform features. This is making integration tests similar as possible to system running on production. Test class will call service running on JLupin Platform as an outer client.

Figure 1. Test client calling microservice.

Example integration test with implementation is shown below:

example-b

Service interface:

package com.example.service.interfaces;

public interface BService {
    String callB(String input);
}

Service implementation:

package com.example.service.impl;

import com.example.service.interfaces.BService;
import org.springframework.stereotype.Service;

@Service(value = "bService")
public class BServiceImpl implements BService {
    @Override
    public String callB(String input) {
        return "[called B]" + input;
    }
}

Spring configuration file:

package com.example.configuration;

import com.jlupin.impl.client.util.JLupinClientUtil;
import com.jlupin.interfaces.client.delegator.JLupinDelegator;
import com.jlupin.interfaces.common.enums.PortType;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;

@Configuration
@ComponentScan("com.example")
public class ExampleBSpringConfiguration {
    @Bean
    public JLupinDelegator getJLupinDelegator() {
        return JLupinClientUtil.generateInnerMicroserviceLoadBalancerDelegator(PortType.JLRMC);
    }

    @Bean(name = "jLupinRegularExpressionToRemotelyEnabled")
    public List getRemotelyBeanList() {
        List<String> list = new ArrayList<>();
        list.add("bService");
        // list.add("<REMOTE_SERVICE_NAME>");
        return list;
    }
}

JLupin Platform configuration file:

package com.example.configuration;

import com.jlupin.impl.container.application.spring.JLupinAbstractSpringApplicationContainer;
import com.jlupin.interfaces.configuration.microservice.container.application.JLupinAbstractApplicationContainerProducer;
import com.jlupin.interfaces.container.application.JLupinApplicationContainer;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;

public class ExampleBJLupinConfiguration extends JLupinAbstractApplicationContainerProducer {
    @Override
    public JLupinApplicationContainer produceJLupinApplicationContainer() {
        return new JLupinAbstractSpringApplicationContainer() {
            @Override
            public AbstractApplicationContext getAbstractApplicationContext() {
                return new AnnotationConfigApplicationContext(ExampleBSpringConfiguration.class);
            }
        };
    }
}

To deploy above microservice just go to automatic or manual deploy chapter.

example-a

Service interface:

package com.example.service.interfaces;


public interface AService {
    String callA(String input);
}

Service implementation:

package com.example.service.impl;

import com.example.service.interfaces.AService;
import com.example.service.interfaces.BService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service(value = "aService")
public class AServiceImpl implements AService {
    @Autowired
    private BService bService;

    @Override
    public String callA(String input) {
        return "[called A]" + bService.callB(input);
    }
}

Spring configuration file:

package com.example.configuration;

import com.example.service.interfaces.BService;
import com.jlupin.impl.client.util.JLupinClientUtil;
import com.jlupin.interfaces.client.delegator.JLupinDelegator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;

@Configuration
@ComponentScan("com.example")
public class ExampleASpringConfiguration {

    @Bean
    public JLupinDelegator getJLupinDelegator() {
        return JLupinClientUtil.generateInnerMicroserviceLoadBalancerDelegator(PortType.JLRMC);
    }
    @Bean(name = "bService")
    public BService getExampleService() {
        return JLupinClientUtil.generateRemote(getJLupinDelegator(), "example-b", "bService", BService.class);
    }

    @Bean(name = "jLupinRegularExpressionToRemotelyEnabled")
    public List getRemotelyBeanList() {
        List<String> list = new ArrayList<>();
        list.add("aService");
        // list.add("<REMOTE_SERVICE_NAME>");
        return list;
    }
}

JLupin Platform configuration file:

package com.example.configuration;

import com.jlupin.impl.container.application.spring.JLupinAbstractSpringApplicationContainer;
import com.jlupin.interfaces.configuration.microservice.container.application.JLupinAbstractApplicationContainerProducer;
import com.jlupin.interfaces.container.application.JLupinApplicationContainer;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;

public class ExampleAJLupinConfiguration extends JLupinAbstractApplicationContainerProducer {
    @Override
    public JLupinApplicationContainer produceJLupinApplicationContainer() {
        return new JLupinAbstractSpringApplicationContainer() {
            @Override
            public AbstractApplicationContext getAbstractApplicationContext() {
                return new AnnotationConfigApplicationContext(ExampleASpringConfiguration.class);
            }
        };
    }
}

To deploy above microservice just go to automatic or manual deploy chapter.

integration-test

At first create base class for tests where you will provide servers where microservice is deployed for testing:

package com.example.base;

import com.jlupin.common.communication.common.various.JLupinMainServerInZoneConfiguration;
import com.jlupin.impl.client.util.JLupinClientUtil;
import com.jlupin.impl.logger.impl.log4j.JLupinLoggerOverLog4jImpl;
import com.jlupin.impl.serialize.JLupinFSTSerializerImpl;
import com.jlupin.interfaces.client.delegator.JLupinDelegator;
import com.jlupin.interfaces.common.enums.PortType;
import com.jlupin.interfaces.logger.JLupinLogger;
import com.jlupin.interfaces.serialize.JLupinSerializer;
import org.junit.Before;

public abstract class BaseTest {
    private final JLupinDelegator jLupinDelegator;

    public BaseTest() {
        jLupinDelegator = JLupinClientUtil.generateOuterMicroserviceLoadBalancerDelegator(
                PortType.JLRMC,
                new JLupinMainServerInZoneConfiguration[]{
                        new JLupinMainServerInZoneConfiguration("NODE_1", "127.0.0.1", 9090, 9095, 9096, 9097)
                }
        );
    }

    public JLupinDelegator getJLupinDelegator() {
        return jLupinDelegator;
    }
}

Now you can define your microservice test:

package com.example;

import com.example.base.BaseTest;
import com.example.service.interfaces.AService;
import com.jlupin.impl.client.util.JLupinClientUtil;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class ExampleATest extends BaseTest {
    private AService getAService() {
        return JLupinClientUtil.generateRemote(getJLupinDelegator(), "example-a", "aService", AService.class);
    }

    @Test
    public void callATest() {
        AService aService = getAService();
        assertEquals("[called A][called B]input", aService.callA("input"));
    }
}

And you can configure Log4j2 to log to standard out. Put this file (log4j2.xml) into resources:

<?xml version="1.0" encoding="UTF-8"?>

<!-- ===================================================================== -->
<!--                                                                       -->
<!--  Log4j2 Configuration                                                  -->
<!--                                                                       -->
<!-- ===================================================================== -->

<!--
   | For more configuration information and examples see the Apache Log4j2
   | website: https://logging.apache.org/log4j/2.x/index.html
-->

<Configuration status="WARN">
    <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT">
            <!-- The default pattern: Date Priority [Category] (Thread) Message\n -->
            <PatternLayout pattern="%d %-5p [%c] (%t) %m%n"/>
        </Console>

        <!-- AsyncAppender for high performance -->
        <Async name="ASYNC_STDOUT">
            <BufferSize>1000</BufferSize>
            <AppenderRef ref="STDOUT"/>
        </Async>
    </Appenders>

    <Loggers>
        <!-- Setup for root logger with AsyncAppender -->
        <Root level="info">
            <AppenderRef ref="ASYNC_STDOUT"/>
        </Root>
    </Loggers>
</Configuration>

As said before microservice is called as from outer client (see base test constructor and line jLupinDelegator = JLupinClientUtil.generateOuterMicroserviceLoadBalancerDelegator().

Test execution

Before running test make sure that you microservices (example-a and example-b) are deployed on server pointed by your base test class. Then execute callATest and see result.

JUnit version 4.12
.2017-09-26 12:00:23,930 INFO  [com.jlupin.impl.balancer.ext.impl.roundrobin.JLupinRoundRobinLoadBalancerImpl$1] (pool-2-thread-1)  MESSAGE ID:52 METHOD:call LINE:83 LOG:compute current node thread started correctly
2017-09-26 12:00:23,930 INFO  [com.jlupin.impl.balancer.base.JLupinBaseLoadLoadBalancer$2] (pool-1-thread-1)  MESSAGE ID:142 METHOD:call LINE:509 LOG:microservice discovery control thread started correctly

Time: 0,731

OK (1 test)