/** * Copyright (C) 2014 Stratio (http://stratio.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 com.stratio.decision.service; import com.stratio.decision.commons.constants.ColumnType; import com.stratio.decision.commons.constants.EngineActionType; import com.stratio.decision.commons.constants.STREAMING; import com.stratio.decision.commons.constants.StreamAction; import com.stratio.decision.commons.messages.ColumnNameTypeValue; import com.stratio.decision.commons.messages.StratioStreamingMessage; import com.stratio.decision.commons.messages.StreamQuery; import com.stratio.decision.configuration.ConfigurationContext; import com.stratio.decision.dao.StreamStatusDao; import com.stratio.decision.drools.DroolsConnectionContainer; import com.stratio.decision.exception.ServiceException; import com.stratio.decision.functions.engine.BaseEngineAction; import com.stratio.decision.functions.engine.DroolsEngineAction; import com.stratio.decision.streams.QueryDTO; import com.stratio.decision.streams.StreamStatusDTO; import com.stratio.decision.utils.SiddhiUtils; import org.kie.api.runtime.KieContainer; import org.wso2.siddhi.core.SiddhiManager; import org.wso2.siddhi.query.api.QueryFactory; import org.wso2.siddhi.query.api.definition.Attribute; import org.wso2.siddhi.query.api.definition.StreamDefinition; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; /** * Created by ajnavarro on 27/11/14. */ public class StreamOperationServiceWithoutMetrics { private final SiddhiManager siddhiManager; private final StreamStatusDao streamStatusDao; private final CallbackService callbackService; private ConfigurationContext configurationContext; private DroolsConnectionContainer droolsConnectionContainer; public StreamOperationServiceWithoutMetrics(SiddhiManager siddhiManager, StreamStatusDao streamStatusDao, CallbackService callbackService) { this.siddhiManager = siddhiManager; this.streamStatusDao = streamStatusDao; this.callbackService = callbackService; } public StreamOperationServiceWithoutMetrics(SiddhiManager siddhiManager, StreamStatusDao streamStatusDao, CallbackService callbackService, ConfigurationContext configurationContext) { this(siddhiManager, streamStatusDao,callbackService); this.configurationContext = configurationContext; } public StreamOperationServiceWithoutMetrics(SiddhiManager siddhiManager, StreamStatusDao streamStatusDao, CallbackService callbackService, DroolsConnectionContainer droolsConnectionContainer, ConfigurationContext configurationContext) { this(siddhiManager, streamStatusDao, callbackService, configurationContext); this.droolsConnectionContainer = droolsConnectionContainer; } public void createInternalStream(String streamName, List<ColumnNameTypeValue> columns) { StreamDefinition newStream = QueryFactory.createStreamDefinition().name(streamName); for (ColumnNameTypeValue column : columns) { newStream.attribute(column.getColumn(), getSiddhiType(column.getType())); } siddhiManager.defineStream(newStream); streamStatusDao.createInferredStream(streamName, columns); } public void createStream(String streamName, List<ColumnNameTypeValue> columns) { StreamDefinition newStream = QueryFactory.createStreamDefinition().name(streamName); if (columns!=null) { for (ColumnNameTypeValue column : columns) { newStream.attribute(column.getColumn(), getSiddhiType(column.getType())); } } siddhiManager.defineStream(newStream); streamStatusDao.create(streamName, columns); } public boolean streamExist(String streamName) { return streamStatusDao.get(streamName) != null ? true : false; } public boolean isUserDefined(String streamName) { StreamStatusDTO streamStatus = streamStatusDao.get(streamName); return streamStatus != null ? streamStatus.getUserDefined() : false; } public int enlargeStream(String streamName, List<ColumnNameTypeValue> columns) throws ServiceException { // int addedColumns = 0; // StreamDefinition streamMetaData = siddhiManager.getStreamDefinition(streamName); // for (ColumnNameTypeValue columnNameTypeValue : columns) { // if (!SiddhiUtils.columnAlreadyExistsInStream(columnNameTypeValue.getColumn(), streamMetaData)) { // addedColumns++; // streamMetaData.attribute(columnNameTypeValue.getColumn(), getSiddhiType(columnNameTypeValue.getType())); // } else { // throw new ServiceException(String.format("Alter stream error, Column %s already exists.", // columnNameTypeValue.getColumn())); // } // } // // return addedColumns; return enlargeStream(streamName, columns, true); } public int enlargeStream(String streamName, List<ColumnNameTypeValue> columns, Boolean raiseException) throws ServiceException { int addedColumns = 0; StreamDefinition streamMetaData = siddhiManager.getStreamDefinition(streamName); for (ColumnNameTypeValue columnNameTypeValue : columns) { if (!SiddhiUtils.columnAlreadyExistsInStream(columnNameTypeValue.getColumn(), streamMetaData)) { addedColumns++; // JPFM -- Updating the columns in streamStatusDao streamStatusDao.addColumn(streamName, columnNameTypeValue); streamMetaData.attribute(columnNameTypeValue.getColumn(), getSiddhiType(columnNameTypeValue.getType())); } else { if (raiseException) { throw new ServiceException(String.format("Alter stream error, Column %s already " + "exists.", columnNameTypeValue.getColumn())); } } } return addedColumns; } public void dropStream(String streamName) { Map<String, QueryDTO> attachedQueries = streamStatusDao.get(streamName).getAddedQueries(); for (String queryId : attachedQueries.keySet()) { siddhiManager.removeQuery(queryId); } siddhiManager.removeStream(streamName); streamStatusDao.remove(streamName); } public String addQuery(String streamName, String queryString) { String queryId = siddhiManager.addQuery(queryString); streamStatusDao.addQuery(streamName, queryId, queryString); for (StreamDefinition streamDefinition : siddhiManager.getStreamDefinitions()) { // XXX refactor to obtain exactly siddhi inferred streams. streamStatusDao.createInferredStream(streamDefinition.getStreamId(), castToColumnNameTypeValue(streamDefinition.getAttributeList())); } return queryId; } private List<ColumnNameTypeValue> castToColumnNameTypeValue(List<Attribute> attributeList) { List<ColumnNameTypeValue> result = new ArrayList<>(); for (Attribute attribute : attributeList) { result.add(new ColumnNameTypeValue(attribute.getName(), getStreamingType(attribute.getType()), null)); } return result; } public void removeQuery(String queryId, String streamName) { siddhiManager.removeQuery(queryId); streamStatusDao.removeQuery(streamName, queryId); for (Map.Entry<String, StreamStatusDTO> streamStatus : streamStatusDao.getAll().entrySet()) { String temporalStreamName = streamStatus.getKey(); if (siddhiManager.getStreamDefinition(temporalStreamName) == null) { this.dropStream(temporalStreamName); } } } public boolean queryIdExists(String streamName, String queryId) { StreamStatusDTO streamStatus = streamStatusDao.get(streamName); if (streamStatus != null) { return streamStatus.getAddedQueries().containsKey(queryId); } else { return false; } } public boolean queryRawExists(String streamName, String queryRaw) { StreamStatusDTO streamStatus = streamStatusDao.get(streamName); if (streamStatus != null) { return streamStatus.getAddedQueries().containsValue(new QueryDTO(queryRaw)); } else { return false; } } public Boolean columnExists(String streamName, String columnName){ return streamStatusDao.existsColumnDefinition(streamName, columnName); } public void enableAction(String streamName, StreamAction action) { if (streamStatusDao.getEnabledActions(streamName).size() == 0) { String actionQueryId = siddhiManager.addQuery(QueryFactory.createQuery() .from(QueryFactory.inputStream(streamName)) .insertInto(STREAMING.STATS_NAMES.SINK_STREAM_PREFIX.concat(streamName))); streamStatusDao.setActionQuery(streamName, actionQueryId); String groupId = null; if (configurationContext!=null && configurationContext.isClusteringEnabled()){ groupId = configurationContext.getGroupId(); } siddhiManager.addCallback(actionQueryId, callbackService.add(streamName, streamStatusDao.getEnabledActions(streamName), groupId)); } streamStatusDao.enableAction(streamName, action); } public void disableAction(String streamName, StreamAction action) { streamStatusDao.disableAction(streamName, action); if (streamStatusDao.getEnabledActions(streamName).size() == 0) { String actionQueryId = streamStatusDao.getActionQuery(streamName); if (actionQueryId != null) { siddhiManager.removeQuery(actionQueryId); } callbackService.remove(streamName); } } public boolean isActionEnabled(String streamName, StreamAction action) { return streamStatusDao.getEnabledActions(streamName).contains(action); } public void enableEngineAction(String streamName, EngineActionType engineActionType, Map<String, Object> engineActionParams) { this.enableEngineAction(streamName, engineActionType, engineActionParams, this); } protected void enableEngineAction(String streamName, EngineActionType engineActionType, Map<String, Object> engineActionParams, StreamOperationServiceWithoutMetrics streamOperationService) { if ( !streamStatusDao.isEngineActionEnabled(streamName, engineActionType)){ String engineActionQueryId = siddhiManager.addQuery(QueryFactory.createQuery() .from(QueryFactory.inputStream(streamName)) .insertInto(STREAMING.STATS_NAMES.SINK_STREAM_PREFIX.concat(streamName))); BaseEngineAction engineAction = null; if (engineActionType == EngineActionType.FIRE_RULES) { engineAction = new DroolsEngineAction(droolsConnectionContainer, engineActionParams, siddhiManager, streamOperationService); } siddhiManager.addCallback(engineActionQueryId, callbackService.addEngineCallback(streamName, engineActionType, engineAction)); streamStatusDao.enableEngineAction(streamName, engineActionType, engineActionParams, engineActionQueryId); } } public void disableEngineAction(String streamName, EngineActionType engineActionType) { if ( streamStatusDao.isEngineActionEnabled(streamName, engineActionType)){ String engineActionQueryId = streamStatusDao.getEngineActionQueryId(streamName, engineActionType); if (engineActionQueryId != null){ siddhiManager.removeQuery(engineActionQueryId); } streamStatusDao.disableEngineAction(streamName, engineActionType); callbackService.removeEngineAction(streamName, engineActionType); } } public List<StratioStreamingMessage> list() { List<StratioStreamingMessage> result = new ArrayList<>(); for (StreamDefinition streamDefinition : siddhiManager.getStreamDefinitions()) { if (suitableToList(streamDefinition.getStreamId())) { StratioStreamingMessage message = new StratioStreamingMessage(); for (Attribute attribute : streamDefinition.getAttributeList()) { message.addColumn(new ColumnNameTypeValue(attribute.getName(), this.getStreamingType(attribute .getType()), null)); } StreamStatusDTO streamStatus = streamStatusDao.get(streamDefinition.getStreamId()); if (streamStatus != null) { Map<String, QueryDTO> attachedQueries = streamStatus.getAddedQueries(); for (Map.Entry<String, QueryDTO> entry : attachedQueries.entrySet()) { message.addQuery(new StreamQuery(entry.getKey(), entry.getValue().getQueryRaw())); } message.setUserDefined(streamStatus.getUserDefined()); message.setActiveActions(streamStatusDao.getEnabledActions(streamDefinition.getStreamId())); } message.setStreamName(streamDefinition.getStreamId()); result.add(message); } } return result; } private boolean suitableToList(String streamName) { boolean startWithSinkPrefix = streamName.startsWith(STREAMING.STATS_NAMES.SINK_STREAM_PREFIX); boolean isAStatStream = Arrays.asList(STREAMING.STATS_NAMES.STATS_STREAMS).contains(streamName); return !startWithSinkPrefix && !isAStatStream; } public void send(String streamName, List<ColumnNameTypeValue> columns) throws ServiceException { try { siddhiManager.getInputHandler(streamName).send( SiddhiUtils.getOrderedValues(siddhiManager.getStreamDefinition(streamName), columns)); } catch (InterruptedException e) { throw new ServiceException(String.format("Error sending data to stream %s, column data: %s", streamName, columns), e); } } private Attribute.Type getSiddhiType(ColumnType originalType) { switch (originalType) { case STRING: return Attribute.Type.STRING; case BOOLEAN: return Attribute.Type.BOOL; case DOUBLE: return Attribute.Type.DOUBLE; case INTEGER: return Attribute.Type.INT; case LONG: return Attribute.Type.LONG; case FLOAT: return Attribute.Type.FLOAT; default: throw new RuntimeException("Unsupported Column type: " + originalType); } } private ColumnType getStreamingType(Attribute.Type type) { switch (type) { case STRING: return ColumnType.STRING; case BOOL: return ColumnType.BOOLEAN; case DOUBLE: return ColumnType.DOUBLE; case INT: return ColumnType.INTEGER; case LONG: return ColumnType.LONG; case FLOAT: return ColumnType.FLOAT; default: throw new RuntimeException("Unsupported Column type: " + type); } } }