2 * Copyright (c) 2004 University of Murcia. All rights reserved.
3 * --------------------------------------------------------------
4 * For more information, please see <http://www.umu.euro6ix.org/>.
7 package org.umu.cops.prpep;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11 import org.umu.cops.COPSStateMan;
12 import org.umu.cops.stack.*;
14 import java.net.Socket;
15 import java.util.HashMap;
20 * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)
23 * The client handle is used to identify a unique request state for a
24 * single PEP per client-type. Client handles are chosen by the PEP and
25 * are opaque to the PDP. The PDP simply uses the request handle to
26 * uniquely identify the request state for a particular Client-Type over
27 * a particular TCP connection and generically tie its decisions to a
28 * corresponding request. Client handles are initiated in request
29 * messages and are then used by subsequent request, decision, and
30 * report messages to reference the same request state. When the PEP is
31 * ready to remove a local request state, it will issue a delete message
32 * to the PDP for the corresponding client handle. A handle MUST be
33 * explicitly deleted by the PEP before it can be used by the PEP to
34 * identify a new request state. Handles referring to different request
35 * states MUST be unique within the context of a particular TCP
36 * connection and client-type.
38 * @version COPSPepReqStateMan.java, v 2.00 2004
41 public class COPSPepReqStateMan extends COPSStateMan {
43 private final static Logger logger = LoggerFactory.getLogger(COPSPepReqStateMan.class);
46 The PolicyDataProcess is used to process policy data in the PEP
48 protected final COPSPepDataProcess _process;
51 The Msg Sender is used to send COPS messages
53 private final COPSPepMsgSender _sender;
58 protected transient boolean _syncState;
61 * Constructor for this class
62 * @param clientType - the PEP client type
63 * @param clientHandle - the client-handle
64 * @param process - the data processor
65 * @param socket - the socket connection
67 public COPSPepReqStateMan(final short clientType, final COPSHandle clientHandle, final COPSPepDataProcess process,
68 final Socket socket) {
69 this(clientType, clientHandle, process, socket, new COPSPepMsgSender(clientType, clientHandle, socket));
73 * Constructor for sub-classes
74 * @param clientType - the PEP client type
75 * @param clientHandle - the client-handle
76 * @param process - the data processor
77 * @param socket - the socket connection
78 * @param sender - responsible for sending COPS messages to the PEP
80 protected COPSPepReqStateMan(final short clientType, final COPSHandle clientHandle, final COPSPepDataProcess process,
81 final Socket socket, final COPSPepMsgSender sender) {
83 super(clientType, clientHandle, socket);
84 this._process = process;
86 // Inits an object for sending COPS messages to the PDP
92 * @throws COPSPepException
94 public void initRequestState() throws COPSException {
95 // If an object for retrieving PEP features exists,
96 // use it for retrieving them
97 final Map<String, String> clientSIs;
99 clientSIs = _process.getClientData(this);
101 clientSIs = new HashMap<>();
104 // TODO - do we really want to send when this is empty???
105 _sender.sendRequest(clientSIs);
108 _status = Status.ST_INIT;
112 * Finalize Request State
114 * @throws COPSPepException
117 public void finalizeRequestState() throws COPSException {
118 _sender.sendDeleteRequest();
119 _status = Status.ST_FINAL;
123 * Process the message Decision
124 * @param dMsg a COPSDecisionMsg
125 * @throws COPSPepException
127 protected void processDecision(final COPSDecisionMsg dMsg) throws COPSException {
128 logger.info("Processing decision message - " + dMsg);
129 final Map<COPSContext, Set<COPSDecision>> decisions = dMsg.getDecisions();
131 final Map<String, String> removeDecs = new HashMap<>();
132 final Map<String, String> installDecs = new HashMap<>();
134 for (final Set<COPSDecision> copsDecisions: decisions.values()) {
135 final COPSDecision cmddecision = copsDecisions.iterator().next();
137 switch (cmddecision.getCommand()) {
139 for (final COPSDecision decision : copsDecisions) {
140 final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
141 switch (obj.getSNum()) {
142 case COPSPrObjBase.PR_PRID:
143 prid = obj.getData().str();
145 case COPSPrObjBase.PR_EPD:
146 installDecs.put(prid, obj.getData().str());
154 for (final COPSDecision decision : copsDecisions) {
155 final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
156 switch (obj.getSNum()) {
157 case COPSPrObjBase.PR_PRID:
158 prid = obj.getData().str();
160 case COPSPrObjBase.PR_EPD:
161 removeDecs.put(prid, obj.getData().str());
172 //** Apply decisions to the configuration
173 // TODO - why is this collection never getting populated???
174 final Map<String, String> errorDecs = new HashMap<>();
175 _process.setDecisions(this, removeDecs, installDecs, errorDecs);
176 _status = Status.ST_DECS;
179 if (_process.isFailReport(this)) {
180 logger.info("Sending FAIL report");
181 _sender.sendFailReport(_process.getReportData(this));
183 logger.info("Sending SUCCESS report");
184 _sender.sendSuccessReport(_process.getReportData(this));
186 _status = Status.ST_REPORT;
189 _sender.sendSyncComplete();
191 _status = Status.ST_SYNCALL;
196 * Process the message NewRequestState
197 * @throws COPSPepException
199 protected void processOpenNewRequestState() throws COPSPepException {
200 if (_process != null)
201 _process.newRequestState(this);
203 _status = Status.ST_NEW;
207 * Process the message DeleteRequestState
208 * @param dMsg a COPSDecisionMsg
209 * @throws COPSPepException
211 protected void processDeleteRequestState(final COPSDecisionMsg dMsg) throws COPSPepException {
212 if (_process != null)
213 _process.closeRequestState(this);
215 _status = Status.ST_DEL;
219 * Process the message SycnStateRequest.
220 * The message SycnStateRequest indicates that the remote PDP
221 * wishes the client (which appears in the common header)
222 * to re-send its state.
223 * @param ssMsg a COPSSyncStateMsg
224 * @throws COPSPepException
226 protected void processSyncStateRequest(final COPSSyncStateMsg ssMsg) throws COPSException {
228 // If an object for retrieving PEP features exists,
229 // use it for retrieving them
230 final Map<String, String> clientSIs;
231 if (_process != null)
232 clientSIs = _process.getClientData(this);
234 clientSIs = new HashMap<>();
237 // TODO - do we really want to send the request when the map is empty???
238 _sender.sendRequest(clientSIs);
240 _status = Status.ST_SYNC;
243 public void processClosedConnection(final COPSError error) throws COPSPepException {
244 if (_process != null)
245 _process.notifyClosedConnection(this, error);
247 _status = Status.ST_CCONN;
250 public void processNoKAConnection() throws COPSException {
251 if (_process != null)
252 _process.notifyNoKAliveReceived(this);
254 _status = Status.ST_NOKA;
258 * Creates and sends an accounting report
259 * @throws COPSException
261 public void processAcctReport() throws COPSException {
262 final Map<String, String> report;
263 if (_process != null) report = _process.getAcctData(this);
264 else report = new HashMap<>();
266 // TODO - do we really want to send when the map is empty???
267 _sender.sendAcctReport(report);
269 _status = Status.ST_ACCT;