3.3.1. Aglet
ASDK cung cấp một kiến trúc được cấu trúc rõ ràng và khả mở để lập trình các aglet với tập API dễ sử dụng. Mỗi aglet là một đối tượng Java di động có thể di trú giữa các trạm cho phép. Mỗi aglet chạy trong luồng thi hành của riêng nó và có khả năng đáp ứng lại các thông điệp gửi tới.
Mỗi aglet được hệ thống gán cho một ID duy nhất, chúng cũng chứa các thông tin như OwnerID, thời điểm được tạo, tên lớp, code base và phiên bản.
Proxy là đối tượng đại diện cho mỗi aglet, nó giúp che chắn bảo vệ các aglet khỏi sự truy nhập trực tiếp tới các phương thức công cộng của chúng.
Mỗi aglet chỉ có thể truy nhập qua proxy tương ứng của nó, nói cách khác, đối tượng proxy cung cấp sự định vị trong suốt cho các đối tượng.
Aglet context là vùng làm việc của các aglet. Aglet context là một đối tượng tĩnh, cung cấp một môi trường thi hành giống nhau cho các aglet. Aglet context cho phép duy trì và quản lý các aglet đang chạy và bảo vệ hệ thống host khỏi các aglet hiểm độc. Lưu ý là trên một máy chỉ có thể có nhiều ngữ cảnh.
Engine Context Aglets Host Resource Hình 3.3: Các Aglet agent Host Context proxy Aglet AgletID Client interaction
3.3.2. Khả năng di động của các aglet
Do ASDK được thực hiện bằng Java, việc tuần tự hóa ngăn xếp thi hành không hỗ trợ. Bởi vậy, điểm vào cố định được định nghĩa cho mỗi lớp aglet, điểm vào này sẽ được gọi tại mỗi điểm đến. Hạn chế này yêu cầu trạng thái thi hành hiện tại của tác vụ aglet phải được tự lưu trữ trong một cấu trúc dữ liệu có thể tuần tự hóa. Với dữ liệu đó, aglet có thể khôi phục trạng thái thi hành sau khi di trú. ASDK sử dụng Java-Object-Serialization của JDK để marshal và unmarshal các đối tượng Java.
Các aglet có thể di trú tới một ngữ cảnh khác bằng cách gọi phương thức dispatch với đối số là URL của trạm ở xa. Aglet và các đối tượng dữ liệu của nó sẽ được tuần tự hóa. Ở điểm đến, các lớp cần thiết để xây dựng tác tử trong ngữ cảnh mới sẽ được tải bởi trình tải class (Class Loader) từ code base đã cho. Hiện tại, các đối tượng proxy không lưu vết của các aglet di trú. Khi một aglet được gửi đi, các đối tượng proxy tham chiếu tới nó sẽ không còn hợp lệ. Trong tương lai, có thể Aglet Framework sẽ phát triển một cơ chế để bảo quản tham chiếu tới các aglet đang di chuyển. Một đối tượng proxy đã di trú vẫn còn hợp lệ.
Aglet có thể di trú theo ý định của nó, hoặc bị buộc di trú bởi aglet khác, bởi người dùng qua GUI ( giao diện người dùng đồ họa) và bởi hệ thống agent. Nó cũng có thể được triệu hồi về bằng cách sử dụng phương thức retrac từ GUI. Ngoài ra, ASDK còn cung cấp lớp – hành trình mà ta có thể được sử dụng để
Host State Bytecode Host Host State Bytecode Host Host Receiving Host Sending Supend Excution Serialize Agent Encode Data Transfer Data Resume Excution Deserialize Agent Decode Data Receive Data NETWORK
xác định các kế hoạch di chuyển phức tạp cho aglet. ASDK không phân biệt các tác tử tĩnh và di động.
3.3.3. Vòng đời của Aglet
Lớp com.ibm.Aglet cung cấp các chức năng cơ bản cho một đối tượng Mobile và mọi aglet phải là thể hiện hoặc lớp con của nó. Để dùng một aglet, trước hết phải tạo ra thể hiện của nó [4],[6]:
+ Tạo một aglet hoàn toàn mới từ định nghĩa lớp bằng cách gọi hàm AgletContext.createAglet. Hàm này tạo ra một thể hiện mới trong context và khởi động nếu cần thiết.
+ Tạo ra một bản sao cửa một aglet đã tồn tại bằng cách dùng hàm Aglet.clone(). Aglet được sao ra sẽ có cùng trạng thái như aglet gốc nhưng có AgletID khác.
Các kịch bản khác nhau trong quá trình hoạt động của một aglet có thể được mô tả như trong hình sau:
Các aglet có thể: Tạo lập (create), nhân bản (clone), gửi đi (dispatch), triệu hồi (retract), dừng kích hoạt (deactivate), kích hoạt (activate) và hủy bỏ (dispose).
+ Create: tạo một aglet trong một ngữ cảnh. Aglet được ấn định ID, được khởi tạo và thi hành.
+ Clone: tạo một bản sao của aglet trong cùng một ngữ cảnh, aglet mới có ID khác và cũng có luồng thi hành khác.
+ Dispatch: aglet di chuyển từ ngữ cảnh hiện tại tới một ngữ cảnh khác, tại đó, sự thi hành được bắt đầu lại.
Aglet Context A Clone Create Class Context B Dispatch Deactive Secondary Storage Active Dispose Retract Aglet
+ Retract: aglet được rút khỏi ngữ cảnh hiện tại và đưa vào ngữ cảnh đã yêu cầu retract.
+ Active: aglet tạm thời dừng thi hành và được lưu vào bộ nhớ thứ cấp. + Deactive: aglet được tải từ bộ nhớ thứ cấp và tiếp tục thi hành khi tái kích hoạt.
+ Dispose: dừng thi hành và loại bỏ khỏi ngữ cảnh.
3.3.4. Liên lạc giữa các aglet
Các aglet giao tiếp với nhau bằng cách gửi các thông điệp. Điều này cho phép giao tiếp động với tất cả các aglet đã biết và chưa biết. Sự liên lạc dựa trên một lược đồ gọi lại đơn giản, yêu cầu mỗi aglet thực hiện những trình quản lý cần thiết cho mỗi loại thông điệp.
Các thông điệp được gửi bằng cách gọi phương thức gửi thông điệp trên đối tượng proxy. Các đối tượng proxy giúp aglet trong suốt về vị trí với một hạn chế: các đối tượng proxy của các aglet đang di chuyển không hợp lệ. Về mặt liên lạc, aglet nhận thông điệp hiện ở trạm cục bộ hay ở xa không có sự khác biệt. Không đòi hỏi phải sinh ra các lớp proxy, bởi vì tất cả các aglet phải thực hiện cùng trình quản lý thông điệp.
Các thông điệp có thể chứa các đối số là kiểu Java bất kỳ, miễn là kiểu đó thi hành lớp Java.io.Serializable. Các thông điệp nguyên tử (atomic-message) có thể được tạo bằng cách sử dụng các contructor đã thiết kế. Các thông điệp non- atomic với nhiều đối số được kiểm soát như một danh sách các cặp khóa và giá trị. Một thông điệp từ xa không dẫn đến việc truyền bytecode. Một điểm cần chú ý là: các lớp sử dụng trong thông điệp phải được cài đặt sẵn trên cả hai trạm.
ASDK hỗ trợ các loại thông điệp đồng bộ, không đồng bộ và thông điệp quảng bá. Với thông điệp không đồng bộ một tham chiếu đối tượng sẽ được trả về và có thể sử dụng nó để kiểm tra các thông điệp phản hồi. Các thông điệp quảng bá có thể gửi tới tất cả các aglet nằm trong một ngữ cảnh cục bộ đã đăng ký kiểm soát loại thông điệp đó.
Mọi thông điệp đến được lưu trữ trong hàng đợi và sau đó chúng sẽ được xử lý tuần tự từng thông điệp một. Việc này tuần tự hóa việc kiểm soát thông điệp và bảo đảm rằng quá trình xử lý thông điệp hiện thời đã kết thúc trước khi trình xử lý thông điệp của aglet được gọi lần nữa. Quá trình này có thể tuỳ biến để cho phép việc xử lý thông điệp dựa trên mức ưu tiên phụ thuộc vào kiểu của chúng và với các thông điệp đồng bộ với trạng thái của aglet. ASDK cũng định nghĩa sẵn các phương thức được gọi cho một số sự kiện chính (ví dụ khi được tạo, khi nhân bản, khi tới đích đến). Các phương thức này có thể được chồng lấp
bởi lập trình viên Aglets nhằm phản ứng với các sự kiện đặc biệt. Tuy nhiên, việc chuyển tiếp thông điệp và các giao diện triệu hồi động không được hỗ trợ.
ASDK cung cấp một dịch vụ thư mục đơn giản cho các aglet, gồm một danh sách các trạm Aglets có thể được nhận cho ngữ cảnh hiện tại. Do các đối tượng proxy không hợp lệ sau khi aglet mà nó tham chiếu di trú, rất khó để theo vết của các aglet đang di chuyển và thiết lập một kết nối tới aglet ở xa với GUID không rõ (Globally Unique Identifier). Việc tạo các đối tượng proxy cần có URL của trạm Aglets và GUID của các đối tượng.
3.4. Các mẫu thiết kế
Các mẫu thiết kế trong lập trình hướng đối tượng cung cấp một phương pháp cơ bản để dùng lại mã giữa các lớp. Với các mẫu thiết kế, việc thiết kế và thực hiện các aglet được đơn giản hóa vì nhà phát triển chỉ phải thực hiện các biến thể của các mẫu thiết kế định nghĩa trước.
ASDK cung cấp hai mẫu thiết kế cơ bản là mẫu Master-Slave và mẫu Itinerary [12].
3.4.1. Mẫu thiết kế Master-Slave.Định nghĩa Định nghĩa
Mẫu thiết kế Master-Slave định nghĩa một master-aglet có khả năng giao phó một công việc cho một Slave-aglet.
Mục đích thiết kế
Có một số lý do để một master-aglet muốn tạo các Slave-aglet khác và giao phó công việc cho chúng.
- Hiệu năng: master-aglet có thể tiếp tục thực hiện những công việc khác song song với Slave-aglet.
- Lý do thứ hai có thể được mô tả qua ví dụ sau: giả sử một ứng dụng nền- aglet cung cấp một giao diện đồ họa người dùng (GUI) để nhận dữ liệu đầu vào và hiển thị các kết quả trung gian của một công việc cụ thể được thực hiện ở xa. Nếu một aglet đơn lẻ vừa cung cấp GUI và thực hiện công việc đó, thì không thể duy trì GUI khi aglet di chuyển từ vị trí gốc tới một điểm đến ở xa. Thay vào đó, master-aglet tĩnh có thể cung cấp và duy trì GUI trong khi slave-aglet di chuyển tới một điểm đến khác, thực hiện công việc được giao và truyền kết quả công việc về master-aglet để hiển thị cho người dùng.
Mẫu thiết kế Master-Slave được xây dựng dựa trên ý tưởng là sử dụng một lớp trừu tượng, cần cục bộ hóa các phần của việc giao phó cho một công việc giữa master và slave-aglet: gửi một Slave tới một điểm đến ở xa, khởi tạo
Các aglet cụ thể được định nghĩa như các lớp con, chỉ có các phần cụ thể như công việc cần thực hiện cần phải được thi hành.
Trong thực tế, master-aglet định nghĩa một trình kiểm soát thông điệp quan tâm đến kết quả các công việc và có lớp hai phương thức trừu tượng initializeTask và doTask, định nghĩa các bước khởi tạo và thực hiện trước khi aglet di chuyển tới một điểm đến mới và công việc cụ thể.
Áp dụng
Mẫu thiết kế Master-Slave có thể được dùng trong các trường hợp:
+ Khi một aglet cần thực hiện một tác vụ song song với các tác vụ khác mà nó chịu trách nhiệm.
+ Khi một aglet tĩnh muốn thực hiện một tác vụ tại một điểm đích ở xa. Trong cả hai trường hợp các tác vụ chỉ được thực hiện tại một điểm đích duy nhất.
Các đối tượng tham gia:
Có ba đối tượng tham gia trong mẫu thiết kế Master-Slave:
1) Slave định nghĩa bộ khung của một slave, sử dụng các phương thức trừu tượng (InitializeTask và Task), sẽ được overridden trong lớp ConcreteSlave.
2) ConcreteSlave thực hiện hai phương thức trừu tượng của lớp.
3) Master thực hiện aglet sẽ tạo ra slave-aglet và nhận thông điệp kết quả của các slave.
Sự cộng tác:
Sự cộng tác giữa các đối tượng trong mẫu thiết kế Master-Slave: 1) Master-aglet tạo một slave-aglet.
2) Slave-aglet khởi tạo tác vụ của nó. Slave Abstract initializeTask() Abstract doTask() Master initializeTask() doTask() ConcreteSlave createAglet sendMessage()- Result initializeTask(){ } doTask(){ }
3) Slave-aglet di chuyển tới trạm ở xa và thực hiện tác vụ của nó. 4) Slave-aglet gửi kết quả thực hiện công việc về cho master-aglet. 5) Slave-aglet tự hủy nó.
Đánh giá:
Khuyết điểm của mẫu thiết kế nền tảng kế thừa là hành vi của slave-aglet bị cố định ngay ở thời điểm thiết kế. Ví dụ, một aglet không thể được biến thành một salve-aglet trong thời gian chạy, cũng không thể dễ dàng ấn định cho nó thực hiện công việc mới. Một phiên bản phức tạp hơn của mẫu thiết kế này là sử dụng một mô hình nền-ủy thác, trong đó công việc được đối tượng hóa và có thể ấn định đối tượng công việc bất kỳ cho một slave-aglet trong thời gian chạy.
3.4.2. Mẫu thiết kế Itinerary[12]
Định nghĩa
Mẫu thiết kế Itinerary hướng tới hành trình của aglet và sự định hướng giữa các điểm đến.
Mục đích
Trở thành một thực thể di động tự trị, một aglet nền – hành trình có thể định hướng độc lập tới nhiều trạm. Đặc biệt, nó cần có khả năng kiểm soát các ngoại lệ (ví dụ như các trạm chưa biết khi thực hiện gửi nó tới các điểm đến mới). Chẳng hạn, nó có thể tự gửi nó đến dịch vụ niên giám các trang vàng, lấy thông tin liên quan đến điểm đến và đặt chúng vào lộ trình của mình.
initializeTask() dispatch() doTask() dispose() sendMessage()-Result aMaster on Host A aSlave on Host A aSlave on Host B
Mẫu thiết kế được xây dựng dựa trên ý tưởng là chuyển trách nhiệm di chuyển từ aglet cho đối tượng hành trình liên hợp với nó. Lớp hành trình cung cấp một giao diện để bảo quản hay sửa đổi lộ trình của aglet và để gửi aglet tới các điểm đến mới. Một đối tượng aglet và một đối tượng lộ trình sẽ được kết nối như sau:
1) Aglet tạo một đối tượng hành trình và khởi tạo nó với một danh sách đích đến để viếng thăm lần lượt và một tham chiếu tới aglet.
2) Aglet sử dụng phương thứcgo() để tự gửi nó tới điểm đến kế tiếp trong hành trình của mình. Để hỗ trợ điều này, đối tượng hành trình cần được chuyển đi cùng với aglet.
Áp dụng
Sử dụng mẫu thiết kế này khi chúng ta cần:
Ẩn đi các chi tiết của kế hoạch di chuyển cho aglet đối với hành vi của nó nhằm phát triển tính mô-đun của cả hai phần.
Cung cấp một giao diện thống nhất cho việc di chuyển các aglet
Định nghĩa các kế hoạch di chuyển có thể dùng lại và chia sẻ bởi các aglet.
Các lớp đối tượng tham gia
Hình sau thể hiện các liên hệ cấu trúc giữa các đối tượng tham gia mẫu Itinerary.
1) Itinerary định nghĩa bộ khung của một hành trình, với hai phương thức trừu tượng:go() vàhasMoreDestinations().
2) ConcreteItinerary thực hiện các phương thức trừu tượng của lớp Itinerary và lưu vết của điểm đến hiện tại của aglet.
3) Aglet là lớp Aglet cơ sở. ConcreteItinerary URL origin AgletProxy aglet go() hasMoreDest() ConcreteItinerary go(){ } hasMoreDest(){ }
Hình 3.9: Các đối tượng trong mẫu Itinerary Aglet
abstract go()
Sự cộng tác
Hình vẽ 3.10 mô tả sự cộng tác tương ứng với mẫu Itinerary 1) Đối tượng ConcreteItinerary được khởi tạo bởi một aglet.
2) Đối tượng gửi aglet tới điểm đến đầu tiên
3) Khi aglet thực hiện phương thức go của hành trình, aglet được gửi tới điểm đến kế tiếp.
3.4.3. Kết hợp hai mẫu thiết kế
Trên đây ta mới chỉ mô tả các slave có một kế hoạch di chuyển đơn mà đích đến đơn giản. Slave-aglet gửi tới một trạm ở xa, thực hiện công việc của nó và trả về kết quả. Ta có thể kết hợp mẫu thiết kế Itinerary và mẫu Master-Slave. Kết quả sẽ là một slave-aglet di chuyển theo một hành trình, viếng thăm nhiều trạm và thực hiện công việc của mình tại mỗi trạm. Hình vẽ sau trình bày một biểu đồ cho master-aglet và intinerary-slave-aglet của nó.
go() go() dispatch(‘D’) go() Init(Aglet) anItinerary anAglet on Host D
Hình 3.10: Sự cộng tác trong mẫu Itinerary dispatch(‘C’) dispatch(‘B’) anAglet on Host A anAglet on Host B anAglet on Host C
3.5. Các tính năng an ninh
Phần này trình bày sơ lược những cơ chế an ninh có sẵn trong Aglets framework.
3.5.1. An ninh trên nền tảng Java
ASDK cung cấp một trình quản lý an ninh aglet, dựa trên trình quản lý an ninh của Java. Trình quản lý an ninh aglet điều khiển truy nhập của aglet tới các phương thức quan trọng và có thể được sử dụng để thi hành các chính sách an ninh riêng.
Mỗi aglet chứa thông tin về định danh của nó và người sở hữu, nhưng