org.apache.juddi.v3.client.config.ClientConfig.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.juddi.v3.client.config.ClientConfig.java

Source

/*
 * Copyright 2001-2009 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package org.apache.juddi.v3.client.config;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.xml.crypto.dsig.CanonicalizationMethod;

import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.SystemConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.juddi.api_v3.Node;
import org.apache.juddi.v3.client.cryptor.CryptorFactory;
import org.apache.juddi.v3.client.cryptor.DigSigUtil;

/**
 * Handles the client configuration of the uddi-client. By default it first
 * looks at system properties. Then loads from the config file from the system property
 * "uddi.client.xml", next the user specified file, finally, "META-INF/uddi.xml"
 * 
 * @author <a href="mailto:kstam@apache.org">Kurt T Stam</a>
 */
public class ClientConfig {
    public final static String UDDI_CONFIG_FILENAME_PROPERTY = "uddi.client.xml";
    public final static String DEFAULT_UDDI_CONFIG = "META-INF/uddi.xml";
    private Log log = LogFactory.getLog(ClientConfig.class);
    private Configuration config = null;;
    private Map<String, UDDINode> uddiNodes = null;
    private Map<String, UDDIClerk> uddiClerks = null;
    private Set<XRegistration> xBusinessRegistrations = null;
    private Set<XRegistration> xServiceBindingRegistrations = null;
    private String clientName = null;
    private String clientCallbackUrl = null;
    private String configurationFile = null;

    /**
     * Constructor (note Singleton pattern).
     * @throws ConfigurationException
     */
    public ClientConfig(String configurationFile) throws ConfigurationException {
        loadConfiguration(configurationFile, null);
    }

    /**
     * Constructor (note Singleton pattern).
     * @throws ConfigurationException
     */
    public ClientConfig(String configurationFile, Properties properties) throws ConfigurationException {
        loadConfiguration(configurationFile, properties);
    }

    /**
     * Attempts to save any changes made to the configuration back to disk
     * @throws ConfigurationException 
     */
    public void saveConfig() throws ConfigurationException {

        XMLConfiguration saveConfiguration = new XMLConfiguration(configurationFile);
        Configuration cc = new CompositeConfiguration(saveConfiguration);
        Iterator<String> keys = this.config.getKeys();
        while (keys.hasNext()) {
            String key = keys.next();
            if (key.startsWith("client") || key.startsWith("config")) {
                cc.setProperty(key, config.getProperty(key));
            }
        }
        saveConfiguration.save();
    }

    protected void readConfig(Properties properties) throws ConfigurationException {
        uddiNodes = readNodeConfig(config, properties);
        uddiClerks = readClerkConfig(config, uddiNodes);
        xServiceBindingRegistrations = readXServiceBindingRegConfig(config, uddiClerks);
        xBusinessRegistrations = readXBusinessRegConfig(config, uddiClerks);
    }

    /**
     * Does the actual work of reading the configuration from System
     * Properties and/or uddi.xml file. When the uddi.xml
     * file is updated the file will be reloaded. By default the reloadDelay is
     * set to 1 second to prevent excessive date stamp checking.
     */
    private void loadConfiguration(String configurationFile, Properties properties) throws ConfigurationException {
        //Properties from system properties
        CompositeConfiguration compositeConfig = new CompositeConfiguration();
        compositeConfig.addConfiguration(new SystemConfiguration());
        //Properties from XML file
        if (System.getProperty(UDDI_CONFIG_FILENAME_PROPERTY) != null) {
            log.info("Using system property config override");
            configurationFile = System.getProperty(UDDI_CONFIG_FILENAME_PROPERTY);
        }
        XMLConfiguration xmlConfig = null;
        if (configurationFile != null) {
            xmlConfig = new XMLConfiguration(configurationFile);
        } else {
            final String filename = System.getProperty(UDDI_CONFIG_FILENAME_PROPERTY);
            if (filename != null) {
                xmlConfig = new XMLConfiguration(filename);
            } else {
                xmlConfig = new XMLConfiguration(DEFAULT_UDDI_CONFIG);
            }
        }
        log.info("Reading UDDI Client properties file " + xmlConfig.getBasePath() + " use -D"
                + UDDI_CONFIG_FILENAME_PROPERTY + " to override");
        this.configurationFile = xmlConfig.getBasePath();
        long refreshDelay = xmlConfig.getLong(Property.UDDI_RELOAD_DELAY, 1000l);
        log.debug("Setting refreshDelay to " + refreshDelay);
        FileChangedReloadingStrategy fileChangedReloadingStrategy = new FileChangedReloadingStrategy();
        fileChangedReloadingStrategy.setRefreshDelay(refreshDelay);
        xmlConfig.setReloadingStrategy(fileChangedReloadingStrategy);
        compositeConfig.addConfiguration(xmlConfig);
        //Making the new configuration globally accessible.
        config = compositeConfig;
        readConfig(properties);
    }

    private Map<String, UDDIClerk> readClerkConfig(Configuration config, Map<String, UDDINode> uddiNodes)
            throws ConfigurationException {
        clientName = config.getString("client[@name]");
        clientCallbackUrl = config.getString("client[@callbackUrl]");
        Map<String, UDDIClerk> clerks = new HashMap<String, UDDIClerk>();
        if (config.containsKey("client.clerks.clerk[@name]")) {
            String[] names = config.getStringArray("client.clerks.clerk[@name]");

            log.debug("clerk names=" + names.length);
            for (int i = 0; i < names.length; i++) {
                UDDIClerk uddiClerk = new UDDIClerk();
                uddiClerk.setManagerName(clientName);
                uddiClerk.setName(config.getString("client.clerks.clerk(" + i + ")[@name]"));
                String nodeRef = config.getString("client.clerks.clerk(" + i + ")[@node]");
                if (!uddiNodes.containsKey(nodeRef))
                    throw new ConfigurationException("Could not find Node with name=" + nodeRef);
                UDDINode uddiNode = uddiNodes.get(nodeRef);
                uddiClerk.setUDDINode(uddiNode);
                uddiClerk.setPublisher(config.getString("client.clerks.clerk(" + i + ")[@publisher]"));
                uddiClerk.setPassword(config.getString("client.clerks.clerk(" + i + ")[@password]"));
                uddiClerk.setIsPasswordEncrypted(
                        config.getBoolean("client.clerks.clerk(" + i + ")[@isPasswordEncrypted]", false));
                uddiClerk.setCryptoProvider(config.getString("client.clerks.clerk(" + i + ")[@cryptoProvider]"));

                String clerkBusinessKey = config.getString("client.clerks.clerk(" + i + ")[@businessKey]");
                String clerkBusinessName = config.getString("client.clerks.clerk(" + i + ")[@businessName]");
                String clerkKeyDomain = config.getString("client.clerks.clerk(" + i + ")[@keyDomain]");

                String[] classes = config.getStringArray("client.clerks.clerk(" + i + ").class");
                uddiClerk.setClassWithAnnotations(classes);

                int numberOfWslds = config.getStringArray("client.clerks.clerk(" + i + ").wsdl").length;
                if (numberOfWslds > 0) {
                    UDDIClerk.WSDL[] wsdls = new UDDIClerk.WSDL[numberOfWslds];
                    for (int w = 0; w < wsdls.length; w++) {
                        UDDIClerk.WSDL wsdl = uddiClerk.new WSDL();
                        String fileName = config.getString("client.clerks.clerk(" + i + ").wsdl(" + w + ")");
                        wsdl.setFileName(fileName);
                        String businessKey = config
                                .getString("client.clerks.clerk(" + i + ").wsdl(" + w + ")[@businessKey]");
                        String businessName = config
                                .getString("client.clerks.clerk(" + i + ").wsdl(" + w + ")[@businessName]");
                        String keyDomain = config
                                .getString("client.clerks.clerk(" + i + ").wsdl(" + w + ")[@keyDomain]");
                        if (businessKey == null)
                            businessKey = clerkBusinessKey;
                        if (businessKey == null)
                            businessKey = uddiClerk.getUDDINode().getProperties().getProperty("businessKey");
                        if (businessKey == null) {
                            //use key convention to build the businessKey
                            if (businessName == null)
                                businessName = clerkBusinessName;
                            if (keyDomain == null)
                                keyDomain = clerkKeyDomain;
                            if (keyDomain == null)
                                keyDomain = uddiClerk.getUDDINode().getProperties().getProperty("keyDomain");
                            if ((businessName == null
                                    && !uddiClerk.getUDDINode().getProperties().containsKey("businessName"))
                                    || keyDomain == null
                                            && !uddiClerk.getUDDINode().getProperties().containsKey("keyDomain"))
                                throw new ConfigurationException("Either the wsdl(" + wsdls[w] + ") or clerk ("
                                        + uddiClerk.name
                                        + ") elements require a businessKey, or businessName & keyDomain attributes");
                            else {
                                Properties properties = new Properties(uddiClerk.getUDDINode().getProperties());
                                if (businessName != null)
                                    properties.put("businessName", businessName);
                                if (keyDomain != null)
                                    properties.put("keyDomain", keyDomain);
                                businessKey = UDDIKeyConvention.getBusinessKey(properties);
                            }
                        }
                        if (!businessKey.toLowerCase().startsWith("uddi:")
                                || !businessKey.substring(5).contains(":")) {
                            throw new ConfigurationException("The businessKey " + businessKey
                                    + " does not implement a valid UDDI v3 key format.");
                        }
                        wsdl.setBusinessKey(businessKey);
                        if (keyDomain == null) {
                            keyDomain = businessKey.split(":")[1];
                        }
                        wsdl.setKeyDomain(keyDomain);
                        wsdls[w] = wsdl;
                    }
                    uddiClerk.setWsdls(wsdls);
                }

                clerks.put(names[i], uddiClerk);
            }
        }
        return clerks;
    }

    /**
     * signals that the specified classes/wsdls are registered with the UDDI server
     * when UDDIClient.start() is called
     * client.clerks[@registerOnStartup]
     * @return true/false
     */
    public boolean isRegisterOnStartup() {
        boolean isRegisterOnStartup = false;
        if (config.containsKey("client.clerks[@registerOnStartup]")) {
            isRegisterOnStartup = config.getBoolean("client.clerks[@registerOnStartup]");
        }
        return isRegisterOnStartup;
    }

    private Map<String, UDDINode> readNodeConfig(Configuration config, Properties properties)
            throws ConfigurationException {
        String[] names = config.getStringArray("client.nodes.node.name");
        Map<String, UDDINode> nodes = new HashMap<String, UDDINode>();
        log.debug("node names=" + names.length);
        for (int i = 0; i < names.length; i++) {
            UDDINode uddiNode = new UDDINode();
            String nodeName = config.getString("client.nodes.node(" + i + ").name");
            String[] propertyKeys = config
                    .getStringArray("client.nodes.node(" + i + ").properties.property[@name]");

            if (propertyKeys != null && propertyKeys.length > 0) {
                if (properties == null)
                    properties = new Properties();
                for (int p = 0; p < propertyKeys.length; p++) {
                    String name = config
                            .getString("client.nodes.node(" + i + ").properties.property(" + p + ")[@name]");
                    String value = config
                            .getString("client.nodes.node(" + i + ").properties.property(" + p + ")[@value]");
                    log.debug("Property: name=" + name + " value=" + value);
                    properties.put(name, value);
                }
                uddiNode.setProperties(properties);
            }

            uddiNode.setHomeJUDDI(config.getBoolean("client.nodes.node(" + i + ")[@isHomeJUDDI]", false));
            uddiNode.setName(
                    TokenResolver.replaceTokens(config.getString("client.nodes.node(" + i + ").name"), properties));
            uddiNode.setClientName(TokenResolver.replaceTokens(config.getString("client[@name]"), properties));
            uddiNode.setDescription(TokenResolver
                    .replaceTokens(config.getString("client.nodes.node(" + i + ").description"), properties));
            uddiNode.setProxyTransport(TokenResolver
                    .replaceTokens(config.getString("client.nodes.node(" + i + ").proxyTransport"), properties));
            uddiNode.setInquiryUrl(TokenResolver
                    .replaceTokens(config.getString("client.nodes.node(" + i + ").inquiryUrl"), properties));
            uddiNode.setInquiryRESTUrl(TokenResolver
                    .replaceTokens(config.getString("client.nodes.node(" + i + ").inquiryRESTUrl"), properties));
            uddiNode.setPublishUrl(TokenResolver
                    .replaceTokens(config.getString("client.nodes.node(" + i + ").publishUrl"), properties));
            uddiNode.setCustodyTransferUrl(TokenResolver.replaceTokens(
                    config.getString("client.nodes.node(" + i + ").custodyTransferUrl"), properties));
            uddiNode.setSecurityUrl(TokenResolver
                    .replaceTokens(config.getString("client.nodes.node(" + i + ").securityUrl"), properties));
            uddiNode.setSubscriptionUrl(TokenResolver
                    .replaceTokens(config.getString("client.nodes.node(" + i + ").subscriptionUrl"), properties));
            uddiNode.setSubscriptionListenerUrl(TokenResolver.replaceTokens(
                    config.getString("client.nodes.node(" + i + ").subscriptionListenerUrl"), properties));
            uddiNode.setJuddiApiUrl(TokenResolver
                    .replaceTokens(config.getString("client.nodes.node(" + i + ").juddiApiUrl"), properties));
            uddiNode.setFactoryInitial(TokenResolver.replaceTokens(
                    config.getString("client.nodes.node(" + i + ").javaNamingFactoryInitial"), properties));
            uddiNode.setFactoryURLPkgs(TokenResolver.replaceTokens(
                    config.getString("client.nodes.node(" + i + ").javaNamingFactoryUrlPkgs"), properties));
            uddiNode.setFactoryNamingProvider(TokenResolver.replaceTokens(
                    config.getString("client.nodes.node(" + i + ").javaNamingProviderUrl"), properties));
            nodes.put(nodeName, uddiNode);
        }
        return nodes;
    }

    private Set<XRegistration> readXBusinessRegConfig(Configuration config, Map<String, UDDIClerk> clerks)
            throws ConfigurationException {
        return readXRegConfig(config, clerks, "business");
    }

    private Set<XRegistration> readXServiceBindingRegConfig(Configuration config, Map<String, UDDIClerk> clerks)
            throws ConfigurationException {
        return readXRegConfig(config, clerks, "servicebinding");
    }

    private Set<XRegistration> readXRegConfig(Configuration config, Map<String, UDDIClerk> clerks,
            String entityType) throws ConfigurationException {
        String[] entityKeys = config.getStringArray("client.clerks.xregister." + entityType + "[@entityKey]");
        Set<XRegistration> xRegistrations = new HashSet<XRegistration>();
        if (entityKeys.length > 0)
            log.info("XRegistration " + entityKeys.length + " " + entityType + "Keys");
        for (int i = 0; i < entityKeys.length; i++) {
            XRegistration xRegistration = new XRegistration();
            xRegistration.setEntityKey(
                    config.getString("client.clerks.xregister." + entityType + "(" + i + ")[@entityKey]"));

            String fromClerkRef = config
                    .getString("client.clerks.xregister." + entityType + "(" + i + ")[@fromClerk]");
            if (!clerks.containsKey(fromClerkRef))
                throw new ConfigurationException("Could not find fromClerk with name=" + fromClerkRef);
            UDDIClerk fromClerk = clerks.get(fromClerkRef);
            xRegistration.setFromClerk(fromClerk);

            String toClerkRef = config.getString("client.clerks.xregister." + entityType + "(" + i + ")[@toClerk]");
            if (!clerks.containsKey(toClerkRef))
                throw new ConfigurationException("Could not find toClerk with name=" + toClerkRef);
            UDDIClerk toClerk = clerks.get(toClerkRef);
            xRegistration.setToClerk(toClerk);
            log.debug(xRegistration);

            xRegistrations.add(xRegistration);
        }
        return xRegistrations;
    }

    protected Map<String, UDDINode> getUDDINodes() {
        return uddiNodes;
    }

    /**
     * gets the current configuration's node list
     * only the node name, client name, descriptions and transport class are returned, everything else is nulled out for
     * security reasons. Only a copy of these values are returned
     * @return a list of nodes representing the config file as described
     */
    public List<Node> getUDDINodeList() {
        List<Node> ret = new ArrayList<Node>();
        Iterator<UDDINode> it = uddiNodes.values().iterator();
        while (it.hasNext()) {
            UDDINode next = it.next();
            Node n = new Node();
            n.setClientName(next.getClientName());
            n.setDescription(next.getDescription());
            n.setName(next.getName());
            n.setProxyTransport(next.getProxyTransport());
            ret.add(n);
        }
        return ret;
    }

    public UDDINode getHomeNode() throws ConfigurationException {
        if (uddiNodes == null)
            throw new ConfigurationException(
                    "The juddi client configuration " + "must contain at least one node element.");
        if (uddiNodes.values().size() == 1)
            return uddiNodes.values().iterator().next();
        for (UDDINode uddiNode : uddiNodes.values()) {
            if (uddiNode.isHomeJUDDI()) {
                return uddiNode;
            }
        }
        throw new ConfigurationException(
                "One of the node elements in the client configuration needs to a 'isHomeJUDDI=\"true\"' attribute.");
    }

    public UDDINode getUDDINode(String nodeName) throws ConfigurationException {
        if (!uddiNodes.containsKey(nodeName)) {
            throw new ConfigurationException(
                    "Node '" + nodeName + "' cannot be found in the config '" + getClientName() + "'");
        }
        return uddiNodes.get(nodeName);
    }

    public Map<String, UDDIClerk> getUDDIClerks() {
        return uddiClerks;
    }

    public Set<XRegistration> getXServiceBindingRegistrations() {
        return xServiceBindingRegistrations;
    }

    public Set<XRegistration> getXBusinessRegistrations() {
        return xBusinessRegistrations;
    }

    public Configuration getConfiguration() {
        return config;
    }

    public String getClientName() {
        return clientName;
    }

    @Deprecated
    public String getClientCallbackUrl() {
        return clientCallbackUrl;
    }

    public String getConfigurationFile() {
        return configurationFile;
    }

    /**
     * Used for WADL/WSDL to WSDL
     * @return true/false
     */
    public boolean isX_To_Wsdl_Ignore_SSL_Errors() {
        return this.config.getBoolean("client.XtoWsdl.IgnoreSSLErrors", false);
    }

    /**
     * Fetches all digital signature related properties for the digital signature utility.
     * warning, this will decrypt all passwords
     * @return a properties object
     * @throws Exception 
     * @see DigSigUtil
     * @see Properties
     */
    public Properties getDigitalSignatureConfiguration() throws Exception {
        Properties p = new Properties();
        p.setProperty(DigSigUtil.CANONICALIZATIONMETHOD,
                this.config.getString("client.signature.canonicalizationMethod", CanonicalizationMethod.EXCLUSIVE));
        p.setProperty(DigSigUtil.CHECK_TIMESTAMPS,
                ((Boolean) (this.config.getBoolean("client.signature.checkTimestamps", true))).toString());
        p.setProperty(DigSigUtil.CHECK_REVOCATION_STATUS_CRL,
                ((Boolean) (this.config.getBoolean("client.signature.checkRevocationCRL", true))).toString());
        p.setProperty(DigSigUtil.CHECK_REVOCATION_STATUS_OCSP,
                ((Boolean) (this.config.getBoolean("client.signature.checkRevocationOCSP", true))).toString());
        p.setProperty(DigSigUtil.CHECK_TRUST_CHAIN,
                ((Boolean) (this.config.getBoolean("client.signature.checkTrust", true))).toString());

        p.setProperty(DigSigUtil.SIGNATURE_KEYSTORE_FILE,
                this.config.getString("client.signature.signingKeyStorePath", ""));
        p.setProperty(DigSigUtil.SIGNATURE_KEYSTORE_FILETYPE,
                this.config.getString("client.signature.signingKeyStoreType", ""));

        if (this.config.getBoolean("client.signature.signingKeyPassword[@isPasswordEncrypted]", false)) {
            String enc = this.config.getString("client.signature.signingKeyPassword", "");
            String prov = this.config.getString("client.signature.signingKeyPassword[@cryptoProvider]", "");
            p.setProperty(DigSigUtil.SIGNATURE_KEYSTORE_KEY_PASSWORD, CryptorFactory.getCryptor(prov).decrypt(enc));
        } else {
            log.warn("Hey, you should consider encrypting your key password!");
            p.setProperty(DigSigUtil.SIGNATURE_KEYSTORE_KEY_PASSWORD,
                    this.config.getString("client.signature.signingKeyPassword", ""));
        }
        if (this.config.getBoolean("client.signature.signingKeyStoreFilePassword[@isPasswordEncrypted]", false)) {
            String enc = this.config.getString("client.signature.signingKeyStoreFilePassword", "");
            String prov = this.config.getString("client.signature.signingKeyStoreFilePassword[@cryptoProvider]",
                    "");
            p.setProperty(DigSigUtil.SIGNATURE_KEYSTORE_FILE_PASSWORD,
                    CryptorFactory.getCryptor(prov).decrypt(enc));
        } else {
            log.warn("Hey, you should consider encrypting your keystore password!");
            p.setProperty(DigSigUtil.SIGNATURE_KEYSTORE_FILE_PASSWORD,
                    this.config.getString("client.signature.signingKeyStoreFilePassword", ""));
        }

        p.setProperty(DigSigUtil.SIGNATURE_KEYSTORE_KEY_ALIAS,
                this.config.getString("client.signature.signingKeyAlias", ""));
        p.setProperty(DigSigUtil.SIGNATURE_METHOD, this.config.getString("client.signature.signatureMethod",
                "http://www.w3.org/2000/09/xmldsig#rsa-sha1"));
        p.setProperty(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SUBJECTDN,
                this.config.getString("client.signature.keyInfoInclusionSubjectDN", "true"));
        p.setProperty(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_BASE64,
                this.config.getString("client.signature.keyInfoInclusionBase64PublicKey", "true"));
        p.setProperty(DigSigUtil.SIGNATURE_OPTION_CERT_INCLUSION_SERIAL,
                this.config.getString("client.signature.keyInfoInclusionSerial", "true"));

        p.setProperty(DigSigUtil.SIGNATURE_OPTION_DIGEST_METHOD,
                this.config.getString("client.signature.digestMethod", "http://www.w3.org/2000/09/xmldsig#sha1"));

        p.setProperty(DigSigUtil.TRUSTSTORE_FILE, this.config.getString("client.signature.trustStorePath", ""));
        p.setProperty(DigSigUtil.TRUSTSTORE_FILETYPE, this.config.getString("client.signature.trustStoreType", ""));

        if (this.config.getBoolean("client.signature.trustStorePassword[@isPasswordEncrypted]", false)) {
            String enc = this.config.getString("client.signature.trustStorePassword", "");
            String prov = this.config.getString("client.signature.trustStorePassword[@cryptoProvider]", "");
            p.setProperty(DigSigUtil.TRUSTSTORE_FILE_PASSWORD, CryptorFactory.getCryptor(prov).decrypt(enc));
        } else {
            log.warn("Hey, you should consider encrypting your trust store password!");
            p.setProperty(DigSigUtil.TRUSTSTORE_FILE_PASSWORD,
                    this.config.getString("client.signature.trustStorePassword", ""));
        }

        return p;
    }
}