package org.mobicents.client.slee.resource.http; import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.slee.Address; import javax.slee.EventTypeID; import javax.slee.facilities.Tracer; import javax.slee.resource.ActivityHandle; import javax.slee.resource.ConfigProperties; import javax.slee.resource.FailureReason; import javax.slee.resource.FireableEventType; import javax.slee.resource.InvalidConfigurationException; import javax.slee.resource.Marshaler; import javax.slee.resource.ReceivableService; import javax.slee.resource.ResourceAdaptor; import javax.slee.resource.ResourceAdaptorContext; import net.java.client.slee.resource.http.HttpClientActivity; import net.java.client.slee.resource.http.HttpClientResourceAdaptorSbbInterface; import net.java.client.slee.resource.http.event.Response; import net.java.client.slee.resource.http.event.ResponseEvent; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; public class HttpClientResourceAdaptor implements ResourceAdaptor { private ResourceAdaptorContext resourceAdaptorContext; private ConcurrentHashMap<HttpClientActivityHandle, HttpClientActivity> activities; private HttpClientResourceAdaptorSbbInterface sbbInterface; private ExecutorService executorService; private Tracer tracer; // caching the only event this ra fires private FireableEventType fireableEventType; // LIFECYCLE METHODS /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#setResourceAdaptorContext(javax.slee.resource.ResourceAdaptorContext) */ public void setResourceAdaptorContext(ResourceAdaptorContext arg0) { resourceAdaptorContext = arg0; tracer = resourceAdaptorContext.getTracer(HttpClientResourceAdaptor.class.getSimpleName()); try { fireableEventType = resourceAdaptorContext.getEventLookupFacility().getFireableEventType(new EventTypeID("net.java.client.slee.resource.http.event.ResponseEvent", "net.java.client.slee", "1.0")); } catch (Throwable e) { throw new RuntimeException(e.getMessage(),e); } } /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#raConfigure(javax.slee.resource.ConfigProperties) */ public void raConfigure(ConfigProperties arg0) { // no config } /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#raActive() */ public void raActive() { activities = new ConcurrentHashMap<HttpClientActivityHandle, HttpClientActivity>(); executorService = Executors.newCachedThreadPool(); sbbInterface = new HttpClientResourceAdaptorSbbInterfaceImpl(this); tracer.info("entity activated."); } /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#raStopping() */ public void raStopping() { // nothing to do } /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#raInactive() */ public void raInactive() { activities.clear(); activities = null; executorService.shutdown(); executorService = null; sbbInterface = null; } /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#raUnconfigure() */ public void raUnconfigure() { // nothing to do } /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#unsetResourceAdaptorContext() */ public void unsetResourceAdaptorContext() { resourceAdaptorContext = null; tracer = null; } // CONFIG MANAGENT /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#raVerifyConfiguration(javax.slee.resource.ConfigProperties) */ public void raVerifyConfiguration(ConfigProperties arg0) throws InvalidConfigurationException { // no config } /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#raConfigurationUpdate(javax.slee.resource.ConfigProperties) */ public void raConfigurationUpdate(ConfigProperties arg0) { // no config } // EVENT FILTERING /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#serviceActive(javax.slee.resource.ReceivableService) */ public void serviceActive(ReceivableService arg0) { // no event filtering } /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#serviceStopping(javax.slee.resource.ReceivableService) */ public void serviceStopping(ReceivableService arg0) { // no event filtering } /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#serviceInactive(javax.slee.resource.ReceivableService) */ public void serviceInactive(ReceivableService arg0) { // no event filtering } // ACCESS INTERFACE /* * (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#getResourceAdaptorInterface(java.lang.String) */ public Object getResourceAdaptorInterface(String arg0) { return sbbInterface; }; /* * (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#getMarshaler() */ public Marshaler getMarshaler() { return null; } // MANDATORY CALLBACKS /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#administrativeRemove(javax.slee.resource.ActivityHandle) */ public void administrativeRemove(ActivityHandle arg0) { } /* * (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#getActivity(javax.slee.resource.ActivityHandle) */ public Object getActivity(ActivityHandle activityHandle) { return activities.get(activityHandle); } /* * (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#getActivityHandle(java.lang.Object) */ public ActivityHandle getActivityHandle(Object arg0) { if (arg0 instanceof HttpClientActivityImpl) { HttpClientActivityHandle handle = new HttpClientActivityHandle(((HttpClientActivityImpl)arg0).getSessionId()); if (activities.containsKey(handle)) { return handle; } } return null; } /* * (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#queryLiveness(javax.slee.resource.ActivityHandle) */ public void queryLiveness(ActivityHandle arg0) { // if the activity is not in the map end it, its a leak if (!activities.contains(arg0)) { resourceAdaptorContext.getSleeEndpoint().endActivity(arg0); } } // OPTIONAL CALLBACKS /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#eventProcessingSuccessful(javax.slee.resource.ActivityHandle, javax.slee.resource.FireableEventType, java.lang.Object, javax.slee.Address, javax.slee.resource.ReceivableService, int) */ public void eventProcessingSuccessful(ActivityHandle arg0, FireableEventType arg1, Object arg2, Address arg3, ReceivableService arg4, int arg5) { // not used } /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#eventProcessingFailed(javax.slee.resource.ActivityHandle, javax.slee.resource.FireableEventType, java.lang.Object, javax.slee.Address, javax.slee.resource.ReceivableService, int, javax.slee.resource.FailureReason) */ public void eventProcessingFailed(ActivityHandle arg0, FireableEventType arg1, Object arg2, Address arg3, ReceivableService arg4, int arg5, FailureReason arg6) { // not used } /* (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#eventUnreferenced(javax.slee.resource.ActivityHandle, javax.slee.resource.FireableEventType, java.lang.Object, javax.slee.Address, javax.slee.resource.ReceivableService, int) */ public void eventUnreferenced(ActivityHandle arg0, FireableEventType arg1, Object arg2, Address arg3, ReceivableService arg4, int arg5) { // not used } /* * (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#activityEnded(javax.slee.resource.ActivityHandle) */ public void activityEnded(ActivityHandle activityHandle) { if (tracer.isFineEnabled()) { tracer.fine("activityEnded( handle = "+activityHandle+")"); } activities.remove(activityHandle); } /* * (non-Javadoc) * @see javax.slee.resource.ResourceAdaptor#activityUnreferenced(javax.slee.resource.ActivityHandle) */ public void activityUnreferenced(ActivityHandle arg0) { // not used } // OWN METHODS /** * Retrieves the ra context * @return */ public ResourceAdaptorContext getResourceAdaptorContext() { return resourceAdaptorContext; } /** * Retrieves the executor service */ public ExecutorService getExecutorService() { return executorService; } /** * Maps the specified activity to the specified handle * @param activityHandle * @param activity */ public void addActivity(HttpClientActivityHandle activityHandle, HttpClientActivity activity) { activities.put(activityHandle, activity); } /** * Ends the specified activity * @param activity */ public void endActivity(HttpClientActivity activity) { final HttpClientActivityHandle ah = new HttpClientActivityHandle(activity .getSessionId()); if (activities.containsKey(ah)) { resourceAdaptorContext.getSleeEndpoint().endActivity(ah); } } /** * Receives an Event from the HTTP client and sends it to the SLEE. * * @param event * @param activity */ public void processResponseEvent(ResponseEvent event, HttpClientActivity activity) { HttpClientActivityHandle ah = new HttpClientActivityHandle(activity .getSessionId()); if (!activities.containsKey(ah)) { // New HttpSession activity activities.put(ah, activity); } if (tracer.isInfoEnabled()) tracer .info("==== FIRING ResponseEvent EVENT TO LOCAL SLEE, Event: " + event + " ===="); try { resourceAdaptorContext.getSleeEndpoint().fireEvent(ah,fireableEventType,event,null,null); } catch (Throwable e) { tracer.severe(e.getMessage(),e); } } protected class AsyncExecuteMethodHandler implements Runnable { private HttpMethod httpMethod; private HttpClient httpClient; private HttpClientActivity activity; public AsyncExecuteMethodHandler(HttpMethod httpMethod, HttpClient httpClient, HttpClientActivity activity) { this.httpMethod = httpMethod; this.httpClient = httpClient; this.activity = activity; } public void run() { ResponseEvent event = null; try { int statusCode = 0; byte[] responseBody = null; String responseBodyAsString = null; Header[] headers = null; Response response = null; statusCode = httpClient.executeMethod(httpMethod); responseBody = httpMethod.getResponseBody(); responseBodyAsString = httpMethod.getResponseBodyAsString(); headers = httpMethod.getResponseHeaders(); response = new ResponseImpl(responseBody, responseBodyAsString, headers, statusCode); // create event with response event = new ResponseEvent(response); } catch (HttpException e) { tracer .severe( "executeMethod failed in AsyncExecuteHttpMethodHandler with HttpException", e); event = new ResponseEvent(e); } catch (IOException e) { tracer .severe( "executeMethod failed in AsyncExecuteHttpMethodHandler with IOException", e); event = new ResponseEvent(e); } catch (Exception e) { tracer .severe( "executeMethod failed in AsyncExecuteHttpMethodHandler with Exception", e); event = new ResponseEvent(e); } finally { // Release the connection. httpMethod.releaseConnection(); } // process event processResponseEvent(event, this.activity); // If EndOnReceivingResponse is set to true, end the Activity if (this.activity.getEndOnReceivingResponse()) { endActivity(this.activity); } } } }