Adding an input port with protocol SODEP
Protocol sodep is a binary protocol released together with Jolie engine. It is an efficient protocol we suggest to use every time you need to integrate a jolie service with another jolie service.
In the following picture we show how to add an inputPort which provides a sodep protocol in addition to those with http/json
and http/soap
already discussed.
As it happened for the addition of soap protocol input port, also in the case of a sodep protocol input port the behaviour of the service is always the same, and you don't need to modify it.
Adding the port
The first step is adding the inputPort to the code. In our example is:
inputPort AdvancedCalculatorPortSOAP {
location: "socket://localhost:8003"
protocol: sodep
interfaces: AdvancedCalculatorInterface
}
No other actions are required.
The complete example
The complete example follows and it may be consulted at this [link] (https://github.com/jolie/examples/tree/master/v1.10.x/tutorials/more_inputports_and_protocols/sodep)
from .AdvancedCalculatorServiceInterfaceModule import AdvancedCalculatorInterface
from .CalculatorInterfaceModule import CalculatorInterface
interface ChuckNorrisIface {
RequestResponse: random( undefined )( undefined )
}
service AdvancedCalculatorService {
execution: concurrent
outputPort Chuck {
location: "socket://api.chucknorris.io:443/"
protocol: https {
.osc.random.method = "get";
.osc.random.alias = "jokes/random"
}
interfaces: ChuckNorrisIface
}
outputPort Calculator {
location: "socket://localhost:8000"
protocol: http { format = "json" }
interfaces: CalculatorInterface
}
inputPort AdvancedCalculatorPort {
location: "socket://localhost:8001"
protocol: http { format = "json" }
interfaces: AdvancedCalculatorInterface
}
inputPort AdvancedCalculatorPortSOAP {
location: "socket://localhost:8002"
protocol: soap {
wsdl = "AdvancedCalculator.wsdl",
wsdl.port = "AdvancedCalculatorPortSOAPServicePort"
}
interfaces: AdvancedCalculatorInterface
}
inputPort AdvancedCalculatorPortSODEP {
location: "socket://localhost:8003"
protocol: sodep
interfaces: AdvancedCalculatorInterface
}
main {
[ factorial( request )( response ) {
for( i = request.term, i > 0, i-- ) {
req_mul.factor[ #req_mul.factor ] = i
}
mul@Calculator( req_mul )( response.factorial )
random@Chuck()( chuck_res )
response.advertisement = chuck_res.value
}]
[ average( request )( response ) {
{
sum@Calculator( request )( sum_res )
div@Calculator( { dividend = double( sum_res ), divisor = double( #request.term ) })( response.average )
}
|
{
random@Chuck()( chuck_res )
response.advertisement = chuck_res.value
}
}]
[ percentage( request )( response ) {
{
div@Calculator( { dividend = request.term, divisor = 100.0 })( div_res )
mul@Calculator( { factor[0] = div_res, factor[1] = request.percentage })( response_mul )
response.result = response_mul
}
|
{
random@Chuck()( chuck_res )
response.advertisement = chuck_res.value
}
}]
}
}
Running the service and invoking it
Since we are extending the example Using more than one dependency, here we need to run two services in two separate shells:
jolie AdvancedCalculatorService.ol
jolie CalcularService.ol
In this case the client is another jolie script that must be run in a separate shell:
from AdvancedCalculatorServiceInterfaceModule import AdvancedCalculatorInterface
from console import *
from string_utils import StringUtils
service SodepClient {
outputPort AdvancedCalculatorService {
location: "socket://localhost:8003"
protocol: sodep
interfaces: AdvancedCalculatorInterface
}
inputPort ConsoleInputPort {
location: "local"
interfaces: ConsoleInputInterface
}
embed Console as Console
embed StringUtils as StringUtils
init {
registerForInput@Console()()
}
main {
println@Console("Select the operation to call:")()
println@Console("1- factorial")()
println@Console("2- percentage")()
println@Console("3- average")()
print@Console("? ")()
in( answer )
if ( (answer != "1") && (answer != "2") && (answer != "3") ) {
println@Console("Please, select 1, 2 or 3")()
throw( Error )
}
if ( answer == "1" ) {
println@Console( "Enter an integer")()
in( term )
factorial@AdvancedCalculatorService( { term = int( term ) } )( factorial_response )
println@Console( "Result: " + factorial_response.factorial )()
println@Console( factorial_response.advertisement )()
}
if ( answer == "2" ) {
println@Console( "Enter a double")()
in ( term )
println@Console( "Enter a percentage to be calculated")()
in ( percentage )
percentage@AdvancedCalculatorService( { term = double( term ), percentage = double( percentage ) } )( percentage_response )
println@Console( "Result: " + percentage_response.result )()
println@Console( percentage_response.advertisement )()
}
if ( answer == "3" ) {
println@Console("Enter a list of integers separated by commas")()
in( terms )
split@StringUtils( terms { regex = ","} )( splitted_terms )
for( t in splitted_terms.result ) {
req_average.term[ #req_average.term ] = int( t )
}
average@AdvancedCalculatorService( req_average )( average_response )
println@Console( "Result: " + average_response.average )()
println@Console( average_response.advertisement )()
}
}
}
Note that in this client the corresponding sodep outputPort is defined. In the behaviour, a simple choice is offered to the user on the console for selecting the operation to invoke. Depending on the choice, the user is asked to insert the specific parameters required by the operation, then the message is sent to the AdvancedCalculatorService. In the following we report an example of an execution:
jolie sodep_client.ol
Select the operation to call:
1- factorial
2- percentage
3- average
? 1
Enter an integer
3
Result: 6
Chuck NOrris is an incredible sitar player.