/* * 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.stream.template.deployer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.databridge.commons.StreamDefinition; import org.wso2.carbon.databridge.commons.exception.MalformedStreamDefinitionException; import org.wso2.carbon.databridge.commons.utils.EventDefinitionConverterUtils; 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.event.stream.core.exception.EventStreamConfigurationException; import org.wso2.carbon.event.stream.core.exception.StreamDefinitionAlreadyDefinedException; import org.wso2.carbon.event.stream.template.deployer.internal.EventStreamTemplateDeployerValueHolder; import org.wso2.carbon.event.stream.template.deployer.internal.util.EventStreamTemplateDeployerConstants; import org.wso2.carbon.event.stream.template.deployer.internal.util.EventStreamTemplateDeployerHelper; 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.exceptions.RegistryException; public class EventStreamTemplateDeployer implements TemplateDeployer { private static final Log log = LogFactory.getLog(EventStreamTemplateDeployer.class); @Override public String getType() { return EventStreamTemplateDeployerConstants.EVENT_STREAM_DEPLOYER_TYPE; } @Override public void deployArtifact(DeployableTemplate template) throws TemplateDeploymentException { String stream = null; StreamDefinition streamDefinition = null; try { if (template == null) { throw new TemplateDeploymentException("No artifact received to be deployed."); } int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); Registry registry = EventStreamTemplateDeployerValueHolder.getRegistryService() .getConfigSystemRegistry(tenantId); if (!registry.resourceExists(EventStreamTemplateDeployerConstants.META_INFO_COLLECTION_PATH)) { registry.put(EventStreamTemplateDeployerConstants.META_INFO_COLLECTION_PATH, registry.newCollection()); } Collection infoCollection = registry.get(EventStreamTemplateDeployerConstants.META_INFO_COLLECTION_PATH, 0, -1); String artifactId = template.getArtifactId(); String streamId = infoCollection.getProperty(artifactId); //~~~~~~~~~~~~~Cleaning up previously deployed stream, if any. if (streamId != null) { //meaning, this particular template element has previously deployed a stream. We need to undeploy it if it has no other users. infoCollection.removeProperty(artifactId); //cleaning up the map before undeploying registry.put(EventStreamTemplateDeployerConstants.META_INFO_COLLECTION_PATH, infoCollection); //Checking whether any other scenario configs/domains are using this stream.... //this info is being kept in a map String mappingResourcePath = EventStreamTemplateDeployerConstants.META_INFO_COLLECTION_PATH + RegistryConstants.PATH_SEPARATOR + streamId; if (registry.resourceExists(mappingResourcePath)) { EventStreamTemplateDeployerHelper.cleanMappingResourceAndUndeploy(registry, mappingResourcePath, artifactId, streamId); } } //~~~~~~~~~~~~~Deploying new stream stream = template.getArtifact(); streamDefinition = EventDefinitionConverterUtils.convertFromJson(stream); streamId = streamDefinition.getStreamId(); //if stream has not deployed already, we deploy it and update the maps in the registry. if (EventStreamTemplateDeployerValueHolder.getEventStreamService(). getStreamDefinition(streamId) == null) { EventStreamTemplateDeployerValueHolder.getEventStreamService().addEventStreamDefinition(streamDefinition); EventStreamTemplateDeployerHelper.updateRegistryMaps(registry, infoCollection, artifactId, streamId); } else { //stream has already being deployed for another scenario/domain StreamDefinition existingStreamDef = EventStreamTemplateDeployerValueHolder.getEventStreamService().getStreamDefinition(streamId); if (streamDefinition.equals(existingStreamDef)) { //if so, just update the registry maps. EventStreamTemplateDeployerHelper.updateRegistryMaps(registry, infoCollection, artifactId, streamId); } else { throw new TemplateDeploymentException("Failed to deploy Event Stream with ID: " + streamId + ", as there exists another stream with the same ID but different Stream Definition. Artifact ID: " + artifactId); } } } catch (MalformedStreamDefinitionException e) { throw new TemplateDeploymentException("Stream definition given in the template is not in valid format. Stream definition: " + stream, e); } catch (EventStreamConfigurationException e) { throw new TemplateDeploymentException("Exception occurred when configuring stream " + streamDefinition.getName(), e); } catch (StreamDefinitionAlreadyDefinedException e) { throw new TemplateDeploymentException("Same template stream name " + streamDefinition.getName() + " has been defined for another definition ", e); } catch (RegistryException e) { throw new TemplateDeploymentException("Could not load the Registry for Tenant Domain: " + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true) + ", when deploying Event Stream with artifact ID: " + template.getArtifactId(), e); } } @Override public void deployIfNotDoneAlready(DeployableTemplate template) throws TemplateDeploymentException { String stream = null; StreamDefinition streamDefinition = null; try { if (template == null) { throw new TemplateDeploymentException("No artifact received to be deployed."); } stream = template.getArtifact(); streamDefinition = EventDefinitionConverterUtils.convertFromJson(stream); if (EventStreamTemplateDeployerValueHolder.getEventStreamService(). getStreamDefinition(streamDefinition.getStreamId()) == null) { deployArtifact(template); } else { log.info("Common Artifact: EventStream with Stream ID " + streamDefinition.getStreamId() + " of Domain " + template.getConfiguration().getDomain() + " was not deployed as it is already being deployed."); } } catch (MalformedStreamDefinitionException e) { throw new TemplateDeploymentException("Stream definition given in the template is not in valid format. Stream definition: " + stream, e); } catch (EventStreamConfigurationException e) { throw new TemplateDeploymentException("Failed to get stream definition for StreamID: " + streamDefinition.getStreamId() + ", hence deployment failed.", e); } } @Override public void undeployArtifact(String artifactId) throws TemplateDeploymentException { String streamId; try { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); Registry registry = EventStreamTemplateDeployerValueHolder.getRegistryService() .getConfigSystemRegistry(tenantId); if (!registry.resourceExists(EventStreamTemplateDeployerConstants.META_INFO_COLLECTION_PATH)) { registry.put(EventStreamTemplateDeployerConstants.META_INFO_COLLECTION_PATH, registry.newCollection()); } Collection infoCollection = registry.get(EventStreamTemplateDeployerConstants.META_INFO_COLLECTION_PATH, 0, -1); streamId = infoCollection.getProperty(artifactId); if (streamId != null) { infoCollection.removeProperty(artifactId); //cleaning up the map registry.put(EventStreamTemplateDeployerConstants.META_INFO_COLLECTION_PATH, infoCollection); String mappingResourcePath = EventStreamTemplateDeployerConstants.META_INFO_COLLECTION_PATH + RegistryConstants.PATH_SEPARATOR + streamId; if (registry.resourceExists(mappingResourcePath)) { EventStreamTemplateDeployerHelper.cleanMappingResourceAndUndeploy(registry, mappingResourcePath, artifactId, streamId); } else { log.warn("Registry data in inconsistent. Resource '" + mappingResourcePath + "' which needs to be deleted is not found."); } } else { log.warn("Registry data in inconsistent. No stream ID associated to artifact ID: " + artifactId + ". Hence nothing to be undeployed."); } } catch (RegistryException e) { throw new TemplateDeploymentException("Could not load the Registry for Tenant Domain: " + PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true) + ", when trying to undeploy Event Stream with artifact ID: " + artifactId, e); } } }