/* * Copyright (c) 2016, 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.event.publisher.template.deployer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.event.publisher.core.config.EventPublisherConfiguration; import org.wso2.carbon.event.publisher.core.config.EventPublisherConfigurationFile; import org.wso2.carbon.event.publisher.core.config.EventPublisherConstants; import org.wso2.carbon.event.publisher.core.exception.EventPublisherConfigurationException; import org.wso2.carbon.event.publisher.template.deployer.internal.EventPublisherTemplateDeployerValueHolder; import org.wso2.carbon.event.publisher.template.deployer.internal.util.EventPublisherTemplateDeployerConstants; import org.wso2.carbon.event.publisher.template.deployer.internal.util.EventPublisherTemplateDeployerHelper; import org.wso2.carbon.event.template.manager.core.DeployableTemplate; import org.wso2.carbon.event.template.manager.core.TemplateDeployer; import org.wso2.carbon.event.template.manager.core.TemplateDeploymentException; import org.wso2.carbon.registry.core.Collection; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.RegistryConstants; import org.wso2.carbon.registry.core.Resource; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import org.xml.sax.SAXException; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; public class EventPublisherTemplateDeployer implements TemplateDeployer { private static final Log log = LogFactory.getLog(EventPublisherTemplateDeployer.class); @Override public String getType() { return EventPublisherTemplateDeployerConstants.EVENT_PUBLISHER_DEPLOYER_TYPE; } @Override public void deployArtifact(DeployableTemplate template) throws TemplateDeploymentException { String artifactId; if (template == null) { throw new TemplateDeploymentException("No artifact received to be deployed."); } artifactId = template.getArtifactId(); undeployArtifact(artifactId, true); deployNewArtifact(template); } @Override public void deployIfNotDoneAlready(DeployableTemplate template) throws TemplateDeploymentException { String publisherName = null; try { if (template == null) { throw new TemplateDeploymentException("No artifact received to be deployed."); } String publisherConfig = template.getArtifact(); publisherName = EventPublisherTemplateDeployerValueHolder.getEventPublisherService().getEventPublisherName(publisherConfig); boolean isPublisherExist = false; for (EventPublisherConfiguration publisherConfiguration : EventPublisherTemplateDeployerValueHolder.getEventPublisherService().getAllActiveEventPublisherConfigurations()) { if (publisherName.equals(publisherConfiguration.getEventPublisherName())) { isPublisherExist = true; } } if (!isPublisherExist) { for (EventPublisherConfigurationFile publisherConfigurationFile : EventPublisherTemplateDeployerValueHolder.getEventPublisherService().getAllInactiveEventPublisherConfigurations()) { if (publisherName.equals(publisherConfigurationFile.getEventPublisherName())) { isPublisherExist = true; } } } if (!isPublisherExist) { deployArtifact(template); } else { log.info("Common-Artifact Event Publisher with name: " + publisherName + " of Domain " + template.getConfiguration().getDomain() + " was not deployed as it is already being deployed."); } } catch (EventPublisherConfigurationException e) { throw new TemplateDeploymentException("Could not deploy Common-Artifact Event Publisher with name: " + publisherName + ", for Artifact ID: " + template.getArtifactId(), e); } } @Override public void undeployArtifact(String artifactId) throws TemplateDeploymentException { undeployArtifact(artifactId, true); } private void deployNewArtifact(DeployableTemplate template) throws TemplateDeploymentException { String publisherName = null; String artifactId = template.getArtifactId(); try { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); Registry registry = EventPublisherTemplateDeployerValueHolder.getRegistryService() .getConfigSystemRegistry(tenantId); String publisherConfig = template.getArtifact(); publisherName = EventPublisherTemplateDeployerValueHolder.getEventPublisherService().getEventPublisherName(publisherConfig); String mappingResourcePath = EventPublisherTemplateDeployerConstants.META_INFO_COLLECTION_PATH + RegistryConstants.PATH_SEPARATOR + publisherName; if (registry.resourceExists(mappingResourcePath)) { String existingPublisherConfigXml = getExistingEventPublisherConfigXml(tenantId, publisherName); //not handling existingConfig==null case because handling such user errors will make this component too complicated. if (EventPublisherTemplateDeployerHelper.arePublisherConfigXmlsSimilar(publisherConfig, existingPublisherConfigXml)) { EventPublisherTemplateDeployerHelper.updateRegistryMaps(registry, artifactId, publisherName); log.info("[Artifact ID: " + artifactId + "] Event Publisher: " + publisherName + " has already being deployed."); } else { throw new TemplateDeploymentException("[Artifact ID: " + artifactId + "] Failed to deploy Event Publisher with name: " + publisherName + ", as there exists another Event Publisher with the same name " + "but different configuration."); } } else { EventPublisherTemplateDeployerHelper.updateRegistryMaps(registry, artifactId, publisherName); EventPublisherTemplateDeployerValueHolder.getEventPublisherService().deployEventPublisherConfiguration(publisherConfig); } } catch (RegistryException e) { throw new TemplateDeploymentException("Could not load the Registry for Tenant Domain: " + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true) + ", when deploying Event Publisher for artifact ID: " + template.getArtifactId(), e); } catch (EventPublisherConfigurationException e) { throw new TemplateDeploymentException("Could not deploy Event Publisher with name: " + publisherName + ", for Artifact ID: " + artifactId, e); } catch (IOException e) { throw new TemplateDeploymentException("Could not deploy Event Publisher with name: " + publisherName + ", for Artifact ID: " + artifactId, e); } catch (SAXException e) { throw new TemplateDeploymentException("Could not deploy Event Publisher with name: " + publisherName + ", for Artifact ID: " + artifactId, e); } } private void undeployArtifact(String artifactId, boolean doDeletePublisher) throws TemplateDeploymentException { String publisherName; try { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); Registry registry = EventPublisherTemplateDeployerValueHolder.getRegistryService() .getConfigSystemRegistry(tenantId); if (!registry.resourceExists(EventPublisherTemplateDeployerConstants.META_INFO_COLLECTION_PATH)) { registry.put(EventPublisherTemplateDeployerConstants.META_INFO_COLLECTION_PATH, registry.newCollection()); } Collection infoCollection = registry.get(EventPublisherTemplateDeployerConstants.META_INFO_COLLECTION_PATH, 0, -1); publisherName = infoCollection.getProperty(artifactId); if (publisherName != null) { infoCollection.removeProperty(artifactId); //cleaning up the map registry.put(EventPublisherTemplateDeployerConstants.META_INFO_COLLECTION_PATH, infoCollection); String mappingResourcePath = EventPublisherTemplateDeployerConstants.META_INFO_COLLECTION_PATH + RegistryConstants.PATH_SEPARATOR + publisherName; if (registry.resourceExists(mappingResourcePath)) { try { Resource mappingResource = registry.get(mappingResourcePath); String mappingResourceContent = new String((byte[]) mappingResource.getContent()); //Removing artifact ID, along with separator comma. int beforeCommaIndex = mappingResourceContent.indexOf(artifactId) - 1; int afterCommaIndex = mappingResourceContent.indexOf(artifactId) + artifactId.length(); if (beforeCommaIndex > 0) { mappingResourceContent = mappingResourceContent.replace( EventPublisherTemplateDeployerConstants.META_INFO_PUBLISHER_NAME_SEPARATER + artifactId, ""); } else if (afterCommaIndex < mappingResourceContent.length()) { mappingResourceContent = mappingResourceContent.replace( artifactId + EventPublisherTemplateDeployerConstants.META_INFO_PUBLISHER_NAME_SEPARATER, ""); } else { mappingResourceContent = mappingResourceContent.replace(artifactId, ""); } if (mappingResourceContent.equals("")) { //undeploying existing event publisher if (doDeletePublisher) { boolean isPublisherActive = false; for (EventPublisherConfiguration publisherConfiguration : EventPublisherTemplateDeployerValueHolder.getEventPublisherService().getAllActiveEventPublisherConfigurations()) { if (publisherName.equals(publisherConfiguration.getEventPublisherName())) { isPublisherActive = true; } } if (isPublisherActive) { EventPublisherTemplateDeployerValueHolder.getEventPublisherService().undeployActiveEventPublisherConfiguration(publisherName); } else { EventPublisherTemplateDeployerValueHolder.getEventPublisherService().undeployInactiveEventPublisherConfiguration(publisherName); } } //deleting mappingResource registry.delete(mappingResourcePath); } else { mappingResource.setContent(mappingResourceContent); registry.put(mappingResourcePath, mappingResource); } } catch (RegistryException e) { throw new TemplateDeploymentException("Could not load the Registry for Tenant Domain: " + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true) + ", when trying to undeploy Event Publisher with artifact ID: " + artifactId, e); } catch (EventPublisherConfigurationException e) { throw new TemplateDeploymentException("Failed to undeploy Event Publisher: " + publisherName + ", for Artifact ID: " + artifactId, e); } } } } catch (RegistryException e) { throw new TemplateDeploymentException("Could not load the Registry for Tenant Domain: " + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true) + ", when trying to undeploy Event Publisher for artifact ID: " + artifactId, e); } } public static String getExistingEventPublisherConfigXml(int tenantId, String receiverName) throws IOException { String filePath = MultitenantUtils.getAxis2RepositoryPath(tenantId) + EventPublisherConstants.EF_CONFIG_DIRECTORY + File.separator + receiverName + EventPublisherConstants.EF_CONFIG_FILE_EXTENSION_WITH_DOT; File file = new File(filePath); if (file.exists()) { byte[] encoded = Files.readAllBytes(Paths.get(filePath)); return new String(encoded); } else { return null; } } }