From 78f0715d86a055aed11138df5f66b0794e72326a Mon Sep 17 00:00:00 2001 From: Christof Rabensteiner Date: Wed, 3 Jul 2019 15:27:14 +0200 Subject: Refactor: Restructure Project - Move components that depend on the service contracts into scheme package. - Move cxf related components into util package. - Rename SameThread to SingleThreaded. --- .../java/at/gv/egiz/moazs/util/ClientFactory.java | 111 +++++++++++++++++++++ ...StoreSOAPBodyBinaryInRepositoryInterceptor.java | 64 ++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 src/main/java/at/gv/egiz/moazs/util/ClientFactory.java create mode 100644 src/main/java/at/gv/egiz/moazs/util/StoreSOAPBodyBinaryInRepositoryInterceptor.java (limited to 'src/main/java/at/gv/egiz/moazs/util') diff --git a/src/main/java/at/gv/egiz/moazs/util/ClientFactory.java b/src/main/java/at/gv/egiz/moazs/util/ClientFactory.java new file mode 100644 index 0000000..e7761fe --- /dev/null +++ b/src/main/java/at/gv/egiz/moazs/util/ClientFactory.java @@ -0,0 +1,111 @@ +package at.gv.egiz.moazs.util; + +import at.gv.zustellung.app2mzs.xsd.ClientType; +import at.gv.zustellung.app2mzs.xsd.KeyStoreType; +import at.gv.zustellung.app2mzs.xsd.SSLType; +import org.apache.cxf.configuration.jsse.TLSClientParameters; +import org.apache.cxf.endpoint.Client; +import org.apache.cxf.frontend.ClientProxy; +import org.apache.cxf.jaxws.JaxWsClientFactoryBean; +import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; +import org.apache.cxf.transport.http.HTTPConduit; +import org.apache.cxf.transports.http.configuration.HTTPClientPolicy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.Nullable; +import javax.net.ssl.SSLContext; +import javax.xml.ws.BindingProvider; +import javax.xml.ws.soap.SOAPBinding; + +import static at.gv.zustellung.app2mzs.xsd.KeyStoreType.keyStoreTypeBuilder; + +@Component +public class ClientFactory { + + private static final Logger log = LoggerFactory.getLogger(ClientFactory.class); + + private final StoreSOAPBodyBinaryInRepositoryInterceptor storeResponseInterceptor; + private final SSLContextCreator sslContextCreator; + private final FileUtils fileUtils; + + @Autowired + public ClientFactory(StoreSOAPBodyBinaryInRepositoryInterceptor storeResponseInterceptor, + SSLContextCreator creator, + FileUtils fileUtils) { + this.storeResponseInterceptor = storeResponseInterceptor; + this.sslContextCreator = creator; + this.fileUtils = fileUtils; + } + + /** + * Creates a client that communicates with a soap service. + * + * @param params for the client, such as service url and ssl parameters. + * @return the client + */ + public T create(ClientType params, Class clazz) { + + var factory = new JaxWsClientFactoryBean(); + factory.setServiceClass(clazz); + factory.setAddress(params.getURL()); + factory.getInInterceptors().add(storeResponseInterceptor); + + var proxy = new JaxWsProxyFactoryBean(factory).create(); + Client client = ClientProxy.getClient(proxy); + HTTPConduit http = (HTTPConduit) client.getConduit(); + + var bindingProvider = (BindingProvider) proxy; + SOAPBinding binding = (SOAPBinding) bindingProvider.getBinding(); + binding.setMTOMEnabled(true); + + var httpClientPolicy = new HTTPClientPolicy(); + httpClientPolicy.setConnectionTimeout(params.getConnectionTimeout().longValueExact()); + httpClientPolicy.setReceiveTimeout(params.getReceiveTimeout().longValueExact()); + http.setClient(httpClientPolicy); + + if (params.getURL().startsWith("https")) { + TLSClientParameters tlsParams = setupTLSParams(params.getSSL()); + http.setTlsClientParameters(tlsParams); + log.info("SSLContext initialized. "); + } + + return ((T)proxy); + } + + private TLSClientParameters setupTLSParams(SSLType ssl) { + + var tlsParams = new TLSClientParameters(); + var keystore = resolveKeyStorePath(ssl.getKeyStore()); + + SSLContext sslContext; + if (ssl.isTrustAll()) { + sslContext = sslContextCreator.createUnsafeSSLContext(keystore); + } else { + var truststore = resolveKeyStorePath(ssl.getTrustStore()); + sslContext = sslContextCreator.createSSLContext(keystore, truststore); + } + tlsParams.setSSLSocketFactory(sslContext.getSocketFactory()); + + if (ssl.isLaxHostNameVerification()) { + tlsParams.setDisableCNCheck(true); + } + + return tlsParams; + } + + private KeyStoreType resolveKeyStorePath(@Nullable KeyStoreType store) { + + if (store == null) return null; + + var resolvedURI = "file:" + fileUtils.determinePath(store.getFileName()); + log.trace("Resolved key store path from {} to {}.", store.getFileName(), resolvedURI); + + return keyStoreTypeBuilder(store) + .withFileName(resolvedURI) + .build(); + } + +} diff --git a/src/main/java/at/gv/egiz/moazs/util/StoreSOAPBodyBinaryInRepositoryInterceptor.java b/src/main/java/at/gv/egiz/moazs/util/StoreSOAPBodyBinaryInRepositoryInterceptor.java new file mode 100644 index 0000000..2db81ab --- /dev/null +++ b/src/main/java/at/gv/egiz/moazs/util/StoreSOAPBodyBinaryInRepositoryInterceptor.java @@ -0,0 +1,64 @@ +package at.gv.egiz.moazs.util; + +import at.gv.egiz.moazs.repository.DeliveryRepository; +import at.gv.egiz.moazs.scheme.SOAPUtils; +import org.apache.cxf.message.Message; +import org.apache.cxf.phase.AbstractPhaseInterceptor; +import org.apache.cxf.phase.Phase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import static at.gv.egiz.moazs.MoaZSException.moaZSException; + +@Component +public class StoreSOAPBodyBinaryInRepositoryInterceptor extends AbstractPhaseInterceptor { + + private static final Logger log = LoggerFactory.getLogger(StoreSOAPBodyBinaryInRepositoryInterceptor.class); + + private final CXFMessageUtils messageUtils; + private final SOAPUtils soapUtils; + private final DeliveryRepository repository; + + @Autowired + public StoreSOAPBodyBinaryInRepositoryInterceptor(CXFMessageUtils extractor, SOAPUtils soapUtils, + DeliveryRepository repository) { + super(Phase.RECEIVE); + this.messageUtils = extractor; + this.soapUtils = soapUtils; + this.repository = repository; + } + + public void handleMessage(Message message) { + + try { + byte[] content = messageUtils.copyContent(message); + + if(log.isTraceEnabled()) { + log.trace("Interceptor received this SOAP message: {}. ", new String(content, StandardCharsets.UTF_8)); + } + + if(content.length > 0) { + Element document = soapUtils.toDOM(content); + byte[] status = soapUtils.unwrapSoapEnvelope(document); + String appDeliveryID = soapUtils.getAppDeliveryIDFrom(document); + repository.addSignedDeliveryRequestStatus(status, appDeliveryID); + + if(log.isTraceEnabled()) { + log.trace("DeliveryRequestStatus with AppDeliveryID={} unwrapped and stored: {}. ", + appDeliveryID, new String(status, StandardCharsets.UTF_8)); + } + } + } catch (ParserConfigurationException | SAXException | IOException | NullPointerException e) { + throw moaZSException("Could not extract signed data from message.", e); + } + } + +} -- cgit v1.2.3