Example of a midPoint overlay project that implements a custom SOAP web service. Head of the master normally follows the current development version of midPoint. See tag v4.4 for the last stable version.
The service is implemented by ExampleSoapService
class without separate interface,
so it is code-first approach with minimal ceremony with WSDL generated by CXF on the fly.
All necessary Spring configuration is in the ctx-overlay.xml
configuration file.
Name of the file is important, midPoint searches for the files with this name on the classpath.
This is an alternative to the official SOAP overlay example with a couple of differences:
-
This one is code-first single maven module. The official one uses WSDL and two modules (separate module for the service and overlay building). You can mix and match, both can be single or multi-module in their current form.
-
This one uses REST channel’s basic authentication. The official one bypasses midPoint’s flexible authentication and uses WS-Security from CXF. Again, you can mix and match and use WS-Security with code-first approach.
To build the example run:
mvn package
The final midpoint.jar
will be built in target
.
You can run the resulting JAR if java
is on the path:
java -jar target/midpoint.jar
To run in an IDE choose com.evolveum.midpoint.web.boot.MidPointSpringApplication
as the main class.
Be sure to add "provided" scope to the classpath in the run configuration.
The service will be listening at http://localhost:8080/midpoint/ws/soap/example-1, to see the WSDL use http://localhost:8080/midpoint/ws/soap/example-1?wsdl. Both WSDL URL and list of services can be accessed via browser.
|
Access to WSDL is authenticated as well, which isn’t practical.
You may ask: "Can’t we just ignore the path with WSDL?"
The answer is no, because current ignore path mechanism matches paths without |
You can test the service with this command:
curl --user "administrator:5ecr3t" -d @- \ -H "Content-Type: text/xml;charset=UTF-8" \ http://localhost:8080/midpoint/ws/soap/example-1 <<< ' <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cus="https://midpoint.example.com/xml/ns/custom-soap-1"> <soapenv:Header/> <soapenv:Body> <cus:self/> </soapenv:Body> </soapenv:Envelope> '
There is also search by user email (just like in original SOAP overlay example):
curl --user "administrator:5ecr3t" -d @- \ -H "Content-Type: text/xml;charset=UTF-8" \ http://localhost:8080/midpoint/ws/soap/example-1 <<< ' <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:cus="https://midpoint.example.com/xml/ns/custom-soap-1"> <soapenv:Header/> <soapenv:Body> <cus:searchUserByEmail> <arg0> <cus:email>[email protected]</cus:email> </arg0> </cus:searchUserByEmail> </soapenv:Body> </soapenv:Envelope> '
See our overlay documentation for more details about midPoint overlay projects. See midpoint-overlay-example for another simple overlay project (not WS specific).
SoapUI or similar tool makes it much easier to test SOAP web services as it is rather hard to construct the whole request XML manually. When you point SoapUI to the WSDL it will ask for authentication twice as there is additional request to an included part.
Don’t forget to add basic authentication to the requests and also check Pre-emptive auth.
|
Never reuse existing midPoint *Type classes in the custom SOAP service interface.
That is, do not use them as parameters or return types.
It is safe to use them in the method body, of course.
|
When using contract first (WSDL) approach all the code is generated for you and that’s what is used in the service.
With code first approach it is tempting to reuse existing types and let CXF to do its best (or what) to generate the WSDL.
Good advice - always write your types separate from midPoint types.
Especially midPoint "JAXB" SomethingType
classes are not really JAXB compliant.
Using those as input/output types is a guaranteed way to obscure errors.
The service will not work and WSDL will not be generated on the fly.
This example shows how to do it, you can even go with public fields if Sonar doesn’t kill you for it.
Service implementation should be the glue code that changes service interface types to various schema types and back.
It is not necessary to create separate service interface (as demonstrated by this overlay),
but extracting it can help with clear type separation.
There should be no midpoint
imports in the service interface file.