public void editInactiveExecutionPlanConfiguration(
     String executionPlanConfiguration, String filename, AxisConfiguration axisConfiguration)
     throws ExecutionPlanConfigurationException, ExecutionPlanDependencyValidationException {
   try {
     int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
     OMElement omElement = AXIOMUtil.stringToOM(executionPlanConfiguration);
     EventProcessorConfigurationHelper.validateExecutionPlanConfiguration(omElement, tenantId);
     ExecutionPlanConfiguration config = EventProcessorConfigurationHelper.fromOM(omElement);
     EventProcessorConfigurationFilesystemInvoker.delete(filename, axisConfiguration);
     EventProcessorConfigurationFilesystemInvoker.save(
         executionPlanConfiguration, config.getName(), filename, axisConfiguration);
   } catch (XMLStreamException e) {
     log.error("Error while creating the xml object");
     throw new ExecutionPlanConfigurationException("Not a valid xml object ", e);
   }
 }
  private SiddhiConfiguration getSiddhiConfigurationFor(
      ExecutionPlanConfiguration executionPlanConfiguration, int tenantId)
      throws ServiceDependencyValidationException {
    SiddhiConfiguration siddhiConfig = new SiddhiConfiguration();
    siddhiConfig.setAsyncProcessing(false);
    siddhiConfig.setInstanceIdentifier(
        "org.wso2.siddhi.instance-" + tenantId + "-" + UUID.randomUUID().toString());

    String isDistributedProcessingEnabledString =
        executionPlanConfiguration
            .getSiddhiConfigurationProperties()
            .get(EventProcessorConstants.SIDDHI_DISTRIBUTED_PROCESSING);
    if (isDistributedProcessingEnabledString != null
        && (isDistributedProcessingEnabledString.equalsIgnoreCase("DistributedCache")
            || isDistributedProcessingEnabledString.equalsIgnoreCase("true"))) {
      siddhiConfig.setDistributedProcessing(true);
      if (EventProcessorValueHolder.getHazelcastInstance() != null) {
        siddhiConfig.setInstanceIdentifier(
            EventProcessorValueHolder.getHazelcastInstance().getName());
      } else {
        throw new ServiceDependencyValidationException(
            EventProcessorConstants.HAZELCAST_INSTANCE, "Hazelcast instance is not initialized.");
      }
    } else if (isDistributedProcessingEnabledString != null
        && isDistributedProcessingEnabledString.equalsIgnoreCase("RedundantNode")) {
      siddhiConfig.setDistributedProcessing(false);
      if (EventProcessorValueHolder.getHazelcastInstance() != null) {
        siddhiConfig.setInstanceIdentifier(
            EventProcessorValueHolder.getHazelcastInstance().getName());
      } else {
        throw new ServiceDependencyValidationException(
            EventProcessorConstants.HAZELCAST_INSTANCE, "Hazelcast instance is not initialized.");
      }
    } else {
      siddhiConfig.setDistributedProcessing(false);
    }

    siddhiConfig.setQueryPlanIdentifier(
        "org.wso2.siddhi-" + tenantId + "-" + executionPlanConfiguration.getName());
    siddhiConfig.setSiddhiExtensions(SiddhiExtensionLoader.loadSiddhiExtensions());
    return siddhiConfig;
  }
 public void editActiveExecutionPlanConfiguration(
     String executionPlanConfiguration,
     String executionPlanName,
     AxisConfiguration axisConfiguration)
     throws ExecutionPlanConfigurationException, ExecutionPlanDependencyValidationException {
   int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
   try {
     OMElement omElement = AXIOMUtil.stringToOM(executionPlanConfiguration);
     EventProcessorConfigurationHelper.validateExecutionPlanConfiguration(omElement, tenantId);
     ExecutionPlanConfiguration executionPlanConfigurationObject =
         EventProcessorConfigurationHelper.fromOM(omElement);
     if (!(executionPlanConfigurationObject.getName().equals(executionPlanName))) {
       if (!(checkExecutionPlanValidity(executionPlanConfigurationObject.getName(), tenantId))) {
         throw new ExecutionPlanConfigurationException(
             executionPlanConfigurationObject.getName()
                 + " already registered as an execution in this tenant");
       }
     }
     if (executionPlanName != null && executionPlanName.length() > 0) {
       String fileName;
       ExecutionPlanConfigurationFile file =
           getExecutionPlanConfigurationFileByPlanName(executionPlanName, tenantId);
       if (file == null) {
         fileName = executionPlanName + EventProcessorConstants.EP_CONFIG_FILE_EXTENSION_WITH_DOT;
       } else {
         fileName = file.getFileName();
       }
       EventProcessorConfigurationFilesystemInvoker.delete(fileName, axisConfiguration);
       EventProcessorConfigurationFilesystemInvoker.save(
           executionPlanConfiguration, executionPlanName, fileName, axisConfiguration);
     } else {
       throw new ExecutionPlanConfigurationException(
           "Invalid configuration provided, No execution plan name.");
     }
   } catch (XMLStreamException e) {
     log.error("Error while creating the xml object");
     throw new ExecutionPlanConfigurationException("Not a valid xml object, ", e);
   }
 }
  @Override
  public void deployExecutionPlanConfiguration(
      ExecutionPlanConfiguration executionPlanConfiguration, AxisConfiguration axisConfiguration)
      throws ExecutionPlanDependencyValidationException, ExecutionPlanConfigurationException {

    String executionPlanName = executionPlanConfiguration.getName();

    int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
    OMElement omElement = EventProcessorConfigurationHelper.toOM(executionPlanConfiguration);
    EventProcessorConfigurationHelper.validateExecutionPlanConfiguration(omElement, tenantId);

    File directory = new File(axisConfiguration.getRepository().getPath());
    if (!directory.exists()) {
      if (directory.mkdir()) {
        throw new ExecutionPlanConfigurationException(
            "Cannot create directory to add tenant specific execution plan : " + executionPlanName);
      }
    }
    directory =
        new File(
            directory.getAbsolutePath()
                + File.separator
                + EventProcessorConstants.EP_ELE_DIRECTORY);
    if (!directory.exists()) {
      if (!directory.mkdir()) {
        throw new ExecutionPlanConfigurationException(
            "Cannot create directory "
                + EventProcessorConstants.EP_ELE_DIRECTORY
                + " to add tenant specific  execution plan :"
                + executionPlanName);
      }
    }
    validateToRemoveInactiveExecutionPlanConfiguration(executionPlanName, axisConfiguration);
    EventProcessorConfigurationFilesystemInvoker.save(
        omElement,
        executionPlanName,
        executionPlanName + EventProcessorConstants.XML_EXTENSION,
        axisConfiguration);
  }
  private SiddhiManager getSiddhiManagerFor(
      ExecutionPlanConfiguration executionPlanConfiguration,
      SiddhiConfiguration siddhiConfig,
      Map<String, InputHandler> inputHandlerMap)
      throws ExecutionPlanConfigurationException {
    SiddhiManager siddhiManager = new SiddhiManager(siddhiConfig);
    try {
      int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
      if (tenantId > -1) {
        DataSourceManager.getInstance().initTenant(tenantId);
      }
      List<CarbonDataSource> dataSources =
          EventProcessorValueHolder.getDataSourceService().getAllDataSources();
      for (CarbonDataSource cds : dataSources) {
        try {
          if (cds.getDSObject() instanceof DataSource) {
            siddhiManager
                .getSiddhiContext()
                .addDataSource(cds.getDSMInfo().getName(), (DataSource) cds.getDSObject());
          }
        } catch (Exception e) {
          log.error("Unable to add the datasource" + cds.getDSMInfo().getName(), e);
        }
      }
    } catch (DataSourceException e) {
      log.error("Unable to populate the data sources in Siddhi engine.", e);
    }

    int persistenceTimeInterval = 0;
    try {
      persistenceTimeInterval =
          Integer.parseInt(
              executionPlanConfiguration
                  .getSiddhiConfigurationProperties()
                  .get(EventProcessorConstants.SIDDHI_SNAPSHOT_INTERVAL));
    } catch (NumberFormatException e) {
      log.error("Unable to parse snapshot time interval.", e);
    }

    if (persistenceTimeInterval > 0) {
      if (null == EventProcessorValueHolder.getPersistenceStore()) {
        if (EventProcessorValueHolder.getClusterInformation() == null) {
          try {
            String adminPassword =
                EventProcessorValueHolder.getUserRealm().getRealmConfiguration().getAdminPassword();
            String adminUserName =
                EventProcessorValueHolder.getUserRealm().getRealmConfiguration().getAdminUserName();

            ClusterInformation clusterInformation =
                new ClusterInformation(adminUserName, adminPassword);
            clusterInformation.setClusterName(CassandraPersistenceStore.CLUSTER_NAME);
            EventProcessorValueHolder.setClusterInformation(clusterInformation);
          } catch (UserStoreException e) {
            log.error("Unable to get realm configuration.", e);
          }
        }
        if (CassandraConnectionValidator.getInstance()
            .checkCassandraConnection(
                EventProcessorValueHolder.getClusterInformation().getUsername(),
                EventProcessorValueHolder.getClusterInformation().getPassword())) {
          Cluster cluster =
              EventProcessorValueHolder.getDataAccessService()
                  .getCluster(EventProcessorValueHolder.getClusterInformation());
          CassandraPersistenceStore casandraPersistenceStore =
              new CassandraPersistenceStore(cluster);
          EventProcessorValueHolder.setPersistenceStore(casandraPersistenceStore);
        } else {
          throw new ExecutionPlanConfigurationException(
              "Cannot connect to Cassandra. To run with embedded Cassandra enabled, start the server with command: ./wso2server.sh -Ddisable.cassandra.server.startup=false");
        }
      }
      siddhiManager.setPersistStore(EventProcessorValueHolder.getPersistenceStore());
    }
    return siddhiManager;
  }
  public void addExecutionPlanConfiguration(
      ExecutionPlanConfiguration executionPlanConfiguration, AxisConfiguration axisConfiguration)
      throws ExecutionPlanDependencyValidationException, ExecutionPlanConfigurationException,
          ServiceDependencyValidationException {
    int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
    Map<String, ExecutionPlan> tenantExecutionPlans = tenantSpecificExecutionPlans.get(tenantId);
    if (tenantExecutionPlans == null) {
      tenantExecutionPlans = new ConcurrentHashMap<String, ExecutionPlan>();
      tenantSpecificExecutionPlans.put(tenantId, tenantExecutionPlans);
    } else if (tenantExecutionPlans.get(executionPlanConfiguration.getName()) != null) {
      // if an execution plan with the same name already exists, we are not going to override it
      // with this plan.
      throw new ExecutionPlanConfigurationException(
          "Execution plan with the same name already exists. Please remove it and retry.");
    }

    // This iteration exists only as a check. Actual usage of imported stream configs is further
    // down
    for (StreamConfiguration streamConfiguration :
        executionPlanConfiguration.getImportedStreams()) {
      try {
        StreamDefinition streamDefinition =
            EventProcessorValueHolder.getEventStreamService()
                .getStreamDefinition(streamConfiguration.getStreamId(), tenantId);
        if (streamDefinition == null) {
          throw new ExecutionPlanDependencyValidationException(
              streamConfiguration.getStreamId(),
              "Imported Stream " + streamConfiguration.getStreamId() + " does not exist");
        }
      } catch (EventStreamConfigurationException e) {
        throw new ExecutionPlanConfigurationException(
            "Error in retrieving stream ID : " + streamConfiguration.getStreamId());
      }
    }

    // This iteration exists only as a check. Actual usage of exported stream configs is further
    // down
    for (StreamConfiguration streamConfiguration :
        executionPlanConfiguration.getExportedStreams()) {
      try {
        StreamDefinition streamDefinition =
            EventProcessorValueHolder.getEventStreamService()
                .getStreamDefinition(streamConfiguration.getStreamId(), tenantId);
        if (streamDefinition == null) {
          throw new ExecutionPlanDependencyValidationException(
              streamConfiguration.getStreamId(),
              "Exported Stream " + streamConfiguration.getStreamId() + " does not exist");
        }
      } catch (EventStreamConfigurationException e) {
        throw new ExecutionPlanConfigurationException(
            "Error in retrieving stream ID : " + streamConfiguration.getStreamId());
      }
    }

    Map<String, InputHandler> inputHandlerMap =
        new ConcurrentHashMap<String, InputHandler>(
            executionPlanConfiguration.getImportedStreams().size());

    SiddhiConfiguration siddhiConfig =
        getSiddhiConfigurationFor(executionPlanConfiguration, tenantId);
    SiddhiManager siddhiManager =
        getSiddhiManagerFor(executionPlanConfiguration, siddhiConfig, inputHandlerMap);

    for (StreamConfiguration importedStreamConfiguration :
        executionPlanConfiguration.getImportedStreams()) {
      org.wso2.siddhi.query.api.definition.StreamDefinition siddhiStreamDefinition =
          new org.wso2.siddhi.query.api.definition.StreamDefinition();
      siddhiStreamDefinition.name(importedStreamConfiguration.getSiddhiStreamName());
      StreamDefinition streamDefinition = null;
      try {
        streamDefinition =
            EventProcessorValueHolder.getEventStreamService()
                .getStreamDefinition(importedStreamConfiguration.getStreamId(), tenantId);

        populateAttributes(
            siddhiStreamDefinition,
            streamDefinition.getMetaData(),
            EventProcessorConstants.META + EventProcessorConstants.ATTRIBUTE_SEPARATOR);
        populateAttributes(
            siddhiStreamDefinition,
            streamDefinition.getCorrelationData(),
            EventProcessorConstants.CORRELATION + EventProcessorConstants.ATTRIBUTE_SEPARATOR);
        populateAttributes(siddhiStreamDefinition, streamDefinition.getPayloadData(), "");
        InputHandler inputHandler = siddhiManager.defineStream(siddhiStreamDefinition);
        inputHandlerMap.put(streamDefinition.getStreamId(), inputHandler);
        log.debug("input handler created for " + siddhiStreamDefinition.getStreamId());
      } catch (EventStreamConfigurationException e) {
        // ignored as this will not happen
      }
    }

    for (StreamConfiguration exportedStreamConfiguration :
        executionPlanConfiguration.getExportedStreams()) {
      org.wso2.siddhi.query.api.definition.StreamDefinition siddhiStreamDefinition =
          new org.wso2.siddhi.query.api.definition.StreamDefinition();
      siddhiStreamDefinition.name(exportedStreamConfiguration.getSiddhiStreamName());
      StreamDefinition streamDefinition = null;
      try {
        streamDefinition =
            EventProcessorValueHolder.getEventStreamService()
                .getStreamDefinition(exportedStreamConfiguration.getStreamId(), tenantId);

        populateAttributes(
            siddhiStreamDefinition,
            streamDefinition.getMetaData(),
            EventProcessorConstants.META + EventProcessorConstants.ATTRIBUTE_SEPARATOR);
        populateAttributes(
            siddhiStreamDefinition,
            streamDefinition.getCorrelationData(),
            EventProcessorConstants.CORRELATION + EventProcessorConstants.ATTRIBUTE_SEPARATOR);
        populateAttributes(siddhiStreamDefinition, streamDefinition.getPayloadData(), "");
        siddhiManager.defineStream(siddhiStreamDefinition);
        log.debug("stream defined for " + siddhiStreamDefinition.getStreamId());
      } catch (EventStreamConfigurationException e) {
        // ignored as this will not happen
      }
    }

    HAManager haManager = null;
    String isDistributedProcessingEnabledString =
        executionPlanConfiguration
            .getSiddhiConfigurationProperties()
            .get(EventProcessorConstants.SIDDHI_DISTRIBUTED_PROCESSING);
    if (isDistributedProcessingEnabledString != null
        && isDistributedProcessingEnabledString.equalsIgnoreCase("RedundantNode")) {
      haManager =
          new HAManager(
              EventProcessorValueHolder.getHazelcastInstance(),
              executionPlanConfiguration.getName(),
              tenantId,
              siddhiManager,
              inputHandlerMap.size(),
              currentCepMembershipInfo);
    }

    try {
      siddhiManager.addExecutionPlan(executionPlanConfiguration.getQueryExpressions());
    } catch (Exception e) {
      throw new ExecutionPlanConfigurationException(
          "Invalid query specified, " + e.getMessage(), e);
    }

    ExecutionPlan executionPlan =
        new ExecutionPlan(
            executionPlanConfiguration.getName(),
            siddhiManager,
            executionPlanConfiguration,
            haManager);
    tenantExecutionPlans.put(executionPlanConfiguration.getName(), executionPlan);

    // subscribe output to junction
    SindhiStormOutputEventListener stormOutputListener = null;
    if (isRunningOnStorm) {
      stormOutputListener =
          new SindhiStormOutputEventListener(executionPlanConfiguration, tenantId);
    }
    for (StreamConfiguration exportedStreamConfiguration :
        executionPlanConfiguration.getExportedStreams()) {

      SiddhiOutputStreamListener streamCallback;

      if (haManager != null) {
        streamCallback =
            new SiddhiHAOutputStreamListener(
                exportedStreamConfiguration.getSiddhiStreamName(),
                exportedStreamConfiguration.getStreamId(),
                executionPlanConfiguration,
                tenantId);
        haManager.addStreamCallback((SiddhiHAOutputStreamListener) streamCallback);
      } else {
        streamCallback =
            new SiddhiOutputStreamListener(
                exportedStreamConfiguration.getSiddhiStreamName(),
                exportedStreamConfiguration.getStreamId(),
                executionPlanConfiguration,
                tenantId);

        if (isRunningOnStorm) {
          stormOutputListener.registerOutputStreamListener(
              exportedStreamConfiguration.getSiddhiStreamName(), streamCallback);
        }
      }
      siddhiManager.addCallback(exportedStreamConfiguration.getSiddhiStreamName(), streamCallback);
      try {
        EventProcessorValueHolder.getEventStreamService().subscribe(streamCallback, tenantId);
      } catch (EventStreamConfigurationException e) {
        // ignored as this will never happen
      }
      executionPlan.addProducer(streamCallback);
    }

    // subscribe input to junction
    for (StreamConfiguration importedStreamConfiguration :
        executionPlanConfiguration.getImportedStreams()) {
      InputHandler inputHandler = inputHandlerMap.get(importedStreamConfiguration.getStreamId());

      AbstractSiddhiInputEventDispatcher eventDispatcher = null;
      if (haManager != null) {
        eventDispatcher =
            new SiddhiHAInputEventDispatcher(
                importedStreamConfiguration.getStreamId(),
                inputHandler,
                executionPlanConfiguration,
                tenantId,
                haManager.getProcessThreadPoolExecutor(),
                haManager.getThreadBarrier());
        haManager.addInputEventDispatcher(
            importedStreamConfiguration.getStreamId(),
            (SiddhiHAInputEventDispatcher) eventDispatcher);
      } else if (isRunningOnStorm) {
        StreamDefinition streamDefinition = null;
        try {
          streamDefinition =
              EventProcessorValueHolder.getEventStreamService()
                  .getStreamDefinition(importedStreamConfiguration.getStreamId(), tenantId);
        } catch (EventStreamConfigurationException e) {
          // Ignore as this would never happen
        }
        eventDispatcher =
            new SiddhiStormInputEventDispatcher(
                streamDefinition,
                importedStreamConfiguration.getSiddhiStreamName(),
                executionPlanConfiguration,
                tenantId);
      } else {
        eventDispatcher =
            new SiddhiInputEventDispatcher(
                importedStreamConfiguration.getStreamId(),
                inputHandler,
                executionPlanConfiguration,
                tenantId);
      }

      try {
        EventProcessorValueHolder.getEventStreamService().subscribe(eventDispatcher, tenantId);
        executionPlan.addConsumer(eventDispatcher);

      } catch (EventStreamConfigurationException e) {
        // ignored as this will never happen
      }
    }

    if (haManager != null) {
      haManager.init();
    }
  }