Tích hợp FileNet với IBM Content Manager, Phần 2: Triển khai
thực hiện các thực thể nghiệp vụ Java và lớp cổng (gateway) cho dữ
liệu trong kho lưu trữ lưu trữ của IBM Content Manager
Mở đầu
Phần 1 của loạt bài này đã giới thiệu cho bạn về các kiến trúc của FileNet P8 BPM và IBM
Content Manager. Bài viết đã sử dụng một hệ thống Yêu cầu bồi thường bảo hiểm tự động của
công ty ABC hư cấu để cho bạn thấy cách tích hợp hai sản phẩm mạnh mẽ này.
Phần 2 giới thiệu các trình diễn công việc của FileNet P8 và cho bạn thấy cách triển khai thực
hiện các thực thể nghiệp vụ Java. Bạn sẽ tìm hiểu cách tạo ra một lớp cổng Java và xem cách sử
dụng tuần tự hóa Java để tránh các hạn chế cụ thể.
Về đầu trang
Các trình diễn công việc
Để sử dụng một kho lưu trữ nội dung của bên thứ ba, FileNet Business Process Management
(BPM) cần có khả năng giao tiếp với kho lưu trữ IBM Content Manager. Các trình diễn công
việc FileNet có thể cho phép BPM tương tác với các ứng dụng hoặc các mã của bên thứ ba.
Trong FileNet P8, các trình diễn công việc cho phép một ứng dụng thực hiện một hoạt động hoặc
một tập các hoạt động liên quan đến một dòng công việc. Thông thường, các trình diễn công việc
được thiết kế không có giao diện người dùng và được sử dụng để thực hiện các hoạt động dòng
công việc tự động, chẳng hạn như các hoạt động được liên kết với một bước dòng công việc cụ
thể trong một định nghĩa dòng công việc. Các hoạt động trình diễn công việc được liên kết với
các bước dòng công việc bao gồm đăng nhập và thiết lập một phiên làm việc của máy quy trình,
thăm dò một hàng đợi người dùng hoặc hàng đợi hệ thống (cố gắng để tìm các hoạt động liên
quan đến một bước dòng công việc cụ thể), khóa các đối tượng được lấy ra, xử lý công việc (cập
nhật dữ liệu và v.v ) và quay ngược để thăm dò hàng đợi. Đại khái là, các trình diễn công việc
cần thiết để tương tác với các ứng dụng của bên thứ ba.
Có hai kiểu trình diễn công việc, dựa vào trình tích hợp thành phần và dựa trên trình tiện ích nền
sau (daemon). Trình diễn công việc dựa vào nhà tích hợp thành phần được dùng trong ví dụ này.
Các trình diễn công việc dựa vào nhà tích hợp thành phần là một thành phần được triển khai thực
hiện như một lớp Java hoặc sự kiện Java Messaging Service (JMS-Dịch vụ gửi thông báo Java).
Một thành phần Java có thể được sử dụng để thực hiện tất cả các hoạt động liên quan đến một
dòng công việc. Hình 1 minh họa kiến trúc của nhà tích hợp thành phần:
Hình 1. Kiến trúc Nhà tích hợp thành phần FileNet P8
Thành phần Java hoặc JMS có thể được nhà quản lý thành phần (component manager) quản lý.
Nhà quản lý thành phần cấu hình và giao tiếp với các bộ điều hợp dịch vụ. Trong thời gian chạy,
nhà quản lý thành phần thăm dò các hàng đợi thành phần về các mục công việc đòi hỏi JMS hoặc
xử lý bởi các thành phần Java và kết nối một mục công việc đang đòi hỏi một thành phần tới bộ
điều hợp dịch vụ thích hợp. Bộ điều hợp Java xử lý các cuộc gọi quy trình cho các đối tượng
Java, được biểu diễn đến máy quy trình như là các hoạt động trên các hàng đợi (các mục công
việc) ở nơi mỗi hoạt động được thực hiện bằng một phương thức của lớp Java. Bộ điều hợp Java
thực hiện ghép nối với thành phần Java, sau đó tự động chờ đáp ứng từ thành phần này, cập nhật
mục công việc và gửi mục công việc này đến bước dòng công việc tiếp theo. Bộ điều hợp JMS
đặt các thông báo vào Hàng đợi JMS (Queue JMS) và gửi đi mục công việc liên quan. Bộ điều
hợp JMS xử lý quy trình gửi lên các sự kiện tới một hàng đợi thông báo (dưới dạng một sự kiện
XML dựa trên phần tử bước cho hoạt động cụ thể).
Về đầu trang
Triển khai thực hiện các thực thể nghiệp vụ Java cho Công ty ABC
Công ty ABC muốn lưu trữ tất cả dữ liệu nội dung trong IBM Content Manager hiện có. Và nó
cũng muốn sử dụng FileNet BPM để xây dựng một ứng dụng tập trung quy trình. Vì vậy bạn cần
triển khai thực hiện các trình diễn công việc trong BPM để thao tác nội dung trong IBM Content
Manager hiện có.
Bạn có thể gói logic ứng dụng bên thứ ba và trưng ra giao diện đó khi triển khai thực hiện thành
phần Java. Với trường hợp của Công ty ABC, trước tiên bạn triển khai thực hiện các thực thể
nghiệp vụ Java có thể truy cập dữ liệu trong IBM Content Manager. Hình 2 cho thấy kiến trúc
của các thực thể nghiệp vụ Java :
Hình 2. Kiến trúc các thực thể nghiệp vụ Java
Như kiến trúc này cho thấy, bạn có thể tạo các đối tượng chuyển giao dữ liệu (DTO) và đối
tượng truy cập dữ liệu (DAO) phù hợp với mỗi lớp trong biểu đồ lớp (Phần 1; Hình 4). Khi lấy
lớp "AutoClaim" làm ví dụ, chúng ta đã tạo ra một lớp DTO AutoClaim.java và một lớp DAO
AutoClaimDAO.java.
Mã Java sau đây là AutoClaim.java. Nó bao gồm các định nghĩa đặc tính và các phương thức
getter và setter có liên quan. Nó biểu diễn giá trị dữ liệu cho một mục trong kho lưu trữ IBM
Content Manager.
Liệt kê 1. DTO mẫu - AutoClaim.java
public class AutoClaim
{
public AutoClaim ()
{
}
private String claimID;
public String getClaimID()
{
return this.claimID;
}
public void setClaimID(String claimID)
{
this.claimID = claimID;
}
private Integer claimStatus;
public Integer getClaimStatus()
{
return this.claimStatus;
}
public void setClaimStatus(Integer claimStatus)
{
this.claimStatus = claimStatus;
}
private String openingDate;
public String getOpeningDate()
{
return this.openingDate;
}
public void setOpeningDate(String openingDate)
{
this.openingDate = openingDate;
}
private Integer claimAmount;
public Integer getClaimAmount() {
return claimAmount;
}
public void setClaimAmount(Integer claimAmount) {
this.claimAmount = claimAmount;
}
private String eventID;
public String getEventID() {
return this.eventID;
}
public void setEventID(String eventID) {
this.eventID = eventID;
}
private String pidString;
public String getPidString() {
return pidString;
}
public void setPidString(String pidString) {
this.pidString = pidString;
}
}
Mã Java sau đây là AutoClaimDAO.java là một đối tượng truy cập dữ liệu. Nó chứa tất cả các
phương thức gọi OOAPI của IBM Content Manager để xử lý dữ liệu trong IBM Content
Manager.
Liệt kê 2. DAO mẫu - AutoClaimDAO.java
public class AutoClaimDAO
{
private String itemType;
public AutoClaimDAO()
{
itemType = "AutoClaim";
}
public String create(AutoClaim autoClaim) throws DKException,
Exception
{
String pidString = null;
DKDatastoreICM dsICM = SConnectDisconnectICM.connect();
DKDDO ddo = dsICM.createDDO("AutoClaim",
DKConstant.DK_CM_ITEM);
setAttrToDDO(ddo, autoClaim);
ddo.add();
pidString = ddo.getPidObject().pidString();
dsICM.disconnect();
return pidString;
}
public AutoClaim retrieveAutoClaimByClaimID(String claimID)
throws DKUsageError, DKException, Exception
{
AutoClaim autoClaim = null;
String queryString = "/AutoClaim[@Claim=\""+claimID+"\"]";
DKDatastoreICM dsICM = SConnectDisconnectICM.connect();
dkIterator dkIter =
(dkIterator) SConnectDisconnectICM.search(dsICM, queryString,
0, true);
if(dkIter.more())
{
autoClaim = new AutoClaim();
DKDDO ddo = (DKDDO)dkIter.next();
ddo.retrieve(DKConstant.DK_CM_CONTENT_ITEMTREE +
DKConstant.DK_CM_CONTENT_NO);
setValueToAutoClaim(ddo, autoClaim);
autoClaim.setPidString( ddo.getPidObject().pidString()
);
}
dsICM.disconnect();
return autoClaim;
}
public void update(String pidString, AutoClaim autoClaim)
throws DKUsageError, DKException, Exception
{
DKDatastoreICM dsICM = SConnectDisconnectICM.connect();
DKDDO ddo= dsICM.createDDO(pidString);
ddo.retrieve(DKConstant.DK_CM_CONTENT_ITEMTREE +
DKConstant.DK_CM_CONTENT_NO);
DKDatastoreExtICM ext = new DKDatastoreExtICM(dsICM);
if(!ext.isCheckedOut(ddo))
{
ext.checkOut(ddo);
}
setAttrToDDO(ddo, autoClaim);
dsICM.updateObject(ddo, DKConstant.DK_CM_CHECKIN);
dsICM.disconnect();
}
public void
delete(String pidString) throws DKUsageError, DKException,
Exception
{
DKDatastoreICM dsICM = SConnectDisconnectICM.connect();
DKDDO ddo = dsICM.createDDO(pidString);
ddo.del();
dsICM.disconnect();
}
public void setAttrToDDO(DKDDO ddo, AutoClaim autoClaim) throws
DKUsageError
{
if(autoClaim.getClaimID()!=null)
ddo.setData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,"ClaimID"),
autoClaim.getClaimID());
if(autoClaim.getClaimStatus()!=null)
ddo.setData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,"ClaimStatus"),
autoClaim.getClaimStatus());
if(autoClaim.getOpeningDate()!=null)
ddo.setData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,"OpeningDate"),
autoClaim.getOpeningDate());
if(autoClaim.getClaimAmount()!=null)
ddo.setData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,"ClaimAmount"),
autoClaim.getClaimAmount());
if( autoClaim.getEventID() != null )
ddo.setData( ddo.dataId( DKConstant.DK_CM_NAMESPACE_ATTR,
"EventID" ),
autoClaim.getEventID() );
}
public void setValueToAutoClaim(DKDDO ddo, AutoClaim autoClaim)
throws DKUsageError
{
Object attr = null;
attr = ddo.getData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,
"ClaimID"));
if(attr!=null)
{
autoClaim.setClaimID((String)attr);
attr = null;
}
attr = ddo.getData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,
"ClaimStatus"));
if(attr!=null)
{
autoClaim.setClaimStatus((Integer)attr);
attr = null;
}
attr = ddo.getData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,
"OpeningDate"));
if(attr!=null)
{
autoClaim.setOpeningDate((String)attr);
attr = null;
}
attr = ddo.getData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,
"ClaimAmount"));
if(attr!=null)
{
autoClaim.setClaimAmount((Integer)attr);
attr = null;
}
attr = ddo.getData(ddo.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,
"EventID"));
if(attr!=null)
{
autoClaim.setEventID( (String) attr );
attr = null;
}
}
}
Đối với các lớp khác trong biểu đồ lớp, có các lớp Java tương tự như AutoPolicy.java và
AutoPolicyDAO.java. Bạn có thể tải về dự án Eclipse có chứa tất cả mã nguồn của lớp Java
này.
Về đầu trang
Triển khai thực hiện lớp cổng cho các thực thể nghiệp vụ Java
Bây giờ bạn đã có một tập hợp các thực thể nghiệp vụ Java và cũng có rất nhiều phương thức
hoạt động trong các thực thể này. Nhưng trong phần FileNet Component Integrator (Nhà tích
hợp thành phần FileNet), một hàng đợi thành phần chỉ có thể trưng ra một phương thức của lớp
Java. Và bạn nên tuân theo các quy tắc sau đây:
Lớp phải có một hàm tạo không có bất kỳ tham số nào.
Các phương thức phải được công khai.
Các phương thức có thể chỉ chứa các kiểu tham số hoạt động thành phần cho phép. Hãy
tham chiếu các kiểu tham số hoạt động thành phần.
Nếu bạn muốn tương tác với nhiều lớp Java từ một ứng dụng của bên thứ ba và muốn đăng ký
chỉ có một hàng đợi thành phần cho ứng dụng này, thì bạn nên bọc tất cả các phương thức của
các lớp Java trong một lớp cổng (gateway). Vì thế với hệ thống Yêu cầu bồi thường bảo hiểm tự
động của Công ty ABC, bạn nên bọc tất cả các phương thức hoạt động DAO trong một lớp cổng
ICMOperation.java thể hiện trong mã Java sau.
Liệt kê 3. Lớp của trình bao bọc mẫu - ICMOperation.java
public class ICMOperation
{
public void createAutoClaim(String claimID,Integer claimStatus,
String openingDate,Integer claimAmount, String eventID) throws Exception
{
AutoClaim autoClaim = new AutoClaim();
autoClaim.setClaimID(claimID);
autoClaim.setClaimStatus(claimStatus);
autoClaim.setOpeningDate(openingDate);
autoClaim.setClaimAmount(claimAmount);
autoClaim.setEventID( eventID );
AutoClaimDAO dao = new AutoClaimDAO();
dao.create( autoClaim );
}
public Integer retrieveClaimStatusByClaimID(String claimID) throws
Exception
{
AutoClaim autoClaim = getAutoClaim( claimID );
return autoClaim.getClaimStatus();
}
public void updateClaimStatusByClaimID( String claimID, Integer
claimStatus )
throws Exception
{
AutoClaimDAO dao = new AutoClaimDAO();
AutoClaim autoClaim = dao.retrieveAutoClaimByClaimID( claimID );
autoClaim.setClaimStatus( claimStatus );
dao.update( autoClaim );
}
private AutoClaim getAutoClaim( String claimID ) throws Exception
{
return new AutoClaimDAO().retrieveAutoClaimByClaimID( claimID );
}
}
Về đầu trang
Một cách giải quyết sử dụng các tham số đối tượng Java khác trong Component Integrator
FileNet P8 Component Integrator (Nhà tích hợp thành phần FileNet P8) chỉ hỗ trợ một số kiểu
tham số nguyên thủy. Nhưng nói chung, một số đối tượng Java luôn được sử dụng như các tham
số trong một phương thức hoạt động. Ở đây, chúng ta đã giới thiệu một giải pháp để khắc phục
hạn chế này: sự tuần tự hóa Java. Hình 3 cho thấy giải pháp này.
Hình 3. Giải pháp tuần tự hóa Java
Khi sử dụng tuần tự hóa Java, bạn có thể tuần tự hóa đối tượng Java ban đầu thành một chuỗi
trong bộ nhớ. Khi bạn cần nhận đối tượng Java ban đầu, bạn có thể không tuần tự hóa chuỗi đó
thành đối tượng Java ban đầu. Hãy lấy AutoClaimDAO.java làm ví dụ. Nếu bạn muốn sử dụng
DTO AutoClaim.java làm tham số trong các phương thức hoạt động, bạn cần phải viết hai
phương thức tiện dụng. Một phương thức là để tuần tự hóa đối tượng Java AutoClaim thành một
chuỗi, trong khi phương thức kia là không tuần tự hóa chuỗi đó thành đối tượng Java AutoClaim
ban đầu. Các đoạn mã Java dưới đây cho thấy hai phương thức này.
Liệt kê 4. Mã mẫu về tuần tự hóa và không tuần tự hóa
public AutoClaim parseStringToAutoClaim( String autoClaimString )
throws IOException, ClassNotFoundException
{
ObjectInputStream objInput = null;
try
{
objInput = new ObjectInputStream( new ByteArrayInputStream(
new BASE64Decoder().decodeBuffer( autoClaimString ) ) );
return (AutoClaim) objInput.readObject();
}
finally
if( objInput != null )
{
objInput.close();
}
}
}
public String parseAutoClaimToString( AutoClaim autoClaim ) throws
IOException
{
ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
ObjectOutputStream objOutput = null;
try
{
objOutput = new ObjectOutputStream( byteOutput );
objOutput.writeObject( autoClaim );
return new BASE64Encoder().encode( byteOutput.toByteArray() );
}
finally
{
byteOutput.close();
if( objOutput != null )
{
objOutput.close();
}
}
}
Sau đó bạn nên làm cho AutoClaim có thể tuần tự hóa được. Điều cần thiết duy nhất là để cho
AutoClaim triển khai thực hiện giao diện java.io.Serializable. Mã sau đây cho thấy AutoClaim
có thể tuần tự hóa.
Liệt kê 5. Mã mẫu triển khai thực hiện tuần tự hóa
public class AutoClaim implements Serializable{
private static final long serialVersionUID = 4599855634813333505L;
}
Bây giờ bạn có thể đăng ký phương thức sử dụng chuỗi để biểu diễn đối tượng Java. Và trong
ứng dụng khách, bạn nên sử dụng phương thức không tuần tự hóa để nhận đối tượng Java ban
đầu. Hãy xem đoạn mã sau. Chúng ta sử dụng một phương thức trong lớp ICMOperation đã
đăng ký để lấy ra đối tượng Java AutoClaim. Sau khi có kết quả, đầu tiên sử dụng phương thức
tuần tự hóa để tuần tự hóa đối tượng Java AutoClaim thành một đối tượng chuỗi, sau đó trả về
chuỗi cho một máy khách. Một khi máy khách nhận được chuỗi đó, sử dụng phương thức không
tuần tự hóa để không tuần tự hóa chuỗi đó thành một đối tượng AutoClaim.
Liệt kê 6. Mã mẫu xem xét xung quanh sự hạn chế tham số
public String retrieveAutoClaimByClaimID( String claimID ) throws
Exception
{
AutoClaim autoClaim = getAutoClaim( claimID );
return new AutoClaimDAO().parseAutoClaimToString( autoClaim );
}
Bây giờ chúng ta có các thực thể nghiệp vụ Java và một lớp cổng Java trưng ra tất cả các phương
thức hoạt động. Bạn có thể tải về tất cả các mã nguồn trong một dự án Java của Eclipse. Lưu ý
rằng mức tuân thủ của trình biên dịch nên được đặt là 1.4 khi tạo các tệp jar tương ứng do sự
tương thích của nhà tích hợp thành phần.