Merge "Copyright"
[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
11 import java.net.Socket;
12 import java.util.HashMap;
13 import java.util.Map;
14 import java.util.Set;
15
16 /**
17  * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)
18  * in PEP.
19  *
20  *   The client handle is used to identify a unique request state for a
21  *   single PEP per client-type. Client handles are chosen by the PEP and
22  *   are opaque to the PDP. The PDP simply uses the request handle to
23  *   uniquely identify the request state for a particular Client-Type over
24  *   a particular TCP connection and generically tie its decisions to a
25  *   corresponding request. Client handles are initiated in request
26  *   messages and are then used by subsequent request, decision, and
27  *   report messages to reference the same request state. When the PEP is
28  *   ready to remove a local request state, it will issue a delete message
29  *   to the PDP for the corresponding client handle. A handle MUST be
30  *   explicitly deleted by the PEP before it can be used by the PEP to
31  *   identify a new request state. Handles referring to different request
32  *   states MUST be unique within the context of a particular TCP
33  *   connection and client-type.
34  *
35  * @version COPSPepReqStateMan.java, v 2.00 2004
36  *
37  */
38 public class COPSPepReqStateMan {
39
40     /**
41      * Request State created
42      */
43     public final static short ST_CREATE = 1;
44     /**
45      * Request sent
46      */
47     public final static short ST_INIT = 2;
48     /**
49      * Decisions received
50      */
51     public final static short ST_DECS = 3;
52     /**
53      * Report sent
54      */
55     public final static short ST_REPORT = 4;
56     /**
57      * Request State finalized
58      */
59     public final static short ST_FINAL = 5;
60     /**
61      * New Request State solicited
62      */
63     public final static short ST_NEW = 6;
64     /**
65      * Delete Request State solicited
66      */
67     public final static short ST_DEL = 7;
68     /**
69      * SYNC Request received
70      */
71     public final static short ST_SYNC = 8;
72     /**
73      * SYNC Completed
74      */
75     public final static short ST_SYNCALL = 9;
76     /**
77      * Close Connection received
78      */
79     public final static short ST_CCONN = 10;
80     /**
81      * KAlive Time out
82      */
83     public final static short ST_NOKA = 11;
84     /**
85      * ACCT Time out
86      */
87     public final static short ST_ACCT = 12;
88
89     /**
90      * The client-type identifies the policy client
91      */
92     protected short _clientType;
93
94     /**
95      *  The client handle is used to uniquely identify a particular
96      *  PEP's request for a client-type
97      */
98     protected COPSHandle _handle;
99
100     /**
101         The PolicyDataProcess is used to process policy data in the PEP
102      */
103     protected COPSPepDataProcess _process;
104
105     /**
106      *  State Request State
107      */
108     protected short _status;
109
110     /**
111         The Msg Sender is used to send COPS messages
112      */
113     protected COPSPepMsgSender _sender;
114
115     /**
116      * Sync State
117      */
118     protected boolean _syncState;
119
120     /**
121      * Create a State Request Manager
122      *
123      * @param    clientHandle                a Client Handle
124      *
125      */
126     public COPSPepReqStateMan(final short clientType, final String clientHandle) {
127         _handle = new COPSHandle(new COPSData(clientHandle));
128         _clientType = clientType;
129         _syncState = true;
130         _status = ST_CREATE;
131     }
132
133     /**
134      * Return client handle
135      *
136      * @return   a COPSHandle
137      *
138      */
139     public COPSHandle getClientHandle() {
140         return _handle;
141     }
142
143     /**
144      * Return client-type
145      *
146      * @return   a short
147      *
148      */
149     public int getClientType() {
150         return _clientType;
151     }
152
153     /**
154      * Return Request State status
155      *
156      * @return      s short
157      */
158     public short getStatus() {
159         return _status;
160     }
161
162     /**
163      * Return the Policy Data Process
164      *
165      * @return   a PolicyConfigure
166      *
167      */
168     public COPSPepDataProcess getDataProcess() {
169         return _process;
170     }
171
172     /**
173      * Establish the Policy Data Process
174      *
175      * @param    process              a  PolicyConfigure
176      *
177      */
178     public void setDataProcess(COPSPepDataProcess process) {
179         _process = process;
180     }
181
182     /**
183      * Init Request State
184      *
185      * @throws   COPSPepException
186      *
187      */
188     protected void initRequestState(Socket sock)
189     throws COPSPepException {
190         // Inits an object for sending COPS messages to the PDP
191         _sender = new COPSPepMsgSender(_clientType, _handle, sock);
192
193         // If an object for retrieving PEP features exists,
194         // use it for retrieving them
195         final Map<String, String> clientSIs;
196         if (_process != null)
197             clientSIs = _process.getClientData(this);
198         else
199             clientSIs = new HashMap<>();
200
201         // Send the request
202         // TODO - do we really want to send when this is empty???
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         final Map<COPSContext, Set<COPSDecision>> decisions = dMsg.getDecisions();
235
236         final Map<String, String> removeDecs = new HashMap<>();
237         final Map<String, String> installDecs = new HashMap<>();
238
239         for (Set<COPSDecision> copsDecisions: decisions.values()) {
240             final COPSDecision cmddecision = copsDecisions.iterator().next();
241             String prid = "";
242             switch (cmddecision.getCommand()) {
243                 case INSTALL:
244                     for (final COPSDecision decision : copsDecisions) {
245                         final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
246                         switch (obj.getSNum()) {
247                             case COPSPrObjBase.PR_PRID:
248                                 prid = obj.getData().str();
249                                 break;
250                             case COPSPrObjBase.PR_EPD:
251                                 installDecs.put(prid, obj.getData().str());
252                                 break;
253                             default:
254                                 break;
255                         }
256                     }
257                     break;
258                 case REMOVE:
259                     for (final COPSDecision decision : copsDecisions) {
260                         final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
261                         switch (obj.getSNum()) {
262                             case COPSPrObjBase.PR_PRID:
263                                 prid = obj.getData().str();
264                                 break;
265                             case COPSPrObjBase.PR_EPD:
266                                 removeDecs.put(prid, obj.getData().str());
267                                 break;
268                             default:
269                                 break;
270                         }
271                     }
272                     break;
273             }
274
275         }
276
277         //** Apply decisions to the configuration
278         // TODO - why is this collection never getting populated???
279         final Map<String, String> errorDecs = new HashMap<>();
280         _process.setDecisions(this, removeDecs, installDecs, errorDecs);
281         _status = ST_DECS;
282
283
284         if (_process.isFailReport(this)) {
285             // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");
286             _sender.sendFailReport(_process.getReportData(this));
287         } else {
288             // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");
289             _sender.sendSuccessReport(_process.getReportData(this));
290         }
291         _status = ST_REPORT;
292
293         if (!_syncState) {
294             _sender.sendSyncComplete();
295             _syncState = true;
296             _status = ST_SYNCALL;
297         }
298     }
299
300     /**
301      * Process the message NewRequestState
302      *
303      * @throws   COPSPepException
304      *
305      */
306     protected void processOpenNewRequestState()
307     throws COPSPepException {
308
309         if (_process != null)
310             _process.newRequestState(this);
311
312         _status = ST_NEW;
313     }
314
315     /**
316      * Process the message DeleteRequestState
317      *
318      * @param    dMsg                a  COPSDecisionMsg
319      *
320      * @throws   COPSPepException
321      *
322      */
323     protected void processDeleteRequestState(COPSDecisionMsg dMsg)
324     throws COPSPepException {
325         if (_process != null)
326             _process.closeRequestState(this);
327
328         _status = ST_DEL;
329     }
330
331     /**
332      * Process the message SycnStateRequest.
333      * The message SycnStateRequest indicates that the remote PDP
334      * wishes the client (which appears in the common header)
335      * to re-send its state.
336      *
337      * @param    ssMsg               a  COPSSyncStateMsg
338      *
339      * @throws   COPSPepException
340      *
341      */
342     protected void processSyncStateRequest(COPSSyncStateMsg ssMsg)
343     throws COPSPepException {
344         _syncState = false;
345         // If an object for retrieving PEP features exists,
346         // use it for retrieving them
347         final Map<String, String> clientSIs;
348         if (_process != null)
349             clientSIs = _process.getClientData(this);
350         else
351             clientSIs = new HashMap<>();
352
353         // Send request
354         // TODO - do we really want to send the request when the map is empty???
355         _sender.sendRequest(clientSIs);
356
357         _status = ST_SYNC;
358     }
359
360     protected void processClosedConnection(COPSError error)
361     throws COPSPepException {
362         if (_process != null)
363             _process.notifyClosedConnection(this, error);
364
365         _status = ST_CCONN;
366     }
367
368     protected void processNoKAConnection()
369     throws COPSPepException {
370         if (_process != null)
371             _process.notifyNoKAliveReceived(this);
372
373         _status = ST_NOKA;
374     }
375
376     protected void processAcctReport()
377     throws COPSPepException {
378
379         final Map<String, String> report;
380         if (_process != null) report = _process.getAcctData(this);
381         else report = new HashMap<>();
382
383         // TODO - do we really want to send when the map is empty???
384         _sender.sendAcctReport(report);
385
386         _status = ST_ACCT;
387     }
388
389 }