4 package org.pcmm.rcd.impl;
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;
18 import java.io.IOException;
19 import java.net.ServerSocket;
20 import java.net.Socket;
21 import java.util.concurrent.Executors;
23 // import org.junit.Assert;
28 * @see pcmm.rcd.IPCMMServer
30 public abstract class AbstractPCMMServer implements IPCMMServer {
31 protected Logger logger;
33 * A ServerSocket to accept messages ( OPN requests)
35 private ServerSocket serverSocket;
37 private Socket stopSocket;
39 private volatile boolean keepAlive;
48 * Constructor to use the port number contained within the PCMMProperties static object
50 protected AbstractPCMMServer() {
51 this(PCMMProperties.get(PCMMConstants.PCMM_PORT, Integer.class));
55 * Constructor for starting the server to a pre-defined port number. When 0 is used, the server socket will
56 * assign one for you. To determine which port is being used, call getPort() after startServer() is called.
57 * @param port - the port number on which to start the server
59 protected AbstractPCMMServer(int port) {
60 // XXX - Assert.assertTrue(port >= 0 && port <= 65535);
63 logger = LoggerFactory.getLogger(getClass().getName());
64 int poolSize = PCMMProperties.get(PCMMConstants.PS_POOL_SIZE, Integer.class);
65 pool = new WorkerPool(poolSize);
71 * @see pcmm.rcd.IPCMMServer#startServer()
73 public void startServer() {
74 if (serverSocket != null)
77 serverSocket = new ServerSocket(port);
78 port = serverSocket.getLocalPort();
79 logger.info("Server started and listening on port :" + port);
80 } catch (IOException e) {
81 logger.error(e.getMessage());
83 // execute this in a single thread executor
84 Executors.newSingleThreadExecutor().execute(new Runnable() {
88 Socket socket = serverSocket.accept();
89 logger.info("Accepted a new connection from :" + socket.getInetAddress().getHostAddress() + ":" + socket.getPort());
91 pool.schedule(getPCMMClientHandler(socket));
92 logger.info("Handler attached tp : " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort());
94 logger.info("connection to be closed : " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort());
97 } catch (IOException e) {
98 logger.error(e.getMessage());
102 if (stopSocket != null && stopSocket.isConnected()) {
103 logger.info("Cleaning up");
106 if (serverSocket != null && serverSocket.isBound()) {
107 logger.info("Server about to stop");
108 serverSocket.close();
109 logger.info("Server stopped");
111 } catch (IOException e) {
112 logger.error(e.getMessage());
119 * This client is used to handle requests from within the Application
122 * @param socket - the connection to the PCMM server
123 * @return client handler
125 protected abstract IPCMMClientHandler getPCMMClientHandler(Socket socket);
130 * @see pcmm.rcd.IPCMMServer#stopServer()
132 public void stopServer() {
136 if (serverSocket != null) {
137 stopSocket = new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort());
138 logger.info("STOP socket created and attached");
140 } catch (Exception e) {
141 logger.error(e.getMessage());
148 * @see pcmm.state.IStateful#recordState()
150 public void recordState() {
157 * @see pcmm.state.IStateful#getRecoredState()
159 public IState getRecoredState() {
166 public int getPort() {
174 public void setPort(int port) {
181 * @see pcmm.rcd.IPCMMServer.IPCMMClientHandler
183 public abstract class AbstractPCMMClientHandler extends AbstractPCMMClient
184 implements IPCMMClientHandler {
186 protected boolean sendCCMessage = false;
188 public AbstractPCMMClientHandler(Socket socket) {
194 public boolean disconnect() {
195 // XXX send CC message
196 sendCCMessage = true;
198 * is this really needed ?
200 // if (getSocket() != null)
201 // handlersPool.remove(getSocket());
202 COPSMsg message = MessageFactory.getInstance().create(OPCode.CC);
203 sendRequest(message);
204 return super.disconnect();