Remote Pointcut - A Language Construct for Distributed AOP

Download Report

Transcript Remote Pointcut - A Language Construct for Distributed AOP

Remote Pointcut
- A Language Construct for Distributed AOP
To appear at AOSD’04
Muga Nishizawa (Tokyo Tech, Japan)
Shigeru Chiba (Tokyo Tech, Japan)
Michiaki Tatsubori (TRL, Japan IBM)
PPL 2004, Gamagori, AICHI
1
This Presentation
 Our goal
 To modularize crosscutting concerns in distributed
software
 This presentation
 Background
 AOP, crosscutting concern, AspectJ, …
 Motivating problem and example
 A test code for distributed software
 Our solution
 Remote pointcut
 SPA’04
PPL 2004, Gamagori, AICHI
2
AOP (Aspect-Oriented Programming)
 Separation of crosscutting concerns
 What is a crosscutting concern?
 The implementation of the concern cuts across
multiple modules
Crosscutting concerns
 Within confines of
existing technology
class Car {
 E.g. OOP
void start() {
System.out.println(“start”);
……
aspect Log {
}}
before():
class Bike {
execution(void Car.start())
exec
void start() {
|| execution(void Bike.start()) {
System.out.println(“start”);
exec
System.out.println(“start”);
……
PPL
2004,
Gamagori,
AICHI
3
}}
}}
AspectJ
- General-purpose AOP Language for Java
 Like event-driven model
 Pointcut
 To identify join points
 Join poin (event)
aspect Log {
before():
execution(void Car.start())
 Execution point in a program
|| execution(void Bike.start()) {
 E.g. method call, field access
System.out.println(“start”);
}}
 Advice (action)
 Code that should be execute at each
identified join point in pointcuts
 Before, after, and around
PPL 2004, Gamagori, AICHI
4
Motivating Problem
 Crosscutting concerns in distributed
software
 AspectJ can separate them
 But, the implementation is NOT simple
PPL 2004, Gamagori, AICHI
5
Test Code for
Distributed Authentication Service
 Confirm addUser() is executed on Database
 Client calls registerUser(),
registerUser() calls addUser()
Authenticator
Register a new
user on a DB
registerUser()
Client
Database
addUser()
PPL 2004, Gamagori, AICHI
6
Ideal Design for Test Code
 On Client,
 1. flag = false.
 2. call registerUser() on Authenticator.
 3. if addUser() is executed on Database,
then flag = true.
 4. assert flag == true.
Authenticator
registerUser()
Client
Database
PPL 2004, Gamagori, AICHI
addUser()
7
Test Code in Java
 Crosscutting concern
 Database code must be edited for test
Authenticator
Client
1. Flag = false
2. Call registerUser()
Database
Crosscutting
3. assert flag == true
RMI
Callback
(Remote Method Invocation)
Flag = true
PPL 2004, Gamagori, AICHI
class Database {
void addUser() {
concern
invoke Callback
……
add the user to the
database
}
……
}
8
Test Code in Java and AspectJ
 The concern is separated
 Database code is not edited
Database
class Database {
void addUser() {
……
add the user to the
database
Client
1. Flag = false
2. Call registerUser()
}
}
3. Assert flag == true
DatabaseTest
Callback
aspect DatabaseTest {
before():
execution(void addUser()){
invoke Callback
}
9
}
Flag = true
RMI
PPL 2004, Gamagori, AICHI
This Design is Not Satisfactory
 When writing the test code, we must consider
two concerns:
 Test
Don’t consider this!
 Distribution
 It requires to divide the code into three sub-modules
 Network processing (RMI) and deployment
1. flag = false.
2. call registerUser() on
Authenticator.
Three distributed sub-modules
3. if addUser() is invoked
on Database,
flag = true.
4. Assert flag == ture
PPL 2004, Gamagori, AICHI
10
Our Solution
- Remote Pointcut
 To identify join points in a program on
a remote host
 To run advice on a different host from the
host where join points are pointcut
 Like RMI for distributed OOP
Identified join point
Remote
aspect Log {
class Database {
pointcut
before() :
void addUser() {
execution(void addUser()) {
System.out.println(“addUser”);
……
}
}
}
PPL 2004, Gamagori, }AICHI
11
Test Code using a Remote Pointcut
 Test program is a single non-distributed
module
AuthenticatorTest
(Aspect)
Authenticator
call registerUser()
1. flag = false
2. call registerUser()
3. assert flag == true
call addUser()
Database
class Database {
void addUser() {
before():
Remote
cflow(call(void registerUser()))
Pointcut
}
&&execution(void addUser()){
……
flag = true
}
}
PPL 2004, Gamagori, AICHI
12
Test Code Implementation
aspect AuthenticatorTest extends TestCase {
boolean flag;
Declares and initializes
the flag
Calls registerUser()
Confirms the flag
is true
When addUser() is
executed, the flag is set
to true
void testRegisterUser() {
flag = false;
String userId = "muga", password = "xxx";
Authenticator auth
= (Authenticator) Naming.lookup("auth");
auth.registerUser(userId, password);
assertTrue(flag);
}
before(): // remote pointcut
cflow(call(void Authenticator.registerUser()))
&& execution(void Database.addUser()) {
flag = true;
}}
PPL 2004, Gamagori, AICHI
13
DJcutter
- Distributed AOP Language
 It’s an extension of AspectJ language
 Remote pointcut
 Remote inter-type declaration
 Load-time weaving
 Aspect weaving in DJcutter is performed at
load-time
PPL 2004, Gamagori, AICHI
14
DJcutter Language Specification
 Pointcut
 DJcutter provides pointcut designators in AspectJ
 Call, execution, within, target, …
 Hosts(Host, …)
 The join points in execution on the hosts
 Cflow(Pointcut)
 All join points that occur between the entry and exit of
each join point specified by Pointcut
 Advice
 Before, after, and around
PPL 2004, Gamagori, AICHI
15
Remote Inter-type Declaration
 To declare methods and fields in classes on
a remote host
AuthenticatorTest
Append at load-time
Database
boolean containsUser();
aspect AuthenticatorTest {
boolean Database.containsUser(String userId) {
// If the user entry specified by userId is found
// in the database.
}
}
PPL 2004, Gamagori, AICHI
16
Use of Remote Inter-type Declaration
aspect AuthenticatorTest extends TestCase {
Confirms that the user
entry
void testRegisterUser() {
String userId = "muga", password = "xxx";
Authenticator auth
= (Authenticator) Naming.lookup("auth");
Database db
= (Database) Naming.lookup(“db”);
assertFalse(!db.containsUser(userId);
auth.registerUser(userId, password);
assertTrue(db.containsUser(userId));
}
boolean Database.containsUser(String userId) {
// If the user entry specified by userId is
// found in the database.
}}
PPL 2004, Gamagori, AICHI
17
DJcutter Implementation
 Compiler
 To generate Java-bytecodes representing
aspects
 Runtime infrastructure
 To implement load-time weaving
PPL 2004, Gamagori, AICHI
18
Load-time Weaving
Distributed software
Aspect source file
weave
Class Loader
Runtime Infrastructure
Compiler
Java bytecode
deploy
Distributed software
weave
entry
Class Loader
Aspect Server
deploy
Runtime Infrastructure
Runtime Infrastructure
PPL 2004, Gamagori, AICHI
19
Related Work 1
 Middleware for automatic distribution
 E.g. J-Orchestra and Addistant
 They completely hide distribution
concern
 Conbination of AspectJ and them
 We are not sure they are good for
Tomcat, Oracle, …
PPL 2004, Gamagori, AICHI
20
Related Work 2
 Other distributed AOP languages
 E.g. D language framework
JAC (Java Aspect Componenets)
 To modularize functional crosscutting
concerns
 DJcutter
 Remote pointcut
 To modularize non-functional
crosscutting concerns
PPL 2004, Gamagori, AICHI
21
Conclusion
 Remote pointcut
 To transparently identify join points on remote
hosts
 Like RMI for distributed OOP
 To run advice on a different host from the host
where join points are pointcut
 Without consideration of distribution concern
 DJcutter – Distributed AOP Language
 Remote pointcut
 Extension of AspectJ language
PPL 2004, Gamagori, AICHI
22
The End
 Thanks
PPL 2004, Gamagori, AICHI
23
PPL 2004, Gamagori, AICHI
24
PPL 2004, Gamagori, AICHI
25
Even if writing RMI is very easy,
 We still have a question:
 Why the test code consists of three submodules?
 Because of not test but distribution concern
1. flag = false.
2. call registerUser() on
Authenticator.
4. Assert flag == ture
Design Problem
3. if addUser() is invoked
on Database,
flag = true.
PPL 2004, Gamagori, AICHI
26
DJcutter Implementation
 Compiler
 To generate a Java-bytecode representing an
aspect
 Runtime infrastructure
 To implement load-time weaving
 Aspect server
 Extended class loader
PPL 2004, Gamagori, AICHI
27
PPL 2004, Gamagori, AICHI
28
Our Solution
 To run advice on a different host from the
host where join points are pointcut
 Implementing a single module without
consideration of distribution
 That is, it can separate distribution concern
from the test code
 Non-distributed sub-modules,
 Automatic deployment,
 And separation of crosscutting concerns
PPL 2004, Gamagori, AICHI
29
Remote Pointcut
 To identify join points in a program flow on
remote host transparently
 Corresponding to RMI for distributed OOP
 Extends to pointcut designators in AspectJ
 A single non-distributed module on a single
host
Log
Database
aspect Log {
before() :
execution(void addUser()) {
System.out.println(“addUser”);
}
}
Remote
pointcut
class Database {
void addUser() {
System.out.println(“addUser”);
……
}
}
PPL 2004, Gamagori, AICHI
30
Three
Distributed
Sub-modules
 Ideally, a concern should be described a nondistributed single module
 We want to write without consideration of
distribution
 The test code is written with consideration of
distribution
 As a result, sub-modules, complicated network
processing, deployment
1. flag = false.
2. call registerUser() on
Authenticator.
3. if addUser() is invoked
on Database,
flag = true.
4. Assert flag == ture
PPL 2004, Gamagori, AICHI
31
Three Distributed Sub-modules
 Idealy, a concern should be described as a
non-distributed single module on a single
host
 この test code は、分散した sub-modules になっ
ている
 Separated, but far from the ideal test code
 Remote method invocation among sub-modules
 Deployment
Client
Client
Callback
DatabaseTest
Callback
DatabaseTest
DatabaseTest
RMI
PPL 2004, Gamagori, AICHI
32
Related Work
PPL 2004, Gamagori, AICHI
33
Ideal Test Code
 In the test code, we declare a flag for comfirming
that addUser() was executed
call registerUser()
Test Program
Main part for testing
call addUser()
1. Sets flag to false
2. Remotely calls
registerUser()
Database
Flag is set to true, when
addUser() is executed
3. Confirms that flag
is ture
Authenticator
PPL 2004, Gamagori, AICHI
class DbServer {
void addUser() {
……
}
}
34
実際に実装する
AuthServerTest
1.registerUser() 呼出
AuthServer
class AuthServerTest extends TestCase {
boolean wasAddUserCalled;
void testRegisterUser() {
Naming.rebind("test", new RecieverImpl());
2.addUser() 呼出
wasAddUserCalled = false;
String userId = "muga", password = "xxx";
DbServer
AuthServer auth
= (AuthServer) Naming.lookup("auth");
auth.registerUser(userId, password);
interface NotificationReceiver { void confirmCall(); }
aspect Notification {
assertTrue(wasAddUserCalled);
before():
}
class ReceiverImpl
execution(void DbServer.addUser()){
extends UnicastRemoteObject
NotificationReceiver test
implements NotificationReceiver {
= (NotificationReceiver)
void confirmCall() {
Naming.lookup("test");
wasAddUserCalled = true;
RMI
test.confirmCall();
}}
PPL
2004,
Gamagori,
AICHI
35
}}
interface NotificationReceiver { void confirmCall(); }
Experimental Results
PPL 2004, Gamagori, AICHI
36