-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
package org.pcmm;
+import org.pcmm.gates.IGateID;
+import org.pcmm.gates.IPCMMError.ErrorCode;
+import org.pcmm.gates.IPCMMGate;
import org.pcmm.gates.ITransactionID;
+import org.pcmm.gates.ITransactionID.GateCommandType;
+import org.pcmm.gates.impl.PCMMError;
import org.pcmm.gates.impl.PCMMGateReq;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.umu.cops.prpdp.COPSPdpException;
+import org.umu.cops.prpdp.COPSPdpReqStateMan;
import org.umu.cops.stack.*;
import org.umu.cops.stack.COPSReportType.ReportType;
/**
* State manager class for provisioning requests, at the PDP side.
*/
-public class PCMMPdpReqStateMan {
-
- public final static Logger logger = LoggerFactory.getLogger(PCMMPdpReqStateMan.class);
+public class PCMMPdpReqStateMan extends COPSPdpReqStateMan {
- /**
- * Request State created
- */
- public final static short ST_CREATE = 1;
- /**
- * Request received
- */
- public final static short ST_INIT = 2;
- /**
- * Decisions sent
- */
- public final static short ST_DECS = 3;
- /**
- * Report received
- */
- 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 sent
- */
- 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;
- /**
- * Keep-alive timeout
- */
- public final static short ST_NOKA = 11;
- /**
- * Accounting timeout
- */
- public final static short ST_ACCT = 12;
-
- /**
- * COPS client-type that identifies the policy client
- */
- protected short _clientType;
-
- /**
- * COPS client handle used to uniquely identify a particular
- * PEP's request for a client-type
- */
- protected COPSHandle _handle;
+ private final static Logger logger = LoggerFactory.getLogger(PCMMPdpReqStateMan.class);
/**
* Object for performing policy data processing
*/
- protected PCMMPdpDataProcess _process;
-
- /**
- * Current state of the request being managed
- */
- protected short _status;
+ protected final PCMMPdpDataProcess _thisProcess;
/** COPS message transceiver used to send COPS messages */
- protected PCMMPdpMsgSender _sender;
+ protected final PCMMPdpMsgSender _sender;
/**
* Creates a request state manager
* @param clientType Client-type
* @param clientHandle Client handle
*/
- public PCMMPdpReqStateMan(final short clientType, final String clientHandle) {
- _handle = new COPSHandle(new COPSData(clientHandle));
- _clientType = clientType;
- _status = ST_CREATE;
- }
-
- /**
- * Gets the client handle
- * @return Client's <tt>COPSHandle</tt>
- */
- public COPSHandle getClientHandle() {
- return _handle;
- }
-
- /**
- * Gets the client-type
- * @return Client-type value
- */
- public int getClientType() {
- return _clientType;
- }
-
- /**
- * Gets the status of the request
- * @return Request state value
- */
- public short getStatus() {
- return _status;
- }
-
- /**
- * Gets the policy data processing object
- * @return Policy data processing object
- */
- public PCMMPdpDataProcess getDataProcess() {
- return _process;
- }
-
- /**
- * Sets the policy data processing object
- * @param process Policy data processing object
- */
- public void setDataProcess(PCMMPdpDataProcess process) {
- _process = process;
- }
-
- /**
- * Called when COPS sync is completed
- * @param repMsg COPS sync message
- * @throws COPSPdpException
- */
- protected void processSyncComplete(COPSSyncStateMsg repMsg)
- throws COPSPdpException {
-
- _status = ST_SYNCALL;
-
- // maybe we should notifySyncComplete ...
- }
-
- /**
- * Initializes a new request state over a socket
- * @param sock Socket to the PEP
- * @throws COPSPdpException
- */
- protected void initRequestState(Socket sock)
- throws COPSPdpException {
- // Inits an object for sending COPS messages to the PEP
- _sender = new PCMMPdpMsgSender(_clientType, _handle, sock);
-
+ // TODO - consider sending in the COPSHandle object instead
+ public PCMMPdpReqStateMan(final short clientType, final COPSHandle clientHandle, final PCMMPdpDataProcess process,
+ final Socket socket) {
+ super(clientType, clientHandle, process, socket);
+ this._thisProcess = process;
+ _sender = new PCMMPdpMsgSender(_clientType, _handle, _socket);
// Initial state
- _status = ST_INIT;
+ _status = Status.ST_INIT;
}
-
-
- /**
- * Processes a COPS request
- * @param msg COPS request received from the PEP
- * @throws COPSPdpException
- */
- protected void processRequest(COPSReqMsg msg)
- throws COPSPdpException {
-
- COPSHeader hdrmsg = msg.getHeader();
- COPSHandle handlemsg = msg.getClientHandle();
- COPSContext contextmsg = msg.getContext();
-
- //** Analyze the request
- //**
-
- /* <Request> ::= <Common Header>
- * <Client Handle>
- * <Context>
- * *(<Named ClientSI>)
- * [<Integrity>]
- * <Named ClientSI> ::= <*(<PRID> <EPD>)>
- *
- * Very important, this is actually being treated like this:
- * <Named ClientSI> ::= <PRID> | <EPD>
- *
-
- // Named ClientSI
- Vector clientSIs = msg.getClientSI();
- Hashtable reqSIs = new Hashtable(40);
- String strobjprid = new String();
- for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) {
- COPSClientSI clientSI = (COPSClientSI) e.nextElement();
-
- COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());
- switch (obj.getSNum())
- {
- case COPSPrObjBase.PR_PRID:
- strobjprid = obj.getData().str();
- break;
- case COPSPrObjBase.PR_EPD:
- reqSIs.put(strobjprid, obj.getData().str());
- // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);
- // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());
- break;
- default:
- break;
- }
- }
-
- //** Here we must retrieve a decision depending on
- //** the supplied ClientSIs
- // reqSIs is a hashtable with the prid and epds
-
- // ................
- //
- Hashtable removeDecs = new Hashtable();
- Hashtable installDecs = new Hashtable();
- _process.setClientData(this, reqSIs);
-
- removeDecs = _process.getRemovePolicy(this);
- installDecs = _process.getInstallPolicy(this);
-
- //** We create the SOLICITED decision
- //**
- _sender.sendDecision(removeDecs, installDecs);
- _status = ST_DECS;
- */
+ @Override
+ public void processRequest(final COPSReqMsg msg) throws COPSPdpException {
+ // TODO - Implement me - see commented out code from history prior to May 4, 2015...
}
- /**
- * Processes a report
- * @param msg Report message from the PEP
- * @throws COPSPdpException
- */
- protected void processReport(COPSReportMsg msg) throws COPSPdpException {
+ // TODO - break apart this method
+ @Override
+ protected void processReport(final COPSReportMsg msg) throws COPSPdpException {
// Report Type
final COPSReportType rtypemsg = msg.getReport();
// PCMMUtils.WriteBinaryDump("COPSReportClientSI", data);
logger.info("PCMMGateReq Parse Gate Message");
- PCMMGateReq gateMsg = new PCMMGateReq(data);
+ final PCMMGateReq gateMsg = PCMMGateReq.parse(data);
+ // TODO FIXME - Why is this Map being filled but never used???
final Map<String, String> repSIs = new HashMap<>();
String strobjprid = "";
final COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());
switch (obj.getSNum()) {
case COPSPrObjBase.PR_PRID:
logger.info("COPSPrObjBase.PR_PRID");
+ // TODO FIXME - this value is never used
strobjprid = obj.getData().str();
break;
case COPSPrObjBase.PR_EPD:
logger.info("COPSPrObjBase.PR_EPD");
+ // TODO FIXME - strobjprid is always empty
repSIs.put(strobjprid, obj.getData().str());
- // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);
- // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());
+ logger.info("PRID: " + strobjprid);
+ logger.info("EPD: " + obj.getData().str());
break;
default:
logger.error("Object s-num: " + obj.getSNum() + "stype " + obj.getSType());
logger.info("rtypemsg process");
//** Here we must act in accordance with
//** the report received
+
+ // retrieve and remove the transactionId to gate request map entry
+ // see PCMMPdpMsgSender.sendGateSet(IPCMMGate gate)
+ final ITransactionID trID = gateMsg.getTransactionID();
+ final Short trIDnum = trID.getTransactionIdentifier();
+
+ logger.info("Removing gate from cache with key - " + trIDnum);
+ final IPCMMGate gate = PCMMGlobalConfig.transactionGateMap.remove(trIDnum);
+ if (gate != null) {
+ // capture the "error" message if any
+ gate.setError(gateMsg.getError());
+ logger.info("Setting error on gate - " + gateMsg.getError());
+ }else {
+ logger.error("processReport(): gateReq not found for transactionID {}", trIDnum);
+ return;
+ }
+
if (rtypemsg.getReportType().equals(ReportType.SUCCESS)) {
logger.info("rtypemsg success");
- _status = ST_REPORT;
- if (_process != null)
- _process.successReport(this, gateMsg);
+ _status = Status.ST_REPORT;
+ final IGateID gateID = gateMsg.getGateID();
+ logger.info("Setting gate ID on gate object - " + gateID);
+ gate.setGateID(gateID);
+ if (_thisProcess != null)
+ _thisProcess.successReport(this, gateMsg);
} else {
- if (gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateDeleteAck) {
- logger.info("GateDeleteAck: GateID = " + gateMsg.getGateID().getGateID());
- if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID1())
- PCMMGlobalConfig.setGateID1(0);
- if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID2())
- PCMMGlobalConfig.setGateID2(0);
-
- }
- if (gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateSetAck) {
- logger.info("GateSetAck: GateID = " + gateMsg.getGateID().getGateID());
- if (0 == PCMMGlobalConfig.getGateID1())
- PCMMGlobalConfig.setGateID1(gateMsg.getGateID().getGateID());
- if (0 == PCMMGlobalConfig.getGateID2())
- PCMMGlobalConfig.setGateID2(gateMsg.getGateID().getGateID());
+ final String cmdType;
+ if (trID.getGateCommandType().equals(GateCommandType.GATE_DELETE_ACK)) {
+ cmdType = "GateDeleteAck";
+ } else if (trID.getGateCommandType().equals(GateCommandType.GATE_SET_ACK)) {
+ cmdType = "GateSetAck";
+ } else cmdType = null;
+ // capture the gateId from the response message
+ final IGateID gateID = gateMsg.getGateID();
+ logger.info("Setting gate ID on gate object - " + gateID);
+ gate.setGateID(gateID);
+
+ if (gateID != null) {
+ int gateIdInt = gateID.getGateID();
+ String gateIdHex = String.format("%08x", gateIdInt);
+ logger.info(getClass().getName() + ": " + cmdType + ": GateID = " + gateIdHex);
+ } else {
+ logger.warn("Gate ID is null");
}
}
if (rtypemsg.getReportType().equals(ReportType.FAILURE)) {
logger.info("rtypemsg failure");
- _status = ST_REPORT;
- if (_process != null)
- _process.failReport(this, gateMsg);
+ _status = Status.ST_REPORT;
+ if (_thisProcess != null)
+ _thisProcess.failReport(this, gateMsg);
else
- logger.info("Gate message error - " + gateMsg.getError().toString());
- } else
- if (rtypemsg.getReportType().equals(ReportType.ACCOUNTING)) {
+ if (gateMsg.getError() != null)
+ logger.info("Gate message error - " + gateMsg.getError().toString());
+ else {
+ // TODO - Determine if this is the correct error code
+ final PCMMError error = new PCMMError(ErrorCode.UNK_GATE_CMD);
+ gate.setError(error);
+ logger.warn("Gate request failed without an error, setting one - " + error);
+ }
+ } else if (rtypemsg.getReportType().equals(ReportType.ACCOUNTING)) {
logger.info("rtypemsg account");
- _status = ST_ACCT;
- if (_process != null)
- _process.acctReport(this, gateMsg);
- }
- }
- }
-
- /**
- * Called when connection is closed
- * @param error Reason
- * @throws COPSPdpException
- */
- protected void processClosedConnection(COPSError error)
- throws COPSPdpException {
- if (_process != null)
- _process.notifyClosedConnection(this, error);
-
- _status = ST_CCONN;
- }
-
- /**
- * Called when no keep-alive is received
- * @throws COPSPdpException
- */
- protected void processNoKAConnection()
- throws COPSPdpException {
- if (_process != null)
- _process.notifyNoKAliveReceived(this);
-
- _status = ST_NOKA;
- }
-
- /**
- * Deletes the request state
- * @throws COPSPdpException
- */
- protected void finalizeRequestState()
- throws COPSPdpException {
- _sender.sendDeleteRequestState();
- _status = ST_FINAL;
- }
-
- /**
- * Asks for a COPS sync
- * @throws COPSPdpException
- */
- protected void syncRequestState()
- throws COPSPdpException {
- _sender.sendSyncRequestState();
- _status = ST_SYNC;
- }
-
- /**
- * Opens a new request state
- * @throws COPSPdpException
- */
- protected void openNewRequestState()
- throws COPSPdpException {
- _sender.sendOpenNewRequestState();
- _status = ST_NEW;
- }
-
- /**
- * Processes a COPS delete message
- * @param dMsg <tt>COPSDeleteMsg</tt> received from the PEP
- * @throws COPSPdpException
- */
- protected void processDeleteRequestState(COPSDeleteMsg dMsg)
- throws COPSPdpException {
- if (_process != null)
- _process.closeRequestState(this);
+ _status = Status.ST_ACCT;
+ if (_thisProcess != null)
+ _thisProcess.acctReport(this, gateMsg);
+ }
- _status = ST_DEL;
+ // let the waiting gateSet/gateDelete sender proceed
+ // TODO - see PCMMService#processReport() gate.notify(). Should determine a better means to
+ // TODO - handle this synchronization.
+ logger.info("Notify gate request has been updated with ID - " + gate.getGateID());
+ synchronized(gate) {
+ gate.notify();
+ }
+ logger.info("Out processReport");
+ }
}
}