/* * JBoss, Home of Professional Open Source. * Copyright 2014, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.wsf.stack.cxf.addressRewrite; import static org.jboss.wsf.stack.cxf.Loggers.ADDRESS_REWRITE_LOGGER; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import org.jboss.wsf.spi.management.ServerConfig; import org.jboss.wsf.spi.metadata.config.SOAPAddressRewriteMetadata; /** * Helper for rewriting soap:address in published wsdl * * @author alessio.soldano@jboss.com * @author rsears@redhat.com * @since 30-Nov-2012 */ public class SoapAddressRewriteHelper { private static final String HTTP = "http"; private static final String HTTPS = "https"; /** * Rewrite and get address to be used for CXF published endpoint url prop (rewritten wsdl address) * * @param wsdlAddress The soap:address in the wsdl * @param epAddress The address that has been computed for the endpoint * @param sarm The deployment SOAPAddressRewriteMetadata * @return The rewritten soap:address to be used in the wsdl */ public static String getRewrittenPublishedEndpointUrl(String wsdlAddress, String epAddress, SOAPAddressRewriteMetadata sarm) { if (wsdlAddress == null) { return null; } if (isRewriteRequired(sarm, wsdlAddress)) { final String origUriScheme = getUriScheme(wsdlAddress); //will be https if the user wants a https address in the wsdl final String newUriScheme = getUriScheme(epAddress); //will be https if the user set confidential transport for the endpoint return rewriteSoapAddress(sarm, wsdlAddress, epAddress, rewriteUriScheme(sarm, origUriScheme, newUriScheme)); } else { return wsdlAddress; } } /** * Rewrite and get address to be used for CXF published endpoint url prop (rewritten wsdl address). * This method is to be used for code-first endpoints, when no wsdl is provided by the user. * * @param address The container computed endpoint address * @param sarm The deployment SOAPAddressRewriteMetadata * @return */ public static String getRewrittenPublishedEndpointUrl(String address, SOAPAddressRewriteMetadata sarm) { try { if (isPathRewriteRequired(sarm) || isSchemeRewriteRequired(sarm)) { final URL url = new URL(address); final String uriScheme = rewriteUriScheme(sarm, getUriScheme(address), null); final String port = getDotPortNumber(uriScheme, sarm); final StringBuilder builder = new StringBuilder(); builder.append(uriScheme); builder.append("://"); builder.append(url.getHost()); builder.append(port); final String path = url.getPath(); builder.append(isPathRewriteRequired(sarm) ? SEDProcessor.newInstance(sarm.getWebServicePathRewriteRule()).processLine(path) : path); final String newUrl = builder.toString(); ADDRESS_REWRITE_LOGGER.addressRewritten(address, newUrl); return newUrl; } else { ADDRESS_REWRITE_LOGGER.rewriteNotRequired(address); return address; } } catch (MalformedURLException e) { ADDRESS_REWRITE_LOGGER.invalidAddressProvidedUseItWithoutRewriting(address, ""); return address; } } public static void validatePathRewriteRule(String rule) { if (rule == null) { throw new IllegalArgumentException(); } SEDProcessor.newInstance(rule); } public static boolean isAutoRewriteOn(SOAPAddressRewriteMetadata sarm) { return sarm.isModifySOAPAddress() && ServerConfig.UNDEFINED_HOSTNAME.equals(sarm.getWebServiceHost()); } private static boolean isRewriteRequired(SOAPAddressRewriteMetadata sarm, String address) { //check config prop forcing address rewrite if (sarm.isModifySOAPAddress()) { ADDRESS_REWRITE_LOGGER.addressRewriteRequiredBecauseOfServerConf(address); return true; } //check if the previous address is not valid if (isInvalidAddress(address)) { ADDRESS_REWRITE_LOGGER.addressRewriteRequiredBecauseOfInvalidAddress(address); return true; } ADDRESS_REWRITE_LOGGER.rewriteNotRequired(address); return false; } private static boolean isInvalidAddress(String address) { if (address == null) { return true; } String s = address.trim(); if (s.length() == 0 || s.contains("REPLACE_WITH_ACTUAL_URL")) { return true; } try { new URL(s); } catch (MalformedURLException e) { return true; } return false; } /** * Rewrite the provided address according to the current server * configuration and always using the specified uriScheme. * * @param sarm The deployment SOAPAddressRewriteMetadata * @param origAddress The source address * @param newAddress The new (candidate) address * @param uriScheme The uriScheme to use for rewrite * @return The obtained address */ private static String rewriteSoapAddress(SOAPAddressRewriteMetadata sarm, String origAddress, String newAddress, String uriScheme) { try { URL url = new URL(newAddress); String path = url.getPath(); String host = sarm.getWebServiceHost(); String port = getDotPortNumber(uriScheme, sarm); StringBuilder sb = new StringBuilder(uriScheme); sb.append("://"); sb.append(host); sb.append(port); if (isPathRewriteRequired(sarm)) { sb.append(SEDProcessor.newInstance(sarm.getWebServicePathRewriteRule()).processLine(path)); } else { sb.append(path); } final String urlStr = sb.toString(); ADDRESS_REWRITE_LOGGER.addressRewritten(origAddress, urlStr); return urlStr; } catch (MalformedURLException e) { ADDRESS_REWRITE_LOGGER.invalidAddressProvidedUseItWithoutRewriting(newAddress, origAddress); return origAddress; } } private static String getDotPortNumber(String uriScheme, SOAPAddressRewriteMetadata sarm) { String port = ""; if (HTTPS.equals(uriScheme)) { int portNo = sarm.getWebServiceSecurePort(); if (portNo != 443) { port = ":" + portNo; } } else { int portNo = sarm.getWebServicePort(); if (portNo != 80) { port = ":" + portNo; } } return port; } private static String getUriScheme(String address) { try { URI addrURI = new URI(address); String scheme = addrURI.getScheme(); return scheme != null ? scheme : HTTP; } catch (URISyntaxException e) { return HTTP; } } public static boolean isPathRewriteRequired(SOAPAddressRewriteMetadata sarm){ if (!sarm.isModifySOAPAddress()) { return false; } final String pathRewriteRule = sarm.getWebServicePathRewriteRule(); return pathRewriteRule != null && !pathRewriteRule.isEmpty(); } public static boolean isSchemeRewriteRequired(SOAPAddressRewriteMetadata sarm) { if (!sarm.isModifySOAPAddress()) { return false; } return sarm.getWebServiceUriScheme() != null; } private static String rewriteUriScheme(final SOAPAddressRewriteMetadata sarm, final String origUriScheme, final String newUriScheme) { //1) if either of orig URI or new URI uses HTTPS, use HTTPS String uriScheme = (HTTPS.equals(origUriScheme) || HTTPS.equals(newUriScheme)) ? HTTPS : HTTP; //2) server / deployment configuration override final String serverUriScheme = sarm.getWebServiceUriScheme(); if (serverUriScheme != null) { uriScheme = serverUriScheme; } return uriScheme; } }