
com.github.skjolber.mockito.soap.SoapEndpointRule Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mockito-soap-cxf Show documentation
Show all versions of mockito-soap-cxf Show documentation
SOAP web-service mocking utility for CXF
package com.github.skjolber.mockito.soap;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.cxf.Bus;
import org.apache.cxf.endpoint.EndpointException;
import org.apache.cxf.endpoint.ServerImpl;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
import org.apache.cxf.service.ServiceImpl;
import org.apache.cxf.service.model.EndpointInfo;
import org.apache.cxf.transport.ChainInitiationObserver;
import org.apache.cxf.transport.Destination;
import org.apache.cxf.transport.DestinationFactory;
import org.apache.cxf.transport.DestinationFactoryManager;
import org.junit.ClassRule;
import jakarta.xml.ws.spi.Provider;
import jakarta.xml.ws.Endpoint;
/**
* Rule for mocking SOAP services using {@linkplain Endpoint}s. Multiple services can run on the same port.
* If used as a {@linkplain ClassRule}, the rule can be used to reserve random free ports.
* Resulting reserved ports are set as system properties to port names provided by the caller.
*
* @author [email protected]
*/
public class SoapEndpointRule extends SoapServiceRule {
private static final int PORT_RANGE_START = 1024+1;
private static final int PORT_RANGE_END = PortManager.PORT_RANGE_MAX;
public static SoapEndpointRule newInstance() {
return new SoapEndpointRule();
}
public static SoapEndpointRule newInstance(String ... portNames) {
return new SoapEndpointRule(portNames);
}
public static SoapEndpointRule newInstance(int portRangeStart, int portRangeEnd, String ... portNames) {
return new SoapEndpointRule(portRangeStart, portRangeEnd, portNames);
}
private Map endpoints = new HashMap<>();
private PortManager portManager;
public SoapEndpointRule() {
this(PORT_RANGE_START, PORT_RANGE_END);
}
public SoapEndpointRule(String ... portNames) {
this(PORT_RANGE_START, PORT_RANGE_END, portNames);
}
public SoapEndpointRule(int portRangeStart, int portRangeEnd, String ... portNames) {
portManager = new PortManager(portRangeStart, portRangeEnd) {
@Override
public Destination reserve(int port) throws Exception {
return createDestination(port);
}
@Override
public void release(Destination destination) {
destination.shutdown();
}
};
portManager.add(portNames);
}
/**
* Returns the port number that was reserved for the given name.
*
* @param portName port name
* @return a valid port number if the port has been reserved, -1 otherwise
*/
public int getPort(String portName) {
return portManager.getPort(portName);
}
/**
* Returns all port names and respective port numbers.
*
* @return a map of port name and port value (a valid port number
* if the port has been reserved, or -1 otherwise)
*/
public Map getPorts() {
return portManager.getPorts();
}
/**
* Attempt to reserve a port by starting a server.
*
* @param port port to reserve
* @return destination if successful
* @throws IOException
* @throws EndpointException
*/
private Destination createDestination(int port) throws IOException, EndpointException {
JaxWsServiceFactoryBean jaxWsServiceFactoryBean = new JaxWsServiceFactoryBean();
JaxWsServerFactoryBean serverFactoryBean = new JaxWsServerFactoryBean(jaxWsServiceFactoryBean);
Bus bus = serverFactoryBean.getBus();
String address = "http://localhost:" + port;
serverFactoryBean.setAddress(address);
DestinationFactory destinationFactory = bus.getExtension(DestinationFactoryManager.class).getDestinationFactoryForUri(address);
EndpointInfo ei = new EndpointInfo(null, Integer.toString(port));
ei.setAddress(address);
Destination destination = destinationFactory.getDestination(ei, bus);
ServiceImpl serviceImpl = new ServiceImpl();
org.apache.cxf.endpoint.Endpoint endpoint = new org.apache.cxf.endpoint.EndpointImpl(bus, serviceImpl, ei);
destination.setMessageObserver(new ChainInitiationObserver(endpoint , bus));
return destination;
}
@Override
public void proxy(T target, Class port, String address, String wsdlLocation, List schemaLocations, Map properties) {
assertValidParams(target, port, address);
if(endpoints.containsKey(address)) {
throw new IllegalArgumentException("Endpoint " + address + " already exists");
}
T serviceInterface = SoapServiceProxy.newInstance(target);
EndpointImpl endpoint = (EndpointImpl)Provider.provider().createEndpoint(null, serviceInterface);
if(wsdlLocation != null) {
endpoint.setWsdlLocation(wsdlLocation);
}
if(schemaLocations != null) {
endpoint.setSchemaLocations(schemaLocations);
}
endpoint.setProperties(processProperties(properties, wsdlLocation, schemaLocations));
Destination destination = portManager.getData(parsePort(address));
if(destination != null) {
ServerImpl server = endpoint.getServer();
server.setDestination(destination);
}
endpoint.publish(address);
endpoints.put(address, endpoint);
}
@Override
protected void before() {
// reserve all ports
portManager.start();
}
@Override
protected void after() {
destroy();
}
/**
* Stop and remove endpoints, keeping port reservations.
*/
public void clear() {
endpoints.values().forEach(EndpointImpl::stop);
endpoints.clear();
}
public void destroy() {
endpoints.values().forEach(endpoint -> {
endpoint.stop();
endpoint.getBus().shutdown(true);
});
endpoints.clear();
portManager.stop();
}
@Override
public void stop() {
endpoints.values().forEach(endpoint -> endpoint.getServer().stop());
}
@Override
public void start() {
// republish
endpoints.values().forEach(endpoint -> endpoint.getServer().start());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy