Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/opencloud/slee/services/sip/proxy/BaseProxySbb.java


1   package com.opencloud.slee.services.sip.proxy;
2   
3   
4   
5   import javax.naming.InitialContext;
6   import javax.naming.NamingException;
7   
8   import javax.sip.*;
9   import javax.sip.TimeoutEvent;
10  import javax.sip.message.Request;
11  import javax.sip.message.Response;
12  
13  import javax.slee.ActivityContextInterface;
14  import javax.slee.ChildRelation;
15  import javax.slee.SbbContext;
16  import javax.slee.SbbLocalObject;
17  import javax.slee.facilities.Level;
18  
19  import com.opencloud.slee.services.sip.common.AbstractSipProxy;
20  import com.opencloud.slee.services.sip.common.SipBaseSbb;
21  
22  public abstract class BaseProxySbb extends SipBaseSbb {
23  
24      protected String getTraceMessageType() { return "SipProxySbb"; }
25      
26      // child relation
27      public abstract ChildRelation getRegistrarSbbChild();
28  
29      // Activity Context Interface narrow method
30      public abstract SipProxySbbActivityContextInterface asSbbActivityContextInterface(ActivityContextInterface ac);
31      
32      private void processRequest(ServerTransaction serverTransaction, Request request, ActivityContextInterface ac) {
33    trace(Level.FINEST, "processRequest: request = \n" + request.toString());
34          try {
35                  
36              SipProxySbbActivityContextInterface sipaci = asSbbActivityContextInterface(ac);
37              
38              if (sipaci.getTransactionTerminated()) {
39                  return; // nothing to do
40              }
41              
42              // Create a worker to process this event            
43              MySipProxy proxy = new MySipProxy(this, sipaci);
44              // Go
45              proxy.processRequest(serverTransaction, request);
46                  
47          } catch (Exception e) {
48              // Send error response so client can deal with it
49              trace(Level.WARNING, "Exception during processRequest", e);
50              try {
51                  serverTransaction.sendResponse(getMessageFactory().createResponse(Response.SERVER_INTERNAL_ERROR, request));
52              } catch (Exception ex) {
53                  ex.printStackTrace();
54              }
55          }            
56                          
57      }
58      
59      private void processResponse(ClientTransaction clientTransaction, Response response, ActivityContextInterface ac) {
60    trace(Level.FINEST, "processResponse: response = \n" + response.toString());
61          try {
62  
63              SipProxySbbActivityContextInterface sipaci = asSbbActivityContextInterface(ac);
64                  
65              // Create a worker to process this event            
66              MySipProxy proxy = new MySipProxy(this, sipaci);
67              // Go
68              proxy.processResponse(getServerTransaction(clientTransaction), response);
69                  
70          } catch (Exception e) {
71              // Send error response so client can deal with it
72              trace(Level.WARNING, "Exception during processResponse", e);
73          }            
74                          
75      }    
76      
77      public void onRegisterEvent(RequestEvent event, ActivityContextInterface ac) {
78          getDefaultSbbUsageParameterSet().incrementNumberOfRegister(1);
79          trace(Level.INFO, "Received REGISTER request, class="+event.getClass());
80          try {
81  
82              // is local domain?
83              
84              // create registrar child SBB
85              ChildRelation relation = getRegistrarSbbChild();
86              SbbLocalObject child = relation.create();
87              
88              // attach child to this activity
89              ac.attach(child);
90              
91              // detach myself
92              ac.detach(getSbbLocalObject());
93              
94              // Event router will pass this event to child SBB
95  
96          } catch (Exception e) {
97              trace(Level.WARNING, "Exception during onRegisterEvent", e);
98          }
99      }
100 
101     public void onInviteEvent(RequestEvent event, ActivityContextInterface ac) {
102         getDefaultSbbUsageParameterSet().incrementNumberOfInvite(1);
103         trace(Level.INFO, "Received INVITE request");
104         try {
105             Request request = event.getRequest();
106             ServerTransaction serverTransaction = event.getServerTransaction();
107             processRequest(serverTransaction, request, ac);
108         } catch (Exception e) {
109             trace(Level.WARNING, "Exception during onInviteEvent", e);
110         }
111     }
112 
113     public void onByeEvent(RequestEvent event, ActivityContextInterface ac) {
114         getDefaultSbbUsageParameterSet().incrementNumberOfBye(1);
115         trace(Level.INFO, "Received BYE request");
116         try {
117             
118             Request request = event.getRequest();
119             ServerTransaction serverTransaction = event.getServerTransaction();
120             processRequest(serverTransaction, request, ac);
121                         
122         } catch (Exception e) {
123             trace(Level.WARNING, "Exception during onByeEvent", e);
124         }
125     }
126 
127     public void onCancelEvent(RequestEvent event, ActivityContextInterface ac) {
128         trace(Level.INFO, "Received CANCEL request");
129         try {
130             
131             Request request = event.getRequest();
132             ServerTransaction serverTransaction = event.getServerTransaction();
133 
134             // CANCELs are hop-by-hop, so here we respond immediately on the server txn.
135             serverTransaction.sendResponse(getMessageFactory().createResponse(Response.OK, request));
136 
137             // This will generate a new CANCEL request that originates from the proxy
138             processRequest(serverTransaction, request, ac);
139                         
140         } catch (Exception e) {
141             trace(Level.WARNING, "Exception during onCancelEvent", e);
142         }
143     }
144 
145     public void onAckEvent(RequestEvent event, ActivityContextInterface ac) {
146         getDefaultSbbUsageParameterSet().incrementNumberOfAck(1);
147         trace(Level.INFO, "Received ACK request");
148         try {
149             
150             Request request = event.getRequest();
151             ServerTransaction serverTransaction = event.getServerTransaction();
152             processRequest(serverTransaction, request, ac);
153                         
154         } catch (Exception e) {
155             trace(Level.WARNING, "Exception during onAckEvent", e);
156         }
157     }
158 
159     public void onOptionsEvent(RequestEvent event, ActivityContextInterface ac) {
160         trace(Level.INFO, "Received OPTIONS request");
161         try {
162             
163             Request request = event.getRequest();
164             ServerTransaction serverTransaction = event.getServerTransaction();
165             processRequest(serverTransaction, request, ac);
166                         
167         } catch (Exception e) {
168             trace(Level.WARNING, "Exception during onOptionsEvent", e);
169         }
170     }
171 
172     public void onInfoRespEvent(ResponseEvent event, ActivityContextInterface ac) {
173         trace(Level.INFO, "Received 1xx (INFO) response");
174         try {
175             
176             Response response = event.getResponse();
177             ClientTransaction clientTransaction = event.getClientTransaction();
178             processResponse(clientTransaction, response, ac);
179                         
180         } catch (Exception e) {
181             trace(Level.WARNING, "Exception during onInfoRespEvent", e);
182         }
183     }
184     
185     public void onSuccessRespEvent(ResponseEvent event, ActivityContextInterface ac) {
186         trace(Level.INFO, "Received 2xx (SUCCESS) response");
187         try {
188             
189             Response response = event.getResponse();
190             ClientTransaction clientTransaction = event.getClientTransaction();
191             processResponse(clientTransaction, response, ac);
192                         
193         } catch (Exception e) {
194             trace(Level.WARNING, "Exception during onSuccessRespEvent", e);
195         }
196     }
197 
198     public void onRedirRespEvent(ResponseEvent event, ActivityContextInterface ac) {
199         trace(Level.INFO, "Received 3xx (REDIRECT) response");
200         try {
201             
202             Response response = event.getResponse();
203             ClientTransaction clientTransaction = event.getClientTransaction();
204             processResponse(clientTransaction, response, ac);
205                         
206         } catch (Exception e) {
207             trace(Level.WARNING, "Exception during onRedirRespEvent", e);
208         }
209     }
210 
211     public void onClientErrorRespEvent(ResponseEvent event, ActivityContextInterface ac) {
212         trace(Level.INFO, "Received 4xx (CLIENT ERROR) response");
213         try {
214             
215             Response response = event.getResponse();
216             ClientTransaction clientTransaction = event.getClientTransaction();
217             processResponse(clientTransaction, response, ac);
218                         
219         } catch (Exception e) {
220             trace(Level.WARNING, "Exception during onClientErrorRespEvent", e);
221         }
222     }
223 
224     public void onServerErrorRespEvent(ResponseEvent event, ActivityContextInterface ac) {
225         trace(Level.INFO, "Received 5xx (SERVER ERROR) response");
226         try {
227             
228             Response response = event.getResponse();
229             ClientTransaction clientTransaction = event.getClientTransaction();
230             processResponse(clientTransaction, response, ac);
231                         
232         } catch (Exception e) {
233             trace(Level.WARNING, "Exception during onServerErrorRespEvent", e);
234         }
235     }
236 
237     public void onGlobalFailureRespEvent(ResponseEvent event, ActivityContextInterface ac) {
238         trace(Level.INFO, "Received 6xx (GLOBAL FAILURE) response");
239         try {
240             
241             Response response = event.getResponse();
242             ClientTransaction clientTransaction = event.getClientTransaction();
243             processResponse(clientTransaction, response, ac);
244                         
245         } catch (Exception e) {
246             trace(Level.WARNING, "Exception during onGlobalFailureRespEvent", e);
247         }
248     }
249       
250     /*
251       Timeouts
252      */
253 
254     public void onTransactionTimeoutEvent( TimeoutEvent event, ActivityContextInterface ac ){
255         ClientTransaction clientTransaction = event.getClientTransaction();
256         ServerTransaction serverTransaction = event.getServerTransaction();
257 
258   trace(Level.INFO, "Received transaction timeout event, tid=" + clientTransaction);
259         if (serverTransaction != null) {
260             try {
261                 // Find the server transaction activity that is associated with this 
262                 // client transaction, and set it to terminated so subsequent ACKs 
263                 // will be ignored.
264                 ActivityContextInterface[] activities = getSbbContext().getActivities();
265                 SipProxySbbActivityContextInterface serverTxnActivity = null;
266                 for (int i=0; i < activities.length; i++) {
267                     serverTxnActivity = asSbbActivityContextInterface(activities[i]);
268                     if (clientTransaction == serverTxnActivity.getClientTransaction()) {
269                         trace(Level.INFO, "onTransactionTimeoutEvent: terminating server transaction " + serverTransaction);
270                         serverTxnActivity.setTransactionTerminated(true);
271                         break;
272                     }
273                 }
274 
275                 serverTransaction.sendResponse(getMessageFactory().createResponse(Response.REQUEST_TIMEOUT, serverTransaction.getRequest()));
276 
277             } catch (Exception e) {
278                 trace(Level.WARNING, "Exception during onTransactionTimeoutEvent", e);
279             }
280         }
281     }
282 
283     public void onTransactionExpiredEvent( TimeoutEvent event, ActivityContextInterface ac ){
284   trace(Level.INFO, "Received transaction expired event");
285     }
286 
287     public ServerTransaction getServerTransaction(ClientTransaction clientTransaction) {
288         // We should only ever be attached to two activities (our client and server transactions) so find the attached activity
289         // that is a server transaction
290         ActivityContextInterface myacis[] = getSbbContext().getActivities();
291         for (int i = 0; i < myacis.length; i++) {
292             ActivityContextInterface myaci = myacis[i];
293             if (myaci.getActivity() instanceof ServerTransaction) {
294                 return (ServerTransaction) myaci.getActivity();
295             }
296         }
297         trace(Level.WARNING, "Could not find an attached ServerTransaction");
298         return null;
299     }
300 
301     /**
302      * Inner class that overrides some proxy behaviour.
303      * Used to store transaction mappings in ACIs
304      *
305      * TODO: support forking
306      */
307     private class MySipProxy extends AbstractSipProxy {
308         
309         private SipProxySbbActivityContextInterface sipaci;
310         
311         MySipProxy(SipBaseSbb config, SipProxySbbActivityContextInterface sipaci) {
312             super(config);
313             this.sipaci = sipaci;
314         }
315         
316         /* overridden to keep state in ACIs */
317         public void forwardRequest(ServerTransaction serverTransaction, Request request) {
318             try {
319                             
320                 if (request.getMethod().equals(Request.ACK)) {
321                     trace(Level.FINEST, "Sending request:\n" + request.toString());
322                     sendStatelessRequest(request);
323                     
324                 }
325                 else if (request.getMethod().equals(Request.CANCEL)) {
326                     // send the CANCEL request to endpoint - don't care about response
327                     sendRequest(request, false);
328                 }
329                 else {
330                     trace(Level.FINEST, "Sending request:\n" + request.toString());
331                     // Send request on a new client transaction, and attach so we get responses
332                     ClientTransaction clientTransaction = sendRequest(request, true);
333                     trace(Level.FINEST, "clientTransaction = " + clientTransaction);
334                 }
335 
336             } catch (Exception e) {
337                 e.printStackTrace();
338                 trace(Level.WARNING, "Exception during forwardRequest", e);
339                 sendErrorResponse(serverTransaction, request, Response.SERVER_INTERNAL_ERROR);
340             }
341         }
342 
343         public void sendErrorResponse(ServerTransaction txn, Request request, int statusCode) {
344             try {
345                 trace(Level.FINEST, "Ending transaction - subsequent messages will be ignored");
346                 new Throwable().printStackTrace();
347                 sipaci.setTransactionTerminated(true);
348                 txn.sendResponse(getMessageFactory().createResponse(statusCode, request));
349             } catch (Exception e) {
350                 //e.printStackTrace();
351                 trace(Level.WARNING, "Exception during sendErrorResponse", e);
352             }
353         }
354 
355         public void forwardResponse(ServerTransaction txn, Response response) {
356             try {
357                 trace(Level.FINEST, "Forwarding response:\n" + response);
358                 if (txn != null) {
359                     txn.sendResponse(response);
360                 } 
361                 else {
362                     // forward statelessly anyway
363                     sendStatelessResponse(response);
364                 }
365             } catch (Exception e) {
366                 e.printStackTrace();
367             }
368         }
369 
370     }
371     public abstract ProxySbbUsage getDefaultSbbUsageParameterSet();
372     protected abstract ClientTransaction sendRequest(Request request, boolean attach) throws SipException;
373     protected abstract void sendStatelessRequest(Request request) throws SipException;
374     protected abstract void sendStatelessResponse(Response response) throws SipException;
375 }
376