/* * Copyright (c) WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * 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.wso2.carbon.bpel.common; import org.apache.axiom.om.OMAttribute; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMXMLBuilderFactory; import org.apache.axiom.om.OMXMLParserWrapper; import org.apache.axiom.om.impl.builder.StAXOMBuilder; import org.apache.axis2.AxisFault; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.deployment.ServiceBuilder; import org.apache.axis2.description.AxisService; import org.apache.axis2.description.Parameter; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.bpel.common.config.EndpointConfiguration; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.context.RegistryType; import org.wso2.carbon.registry.api.Registry; import org.wso2.carbon.registry.api.RegistryException; import org.wso2.carbon.registry.api.Resource; import org.wso2.carbon.unifiedendpoint.core.UnifiedEndpointConstants; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.Iterator; /** * Configure the service based on the services.xml file provided with the bpel archive. */ public class ServiceConfigurationUtil { private static final Log log = LogFactory.getLog(ServiceConfigurationUtil.class); public static void configureService(AxisService axisService, EndpointConfiguration endpointConf, ConfigurationContext configCtx) throws AxisFault { if (endpointConf != null && endpointConf.isServiceDescriptionAvailable() && StringUtils.isNotEmpty(endpointConf.getServiceDescriptionLocation())) { OMElement documentEle = getServiceElement(endpointConf); if (documentEle != null) { if (log.isDebugEnabled()) { log.debug("Configuring service " + axisService.getName() + " using: " + endpointConf.getServiceDescriptionLocation()); } ServiceBuilder builder = new ServiceBuilder(configCtx, axisService); Iterator itr = documentEle.getChildElements(); while (itr.hasNext()) { OMElement serviceEle = (OMElement) itr.next(); if (serviceEle.getLocalName().toLowerCase().equals("service")) { if (serviceEle.getAttribute(new QName("name")) != null && serviceEle.getAttribute(new QName("name")).getAttributeValue().equals(axisService.getName())) { builder.populateService(serviceEle); // This is a hack to avoid security configurations get persisted when we configure using // services.xml file or policy.xml file BPEL package. But this should be fix at the // Carbon Persistence manager. Parameter param = new Parameter( BusinessProcessConstants.CONFIGURED_USING_BPEL_PKG_CONFIG_FILES, "true"); axisService.addParameter(param); } } } } } } private static OMElement getServiceElement(EndpointConfiguration endpointConfig) { OMElement serviceElement; String serviceDescriptionLocation = endpointConfig.getServiceDescriptionLocation(); if (!serviceDescriptionLocation.startsWith(UnifiedEndpointConstants.VIRTUAL_GOV_REG) && !serviceDescriptionLocation.startsWith(UnifiedEndpointConstants.VIRTUAL_CONF_REG) && !serviceDescriptionLocation.startsWith(UnifiedEndpointConstants.VIRTUAL_REG)) { if (serviceDescriptionLocation.startsWith(UnifiedEndpointConstants.VIRTUAL_FILE)) { serviceDescriptionLocation = serviceDescriptionLocation.substring(UnifiedEndpointConstants.VIRTUAL_FILE. length()); } if (!EndpointConfiguration.isAbsolutePath(serviceDescriptionLocation)) { serviceDescriptionLocation = endpointConfig.getBasePath() + File.separator + serviceDescriptionLocation; } serviceElement = readOMElementFromFile(serviceDescriptionLocation); } else { serviceElement = readOMElementFromRegistry(serviceDescriptionLocation); } // We need to check whether policy file is embedded within the services.xml or it is referred from the // file system using <policy key="custom_policy_file.xml" if(serviceElement != null) { loadAndEmbedPolicy(serviceElement, endpointConfig); } return serviceElement; } //If the service file is located in the file system, read if from the file. private static OMElement readOMElementFromFile(String fileLocation) { OMElement element = null; File serviceDescFile = new File(fileLocation); if (serviceDescFile.exists()) { InputStream fis = null; try { fis = new FileInputStream(serviceDescFile); OMXMLParserWrapper omBuilder = OMXMLBuilderFactory.createOMBuilder(fis); element = omBuilder.getDocumentElement(); element.build(); } catch (FileNotFoundException ex ) { log.error("Error while processing the services file : " + fileLocation, ex); } // finally { // if(fis != null) { // IOUtils.closeQuietly(fis); // } // } } return element; } //If the service file is located in the registry, read if from the registry. private static OMElement readOMElementFromRegistry(String registryLocation) { OMElement serviceElement = null; Registry registry; String location; if (registryLocation.startsWith(UnifiedEndpointConstants.VIRTUAL_CONF_REG)) { registry = CarbonContext.getThreadLocalCarbonContext().getRegistry(RegistryType.SYSTEM_CONFIGURATION); location = registryLocation.substring(registryLocation.indexOf( UnifiedEndpointConstants.VIRTUAL_CONF_REG) + UnifiedEndpointConstants.VIRTUAL_CONF_REG.length()); serviceElement = loadOMElement(registry, location); } else if (registryLocation.startsWith(UnifiedEndpointConstants.VIRTUAL_GOV_REG)) { registry = CarbonContext.getThreadLocalCarbonContext().getRegistry(RegistryType.SYSTEM_GOVERNANCE); location = registryLocation.substring(registryLocation.indexOf( UnifiedEndpointConstants.VIRTUAL_GOV_REG) + UnifiedEndpointConstants.VIRTUAL_GOV_REG.length()); serviceElement = loadOMElement(registry, location); } else if (registryLocation.startsWith(UnifiedEndpointConstants.VIRTUAL_REG)) { registry = CarbonContext.getThreadLocalCarbonContext().getRegistry(RegistryType.LOCAL_REPOSITORY); location = registryLocation.substring(registryLocation.indexOf( UnifiedEndpointConstants.VIRTUAL_REG) + UnifiedEndpointConstants.VIRTUAL_REG.length()); serviceElement = loadOMElement(registry, location); } else { String errMsg = "Invalid service.xml file location: " + registryLocation; log.warn(errMsg); } return serviceElement; } private static OMElement loadOMElement(Registry registry, String location) { OMElement serviceElement = null; ByteArrayInputStream bis = null; try { if (registry.resourceExists(location)) { Resource resource = registry.get(location); String resourceContent = new String((byte[]) resource.getContent()); bis = new ByteArrayInputStream(resourceContent.getBytes()); serviceElement = new StAXOMBuilder(bis).getDocumentElement(); serviceElement.build(); } else { String errMsg = "The resource: " + location + " does not exist."; log.warn(errMsg); } } catch (RegistryException | XMLStreamException e) { String errMsg = "Error occurred while creating the OMElement out of service.xml " + location; log.warn(errMsg, e); } // finally { // if(null != bis) { // IOUtils.closeQuietly(bis); // } // } return serviceElement; } private static void loadAndEmbedPolicy(OMElement serviceElement, EndpointConfiguration endpointConfiguration) { Iterator serviceIterator = serviceElement.getChildrenWithLocalName("service"); while(serviceIterator.hasNext()) { OMElement nextService = (OMElement)serviceIterator.next(); OMElement policy = nextService.getFirstChildWithName(new QName("policy")); if (policy != null) { OMAttribute key = policy.getAttribute(new QName("key")); if (key != null && null != key.getAttributeValue()) { String location = key.getAttributeValue(); OMElement policyElement = null; if (location.startsWith(UnifiedEndpointConstants.VIRTUAL_CONF_REG) || location.startsWith(UnifiedEndpointConstants.VIRTUAL_GOV_REG) || location.startsWith(UnifiedEndpointConstants.VIRTUAL_REG)) { policyElement = readOMElementFromRegistry(location); } else { if (location.startsWith(UnifiedEndpointConstants.VIRTUAL_FILE)) { // load the policy file from file system location = location.substring(UnifiedEndpointConstants.VIRTUAL_FILE.length()); } if(!EndpointConfiguration.isAbsolutePath(location)) { location = endpointConfiguration.getBasePath() + File.separator + location; } policyElement = readOMElementFromFile(location); } if (policyElement != null) { policy.detach(); nextService.addChild(policyElement); if (log.isDebugEnabled()) { log.debug(" Processed Service descriptor : " + serviceElement.toString()); } } } else { if (log.isDebugEnabled()) { log.debug("Policy file not correctly specified when referring using <policy key=... syntax"); } } } } } }