320 likes | 436 Views
Remote Pointcut - A Language Construct for Distributed AOP. Muga Nishizawa (Tokyo Tech, Japan) Shigeru Chiba (Tokyo Tech, Japan) Michiaki Tatsubori (TRL, Japan IBM). This Talk. Our goal To modularize crosscutting concerns in distributed software Motivating problem
E N D
Remote Pointcut- A Language Construct for Distributed AOP Muga Nishizawa (Tokyo Tech, Japan) Shigeru Chiba (Tokyo Tech, Japan) Michiaki Tatsubori (TRL, Japan IBM) AOSD'04, Lancaster, UK
This Talk • Our goal • To modularize crosscutting concerns in distributed software • Motivating problem • AspectJ can separate them • But, the implementation is NOT simple • E.g. a test code for distributed software • Our solution • Remote pointcut AOSD'04, Lancaster, UK
Test Code for Distributed Authentication Service • Confirm addUser() is executed on Database when client remotely calls registerUser() • Client calls registerUser(), registerUser() calls addUser() Authenticator Register a new user on a DB registerUser() Client Database addUser() AOSD'04, Lancaster, UK
Authenticator registerUser() Client Database addUser() 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. AOSD'04, Lancaster, UK
Test Code in Java • Crosscutting concern • Database code must be edited for test Authenticator Client Database class Database { void addUser() { invoke Callback … … add the user to the database } … … } • Flag = false • Call registerUser() • assert flag == true Crosscutting concern RMI (Remote Method Invocation) Callback Flag = true AOSD'04, Lancaster, UK
Test Code in Java and AspectJ Database • The concern is separated • Database code is not edited class Database { void addUser() { … … add the user to the database } } Client • Flag = false • Call registerUser() • Assert flag == true DatabaseTest aspect DatabaseTest { before(): execution(void addUser()){ invoke Callback } } Callback RMI Flag = true AOSD'04, Lancaster, UK
This Design is Not Satisfactory • When writing the test code, we must consider two concerns: • Test • Distribution • It requires to divide the code into three sub-modules • Network processing (RMI) and deployment Don’t consider this! 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 AOSD'04, Lancaster, UK
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 aspect Log { before() : execution(void addUser()) { System.out.println(“addUser”); } } Remote pointcut class Database { void addUser() { … … } } AOSD'04, Lancaster, UK
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 before(): cflow(call(void registerUser())) &&execution(void addUser()){ flag = true } call addUser() Database class Database { void addUser() { } … … } Remote Pointcut AOSD'04, Lancaster, UK
Test Code Implementation aspect AuthenticatorTest extends TestCase { boolean flag; 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; }} Declares and initializes the flag Calls registerUser() Confirms the flag is true When addUser() is executed, the flag is set to true AOSD'04, Lancaster, UK
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 AOSD'04, Lancaster, UK
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 AOSD'04, Lancaster, UK
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. } } AOSD'04, Lancaster, UK
Use of Remote Inter-type Declaration aspect AuthenticatorTest extends TestCase { void testRegisterUser() { String userId = "muga", password = "xxx"; Authenticator auth = (Authenticator) Naming.lookup("auth"); Database db = (Database) Naming.lookup(“db”); assertTrue(! 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. }} Confirms that the user entry AOSD'04, Lancaster, UK
Class Loader Class Loader Aspect Server DJcutter Implementation - Load-time Weaving Distributed software Aspect source file weave Runtime Infrastructure Compiler Java bytecode Distributed software deploy weave entry Runtime Infrastructure deploy Runtime Infrastructure AOSD'04, Lancaster, UK
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, … AOSD'04, Lancaster, UK
Related Work 2 • Other distributed AOP languages • E.g. D language framework JAC (Java Aspect Componenets) DADO • To modularize functional crosscutting concerns • DJcutter • Remote pointcut • To modularize non-functional crosscutting concerns AOSD'04, Lancaster, UK
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 AOSD'04, Lancaster, UK
The End • Thanks AOSD'04, Lancaster, UK
Even if writing RMI is very easy, • We still have a question: • Why the test code consists of three sub-modules? • Because of not test but distribution concern 1. flag = false. 2. call registerUser() on Authenticator. Design Problem 4. Assert flag == ture 3. if addUser() is invoked on Database, flag = true. AOSD'04, Lancaster, UK
DJcutter Implementation • Compiler • To generate a Java-bytecode representing an aspect • Runtime infrastructure • To implement load-time weaving • Aspect server • Extended class loader AOSD'04, Lancaster, UK
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 AOSD'04, Lancaster, UK
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”); } } class Database { void addUser() { System.out.println(“addUser”); … … } } Remote pointcut AOSD'04, Lancaster, UK
Three Distributed Sub-modules • Ideally, a concern should be described a non-distributed 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 AOSD'04, Lancaster, UK
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 Callback DatabaseTest Client DatabaseTest RMI Callback DatabaseTest AOSD'04, Lancaster, UK
Related Work AOSD'04, Lancaster, UK
Ideal Test Code • In the test code, we declare a flag for comfirming that addUser() was executed Test Program call registerUser() Authenticator Main part for testing call addUser() 1. Sets flag to false 2. Remotely calls registerUser() 3. Confirms that flag is ture Database class DbServer { void addUser() { … … } } Flag is set to true, when addUser() is executed AOSD'04, Lancaster, UK
実際に実装する 1.registerUser() 呼出 AuthServerTest AuthServer class AuthServerTest extends TestCase { boolean wasAddUserCalled; void testRegisterUser() { Naming.rebind("test", new RecieverImpl()); wasAddUserCalled = false; String userId = "muga", password = "xxx"; AuthServer auth = (AuthServer) Naming.lookup("auth"); auth.registerUser(userId, password); assertTrue(wasAddUserCalled); } class ReceiverImpl extends UnicastRemoteObject implements NotificationReceiver { void confirmCall() { wasAddUserCalled = true; } } interface NotificationReceiver { void confirmCall(); } 2.addUser() 呼出 DbServer interface NotificationReceiver { void confirmCall(); } aspect Notification { before(): execution(void DbServer.addUser()){ NotificationReceiver test = (NotificationReceiver) Naming.lookup("test"); test.confirmCall(); }} RMI AOSD'04, Lancaster, UK
Experimental Results AOSD'04, Lancaster, UK