如何使用Shark

来源:互联网 发布:地瓜网络嗅探器破解 编辑:程序博客网 时间:2024/05/14 20:17

如何使用Shark

 

 

 

 

 

翻译人:林勇                 QQ:313340285

Email:showsscel@gmail.com   MSN:showsscel@hotmail.com

Skype:showsscel

 

 

 

 

Shark介绍及配置 -- Enhydra Shark

 

2007316

版本:1.0

 

       本文仅代表个人对Shark的理解,如有理解错误或不准确的地方,敬请大家指出,我将急时修证。迎大家共同交流、相互学习。

 

 

 

 


3

3

3

4

5

5

10

10

11

11

12

13

13

 

目录

数据库………………………………………………………………………………………………

       如何配置shark使用其它数据库?…………………………………………………………

       如何清除Shark数据库?……………………………………………………………………

       如何调整数据库访问?………………………………………………………………………

Shark客户端接口……………………………………………………………………….. …………

       如何使用shark………………………………………………………………………………

XPDL流程定义…………………………………………………………………………………….

如何写活动的最终期限表达式………………………………………………………………..

如何在shark的管理应用中写为更新/浏览活动变量的扩展属性…………………………..

如何在shark中写使用自定义Java类变量的XPDL………………………………………..

       如何在XPDL中定义变量初始化为“null ………………………………………………

如何指定脚本语言……………………………………………………………………………

       如何使用XPDL直接映射应用程序定义到具体的工作代理(运行时不需要应用程序映射)

      

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

摘要

      这里你可以找到常见问题的答案。

数据库

如何配置shark使用其它数据库

       配置程序结束后将有一个HipersonicSQL数据被创建。这是完全可用的,Shark提供一个选项使用其它数据库:DB2PostgreSQLMySQL,。。。。。

·首先你需要停止任何可能运行(POJO swing管理应用/任务管理者,或者CORBA服务器)的Shark实例。

·编辑configure.properties文件设置下列值:

db_loader_job 包含Octoputs装载器作业的目录名称,选项是:db2,hsql,Informix,msql,mysql,oracle,postgresql,sybase;

db_user 数据库认证用户名;

db_passwd 数据库认证用户密码;

db_ext_dirs 包含JDBC驱动程序包的目录,如果需要定义多于一个的目录- ${path.separator}连接它们;

${db_loader_job}_JdbcDriver 你想使用的JDBC驱动器名称,这些条目已经填充了默认值;

${db_loader_job}_Connection_Url 完整的数据库URL,这些条目已经填充了默认值;

       ·运行configure.[bat|sh]

注意:装载新创建的数据库时,Octopus将抱怨不能删除索引和表,但是这些警告被忽略。

如何清除Shark数据库?

       在测试流程中将开始你想清除的数据并且从零开始,清除数据库你可以运行主configure.[bat|sh]文件。如果你不想等待不必要的过滤,war文档 你运行bin/recreateDB.[bat|sh]

       后面的方法只运行Octopus装载作业删除和创建表和索引。

如何调整数据库访问?

       Shark引擎是组件的一部份,它们中的一些是用DODS与数据库通信[http://dods.objectweb.org/]

       也许知道一些控制DODS行为的参数是派得上用场的。

       DatabaseManager.DB.*.Connection.MaxPoolSize

    连接池控制的连接最大数。如果你知道应用不需要这么多同时连接,在这个连接数量下是安全的。

    DatabaseManager.DB.*.ObjectId.CacheSize

    在内存中被分配为一个组和句柄的对象标识数量。

DatabaseManager.defaults.cache.maxCacheSize

限制能够被存储的对象最大数的缓存的大小。缓存大小是完整的,缓存中的对象通过LRU运算法则用新的对象替换。

DatabaseManager.defaults.cache.maxSimpleCacheSize and DatabaseManager.defaults.cache.maxComplexCacheSize

与主对象缓存相比,有可能使用两种查询缓存(简单的和复合型)。这些查询缓存也是LRU运算法则缓存。

DatabaseManager.defaults.maxExecuteTime

比最大查询时间更长的每一个查询被打印(SQL声明,执行时间和最大执行时间)到日志文件中。通过这种方式你可以发现在应用或引擎内部可能出现的问题。

DatabaseManager.DB.sharkdb.Connection.MaxPoolSize=300

DatabaseManager.DB.sharkdb.ObjectId.CacheSize=200

DatabaseManager.defaults.cache.maxCacheSize=100

DatabaseManager.defaults.cache.maxSimpleCacheSize=50

DatabaseManager.defaults.cache.maxComplexCacheSize=25

DatabaseManager.defaults.maxExecuteTime=200

由于内存消耗和其它原因缓存总在增长,将不能获得更佳的执行效果。

注意:如果你使用相同的数据运行多引擎实例(例如:集群环境),既不能使用DODS也不能使用Shark的缓存。

Shark客户端接口

如何使用Shark

客户端应用通过在org.enhydra.shark.api.client包中的接口设置使用Shark库。首先应用通过调用没有参数(从jar文件中的Shark.conf配置文件中配置Shark)的configure()方法配置任何库,或者调用指定文件名的或准备一个Properties对象的调用方法。配置后org.enhydr.shark.Shark.getInstance()返回一个SharkInterface实例。从这个入手,应用开发者参考(或分配任务)如何使用shark库,或者获取一个连接和执行任务分配或获取一个AdminInterface管理用户,组,包等等。

1.不是非常有用的任务列表管理者

例子的第一行使用conf/Shark.conf文件配置引擎。然后获取一个连接并且成功连接到Shark.查询当前用户有多少资源对象分配(在第四行)。

Shark.configure("conf/Shark.conf");

      SharkConnection sConn = Shark.getInstance().getSharkConnection();

      sConn.connect("qq", "lele", "shark", "");

      if (0 < sConn.getResourceObject().how_many_work_item()) {

          System.err.println("Oh, let these tasks wait until tomorrow!");

      }

      System.out.println("Job done!");

2.用户组管理

如果你设置Shark使用LDAP为用户组管理组件该例子是不能运行的,但是基于数据库组件开始为空,至少定义一个组和用户对于任何操作是有用的。

Shark.configure();

      UserGroupAdministration ugAdmin = Shark.getInstance()

         .getAdminInterface()

         .getUserGroupAdministration();

      ugAdmin.createGroup("developers", "sweat-shop");

      ugAdmin.createUser("developers",

                         "user",

                         "secret",

                         "Jane",

                         "Doe",

                         "some@email.address");

      System.out.println("Group and user created!");

3.装载包到Shark的库

包的XPDL文件位置是XPDL包仓库根的相对路径。执行操作之前,可能想在客户端对象中调用getDefinedPackagesPath()方法取所有包相对路径。首先你需要相对于XPDL包仓库的包的XPDL文件位置,然后你需要获取一个PackageAdministation实例。

String xpdlName = "test.xpdl";

      Properties props = new Properties();

      props.setProperty("enginename", "testSharkInstance");

      props.setProperty("EXTERNAL_PACKAGES_REPOSITORY",

                        "c:/Shark/repository/xpdls");

      Shark.configure(props);

      String pkgId = Shark.getInstance()

         .getRepositoryManager()

         .getPackageId(xpdlName);

      PackageAdministration pa = Shark.getInstance()

         .getAdminInterface()

         .getPackageAdministration();

      if (!pa.isPackageOpened(pkgId)) {

         pa.openPackage(xpdlName);

      }

      System.out.println("Package " + xpdlName + " is loaded");

4.创建和启动流程

装载XPDLshark之后,允许创建流程,填充初始化流程变量的值,启动一些基于在XPDL定义的流程。

String pkgId = "test";

      String pDefId1 = "basic";

      String pDefId2 = "complex";

 

      SharkConnection sConn = Shark.getInstance().getSharkConnection();

 

      sConn.connect("user", "secret", "", "");

 

      WfProcess proc1 = sConn.createProcess(pkgId, pDefId1);

      WfProcess proc2 = sConn.createProcess(pkgId, pDefId2);

 

      Map m1 = new HashMap();

      m1.put("test_var",

            "This is String variable defined in XPDL for the process basic");

      proc1.set_process_context(m1);

      Map m2 = new HashMap();

      m2.put("counter", new Long(55));

      proc2.set_process_context(m2);

 

      proc1.start();

      proc2.start();

5.设置流程相关数据

成功连接到Shark后,获取分配任务列表,允许做一些有用的事,象设置流程相关数据和结束活动。

/*

      SharkConnection sConn;

      String activityId;

      String vName;

      String vValue;

       */

      WfAssignment a = null;

      WfAssignment[] ar = sConn.getResourceObject().get_sequence_work_item(0);

      for (int i = 0; i < ar.length; ++i) {

         if (activityId.equals(ar[i].activity().key())) {

            a = ar[i];

            break;

         }

      }

      if (null == a)

         throw new BaseException("Activity:"

                                 + activityId

                                 +" not found in "

                                 + sConn.getResourceObject().resource_key()

                                 +"'s worklist");

      if (!a.get_accepted_status())

         throw new BaseException("I don't own activity "+ activityId);

      Map _m = new HashMap();

      WfActivity activity = a.activity();

      Object c = activity.process_context().get(vName);

      if (c instanceof Long) {

         c = new Long(vValue);

      } else {

         c = vValue;

      }

      _m.put(vName, c);

      activity.set_result(_m);

      activity.complete();

6.基于一些规则获取流程管理器

这个例子展示如何基于一些规则获取流程管理器。它试着获取包id为“test”并且状态为激活的所有流程管理器。

ExecutionAdministration eAdmin = Shark.getInstance()

         .getAdminInterface()

         .getExecutionAdministration();

      eAdmin.connect("user", "secret", "", "");

 

      WfProcessMgrIterator pmi = eAdmin.get_iterator_processmgr();

      String query = "packageId.equals(/"test/") && enabled.booleanValue()";

      pmi.set_query_expression(query);

      WfProcessMgr[] procs = pmi.get_next_n_sequence(0);

7.基于一些规则获取流程

这个例子展示如何基于一些规则通过一些流程管理器获取流程。它试着获取状态为“open.running”,并且在最近10分钟中启动,并且多于三个活动行为,并且“myvariable”字符串变量的值为“test”的所有流程。

/*

      WfProcessMgr mgr;

       */

      WfProcessIterator wpi = mgr.get_iterator_process();

      String query = "state.equals(/"open.running/") && "

                     + "startTime.longValue()>(java.lang.System.currentTimeMillis()-10*60*1000) && "

                     + "activeActivitiesNo.longValue()>3 && "

                     + "context_myvariable.equals(/"test/")";

      wpi.set_query_expression(query);

      WfProcess[] procs = wpi.get_next_n_sequence(0);

8.使用外部事务

Shark API的每个方法呈现事务分离:引擎内部创建,使用,非强制提交和最终释放事务。也就是说十分简单的代码利用Shark能够不知不觉使用许多事务处理。

有时,需要做不同的事情,因此SharkTransaction被引入。一个应用可以选择使用外部事务为多个理由,包括使用同一数据库存储应用数据,消除频繁创建/释放事务,。。。。

当然,这个方法是有代价的:你必须服从使用角色。事务创建调用Shark.getInstance().createTransaction()方法,只不过释放之前你的应用必须调用Shark.getInstance().unlockProcesses(st)方法通知Shark做内部登记。如果发生任何错误你必须捕获异常并调用Shark.getInstance().emptyCaches(st)清除缓存。是的,你读取知觉的错误信息必须捕获它,否则你将在不明确的状态下退出shark引擎。

    这里是可用于设置修改使用单事务的例子。

  /*

      SharkConnection sConn;

      String activityId;

      String vName;

      String vValue;

       */

      SharkTransaction st = Shark.getInstance().createTransaction();

      try {

         WfAssignment a = null;

         WfAssignment[] ar = sConn.getResourceObject(st)

            .get_sequence_work_item(st, 0);

         for (int i = 0; i < ar.length; ++i) {

            if (activityId.equals(ar[i].activity(st).key(st))) {

               a = ar[i];

               break;

            }

         }

         if (null == a) throw new BaseException("Activity:"

                                                + activityId

                                                + " not found in "

                                                + sConn.getResourceObject(st)

                                                   .resource_key(st)

                                                + "'s worklist");

         if (!a.get_accepted_status(st)) throw new BaseException("I don't own activity "

                                                                 + activityId);

         Map _m = new HashMap();

         WfActivity activity = a.activity(st);

         Object c = activity.process_context(st).get(vName);

         if (c instanceof Long) {

            c = new Long(vValue);

         } else {

            c = vValue;

         }

         _m.put(vName, c);

         activity.set_result(st, _m);

         activity.complete(st);

         st.commit();

      } catch (Throwable t) {

         Shark.getInstance().emptyCaches(st);

         st.rollback();

         if (t instanceof RootException)

            throw (RootException) t;

         else

            throw new RootException(t);

      } finally {

         try {

            Shark.getInstance().unlockProcesses(st);

         } catch (Exception _) {}

         st.release();

      }

XPDL流程定义

       (你可以通过我们的XPDL编辑器JaWE[http://jawe.objectweb.org]很容易创建XPDL)

如何写活动的最终期限表达式

       Shark中的最终期限表达式连同所有流程变量一起,你可以指定变量。Java变量类型是java.util.Date,这里是它们的描述:

       ·PROCESS_STARTED_TIME – 流程启动的时间;

       ·ACTIVITY_ACTIVATED_TIME – 流程到达和任务分配活动创建的时间;

       ·ACTIVITY_ACCEPTED_TIME – 第一个任务分配活动创建的时间;

     注意:如果活动在接受之后被拒绝,或者没有被任何人接受, ACTIVITY_ACCEPTED_TIME将来被设置为一些最大值。

     这里是一些创建最终期限表达式的规则:

     ·最终期限表达式用java.util.Date对象返回值;

·如果shark没有设置重新评估最终期限,而是初化时评估最终期限限制时间,因为将来它包含一些最大时间,所以ACTIVITY_ACCEPTED_TIME不应该用于表达式中。

·在最终期限表达式中不应该有相同Id的流程变量(来自于XPDL中的工作流相关数据或形式参数)。

这里是最终期限表达式的几个例子:

// Deadline limit is set to 15 secunds after accepting activity

var d=new java.util.Date();

d.setTime(ACTIVITY_ACCEPTED_TIME.getTime()+15000);

d;

 

 

// Deadline limit is set to 5 minutes after activity is started (activated)

var d=new java.util.Date();

d.setTime(ACTIVITY_ACTIVATED_TIME.getTime()+300000);

d;

 

// Deadline limit is set to 1 hour after process is started

var d=new java.util.Date();

d.setTime(PROCESS_STARTED_TIME.getTime()+3600000);

d;

如何在shark的管理应用中写为更新/浏览活动变量的扩展属性

       shark管理应用中为了更新活动变量,XPDL活动定义必须包含一些预告确定的扩展属性。

假如XPDL流程定义包含变量(XPDL工作流相关数据标签)“x”和变量(XPDL形式参数类型)input_var”。

如果执行活动时你想管理用户只是能浏览这些变量,你将定义下列的活动扩展属性:

<ExtendedAttribute Name="VariableToProcess_VIEW" Value="x"/>

<ExtendedAttribute Name="VariableToProcess_VIEW" Value="input_var"/>

如果你想用户更新相同的变量,你将定义下列的活动扩展属性:

<ExtendedAttribute Name="VariableToProcess_UPDATE" Value="x"/>

<ExtendedAttribute Name="VariableToProcess_UPDATE" Value="input_var"/>

如何在shark中写使用自定义Java类变量的XPDL

       你将定义变量为XPDL外部参考能够做到,设置你想使用的Java类的全名为位置属性。例如:它应该看起来像下面这样:

     ...

<DataField Id="participants" IsArray="FALSE">

   <DataType>

      <ExternalReference location="org.enhydra.shark.wrd.Participants"/>

   </DataType>

</DataField>

...

...

<FormalParameter Id="participantGroup" Mode="INOUT">

   <DataType>

      <ExternalReference location="org.enhydra.shark.wrd.Participants"/>

   </DataType>

</FormalParameter>

...

    也许最好的方法是定义将使用类型的类型声明元素。你能够在任何地方使用(创建应用/子流程的形式参数时不需要定义适当数据类型):

    ...

<TypeDeclaration Id="participants_type">

   <ExternalReference location="org.enhydra.shark.wrd.Participants"/>

</TypeDeclaration>

...

    然后定义如何数据类型或形式参数:

    ...

<DataField Id="participants" IsArray="FALSE">

   <DataType>

      <DeclaredType Id="participants_type"/>

   </DataType>

</DataField>

...

<FormalParameter Id="participantGroup" Mode="INOUT">

   <DataType>

      <DeclaredType Id="participants_type"/>

   </DataType>

</FormalParameter>

...

    通过外部参数元素指定的类必须在shark的类路径中存在。

如何在XPDL中定义变量初始化为“null

       你简单写入“null“为初始化工作流相关数据元素:

       <DataField Id="participants" IsArray="FALSE">

        <DataType>

            <DeclaredType Id="participants_type"/>

        </DataType>

        <InitialValue>null</InitialValue>

</DataField>

       你能够使用接口或抽象java类为工作流变量。这些类的具体实现能够被工具代理创建。

如何指定脚本语言

       Shark现在支持三种脚本解释程序:JavaScriptBeanShellPython(最后一种没有完全测试过)。告诉shark那个脚本语言被使用在条件表达式,你将指定包的脚本元素:

# if you want to use java-like syntax (interpreted by BeanShell), specify:

 

<Script Type="text/java"/>

 

# if you want to use java script syntax, specify:

 

<Script Type="text/javascript"/>

 

# if you want to use python syntax, specify:

 

<Script Type="text/pythonscript"/>

       如果你没有指定脚本或指定了shark不支持的脚本Shark将发出警告。

如何使用XPDL直接映射应用程序定义到具体的工作代理(运行时不需要应用程序映射)

       如果你想在XPDL中直接指定被工具活动执行的具体工具代理,你将为XPDL应用程序定义一些扩展属性。

       注意映射到工具代理名“ToolAgentClass”的每个应用程序定义的主要扩展属性,它的值是描述工具代理执行的类的全名,例如:

       <ExtendedAttribute Name="ToolAgentClass" Value="org.enhydra.shark.toolagent.JavaScriptToolAgent"/>

    这个属性被shark默认的工具代理读取,shark执行基于这个属性值指定的工具代理。

    其它的扩展属性是指定被工具代理的实现读取的参数,例如,JavaScriptBeanShell工具代理指定扩展属性名“Script,该属性的值是运行时工具代理执行的脚本内容。既然这样,你事实上使用XPDL为程序服务。例如:

    <ExtendedAttribute Name="Script" Value="java.lang.System.out.println(&quot;I'm going to perform operation c=&quot;+a+&quot;*&quot;+b);&#10;c=a*b;&#10;java.lang.System.out.println(&quot;The result is c=&quot;+c);"/>

    这个脚本执行变量“a”和“b”相乘,结果保存到“c(这些变量是XPDL应用程序定义的形式参数)