-/*\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 org.umu.cops.stack.*;\r
-\r
-import java.net.Socket;\r
-import java.util.Enumeration;\r
-import java.util.Hashtable;\r
-import java.util.Vector;\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
- _handle = new COPSHandle(new COPSData(clientHandle));\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
+/*
+ * Copyright (c) 2004 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.prpep;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.COPSStateMan;
+import org.umu.cops.stack.*;
+
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)
+ * in PEP.
+ *
+ * The client handle is used to identify a unique request state for a
+ * single PEP per client-type. Client handles are chosen by the PEP and
+ * are opaque to the PDP. The PDP simply uses the request handle to
+ * uniquely identify the request state for a particular Client-Type over
+ * a particular TCP connection and generically tie its decisions to a
+ * corresponding request. Client handles are initiated in request
+ * messages and are then used by subsequent request, decision, and
+ * report messages to reference the same request state. When the PEP is
+ * ready to remove a local request state, it will issue a delete message
+ * to the PDP for the corresponding client handle. A handle MUST be
+ * explicitly deleted by the PEP before it can be used by the PEP to
+ * identify a new request state. Handles referring to different request
+ * states MUST be unique within the context of a particular TCP
+ * connection and client-type.
+ *
+ * @version COPSPepReqStateMan.java, v 2.00 2004
+ *
+ */
+public class COPSPepReqStateMan extends COPSStateMan {
+
+ private final static Logger logger = LoggerFactory.getLogger(COPSPepReqStateMan.class);
+
+ /**
+ The PolicyDataProcess is used to process policy data in the PEP
+ */
+ protected final COPSPepDataProcess _process;
+
+ /**
+ The Msg Sender is used to send COPS messages
+ */
+ protected final COPSPepMsgSender _sender;
+
+ /**
+ * Sync State
+ */
+ protected transient boolean _syncState;
+
+ /**
+ * Constructor for this class
+ * @param clientType - the PEP client type
+ * @param clientHandle - the client-handle
+ * @param process - the data processor
+ * @param socket - the socket connection
+ */
+ public COPSPepReqStateMan(final short clientType, final COPSHandle clientHandle, final COPSPepDataProcess process,
+ final Socket socket) {
+ this(clientType, clientHandle, process, socket, new COPSPepMsgSender(clientType, clientHandle, socket));
+ }
+
+ /**
+ * Constructor for sub-classes
+ * @param clientType - the PEP client type
+ * @param clientHandle - the client-handle
+ * @param process - the data processor
+ * @param socket - the socket connection
+ * @param sender - responsible for sending COPS messages to the PEP
+ */
+ protected COPSPepReqStateMan(final short clientType, final COPSHandle clientHandle, final COPSPepDataProcess process,
+ final Socket socket, final COPSPepMsgSender sender) {
+
+ super(clientType, clientHandle, socket);
+ this._process = process;
+ _syncState = true;
+ // Inits an object for sending COPS messages to the PDP
+ _sender = sender;
+ }
+
+ /**
+ * Init Request State
+ * @throws COPSPepException
+ */
+ public void initRequestState() throws COPSException {
+ // If an object for retrieving PEP features exists,
+ // use it for retrieving them
+ final Map<String, String> clientSIs;
+ if (_process != null)
+ clientSIs = _process.getClientData(this);
+ else
+ clientSIs = new HashMap<>();
+
+ // Send the request
+ // TODO - do we really want to send when this is empty???
+ _sender.sendRequest(clientSIs);
+
+ // Initial state
+ _status = Status.ST_INIT;
+ }
+
+ /**
+ * Finalize Request State
+ *
+ * @throws COPSPepException
+ *
+ */
+ public void finalizeRequestState() throws COPSException {
+ _sender.sendDeleteRequest();
+ _status = Status.ST_FINAL;
+ }
+
+ /**
+ * Process the message Decision
+ * @param dMsg a COPSDecisionMsg
+ * @throws COPSPepException
+ */
+ protected void processDecision(final COPSDecisionMsg dMsg) throws COPSException {
+ logger.info("Processing decision message - " + dMsg);
+ final Map<COPSContext, Set<COPSDecision>> decisions = dMsg.getDecisions();
+
+ final Map<String, String> removeDecs = new HashMap<>();
+ final Map<String, String> installDecs = new HashMap<>();
+
+ for (final Set<COPSDecision> copsDecisions: decisions.values()) {
+ final COPSDecision cmddecision = copsDecisions.iterator().next();
+ String prid = "";
+ switch (cmddecision.getCommand()) {
+ case INSTALL:
+ for (final COPSDecision decision : copsDecisions) {
+ final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
+ switch (obj.getSNum()) {
+ case COPSPrObjBase.PR_PRID:
+ prid = obj.getData().str();
+ break;
+ case COPSPrObjBase.PR_EPD:
+ installDecs.put(prid, obj.getData().str());
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case REMOVE:
+ for (final COPSDecision decision : copsDecisions) {
+ final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
+ switch (obj.getSNum()) {
+ case COPSPrObjBase.PR_PRID:
+ prid = obj.getData().str();
+ break;
+ case COPSPrObjBase.PR_EPD:
+ removeDecs.put(prid, obj.getData().str());
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ }
+
+ }
+
+ //** Apply decisions to the configuration
+ // TODO - why is this collection never getting populated???
+ final Map<String, String> errorDecs = new HashMap<>();
+ _process.setDecisions(this, removeDecs, installDecs, errorDecs);
+ _status = Status.ST_DECS;
+
+
+ if (_process.isFailReport(this)) {
+ logger.info("Sending FAIL report");
+ _sender.sendFailReport(_process.getReportData(this));
+ } else {
+ logger.info("Sending SUCCESS report");
+ _sender.sendSuccessReport(_process.getReportData(this));
+ }
+ _status = Status.ST_REPORT;
+
+ if (!_syncState) {
+ _sender.sendSyncComplete();
+ _syncState = true;
+ _status = Status.ST_SYNCALL;
+ }
+ }
+
+ /**
+ * Process the message NewRequestState
+ * @throws COPSPepException
+ */
+ protected void processOpenNewRequestState() throws COPSPepException {
+ if (_process != null)
+ _process.newRequestState(this);
+
+ _status = Status.ST_NEW;
+ }
+
+ /**
+ * Process the message DeleteRequestState
+ * @param dMsg a COPSDecisionMsg
+ * @throws COPSPepException
+ */
+ protected void processDeleteRequestState(final COPSDecisionMsg dMsg) throws COPSPepException {
+ if (_process != null)
+ _process.closeRequestState(this);
+
+ _status = Status.ST_DEL;
+ }
+
+ /**
+ * Process the message SycnStateRequest.
+ * The message SycnStateRequest indicates that the remote PDP
+ * wishes the client (which appears in the common header)
+ * to re-send its state.
+ * @param ssMsg a COPSSyncStateMsg
+ * @throws COPSPepException
+ */
+ protected void processSyncStateRequest(final COPSSyncStateMsg ssMsg) throws COPSException {
+ _syncState = false;
+ // If an object for retrieving PEP features exists,
+ // use it for retrieving them
+ final Map<String, String> clientSIs;
+ if (_process != null)
+ clientSIs = _process.getClientData(this);
+ else
+ clientSIs = new HashMap<>();
+
+ // Send request
+ // TODO - do we really want to send the request when the map is empty???
+ _sender.sendRequest(clientSIs);
+
+ _status = Status.ST_SYNC;
+ }
+
+ public void processClosedConnection(final COPSError error) throws COPSPepException {
+ if (_process != null)
+ _process.notifyClosedConnection(this, error);
+
+ _status = Status.ST_CCONN;
+ }
+
+ public void processNoKAConnection() throws COPSException {
+ if (_process != null)
+ _process.notifyNoKAliveReceived(this);
+
+ _status = Status.ST_NOKA;
+ }
+
+ /**
+ * Creates and sends an accounting report
+ * @throws COPSException
+ */
+ public void processAcctReport() throws COPSException {
+ final Map<String, String> report;
+ if (_process != null) report = _process.getAcctData(this);
+ else report = new HashMap<>();
+
+ // TODO - do we really want to send when the map is empty???
+ _sender.sendAcctReport(report);
+
+ _status = Status.ST_ACCT;
+ }
+
+}