/******************************************************************************* * Open Behavioral Health Information Technology Architecture (OBHITA.org) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the <organization> nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ package gov.samhsa.acs.pep.wsclient; import gov.samhsa.acs.common.cxf.AbstractCXFLoggingConfigurerClient; import gov.samhsa.acs.common.tool.SimpleMarshallerImpl; import gov.samhsa.acs.pep.security.CredentialProvider; import gov.samhsa.acs.pep.security.CredentialProviderImpl; import gov.samhsa.ds4ppilot.contract.pep.PepPortType; import gov.samhsa.ds4ppilot.contract.pep.PepService; import gov.samhsa.ds4ppilot.contract.pep.PepService.PepPortTypeProxy; import gov.samhsa.ds4ppilot.schema.pep.DirectEmailSendRequest; import gov.samhsa.ds4ppilot.schema.pep.DirectEmailSendResponse; import ihe.iti.xds_b._2007.RetrieveDocumentSetRequest; import ihe.iti.xds_b._2007.RetrieveDocumentSetResponse; import java.net.URL; import java.util.Arrays; import java.util.LinkedList; import java.util.Optional; import java.util.Scanner; import javax.xml.namespace.QName; import javax.xml.ws.BindingProvider; import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryRequest; import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryResponse; import org.apache.cxf.endpoint.Client; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.ws.security.SecurityConstants; import org.apache.cxf.ws.security.tokenstore.SecurityToken; import org.apache.cxf.ws.security.tokenstore.TokenStore; import org.apache.cxf.ws.security.trust.STSClient; import org.apache.wss4j.common.util.DOM2Writer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.StringUtils; import org.w3c.dom.Element; /** * The Class PepWebServiceClient. */ public class PepWebServiceClient extends AbstractCXFLoggingConfigurerClient { /** The logger. */ private final Logger logger = LoggerFactory.getLogger(this.getClass()); /** The endpoint address. */ private final String endpointAddress; /** The credential provider. */ private final CredentialProvider credentialProvider; /** * Instantiates a new pep web service client. * * @param endpointAddress * the endpoint address * @param cp * the cp */ public PepWebServiceClient(String endpointAddress, CredentialProvider cp) { this.endpointAddress = endpointAddress; this.credentialProvider = cp; } /** * Direct email send. * * @param directEmailSendRequest * the direct email send request * @return the direct email send response */ public DirectEmailSendResponse directEmailSend( DirectEmailSendRequest directEmailSendRequest) { try (PepPortTypeProxy port = createPort()) { final DirectEmailSendResponse directEmailSend = port .directEmailSend(directEmailSendRequest); logSecurityTokenIfLoggingEnabled(port); return directEmailSend; } catch (final Exception e) { throw toPepWebServiceClientException(e); } } /** * Registry stored query. * * @param registeryStoredQueryRequest * the registery stored query request * @return the adhoc query response */ public AdhocQueryResponse registryStoredQuery( AdhocQueryRequest registeryStoredQueryRequest) { try (PepPortTypeProxy port = createPort()) { final AdhocQueryResponse registryStoredQuery = port .registryStoredQuery(registeryStoredQueryRequest); logSecurityTokenIfLoggingEnabled(port); return registryStoredQuery; } catch (final Exception e) { throw toPepWebServiceClientException(e); } } /** * Retrieve document set. * * @param retrieveDocumentSetRequest * the retrieve document set request * @return the retrieve document set response */ public RetrieveDocumentSetResponse retrieveDocumentSet( RetrieveDocumentSetRequest retrieveDocumentSetRequest) { try (PepPortTypeProxy port = createPort()) { final RetrieveDocumentSetResponse retrieveDocumentSet = port .retrieveDocumentSet(retrieveDocumentSetRequest); logSecurityTokenIfLoggingEnabled(port); return retrieveDocumentSet; } catch (final Exception e) { throw toPepWebServiceClientException(e); } } /** * Creates the port. * * @return the pep port type proxy */ private PepPortTypeProxy createPort() { return configurePort(this::createPortProxy); } /** * Creates the port. * * @return the pep port type proxy */ private PepPortTypeProxy createPortProxy() { final URL wsdlURL = this.getClass().getClassLoader() .getResource("Pep.wsdl"); final QName serviceName = new QName( "http://www.samhsa.gov/ds4ppilot/contract/pep", "PepService"); final PepService service = new PepService(wsdlURL, serviceName); final PepPortTypeProxy port = service.getXDSHTTPEndpoint(); final BindingProvider bp = port; final STSClient stsClient = (STSClient) bp.getRequestContext().get( "ws-security.sts.client"); stsClient.getProperties().put("ws-security.username", this.credentialProvider.getUsername()); if (StringUtils.hasText(endpointAddress)) { bp.getRequestContext().put( BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointAddress); } return port; } /** * Logs the security token. * * @param port * the port */ private void logSecurityToken(PepPortType port) { final Optional<Endpoint> ep = Optional.of(port) .map(ClientProxy::getClient).map(Client::getEndpoint); final Optional<String> tokenId = ep.map( e -> e.get(SecurityConstants.TOKEN_ID)).map(o -> (String) o); final Optional<TokenStore> tokenStore = ep .map(Endpoint::getEndpointInfo) .map(e -> e.getProperty(TokenStore.class.getName())) .map(ts -> (TokenStore) ts); final Optional<SecurityToken> securityToken = tokenId .flatMap(tid -> tokenStore.map(ts -> ts.getToken(tid))); final Optional<Element> tokenElement = securityToken .map(SecurityToken::getToken); logger.info(tokenElement.map(PepWebServiceClient::tokenElementToString) .orElse("ERROR while trying to log SecurityToken")); } /** * Log security token if logging enabled. * * @param port * the port */ private void logSecurityTokenIfLoggingEnabled(PepPortTypeProxy port) { if (isEnableLoggingInterceptors()) { logSecurityToken(port); } } /** * To pep web service client exception. * * @param exception * the exception * @return the pep web service client exception */ private PepWebServiceClientException toPepWebServiceClientException( Exception exception) { logger.error("Error closing PepWebServiceClient port"); logger.error(exception.getMessage(), exception); return new PepWebServiceClientException(exception); } /** * The main method. * * @param args * the arguments * @throws Throwable * the throwable */ public static void main(String[] args) throws Throwable { try { // // set proxy // System.setProperty("http.proxyHost", "127.0.0.1"); // System.setProperty("https.proxyHost", "127.0.0.1"); // System.setProperty("http.proxyPort", "8888"); // System.setProperty("https.proxyPort", "8888"); final Boolean enableCXFLogging = Arrays.stream(args) .filter(arg -> arg.startsWith("-enableCXFLogging")) .findFirst().map(arg -> arg.split("=")[1]) .map(Boolean::parseBoolean).orElse(Boolean.FALSE); final String address = "http://localhost:8080/Pep-bl/services/PepService"; final PepWebServiceClient client = new PepWebServiceClient(address, new CredentialProviderImpl()); client.setEnableLoggingInterceptors(enableCXFLogging); final AdhocQueryResponse response1 = client .registryStoredQuery(constructAdhocQuery()); final SimpleMarshallerImpl marshaller = new SimpleMarshallerImpl(); System.out.println("Adhoc Response: " + marshaller.marshal(response1)); final Scanner scan = new Scanner(System.in); System.out.println("Please enter documentUniqueId:"); final LinkedList<String> documentIds = new LinkedList<String>(); boolean go = false; while (!go && scan.hasNextLine()) { final String command = scan.nextLine(); if ("go".equalsIgnoreCase(command)) { go = true; } else { documentIds.add(command); } } scan.close(); RetrieveDocumentSetResponse retrieveDocResp = null; try { retrieveDocResp = client .retrieveDocumentSet(constructRetrieveDocumentRequest(documentIds)); } catch (final Exception e) { e.printStackTrace(); } System.out.println("Retrieve Response: " + marshaller.marshal(retrieveDocResp)); if (null != retrieveDocResp.getDocumentResponse()) { System.out.println(new String(retrieveDocResp .getDocumentResponse().get(0).getDocument())); } } catch (final Exception e) { e.printStackTrace(); } finally { // // clean up proxy // final Properties sysProps = System.getProperties(); // sysProps.remove("http.proxyHost"); // sysProps.remove("https.proxyHost"); // sysProps.remove("http.proxyPort"); // sysProps.remove("https.proxyPort"); } } /** * Construct adhoc query. * * @return the adhoc query request * @throws Exception * the exception */ private static AdhocQueryRequest constructAdhocQuery() throws Exception { final SimpleMarshallerImpl marshaller = new SimpleMarshallerImpl(); final String reqString = " <ns3:AdhocQueryRequest xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:ns2=\"urn:oasis:names:tc:ebxml-regrep:xsd:rs:3.0\" xmlns=\"urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0\" xmlns:ns3=\"urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0\"><ns3:ResponseOption returnType=\"LeafClass\" returnComposedObjects=\"true\"/><AdhocQuery id=\"urn:uuid:14d4debf-8f97-4251-9a74-a90016b0af0d\"><Slot name=\"$XDSDocumentEntryPatientId\"><ValueList><Value>'d9d460e0-e1fc-11e4-941d-00155d0a6a16^^^&2.16.840.1.113883.4.357&ISO'</Value></ValueList></Slot><Slot name=\"$XDSDocumentEntryStatus\"><ValueList><Value>('urn:oasis:names:tc:ebxml-regrep:StatusType:Approved')</Value></ValueList></Slot><Slot name=\"$XDSDocumentEntryFormatCode\"><ValueList><Value>'2.16.840.1.113883.10.20.1^^HITSP'</Value></ValueList></Slot></AdhocQuery></ns3:AdhocQueryRequest>"; final AdhocQueryRequest request = marshaller.unmarshalFromXml( AdhocQueryRequest.class, reqString); return request; } /** * Construct retrieve document request. * * @param documentIds * the document ids * @return the retrieve document set request * @throws Exception * the exception */ private static RetrieveDocumentSetRequest constructRetrieveDocumentRequest( LinkedList<String> documentIds) throws Exception { final SimpleMarshallerImpl marshaller = new SimpleMarshallerImpl(); final StringBuilder builder = new StringBuilder(); builder.append("<urn:RetrieveDocumentSetRequest xmlns:urn=\"urn:ihe:iti:xds-b:2007\">"); for (final String documentId : documentIds) { builder.append("<urn:DocumentRequest><urn:RepositoryUniqueId>1.3.6.1.4.1.21367.2010.1.2.1040</urn:RepositoryUniqueId><urn:DocumentUniqueId>"); builder.append(documentId); builder.append("</urn:DocumentUniqueId></urn:DocumentRequest>"); } builder.append("</urn:RetrieveDocumentSetRequest>"); final RetrieveDocumentSetRequest request = marshaller.unmarshalFromXml( RetrieveDocumentSetRequest.class, builder.toString()); System.out.println("RetrieveDocumentSetRequest XML:" + builder.toString()); return request; } /** * Token element to string. * * @param e * the e * @return the string */ private static final String tokenElementToString(Element e) { return new StringBuilder() .append("\n******************** TOKEN ********************\n") .append(DOM2Writer.nodeToString(e)) .append("\n******************** TOKEN ********************") .toString(); } }