View Javadoc

1   package org.kuali.rice.test.remote;
2   
3   import org.apache.commons.logging.Log;
4   import org.apache.commons.logging.LogFactory;
5   import org.apache.cxf.endpoint.Client;
6   import org.apache.cxf.frontend.ClientProxy;
7   import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
8   import org.kuali.rice.core.cxf.interceptors.ImmutableCollectionsInInterceptor;
9   
10  import javax.jws.WebService;
11  import javax.xml.ws.Endpoint;
12  
13  /**
14   * Harness used to hold a reference to an endpoint that is published to support remote tests.  Tests using
15   * this harness should pass in a @WebService annotated interface class and an object of an implementing class
16   * of that interface to the publishEndpointAndReturnProxy method in @Before or setUp methods used in tests.
17   * <p/>
18   * After each test is run, stopEndPoint should be called in @After or tearDown methods in order to unpublish the
19   * endpoint.
20   */
21  public class RemoteTestHarness {
22  
23      private static final Log LOG = LogFactory.getLog(RemoteTestHarness.class);
24  
25      private static String ENDPOINT_ROOT = "http://localhost"; //Default URL
26      private static String ENDPOINT_PATH = "/service";
27  
28      private Endpoint endpoint;
29  
30      @SuppressWarnings("unchecked")
31      /**
32       * Creates a published endpoint from the passed in serviceImplementation and also returns a proxy implementation
33       * of the passed in interface for clients to use to hit the created endpoint.
34       */
35      public <T> T publishEndpointAndReturnProxy(Class<T> jaxWsAnnotatedInterface, T serviceImplementation) {
36          if (jaxWsAnnotatedInterface.isInterface() &&
37                  jaxWsAnnotatedInterface.getAnnotation(WebService.class) != null &&
38                  jaxWsAnnotatedInterface.isInstance(serviceImplementation)) {
39  
40              String endpointUrl = getAvailableEndpointUrl();
41              endpoint = Endpoint.publish(endpointUrl, serviceImplementation);
42  
43              JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
44              factory.setServiceClass(jaxWsAnnotatedInterface);
45              factory.setAddress(endpointUrl);
46  
47              T serviceProxy = (T) factory.create();
48              Client cxfClient = ClientProxy.getClient(serviceProxy);
49              cxfClient.getInInterceptors().add(new ImmutableCollectionsInInterceptor());
50  
51  //            waitAndCheck(endpoint, false);
52  
53              return serviceProxy;
54          } else {
55              throw new IllegalArgumentException("Passed in interface class type must be annotated with @WebService " +
56                      "and object reference must be an implementing class of that interface.");
57  
58          }
59      }
60  
61      /**
62       * Stops and makes an internal endpoint unpublished if it was previously published.
63       * Otherwise, this method is a no-op.
64       */
65      public void stopEndpoint() {
66          if (endpoint != null) {
67              endpoint.stop();
68  //            waitAndCheck(endpoint, true);
69          }
70      }
71  
72      private String getAvailableEndpointUrl() {
73          String port = Integer.toString(AvailablePortFinder.getNextAvailable());
74          return ENDPOINT_ROOT + ":" + port + ENDPOINT_PATH;
75      }
76  
77      /*private static void waitAndCheck(Endpoint ep, boolean published) {
78          //Thread.sleep() seems to be causing deadlock...using another mechanism for wait
79          if (ep.isPublished() == published) {
80              for (int i = 0; i < MAX_WAIT_ITR; i++) {
81                  if (ep.isPublished() != published) {
82                      LOG.info("took " + i + " iterations to change published state of endpoint: " + ep);
83                      break;
84                  }
85              }
86          }
87  
88          if (ep.isPublished() == published) {
89              LOG.warn("endpoint: " + ep + " published: " + published);
90          }
91      }*/
92  }