Expanded CMTS emulator to respond properly to gate add requests.
[packetcable.git] / packetcable-driver / src / main / java / org / umu / cops / prpep / COPSPepReqStateMan.java
index f29cdb248bf34e20186281cdc52c955edac3bf36..3a4f6587ca8a27baf4ac30834a27fab3c4970e88 100644 (file)
@@ -6,13 +6,15 @@
 
 package org.umu.cops.prpep;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.COPSStateMan;
 import org.umu.cops.stack.*;
-import org.umu.cops.stack.COPSDecision.Command;
 
 import java.net.Socket;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)
@@ -36,174 +38,74 @@ import java.util.Vector;
  * @version COPSPepReqStateMan.java, v 2.00 2004
  *
  */
-public class COPSPepReqStateMan {
+public class COPSPepReqStateMan extends COPSStateMan {
 
-    /**
-     * Request State created
-     */
-    public final static short ST_CREATE = 1;
-    /**
-     * Request sent
-     */
-    public final static short ST_INIT = 2;
-    /**
-     * Decisions received
-     */
-    public final static short ST_DECS = 3;
-    /**
-     * Report sent
-     */
-    public final static short ST_REPORT = 4;
-    /**
-     * Request State finalized
-     */
-    public final static short ST_FINAL = 5;
-    /**
-     * New Request State solicited
-     */
-    public final static short ST_NEW = 6;
-    /**
-     * Delete Request State solicited
-     */
-    public final static short ST_DEL = 7;
-    /**
-     * SYNC Request received
-     */
-    public final static short ST_SYNC = 8;
-    /**
-     * SYNC Completed
-     */
-    public final static short ST_SYNCALL = 9;
-    /**
-     * Close Connection received
-     */
-    public final static short ST_CCONN = 10;
-    /**
-     * KAlive Time out
-     */
-    public final static short ST_NOKA = 11;
-    /**
-     * ACCT Time out
-     */
-    public final static short ST_ACCT = 12;
-
-    /**
-     * The client-type identifies the policy client
-     */
-    protected short _clientType;
-
-    /**
-     *  The client handle is used to uniquely identify a particular
-     *  PEP's request for a client-type
-     */
-    protected COPSHandle _handle;
+    private final static Logger logger = LoggerFactory.getLogger(COPSPepReqStateMan.class);
 
     /**
         The PolicyDataProcess is used to process policy data in the PEP
      */
-    protected COPSPepDataProcess _process;
-
-    /**
-     *  State Request State
-     */
-    protected short _status;
+    protected final COPSPepDataProcess _process;
 
     /**
         The Msg Sender is used to send COPS messages
      */
-    protected COPSPepMsgSender _sender;
+    protected final COPSPepMsgSender _sender;
 
     /**
      * Sync State
      */
-    protected boolean _syncState;
+    protected transient boolean _syncState;
 
     /**
-     * Create a State Request Manager
-     *
-     * @param    clientHandle                a Client Handle
-     *
+     * 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(short clientType, String clientHandle) {
-        _handle = new COPSHandle(new COPSData(clientHandle));
-        _clientType = clientType;
-        _syncState = true;
-        _status = ST_CREATE;
+    public COPSPepReqStateMan(final short clientType, final COPSHandle clientHandle, final COPSPepDataProcess process,
+                              final Socket socket) {
+        this(clientType, clientHandle, process, socket, new COPSPepMsgSender(clientType, clientHandle, socket));
     }
 
     /**
-     * Return client handle
-     *
-     * @return   a COPSHandle
-     *
+     * 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
      */
-    public COPSHandle getClientHandle() {
-        return _handle;
-    }
+    protected COPSPepReqStateMan(final short clientType, final COPSHandle clientHandle, final COPSPepDataProcess process,
+                                 final Socket socket, final COPSPepMsgSender sender) {
 
-    /**
-     * Return client-type
-     *
-     * @return   a short
-     *
-     */
-    public short getClientType() {
-        return _clientType;
-    }
-
-    /**
-     * Return Request State status
-     *
-     * @return      s short
-     */
-    public short getStatus() {
-        return _status;
-    }
-
-    /**
-     * Return the Policy Data Process
-     *
-     * @return   a PolicyConfigure
-     *
-     */
-    public COPSPepDataProcess getDataProcess() {
-        return _process;
-    }
-
-    /**
-     * Establish the Policy Data Process
-     *
-     * @param    process              a  PolicyConfigure
-     *
-     */
-    public void setDataProcess(COPSPepDataProcess process) {
-        _process = process;
+        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
-     *
      */
-    protected void initRequestState(Socket sock)
-    throws COPSPepException {
-        // Inits an object for sending COPS messages to the PDP
-        _sender = new COPSPepMsgSender(_clientType, _handle, sock);
-
+    public void initRequestState() throws COPSException {
         // If an object for retrieving PEP features exists,
         // use it for retrieving them
-        Hashtable clientSIs;
+        final Map<String, String> clientSIs;
         if (_process != null)
             clientSIs = _process.getClientData(this);
         else
-            clientSIs = null;
+            clientSIs = new HashMap<>();
 
         // Send the request
+        // TODO - do we really want to send when this is empty???
         _sender.sendRequest(clientSIs);
 
         // Initial state
-        _status = ST_INIT;
+        _status = Status.ST_INIT;
     }
 
     /**
@@ -212,129 +114,105 @@ public class COPSPepReqStateMan {
      * @throws   COPSPepException
      *
      */
-    protected void finalizeRequestState()
-    throws COPSPepException {
+    public void finalizeRequestState() throws COPSException {
         _sender.sendDeleteRequest();
-        _status = ST_FINAL;
+        _status = Status.ST_FINAL;
     }
 
     /**
      * Process the message Decision
-     *
      * @param    dMsg                a  COPSDecisionMsg
-     *
      * @throws   COPSPepException
-     *
      */
-    protected void processDecision(COPSDecisionMsg dMsg)
-    throws COPSPepException {
-        // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());
-
-        // COPSHandle handle = dMsg.getClientHandle();
-        Hashtable decisions = dMsg.getDecisions();
-
-        Hashtable removeDecs = new Hashtable(40);
-        Hashtable installDecs = new Hashtable(40);
-        Hashtable errorDecs = new Hashtable(40);
-        for (Enumeration e = decisions.keys() ; e.hasMoreElements() ;) {
-
-            COPSContext context = (COPSContext) e.nextElement();
-            Vector v = (Vector) decisions.get(context);
-            Enumeration ee = v.elements();
-            COPSDecision cmddecision = (COPSDecision) ee.nextElement();
-
-            // cmddecision --> we must check whether it is an error!
-
-            if (cmddecision.getCommand().equals(Command.INSTALL)) {
-                String prid = "";
-                for (; ee.hasMoreElements() ;) {
-                    COPSDecision decision = (COPSDecision) ee.nextElement();
-
-                    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;
+    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;
+                        }
                     }
-                }
-            }
-
-            if (cmddecision.getCommand().equals(Command.REMOVE)) {
-
-                String prid = "";
-                for (; ee.hasMoreElements() ;) {
-                    COPSDecision decision = (COPSDecision) ee.nextElement();
-
-                    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;
+                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 = ST_DECS;
+        _status = Status.ST_DECS;
 
 
         if (_process.isFailReport(this)) {
-            // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");
+            logger.info("Sending FAIL report");
             _sender.sendFailReport(_process.getReportData(this));
         } else {
-            // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");
+            logger.info("Sending SUCCESS report");
             _sender.sendSuccessReport(_process.getReportData(this));
         }
-        _status = ST_REPORT;
+        _status = Status.ST_REPORT;
 
         if (!_syncState) {
             _sender.sendSyncComplete();
             _syncState = true;
-            _status = ST_SYNCALL;
+            _status = Status.ST_SYNCALL;
         }
     }
 
     /**
      * Process the message NewRequestState
-     *
      * @throws   COPSPepException
-     *
      */
-    protected void processOpenNewRequestState()
-    throws COPSPepException {
-
+    protected void processOpenNewRequestState() throws COPSPepException {
         if (_process != null)
             _process.newRequestState(this);
 
-        _status = ST_NEW;
+        _status = Status.ST_NEW;
     }
 
     /**
      * Process the message DeleteRequestState
-     *
      * @param    dMsg                a  COPSDecisionMsg
-     *
      * @throws   COPSPepException
-     *
      */
-    protected void processDeleteRequestState(COPSDecisionMsg dMsg)
-    throws COPSPepException {
+    protected void processDeleteRequestState(final COPSDecisionMsg dMsg) throws COPSPepException {
         if (_process != null)
             _process.closeRequestState(this);
 
-        _status = ST_DEL;
+        _status = Status.ST_DEL;
     }
 
     /**
@@ -342,55 +220,53 @@ public class COPSPepReqStateMan {
      * 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(COPSSyncStateMsg ssMsg)
-    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
-        Hashtable clientSIs;
+        final Map<String, String> clientSIs;
         if (_process != null)
             clientSIs = _process.getClientData(this);
         else
-            clientSIs = null;
+            clientSIs = new HashMap<>();
 
         // Send request
+        // TODO - do we really want to send the request when the map is empty???
         _sender.sendRequest(clientSIs);
 
-        _status = ST_SYNC;
+        _status = Status.ST_SYNC;
     }
 
-    protected void processClosedConnection(COPSError error)
-    throws COPSPepException {
+    public void processClosedConnection(final COPSError error) throws COPSPepException {
         if (_process != null)
             _process.notifyClosedConnection(this, error);
 
-        _status = ST_CCONN;
+        _status = Status.ST_CCONN;
     }
 
-    protected void processNoKAConnection()
-    throws COPSPepException {
+    public void processNoKAConnection() throws COPSException {
         if (_process != null)
             _process.notifyNoKAliveReceived(this);
 
-        _status = ST_NOKA;
+        _status = Status.ST_NOKA;
     }
 
-    protected void processAcctReport()
-    throws COPSPepException {
-
-        Hashtable report = new Hashtable();
-        if (_process != null)
-            report = _process.getAcctData(this);
+    /**
+     * 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 = ST_ACCT;
+        _status = Status.ST_ACCT;
     }
 
 }