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