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 org.umu.cops.stack.*;
\r
11 import java.net.Socket;
\r
12 import java.util.Enumeration;
\r
13 import java.util.Hashtable;
\r
14 import java.util.Vector;
\r
17 * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)
\r
20 * The client handle is used to identify a unique request state for a
\r
21 * single PEP per client-type. Client handles are chosen by the PEP and
\r
22 * are opaque to the PDP. The PDP simply uses the request handle to
\r
23 * uniquely identify the request state for a particular Client-Type over
\r
24 * a particular TCP connection and generically tie its decisions to a
\r
25 * corresponding request. Client handles are initiated in request
\r
26 * messages and are then used by subsequent request, decision, and
\r
27 * report messages to reference the same request state. When the PEP is
\r
28 * ready to remove a local request state, it will issue a delete message
\r
29 * to the PDP for the corresponding client handle. A handle MUST be
\r
30 * explicitly deleted by the PEP before it can be used by the PEP to
\r
31 * identify a new request state. Handles referring to different request
\r
32 * states MUST be unique within the context of a particular TCP
\r
33 * connection and client-type.
\r
35 * @version COPSPepReqStateMan.java, v 2.00 2004
\r
38 public class COPSPepReqStateMan {
\r
41 * Request State created
\r
43 public final static short ST_CREATE = 1;
\r
47 public final static short ST_INIT = 2;
\r
49 * Decisions received
\r
51 public final static short ST_DECS = 3;
\r
55 public final static short ST_REPORT = 4;
\r
57 * Request State finalized
\r
59 public final static short ST_FINAL = 5;
\r
61 * New Request State solicited
\r
63 public final static short ST_NEW = 6;
\r
65 * Delete Request State solicited
\r
67 public final static short ST_DEL = 7;
\r
69 * SYNC Request received
\r
71 public final static short ST_SYNC = 8;
\r
75 public final static short ST_SYNCALL = 9;
\r
77 * Close Connection received
\r
79 public final static short ST_CCONN = 10;
\r
83 public final static short ST_NOKA = 11;
\r
87 public final static short ST_ACCT = 12;
\r
90 * The client-type identifies the policy client
\r
92 protected short _clientType;
\r
95 * The client handle is used to uniquely identify a particular
\r
96 * PEP's request for a client-type
\r
98 protected COPSHandle _handle;
\r
101 The PolicyDataProcess is used to process policy data in the PEP
\r
103 protected COPSPepDataProcess _process;
\r
106 * State Request State
\r
108 protected short _status;
\r
111 The Msg Sender is used to send COPS messages
\r
113 protected COPSPepMsgSender _sender;
\r
118 protected boolean _syncState;
\r
121 * Create a State Request Manager
\r
123 * @param clientHandle a Client Handle
\r
126 public COPSPepReqStateMan(short clientType, String clientHandle) {
\r
127 _handle = new COPSHandle(new COPSData(clientHandle));
\r
128 _clientType = clientType;
\r
130 _status = ST_CREATE;
\r
134 * Return client handle
\r
136 * @return a COPSHandle
\r
139 public COPSHandle getClientHandle() {
\r
144 * Return client-type
\r
149 public short getClientType() {
\r
150 return _clientType;
\r
154 * Return Request State status
\r
158 public short getStatus() {
\r
163 * Return the Policy Data Process
\r
165 * @return a PolicyConfigure
\r
168 public COPSPepDataProcess getDataProcess() {
\r
173 * Establish the Policy Data Process
\r
175 * @param process a PolicyConfigure
\r
178 public void setDataProcess(COPSPepDataProcess process) {
\r
179 _process = process;
\r
183 * Init Request State
\r
185 * @throws COPSPepException
\r
188 protected void initRequestState(Socket sock)
\r
189 throws COPSPepException {
\r
190 // Inits an object for sending COPS messages to the PDP
\r
191 _sender = new COPSPepMsgSender(_clientType, _handle, sock);
\r
193 // If an object for retrieving PEP features exists,
\r
194 // use it for retrieving them
\r
195 Hashtable clientSIs;
\r
196 if (_process != null)
\r
197 clientSIs = _process.getClientData(this);
\r
201 // Send the request
\r
202 _sender.sendRequest(clientSIs);
\r
209 * Finalize Request State
\r
211 * @throws COPSPepException
\r
214 protected void finalizeRequestState()
\r
215 throws COPSPepException {
\r
216 _sender.sendDeleteRequest();
\r
217 _status = ST_FINAL;
\r
221 * Process the message Decision
\r
223 * @param dMsg a COPSDecisionMsg
\r
225 * @throws COPSPepException
\r
228 protected void processDecision(COPSDecisionMsg dMsg)
\r
229 throws COPSPepException {
\r
230 // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());
\r
232 // COPSHandle handle = dMsg.getClientHandle();
\r
233 Hashtable decisions = dMsg.getDecisions();
\r
235 Hashtable removeDecs = new Hashtable(40);
\r
236 Hashtable installDecs = new Hashtable(40);
\r
237 Hashtable errorDecs = new Hashtable(40);
\r
238 for (Enumeration e = decisions.keys() ; e.hasMoreElements() ;) {
\r
240 COPSContext context = (COPSContext) e.nextElement();
\r
241 Vector v = (Vector) decisions.get(context);
\r
242 Enumeration ee = v.elements();
\r
243 COPSDecision cmddecision = (COPSDecision) ee.nextElement();
\r
245 // cmddecision --> we must check whether it is an error!
\r
247 if (cmddecision.isInstallDecision()) {
\r
248 String prid = new String();
\r
249 for (; ee.hasMoreElements() ;) {
\r
250 COPSDecision decision = (COPSDecision) ee.nextElement();
\r
252 COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
\r
253 switch (obj.getSNum()) {
\r
254 case COPSPrObjBase.PR_PRID:
\r
255 prid = obj.getData().str();
\r
257 case COPSPrObjBase.PR_EPD:
\r
258 installDecs.put(prid, obj.getData().str());
\r
266 if (cmddecision.isRemoveDecision()) {
\r
268 String prid = new String();
\r
269 for (; ee.hasMoreElements() ;) {
\r
270 COPSDecision decision = (COPSDecision) ee.nextElement();
\r
272 COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
\r
273 switch (obj.getSNum()) {
\r
274 case COPSPrObjBase.PR_PRID:
\r
275 prid = obj.getData().str();
\r
277 case COPSPrObjBase.PR_EPD:
\r
278 removeDecs.put(prid, obj.getData().str());
\r
287 //** Apply decisions to the configuration
\r
288 _process.setDecisions(this, removeDecs, installDecs, errorDecs);
\r
292 if (_process.isFailReport(this)) {
\r
293 // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");
\r
294 _sender.sendFailReport(_process.getReportData(this));
\r
296 // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");
\r
297 _sender.sendSuccessReport(_process.getReportData(this));
\r
299 _status = ST_REPORT;
\r
302 _sender.sendSyncComplete();
\r
304 _status = ST_SYNCALL;
\r
309 * Process the message NewRequestState
\r
311 * @throws COPSPepException
\r
314 protected void processOpenNewRequestState()
\r
315 throws COPSPepException {
\r
317 if (_process != null)
\r
318 _process.newRequestState(this);
\r
324 * Process the message DeleteRequestState
\r
326 * @param dMsg a COPSDecisionMsg
\r
328 * @throws COPSPepException
\r
331 protected void processDeleteRequestState(COPSDecisionMsg dMsg)
\r
332 throws COPSPepException {
\r
333 if (_process != null)
\r
334 _process.closeRequestState(this);
\r
340 * Process the message SycnStateRequest.
\r
341 * The message SycnStateRequest indicates that the remote PDP
\r
342 * wishes the client (which appears in the common header)
\r
343 * to re-send its state.
\r
345 * @param ssMsg a COPSSyncStateMsg
\r
347 * @throws COPSPepException
\r
350 protected void processSyncStateRequest(COPSSyncStateMsg ssMsg)
\r
351 throws COPSPepException {
\r
352 _syncState = false;
\r
353 // If an object for retrieving PEP features exists,
\r
354 // use it for retrieving them
\r
355 Hashtable clientSIs;
\r
356 if (_process != null)
\r
357 clientSIs = _process.getClientData(this);
\r
362 _sender.sendRequest(clientSIs);
\r
367 protected void processClosedConnection(COPSError error)
\r
368 throws COPSPepException {
\r
369 if (_process != null)
\r
370 _process.notifyClosedConnection(this, error);
\r
372 _status = ST_CCONN;
\r
375 protected void processNoKAConnection()
\r
376 throws COPSPepException {
\r
377 if (_process != null)
\r
378 _process.notifyNoKAliveReceived(this);
\r
383 protected void processAcctReport()
\r
384 throws COPSPepException {
\r
386 Hashtable report = new Hashtable();
\r
387 if (_process != null)
\r
388 report = _process.getAcctData(this);
\r
390 _sender.sendAcctReport(report);
\r