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