Create microservice
Native microservice
Native microservice is a set of POJO Java classes available for JLupin Next Server through configured spring container.
Creating interface
package com.jlupin.sample.interfaces;
public interface ExampleService {
String getName();
}
Creating implementation
package com.jlupin.sample.impl;
import com.jlupin.sample.interfaces.ExampleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service(value = "exampleService")
public class ExampleServiceImpl implements ExampleService {
private final static Logger logger = LoggerFactory.getLogger(ExampleServiceImpl.class);
@Override
public String getName() {
logger.info("called getName() method");
return "name";
}
}
Interface is optional here (it is a good practice to create interface for every service) but is required for binary communication (generated proxy object is implementing interface). It is also a good practice to put interface in seperate jar to not share your internal implementation with the others. More details about logging can be found in Logging chapter.
Remote sharing
package com.jlupin.sample.configuration;
import java.util.ArrayList;
import java.util.List;
@Configuration
@ComponentScan("com.jlupin.sample")
public class SpringConfiguration {
@Bean(name = "jLupinRegularExpressionToRemotelyEnabled")
public List getRemotelyBeanList() {
List<String> list = new ArrayList<>();
list.add("exampleService");
return list;
}
}
Class is annotated as standard Spring configuration class with component scan (to scan package for used annotations). The important part is a bean named jLupinRegularExpressionToRemotelyEnabled. It is a list of regular expressions wich are working as a masks for services available to JLupin Next Server. What does it mean? For security reasons not all services are available for remote execution. And decision which are visible outside and which are not is being made by developer. Being specific, every object living inside spring container is a bean. And every bean in Spring container has a name (by default it is class name with first letter downcased). To determine wchich service should be exposed JLupin Next Server takes all beans from application container and then check if this name matches any of regular expressions on bean jLupinRegularExpressionToRemotelyEnabled (this bean is a list). If it matches service is remotely enabled and can be called with remote execution.
You also need to tell JLupin which context to use. You do this by creating proper class and putting it's name in microservice configuration (configuration.yml).
package com.example.currency.converter.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 JLupinConfiguration extends JLupinAbstractApplicationContainerProducer {
@Override
public JLupinApplicationContainer produceJLupinApplicationContainer() {
return new JLupinAbstractSpringApplicationContainer() {
@Override
public AbstractApplicationContext getAbstractApplicationContext() {
return new AnnotationConfigApplicationContext(SpringConfiguration.class);
}
};
}
}
Running microservice
When your microservice is done compile it into jar file. Then put this file with all other required by your microservice (like configuration.yml, logger configuration file, properties file, etc.) into directory which name is your microservice name inside server/application
directory. To start it just run control.sh/.cmd
and type in command microservice start [your_microservice_name]
.
Example microservice configuration file is shown below full configuration file description:
SERVERS:
JLRMC: #JLupin Remote Method Calls Fast Protocol
readTimeout: 480000
isWaitForFinishExecuteAllRequests: true
waitToShutdownThreadsOnStop: 60000
backlog: 0
receiveBufferSize: 0
isReuseAddress: false
threadPoolSize: 128
isLogPeriodicOnDebug: true
isDestroyThreadOnTimeout: false
threadExecutingTimeOut: 240000
TRANSMISSION:
readTimeout: 480000
isWaitForFinishExecuteAllRequests: false
waitToShutdownThreadsOnStop: 60000
backlog: 0
receiveBufferSize: 0
isReuseAddress: false
threadPoolSize: 8
isLogPeriodicOnDebug: true
isDestroyThreadOnTimeout: false
threadExecutingTimeOut: 3600000
QUEUE:
readTimeout: 480000
isWaitForFinishExecuteAllRequests: true
waitToShutdownThreadsOnStop: 60000
backlog: 1024
receiveBufferSize: 1024
isReuseAddress: false
threadPoolSize: 128
isLogPeriodicOnDebug: true
isDestroyThreadOnTimeout: false
threadExecutingTimeOut: 240000
ENTRY_POINTS:
QUEUE:
threadAmount: 512
howOftenCheckingServerInMillis: 5000
repeatsAmount: 4
timeToWaitBetweenRepeatProbeInMillis: 1000
PROPERTIES:
#jvmOptions1: '-Xms128M -Xmx256M -agentlib:jdwp=transport=dt_socket,address=12998,server=y,suspend=n'
jvmOptions1: '-Xms64M -Xmx128M' #jvmOptions_2 - default the same as jvmOptions_1
#jvmOptions2: '-Xms128M -Xmx256M'
externalPort: '8000'
version: '1.0'
switchDelayTime: 0
connectionSocketTimeoutInMillis: 1000
readTimeoutInMillis: 30000
isKeepAlive: false
isOOBInline: false
isTcpNoDelay: false
isReuseAddress: false
sendBufferSize: 0
receiveBufferSize: 0
soLinger: 0
trafficClass: 0
#javaExecutablePath: 'c:\\jvm\\bin\\java.exe'
#additionalClassPath: 'c:\\temp\\*'
isStartOnMainServerInitialize: true
priorityStartOnMainServerInitialize: 4
waitForProcessInitResponseTimeInMillis: 90000
waitForProcessStartResponseTimeInMillis: 90000
waitForProcessDestroyResponseTimeInMillis: 30000
isAllFilesToJVMAppClassLoader: false
isArchiveOnStart: false
startLogMode: INFO
isInitErrorCauseWithNetworkInformation: true
checkAvailableScript: 'function isAvailable(checkResponseTimeInMillis, jrmcActiveThreads, jrmcMaxThreads,
queueActiveThreads, queueMaxThreads, servletActiveThreads, servletMaxThreads,
jvmMaxMemoryInBytes, jvmTotalMemoryInBytes, jvmFreeMemoryInBytes,
jvmProcessCpuLoadInPercentage, userAvailableFlag) {
var isAvailableByUser = Boolean(userAvailableFlag);
if(checkResponseTimeInMillis > 20000 || !isAvailableByUser) {
return false;
}
return true;
}'
APPLICATION:
applicationContainerProducerClassName: 'com.example.currency.converter.configuration.CurrencyConverterEurJLupinConfiguration'
INITIALIZING_LOGGER:
#directoryPath: '/logs/server'
#fileName: 'file_name'
fileExtension: 'log'
fileSizeInMB: 20
maxFiles: 10
MEMORY_ERRORS:
isRestartOnError: true
howManyTimes: 4
percentageGrowth: 15
isHeapDump: true
THREAD_POOLS:
THREAD_POOL_1:
size: 8
waitingTimeForTasksCompletionInMillis: 10000
#THREAD_POOL_2:
# size: 8
# waitingTimeForTasksCompletionInMillis: 10000