Lagom SOAP allows a Lagom application to make calls on a remote web service using SOAP. It provides a reactive interface to doing so, making HTTP requests asynchronously and returning futures of the result. Lagom SOAP use Play SAOP library and Circuit Breaker feature of Lagom.
Lagom Soap Client | Lagom | Scala |
---|---|---|
1.+ | 1.4.+ 1.5.+ 1.6.+ |
2.11 2.12 2.13 |
- Use Play SAOP for generate async client.
- Add generated client to dependencies of Lagom service. For example:
val externalSoapClient = "foo.bar" %% "external-async-client" % "X.Y.Z"
...
.settings(
libraryDependencies ++= Seq(
externalSoapClient
)
)
Extend your Guice module by ServiceGuiceSupport
and use bindSoapClient
method for registration client. Also you can register SOAP message handler for this service.
For example:
import org.taymyr.lagom.soap.ServiceGuiceSupport;
public class MyServiceModule extends AbstractModule implements ServiceGuiceSupport {
@Override
protected void configure() {
bindSoapClient(Service.class, ServicePort.class, new DisableJaxbValidationHandler());
}
}
public class MyServiceImpl implements MyService {
private final ServicePort soapService;
@Inject
public MyServiceImpl(ServicePort soapService) {
this.soapService = soapService;
}
}
You can inject provider of SOAP client for using custom handling every SOAP message.
public class MyServiceImpl implements MyService {
private final ServiceProvider<ServicePort> serviceProvider;
@Inject
public MyServiceImpl(ServiceProvider<ServicePort> serviceProvider) {
this.serviceProvider = serviceProvider;
}
}
You can get SOAP client from the provider, passing it a list message handlers, that will be used in addition to the list passed during registration.
Within these handlers, you can implement the query logic that depends on the current context. For example, put the header User-Agent
in the outgoing SOAP request
depending on the headers of the current request.
import static org.taymyr.lagom.soap.WebFaultException.processWebFault;
import static org.taymyr.lagom.soap.handler.SetUserAgentHandler.userAgent;
public class MyServiceImpl implements MyService {
@Override
public HeaderServiceCall<NotUsed, String> myMethod() {
return (headers, request) -> {
ServicePort service = serviceProvider.get(userAgent("Agent"));
return service.foo(new Bar())
.thenApplyAsync(result -> ok("Foo: " + result))
.exceptionally(throwable -> processWebFault(throwable, e -> {
if (e instanceof ServiceLogicException) {
// do something
} else {
throw new TransportException(InternalServerError, new ExceptionMessage("", ""));
}
}));
};
}
}
-
Add
org.taymyr.lagom.soap.WebFaultException
to Circuit Breakers whitelist (lagom.circuit-breaker.default.exception-whitelist
), because all checked SOAP exceptions boxing toWebFaultException
. Otherwise Circuit Breaker will be opened for all SOAP exceptions. -
Configure Circuit Breaker for SOAP client
lagom.circuit-breaker.<SERVICE_CLASS>
. To configure methods uselagom.circuit-breaker.<SERVICE_CLASS>.methods.<METHOD_NAME>
Highly recommended configuring Circuit Breaker (see all available settings in Lagom docs) inplay.soap.services
block and use reference to this configuration inlagom.circuit-breaker
block. -
Configure address external SOAP service
play.soap.services.<SERVICE_CLASS>.address
. See details in Play SOAP docs. -
Configure value of User-Agent header
play.soap.services.<SERVICE_CLASS>.browser-type
. (Default valuelagom
). -
Configure SOAP client
play.soap.services.<SERVICE_CLASS>.singleton
as Singleton for better performance. Warning: It can be NOT thread-safe. More details see on CXF docs (Default valuefalse
) -
Configure max log size of you soap-client
play.soap.services.<SERVICE_CLASS>.log-size
(Default value 48 kB). When you use log-size more than 128 kbytes CXF creates temporary files that contains messages, and CXF deletes files by itself.
lagom.circuit-breaker {
default.exception-whitelist = [
org.taymyr.lagom.soap.WebFaultException
]
com.foo.bar.service.Service = ${play.soap.services.com.foo.bar.service.Service.breaker}
com.foo.bar.service.Service.methods.method1 = ${play.soap.services.com.foo.bar.service.Service.methods.method1.breaker}
com.foo.bar.service.Service.methods.method2 = ${play.soap.services.com.foo.bar.service.Service.methods.method2.breaker}
}
play.soap.services {
com.foo.bar.service.Service {
address = "http://domain:PORT/service"
browser-type = "Lagom MyService"
singleton: false
log-size : 1MB
breaker = {
call-timeout = 10s
}
methods {
method1 {
breaker {
call-timeout = 20s
}
}
method2 {
breaker {
call-timeout = 30s
}
}
}
}
}
All released artifacts are available in the Maven central repository.
Just add a lagom-soap-client
to your service dependencies:
- SBT
libraryDependencies += "org.taymyr.lagom" %% "lagom-soap-client-java" % "X.Y.Z"
- Maven
<dependency>
<groupId>org.taymyr.lagom</groupId>
<artifactId>lagom-soap-client-java_${scala.binary.version}</artifactId>
<version>X.Y.Z</version>
</dependency>
All snapshot artifacts are available in the Sonatype snapshots repository. This repository must be added in your build system.
- SBT
resolvers ++= Resolver.sonatypeRepo("snapshots")
- Maven
<repositories>
<repository>
<id>snapshots-repo</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
Contributions are very welcome.
Copyright © 2019 Digital Economy League (https://www.digitalleague.ru/).
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.