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.*;
10 import org.umu.cops.stack.COPSHeader.ClientType;
12 import java.net.Socket;
13 import java.util.HashMap;
18 * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)
21 * The client handle is used to identify a unique request state for a
22 * single PEP per client-type. Client handles are chosen by the PEP and
23 * are opaque to the PDP. The PDP simply uses the request handle to
24 * uniquely identify the request state for a particular Client-Type over
25 * a particular TCP connection and generically tie its decisions to a
26 * corresponding request. Client handles are initiated in request
27 * messages and are then used by subsequent request, decision, and
28 * report messages to reference the same request state. When the PEP is
29 * ready to remove a local request state, it will issue a delete message
30 * to the PDP for the corresponding client handle. A handle MUST be
31 * explicitly deleted by the PEP before it can be used by the PEP to
32 * identify a new request state. Handles referring to different request
33 * states MUST be unique within the context of a particular TCP
34 * connection and client-type.
36 * @version COPSPepReqStateMan.java, v 2.00 2004
39 public class COPSPepReqStateMan {
42 * Request State created
44 public final static short ST_CREATE = 1;
48 public final static short ST_INIT = 2;
52 public final static short ST_DECS = 3;
56 public final static short ST_REPORT = 4;
58 * Request State finalized
60 public final static short ST_FINAL = 5;
62 * New Request State solicited
64 public final static short ST_NEW = 6;
66 * Delete Request State solicited
68 public final static short ST_DEL = 7;
70 * SYNC Request received
72 public final static short ST_SYNC = 8;
76 public final static short ST_SYNCALL = 9;
78 * Close Connection received
80 public final static short ST_CCONN = 10;
84 public final static short ST_NOKA = 11;
88 public final static short ST_ACCT = 12;
91 * The client-type identifies the policy client
93 protected ClientType _clientType;
96 * The client handle is used to uniquely identify a particular
97 * PEP's request for a client-type
99 protected COPSHandle _handle;
102 The PolicyDataProcess is used to process policy data in the PEP
104 protected COPSPepDataProcess _process;
107 * State Request State
109 protected short _status;
112 The Msg Sender is used to send COPS messages
114 protected COPSPepMsgSender _sender;
119 protected boolean _syncState;
122 * Create a State Request Manager
124 * @param clientHandle a Client Handle
127 public COPSPepReqStateMan(final ClientType clientType, final String clientHandle) {
128 _handle = new COPSHandle(new COPSData(clientHandle));
129 _clientType = clientType;
135 * Return client handle
137 * @return a COPSHandle
140 public COPSHandle getClientHandle() {
150 public ClientType getClientType() {
155 * Return Request State status
159 public short getStatus() {
164 * Return the Policy Data Process
166 * @return a PolicyConfigure
169 public COPSPepDataProcess getDataProcess() {
174 * Establish the Policy Data Process
176 * @param process a PolicyConfigure
179 public void setDataProcess(COPSPepDataProcess process) {
186 * @throws COPSPepException
189 protected void initRequestState(Socket sock)
190 throws COPSPepException {
191 // Inits an object for sending COPS messages to the PDP
192 _sender = new COPSPepMsgSender(_clientType, _handle, sock);
194 // If an object for retrieving PEP features exists,
195 // use it for retrieving them
196 final Map<String, String> clientSIs;
197 if (_process != null)
198 clientSIs = _process.getClientData(this);
200 clientSIs = new HashMap<>();
203 // TODO - do we really want to send when this is empty???
204 _sender.sendRequest(clientSIs);
211 * Finalize Request State
213 * @throws COPSPepException
216 protected void finalizeRequestState()
217 throws COPSPepException {
218 _sender.sendDeleteRequest();
223 * Process the message Decision
225 * @param dMsg a COPSDecisionMsg
227 * @throws COPSPepException
230 protected void processDecision(COPSDecisionMsg dMsg)
231 throws COPSPepException {
232 // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());
234 // COPSHandle handle = dMsg.getClientHandle();
235 final Map<COPSContext, Set<COPSDecision>> decisions = dMsg.getDecisions();
237 final Map<String, String> removeDecs = new HashMap<>();
238 final Map<String, String> installDecs = new HashMap<>();
240 for (Set<COPSDecision> copsDecisions: decisions.values()) {
241 final COPSDecision cmddecision = copsDecisions.iterator().next();
243 switch (cmddecision.getCommand()) {
245 for (final COPSDecision decision : copsDecisions) {
246 final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
247 switch (obj.getSNum()) {
248 case COPSPrObjBase.PR_PRID:
249 prid = obj.getData().str();
251 case COPSPrObjBase.PR_EPD:
252 installDecs.put(prid, obj.getData().str());
260 for (final COPSDecision decision : copsDecisions) {
261 final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
262 switch (obj.getSNum()) {
263 case COPSPrObjBase.PR_PRID:
264 prid = obj.getData().str();
266 case COPSPrObjBase.PR_EPD:
267 removeDecs.put(prid, obj.getData().str());
278 //** Apply decisions to the configuration
279 // TODO - why is this collection never getting populated???
280 final Map<String, String> errorDecs = new HashMap<>();
281 _process.setDecisions(this, removeDecs, installDecs, errorDecs);
285 if (_process.isFailReport(this)) {
286 // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");
287 _sender.sendFailReport(_process.getReportData(this));
289 // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");
290 _sender.sendSuccessReport(_process.getReportData(this));
295 _sender.sendSyncComplete();
297 _status = ST_SYNCALL;
302 * Process the message NewRequestState
304 * @throws COPSPepException
307 protected void processOpenNewRequestState()
308 throws COPSPepException {
310 if (_process != null)
311 _process.newRequestState(this);
317 * Process the message DeleteRequestState
319 * @param dMsg a COPSDecisionMsg
321 * @throws COPSPepException
324 protected void processDeleteRequestState(COPSDecisionMsg dMsg)
325 throws COPSPepException {
326 if (_process != null)
327 _process.closeRequestState(this);
333 * Process the message SycnStateRequest.
334 * The message SycnStateRequest indicates that the remote PDP
335 * wishes the client (which appears in the common header)
336 * to re-send its state.
338 * @param ssMsg a COPSSyncStateMsg
340 * @throws COPSPepException
343 protected void processSyncStateRequest(COPSSyncStateMsg ssMsg)
344 throws COPSPepException {
346 // If an object for retrieving PEP features exists,
347 // use it for retrieving them
348 final Map<String, String> clientSIs;
349 if (_process != null)
350 clientSIs = _process.getClientData(this);
352 clientSIs = new HashMap<>();
355 // TODO - do we really want to send the request when the map is empty???
356 _sender.sendRequest(clientSIs);
361 protected void processClosedConnection(COPSError error)
362 throws COPSPepException {
363 if (_process != null)
364 _process.notifyClosedConnection(this, error);
369 protected void processNoKAConnection()
370 throws COPSPepException {
371 if (_process != null)
372 _process.notifyNoKAliveReceived(this);
377 protected void processAcctReport()
378 throws COPSPepException {
380 final Map<String, String> report;
381 if (_process != null) report = _process.getAcctData(this);
382 else report = new HashMap<>();
384 // TODO - do we really want to send when the map is empty???
385 _sender.sendAcctReport(report);