/* * Copyright WSO2, Inc. (http://wso2.com) * * 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.cloud.gateway.agent.service; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.util.Base64; import org.apache.axis2.AxisFault; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; import org.apache.axis2.description.AxisOperation; import org.apache.axis2.description.AxisService; import org.apache.axis2.description.TransportInDescription; import org.apache.axis2.description.TransportOutDescription; import org.apache.axis2.engine.AxisConfiguration; import org.apache.axis2.engine.AxisEvent; import org.apache.axis2.wsdl.WSDLConstants; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.cloud.gateway.agent.CGAgentPollingTaskFlags; import org.wso2.carbon.cloud.gateway.agent.CGAgentUtils; import org.wso2.carbon.cloud.gateway.agent.client.AuthenticationClient; import org.wso2.carbon.cloud.gateway.agent.client.CGAdminClient; import org.wso2.carbon.cloud.gateway.agent.transport.CGPollingTransportReceiver; import org.wso2.carbon.cloud.gateway.agent.transport.CGPollingTransportSender; import org.wso2.carbon.cloud.gateway.common.CGConstant; import org.wso2.carbon.cloud.gateway.common.CGException; import org.wso2.carbon.cloud.gateway.common.CGServerBean; import org.wso2.carbon.cloud.gateway.common.CGUtils; import org.wso2.carbon.cloud.gateway.common.thrift.CGThriftClient; import org.wso2.carbon.cloud.gateway.stub.types.common.CGProxyToolsURLs; import org.wso2.carbon.cloud.gateway.stub.types.common.CGServiceMetaDataBean; import org.wso2.carbon.cloud.gateway.stub.types.common.CGThriftServerBean; import org.wso2.carbon.core.AbstractAdmin; import org.wso2.carbon.core.persistence.PersistenceFactory; import org.wso2.carbon.core.persistence.ServicePersistenceManager; import org.wso2.carbon.core.transports.TransportService; import org.wso2.carbon.core.transports.util.TransportSummary; import org.wso2.carbon.core.util.CryptoException; import org.wso2.carbon.core.util.CryptoUtil; import org.wso2.carbon.core.util.SystemFilter; import org.wso2.carbon.registry.api.Collection; import org.wso2.carbon.registry.api.RegistryException; import org.wso2.carbon.registry.api.Resource; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.jdbc.utils.Transaction; import org.wso2.carbon.core.Resources; import org.wso2.carbon.service.mgt.ServiceAdmin; import org.wso2.carbon.cloud.gateway.agent.CGAgentWsdlDependencyResolver; import org.wso2.carbon.cloud.gateway.stub.types.common.CGServiceDependencyBean; import org.wso2.carbon.utils.ServerConstants; import javax.xml.namespace.QName; import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; /** * The class <code>CGAgentAdminService</code> provides the admin service to manipulate the * CGAgent remotely */ public class CGAgentAdminService extends AbstractAdmin { private static final Log log = LogFactory.getLog(CGAgentAdminService.class); /** * Deploy the proxy service * * @param serviceName the service to deploy * @param serverName the serverName to publish * @param isAutomatic the mode of service publishing * @throws org.wso2.carbon.cloud.gateway.common.CGException * throws in case of an error */ public void publishService(String serviceName, String serverName, boolean isAutomatic) throws CGException { try { CGServerBean csgServer = getCGServerBean(serverName); if (csgServer == null) { handleException("No persist information found for the server'" + serverName + "'"); } if (getAxisConfig().getService(serviceName) == null) { handleException("AxisService is null for service '" + serviceName + "'"); } CGAdminClient csgAdminClient = getCGAdminClient(csgServer); if (csgAdminClient == null) { handleException("CGAdminClient is null"); } handleServicePublishing(serviceName, serverName, isAutomatic, csgAdminClient, csgServer); // deploy proxy CGServiceMetaDataBean cgServiceMetaData = getCGServiceMetaData(getAxisConfig().getService(serviceName), csgServer.getDomainName(), serverName); csgAdminClient.deployProxy(cgServiceMetaData); flagServiceStatus(serviceName, serverName, cgServiceMetaData, true, isAutomatic); AxisService service = getAxisConfig().getService(serviceName); service.removeExposedTransport(CGConstant.CG_POLLING_TRANSPORT_NAME); } catch (Exception e) { handleException("Could not publish service '" + serviceName + "'. " + e.getMessage(), e); } } public void rePublishService(String serviceName, String serverName, boolean isAutomatic) throws CGException { try { CGServerBean csgServer = getCGServerBean(serverName); if (csgServer == null) { handleException("No persist information found for the server'" + serverName + "'"); } CGAdminClient csgAdminClient = getCGAdminClient(csgServer); if (csgAdminClient == null) { handleException("CGAdminClient is null"); } handleServicePublishing(serviceName, serverName, isAutomatic, csgAdminClient, csgServer); flagServiceStatus(serviceName, serverName, null, true, isAutomatic); } catch (CGException e) { handleException("Cloud not republish service '" + serviceName + "'", e); } } /** * Un-deploy the proxy service * * @param serviceName the service to un-deploy * @param serverName the server name to publish * @param isCheckBackend check the backend availability * @throws org.wso2.carbon.cloud.gateway.common.CGException * throws in case of an error */ public void unPublishService(String serviceName, String serverName, boolean isCheckBackend) throws CGException { if (serviceName == null) { handleException("The service name is not supplied for un-publishing"); } try { AxisService service = getAxisConfig().getService(serviceName); if (service == null) { handleException("No service is found with the name '" + serviceName + "'"); } service.removeExposedTransport(CGConstant.CG_POLLING_TRANSPORT_NAME); CGServerBean csgServer = getCGServerBean(serverName); if (csgServer == null) { throw new CGException("No CG server information found with the name '" + serverName + "'"); } CGAdminClient csgAdminClient = getCGAdminClient(csgServer); if (csgAdminClient == null && isCheckBackend) { handleException("CGAdminClient is null"); } // flag this service's polling task for shutdown CGAgentPollingTaskFlags.flagForShutDown(serviceName, true); if (csgAdminClient != null) { csgAdminClient.unDeployProxy(serviceName); } else { log.warn("Could not un-publish the service in the remote CG server, You need to manually un-publish "); } flagServiceStatus(serviceName, serverName, null, false, false); } catch (Exception e) { handleException("Could not un-publish the service '" + serviceName + "'", e); } } /** * Add a new CG server and store it in registry * * @param csgServer new csg server instance * @throws org.wso2.carbon.cloud.gateway.common.CGException * throws in case of an error */ public void addCGServer(CGServerBean csgServer) throws CGException { try { // authenticate using provided credentials and if logged in persist the server loggingToRemoteCGServer(csgServer); org.wso2.carbon.registry.core.Registry registry = getConfigSystemRegistry(); CGAgentUtils.persistServer(registry, csgServer); } catch (Exception e) { handleException("Could not add CG server '" + csgServer.getName() + "'. Error is " + e.getMessage(), e); } } /** * Get the CG server given by the name * * @param csgServerName csg server name * @return the csg server instance * @throws org.wso2.carbon.cloud.gateway.common.CGException * throws in case of an error */ public CGServerBean getCGServer(String csgServerName) throws CGException { org.wso2.carbon.registry.core.Registry registry = getConfigSystemRegistry(); String resourcePath = CGConstant.REGISTRY_SERVER_RESOURCE_PATH + "/" + csgServerName; try { if (registry != null && registry.resourceExists(resourcePath)) { Resource resource = registry.get(resourcePath); return CGAgentUtils.getCGServerBean(resource); } } catch (RegistryException e) { handleException("Could not read the registry resource '" + resourcePath + "'. Error is " + e.getMessage(), e); } return null; } /** * Get the set of CSG servers * * @return the list of CG_TRANSPORT_NAME servers * @throws org.wso2.carbon.cloud.gateway.common.CGException * throws in case of an error */ public CGServerBean[] getCGServerList() throws CGException { try { org.wso2.carbon.registry.core.Registry registry = getConfigSystemRegistry(); if (registry != null && registry.resourceExists(CGConstant.REGISTRY_SERVER_RESOURCE_PATH)) { Resource resource = registry.get(CGConstant.REGISTRY_SERVER_RESOURCE_PATH); if (resource instanceof Collection) { Collection collection = (Collection) resource; int size = collection.getChildCount(); CGServerBean[] beanInfo = new CGServerBean[size]; String[] child = collection.getChildren(); for (int i = 0; child.length > i; i++) { String s = child[i]; // returns the set of path Resource childResource = registry.get(s); beanInfo[i] = CGAgentUtils.getCGServerBean(childResource); } return beanInfo; } } } catch (RegistryException e) { handleException("Could not retrieve the CSG server list. Error is " + e.getMessage(), e); } return null; } /** * Update the CSG server and persist new information into registry * * @param csgServer new csg server information * @throws org.wso2.carbon.cloud.gateway.common.CGException * throws in case of an error */ public void updateCGServer(CGServerBean csgServer) throws CGException { // check if the new user can log in loggingToRemoteCGServer(csgServer); boolean isTransactionAlreadyStarted = Transaction.isStarted(); boolean isTransactionSuccess = true; org.wso2.carbon.registry.core.Registry registry = getConfigSystemRegistry(); String resource = CGConstant.REGISTRY_SERVER_RESOURCE_PATH + "/" + csgServer.getName(); try { if (!isTransactionAlreadyStarted) { // start a transaction only if we are not in one. registry.beginTransaction(); } if (registry != null && registry.resourceExists(resource)) { // delete the resource and add it again registry.delete(resource); CGAgentUtils.persistServer(registry, csgServer); } } catch (RegistryException e) { isTransactionSuccess = false; handleException("Could not read the registry resource '" + resource + "'. Error is " + e.getMessage(), e); } finally { if (!isTransactionAlreadyStarted) { // commit or rollback the transaction since we started it. try { if (isTransactionSuccess) { registry.commitTransaction(); } else { registry.rollbackTransaction(); } } catch (RegistryException re) { handleException("Error occurred while trying to rollback or commit the " + "transaction", re); } } } } /** * Remove the CSG server given by the name * * @param csgServerName the csg server name * @throws org.wso2.carbon.cloud.gateway.common.CGException * throws in case of an error */ public void removeCGServer(String csgServerName) throws CGException { boolean isTransactionAlreadyStarted = Transaction.isStarted(); boolean isTransactionSuccess = true; org.wso2.carbon.registry.core.Registry registry = getConfigSystemRegistry(); try { if (!isTransactionAlreadyStarted) { // start a transaction only if we are not in one. registry.beginTransaction(); } String resource = CGConstant.REGISTRY_SERVER_RESOURCE_PATH + "/" + csgServerName; if (registry != null && registry.resourceExists(resource)) { if (!isHasPublishedServices(csgServerName)) { registry.delete(resource); } else { handleException(csgServerName + " has services published onto it."); } } else { log.error("The resource '" + resource + "' does not exist!"); } } catch (Exception e) { isTransactionSuccess = false; handleException("Could not remove the CSG server: " + csgServerName + ". Error is " + e.getMessage(), e); } finally { if (!isTransactionAlreadyStarted) { try { if (isTransactionSuccess) { // commit the transaction since we started it. registry.commitTransaction(); } else { registry.rollbackTransaction(); } } catch (RegistryException re) { handleException("Error occurred while trying to rollback or commit " + "the transaction", re); } } } } /** * Returns the status of the service * * @param serviceName service name * @return a string states representing the service status * @throws org.wso2.carbon.cloud.gateway.common.CGException * throws in case of an error */ public String getServiceStatus(String serviceName) throws CGException { try { org.wso2.carbon.registry.core.Registry registry = getConfigSystemRegistry(); String resourcePath = CGConstant.REGISTRY_FLAG_RESOURCE_PATH + "/" + serviceName + ".flag"; if (registry != null && registry.resourceExists(resourcePath)) { Resource resource = registry.get(resourcePath); return new String((byte[]) resource.getContent()); } } catch (Exception e) { handleException("Could not retrieve the service publish flag for service '" + serviceName + "'", e); } return CGConstant.CG_SERVICE_STATUS_UNPUBLISHED; } public void setServiceStatus(String serviceName, String status) throws CGException { boolean isTransactionAlreadyStarted = Transaction.isStarted(); boolean isTransactionSuccess = true; org.wso2.carbon.registry.core.Registry registry = getConfigSystemRegistry(); try { if (!isTransactionAlreadyStarted) { // start a new transaction if there exists none. registry.beginTransaction(); } org.wso2.carbon.registry.core.Resource resource = registry.newResource(); resource.setContent(status); registry.put(CGConstant.REGISTRY_FLAG_RESOURCE_PATH + "/" + serviceName + ".flag", resource); } catch (Exception e) { isTransactionSuccess = false; handleException("Could not retrieve the service publish flag for service '" + serviceName + "'", e); } finally { if (!isTransactionAlreadyStarted) { try { if (isTransactionSuccess) { // commit the transaction since we started it. registry.commitTransaction(); } else { registry.rollbackTransaction(); } } catch (RegistryException re) { handleException("Error occurred while trying to rollback or " + "commit the transaction", re); } } } } public void doServiceUpdate(String serviceName, int eventType) throws CGException { String publishedServer = getPublishedServer(serviceName); if (publishedServer != null) { CGServerBean csgServer = getCGServerBean(publishedServer); if (csgServer == null) { handleException("No persist information found for the server'" + publishedServer + "'"); } try { if (eventType == AxisEvent.SERVICE_REMOVE) { CGAdminClient csgAdminClient = getCGAdminClient(csgServer); if (csgAdminClient == null) { handleException("CGAdminClient is null"); } // flag this service's polling task for shutdown CGAgentPollingTaskFlags.flagForShutDown(serviceName, true); csgAdminClient.unDeployProxy(serviceName); flagServiceStatus(serviceName, publishedServer, null, false, false); } } catch (Exception e) { handleException("Cloud not update service the service '" + serviceName + "'"); } } } /** * Get the server that this service has published to * * @param serviceName service name * @return the server that this service has published to * @throws org.wso2.carbon.cloud.gateway.common.CGException * throws in case of an error */ public String getPublishedServer(String serviceName) throws CGException { try { org.wso2.carbon.registry.core.Registry registry = getConfigSystemRegistry(); String serverResourcePath = CGConstant.REGISTRY_FLAG_RESOURCE_PATH + "/" + serviceName + ".server"; if (registry != null && registry.resourceExists(serverResourcePath)) { Resource serverResource = registry.get(serverResourcePath); if (serverResource != null && serverResource.getContent() != null) { return new String((byte[]) serverResource.getContent()); } } } catch (RegistryException e) { handleException("Could not retrieve the published server list. Error is " + e.getMessage(), e); } return null; } public CGProxyToolsURLs getPublishedProxyToolsURLs(String serviceName) throws CGException { try { CGServerBean bean = getCGServer(getPublishedServer(serviceName)); if (bean == null) { handleException("No persist server information found for the published service '" + serviceName + "'"); } String domainName = bean.getDomainName(); CGAdminClient csgAdminClient = getCGAdminClient(bean); if (csgAdminClient == null) { handleException("CGAdminClient is null"); } CGProxyToolsURLs tools = csgAdminClient.getPublishedProxyToolsURLs(serviceName, domainName); CGProxyToolsURLs tempTools = new CGProxyToolsURLs(); if (tools != null) { tempTools.setTryItURL(tools.getTryItURL()); tempTools.setWsdl11URL(tools.getWsdl11URL()); tempTools.setWsdl2URL(tools.getWsdl2URL()); tempTools.setEprArray(tools.getEprArray()); return tempTools; } } catch (Exception e) { handleException(e.getMessage(), e); } return null; } /** * Determines whether at least a one service has been published to specified CSG server. * * @param csgServerName Name of the CSG sever * @return true if there is at least a one service published to the CSG server or false otherwise. * @throws org.wso2.carbon.cloud.gateway.common.CGException * in case of an error */ public boolean isHasPublishedServices(String csgServerName) throws CGException { boolean isHasServices = false; try { org.wso2.carbon.registry.core.Registry registry = getConfigSystemRegistry(); if (registry != null && registry.resourceExists(CGConstant.REGISTRY_FLAG_RESOURCE_PATH)) { Resource resource = registry.get(CGConstant.REGISTRY_FLAG_RESOURCE_PATH); if (resource instanceof Collection) { Collection serviceFlagCollection = (Collection) resource; String[] flags = serviceFlagCollection.getChildren(); List<String> serverFlagPaths = filterForServiceFlags(flags); for (String serverFlagPath : serverFlagPaths) { Resource serverFlag = registry.get(serverFlagPath); String publishedServer = serverFlag.getContent() != null ? new String((byte[]) serverFlag.getContent()) : ""; if (csgServerName.equals(publishedServer)) { // found at least one service, published to specified server isHasServices = true; break; } } } } } catch (Exception e) { handleException("Unable to retrieve CSG services configurations", e); } return isHasServices; } private void handleServicePublishing(String serviceName, String serverName, boolean isAutomatic, CGAdminClient csgAdminClient, CGServerBean csgServer) throws CGException { if (serviceName == null) { handleException("Service name is null!"); } try { AxisService service = getAxisConfig().getService(serviceName); if (service == null) { handleException("No service found with the name '" + serviceName + "'"); } service.addExposedTransport(CGConstant.CG_POLLING_TRANSPORT_NAME); String domainName = csgServer.getDomainName(); String passWord = csgServer.getPassWord(); String userName = CGUtils.getFullUserName(csgServer.getUserName(), domainName); CGThriftServerBean bean = csgAdminClient.getThriftServerConnectionBean(); // thrift server either bind to loop back address(most of the time "localhost") or it can bound to // ip or host name but not both so below is used String hostName = csgServer.getHost(); if ("localhost".equals(hostName) || "127.0.0.1".equals(hostName)) { hostName = bean.getHostName(); // bean is the remote thrift server information } else { bean.setHostName(hostName); } int port = bean.getPort(); int timeOut = bean.getTimeOut(); String trustStorePath = CGUtils.getTrustStoreFilePath(); String trustStorePassword = CGUtils.getTrustStorePassWord(); if (log.isDebugEnabled()) { log.debug("Loading the trust store from the location '" + trustStorePath + "'"); } // get a token for this service CGThriftClient csgThriftClient = new CGThriftClient(CGUtils.getCGThriftClient( hostName, port, timeOut, trustStorePath, trustStorePassword)); // we use the CSG EPR as the key of the buffer String queueName = CGUtils.getCGEPR(domainName, serverName, serviceName); String token = csgThriftClient.login(userName, passWord, queueName); // encrypt and embed, so nobody can steal persistToken(serviceName, token); persistCGServerDetails(serviceName, bean); CGAgentPollingTaskFlags.flagForShutDown(serviceName, false); if (hasInOutOperations(service)) { // enable CSG Thrift transport sender as well // FIXME - need to persist the configured transport enableCGPollingTransportSender(getAxisConfig()); } // enable CSG transport receiver for this service // FIXME - need to persist the configured transport enableCGPollingTransportReceiver(getAxisConfig()); } catch (Exception e) { throw new CGException(e); } } private void handleException(String msg) throws CGException { log.error(msg); throw new CGException(msg); } private void handleException(String msg, Throwable t) throws CGException { log.error(msg, t); throw new CGException(msg, t); } private CGServerBean getCGServerBean(String csgServerName) throws CGException { CGServerBean bean = null; try { org.wso2.carbon.registry.core.Registry registry = getConfigSystemRegistry(); String resourceName = CGConstant.REGISTRY_SERVER_RESOURCE_PATH + "/" + csgServerName; if (registry != null && registry.resourceExists(resourceName)) { org.wso2.carbon.registry.core.Resource resource = registry.get(resourceName); try { bean = new CGServerBean(); bean.setHost(resource.getProperty(CGConstant.CG_SERVER_HOST)); bean.setName(resource.getProperty(CGConstant.CG_SERVER_NAME)); bean.setUserName(resource.getProperty(CGConstant.CG_SERVER_USER_NAME)); bean.setPort(resource.getProperty(CGConstant.CG_SERVER_PORT)); bean.setDomainName(resource.getProperty(CGConstant.CG_SERVER_DOMAIN_NAME)); CryptoUtil cryptoUtil = CryptoUtil.getDefaultCryptoUtil(); bean.setPassWord(new String(cryptoUtil.base64DecodeAndDecrypt( resource.getProperty("password")))); } catch (CryptoException e) { handleException("Could not convert into an AXIOM element"); } } else { throw new CGException("Resource :" + resourceName + " does not exist"); } } catch (org.wso2.carbon.registry.core.exceptions.RegistryException e) { handleException("Could not retrieve the server information for server: " + csgServerName, e); } return bean; } private static String getAuthServiceURL(CGServerBean csgServer) { return "https://" + csgServer.getHost() + ":" + csgServer.getPort() + "/services/AuthenticationAdmin"; } private static String getProxyURL(CGServerBean csgServer) { return "https://" + csgServer.getHost() + ":" + csgServer.getPort() + "/services/"; } private static boolean hasInOutOperations(AxisService service) { for (Iterator<AxisOperation> axisOpItr = service.getOperations(); axisOpItr.hasNext(); ) { AxisOperation axisOp = axisOpItr.next(); if (axisOp.getAxisSpecificMEPConstant() == WSDLConstants.MEP_CONSTANT_IN_OUT) { return true; } } return false; } private void flagServiceStatus(String serviceName, String serverName, CGServiceMetaDataBean cgServiceMetaData, boolean isPublished, boolean isAutoMatic) throws CGException { boolean isTransactionAlreadyStarted = Transaction.isStarted(); boolean isTransactionSuccess = true; Registry registry = getConfigSystemRegistry(); try { if (!isTransactionAlreadyStarted) { registry.beginTransaction(); // start a transaction if none exists currently. } if (registry != null && !registry.resourceExists(CGConstant.REGISTRY_CG_RESOURCE_PATH)) { org.wso2.carbon.registry.core.Collection collection = registry.newCollection(); registry.put(CGConstant.REGISTRY_CG_RESOURCE_PATH, collection); } org.wso2.carbon.registry.core.Resource resource = registry.newResource(); org.wso2.carbon.registry.core.Resource serverResource = registry.newResource(); String serverResourcePath = CGConstant.REGISTRY_FLAG_RESOURCE_PATH + "/" + serviceName + ".server"; String wsdlResourcePath = CGConstant.REGISTRY_FLAG_RESOURCE_PATH + "/" + serviceName + ".wsdl"; String cgServerResourcePath = CGConstant.REGISTRY_FLAG_RESOURCE_PATH + "/" + serviceName + ".cgserver"; String tokenResourcePath = CGConstant.REGISTRY_FLAG_RESOURCE_PATH + "/" + serviceName + ".token"; if (isPublished) { if (isAutoMatic) { resource.setContent(CGConstant.CG_SERVICE_STATUS_AUTO_MATIC); } else { resource.setContent(CGConstant.CG_SERVICE_STATUS_PUBLISHED); } serverResource.setContent(serverName); if (cgServiceMetaData != null && cgServiceMetaData.getInLineWSDL() != null) { org.wso2.carbon.registry.core.Resource wsdlResource = registry.newResource(); wsdlResource.setContent(cgServiceMetaData.getInLineWSDL()); registry.put(wsdlResourcePath, wsdlResource); } } else { resource.setContent(CGConstant.CG_SERVICE_STATUS_UNPUBLISHED); // remove the published server from the list if (registry.resourceExists(serverResourcePath)) { registry.delete(serverResourcePath); } if (registry.resourceExists(wsdlResourcePath)) { registry.delete(wsdlResourcePath); } if (registry.resourceExists(cgServerResourcePath)) { registry.delete(cgServerResourcePath); } if (registry.resourceExists(tokenResourcePath)) { registry.delete(tokenResourcePath); } } registry.put(CGConstant.REGISTRY_FLAG_RESOURCE_PATH + "/" + serviceName + ".flag", resource); registry.put(serverResourcePath, serverResource); } catch (org.wso2.carbon.registry.core.exceptions.RegistryException e) { isTransactionSuccess = false; handleException("Could not flag the service '" + serviceName + "'", e); } finally { if (!isTransactionAlreadyStarted) { try { if (isTransactionSuccess) { registry.commitTransaction(); } else { registry.rollbackTransaction(); } } catch (Exception exception) { handleException("Error occurred while trying to rollback or commit the " + "transaction", exception); } } } } private CGServiceMetaDataBean getCGServiceMetaData(AxisService service, String tenantName, String serverName) throws CGException { try { CGServiceMetaDataBean privateServiceMetaData = new org.wso2.carbon.cloud.gateway.stub.types.common.CGServiceMetaDataBean(); privateServiceMetaData.setServiceName(service.getName()); privateServiceMetaData.setEndpoint( CGUtils.getCGEPR(tenantName, serverName, service.getName())); ServiceAdmin serviceAdmin = new ServiceAdmin(getAxisConfig()); org.wso2.carbon.service.mgt.ServiceMetaData serviceAdminMetaData = serviceAdmin.getServiceData(service.getName()); if (serviceAdminMetaData.isActive()) { // Transmit dependencies to CSG server if this service has any. List<CGServiceDependencyBean> dependencies = new ArrayList<CGServiceDependencyBean>(); CGAgentWsdlDependencyResolver dependencyResolver = new CGAgentWsdlDependencyResolver(service, serviceAdminMetaData.getWsdlURLs()[0]); OMElement adjustedWsdl = null; String persistedWsdlContent = null; try { adjustedWsdl = dependencyResolver.parseWsdlDependencies(dependencies); } catch (CGException e) { persistedWsdlContent = getPersistedWsdlContent(service.getName()); } if (!dependencies.isEmpty()) { // Service has dependencies privateServiceMetaData.setServiceDependencies( dependencies.toArray(new CGServiceDependencyBean[dependencies.size()])); } if (adjustedWsdl == null && persistedWsdlContent == null) { privateServiceMetaData.setInLineWSDL(null); } else if (adjustedWsdl != null && persistedWsdlContent == null) { String wsdlString = adjustedWsdl.toStringWithConsume(); if (log.isDebugEnabled()) { log.debug("Adjusted wsdl : " + wsdlString); } privateServiceMetaData.setInLineWSDL(wsdlString); } else { privateServiceMetaData.setInLineWSDL(persistedWsdlContent); } } populateExposedTransports(service, privateServiceMetaData); if (hasInOutOperations(service)) { privateServiceMetaData.setHasInOutMEP(true); } return privateServiceMetaData; } catch (Exception e) { handleException("Error while retrieving the meta data of the service '" + service.getName() + "'", e); } return null; } private void populateExposedTransports(AxisService service, CGServiceMetaDataBean privateServiceMetaData) { if (service.getExposedTransports() != null && service.getExposedTransports().size() > 0) { List<String> exposedTransports = service.getExposedTransports(); exposedTransports.remove(CGConstant.CG_POLLING_TRANSPORT_NAME); privateServiceMetaData.setEnabledTransports(exposedTransports.toArray(new String[exposedTransports.size()])); } } private String getPersistedWsdlContent(String serviceName) throws Exception { Registry registry = getConfigSystemRegistry(); String wsdlResourcePath = CGConstant.REGISTRY_FLAG_RESOURCE_PATH + "/" + serviceName + ".wsdl"; if (registry.resourceExists(wsdlResourcePath)) { Resource resource = registry.get(wsdlResourcePath); if (resource != null && resource.getContent() != null) { return IOUtils.toString(resource.getContentStream()); } } return null; } private void persistCGServerDetails(String serviceName, CGThriftServerBean thriftConnectionBean) throws Exception { if (thriftConnectionBean == null) { handleException("Remote CG server information not found"); } Registry registry = getConfigSystemRegistry(); if (!registry.resourceExists(CGConstant.REGISTRY_CG_RESOURCE_PATH)) { org.wso2.carbon.registry.core.Collection collection = registry.newCollection(); registry.put(CGConstant.REGISTRY_CG_RESOURCE_PATH, collection); } String cgServerResourcePath = CGConstant.REGISTRY_FLAG_RESOURCE_PATH + "/" + serviceName + ".cgserver"; org.wso2.carbon.registry.core.Resource cgServerResource = registry.newResource(); cgServerResource.setContent(toString(thriftConnectionBean)); registry.put(cgServerResourcePath, cgServerResource); } private void persistToken(String serviceName, String token) throws Exception { if (token == null) { handleException("Token cannot be null"); } Registry registry = getConfigSystemRegistry(); if (!registry.resourceExists(CGConstant.REGISTRY_CG_RESOURCE_PATH)) { org.wso2.carbon.registry.core.Collection collection = registry.newCollection(); registry.put(CGConstant.REGISTRY_CG_RESOURCE_PATH, collection); } String tokenResourcePath = CGConstant.REGISTRY_FLAG_RESOURCE_PATH + "/" + serviceName + ".token"; org.wso2.carbon.registry.core.Resource tokenResource = registry.newResource(); CryptoUtil cryptoUtil = CryptoUtil.getDefaultCryptoUtil(); tokenResource.setContent(cryptoUtil.encryptAndBase64Encode(token.getBytes())); registry.put(tokenResourcePath, tokenResource); } private CGAdminClient getCGAdminClient(CGServerBean bean) throws CGException { try { String domainName = bean.getDomainName(); String passWord = bean.getPassWord(); String sessionCookie = CGAgentUtils.getSessionCookie(getAuthServiceURL(bean), bean.getUserName(), passWord, domainName, bean.getHost()); CGAdminClient csgAdminClient; if (CGAgentUtils.isClientAxis2XMLExists()) { ConfigurationContext configCtx = ConfigurationContextFactory. createConfigurationContextFromFileSystem(null, CGConstant.CLIENT_AXIS2_XML); csgAdminClient = new CGAdminClient(sessionCookie, getProxyURL(bean), configCtx); } else { csgAdminClient = new CGAdminClient(sessionCookie, getProxyURL(bean)); } return csgAdminClient; } catch (Exception e) { log.error("Exception occurred while construct the CGAgentAdmin client", e); } return null; } private void enableCGPollingTransportSender(AxisConfiguration axisConfig) throws AxisFault { TransportOutDescription transportOut = new TransportOutDescription(CGConstant.CG_POLLING_TRANSPORT_NAME); CGPollingTransportSender txSender = new CGPollingTransportSender(); transportOut.setSender(txSender); axisConfig.addTransportOut(transportOut); transportOut.getSender().init(getConfigContext(), transportOut); } private void enableCGPollingTransportReceiver(AxisConfiguration axisConfig) throws AxisFault { // FIXME:https://wso2.org/jira/browse/CG-23, Services of the type RegistryAdminService1348830151341_12, // ServiceAdmin1348830151485_3, CGAgentAdminService1348830155933_11 are added into axis2 config // which are not admin services for (AxisService service : axisConfig.getServices().values()) { if (!SystemFilter.isAdminService(service) && !SystemFilter.isHiddenService(service) && service.getExposedTransports().size() == 0 && service.isEnableAllTransports() && service.getName().matches("(\\w)*Admin(\\w)*(\\d)*_(\\d)*")) { service.setEnableAllTransports(false); if (log.isDebugEnabled()) { log.debug("The non admin service '" + service.getName() + "' has zero exposed transports but has" + " marked to enable all transports. So setting enable all transport to false"); } } } TransportInDescription transportIn = new TransportInDescription(CGConstant.CG_POLLING_TRANSPORT_NAME); CGPollingTransportReceiver receiver = new CGPollingTransportReceiver(); transportIn.setReceiver(receiver); axisConfig.addTransportIn(transportIn); transportIn.getReceiver().init(getConfigContext(), transportIn); transportIn.getReceiver().start(); } private List<String> filterForServiceFlags(String[] flags) { List<String> filtered = new ArrayList<String>(); for (String flag : flags) { if (flag.endsWith(".server")) { filtered.add(flag); } } return filtered; } private void loggingToRemoteCGServer(CGServerBean csgServer) throws CGException { String authServerUrl = "https://" + csgServer.getHost() + ":" + csgServer.getPort() + "/services/AuthenticationAdmin"; AuthenticationClient authClient = new AuthenticationClient(); authClient.getLoggedAuthAdminStub( authServerUrl, csgServer.getUserName(), csgServer.getPassWord(), csgServer.getHost(), csgServer.getDomainName()); } protected void addExposedTransports(String serviceName, String transport) throws Exception { ServiceAdmin admin; if (serviceName == null) { handleException("Invalid service name: Service name must not be null"); } if (transport == null) { handleException("Invalid transport name: Transport name must not be null"); } try { admin = new ServiceAdmin(getAxisConfig()); admin.addTransportBinding(serviceName, transport); } catch (Exception e) { handleException("Error while adding exposed transport " + transport, e); } } protected void removeExposedTransports(String serviceName, String transportProtocol) throws Exception { TransportSummary[] transports; PersistenceFactory pf = PersistenceFactory.getInstance(getAxisConfig()); ServicePersistenceManager pm; AxisService axisService; if (serviceName == null) { handleException("Invalid service name"); } if (transportProtocol == null) { handleException("Invalid transport name"); } axisService = getAxisConfig().getServiceForActivation(serviceName); if (axisService == null) { handleException("No service exists by the name : " + serviceName); } try { if (isUTEnabled(serviceName)) { // If UT enabled, you can't remove HTTPS transport from this service. if (ServerConstants.HTTPS_TRANSPORT.equalsIgnoreCase(transportProtocol)) { throw new Exception("Cannot remove HTTPS transport binding for Service [" + serviceName + "] since a security scenario which requires the " + "service to contain only the HTTPS transport binding" + " has been applied to this service."); } } if (!axisService.isEnableAllTransports()) { if (axisService.getExposedTransports().size() == 1) { log.warn("At least one transport binding must exist for a service. No bindings " + "will be removed."); return; } // Simply remove the transport from the list of exposed transport axisService.removeExposedTransport(transportProtocol); } else { // This returns all the available transports - not just active ones. transports = listTransports(); // populate the exposed transports list with the other transports for (TransportSummary transport : transports) { if (transport.isListenerActive() && !transport.getProtocol().equals(transportProtocol)) { axisService.addExposedTransport(transport.getProtocol()); } } axisService.setEnableAllTransports(false); } pm = pf.getServicePM(); pm.removeExposedTransports(serviceName, transportProtocol); getAxisConfig().notifyObservers( new AxisEvent(CarbonConstants.AxisEvent.TRANSPORT_BINDING_REMOVED, axisService), axisService); } catch (Exception e) { handleException("Error while removing exposed transport : " + transportProtocol, e); } } protected boolean isUTEnabled(String serviceName) throws AxisFault { AxisService axisService; OMElement serviceElement; axisService = getAxisConfig().getServiceForActivation(serviceName); try { ServicePersistenceManager pm = PersistenceFactory.getInstance(getAxisConfig()).getServicePM(); serviceElement = pm.getService(axisService); if (serviceElement == null) { pm.handleNewServiceAddition(axisService); serviceElement = pm.getService(axisService); } if (serviceElement.getAttributeValue(new QName(Resources.ServiceProperties.IS_UT_ENABLED)) != null) { return true; } } catch (Exception e) { log.error("Error occurred while checking whether UT being enabled for service " + serviceName, e); return false; } return false; } protected TransportSummary[] listTransports() { Map<String, TransportService> transports; ArrayList<TransportSummary> transCollection; TransportStore transportStore; // TransportStore already being created - so we pass null. transportStore = TransportStore.getInstance(); // All transport bundles update the TransportStore - with the corresponding transports // supported by those. transports = transportStore.getAvailableTransports(); transCollection = new ArrayList<TransportSummary>(); for (Iterator<TransportService> iter = transports.values().iterator(); iter.hasNext();) { TransportService transportService; TransportSummary summary; transportService = iter.next(); // TransportSummary only needs a subset of information from TransportInfo. summary = new TransportSummary(); summary.setProtocol(transportService.getName()); // All transports already loaded in to axis2configuration are considered as active. // Inactive transports still available in the management UI so the user can enable // those. summary.setListenerActive(transportService.isEnabled(true, getAxisConfig())); summary.setSenderActive(transportService.isEnabled(false, getAxisConfig())); transCollection.add(summary); } return transCollection.toArray(new TransportSummary[transCollection.size()]); } /** * Write the object to a Base64 string. */ private static String toString(Serializable object) { try { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream); objectOutputStream.writeObject(object); objectOutputStream.close(); return Base64.encode(outputStream.toByteArray()); } catch (Exception e) { log.error("Exception occurred while writing object to the base64 String", e); } return null; } }