Title: Interceptor Morgan Deters CS562 Spring 2003 Wednesday, 29 Jan 2003
1InterceptorMorgan DetersCS562 Spring
2003Wednesday, 29 Jan 2003
Context
Interceptors
- With slide credits to
- Anand Krishnan
- Venkita Subramonian
- Morgan Deters
2Interceptor Questions
- Questions to consider
- What is an Interceptor?
- In which contexts is an Interceptor used?
- What problems do Interceptors solve, and how
- How might Interceptors in the large constitute
a development paradigm all their own? - Should Interceptor be a fundamental language
feature? - What relationships are there between the
Interceptor pattern and generic programming? - What are the relationships between Interceptor
and other similar patterns?
3Overview
The Interceptor architectural pattern allows
services to be added transparently to a framework
and triggered automatically when certain events
occur.
- Abstraction
- Genericity
- Conformity
- Extensibility
- Reusability
- Modularity
- Flexibility
4Motivation
- Simple client/server app
- add logging feature
- add security checks
- add encryption
- add QoS/prioritization
- Special-case or exceptional handling
- traffic overload
- administrator access
- Code becomes tangled and unmanageable
- Adding a new interception point is error-prone
int send_data(Buffer buf, size_t n) log(buf,
n) if(!check_security(buf, n) return 0
encrypt(buf, n) // etc... finally_actually_se
nd_data(buf, n) return 1
5Problem
- Fundamental problem
- How to integrate out-of-band tasks
- with in-band tasks?
- Straightforward approach
- Inline the out-of-band logic
- May be multiple places to inline it
- Fragile, difficult to modify, special-purpose
- Is there a more general approach?
6Example 1 Java event model
- public class Demo extends JApplet
- public void init()
- bHandler new ButtonHandler()
- button new JButton("Click Me")
- getContentPane().add(button,
- BorderLayout.CENTER)
- button.addActionListener(bHandle)
-
- public class ButtonHandler
- implements ActionListener
- void actionPerformed(ActionEvent e)
- // take appropriate action
-
-
Applet Framework
Button clicked
Action Listener
ActionEvent
Some action
7Example 2 Unix signals
OS Framework
- void catch_int(int sig_num)
- signal(SIGINT, catch_int)
- printf("Don't do that\n")
- fflush(stdout)
-
- int main(void)
- ...
- signal(SIGINT, catch_int)
- ...
-
Ctrl C
signal handler
Signal info
Some action
8Example 3 - Database Triggers
- CREATE TRIGGER print_salary_changes
- BEFORE UPDATE ON emp
- FOR EACH ROW
- WHEN (new.empno gt 0)
- DECLARE sal_diff number
- BEGIN
- sal_diff new.sal - old.sal
dbms_output.put('Old salary ' old.sal)
dbms_output.put(' New salary ' new.sal)
dbms_output.put(' Difference ' sal_diff) - END
- UPDATE emp
- SET sal sal 500.00 WHERE deptno 10
- Trigger will fire once for each row that is
- updated, and it prints the new and old
- salaries, and the difference.
Database Framework
Update Request
Before Update Trigger
After Update Trigger
Result
9Example 4 CORBA ORB
- In-band tasks
- Connection management with peer ORB
- Request/reply marshaling/demarshaling
- Demultiplexing requests to objects
- Out-of-band tasks
- Added at interceptor points
- Security, Fault Tolerance
ORB
ORB
Security Service
Fault Tolerance Service
10Solution
- Problem
- to find a general mechanism to integrate
- out-of-band tasks with in-band tasks
- Solution
- Out-of-band tasks
- register with framework via specific interfaces
- get triggered by framework on certain events
- are provided access to framework internals
(context) via specific interfaces
11UML Class Diagram
Application
Concrete Interceptor
Interceptor
12UML Class Diagram
Application
Concrete Interceptor
ltltimplementsgtgt
Interceptor
13UML Class Diagram
ltltregistergtgt
Application
Concrete Interceptor
ltltimplementsgtgt
Dispatcher
Interceptor
14UML Class Diagram
ltltregistergtgt
Application
event/trigger
Concrete Framework
Concrete Interceptor
ltltimplementsgtgt
Dispatcher
Interceptor
15UML Class Diagram
ltltregistergtgt
Context Object (CO)
Application
ltltinstantiatesgtgt
event/trigger
Concrete Framework
Concrete Interceptor
ltltimplementsgtgt
Dispatcher
Interceptor
16UML Class Diagram
ltltregistergtgt
Context Object (CO)
Application
ltltinstantiatesgtgt
event/trigger
Concrete Framework
Concrete Interceptor
ltltnotifygtgt
ltltimplementsgtgt
Dispatcher
Interceptor
17UML Class Diagram
ltltregistergtgt
Context Object (CO)
Application
ltltinstantiatesgtgt
event/trigger
Concrete Framework
Concrete Interceptor
ltltnotifygtgt
ltltimplementsgtgt
Dispatcher
Interceptor
1..
18UML Class Diagram
ltltregistergtgt
Context Object (CO)
Application
ltltinstantiatesgtgt
event/trigger
Concrete Framework
Concrete Interceptor
ltltnotifygtgt
ltltimplementsgtgt
Dispatcher
Interceptor
1..
19Implementation
- Model internal behavior of concrete framework
- Identify and model interception points
- Identify concrete framework state transitions
- Partition interception points into reader/writer
sets - Integrate them into state machine model
- Partition them into disjoint interception groups
- Specify the context object
- semantics
- number of context object types
- strategy for passing context objects to
interceptors - per-registration vs. per-event
20Implementation
- Specify the interceptors
- Specify the dispatchers
- interceptor registration interface
- dispatcher callback interface
- Implement call-back mechanisms in concrete
framework - Implement concrete interceptors
21Interceptor Themes
- Design arrogance
- Have you covered all the bases?
- Security
- influence of each Interceptor
- accessing secure internals
- Performance
- simplicity of model
- in-band vs. out-of-band
- Interceptor inter-dependence?
22Dynamic Interceptor
- Base Interceptor
- virtual apply_XXX()
- Concrete Interceptors
- Logging
- Checksum
- Statistics
- Encrypt
- security checks
- Future extensibility (design arrogance)
class Interceptor public virtual void
apply_encode(string) 0 virtual void
apply_decode(string) 0
23The Data_Endpoint class
- Abstraction for sending and receiving data
- Two Data_Endpoints connect then send
- send_data() and receive_data() both dispatch to
interceptors - add_interceptor() registers new concrete
interceptors
24Dynamic Interceptor
// A simple Interceptor Function class that
rot13's a message.class Rot13_Interceptor
public Interceptor class Rot13 public
unary_functionltchar, chargt public char
operator()(char c) if(islower(c)) return
c ((c gt 'a' 13) ? -13 13)
if(isupper(c)) return c ((c gt 'A' 13) ? -13
13) return c public void
apply_encode(string s) transform(s.begin(),
s.end(), s.begin(), Rot13()) void
apply_decode(string s) transform(s.begin(),
s.end(), s.begin(), Rot13())
25Dynamic Interceptor
class Data_Endpoint Data_Endpoint peer_
string data_ typedef vectorltInterceptorgt
Interceptor_List Interceptor_List
interceptors_ // public // void
send_data(const string s) // not mt-safe!
Encode_Dispatcher dispatch(s)
for_each(interceptors_.begin(),
interceptors_.end(), dispatch) string t
dispatch.get_result() peer_-gtdata_ t
cout ltlt "Data_Endpoint_at_" ltlt this ltlt " sent '"
ltlt t ltlt "' on the wire" ltlt endl
//
26Dynamic Interceptor
class Encode_Dispatcher public
unary_functionltInterceptor, voidgt string
s_public Encode_Dispatcher(string s) s_(s)
void operator()(Interceptor i)
i-gtapply_encode(s_) string get_result(void)
return s_
27Using Dynamic Interceptor
- Data_Endpoint foo Data_Endpoint bar
Print_Interceptor pf new Print_Interceptor
Rot13_Interceptor rot13 new Rot13_Interceptor
foo.add_interceptor(pf) foo.add_interceptor(
rot13) foo.add_interceptor(pf)
bar.add_interceptor(pf) bar.add_interceptor(rot
13) bar.add_interceptor(pf)
foo.connect(bar) foo.send_data(a string)
28Analysis of Dynamic Interceptor
- apply_XXX() design is fragile
- To add a new interception type
- add pure virtual apply_foo() to base
- implement in all existing concrete interceptors
- or refactor to have a single apply() with a
switch - May not need all of this flexibility
- may not need per-event context objects
- may not need to reorder or add interceptors at
runtime
29Static Interceptor
- No interceptor instances
- No context objects
- Data_Endpoint incompatibility
- Only one interceptor
- Cant checksum and encrypt
template ltclass Interceptorgt class Data_Endpoint
public send() ...
Interceptor(Send_Event()) ...
... class Logging_Interceptor public
void operator()(...) ...
30Addressing Problems
- Data_Endpoint incompatibility
- arises from instantiating the Data_Endpoint
template with different types - connect() and send() no longer work
- Solution
- template ltclass Other_Interceptorgt
- friend class Data_Endpoint
- Single Interceptor only
- use Typelists!
31Typelists
- List of types using templates
- No inherent runtime overhead
- Allows arbitrary number of Interceptors
template ltclass T, class Ugtstruct Typelist
typedef T Head typedef U Tail
TypelistltLogging_Interceptor,
TypelistltChecksum_Interceptor, NullTypegt gt
Andrei Alexandrescu, Modern C Design Generic
Programming and Design Patterns Applied
32More on Typelists
- Telescoping Typelist definitions awkward
- typelist.h defines
- Mechanism includes various algorithms
- Length, TypeAt (index), Append, Erase (type from
Typelist), Replace (type with type),
DerivedToFront - all for free evaluated at compile time!
define TYPELIST_1(T1) TypelistltT1,NullTypegt defi
ne TYPELIST_2(T1,T2) TypelistltT1,TYPELIST_1(T2)
gt define TYPELIST_3(T1,T2,T3) TypelistltT1,TYPELIS
T_2(T2,T3) gt ... up to TYPELIST_50(...)
33Static Interceptor contd
- With Typelists, can do efficient dispatch to
multiple Interceptors - Let compiler write special cases from our generic
templates - Apply chain of responsibility pattern
34Using Static Interceptor
- Data_EndpointltChain_Interceptorlt
- TYPELIST_3(Print_Interceptor,
- Rot13_Interceptor,
- Print_Interceptor)gt gt foo
- Data_EndpointltChain_Interceptorlt
- TYPELIST_1(Rot13_Interceptor)gt gt bar
- foo.connect(bar)
- foo.send_data(Hello world)
35Static Interceptor Analysis
- No runtime modification of Interceptors
- BUT efficient (inlined) dispatch
- Performance vs. Flexibility
- Because of template use, its compile-time
configurable and flexible - easy to change Interceptor attachment
- but must recompile
36More Static Interceptor Analysis
- Easy to write new Interceptor type
- Efficient
- Introduction of context objects and interceptor
instances ? - Sure, we still have fixed Interceptor lists
- Some loss of performance
37Interceptors within a Language
- Interception as a first-class concern
- Interception points are language gestures
- Variable mutation, method execution, object
instantiation, etc... - Concrete Framework need not be specially prepared
for extension - Aspect-Oriented Programming (AOP)
38Interceptors and AOP
- Join Points
- Language constructs
- execution/data, static/dynamic
- Correspond to interception points
- Aspect
- Collection of (possibly abstract) Interceptors
- Specifies the join points to operate on
- Attach advice to these join points, reflectively
consider its place in the system
39Language-Level InterceptorsExamples
- Component Configurator
- Infrequently-used features (e.g.,
backward-compatible protocol support) can be
loaded, unloaded without the application being
aware of it - Customization
- Quality of Service
- Fault-Tolerance
40Consequences
- Separation of Concerns
- (Future) Flexibility
- Reusability/Portability
- - Efficiency/Heterogenity
- - Evil Interceptors
41Interceptor Variants
- Bind Interceptor - Fault Tolerance
- Client Request Interceptor - Load Balancing
- Interceptor Proxy / Delegator - Customized
Service - Portable Interceptor
- Strategies
- Single Interceptor Per Dispatcher
- Interceptor Factory
- Implicit Interceptor Registration
- Component Configurator Pattern
- similar (partly) to AOP -- AOP languages can
differ - load from a library at runtime, Concrete
Framework creates the Interceptors
42Relationships to Other Patterns
- Chain of Responsibility (single handler)
- Observer/Publisher-Subscriber (notification)
- Template Method (localized interception)
- Interceptor reaches across multiple layers
- Pipes Filters
- Reflection
43Reading Assignment forMonday, 03 February
- Algorithms and Ranges Austern Chapter 2
- Optionally Chapters 11-13
- Why is it traditional to use open ranges?
- What is a concept? What is a model? How are the
two related? - In what contexts are the different types of
iterators useful? - Are modeling and refinement synonymous with
inheritance and polymorphism? Why or why not?
LAB 0 DUE FRIDAY 1159 PM