--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.prpep;\r
+\r
+import java.net.Socket;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+import org.umu.cops.stack.COPSContext;\r
+import org.umu.cops.stack.COPSData;\r
+import org.umu.cops.stack.COPSDecision;\r
+import org.umu.cops.stack.COPSDecisionMsg;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSHandle;\r
+import org.umu.cops.stack.COPSPrObjBase;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+\r
+/**\r
+ * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)\r
+ * in PEP.\r
+ *\r
+ * The client handle is used to identify a unique request state for a\r
+ * single PEP per client-type. Client handles are chosen by the PEP and\r
+ * are opaque to the PDP. The PDP simply uses the request handle to\r
+ * uniquely identify the request state for a particular Client-Type over\r
+ * a particular TCP connection and generically tie its decisions to a\r
+ * corresponding request. Client handles are initiated in request\r
+ * messages and are then used by subsequent request, decision, and\r
+ * report messages to reference the same request state. When the PEP is\r
+ * ready to remove a local request state, it will issue a delete message\r
+ * to the PDP for the corresponding client handle. A handle MUST be\r
+ * explicitly deleted by the PEP before it can be used by the PEP to\r
+ * identify a new request state. Handles referring to different request\r
+ * states MUST be unique within the context of a particular TCP\r
+ * connection and client-type.\r
+ *\r
+ * @version COPSPepReqStateMan.java, v 2.00 2004\r
+ *\r
+ */\r
+public class COPSPepReqStateMan {\r
+\r
+ /**\r
+ * Request State created\r
+ */\r
+ public final static short ST_CREATE = 1;\r
+ /**\r
+ * Request sent\r
+ */\r
+ public final static short ST_INIT = 2;\r
+ /**\r
+ * Decisions received\r
+ */\r
+ public final static short ST_DECS = 3;\r
+ /**\r
+ * Report sent\r
+ */\r
+ public final static short ST_REPORT = 4;\r
+ /**\r
+ * Request State finalized\r
+ */\r
+ public final static short ST_FINAL = 5;\r
+ /**\r
+ * New Request State solicited\r
+ */\r
+ public final static short ST_NEW = 6;\r
+ /**\r
+ * Delete Request State solicited\r
+ */\r
+ public final static short ST_DEL = 7;\r
+ /**\r
+ * SYNC Request received\r
+ */\r
+ public final static short ST_SYNC = 8;\r
+ /**\r
+ * SYNC Completed\r
+ */\r
+ public final static short ST_SYNCALL = 9;\r
+ /**\r
+ * Close Connection received\r
+ */\r
+ public final static short ST_CCONN = 10;\r
+ /**\r
+ * KAlive Time out\r
+ */\r
+ public final static short ST_NOKA = 11;\r
+ /**\r
+ * ACCT Time out\r
+ */\r
+ public final static short ST_ACCT = 12;\r
+\r
+ /**\r
+ * The client-type identifies the policy client\r
+ */\r
+ protected short _clientType;\r
+\r
+ /**\r
+ * The client handle is used to uniquely identify a particular\r
+ * PEP's request for a client-type\r
+ */\r
+ protected COPSHandle _handle;\r
+\r
+ /**\r
+ The PolicyDataProcess is used to process policy data in the PEP\r
+ */\r
+ protected COPSPepDataProcess _process;\r
+\r
+ /**\r
+ * State Request State\r
+ */\r
+ protected short _status;\r
+\r
+ /**\r
+ The Msg Sender is used to send COPS messages\r
+ */\r
+ protected COPSPepMsgSender _sender;\r
+\r
+ /**\r
+ * Sync State\r
+ */\r
+ protected boolean _syncState;\r
+\r
+ /**\r
+ * Create a State Request Manager\r
+ *\r
+ * @param clientHandle a Client Handle\r
+ *\r
+ */\r
+ public COPSPepReqStateMan(short clientType, String clientHandle) {\r
+ // COPS Handle\r
+ _handle = new COPSHandle();\r
+ COPSData id = new COPSData(clientHandle);\r
+ _handle.setId(id);\r
+ // client-type\r
+ _clientType = clientType;\r
+ _syncState = true;\r
+ _status = ST_CREATE;\r
+ }\r
+\r
+ /**\r
+ * Return client handle\r
+ *\r
+ * @return a COPSHandle\r
+ *\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _handle;\r
+ }\r
+\r
+ /**\r
+ * Return client-type\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Return Request State status\r
+ *\r
+ * @return s short\r
+ */\r
+ public short getStatus() {\r
+ return _status;\r
+ }\r
+\r
+ /**\r
+ * Return the Policy Data Process\r
+ *\r
+ * @return a PolicyConfigure\r
+ *\r
+ */\r
+ public COPSPepDataProcess getDataProcess() {\r
+ return _process;\r
+ }\r
+\r
+ /**\r
+ * Establish the Policy Data Process\r
+ *\r
+ * @param process a PolicyConfigure\r
+ *\r
+ */\r
+ public void setDataProcess(COPSPepDataProcess process) {\r
+ _process = process;\r
+ }\r
+\r
+ /**\r
+ * Init Request State\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ protected void initRequestState(Socket sock)\r
+ throws COPSPepException {\r
+ // Inits an object for sending COPS messages to the PDP\r
+ _sender = new COPSPepMsgSender(_clientType, _handle, sock);\r
+\r
+ // If an object for retrieving PEP features exists,\r
+ // use it for retrieving them\r
+ Hashtable clientSIs;\r
+ if (_process != null)\r
+ clientSIs = _process.getClientData(this);\r
+ else\r
+ clientSIs = null;\r
+\r
+ // Send the request\r
+ _sender.sendRequest(clientSIs);\r
+\r
+ // Initial state\r
+ _status = ST_INIT;\r
+ }\r
+\r
+ /**\r
+ * Finalize Request State\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ protected void finalizeRequestState()\r
+ throws COPSPepException {\r
+ _sender.sendDeleteRequest();\r
+ _status = ST_FINAL;\r
+ }\r
+\r
+ /**\r
+ * Process the message Decision\r
+ *\r
+ * @param dMsg a COPSDecisionMsg\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ protected void processDecision(COPSDecisionMsg dMsg)\r
+ throws COPSPepException {\r
+ // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());\r
+\r
+ // COPSHandle handle = dMsg.getClientHandle();\r
+ Hashtable decisions = dMsg.getDecisions();\r
+\r
+ Hashtable removeDecs = new Hashtable(40);\r
+ Hashtable installDecs = new Hashtable(40);\r
+ Hashtable errorDecs = new Hashtable(40);\r
+ for (Enumeration e = decisions.keys() ; e.hasMoreElements() ;) {\r
+\r
+ COPSContext context = (COPSContext) e.nextElement();\r
+ Vector v = (Vector) decisions.get(context);\r
+ Enumeration ee = v.elements();\r
+ COPSDecision cmddecision = (COPSDecision) ee.nextElement();\r
+\r
+ // cmddecision --> we must check whether it is an error!\r
+\r
+ if (cmddecision.isInstallDecision()) {\r
+ String prid = new String();\r
+ for (; ee.hasMoreElements() ;) {\r
+ COPSDecision decision = (COPSDecision) ee.nextElement();\r
+\r
+ COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());\r
+ switch (obj.getSNum()) {\r
+ case COPSPrObjBase.PR_PRID:\r
+ prid = obj.getData().str();\r
+ break;\r
+ case COPSPrObjBase.PR_EPD:\r
+ installDecs.put(prid, obj.getData().str());\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (cmddecision.isRemoveDecision()) {\r
+\r
+ String prid = new String();\r
+ for (; ee.hasMoreElements() ;) {\r
+ COPSDecision decision = (COPSDecision) ee.nextElement();\r
+\r
+ COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());\r
+ switch (obj.getSNum()) {\r
+ case COPSPrObjBase.PR_PRID:\r
+ prid = obj.getData().str();\r
+ break;\r
+ case COPSPrObjBase.PR_EPD:\r
+ removeDecs.put(prid, obj.getData().str());\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ //** Apply decisions to the configuration\r
+ _process.setDecisions(this, removeDecs, installDecs, errorDecs);\r
+ _status = ST_DECS;\r
+\r
+\r
+ if (_process.isFailReport(this)) {\r
+ // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");\r
+ _sender.sendFailReport(_process.getReportData(this));\r
+ } else {\r
+ // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");\r
+ _sender.sendSuccessReport(_process.getReportData(this));\r
+ }\r
+ _status = ST_REPORT;\r
+\r
+ if (!_syncState) {\r
+ _sender.sendSyncComplete();\r
+ _syncState = true;\r
+ _status = ST_SYNCALL;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Process the message NewRequestState\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ protected void processOpenNewRequestState()\r
+ throws COPSPepException {\r
+\r
+ if (_process != null)\r
+ _process.newRequestState(this);\r
+\r
+ _status = ST_NEW;\r
+ }\r
+\r
+ /**\r
+ * Process the message DeleteRequestState\r
+ *\r
+ * @param dMsg a COPSDecisionMsg\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ protected void processDeleteRequestState(COPSDecisionMsg dMsg)\r
+ throws COPSPepException {\r
+ if (_process != null)\r
+ _process.closeRequestState(this);\r
+\r
+ _status = ST_DEL;\r
+ }\r
+\r
+ /**\r
+ * Process the message SycnStateRequest.\r
+ * The message SycnStateRequest indicates that the remote PDP\r
+ * wishes the client (which appears in the common header)\r
+ * to re-send its state.\r
+ *\r
+ * @param ssMsg a COPSSyncStateMsg\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ protected void processSyncStateRequest(COPSSyncStateMsg ssMsg)\r
+ throws COPSPepException {\r
+ _syncState = false;\r
+ // If an object for retrieving PEP features exists,\r
+ // use it for retrieving them\r
+ Hashtable clientSIs;\r
+ if (_process != null)\r
+ clientSIs = _process.getClientData(this);\r
+ else\r
+ clientSIs = null;\r
+\r
+ // Send request\r
+ _sender.sendRequest(clientSIs);\r
+\r
+ _status = ST_SYNC;\r
+ }\r
+\r
+ protected void processClosedConnection(COPSError error)\r
+ throws COPSPepException {\r
+ if (_process != null)\r
+ _process.notifyClosedConnection(this, error);\r
+\r
+ _status = ST_CCONN;\r
+ }\r
+\r
+ protected void processNoKAConnection()\r
+ throws COPSPepException {\r
+ if (_process != null)\r
+ _process.notifyNoKAliveReceived(this);\r
+\r
+ _status = ST_NOKA;\r
+ }\r
+\r
+ protected void processAcctReport()\r
+ throws COPSPepException {\r
+\r
+ Hashtable report = new Hashtable();\r
+ if (_process != null)\r
+ report = _process.getAcctData(this);\r
+\r
+ _sender.sendAcctReport(report);\r
+\r
+ _status = ST_ACCT;\r
+ }\r
+\r
+}\r