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