HTTP Elastic API
HTTP Elastic API is an automated text communication entry point. It is used to call remotely enabled services. By default it is exposed by Main Server on port 8082.
HTTP Elastic API is only exposed for native (nativeApp) microservices. For servlet (servletApp) microservices it is not possible to expose it as microservices are handling all incoming http requests by themselves.
Example application
For all examples in this chapter will be used example application which consists of files listed below:
Input object class:
package com.example.service.pojo;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("mulInput")
public class MulInput {
private Integer a;
private Integer b;
public void setA(Integer a) {
this.a = a;
}
public Integer getA() {
return a;
}
public void setB(Integer b) {
this.b = b;
}
public Integer getB() {
return b;
}
}
Output object class:
package com.example.service.pojo;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("mulOutput")
public class MulOutput {
private Integer result;
public void setResult(Integer result) {
this.result = result;
}
public Integer getResult() {
return result;
}
}
Service interface:
package com.example.service.interfaces;
import com.example.service.pojo.MulInput;
import com.example.service.pojo.MulOutput;
public interface MultiplierService {
Integer mulOne(Integer a, Integer b);
MulOutput mulTwo(MulInput mulInput);
Integer mulThree(MulInput mulInput);
MulOutput mulFour(Integer a, Integer b);
}
Service implementation:
package com.example.service.impl;
import com.example.service.interfaces.MultiplierService;
import com.example.service.pojo.MulInput;
import com.example.service.pojo.MulOutput;
import org.springframework.stereotype.Service;
@Service(value = "multiplierService")
public class MultiplierServiceImpl implements MultiplierService {
@Override
public Integer mulOne(Integer a, Integer b) {
return a * b;
}
@Override
public MulOutput mulTwo(MulInput mulInput) {
final MulOutput mulOutput = new MulOutput();
mulOutput.setResult(mulInput.getA() * mulInput.getB());
return mulOutput;
}
@Override
public Integer mulThree(MulInput mulInput) {
return mulInput.getA() * mulInput.getB();
}
@Override
public MulOutput mulFour(Integer a, Integer b) {
final MulOutput mulOutput = new MulOutput();
mulOutput.setResult(a * b);
return mulOutput;
}
}
Spring configuration file:
package com.example.configuration;
import com.example.service.pojo.MulInput;
import com.example.service.pojo.MulOutput;
import com.jlupin.impl.client.util.JLupinClientUtil;
import com.jlupin.interfaces.client.delegator.JLupinDelegator;
import com.jlupin.interfaces.common.enums.PortType;
import com.thoughtworks.xstream.XStream;
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 ExampleSpringConfiguration {
@Bean
public JLupinDelegator getJLupinDelegator() {
return JLupinClientUtil.generateInnerMicroserviceLoadBalancerDelegator(PortType.JLRMC);
}
@Bean(name = "jLupinRegularExpressionToRemotelyEnabled")
public List getRemotelyBeanList() {
List<String> list = new ArrayList<>();
list.add("multiplierService");
// list.add("<REMOTE_SERVICE_NAME>");
return list;
}
@Bean(name = "xStreamXmlSerializer")
public XStream getXStreamXmlSerializer() {
XStream xStream = new XStream();
xStream.processAnnotations(MulInput.class);
xStream.processAnnotations(MulOutput.class);
return xStream;
}
}
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 ExampleJLupinConfiguration extends JLupinAbstractApplicationContainerProducer {
@Override
public JLupinApplicationContainer produceJLupinApplicationContainer() {
return new JLupinAbstractSpringApplicationContainer() {
@Override
public AbstractApplicationContext getAbstractApplicationContext() {
return new AnnotationConfigApplicationContext(ExampleSpringConfiguration.class);
}
};
}
}
To deploy above microservice just go to automatic or manual deploy chapter.
Using Elastic API
For Elastic API all additional parameters of invocation had been moved to request headers. Request body contains only serialized data sent to method. These way it is easy to configure your client to send proper requests. You cannot overload method names when using ElasticAPI. There are two main options to invoke service methods:
- Remote Object API (ROA) - requires called method to have only one parameter
- Remote Method Call (RMC) - no limits.
Headers specification
Header | Description | Example value |
---|---|---|
X-JLNS-API-ID |
API ID to tell server which facade to use. | ROA , RMC (case sensitive) |
X-JLNS-Privilege-Names |
List of privileged names separated by semicolon used with JLupinPermissionResolver to check if call is privileged. | privileged1;privileged2 |
X-JLNS-Locale |
Locale for translation. | en |
X-JLNS-Sequence-Name |
Sequence name to use for deserializing method parameters. | xStreamParamArrayXmlInOutSequence , xStreamParamArrayJsonInOutSequence , jacksonParamArrayXmlInOutSequence , jacksonParamArrayJsonInOutSequence |
X-JLNS-Request-ID |
Request ID. | request1 |
X-JLNS-Session-ID |
Session ID. | session1 |
X-JLNS-User |
User. | user1 |
X-JLNS-Client-Application-Name |
Client application name. | application1 |
X-JLNS-IP |
IP address. | 127.0.0.1 |
All above parameters are optional. By default API ID and sequence name is taken from main server configuration file:
[...]
ENTRY_POINTS:
WEB_SERVICE_FACADE_HTTP:
[...]
defaultSequenceName: jacksonParamArrayJsonInOutSequence
defaultApiId: ROA
[...]
[...]
URL structure:
/[microserviceName]/[serviceName]/[methodName]
All requests must be invoked with method POST (also support for options is added for web browsers). Content-Type
or Accept
must be send to determine serialization type. Also both headers must be consistent (you can’t send JSON data and as return get XML data).
Body specification
ROA
For ROA request body is a serialized method argument. As said before through ROA only methods with one argument can be called. For example from MultiplierService
only mulTwo
and mulThree
methods can be called. As an input they accept MulInput
object.
Example for JSON (when jacksonParamArrayJsonInOutSequence
is used):
{
"a": 3,
"b": 4
}
Example for XML (when xStreamParamArrayXmlInOutSequence
is used):
<mulInput>
<a>3</a>
<b>4</b>
</mulInput>
RMC
For RMC request body is an array, where objects are serialized arguments. As said before through RMC you can call all your methods (remember that method names overloading is forbidden). For example from MultiplierService
all methods could be called.
Example for JSON (when jacksonParamArrayJsonInOutSequence
is used) for methods mulTwo
and mulThree
:
[
{
"a": 3,
"b": 4
}
]
Example for JSON (when jacksonParamArrayJsonInOutSequence
is used) for methods mulOne
and mulFour
:
[
3,
4
]
Example for XML (when xStreamParamArrayXmlInOutSequence
is used) for methods mulTwo
and mulThree
:
<paramArray>
<mulInput>
<a>3</a>
<b>4</b>
</mulInput>
</paramArray>
Example for XML (when xStreamParamArrayXmlInOutSequence
is used) for methods mulOne
and mulFour
:
<paramArray>
<int>3</int>
<int>4</int>
</paramArray>
Example calls
Below are showed full examples of requests including request headers, body and response.
ROA
JSON
mulTwo
Request:
POST /example/multiplierService/mulTwo HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/json
Content-Type: application/json
Content-Length: 16
{"a": 3, "b": 4}
Curl command:
curl -X POST "http://localhost:8082/example/multiplierService/mulTwo" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"a": 3, "b": 4}'
Response:
{"result":12}
mulThree
Request:
POST /example/multiplierService/mulThree HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/json
Content-Type: application/json
Content-Length: 16
{"a": 3, "b": 4}
Curl command:
curl -X POST "http://localhost:8082/example/multiplierService/mulThree" -H "Accept: application/json" -H "Content-Type: application/json" -d '{"a": 3, "b": 4}'
Response:
12
XML
mulTwo
Request:
POST /example/multiplierService/mulTwo HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/xml
Content-Type: application/xml
X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence
Content-Length: 37
<mulInput><a>3</a><b>4</b></mulInput>
Curl command:
curl -X POST "http://localhost:8082/example/multiplierService/mulTwo" -H "Accept: application/xml" -H "Content-Type: application/xml" -H "X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence" -d '<mulInput><a>3</a><b>4</b></mulInput>'
Response:
<mulOutput>
<result>12</result>
</mulOutput>
mulThree
Request:
POST /example/multiplierService/mulThree HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/xml
Content-Type: application/xml
X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence
Content-Length: 37
<mulInput><a>3</a><b>4</b></mulInput>
Curl command:
curl -X POST "http://localhost:8082/example/multiplierService/mulThree" -H "Accept: application/xml" -H "Content-Type: application/xml" -H "X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence" -d '<mulInput><a>3</a><b>4</b></mulInput>'
Response:
<int>12</int>
RMC
JSON
mulOne
Request:
POST /example/multiplierService/mulOne HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/json
Content-Type: application/json
X-JLNS-API-ID: RMC
Content-Length: 6
[3, 4]
Curl command:
curl -X POST "http://localhost:8082/example/multiplierService/mulOne" -H "Accept: application/json" -H "Content-Type: application/json" -H "X-JLNS-API-ID: RMC" -d '[3, 4]'
Response:
12
mulTwo
Request:
POST /example/multiplierService/mulTwo HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/json
Content-Type: application/json
X-JLNS-API-ID: RMC
Content-Length: 18
[{"a": 3, "b": 4}]
Curl command:
curl -X POST "http://localhost:8082/example/multiplierService/mulTwo" -H "Accept: application/json" -H "Content-Type: application/json" -H "X-JLNS-API-ID: RMC" -d '[{"a": 3, "b": 4}]'
Response:
{"result":12}
mulThree
Request:
POST /example/multiplierService/mulThree HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/json
Content-Type: application/json
X-JLNS-API-ID: RMC
Content-Length: 18
[{"a": 3, "b": 4}]
Curl command:
curl -X POST "http://localhost:8082/example/multiplierService/mulThree" -H "Accept: application/json" -H "Content-Type: application/json" -H "X-JLNS-API-ID: RMC" -d '[{"a": 3, "b": 4}]'
Response:
12
mulFour
Request:
POST /example/multiplierService/mulFour HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/json
Content-Type: application/json
X-JLNS-API-ID: RMC
Content-Length: 6
[3, 4]
Curl command:
curl -X POST "http://localhost:8082/example/multiplierService/mulFour" -H "Accept: application/json" -H "Content-Type: application/json" -H "X-JLNS-API-ID: RMC" -d '[3, 4]'
Response:
{"result":12}
XML
mulOne
Request:
POST /example/multiplierService/mulOne HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/xml
Content-Type: application/xml
X-JLNS-API-ID: RMC
X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence
Content-Length: 49
<paramArray><int>3</int><int>4</int></paramArray>
Curl command:
curl -X POST "http://localhost:8082/example/multiplierService/mulOne" -H "Accept: application/xml" -H "Content-Type: application/xml" -H "X-JLNS-API-ID: RMC" -H "X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence" -d '<paramArray><int>3</int><int>4</int></paramArray>'
Response:
<int>12</int>
mulTwo
Request:
POST /example/multiplierService/mulTwo HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/xml
Content-Type: application/xml
X-JLNS-API-ID: RMC
X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence
Content-Length: 62
<paramArray><mulInput><a>3</a><b>4</b></mulInput></paramArray>
Curl command:
curl -X POST "http://localhost:8082/example/multiplierService/mulTwo" -H "Accept: application/xml" -H "Content-Type: application/xml" -H "X-JLNS-API-ID: RMC" -H "X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence" -d '<paramArray><mulInput><a>3</a><b>4</b></mulInput></paramArray>'
Response:
<mulOutput>
<result>12</result>
</mulOutput>
mulThree
Request:
POST /example/multiplierService/mulThree HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/xml
Content-Type: application/xml
X-JLNS-API-ID: RMC
X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence
Content-Length: 62
<paramArray><mulInput><a>3</a><b>4</b></mulInput></paramArray>
Curl command:
curl -X POST "http://localhost:8082/example/multiplierService/mulThree" -H "Accept: application/xml" -H "Content-Type: application/xml" -H "X-JLNS-API-ID: RMC" -H "X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence" -d '<paramArray><mulInput><a>3</a><b>4</b></mulInput></paramArray>'
Response:
<int>12</int>
mulFour
Request:
POST /example/multiplierService/mulFour HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/xml
Content-Type: application/xml
X-JLNS-API-ID: RMC
X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence
Content-Length: 49
<paramArray><int>3</int><int>4</int></paramArray>
Curl command:
curl -X POST "http://localhost:8082/example/multiplierService/mulFour" -H "Accept: application/xml" -H "Content-Type: application/xml" -H "X-JLNS-API-ID: RMC" -H "X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence" -d '<paramArray><int>3</int><int>4</int></paramArray>'
Response:
<mulOutput>
<result>12</result>
</mulOutput>
Architecture
Below architecture of Elastic API is shown with detailed where deserialization is taking place.
ROA
Your request is send to Main Server (1). It takes it and extracts body into String variable. Then through JLRMC (binary communication) your serialized object as a String is send to your microservice. Where deserialization is taking place (2). Appropriate serializer/deserializer is used based on chosen sequence (can be set with appropriate header in request). When object is deserialized, method is called (3) and as an argument deserialized object is passed.
Example with JSON
Request:
POST /example/multiplierService/mulTwo HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/json
Content-Type: application/json
Content-Length: 16
{"a": 3, "b": 4}
Response:
{"result":12}
Main Server handles HTTP request and changes it to JLRMC (binary communication). Microservice receives String "{\"a\": 3, \"b\": 4}"
which is deserialized by jackson json serializer/deserializer (because default sequence is jacksonParamArrayJsonInOutSequence
). Then method mulTwo
is executed with argument being MulInput{a=3, b=4}
. The result MulOutput{result=12}
is serialized by jackson json serializer/deserializer (because default sequence is jacksonParamArrayJsonInOutSequence
). Then serialized result is send back to Main Server which returns it.
Example with XML
Request:
POST /example/multiplierService/mulTwo HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/xml
Content-Type: application/xml
X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence
Content-Length: 37
<mulInput><a>3</a><b>4</b></mulInput>
Response:
<mulOutput>
<result>12</result>
</mulOutput>
Main Server handles HTTP request and changes it to JLRMC (binary communication). Microservice receives String "<mulInput><a>3</a><b>4</b></mulInput>"
which is deserialized by xstream xml serializer/deserializer (because used sequence is xStreamParamArrayXmlInOutSequence
). Then method mulTwo
is executed with argument being MulInput{a=3, b=4}
. The result MulOutput{result=12}
is serialized by xstream xml serializer/deserializer (because used sequence is xStreamParamArrayXmlInOutSequence
). Then serialized result is send back to Main Server which returns it.
RMC
Your request is send to Main Server (1). It takes it and extracts body and divides it into separate String objects. Each array argument becomes one String. Then through JLRMC (binary communication) your serialized objects as a Strings are send to your microservice. Where deserialization is taking place (2). Appropriate serializer/deserializer is used based on chosen sequence (can be set with appropriate header in request). When objects are deserialized, method is called (3) and as an arguments deserialized objects are passed.
Example with JSON
Request:
POST /example/multiplierService/mulFour HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/json
Content-Type: application/json
X-JLNS-API-ID: RMC
Content-Length: 6
[3, 4]
Response:
{"result":12}
Main Server handles HTTP request and changes it to JLRMC (binary communication). Microservice receives array with two Strings: "3"
, "4"
. They are deserialized (each of them separately) by jackson json serializer/deserializer (because default sequence is jacksonParamArrayJsonInOutSequence
). Then method mulFour
is executed with arguments being Integer{3}
, Integer{4}
. The result MulOutput{result=12}
is serialized by jackson json serializer/deserializer (because default sequence is jacksonParamArrayJsonInOutSequence
). Then serialized result is send back to Main Server which returns it.
Example with XML
Request:
POST /example/multiplierService/mulFour HTTP/1.1
Host: localhost:8082
User-Agent: curl/7.52.1
Accept: application/xml
Content-Type: application/xml
X-JLNS-API-ID: RMC
X-JLNS-Sequence-Name: xStreamParamArrayXmlInOutSequence
Content-Length: 49
<paramArray><int>3</int><int>4</int></paramArray>
Response:
<mulOutput>
<result>12</result>
</mulOutput>
Main Server handles HTTP request and changes it to JLRMC (binary communication). Microservice receives array with two Strings: "<int>3</int>"
, "<int>4</int>"
. They are deserialized (each of them separately) by xstream xml serializer/deserializer (because used sequence is xStreamParamArrayXmlInOutSequence
). Then method mulFour
is executed with arguments being Integer{3}
, Integer{4}
. The result MulOutput{result=12}
is serialized by xstream xml serializer/deserializer (because used sequence is xStreamParamArrayXmlInOutSequence
). Then serialized result is send back to Main Server which returns it.
Configuring serializer/deserializer
xStreamParamArrayXmlInOutSequence
Sequence xStreamParamArrayXmlInOutSequence
is looking in your application context for a bean named xStreamXmlSerializer
which type is XStream
. If you do not define it by yourself JLupin will provide default definition which is:
@Bean(name = "xStreamXmlSerializer")
public XStream getXStreamXmlSerializer() {
return new XStream();
}
But if you define it by yourself you are free to configure it as you want. JLupin will always use this bean for serialization/deserialization when sequence xStreamParamArrayXmlInOutSequence
is used.
xStreamParamArrayJsonInOutSequence
Sequence xStreamParamArrayJsonInOutSequence
is looking in your application context for a bean named xStreamJsonSerializer
which type is XStream
. If you do not define it by yourself JLupin will provide default definition which is:
@Bean(name = "xStreamJsonSerializer")
public XStream getXStreamJsonSerializer() {
return new XStream(new JettisonMappedXmlDriver());
}
But if you define it by yourself you are free to configure it as you want. JLupin will always use this bean for serialization/deserialization when sequence xStreamParamArrayJsonInOutSequence
is used.
jacksonParamArrayXmlInOutSequence
Sequence jacksonParamArrayXmlInOutSequence
is looking in your application context for a bean named jacksonXmlSerializer
which type is XmlMapper
. If you do not define it by yourself JLupin will provide default definition which is:
@Bean(name = "jacksonXmlSerializer")
public XmlMapper getJacksonXmlSerializer() {
return new XmlMapper();
}
But if you define it by yourself you are free to configure it as you want. JLupin will always use this bean for serialization/deserialization when sequence jacksonParamArrayXmlInOutSequence
is used.
jacksonParamArrayJsonInOutSequence
Sequence jacksonParamArrayJsonInOutSequence
is looking in your application context for a bean named jacksonJsonSerializer
which type is ObjectMapper
. If you do not define it by yourself JLupin will provide default definition which is:
@Bean(name = "jacksonJsonSerializer")
public ObjectMapper getJacksonJsonSerializer() {
return new ObjectMapper();
}
But if you define it by yourself you are free to configure it as you want. JLupin will always use this bean for serialization/deserialization when sequence jacksonParamArrayJsonInOutSequence
is used.
Swagger integration
If you are using ROA you can integrate with swagger to generate documentation and client libraries. The example will use JSON message format with standard Jackson serializer. Below are shown project files:
Input object class:
package com.example.service.pojo;
public class OperationInput {
private Integer a;
private Integer b;
public void setA(Integer a) {
this.a = a;
}
public Integer getA() {
return a;
}
public void setB(Integer b) {
this.b = b;
}
public Integer getB() {
return b;
}
}
Output object class:
package com.example.service.pojo;
public class OperationOutput {
private Integer result;
public void setResult(Integer result) {
this.result = result;
}
public Integer getResult() {
return result;
}
}
Service interface:
package com.example.service.interfaces;
import com.example.service.pojo.OperationInput;
import com.example.service.pojo.OperationOutput;
public interface CalculatorService {
OperationOutput add(OperationInput operationInput);
OperationOutput sub(OperationInput operationInput);
OperationOutput mul(OperationInput operationInput);
OperationOutput div(OperationInput operationInput);
}
Service implementation:
package com.example.service.impl;
import com.example.service.interfaces.CalculatorService;
import com.example.service.pojo.OperationInput;
import com.example.service.pojo.OperationOutput;
import org.springframework.stereotype.Service;
@Service(value = "calculaotrService")
public class CalculatorServiceImpl implements CalculatorService {
@Override
public OperationOutput add(OperationInput operationInput) {
final OperationOutput operationOutput = new OperationOutput();
operationOutput.setResult(operationInput.getA() * operationInput.getB());
return operationOutput;
}
@Override
public OperationOutput sub(OperationInput operationInput) {
final OperationOutput operationOutput = new OperationOutput();
operationOutput.setResult(operationInput.getA() * operationInput.getB());
return operationOutput;
}
@Override
public OperationOutput mul(OperationInput operationInput) {
final OperationOutput operationOutput = new OperationOutput();
operationOutput.setResult(operationInput.getA() * operationInput.getB());
return operationOutput;
}
@Override
public OperationOutput div(OperationInput operationInput) {
final OperationOutput operationOutput = new OperationOutput();
operationOutput.setResult(operationInput.getA() * operationInput.getB());
return operationOutput;
}
}
Spring configuration file:
package com.example.configuration;
import com.example.service.pojo.MulInput;
import com.example.service.pojo.MulOutput;
import com.jlupin.impl.client.util.JLupinClientUtil;
import com.jlupin.interfaces.client.delegator.JLupinDelegator;
import com.jlupin.interfaces.common.enums.PortType;
import com.thoughtworks.xstream.XStream;
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 ExampleSpringConfiguration {
@Bean
public JLupinDelegator getJLupinDelegator() {
return JLupinClientUtil.generateInnerMicroserviceLoadBalancerDelegator(PortType.JLRMC);
}
@Bean(name = "jLupinRegularExpressionToRemotelyEnabled")
public List getRemotelyBeanList() {
List<String> list = new ArrayList<>();
list.add("calculatorService");
// 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 ExampleJLupinConfiguration extends JLupinAbstractApplicationContainerProducer {
@Override
public JLupinApplicationContainer produceJLupinApplicationContainer() {
return new JLupinAbstractSpringApplicationContainer() {
@Override
public AbstractApplicationContext getAbstractApplicationContext() {
return new AnnotationConfigApplicationContext(ExampleSpringConfiguration.class);
}
};
}
}
To deploy above microservice just go to automatic or manual deploy chapter.
So now we have prepared application with ROA api available. We want to create Swagger API specification file which then will be used by all Swagger tools. First of all we need to add annotations to our service implementation to tell which elements belong to API. We will use JCS Jlupin Platform Maven Plugin with goal generate-swagger
.
Let's start with modifying CalculatorServiceImpl
class:
package com.example.application.service.impl;
import com.example.application.service.interfaces.CalculatorService;
import com.example.application.service.pojo.OperationInput;
import com.example.application.service.pojo.OperationOutput;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Service;
@Api
@Service(value = "calculatorService")
public class CalculatorServiceImpl implements CalculatorService {
@ApiOperation(value = "Add two numbers.")
@Override
public OperationOutput add(OperationInput operationInput) {
final OperationOutput operationOutput = new OperationOutput();
operationOutput.setResult(operationInput.getA() * operationInput.getB());
return operationOutput;
}
@ApiOperation(value = "Subtract two numbers.")
@Override
public OperationOutput sub(OperationInput operationInput) {
final OperationOutput operationOutput = new OperationOutput();
operationOutput.setResult(operationInput.getA() * operationInput.getB());
return operationOutput;
}
@ApiOperation(value = "Multiply two numbers.")
@Override
public OperationOutput mul(OperationInput operationInput) {
final OperationOutput operationOutput = new OperationOutput();
operationOutput.setResult(operationInput.getA() * operationInput.getB());
return operationOutput;
}
@ApiOperation(value = "Divide two numbers.")
@Override
public OperationOutput div(OperationInput operationInput) {
final OperationOutput operationOutput = new OperationOutput();
operationOutput.setResult(operationInput.getA() * operationInput.getB());
return operationOutput;
}
}
@Api
annotation tells that class is included into external API. @ApiOperation
tells which methods are included.
Add configuration for generating Swagger API specification to pom.xml
file of example
microservice.
<project>
[...]
<build>
[...]
<plugins>
[...]
<plugin>
<groupId>com.jlupin</groupId>
<artifactId>jlupin-platform-maven-plugin</artifactId>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>generate-swagger</goal>
</goals>
<configuration>
<apiSources>
<apiSource>
<locations>${project.groupId}</locations>
<info>
<title>Calculator API</title>
<version>${project.version}</version>
</info>
<swaggerDirectory>${build.directory}</swaggerDirectory>
</apiSource>
</apiSources>
</configuration>
</execution>
</executions>
</plugin>
[...]
</plugins>
[...]
</build>
[...]
</project>
Now generate Swagger API specification file with maven command mvn jlupin-platform:generate-swagger --projects example/implementation
. You should see your swagger.json
inside example-implementation
target
directory. Next step is to serve this file through HTTP server wich CORS support enabled. You can do this with our static-files-provider
microservice. Just copy swagger.json
to static
directory inside microservice folder. Your file should be available at http://localhost:8000/jlupin-static-files-provider/swagger.json
. Then go to Swagger UI page http://petstore.swagger.io/ and paste your url in top of the page and clock Explore. Your api should be loaded and ready to play with.