Shark 怎樣...(翻譯)

   

    你可以從這裏找到常見問題的解答。

   

數據庫

 

 

 

Shark 怎樣與其他數據庫進行配置?

   

    結束安裝過程後,你將有已建好的 HipersonicSQL 數據庫。這還是比較有用的,Shark 也提供了你其他數據庫的選擇:DB2, PostgreSQL, MySQL,....

   

    首先你要停止任何可能正在運行的 Shark 實例(POJO swing 管理/worklist 管理器,或 CORBA 服務器)。

    編輯 configure.properties 文件併爲屬性設置參數:

   

    db_loader_job

   

    目錄名包含了 Octopus 裝載工作,選項有:db2, hsql, informix, msql, mysql, oracle, postgresql, sybase

   

    db_user

   

    數據庫驗證用戶名

   

    db_passwd

   

    數據庫驗證密碼

   

    db_ext_dirs

   

    包含 JDBC 驅動的 jar 文件目錄,如果你需要更多,一個 directory 將被指定 通過 ${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 與數據庫交互。

   

    似乎有些控制 DODS 特性的參數很難理解。

   

    DatabaseManager.DB.*.Connection.MaxPoolSize

   

    連接池能承受連接的最大數目。如果你知道程序不需要太多併發連接,它可以安全的減少數目。

   

    DatabaseManager.DB.*.ObjectId.CacheSize

   

    作爲組分配和保存在內存中的對象標識符數目。這些標識符被指派給新數據對象添加到數據庫。

   

    DatabaseManager.defaults.cache.maxCacheSize

   

    根據對象存儲的最大數目限制的緩存大小。當緩存已滿,緩存中的對象按照 LRU(最近使用)原則被替換爲新對象。

   

    DatabaseManager.defaults.cache.maxSimpleCacheSize

    DatabaseManager.defaults.cache.maxComplexCacheSize

   

    除了主要對象緩存,還有兩種查詢緩存可用(簡單和複雜)。查詢緩存也是 LRU 緩存。

   

    DatabaseManager.defaults.maxExecuteTime

   

    每次運行查詢都比 maxExecuteTime 打印到(SQL 語句,執行時間和 maxExecuteTime)日誌文件的時間長。這種方式可在你的程序或引擎內部發現很細微的可能問題。

   

    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

   

    客戶端程序通過 org.enhydra.shark.api.client 包中的一組接口來訪問 Shark 庫。首先客戶端程序應該配置庫或通過調用不帶參數的 configure() 方法(接着採用 Shark.conf 文件配置的 jar),或通過指定文件名(做爲 String File 對象)或通過準備並調用 Properties 對象方法。配置完畢後 org.enhydra.shark.Shark.getInstance() 返回一個 SharkInterface 實例。從這點開始,客戶端程序開發者偏愛(或任務)知道程序怎樣使用庫,怎樣得到連接和執行指派或得到 AdminInterface 以及管理用戶、組、包,...

   

    例子 1. 不是非常有用的 work-list 管理器

   

    例子的第一行,引擎使用 conf/Shark.conf 文件進行配置。當得到連接和成功連接後,引擎獲取 Resource 對象,來確定爲用戶進行了多少指派(第4行)。

   

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

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

    sConn.connect(userId, passwd, engineName, scope);

    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 user-group 組件,但是基於組件的數據庫開始時確是空的,所以要做任何實際的工作你都需要定義至少一個組和用戶。

   

    Shark.configure();

    UserGroupAdministration ugAdmin =

      Shark.getInstance().getAdminInterface().getUserGroupAdministration()

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

    ugAdmin.createUser("developers", "user", "secret", "Jane Doe", "[email protected]");

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

   

    例子 3. 裝載包到 Shark

   

    包的 XPDL 文件位置與包知識庫的根路徑有關。在你執行該操作之前,通過在客戶端對象調用 getDefinedPackagesPath() 方法你將得到所有的包相關路徑。首先根據包知識庫的根路徑,找到你需要包的 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. 構建和開始流程

   

    當加載 XPDL shark 後,再構建它,填入初始化變量值,啓動基於 XPDL 定義的流程。

   

    String pkgId="test";

    String pDefId1="basic";

    String pDefId2="complex";

 

 

 

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

 

 

 

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

 

 

 

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

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

 

 

 

    proc1.set_process_context("test_var","This is String variable defined in XPDL for the process basic");

    proc2.set_process_context("counter",new Long(55));

 

 

 

    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"並且狀態是 enabled 的所有流程管理器。

   

   ExecutionAdministration eAdmin=Shark.getInstance().getAdminInterface().getExecutionAdministration();

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

 

 

 

   WfProcessMgrIterator pmi=eAdmin.et_iterator_processmgr();

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

   pmi.set_query_expression(query);

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

  

    例子 7. 獲得基於標準的流程

   

    該範例展示了怎樣獲得由基於標準的流程管理器構建的流程。範例試圖得到所有狀態爲"open.running",並且是十分種之前啓動,有 3 個以上的激活活動,有叫做"myvariable"且值爲"test" String 類型變量的流程。

   

   /*

   WfProcessMgr mgr;

   */

 

 

 

   WfProcessIterator wpi=mgr.get_iterator_process ();

   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 被引入進來了。一個程序(的開發者)會因爲多種因素選擇使用外部事務,比如使用相同數據庫保存程序(work-flow無關)數據,這是爲避免經常構建/丟棄事務,...

   

    當然,這種方法也會有代價:你必須遵從於使用規則。通過調用 Shark.getInstance().createTransaction(); 事務被構建,在你釋放一個事務之前,程序必須調用 Shark.getInstance().unlockProcesses(st); 通知 Shark 進行內部記帳。如果有任何錯誤,你必須捕捉 Throwable(異常)再調用 Shark.getInstance().emptyCaches(st);。是的,你甚至應該爲捕獲錯誤而準備好,另外你將面對未知狀態下脫離引擎。

   

    這是利用單一事務進行變量設置的例子。

   

      /*

      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 會使構建 XPDL 變得簡單。)

   

怎樣爲活動定義 deadline 表達式?

   

    shark deadline 表達式中連同所有流程變量,你能使用特殊變量。這些變量的 Java 類型是 java.util.Date,以下是描述:

   

    PROCESS_STARTED_TIME - 流程開始的時間

   

    ACTIVITY_ACTIVATED_TIME - 當流程流到活動以及爲活動構建指派的時間。

   

    ACTIVITY_ACCEPTED_TIME - 第一次爲活動指派的接收時間。

   

    注意

   

    如果活動在接收後被拒絕,或根本沒有接收,ACTIVITY_ACCEPTED_TIME 將會設置成最大值。

   

    在構建 deadline 表達式時有些規則:

   

    Deadline 表達式就是 java.util.Date

   

    如果 shark 設置爲沒有重評估 deadline,而只是最初評估 deadline 時間期限,ACTIVITY_ACCEPTED_TIME 不會被用在表達式中,因爲它將在以後包含最大時間值。

   

    那些不是流程變量(來自於 XPDL DataField FormalParameter 實體),和先前列出的其中之一有相同 Id

   

    一點 deadline 表達式的例子:

   

// 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 DataField 標記),和叫做"input_var"的變量(XPDL FormalParameter 類型)。

   

    如果在執行活動時你想讓管理用戶僅僅查看那些變量,你應該定義如下活動擴展屬性:

   

<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 中怎樣讓 XPDL 使用自定義 Java 類做爲變量

   

    要做到這些,你應該定義變量作爲 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 元素做爲其類型。那樣的話你就可以隨處用到了(當建立程序的/子流程的 FormalParameters 時你不用定義適合的 DataType):

   

...

<TypeDeclaration Id="participants_type">

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

</TypeDeclaration>

...

 

 

 

    定義 DataField FormalParameter

   

...

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

   <DataType>

      <DeclaredType Id="participants_type"/>

   </DataType>

</DataField>

...

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

   <DataType>

      <DeclaredType Id="participants_type"/>

   </DataType>

</FormalParameter>

...

 

 

 

    通過 ExternalReference 元素指定的類必須在 shark 類路徑中。

   

 

 

 

怎樣在 XPDL 中定義變量爲 'null' 的初始值

   

    只需簡單將 DataField InitialValue 元素寫成 "null"

   

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

   <DataType>

      <DeclaredType Id="participants_type"/>

   </DataType>

   <InitialValue>null</InitialValue>

</DataField>

 

 

 

    你可使用接口或抽象 java 類做爲工作流變量。這些變量的具體實現可由一些 tool agent 構建。

   

 

 

 

怎樣指定腳本語言

   

    Shark 目前支持三種腳本解釋器:JavaScriptBeanShell Python(最後一個未完全測試)。要告訴 shark 哪種腳本語言被用於書寫條件式(比如在事務條件中),你應該指定包的 script 元素:

   

# 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 爲特定的 ToolAgent 直接映射程序定義(不需要在運行期爲程序映射)

   

    如果你想直接在 XPDL 中指定 ToolAgentTool 活動將執行該 ToolAgent,所以你應該爲 XPDL 程序定義設置一些擴展屬性。

   

    主要的擴展屬性應該在每個程序定義中定義,趨向於映射給名叫"ToolAgentClass" ToolAgent,並且它的值應該是被執行的 tool agent 類全名,例如:

   

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

   

    該屬性通過 shark tool agent 定義工具閱讀,並且它執行基於該屬性值的特定 ToolAgent

   

    其他外部屬性被指定來實現 tool agent,並通過它們讀取。比如 JavaScript BeanShell tool agent 指定了名爲"Script"的外部屬性,而且內容是通過 tool agent 在運行期執行腳本獲得的。這種情況下,你就是在用 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 程序定義的形參)。 

 

 (請注意!引用、轉貼本文應註明原譯者:Rosen Jiang 以及出處:http://blog.csdn.net/rosen

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章