60b5b7a27ba962aa522b10ba7df66cecb0f1d70f
[shibboleth/sp.git] / shibsp / remoting / ListenerService.h
1 /*
2  *  Copyright 2001-2009 Internet2
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * @file shibsp/remoting/ListenerService.h
19  *
20  * Interprocess remoting engine.
21  */
22
23 #ifndef __shibsp_listener_h__
24 #define __shibsp_listener_h__
25
26 #include <shibsp/remoting/ddf.h>
27 #include <map>
28
29 namespace shibsp {
30
31     /**
32      * Interface to a remoted service
33      *
34      * Classes that support remoted messages delivered by the Listener runtime
35      * support this interface and register themselves with the runtime to receive
36      * particular messages.
37      */
38     class SHIBSP_API Remoted
39     {
40         MAKE_NONCOPYABLE(Remoted);
41     protected:
42         Remoted();
43     public:
44         virtual ~Remoted();
45
46         /**
47          * Remoted classes implement this method to process incoming messages.
48          *
49          * @param in    incoming DDF message
50          * @param out   stream to write outgoing DDF message to
51          */
52         virtual void receive(DDF& in, std::ostream& out)=0;
53     };
54
55 #if defined (_MSC_VER)
56     #pragma warning( push )
57     #pragma warning( disable : 4250 4251 )
58 #endif
59
60     /**
61      * Interface to a remoting engine.
62      *
63      * A ListenerService supports the remoting of DDF objects, which are dynamic data trees
64      * that other class implementations can use to remote themselves by calling an
65      * out-of-process peer implementation with arbitrary data to carry out tasks
66      * on the implementation's behalf that require isolation from the dynamic process
67      * fluctuations that web servers are prone to. The ability to pass arbitrary data
68      * trees across the boundary allows arbitrary separation of duty between the
69      * in-process and out-of-process "halves". The ListenerService is responsible
70      * for marshalling and transmitting messages, as well as managing connections
71      * and communication errors.
72      */
73     class SHIBSP_API ListenerService : public virtual Remoted
74     {
75     protected:
76         ListenerService();
77     public:
78         virtual ~ListenerService();
79
80         /**
81          * Send a remoted message and return the response.
82          *
83          * @param in    input message to send
84          * @return      response from remote service
85          */
86         virtual DDF send(const DDF& in)=0;
87
88         void receive(DDF& in, std::ostream& out);
89
90         // Remoted classes register and unregister for messages using these methods.
91         // Registration returns any existing listeners, allowing message hooking.
92
93         /**
94          * Register for a message. Returns existing remote service, allowing message hooking.
95          *
96          * @param address   message address to register
97          * @param svc       pointer to remote service
98          * @return  previous service registered for message, if any
99          */
100         virtual Remoted* regListener(const char* address, Remoted* svc);
101
102         /**
103          * Unregisters service from an address, possibly restoring an original.
104          *
105          * @param address   message address to modify
106          * @param current   pointer to unregistering service
107          * @param restore   service to "restore" registration for
108          * @return  true iff the current service was still registered
109          */
110         virtual bool unregListener(const char* address, Remoted* current, Remoted* restore=NULL);
111
112         /**
113          * Returns current service registered at an address, if any.
114          *
115          * @param address message address to access
116          * @return  registered service, or NULL
117          */
118         virtual Remoted* lookup(const char* address) const;
119
120         /**
121          * OutOfProcess servers can implement server-side initialization that should occur
122          * before daemonization.
123          *
124          * <p>The parameter applies to implementations that can detect and remove
125          * the results of ungraceful shutdowns of previous executions and continue
126          * successfully. File-based sockets are the most common example.
127          *
128          * @param force     true iff remnant network state should be forcibly cleared
129          * @return true iff the service initialization was successful
130          */
131         virtual bool init(bool force);
132
133         /**
134          * OutOfProcess servers can implement server-side transport handling by
135          * calling the run method and supplying a flag to monitor for shutdown.
136          *
137          * @param shutdown  pointer to flag that caller will set when shutdown is required
138          * @return true iff the service execution was successful
139          */
140         virtual bool run(bool* shutdown)=0;
141
142         /**
143          * OutOfProcess servers can implement server-side termination/cleanup.
144          */
145         virtual void term();
146
147     private:
148         std::map<std::string,Remoted*> m_listenerMap;
149     };
150
151 #if defined (_MSC_VER)
152     #pragma warning( pop )
153 #endif
154
155     /**
156      * Registers ListenerService classes into the runtime.
157      */
158     void SHIBSP_API registerListenerServices();
159
160     /** Listener based on TCP socket remoting. */
161     #define TCP_LISTENER_SERVICE "TCPListener"
162
163     /** Listener based on UNIX domain socket remoting. */
164     #define UNIX_LISTENER_SERVICE "UnixListener"
165 };
166
167 #endif /* __shibsp_listener_h__ */