Merge "Copyright"
[packetcable.git] / packetcable-driver / src / main / java / org / pcmm / rcd / impl / AbstractPCMMServer.java
1 /**
2  @header@
3  */
4 package org.pcmm.rcd.impl;
5
6 import org.pcmm.PCMMConstants;
7 import org.pcmm.PCMMProperties;
8 import org.pcmm.concurrent.IWorkerPool;
9 import org.pcmm.concurrent.impl.WorkerPool;
10 import org.pcmm.messages.impl.MessageFactory;
11 import org.pcmm.rcd.IPCMMServer;
12 import org.pcmm.state.IState;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15 import org.umu.cops.stack.COPSHeader.OPCode;
16 import org.umu.cops.stack.COPSMsg;
17
18 import java.io.IOException;
19 import java.net.ServerSocket;
20 import java.net.Socket;
21 import java.util.concurrent.Executors;
22
23 // import org.junit.Assert;
24
25 /*
26  * (non-Javadoc)
27  *
28  * @see pcmm.rcd.IPCMMServer
29  */
30 public abstract class AbstractPCMMServer implements IPCMMServer {
31         protected Logger logger;
32         /*
33          * A ServerSocket to accept messages ( OPN requests)
34          */
35         private ServerSocket serverSocket;
36
37         private Socket stopSocket;
38
39         private volatile boolean keepAlive;
40         /*
41      *
42      */
43         private int port;
44
45         IWorkerPool pool;
46
47         protected AbstractPCMMServer() {
48                 this(PCMMProperties.get(PCMMConstants.PCMM_PORT, Integer.class));
49         }
50
51         protected AbstractPCMMServer(int port) {
52                 // XXX - Assert.assertTrue(port >= 0 && port <= 65535);
53                 this.port = port;
54                 keepAlive = true;
55                 logger = LoggerFactory.getLogger(getClass().getName());
56                 int poolSize = PCMMProperties.get(PCMMConstants.PS_POOL_SIZE, Integer.class);
57                 pool = new WorkerPool(poolSize);
58         }
59
60         /*
61          * (non-Javadoc)
62          * 
63          * @see pcmm.rcd.IPCMMServer#startServer()
64          */
65         public void startServer() {
66                 if (serverSocket != null)
67                         return;
68                 try {
69                         serverSocket = new ServerSocket(port);
70                         logger.info("Server started and listening on port :" + port);
71                 } catch (IOException e) {
72                         logger.error(e.getMessage());
73                 }
74                 // execute this in a single thread executor
75                 Executors.newSingleThreadExecutor().execute(new Runnable() {
76                         public void run() {
77                                 while (keepAlive) {
78                                         try {
79                                                 Socket socket = serverSocket.accept();
80                                                 logger.info("Accepted a new connection from :" + socket.getInetAddress().getHostAddress() + ":" + socket.getPort());
81                                                 if (keepAlive) {
82                                                         pool.schedule(getPCMMClientHandler(socket));
83                                                         logger.info("Handler attached tp : " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort());
84                                                 } else {
85                                                         logger.info("connection to be closed : " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort());
86                                                         socket.close();
87                                                 }
88                                         } catch (IOException e) {
89                                                 logger.error(e.getMessage());
90                                         }
91                                 }
92                                 try {
93                                         if (stopSocket != null && stopSocket.isConnected()) {
94                                                 logger.info("Cleaning up");
95                                                 stopSocket.close();
96                                         }
97                                         if (serverSocket != null && serverSocket.isBound()) {
98                                                 logger.info("Server about to stop");
99                                                 serverSocket.close();
100                                                 logger.info("Server stopped");
101                                         }
102                                 } catch (IOException e) {
103                                         logger.error(e.getMessage());
104                                 }
105                         }
106                 });
107         }
108
109         /**
110          * This client is used to handle requests from within the Application
111          * Manager
112          * 
113          * @param socket - the connection to the PCMM server
114          * @return client handler
115          */
116         protected abstract IPCMMClientHandler getPCMMClientHandler(Socket socket);
117
118         /*
119          * (non-Javadoc)
120          * 
121          * @see pcmm.rcd.IPCMMServer#stopServer()
122          */
123         public void stopServer() {
124                 // set to stop
125                 keepAlive = false;
126                 try {
127                         if (serverSocket != null) {
128                                 stopSocket = new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort());
129                                 logger.info("STOP socket created and attached");
130                         }
131                 } catch (Exception e) {
132                         logger.error(e.getMessage());
133                 }
134         }
135
136         /*
137          * (non-Javadoc)
138          * 
139          * @see pcmm.state.IStateful#recordState()
140          */
141         public void recordState() {
142
143         }
144
145         /*
146          * (non-Javadoc)
147          * 
148          * @see pcmm.state.IStateful#getRecoredState()
149          */
150         public IState getRecoredState() {
151                 return null;
152         }
153
154         /**
155          * @return the serverSocket
156          */
157         public ServerSocket getServerSocket() {
158                 return serverSocket;
159         }
160
161         /**
162          * @param serverSocket
163          *            the serverSocket to set
164          */
165         public void setServerSocket(ServerSocket serverSocket) {
166                 this.serverSocket = serverSocket;
167         }
168
169         /**
170          * @return the port
171          */
172         public int getPort() {
173                 return port;
174         }
175
176         /**
177          * @param port
178          *            the port to set
179          */
180         public void setPort(int port) {
181                 this.port = port;
182         }
183
184         /*
185          * (non-Javadoc)
186          * 
187          * @see pcmm.rcd.IPCMMServer.IPCMMClientHandler
188          */
189         public abstract class AbstractPCMMClientHandler extends AbstractPCMMClient
190                         implements IPCMMClientHandler {
191
192                 protected boolean sendCCMessage = false;
193
194                 public AbstractPCMMClientHandler(Socket socket) {
195                         super();
196                         setSocket(socket);
197                 }
198
199                 @Override
200                 public boolean disconnect() {
201                         // XXX send CC message
202                         sendCCMessage = true;
203                         /*
204                          * is this really needed ?
205                          */
206                         // if (getSocket() != null)
207                         // handlersPool.remove(getSocket());
208                         COPSMsg message = MessageFactory.getInstance().create(OPCode.CC);
209                         sendRequest(message);
210                         return super.disconnect();
211                 }
212
213         }
214
215 }