2 * Copyright (c) 2004 University of Murcia. All rights reserved.
\r
3 * --------------------------------------------------------------
\r
4 * For more information, please see <http://www.umu.euro6ix.org/>.
\r
7 package org.umu.cops.prpep;
\r
9 import java.net.Socket;
\r
10 import java.util.Enumeration;
\r
11 import java.util.Hashtable;
\r
12 import java.util.Vector;
\r
14 import org.umu.cops.stack.COPSContext;
\r
15 import org.umu.cops.stack.COPSData;
\r
16 import org.umu.cops.stack.COPSDecision;
\r
17 import org.umu.cops.stack.COPSDecisionMsg;
\r
18 import org.umu.cops.stack.COPSError;
\r
19 import org.umu.cops.stack.COPSHandle;
\r
20 import org.umu.cops.stack.COPSPrObjBase;
\r
21 import org.umu.cops.stack.COPSSyncStateMsg;
\r
24 * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)
\r
27 * The client handle is used to identify a unique request state for a
\r
28 * single PEP per client-type. Client handles are chosen by the PEP and
\r
29 * are opaque to the PDP. The PDP simply uses the request handle to
\r
30 * uniquely identify the request state for a particular Client-Type over
\r
31 * a particular TCP connection and generically tie its decisions to a
\r
32 * corresponding request. Client handles are initiated in request
\r
33 * messages and are then used by subsequent request, decision, and
\r
34 * report messages to reference the same request state. When the PEP is
\r
35 * ready to remove a local request state, it will issue a delete message
\r
36 * to the PDP for the corresponding client handle. A handle MUST be
\r
37 * explicitly deleted by the PEP before it can be used by the PEP to
\r
38 * identify a new request state. Handles referring to different request
\r
39 * states MUST be unique within the context of a particular TCP
\r
40 * connection and client-type.
\r
42 * @version COPSPepReqStateMan.java, v 2.00 2004
\r
45 public class COPSPepReqStateMan {
\r
48 * Request State created
\r
50 public final static short ST_CREATE = 1;
\r
54 public final static short ST_INIT = 2;
\r
56 * Decisions received
\r
58 public final static short ST_DECS = 3;
\r
62 public final static short ST_REPORT = 4;
\r
64 * Request State finalized
\r
66 public final static short ST_FINAL = 5;
\r
68 * New Request State solicited
\r
70 public final static short ST_NEW = 6;
\r
72 * Delete Request State solicited
\r
74 public final static short ST_DEL = 7;
\r
76 * SYNC Request received
\r
78 public final static short ST_SYNC = 8;
\r
82 public final static short ST_SYNCALL = 9;
\r
84 * Close Connection received
\r
86 public final static short ST_CCONN = 10;
\r
90 public final static short ST_NOKA = 11;
\r
94 public final static short ST_ACCT = 12;
\r
97 * The client-type identifies the policy client
\r
99 protected short _clientType;
\r
102 * The client handle is used to uniquely identify a particular
\r
103 * PEP's request for a client-type
\r
105 protected COPSHandle _handle;
\r
108 The PolicyDataProcess is used to process policy data in the PEP
\r
110 protected COPSPepDataProcess _process;
\r
113 * State Request State
\r
115 protected short _status;
\r
118 The Msg Sender is used to send COPS messages
\r
120 protected COPSPepMsgSender _sender;
\r
125 protected boolean _syncState;
\r
128 * Create a State Request Manager
\r
130 * @param clientHandle a Client Handle
\r
133 public COPSPepReqStateMan(short clientType, String clientHandle) {
\r
135 _handle = new COPSHandle();
\r
136 COPSData id = new COPSData(clientHandle);
\r
139 _clientType = clientType;
\r
141 _status = ST_CREATE;
\r
145 * Return client handle
\r
147 * @return a COPSHandle
\r
150 public COPSHandle getClientHandle() {
\r
155 * Return client-type
\r
160 public short getClientType() {
\r
161 return _clientType;
\r
165 * Return Request State status
\r
169 public short getStatus() {
\r
174 * Return the Policy Data Process
\r
176 * @return a PolicyConfigure
\r
179 public COPSPepDataProcess getDataProcess() {
\r
184 * Establish the Policy Data Process
\r
186 * @param process a PolicyConfigure
\r
189 public void setDataProcess(COPSPepDataProcess process) {
\r
190 _process = process;
\r
194 * Init Request State
\r
196 * @throws COPSPepException
\r
199 protected void initRequestState(Socket sock)
\r
200 throws COPSPepException {
\r
201 // Inits an object for sending COPS messages to the PDP
\r
202 _sender = new COPSPepMsgSender(_clientType, _handle, sock);
\r
204 // If an object for retrieving PEP features exists,
\r
205 // use it for retrieving them
\r
206 Hashtable clientSIs;
\r
207 if (_process != null)
\r
208 clientSIs = _process.getClientData(this);
\r
212 // Send the request
\r
213 _sender.sendRequest(clientSIs);
\r
220 * Finalize Request State
\r
222 * @throws COPSPepException
\r
225 protected void finalizeRequestState()
\r
226 throws COPSPepException {
\r
227 _sender.sendDeleteRequest();
\r
228 _status = ST_FINAL;
\r
232 * Process the message Decision
\r
234 * @param dMsg a COPSDecisionMsg
\r
236 * @throws COPSPepException
\r
239 protected void processDecision(COPSDecisionMsg dMsg)
\r
240 throws COPSPepException {
\r
241 // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());
\r
243 // COPSHandle handle = dMsg.getClientHandle();
\r
244 Hashtable decisions = dMsg.getDecisions();
\r
246 Hashtable removeDecs = new Hashtable(40);
\r
247 Hashtable installDecs = new Hashtable(40);
\r
248 Hashtable errorDecs = new Hashtable(40);
\r
249 for (Enumeration e = decisions.keys() ; e.hasMoreElements() ;) {
\r
251 COPSContext context = (COPSContext) e.nextElement();
\r
252 Vector v = (Vector) decisions.get(context);
\r
253 Enumeration ee = v.elements();
\r
254 COPSDecision cmddecision = (COPSDecision) ee.nextElement();
\r
256 // cmddecision --> we must check whether it is an error!
\r
258 if (cmddecision.isInstallDecision()) {
\r
259 String prid = new String();
\r
260 for (; ee.hasMoreElements() ;) {
\r
261 COPSDecision decision = (COPSDecision) ee.nextElement();
\r
263 COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
\r
264 switch (obj.getSNum()) {
\r
265 case COPSPrObjBase.PR_PRID:
\r
266 prid = obj.getData().str();
\r
268 case COPSPrObjBase.PR_EPD:
\r
269 installDecs.put(prid, obj.getData().str());
\r
277 if (cmddecision.isRemoveDecision()) {
\r
279 String prid = new String();
\r
280 for (; ee.hasMoreElements() ;) {
\r
281 COPSDecision decision = (COPSDecision) ee.nextElement();
\r
283 COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
\r
284 switch (obj.getSNum()) {
\r
285 case COPSPrObjBase.PR_PRID:
\r
286 prid = obj.getData().str();
\r
288 case COPSPrObjBase.PR_EPD:
\r
289 removeDecs.put(prid, obj.getData().str());
\r
298 //** Apply decisions to the configuration
\r
299 _process.setDecisions(this, removeDecs, installDecs, errorDecs);
\r
303 if (_process.isFailReport(this)) {
\r
304 // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");
\r
305 _sender.sendFailReport(_process.getReportData(this));
\r
307 // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");
\r
308 _sender.sendSuccessReport(_process.getReportData(this));
\r
310 _status = ST_REPORT;
\r
313 _sender.sendSyncComplete();
\r
315 _status = ST_SYNCALL;
\r
320 * Process the message NewRequestState
\r
322 * @throws COPSPepException
\r
325 protected void processOpenNewRequestState()
\r
326 throws COPSPepException {
\r
328 if (_process != null)
\r
329 _process.newRequestState(this);
\r
335 * Process the message DeleteRequestState
\r
337 * @param dMsg a COPSDecisionMsg
\r
339 * @throws COPSPepException
\r
342 protected void processDeleteRequestState(COPSDecisionMsg dMsg)
\r
343 throws COPSPepException {
\r
344 if (_process != null)
\r
345 _process.closeRequestState(this);
\r
351 * Process the message SycnStateRequest.
\r
352 * The message SycnStateRequest indicates that the remote PDP
\r
353 * wishes the client (which appears in the common header)
\r
354 * to re-send its state.
\r
356 * @param ssMsg a COPSSyncStateMsg
\r
358 * @throws COPSPepException
\r
361 protected void processSyncStateRequest(COPSSyncStateMsg ssMsg)
\r
362 throws COPSPepException {
\r
363 _syncState = false;
\r
364 // If an object for retrieving PEP features exists,
\r
365 // use it for retrieving them
\r
366 Hashtable clientSIs;
\r
367 if (_process != null)
\r
368 clientSIs = _process.getClientData(this);
\r
373 _sender.sendRequest(clientSIs);
\r
378 protected void processClosedConnection(COPSError error)
\r
379 throws COPSPepException {
\r
380 if (_process != null)
\r
381 _process.notifyClosedConnection(this, error);
\r
383 _status = ST_CCONN;
\r
386 protected void processNoKAConnection()
\r
387 throws COPSPepException {
\r
388 if (_process != null)
\r
389 _process.notifyNoKAliveReceived(this);
\r
394 protected void processAcctReport()
\r
395 throws COPSPepException {
\r
397 Hashtable report = new Hashtable();
\r
398 if (_process != null)
\r
399 report = _process.getAcctData(this);
\r
401 _sender.sendAcctReport(report);
\r