/* * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you 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.core.internal; import org.apache.axis2.engine.AxisConfiguration; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.core.multitenancy.utils.TenantAxisUtils; import org.wso2.carbon.databridge.commons.Attribute; import org.wso2.carbon.databridge.commons.Event; import org.wso2.carbon.databridge.commons.StreamDefinition; import org.wso2.carbon.databridge.commons.utils.DataBridgeCommonsUtils; import org.wso2.carbon.event.stream.core.EventProducer; import org.wso2.carbon.event.stream.core.EventStreamConfiguration; import org.wso2.carbon.event.stream.core.EventStreamListener; import org.wso2.carbon.event.stream.core.EventStreamService; import org.wso2.carbon.event.stream.core.SiddhiEventConsumer; import org.wso2.carbon.event.stream.core.WSO2EventConsumer; import org.wso2.carbon.event.stream.core.WSO2EventListConsumer; import org.wso2.carbon.event.stream.core.exception.EventStreamConfigurationException; import org.wso2.carbon.event.stream.core.exception.StreamDefinitionAlreadyDefinedException; import org.wso2.carbon.event.stream.core.internal.ds.EventStreamServiceValueHolder; import org.wso2.carbon.event.stream.core.internal.util.CarbonEventStreamUtil; import org.wso2.carbon.event.stream.core.internal.util.EventStreamConstants; import org.wso2.carbon.event.stream.core.internal.util.SampleEventGenerator; import org.wso2.carbon.event.stream.core.internal.util.helper.EventStreamConfigurationFileSystemInvoker; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class CarbonEventStreamService implements EventStreamService { private static final Log log = LogFactory.getLog(CarbonEventStreamService.class); private final List<StreamDefinition> pendingStreams = new ArrayList<StreamDefinition>(); private Map<Integer, ConcurrentHashMap<String, EventStreamConfiguration>> tenantSpecificEventStreamConfigs = new ConcurrentHashMap<Integer, ConcurrentHashMap<String, EventStreamConfiguration>>(); public void removeEventStreamConfigurationFromMap(String fileName) throws EventStreamConfigurationException{ int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); Map<String, EventStreamConfiguration> eventStreamConfigs = tenantSpecificEventStreamConfigs.get(tenantId); String streamId = null; if (eventStreamConfigs != null) { for (EventStreamConfiguration eventStreamConfiguration : eventStreamConfigs.values()) { if (eventStreamConfiguration.getFileName().equals(fileName)) { streamId = eventStreamConfiguration.getStreamDefinition().getStreamId(); break; } } } if (streamId != null) { eventStreamConfigs.remove(streamId); for (EventStreamListener eventStreamListener : EventStreamServiceValueHolder.getEventStreamListenerList()) { eventStreamListener.removedEventStream(tenantId, DataBridgeCommonsUtils.getStreamNameFromStreamId(streamId), DataBridgeCommonsUtils.getStreamVersionFromStreamId(streamId)); } EventStreamServiceValueHolder.getEventStreamRuntime().deleteStreamJunction(streamId); } } /** * Pending streams will be added */ public void addPendingStreams() { synchronized (pendingStreams) { for (StreamDefinition stream : pendingStreams) { try { addEventStreamDefinition(stream); } catch (EventStreamConfigurationException e) { log.error("Error occurred when adding stream " + stream.getName(), e); } } pendingStreams.clear(); } } /** * @param name * @param version * @return */ @Override public StreamDefinition getStreamDefinition(String name, String version) throws EventStreamConfigurationException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); Map<String, EventStreamConfiguration> eventStreamConfigs = tenantSpecificEventStreamConfigs.get(tenantId); if (eventStreamConfigs != null && eventStreamConfigs.containsKey(name + ":" + version)) { return eventStreamConfigs.get(name + ":" + version).getStreamDefinition(); } return null; } /** * @param streamId * @return StreamDefinition and returns null if ont exist */ @Override public StreamDefinition getStreamDefinition(String streamId) throws EventStreamConfigurationException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); Map<String, EventStreamConfiguration> eventStreamConfigs = tenantSpecificEventStreamConfigs.get(tenantId); if (eventStreamConfigs != null && eventStreamConfigs.containsKey(streamId)) { return eventStreamConfigs.get(streamId).getStreamDefinition(); } return null; } public EventStreamConfiguration getEventStreamConfiguration(String streamId) { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); Map<String, EventStreamConfiguration> eventStreamConfigs = tenantSpecificEventStreamConfigs.get(tenantId); if (eventStreamConfigs != null && eventStreamConfigs.containsKey(streamId)) { return eventStreamConfigs.get(streamId); } return null; } @Override public List<StreamDefinition> getAllStreamDefinitions() throws EventStreamConfigurationException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); Map<String, EventStreamConfiguration> eventStreamConfigs = tenantSpecificEventStreamConfigs.get(tenantId); List<StreamDefinition> list = new ArrayList<StreamDefinition>(); if (eventStreamConfigs == null) { return list; } for (EventStreamConfiguration eventStreamConfiguration : eventStreamConfigs.values()) { list.add(eventStreamConfiguration.getStreamDefinition()); } return list; } @Override public List<EventStreamConfiguration> getAllEventStreamConfigurations() throws EventStreamConfigurationException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); Map<String, EventStreamConfiguration> eventStreamConfigs = tenantSpecificEventStreamConfigs.get(tenantId); if (eventStreamConfigs == null) { return new ArrayList<EventStreamConfiguration>(); } return new ArrayList<EventStreamConfiguration>(eventStreamConfigs.values()); } public void addEventStreamConfig(EventStreamConfiguration eventStreamConfiguration) throws EventStreamConfigurationException { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); ConcurrentHashMap<String, EventStreamConfiguration> eventStreamConfigs = tenantSpecificEventStreamConfigs.get(tenantId); if (eventStreamConfigs == null) { eventStreamConfigs = new ConcurrentHashMap<String, EventStreamConfiguration>(); tenantSpecificEventStreamConfigs.put(tenantId, eventStreamConfigs); } eventStreamConfigs.put(eventStreamConfiguration.getStreamDefinition().getStreamId(), eventStreamConfiguration); for (EventStreamListener eventStreamListener : EventStreamServiceValueHolder.getEventStreamListenerList()) { eventStreamListener.addedEventStream(tenantId, eventStreamConfiguration.getStreamDefinition().getName(), eventStreamConfiguration.getStreamDefinition().getVersion()); } } public void validateEventStreamDefinition(StreamDefinition streamDefinition) throws EventStreamConfigurationException { // validate meta attribute if (streamDefinition.getMetaData() != null && streamDefinition.getMetaData().size() != 0) { for (int i = 0; i < streamDefinition.getMetaData().size(); i++) { String checkName = streamDefinition.getMetaData().get(i).getName(); for (int j = i + 1; j < streamDefinition.getMetaData().size(); j++) { if (checkName.equals(streamDefinition.getMetaData().get(j).getName())) { throw new EventStreamConfigurationException("Cannot have same name \'" + checkName +"\' for multiple meta data attributes, give different names"); } } } } // validate correlation attribute if (streamDefinition.getCorrelationData() != null && streamDefinition.getCorrelationData().size() != 0) { for (int i = 0; i < streamDefinition.getCorrelationData().size(); i++) { String checkName = streamDefinition.getCorrelationData().get(i).getName(); for (int j = i + 1; j < streamDefinition.getCorrelationData().size(); j++) { if (checkName.equals(streamDefinition.getCorrelationData().get(j).getName())) { throw new EventStreamConfigurationException("Cannot have same name \'" + checkName + "\' for multiple correlation data attributes, give different names"); } } } } // validate payload attribute if (streamDefinition.getPayloadData() != null && streamDefinition.getPayloadData().size() != 0) { for (int i = 0; i < streamDefinition.getPayloadData().size(); i++) { String checkName = streamDefinition.getPayloadData().get(i).getName(); for (int j = i + 1; j < streamDefinition.getPayloadData().size(); j++) { if (checkName.equals(streamDefinition.getPayloadData().get(j).getName())) { throw new EventStreamConfigurationException("Cannot have same name \'" + checkName +"\' for multiple payload data attributes, give different names"); } } } } } @Override public void addEventStreamDefinition(StreamDefinition streamDefinition) throws EventStreamConfigurationException { //If ConfigurationContextService is available stream will be saved, //Else stream will be added pendingStreams list to save once ConfigurationContextService is available if (EventStreamServiceValueHolder.getConfigurationContextService() != null) { AxisConfiguration axisConfig = getAxisConfiguration(); String directoryPath = new File(axisConfig.getRepository().getPath()) .getAbsolutePath() + File.separator + EventStreamConstants.EVENT_STREAMS; File directory = new File(directoryPath); if (!directory.exists()) { if (!directory.mkdir()) { throw new EventStreamConfigurationException("Cannot create directory to add tenant specific Event Stream : " + streamDefinition.getStreamId()); } } String filePath = directoryPath + File.separator + streamDefinition.getName() + EventStreamConstants.STREAM_DEFINITION_FILE_DELIMITER + streamDefinition.getVersion() + EventStreamConstants.STREAM_DEFINITION_FILE_EXTENSION; StreamDefinition streamDefinitionOld = getStreamDefinition(streamDefinition.getStreamId()); if (streamDefinitionOld != null) { if (!(streamDefinitionOld.equals(streamDefinition))) { throw new StreamDefinitionAlreadyDefinedException("Different stream definition with same stream id " + streamDefinition.getStreamId() + " already exist " + streamDefinitionOld.toString() + ", cannot add stream definition " + streamDefinition.toString()); } else { return; } } validateEventStreamDefinition(streamDefinition); EventStreamConfigurationFileSystemInvoker.save(streamDefinition, filePath, axisConfig); } else { synchronized (pendingStreams) { if (EventStreamServiceValueHolder.getConfigurationContextService() != null) { addEventStreamDefinition(streamDefinition); } else { pendingStreams.add(streamDefinition); } } } } private AxisConfiguration getAxisConfiguration() { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); AxisConfiguration axisConfig; if (tenantId == MultitenantConstants.SUPER_TENANT_ID) { axisConfig = EventStreamServiceValueHolder.getConfigurationContextService().getServerConfigContext().getAxisConfiguration(); } else { axisConfig = TenantAxisUtils.getTenantAxisConfiguration(PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(), EventStreamServiceValueHolder.getConfigurationContextService().getServerConfigContext()); } return axisConfig; } public void removeEventStreamDefinition(String streamId) throws EventStreamConfigurationException { String name = null, version = null; if (streamId != null && streamId.contains(StreamdefinitionStoreConstants.STREAM_ID_SPLITTER)) { name = streamId.split(StreamdefinitionStoreConstants.STREAM_ID_SPLITTER)[0]; version = streamId.split(StreamdefinitionStoreConstants.STREAM_ID_SPLITTER)[1]; } removeEventStreamDefinition(name, version); } @Override public void removeEventStreamDefinition(String streamName, String streamVersion) throws EventStreamConfigurationException { AxisConfiguration axisConfig = getAxisConfiguration(); EventStreamConfigurationFileSystemInvoker.delete(streamName + EventStreamConstants.STREAM_DEFINITION_FILE_DELIMITER + streamVersion + EventStreamConstants.STREAM_DEFINITION_FILE_EXTENSION, axisConfig); log.info("Stream definition - " + streamName + EventStreamConstants.STREAM_DEFINITION_DELIMITER + streamVersion + " removed successfully"); } @Override public List<String> getStreamIds() throws EventStreamConfigurationException { Collection<StreamDefinition> eventStreamConfigs = getAllStreamDefinitions(); List<String> streamDefinitionsIds = new ArrayList<String>(eventStreamConfigs.size()); for (StreamDefinition streamDefinition : eventStreamConfigs) { streamDefinitionsIds.add(streamDefinition.getStreamId()); } return streamDefinitionsIds; } @Override public String generateSampleEvent(String streamId, String eventType) throws EventStreamConfigurationException { StreamDefinition streamDefinition = getStreamDefinition(streamId); if (eventType.equals(EventStreamConstants.XML_EVENT)) { return SampleEventGenerator.generateXMLEvent(streamDefinition); } else if (eventType.equals(EventStreamConstants.JSON_EVENT)) { return SampleEventGenerator.generateJSONEvent(streamDefinition); } else if (eventType.equals(EventStreamConstants.TEXT_EVENT)) { return SampleEventGenerator.generateTextEvent(streamDefinition); } return null; } @Override public void subscribe(SiddhiEventConsumer siddhiEventConsumer) throws EventStreamConfigurationException { EventStreamServiceValueHolder.getEventStreamRuntime().subscribe(siddhiEventConsumer); } @Override public void subscribe(EventProducer eventProducer) throws EventStreamConfigurationException { EventStreamServiceValueHolder.getEventStreamRuntime().subscribe(eventProducer); } @Override public void subscribe(WSO2EventConsumer wso2EventConsumer) throws EventStreamConfigurationException { EventStreamServiceValueHolder.getEventStreamRuntime().subscribe(wso2EventConsumer); } @Override public void subscribe(WSO2EventListConsumer wso2EventListConsumer) throws EventStreamConfigurationException { EventStreamServiceValueHolder.getEventStreamRuntime().subscribe(wso2EventListConsumer); } @Override public void unsubscribe(SiddhiEventConsumer siddhiEventConsumer) { EventStreamServiceValueHolder.getEventStreamRuntime().unsubscribe(siddhiEventConsumer); } @Override public void unsubscribe(EventProducer eventProducer) { EventStreamServiceValueHolder.getEventStreamRuntime().unsubscribe(eventProducer); } @Override public void unsubscribe(WSO2EventConsumer wso2EventConsumer) { EventStreamServiceValueHolder.getEventStreamRuntime().unsubscribe(wso2EventConsumer); } @Override public void unsubscribe(WSO2EventListConsumer wso2EventConsumer) { EventStreamServiceValueHolder.getEventStreamRuntime().unsubscribe(wso2EventConsumer); } @Override public void publish(Event event) { EventStreamServiceValueHolder.getEventStreamRuntime().publish(event.getStreamId(), event); } public boolean isEventStreamFileExists(String eventStreamFileName) { int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); Map<String, EventStreamConfiguration> eventStreamConfigs = tenantSpecificEventStreamConfigs.get(tenantId); if (eventStreamConfigs != null) { for (EventStreamConfiguration eventStreamConfiguration : eventStreamConfigs.values()) { if (eventStreamConfiguration.getFileName().equals(eventStreamFileName)) { return true; } } } return false; } public boolean isMatchForStreamDefinition(StreamDefinition streamDefinition, StreamDefinition existingStreamDefinition) { if (streamDefinition == null || existingStreamDefinition == null) { throw new IllegalArgumentException("Stream definitions passed in cannot be null!"); } List<Attribute> existingStreamMetaData = existingStreamDefinition.getMetaData(); List<Attribute> incomingStreamMetaData = streamDefinition.getMetaData(); if (existingStreamMetaData != null && incomingStreamMetaData != null) { if (incomingStreamMetaData.size() != existingStreamMetaData.size()) { return false; } for (int i = 0; i < existingStreamMetaData.size(); i++) { Attribute attribute = existingStreamMetaData.get(i); if (incomingStreamMetaData.get(i) == null || !incomingStreamMetaData.get(i).equals(attribute)) { return false; } } } List<Attribute> existingStreamCorrelationData = existingStreamDefinition.getCorrelationData(); List<Attribute> incomingStreamCorrelationData = streamDefinition.getCorrelationData(); if (existingStreamCorrelationData != null && incomingStreamCorrelationData != null) { if (incomingStreamCorrelationData.size() != existingStreamCorrelationData.size()) { return false; } for (int i = 0; i < existingStreamCorrelationData.size(); i++) { Attribute attribute = existingStreamCorrelationData.get(i); if (incomingStreamCorrelationData.get(i) == null || !incomingStreamCorrelationData.get(i).equals(attribute)) { return false; } } } List<Attribute> existingStreamPayloadData = existingStreamDefinition.getPayloadData(); List<Attribute> incomingStreamPayloadData = streamDefinition.getPayloadData(); if (existingStreamPayloadData != null && incomingStreamPayloadData != null) { if (incomingStreamPayloadData.size() != existingStreamPayloadData.size()) { return false; } for (int i = 0; i < existingStreamPayloadData.size(); i++) { Attribute attribute = existingStreamPayloadData.get(i); if (incomingStreamPayloadData.get(i) == null || !incomingStreamPayloadData.get(i).equals(attribute)) { return false; } } } return true; } }