Expanded CMTS emulator to respond properly to gate add requests.
[packetcable.git] / packetcable-driver / src / main / java / org / umu / cops / prpep / COPSPepReqStateMan.java
index 5d09425ab134045c6378288105d94fb9d68f2a91..3a4f6587ca8a27baf4ac30834a27fab3c4970e88 100644 (file)
-/*\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;
+    }
+
+}