Merge "The second patch of an estimated 4 to complete the COPS message refactoring...
[packetcable.git] / packetcable-driver / src / main / java / org / umu / cops / prpep / COPSPepReqStateMan.java
1 /*
2  * Copyright (c) 2004 University of Murcia.  All rights reserved.
3  * --------------------------------------------------------------
4  * For more information, please see <http://www.umu.euro6ix.org/>.
5  */
6
7 package org.umu.cops.prpep;
8
9 import org.umu.cops.stack.*;
10 import org.umu.cops.stack.COPSDecision.Command;
11
12 import java.net.Socket;
13 import java.util.Enumeration;
14 import java.util.Hashtable;
15 import java.util.Vector;
16
17 /**
18  * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)
19  * in PEP.
20  *
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.
35  *
36  * @version COPSPepReqStateMan.java, v 2.00 2004
37  *
38  */
39 public class COPSPepReqStateMan {
40
41     /**
42      * Request State created
43      */
44     public final static short ST_CREATE = 1;
45     /**
46      * Request sent
47      */
48     public final static short ST_INIT = 2;
49     /**
50      * Decisions received
51      */
52     public final static short ST_DECS = 3;
53     /**
54      * Report sent
55      */
56     public final static short ST_REPORT = 4;
57     /**
58      * Request State finalized
59      */
60     public final static short ST_FINAL = 5;
61     /**
62      * New Request State solicited
63      */
64     public final static short ST_NEW = 6;
65     /**
66      * Delete Request State solicited
67      */
68     public final static short ST_DEL = 7;
69     /**
70      * SYNC Request received
71      */
72     public final static short ST_SYNC = 8;
73     /**
74      * SYNC Completed
75      */
76     public final static short ST_SYNCALL = 9;
77     /**
78      * Close Connection received
79      */
80     public final static short ST_CCONN = 10;
81     /**
82      * KAlive Time out
83      */
84     public final static short ST_NOKA = 11;
85     /**
86      * ACCT Time out
87      */
88     public final static short ST_ACCT = 12;
89
90     /**
91      * The client-type identifies the policy client
92      */
93     protected short _clientType;
94
95     /**
96      *  The client handle is used to uniquely identify a particular
97      *  PEP's request for a client-type
98      */
99     protected COPSHandle _handle;
100
101     /**
102         The PolicyDataProcess is used to process policy data in the PEP
103      */
104     protected COPSPepDataProcess _process;
105
106     /**
107      *  State Request State
108      */
109     protected short _status;
110
111     /**
112         The Msg Sender is used to send COPS messages
113      */
114     protected COPSPepMsgSender _sender;
115
116     /**
117      * Sync State
118      */
119     protected boolean _syncState;
120
121     /**
122      * Create a State Request Manager
123      *
124      * @param    clientHandle                a Client Handle
125      *
126      */
127     public COPSPepReqStateMan(short clientType, String clientHandle) {
128         _handle = new COPSHandle(new COPSData(clientHandle));
129         _clientType = clientType;
130         _syncState = true;
131         _status = ST_CREATE;
132     }
133
134     /**
135      * Return client handle
136      *
137      * @return   a COPSHandle
138      *
139      */
140     public COPSHandle getClientHandle() {
141         return _handle;
142     }
143
144     /**
145      * Return client-type
146      *
147      * @return   a short
148      *
149      */
150     public short getClientType() {
151         return _clientType;
152     }
153
154     /**
155      * Return Request State status
156      *
157      * @return      s short
158      */
159     public short getStatus() {
160         return _status;
161     }
162
163     /**
164      * Return the Policy Data Process
165      *
166      * @return   a PolicyConfigure
167      *
168      */
169     public COPSPepDataProcess getDataProcess() {
170         return _process;
171     }
172
173     /**
174      * Establish the Policy Data Process
175      *
176      * @param    process              a  PolicyConfigure
177      *
178      */
179     public void setDataProcess(COPSPepDataProcess process) {
180         _process = process;
181     }
182
183     /**
184      * Init Request State
185      *
186      * @throws   COPSPepException
187      *
188      */
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);
193
194         // If an object for retrieving PEP features exists,
195         // use it for retrieving them
196         Hashtable clientSIs;
197         if (_process != null)
198             clientSIs = _process.getClientData(this);
199         else
200             clientSIs = null;
201
202         // Send the request
203         _sender.sendRequest(clientSIs);
204
205         // Initial state
206         _status = ST_INIT;
207     }
208
209     /**
210      * Finalize Request State
211      *
212      * @throws   COPSPepException
213      *
214      */
215     protected void finalizeRequestState()
216     throws COPSPepException {
217         _sender.sendDeleteRequest();
218         _status = ST_FINAL;
219     }
220
221     /**
222      * Process the message Decision
223      *
224      * @param    dMsg                a  COPSDecisionMsg
225      *
226      * @throws   COPSPepException
227      *
228      */
229     protected void processDecision(COPSDecisionMsg dMsg)
230     throws COPSPepException {
231         // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());
232
233         // COPSHandle handle = dMsg.getClientHandle();
234         Hashtable decisions = dMsg.getDecisions();
235
236         Hashtable removeDecs = new Hashtable(40);
237         Hashtable installDecs = new Hashtable(40);
238         Hashtable errorDecs = new Hashtable(40);
239         for (Enumeration e = decisions.keys() ; e.hasMoreElements() ;) {
240
241             COPSContext context = (COPSContext) e.nextElement();
242             Vector v = (Vector) decisions.get(context);
243             Enumeration ee = v.elements();
244             COPSDecision cmddecision = (COPSDecision) ee.nextElement();
245
246             // cmddecision --> we must check whether it is an error!
247
248             if (cmddecision.getCommand().equals(Command.INSTALL)) {
249                 String prid = "";
250                 for (; ee.hasMoreElements() ;) {
251                     COPSDecision decision = (COPSDecision) ee.nextElement();
252
253                     COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
254                     switch (obj.getSNum()) {
255                     case COPSPrObjBase.PR_PRID:
256                         prid = obj.getData().str();
257                         break;
258                     case COPSPrObjBase.PR_EPD:
259                         installDecs.put(prid, obj.getData().str());
260                         break;
261                     default:
262                         break;
263                     }
264                 }
265             }
266
267             if (cmddecision.getCommand().equals(Command.REMOVE)) {
268
269                 String prid = "";
270                 for (; ee.hasMoreElements() ;) {
271                     COPSDecision decision = (COPSDecision) ee.nextElement();
272
273                     COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
274                     switch (obj.getSNum()) {
275                     case COPSPrObjBase.PR_PRID:
276                         prid = obj.getData().str();
277                         break;
278                     case COPSPrObjBase.PR_EPD:
279                         removeDecs.put(prid, obj.getData().str());
280                         break;
281                     default:
282                         break;
283                     }
284                 }
285             }
286         }
287
288         //** Apply decisions to the configuration
289         _process.setDecisions(this, removeDecs, installDecs, errorDecs);
290         _status = ST_DECS;
291
292
293         if (_process.isFailReport(this)) {
294             // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");
295             _sender.sendFailReport(_process.getReportData(this));
296         } else {
297             // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");
298             _sender.sendSuccessReport(_process.getReportData(this));
299         }
300         _status = ST_REPORT;
301
302         if (!_syncState) {
303             _sender.sendSyncComplete();
304             _syncState = true;
305             _status = ST_SYNCALL;
306         }
307     }
308
309     /**
310      * Process the message NewRequestState
311      *
312      * @throws   COPSPepException
313      *
314      */
315     protected void processOpenNewRequestState()
316     throws COPSPepException {
317
318         if (_process != null)
319             _process.newRequestState(this);
320
321         _status = ST_NEW;
322     }
323
324     /**
325      * Process the message DeleteRequestState
326      *
327      * @param    dMsg                a  COPSDecisionMsg
328      *
329      * @throws   COPSPepException
330      *
331      */
332     protected void processDeleteRequestState(COPSDecisionMsg dMsg)
333     throws COPSPepException {
334         if (_process != null)
335             _process.closeRequestState(this);
336
337         _status = ST_DEL;
338     }
339
340     /**
341      * Process the message SycnStateRequest.
342      * The message SycnStateRequest indicates that the remote PDP
343      * wishes the client (which appears in the common header)
344      * to re-send its state.
345      *
346      * @param    ssMsg               a  COPSSyncStateMsg
347      *
348      * @throws   COPSPepException
349      *
350      */
351     protected void processSyncStateRequest(COPSSyncStateMsg ssMsg)
352     throws COPSPepException {
353         _syncState = false;
354         // If an object for retrieving PEP features exists,
355         // use it for retrieving them
356         Hashtable clientSIs;
357         if (_process != null)
358             clientSIs = _process.getClientData(this);
359         else
360             clientSIs = null;
361
362         // Send request
363         _sender.sendRequest(clientSIs);
364
365         _status = ST_SYNC;
366     }
367
368     protected void processClosedConnection(COPSError error)
369     throws COPSPepException {
370         if (_process != null)
371             _process.notifyClosedConnection(this, error);
372
373         _status = ST_CCONN;
374     }
375
376     protected void processNoKAConnection()
377     throws COPSPepException {
378         if (_process != null)
379             _process.notifyNoKAliveReceived(this);
380
381         _status = ST_NOKA;
382     }
383
384     protected void processAcctReport()
385     throws COPSPepException {
386
387         Hashtable report = new Hashtable();
388         if (_process != null)
389             report = _process.getAcctData(this);
390
391         _sender.sendAcctReport(report);
392
393         _status = ST_ACCT;
394     }
395
396 }