/** * Returns the execution plan name * * @param executionPlanAsString executionPlan (taken from code mirror) as a string * @return execution plan name as given in @Plan:name('MyPlanName'). Returns null in the absence * of @Plan:name('MyPlanName') */ public static String getExecutionPlanName(String executionPlanAsString) { String executionPlanName = null; ExecutionPlan executionPlan = SiddhiCompiler.parse(executionPlanAsString); executionPlanName = AnnotationHelper.getAnnotationElement( EventProcessorConstants.ANNOTATION_NAME_NAME, null, executionPlan.getAnnotations()) .getValue(); return executionPlanName; }
public static void validateExecutionPlan(String executionPlan) throws ExecutionPlanConfigurationException, ExecutionPlanDependencyValidationException { String planName; int i = 0; // this is maintained for giving more context info in error messages, when throwing // exceptions. ArrayList<String> importedStreams = new ArrayList<String>(); ArrayList<String> exportedStreams = new ArrayList<String>(); Pattern databridgeStreamNamePattern = Pattern.compile(EventProcessorConstants.DATABRIDGE_STREAM_REGEX); Pattern streamVersionPattern = Pattern.compile(EventProcessorConstants.STREAM_VER_REGEX); ExecutionPlan parsedExecPlan = SiddhiCompiler.parse(executionPlan); Element element = AnnotationHelper.getAnnotationElement( EventProcessorConstants.ANNOTATION_NAME_NAME, null, parsedExecPlan.getAnnotations()); if (element == null) { // check if plan name is given throw new ExecutionPlanConfigurationException( "Execution plan name is not given. Please specify execution plan name using the annotation " + "'" + EventProcessorConstants.ANNOTATION_TOKEN_AT + EventProcessorConstants.ANNOTATION_PLAN + EventProcessorConstants.ANNOTATION_TOKEN_COLON + EventProcessorConstants.ANNOTATION_NAME_NAME + EventProcessorConstants.ANNOTATION_TOKEN_OPENING_BRACKET + EventProcessorConstants.SIDDHI_SINGLE_QUOTE + "executionPlanNameHere" + EventProcessorConstants.SIDDHI_SINGLE_QUOTE + EventProcessorConstants.ANNOTATION_TOKEN_CLOSING_BRACKET + "'"); } planName = element.getValue(); if (planName.equals("")) { throw new ExecutionPlanConfigurationException( "Execution plan name is empty. Hence the plan is invalid"); } if (planName.trim().contains(" ")) { throw new ExecutionPlanConfigurationException( "Execution plan name '" + planName + "' contains whitespaces. Please remove whitespaces."); } Map<String, org.wso2.siddhi.query.api.definition.StreamDefinition> streamDefMap = parsedExecPlan.getStreamDefinitionMap(); for (Map.Entry<String, org.wso2.siddhi.query.api.definition.StreamDefinition> entry : streamDefMap.entrySet()) { Element importElement = AnnotationHelper.getAnnotationElement( EventProcessorConstants.ANNOTATION_IMPORT, null, entry.getValue().getAnnotations()); Element exportElement = AnnotationHelper.getAnnotationElement( EventProcessorConstants.ANNOTATION_EXPORT, null, entry.getValue().getAnnotations()); if (importElement != null && exportElement != null) { throw new ExecutionPlanConfigurationException( "Same stream definition has being imported and exported. Please correct " + i + "th of the " + parsedExecPlan.getStreamDefinitionMap().size() + "stream definition, with stream id '" + entry.getKey() + "'"); } if (importElement != null) { // Treating import & export cases separately to give more specific error // messages. String atImportLiteral = EventProcessorConstants.ANNOTATION_TOKEN_AT + EventProcessorConstants.ANNOTATION_IMPORT; String importElementValue = importElement.getValue(); if (importElementValue == null || importElementValue.trim().isEmpty()) { throw new ExecutionPlanConfigurationException( "Imported stream cannot be empty as in '" + atImportLiteral + EventProcessorConstants.ANNOTATION_TOKEN_OPENING_BRACKET + EventProcessorConstants.SIDDHI_SINGLE_QUOTE + EventProcessorConstants.SIDDHI_SINGLE_QUOTE + EventProcessorConstants.ANNOTATION_TOKEN_CLOSING_BRACKET + "'. Please correct " + i + "th of the " + parsedExecPlan.getStreamDefinitionMap().size() + "stream definition, with stream id '" + entry.getKey() + "'"); } String[] streamIdComponents = importElementValue.split(EventProcessorConstants.STREAM_SEPARATOR); if (streamIdComponents.length != 2) { throw new ExecutionPlanConfigurationException( "Found malformed " + atImportLiteral + " element '" + importElementValue + "'. " + atImportLiteral + " annotation should take the form '" + atImportLiteral + EventProcessorConstants.ANNOTATION_TOKEN_OPENING_BRACKET + EventProcessorConstants.SIDDHI_SINGLE_QUOTE + "streamName" + EventProcessorConstants.STREAM_SEPARATOR + "StreamVersion" + EventProcessorConstants.SIDDHI_SINGLE_QUOTE + EventProcessorConstants.ANNOTATION_TOKEN_CLOSING_BRACKET + "'. There should be a '" + EventProcessorConstants.STREAM_SEPARATOR + "' character, separating the streamName and its version"); } if ((!databridgeStreamNamePattern.matcher(streamIdComponents[0].trim()).matches())) { throw new ExecutionPlanConfigurationException( "Invalid imported stream name[" + streamIdComponents[0] + "] in execution plan:" + planName + ". Stream name should match the regex '" + EventProcessorConstants.DATABRIDGE_STREAM_REGEX + "'"); } Matcher m = streamVersionPattern.matcher(streamIdComponents[1].trim()); if (!m.matches()) { throw new ExecutionPlanConfigurationException( "Invalid stream version [" + streamIdComponents[1] + "] for stream name " + streamIdComponents[0] + " in execution plan: " + planName + ". Stream version should match the regex '" + EventProcessorConstants.STREAM_VER_REGEX + "'"); } validateSiddhiStreamWithDatabridgeStream( streamIdComponents[0], streamIdComponents[1], entry.getValue()); if (exportedStreams.contains( importElementValue)) { // check if same stream has been imported and exported. throw new ExecutionPlanConfigurationException( "Imported stream '" + importElementValue + "' is also among the exported streams. Hence the execution plan is invalid"); } importedStreams.add(importElementValue); } if (exportElement != null) { String atExportLiteral = EventProcessorConstants.ANNOTATION_TOKEN_AT + EventProcessorConstants.ANNOTATION_EXPORT; String exportElementValue = exportElement.getValue(); if (exportElementValue == null || exportElementValue.trim().isEmpty()) { throw new ExecutionPlanConfigurationException( "Exported stream cannot be empty as in '" + atExportLiteral + EventProcessorConstants.ANNOTATION_TOKEN_OPENING_BRACKET + EventProcessorConstants.SIDDHI_SINGLE_QUOTE + EventProcessorConstants.SIDDHI_SINGLE_QUOTE + EventProcessorConstants.ANNOTATION_TOKEN_CLOSING_BRACKET + "'. Please correct " + i + "th of the " + parsedExecPlan.getStreamDefinitionMap().size() + "stream definition, with stream id '" + entry.getKey()); } String[] streamIdComponents = exportElementValue.split(EventProcessorConstants.STREAM_SEPARATOR); if (streamIdComponents.length != 2) { throw new ExecutionPlanConfigurationException( "Found malformed " + atExportLiteral + " element '" + exportElementValue + "'. " + atExportLiteral + " annotation should take the form '" + atExportLiteral + EventProcessorConstants.ANNOTATION_TOKEN_OPENING_BRACKET + EventProcessorConstants.SIDDHI_SINGLE_QUOTE + "streamName" + EventProcessorConstants.STREAM_SEPARATOR + "StreamVersion" + EventProcessorConstants.SIDDHI_SINGLE_QUOTE + EventProcessorConstants.ANNOTATION_TOKEN_CLOSING_BRACKET + "'. There should be a '" + EventProcessorConstants.STREAM_SEPARATOR + "' character, separating the streamName and its version"); } if ((!databridgeStreamNamePattern.matcher(streamIdComponents[0].trim()).matches())) { throw new ExecutionPlanConfigurationException( "Invalid exported stream name[" + streamIdComponents[0] + "] in execution plan:" + planName + ". Stream name should match the regex '" + EventProcessorConstants.DATABRIDGE_STREAM_REGEX + "'"); } Matcher m = streamVersionPattern.matcher(streamIdComponents[1].trim()); if (!m.matches()) { throw new ExecutionPlanConfigurationException( "Invalid stream version [" + streamIdComponents[1] + "] for stream name " + streamIdComponents[0] + " in execution plan: " + planName + ". Stream version should match the regex '" + EventProcessorConstants.STREAM_VER_REGEX + "'"); } validateSiddhiStreamWithDatabridgeStream( streamIdComponents[0], streamIdComponents[1], entry.getValue()); if (importedStreams.contains(exportElementValue)) { throw new ExecutionPlanConfigurationException( "Exported stream '" + exportElementValue + "' is also among the imported streams. Hence the execution plan is invalid"); } exportedStreams.add(exportElementValue); } i++; } SiddhiManager siddhiManager = EventProcessorValueHolder.getSiddhiManager(); loadDataSourceConfiguration(siddhiManager); try { siddhiManager.validateExecutionPlan(executionPlan); } catch (Throwable t) { throw new ExecutionPlanConfigurationException(t.getMessage(), t); } }