Monitoring Model Deployment

To provide a monitoring for user/realm management and model deployment, you can implement the interface org.eclipse.stardust.engine.core.spi.monitoring.IPartitionMonitor.

This service provider interface can be used to execute custom code in the following cases:

It can be used for instance to implement:

The Interface

package org.eclipse.stardust.engine.core.spi.monitoring;

import org.eclipse.stardust.engine.api.model.IModel;
import org.eclipse.stardust.engine.api.runtime.DeploymentException;
import org.eclipse.stardust.engine.core.runtime.beans.IUser;
import org.eclipse.stardust.engine.core.runtime.beans.IUserRealm;

/**
 * SPI based monitoring for
 * user/realm management
 * model deployment
 */
public interface IPartitionMonitor
{
   /**
    * Client can analyze and monitor argument and method call.
    * 
    * @param realm
    */
   void userRealmCreated(IUserRealm realm);
   
   /**
    * Client can analyze and monitor argument and method call.
    * 
    * @param realm
    */
   void userRealmDropped(IUserRealm realm);
   
   /**
    * Client can analyze and monitor argument and method call.
    * 
    * @param user
    */
   void userCreated(IUser user);
   
   /**
    * Client can analyze and monitor argument and method call.
    * 
    * @param user
    */
   void userEnabled(IUser user);
   
   /**
    * Client can analyze and monitor argument and method call.
    * 
    * @param user
    */
   void userDisabled(IUser user);

   /**
    * Client can check if arguments are valid and otherwise throw an DeploymentException.
    * 
    * @param model
    * @param isOverwrite
    * @throws DeploymentException
    */
   void modelDeployed(IModel model, boolean isOverwrite) throws DeploymentException;
 
   /**
    * Client can check if arguments are valid and otherwise throw an DeploymentException.
    * 
    * @param model
    * @throws DeploymentException
    */
   void modelDeleted(IModel model) throws DeploymentException;   
}

Implementing the IPartitionMonitor Interface

To implement the IPartitionMonitor interface and publish the implementation to the engine, a file named by the interface's factory has to be created in the /META-INF/services folder of the jar. Perform the following steps:

  1. Implement the interface as shown below
  2. Create a text file named org.eclipse.stardust.engine.core.spi.monitoring.IPartitionMonitor. The file contents needs to be the fully qualified name of your implementation class, e.g. org.eclipse.stardust.example.PartitionMonitorImpl.
  3. Place the file into the META-INF/services folder of the jar that will contain your implementation class

Refer to chapter Configuring SPI Implementations per Tenant for details on how to configure custom Service Provider Interface implementations.

package org.eclipse.stardust.example;
 
import java.util.Iterator;
 
import org.eclipse.stardust.common.log.LogManager;
import org.eclipse.stardust.common.log.Logger;
import org.eclipse.stardust.engine.api.model.IModel;
import org.eclipse.stardust.engine.api.model.IProcessDefinition;
import org.eclipse.stardust.engine.api.model.IRole;
import org.eclipse.stardust.engine.api.runtime.DeploymentException;
import org.eclipse.stardust.engine.core.model.utils.ModelElementList;
import org.eclipse.stardust.engine.core.runtime.beans.IUser;
import org.eclipse.stardust.engine.core.runtime.beans.IUserRealm;
import org.eclipse.stardust.engine.core.spi.monitoring.IPartitionMonitor;
 
 
public class PartitionMonitorImpl implements IPartitionMonitor {
 
   final Logger log = LogManager.getLogger(PartitionMonitorImpl.class);
 
   @Override
   public void modelDeleted(IModel arg0) throws DeploymentException {
   }
 
   @Override
   public void modelDeployed(IModel model, boolean arg1)
         throws DeploymentException {
 
      log.info("In modelDeployed. ModelId:" + model.getId());
      ModelElementList<IProcessDefinition> pdList = model.getProcessDefinitions();
 
      for (IProcessDefinition pd : pdList) {
         log.info("Found process definition: " + pd.getId());
      }
 
      @SuppressWarnings("unchecked")
      Iterator<IRole> ritr = model.getAllRoles();
      while (ritr.hasNext()) {
         IRole role = ritr.next();
         log.info(role.getQualifiedId());
      }
   }
 
   @Override
   public void userCreated(IUser arg0) {
   }
 
   @Override
   public void userDisabled(IUser arg0) {
   }
 
   @Override
   public void userEnabled(IUser arg0) {
   }
 
   @Override
   public void userRealmCreated(IUserRealm arg0) {
   }
 
   @Override
   public void userRealmDropped(IUserRealm arg0) {
   }
}

Example Implementation

package custom.bpm.spi.monitoring;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.eclipse.stardust.common.log.LogManager;
import org.eclipse.stardust.common.log.Logger;
import org.eclipse.stardust.engine.api.model.IModel;
import org.eclipse.stardust.engine.api.model.IProcessDefinition;
import org.eclipse.stardust.engine.api.model.Inconsistency;
import org.eclipse.stardust.engine.api.runtime.DeploymentException;
import org.eclipse.stardust.engine.api.runtime.DeploymentInfo;
import org.eclipse.stardust.engine.core.model.utils.ModelElementList;
import org.eclipse.stardust.engine.core.runtime.beans.IUser;
import org.eclipse.stardust.engine.core.runtime.beans.IUserRealm;
import org.eclipse.stardust.engine.core.spi.monitoring.IPartitionMonitor;

public class PartitionMonitor implements IPartitionMonitor
{
   private static String standeredMessage = "Pre Deployment Check";
   private static List<String> deployedModels; 
   protected static Logger trace = LogManager.getLogger(PartitionMonitor.class);
   
   @Override
   public void userRealmCreated(IUserRealm realm)
   {
   }

   @Override
   public void userRealmDropped(IUserRealm realm)
   {
   }

   @Override
   public void userCreated(IUser user)
   {
   }

   @Override
   public void userEnabled(IUser user)
   {
   }

   @Override
   public void userDisabled(IUser user)
   {
   }

   @Override
   public void modelDeployed(IModel model, boolean isOverwrite)
         throws DeploymentException
   {
      trace.info("In modelDeployed : model ="+model.getId());
      if(model.getId().equalsIgnoreCase("MyModel")||model.getId().equalsIgnoreCase("MyConsumer")||model.getId().equalsIgnoreCase("MyProvider")||model.getId().equalsIgnoreCase("FlushModel"))
      {
         trace.info("Going for Monitoring");
         doMonitoring(model,isOverwrite);
      }
         
   }
   
   private void doMonitoring(IModel model, boolean isOverwrite) throws DeploymentException{
      
      String localMessage = standeredMessage+" , "+isOverwrite;
      
      if(isOverwrite)
      {
         throw new DeploymentException("asked to Overwrite",new MyDeploymentInfo(model.getId())); 
      }
      
      if(model.getId().equalsIgnoreCase("FlushModel"))
      { 
         // flush list of models 
         deployedModels = null;
         throw new DeploymentException("Model list cleared",new MyDeploymentInfo(model.getId())); 
      }
      
      ModelElementList<IProcessDefinition> processDefinationList = model.getProcessDefinitions();
      if(processDefinationList.size()!=1)
      {
         throw new DeploymentException("Unexpected number of PDs",new MyDeploymentInfo(model.getId()));
      }
      
      IProcessDefinition pd= processDefinationList.get(0);
   
      trace.info("Got PD : "+pd.getId());
      
      if(pd.getId().equalsIgnoreCase("Deploy")) 
      {  
            if(null == deployedModels)
           {
              trace.info("Creating array list for models list");
              deployedModels = new ArrayList<String>();
           }
            else if(model.getId().equalsIgnoreCase("MyConsumer"))
            {
              trace.info("at consumer");
              if(deployedModels.contains("MyProvider"))
              {     localMessage = localMessage+", second of set provider consumer,first was 'MyProvider'";
                 throw new DeploymentException(localMessage,new MyDeploymentInfo(model.getId()));
              }
              else
              {
                 trace.info("provider was not there");
              }
            } else if(model.getId().equalsIgnoreCase("MyProvider"))
           {        trace.info("at provider");
                 
               if(deployedModels.contains("MyConsumer"))
               {
                  localMessage = localMessage+", second of set provider consumer,first was 'MyConsumer'";
                       throw new DeploymentException(localMessage,new MyDeploymentInfo(model.getId()+""));
               }
               else
               {
                    trace.info("consumer was not there");
               }
           }
            deployedModels.add(model.getId());
      } else if(pd.getId().equalsIgnoreCase("DoNotDeploy"))
      {
         trace.info("Going to throw deployment Exception");
         throw new DeploymentException(localMessage,new MyDeploymentInfo(model.getId()));
      }
      else 
      {
         
         throw new DeploymentException("Error",new MyDeploymentInfo(model.getId()));
      }
   }

   @Override
   public void modelDeleted(IModel model) throws DeploymentException
   {
      trace.info("In modelDeleted : model ="+model.getId());
      if(model.getId().equalsIgnoreCase("MyModel"))
      {
         trace.info("Going to throw exception");
         throw new DeploymentException("asked to delete model",new MyDeploymentInfo(model.getId())); 
      }
   }
      
   static class MyDeploymentInfo implements DeploymentInfo{
      
   private static final long serialVersionUID = 1L;
   
   String message;
      
    public  MyDeploymentInfo(String msg)
    {
       message = msg;
    }
      
   @Override
   public List<Inconsistency> getErrors() {
      return null;
   }

   @Override
   public String getId() {
      return null;
   }

   @Override
   public int getModelOID() {
      return 0;
   }

   @Override
   public List<Inconsistency> getWarnings() {
      return null;
   }

   @Override
   public boolean hasErrors() {
      return false;
   }

   @Override
   public boolean hasWarnings() {
      return false;
   }

   @Override
   public boolean isValid() {
      return false;
   }

   @Override
   public boolean success() {
      return false;
   }

   @Override
   public String getDeploymentComment() {
      trace.info("In get deployment comment");
      return message;
   }

   @Override
   public Date getDeploymentTime() {
      return null;
   }

   @Override
   public int getRevision() {
      return 0;
   }

   @Override
   public Date getValidFrom() {
      // TODO Auto-generated method stub
      return null;
   }
   }
}

Method Invocation Pattern

The invocation of the methods is performed as follows:

In any case, the callback method will be invoked prior to finalizing or committing the deployment operation in question and the action will be rolled back in case the callback implementation throws a DeploymentException.