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.umu.cops.stack.*;
11 import java.net.Socket;
12 import java.util.HashMap;
17 * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)
20 * The client handle is used to identify a unique request state for a
21 * single PEP per client-type. Client handles are chosen by the PEP and
22 * are opaque to the PDP. The PDP simply uses the request handle to
23 * uniquely identify the request state for a particular Client-Type over
24 * a particular TCP connection and generically tie its decisions to a
25 * corresponding request. Client handles are initiated in request
26 * messages and are then used by subsequent request, decision, and
27 * report messages to reference the same request state. When the PEP is
28 * ready to remove a local request state, it will issue a delete message
29 * to the PDP for the corresponding client handle. A handle MUST be
30 * explicitly deleted by the PEP before it can be used by the PEP to
31 * identify a new request state. Handles referring to different request
32 * states MUST be unique within the context of a particular TCP
33 * connection and client-type.
35 * @version COPSPepReqStateMan.java, v 2.00 2004
38 public class COPSPepReqStateMan {
41 * Request State created
43 public final static short ST_CREATE = 1;
47 public final static short ST_INIT = 2;
51 public final static short ST_DECS = 3;
55 public final static short ST_REPORT = 4;
57 * Request State finalized
59 public final static short ST_FINAL = 5;
61 * New Request State solicited
63 public final static short ST_NEW = 6;
65 * Delete Request State solicited
67 public final static short ST_DEL = 7;
69 * SYNC Request received
71 public final static short ST_SYNC = 8;
75 public final static short ST_SYNCALL = 9;
77 * Close Connection received
79 public final static short ST_CCONN = 10;
83 public final static short ST_NOKA = 11;
87 public final static short ST_ACCT = 12;
90 * The client-type identifies the policy client
92 protected short _clientType;
95 * The client handle is used to uniquely identify a particular
96 * PEP's request for a client-type
98 protected COPSHandle _handle;
101 The PolicyDataProcess is used to process policy data in the PEP
103 protected COPSPepDataProcess _process;
106 * State Request State
108 protected short _status;
111 The Msg Sender is used to send COPS messages
113 protected COPSPepMsgSender _sender;
118 protected boolean _syncState;
121 * Create a State Request Manager
123 * @param clientHandle a Client Handle
126 public COPSPepReqStateMan(final short clientType, final String clientHandle) {
127 _handle = new COPSHandle(new COPSData(clientHandle));
128 _clientType = clientType;
134 * Return client handle
136 * @return a COPSHandle
139 public COPSHandle getClientHandle() {
149 public int getClientType() {
154 * Return Request State status
158 public short getStatus() {
163 * Return the Policy Data Process
165 * @return a PolicyConfigure
168 public COPSPepDataProcess getDataProcess() {
173 * Establish the Policy Data Process
175 * @param process a PolicyConfigure
178 public void setDataProcess(COPSPepDataProcess process) {
185 * @throws COPSPepException
188 protected void initRequestState(Socket sock)
189 throws COPSPepException {
190 // Inits an object for sending COPS messages to the PDP
191 _sender = new COPSPepMsgSender(_clientType, _handle, sock);
193 // If an object for retrieving PEP features exists,
194 // use it for retrieving them
195 final Map<String, String> clientSIs;
196 if (_process != null)
197 clientSIs = _process.getClientData(this);
199 clientSIs = new HashMap<>();
202 // TODO - do we really want to send when this is empty???
203 _sender.sendRequest(clientSIs);
210 * Finalize Request State
212 * @throws COPSPepException
215 protected void finalizeRequestState()
216 throws COPSPepException {
217 _sender.sendDeleteRequest();
222 * Process the message Decision
224 * @param dMsg a COPSDecisionMsg
226 * @throws COPSPepException
229 protected void processDecision(COPSDecisionMsg dMsg)
230 throws COPSPepException {
231 // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());
233 // COPSHandle handle = dMsg.getClientHandle();
234 final Map<COPSContext, Set<COPSDecision>> decisions = dMsg.getDecisions();
236 final Map<String, String> removeDecs = new HashMap<>();
237 final Map<String, String> installDecs = new HashMap<>();
239 for (Set<COPSDecision> copsDecisions: decisions.values()) {
240 final COPSDecision cmddecision = copsDecisions.iterator().next();
242 switch (cmddecision.getCommand()) {
244 for (final COPSDecision decision : copsDecisions) {
245 final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
246 switch (obj.getSNum()) {
247 case COPSPrObjBase.PR_PRID:
248 prid = obj.getData().str();
250 case COPSPrObjBase.PR_EPD:
251 installDecs.put(prid, obj.getData().str());
259 for (final COPSDecision decision : copsDecisions) {
260 final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
261 switch (obj.getSNum()) {
262 case COPSPrObjBase.PR_PRID:
263 prid = obj.getData().str();
265 case COPSPrObjBase.PR_EPD:
266 removeDecs.put(prid, obj.getData().str());
277 //** Apply decisions to the configuration
278 // TODO - why is this collection never getting populated???
279 final Map<String, String> errorDecs = new HashMap<>();
280 _process.setDecisions(this, removeDecs, installDecs, errorDecs);
284 if (_process.isFailReport(this)) {
285 // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");
286 _sender.sendFailReport(_process.getReportData(this));
288 // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");
289 _sender.sendSuccessReport(_process.getReportData(this));
294 _sender.sendSyncComplete();
296 _status = ST_SYNCALL;
301 * Process the message NewRequestState
303 * @throws COPSPepException
306 protected void processOpenNewRequestState()
307 throws COPSPepException {
309 if (_process != null)
310 _process.newRequestState(this);
316 * Process the message DeleteRequestState
318 * @param dMsg a COPSDecisionMsg
320 * @throws COPSPepException
323 protected void processDeleteRequestState(COPSDecisionMsg dMsg)
324 throws COPSPepException {
325 if (_process != null)
326 _process.closeRequestState(this);
332 * Process the message SycnStateRequest.
333 * The message SycnStateRequest indicates that the remote PDP
334 * wishes the client (which appears in the common header)
335 * to re-send its state.
337 * @param ssMsg a COPSSyncStateMsg
339 * @throws COPSPepException
342 protected void processSyncStateRequest(COPSSyncStateMsg ssMsg)
343 throws COPSPepException {
345 // If an object for retrieving PEP features exists,
346 // use it for retrieving them
347 final Map<String, String> clientSIs;
348 if (_process != null)
349 clientSIs = _process.getClientData(this);
351 clientSIs = new HashMap<>();
354 // TODO - do we really want to send the request when the map is empty???
355 _sender.sendRequest(clientSIs);
360 protected void processClosedConnection(COPSError error)
361 throws COPSPepException {
362 if (_process != null)
363 _process.notifyClosedConnection(this, error);
368 protected void processNoKAConnection()
369 throws COPSPepException {
370 if (_process != null)
371 _process.notifyNoKAliveReceived(this);
376 protected void processAcctReport()
377 throws COPSPepException {
379 final Map<String, String> report;
380 if (_process != null) report = _process.getAcctData(this);
381 else report = new HashMap<>();
383 // TODO - do we really want to send when the map is empty???
384 _sender.sendAcctReport(report);