3. CHƯƠNG 3: LẬP TRÌNH PHÂN TÁN VỚI CORBA
1.12. CORBA VÀ TRÌNH MÔI GIỚI ORB VISIBROKER
3.1.14. Giới thiệu
Trong các phần trên, để minh họa hoạt động của hệ phân tán theo mô CORBA, ta sử dụng trình môi giới trung gian ORB được nhúng sẵn trong bộ JDK. Tuy nhiên, do tính chất miễn phí nên ORB do SUN cài đặt không mang đầy đủ các chức năng cần thiết để phát triển một ứng dụng thật sự. Do đó, để xây dựng các chương trình ứng dụng, ta cần sử dụng trình môi giới trung gian của hãng thứ ba đầy đủ hơn. Trong phần này sẽ đề cập đến trình môi giới trung gian ORB VisiBroker nổi tiếng của hãng Inprise (Borland).
Inprise là hãng phát triển công cụ lập trình nổi tiếng với các sản phẩm như Borland C++, Pascal, Delphi, Jbuilder. Inprise luôn tìm ra cách tích hợp các ngôn ngữ lập trình với nhau. CORBA là một giải pháp khá hoàn hảo để Inprise thực hiện mong muốn của mình. VisiBroker là sản phẩm cho những nhà lập trình theo hướng CORBA. VisiBroker là trình môi giới trung gian ORB có khả năng giao tiếp được với hầu hết các đối tượng CORBA cài đặt bằng Java, C++, Delphi hay Pascal.Trong hầu hết các sản phẩm của Inprise khi cài đặt đều có VisiBroker kèm theo. Cho đến thời điểm này, VisiBroker đã được nhúng vào các sản phẩm của Oracle, cùng với sự chấp nhận của các hãng khác như IBM, Cisco Systems, HP…
3.1.15. Xây dựng ứng dụng CORBA minh họa sử dụng VisiBroker
Chương trình ví dụ sau đây minh họa giao dịch trong ngân hàng thông qua đối tượng CORBA. Đối tượng AccountManager dùng để quản lý và cấp phát Account cho khách hàng nào muốn mở tài khoản.
Xây dựng đối tượng chủ CORBA
Bước 1: Đặc tả đối tượng CORBA bằng ngôn ngữ IDL
//Bank.idl
interface Account { float balance();
interface AccountManager { Account open(in string name); };
Biên dịch tập tin Bank.idl sang Java như sau:
idlj2java Bank.idl
Chương trình idlj2java.exe do VisiBroker cung cấp, nó tương tự như trình idlj.exe trong bộ JDK mà ta đã dùng.
Kết quả ta thu được các tập tin sau:
Đối tượng Account:
Account.java AccountHelper.java AccountHolder.java AccountOperations.java AccountPOA.java AccountPOATie.java
Đối tượng AccountManager:
AccountManager.java AccountManagerHelper.java AccountManagerHolder.java AccountManagerOperations.java AccountPOAManager.java AccountManagerPOATie.java
Trong đó, <interface>_POATie.java là lớp trung gian đóng vai trò giao tiếp giữa đối tượng và ORB.
Để cài đặt cho đối tượng CORBA trong VisiBroker, ta kế thừa từ lớp <interfacename>POA như sau:
//AcountImpl.java
class AccountImpl extends Bank.AccountPOA { private float _balance;
public float balance() {return _balance; } }
Đối tượng Account của ta cung cấp phương thức balance() trả về số tài khoản của khách hàng. Account được tạo ra bởi phương thức open() của AccountManager như sau:
//AcountManagerImpl.java
import org.omg.PortableServer.*; import java.util.*;
class AccountManagerImpl extends Bank.AccountManagerPOA {
// Bảng chứa các tài khoản quản lý
private Dictionary _accounts = new Hashtable();
// Đối tượng tạo số ngẫu nhiên
private Random _random = new Random();
// Mở tài khoản cho khách hàng mang tên “name”
public Bank.Account open(String name) {
// Tìm xem tài khoản đã có trong danh sách hay chưa
Bank.Account account = (Bank.Account) _accounts.get(name);
// Nếu chưa thì tạo tài khoản mới
if(account == null) {
// Tạo số tiền ban đầu cho tài khoản
float balance = Math.abs(_random.nextInt()) % 100000;
// Tạo đối tượng tài khoản mới
AccountImpl accountServant = new AccountImpl(balance); try {
// Chuyển đối tượng về kiểu Account
account = Bank.AccountHelper.narrow(
_default_POA().servant_to_reference(accountServant)); }
catch (Exception e) { e.printStackTrace();}
System.out.println("Created " + name + "'s account: " + account);
// Lưu tài khoản vào danh sách
_accounts.put(name, account); }
} }
Chương trình Server dùng đăng ký đối tượng AccountManager với trình môi giới VisiBroker được thực hiện như sau:
//Server.java
import org.omg.PortableServer.*; class Server {
public static void main(String[] args) { try {
// Khởi tạo trình ORB
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
// Lấy về tham chiếu gốc của đối tượng ContextPOA
POA rootPOA =
POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
// Tạo chính sách quy định cách đối tượng hoạt động
org.omg.CORBA.Policy[] policies = {
rootPOA.create_lifespan_policy(LifespanPolicyValue.PERSISTENT) };
// Tạo đối tượng myPOA mới thêm vào đối tượng POA gốc
POA myPOA = rootPOA.create_POA
( "bank_agent_poa", rootPOA.the_POAManager(),policies );
// Tạo đối tượng phục vụ
AccountManagerImpl managerServant = new AccountManagerImpl();
// Chỉ định tên (id) cho đối tượng
byte[] managerId = "BankManager".getBytes();
// Kích hoạt đối tượng chứa trong POA
myPOA.activate_object_with_id(managerId, managerServant);
// Kích hoạt bộ quản lý POA
rootPOA.the_POAManager().activate(); System.out.println(
myPOA.servant_to_reference(managerServant) + " is ready.");
// Chờ yêu cầu gọi từ máy khách
}
catch (Exception e) {e.printStackTrace();} }
}
Xây dựng trình khách:
//Client.java
class Client {
public static void main(String[] args) {
// khởi động trình mối giới trung gian ORB
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
// Định tên của đối tượng CORBA cần gọi
byte[] managerId = "BankManager".getBytes();
// Truy tìm tham chiếu của đối tượng
Bank.AccountManager manager = Bank.AccountManagerHelper.bind (orb, "/bank_agent_poa", managerId);
// Sử dụng đối số args[0] làm tên tài khoản
String name = args[0] ;
// Yêu cầu đối tượng AccountManager mở tài khoản
Bank.Account account = manager.open(name);
// Lấy về số dư tài khoản
float balance = account.balance();
// In kết quả
System.out.println ("The balance in " + name + "s account is $" + balance); }
}
3.1.16. Biên dịch và triệu gọi đối tượng CORBA trong VisiBroker
VisiBroker sử dụng trình vbjc.exe để biên dịch và vbj.exe để thực thi chương trình. Thực ra cả hai chương trình vbjc và vbj đều gọi đến javac.exe và java.exe.
Biên dịch mã nguồn:
E:\Luanvan\EXAM\CORBA\BankApp>vbjc *.java
E:\Luanvan\EXAM\CORBA\BankApp>osagent.exe
Trình osagent chịu trách nhiệm quản lý tên đăng ký của đối tượng CORBA. Chạy trình chủ:
E:\Luanvan\EXAM\CORBA\BankApp>vbj Server
Chạy trình khách:
E:\Luanvan\EXAM\CORBA\BankApp>vbj Client
Kết quả:
The balance in Jack’s account is $892.23
3.1.17. Các đặc tả mới của CORBA và VisiBroker:
CORBA trong đặc tả mới nhất muốn xây dựng mô hình khả chuyển (portable) cho các đối tượng bằng khái niệm POA (Portable Object Adapter). POA là lớp chịu trách nhiệm quản lý và kích hoạt các đối tượng theo yêu cầu của trình khách. ORB cung cấp rất nhiều lớp POA. Tất cả các lớp POA con đều phải được tạo ra từ POA gốc (gọi là Root POA). Mỗi POA chứa một bảng danh sách (Active Object Map) cho biết đối tượng nào đang trong trạng thái phục vụ (đã được kích hoạt). Đối tượng được POA quản lý theo định danh ID chứa trong danh sách kích hoạt.
Hình 3.5-15: Cơ chế quản lý đối tượng của CORBA theo đặc tả mới
Khi trình khách yêu cầu triệu gọi một đối tượng từ POA, lớp POA kiểm tra xem định danh ID của đối tượng cần gọi đã có trong bản kích hoạt hay chưa. Nếu đã có, POA sẽ trả về tham chiếu của đối tượng để trình khách triệu gọi. Nếu chưa có, POA sẽ yêu cầu bộ quản lý đối tượng (Servant Manager) kiến tạo đối tượng và đưa đối tượng vào bảng kích hoạt (Active Object Map) để POA quản lý
• Đăng ký phía máy chủ:
Trình tự của quá trình đăng ký đối tượng AccountManager ở ví dụ Setup.java trên diễn ra như sau:
- Khai báo thư viện PortableServer để sử dụng các lời gọi đến POA: import org.omg.PortableServer.*;
- Lấy về tham chiếu đến POA gốc (RootPOA). Điều này tương tự như việc lấy về context gốc trong dịch vụ tnameserv:
POA rootPOA =
POAHelper.narrow(orb.resolve_initial_references(“RootPOA”));
- Ta có thể dùng POA gốc để quản lý các AccountManager tạo ra và cũng có thể tạo ra POA con khác. POA con mang tên bank_agent_poa được tạo ra
POA myPOA = rootPOA.create_POA(
“bank_agent_poa”,rootPOA.the_POAManager(),policies);
Mỗi POA cần một chính sách (policy) để hoạt động như là thời gian cho phép đối tượng hoạt động, cách kích hoạt đối tượng. Chính sách này tạo ra như sau:
org.omg.CORBA.Policy []policies = {
rootPOA.create_lifespan_policy(LifespanPolicyValue.PERSISTENT)}; - Đối tượng AccountManager của ta được tạo ra và đưa vào trạng thái kích
hoạt trong POA như sau:
//Tạo đối tượng phục vụ servant
AccountManagerImpl managerServant = new AccountManagerImpl();
// Chỉ định tên (id) cho đối tượng
byte []managerID = “BankManager”.getBytes();
// Kích hoạt đối tượng chứa trong POA
myPOA.active_object_with_id (managerId, managerServant);
Khi ta kích hoạt một đối tượng trong POA, nó chưa thật sự hoạt động. Muốn đối tượng có thể triệu gọi được từ xa bởi trình khách ta cần kích hoạt POA chứa đối tượng như sau:
rootPOA.the_POAManager().activate();
- Bước cuối cùng là yêu cầu ORB lắng nghe lời triệu gọi từ phía máy khách:
orb.run();
• Gọi đối tượng trên máy chủ từ máy khách:
Đầu tiên, ta khởi động trình môi giới ORB:
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init (args,null);
tiếp đến là lấy các lớp trợ giúp do idl2java sinh ra và nhận về tham chiếu của đối tượng chủ như sau:
// Định tên của đối tượng CORBA cần gọi
byte[] managerId = "BankManager".getBytes();
// Truy tìm tham chiếu của đối tượng
AccountManager manager = AccountManagerHelper.bind
PHẦN II:
XÂY DỰNG CHƯƠNG TRÌNH ỨNG DỤNG