Author: lryan
Date: Tue Jun  2 06:11:45 2009
New Revision: 780946

URL: http://svn.apache.org/viewvc?rev=780946&view=rev
Log:
Allow direct configuration of OSAPI in container config in addition to 
introspecting the methods available from RPC endpoints. Useful if you want a 
more static configuration. To add simply put in the container config 
{
...
"osapi.services" : {  "<endpoint1>" : [ "<operation1>", ...], ... }
}
E.g.
"osapi.services" : {  "http://%host%/gadgets/api/rpc"; : [ "http.get", 
"http.put", ...], ... }

Added:
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultServiceFetcher.java
   (contents, props changed)
      - copied, changed from r780559, 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RpcServiceFetcher.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/DefaultServiceFetcherTest.java
Removed:
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RpcServiceFetcher.java
Modified:
    
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultRpcServiceLookup.java
    
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/DefaultRpcServiceLookupTest.java

Modified: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultRpcServiceLookup.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultRpcServiceLookup.java?rev=780946&r1=780945&r2=780946&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultRpcServiceLookup.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultRpcServiceLookup.java
 Tue Jun  2 06:11:45 2009
@@ -46,14 +46,14 @@
 
   private final ConcurrentMap<String, Multimap<String, String>> 
containerServices;
 
-  private final RpcServiceFetcher fetcher;
+  private final DefaultServiceFetcher fetcher;
 
   /**
    * @param fetcher  RpcServiceFetcher to retrieve services available from 
endpoints
    * @param duration in seconds service definitions should remain in the cache
    */
   @Inject
-  public DefaultRpcServiceLookup(RpcServiceFetcher fetcher,
+  public DefaultRpcServiceLookup(DefaultServiceFetcher fetcher,
       @Named("org.apache.shindig.serviceExpirationDurationMinutes")Long 
duration) {
     containerServices = new MapMaker().expiration(duration * 60, 
TimeUnit.SECONDS).makeMap();
     this.fetcher = fetcher;

Copied: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultServiceFetcher.java
 (from r780559, 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RpcServiceFetcher.java)
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultServiceFetcher.java?p2=incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultServiceFetcher.java&p1=incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RpcServiceFetcher.java&r1=780559&r2=780946&rev=780946&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/RpcServiceFetcher.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultServiceFetcher.java
 Tue Jun  2 06:11:45 2009
@@ -41,26 +41,29 @@
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Multimaps;
 import com.google.common.collect.Sets;
+import com.google.common.collect.ImmutableList;
 import com.google.inject.Inject;
 
 /**
  * Retrieves the rpc services for a container by fetching them from the 
container's
  * system.listMethods endpoints as defined in the container config.
  */
-public class RpcServiceFetcher {
+public class DefaultServiceFetcher {
 
-  private static final Logger logger = 
Logger.getLogger(Renderer.class.getName());
+  static final Logger logger = Logger.getLogger(Renderer.class.getName());
 
-  private static final String JSON_RESPONSE_WRAPPER_ELEMENT = "data";
+  static final String JSON_RESPONSE_WRAPPER_ELEMENT = "data";
 
-  private static final String OSAPI_FEATURE_CONFIG = "osapi";
+  static final String OSAPI_FEATURE_CONFIG = "osapi";
 
-  private static final String GADGETS_FEATURES_CONFIG = "gadgets.features";
+  static final String OSAPI_SERVICES = "osapi.services";
 
-  private static final String SYSTEM_LIST_METHODS_METHOD = 
"system.listMethods";
+  static final String GADGETS_FEATURES_CONFIG = "gadgets.features";
+
+  static final String SYSTEM_LIST_METHODS_METHOD = "system.listMethods";
 
   /** Key in container config that lists the endpoints offering services */
-  private static final String OSAPI_BASE_ENDPOINTS = "endPoints";
+  static final String OSAPI_BASE_ENDPOINTS = "endPoints";
 
   private final ContainerConfig containerConfig;
 
@@ -68,7 +71,7 @@
 
   /** @param config Container Config for looking up endpoints */
   @Inject
-  public RpcServiceFetcher(ContainerConfig config, HttpFetcher fetcher) {
+  public DefaultServiceFetcher(ContainerConfig config, HttpFetcher fetcher) {
     this.containerConfig = config;
     this.fetcher = fetcher;
   }
@@ -83,22 +86,35 @@
     if (containerConfig == null) {
       return ImmutableMultimap.<String, String>builder().build();
     }
-    List<String> endpoints = getEndpointsFromContainerConfig(container, host);
     LinkedHashMultimap<String, String> endpointServices = 
Multimaps.newLinkedHashMultimap();
+
+    // First check services directly declared in container config
+    Map<String, Object> declaredServices = containerConfig.getMap(container, 
OSAPI_SERVICES);
+    if (!declaredServices.isEmpty()) {
+      for (Map.Entry<String, Object> entry : declaredServices.entrySet()) {
+        endpointServices.putAll(entry.getKey(), 
(Iterable<String>)entry.getValue());
+      }
+    }
+
+    // Merge services lazily loaded from the endpoints if any
+    List<String> endpoints = getEndpointsFromContainerConfig(container, host);
     for (String endpoint : endpoints) {
       endpointServices.putAll(endpoint, 
retrieveServices(endpoint.replace("%host%", host)));
     }
+    
     return ImmutableMultimap.copyOf(endpointServices);
   }
 
+  @SuppressWarnings("unchecked")
   private List<String> getEndpointsFromContainerConfig(String container, 
String host) {
     @SuppressWarnings("unchecked")
     Map<String, Object> properties = (Map<String, Object>) 
containerConfig.getMap(container,
         GADGETS_FEATURES_CONFIG).get(OSAPI_FEATURE_CONFIG);
 
-    @SuppressWarnings("unchecked")
-    List<String> endpoints = (List<String>) 
properties.get(OSAPI_BASE_ENDPOINTS);
-    return endpoints;
+    if (properties != null) {
+      return (List<String>) properties.get(OSAPI_BASE_ENDPOINTS);
+    }
+    return ImmutableList.of();
   }
 
   private Set<String> retrieveServices(String endpoint) {

Propchange: 
incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/render/DefaultServiceFetcher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/DefaultRpcServiceLookupTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/DefaultRpcServiceLookupTest.java?rev=780946&r1=780945&r2=780946&view=diff
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/DefaultRpcServiceLookupTest.java
 (original)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/DefaultRpcServiceLookupTest.java
 Tue Jun  2 06:11:45 2009
@@ -38,7 +38,7 @@
   @Override
   protected void setUp() throws Exception {
     super.setUp();
-    svcLookup = new DefaultRpcServiceLookup(new RpcServiceFetcher(null, new 
BasicHttpFetcher()), 60l);
+    svcLookup = new DefaultRpcServiceLookup(new DefaultServiceFetcher(null, 
new BasicHttpFetcher()), 60l);
     socialEndpoint = "http://localhost:8080/social/rpc";;
     host = "localhost:8080";
   }

Added: 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/DefaultServiceFetcherTest.java
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/DefaultServiceFetcherTest.java?rev=780946&view=auto
==============================================================================
--- 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/DefaultServiceFetcherTest.java
 (added)
+++ 
incubator/shindig/trunk/java/gadgets/src/test/java/org/apache/shindig/gadgets/render/DefaultServiceFetcherTest.java
 Tue Jun  2 06:11:45 2009
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.shindig.gadgets.render;
+
+import org.apache.shindig.common.EasyMockTestCase;
+import org.apache.shindig.config.JsonContainerConfig;
+import org.apache.shindig.expressions.Expressions;
+import org.apache.shindig.expressions.Functions;
+import org.apache.shindig.gadgets.http.HttpFetcher;
+import org.apache.shindig.gadgets.http.HttpRequest;
+import org.apache.shindig.gadgets.http.HttpResponse;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import org.easymock.classextension.EasyMock;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.json.JSONException;
+
+import java.util.List;
+
+/**
+ * Test fetching of osapi services from container config and endpoints.
+ */
+public class DefaultServiceFetcherTest extends EasyMockTestCase {
+  protected DefaultServiceFetcher fetcher;
+  protected HttpFetcher mockFetcher;
+  protected Multimap<String, String> configuredServices;
+  protected static final String endPoint1 = "http://%host%/api/rpc";;
+  protected static final String endPoint2 = "http://%host%/social/api/rpc";;
+
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    JSONObject config = createConfig();
+
+    JsonContainerConfig containerConfig =
+        new JsonContainerConfig(config, new Expressions(new Functions()));
+    mockFetcher = mock(HttpFetcher.class);
+    fetcher = new DefaultServiceFetcher(containerConfig, mockFetcher);
+  }
+
+  private JSONObject createConfig() throws JSONException {
+    JSONObject config = new JSONObject();
+    JSONObject container = new JSONObject();
+    JSONObject services = new JSONObject();
+    JSONObject features = new JSONObject();
+
+    configuredServices = ImmutableMultimap.<String, String>builder()
+      .putAll("http://localhost/api/rpc";, "system.listMethods", "service.get")
+      .putAll("gadgets.rpc", "messages.send", "ui.resize").build();
+
+    for (String key : configuredServices.keySet()) {
+      services.put(key, configuredServices.get(key));
+    }
+    container.put(DefaultServiceFetcher.OSAPI_SERVICES, services);
+
+    JSONObject endpoints = new JSONObject();
+
+    endpoints.put(DefaultServiceFetcher.OSAPI_BASE_ENDPOINTS,
+        new JSONArray(ImmutableList.of(endPoint1, endPoint2)));
+    features.put(DefaultServiceFetcher.OSAPI_FEATURE_CONFIG, endpoints);
+    container.put(DefaultServiceFetcher.GADGETS_FEATURES_CONFIG, features);
+
+    config.put("default", container);
+    return config;
+  }
+
+  public void testReadConfigNoEndpoints() throws Exception {
+    JSONObject config = createConfig();
+    
config.getJSONObject("default").remove(DefaultServiceFetcher.GADGETS_FEATURES_CONFIG);
+    JsonContainerConfig containerConfig =
+        new JsonContainerConfig(config, new Expressions(new Functions()));
+    fetcher = new DefaultServiceFetcher(containerConfig, mockFetcher);
+
+    
EasyMock.expect(mockFetcher.fetch(EasyMock.isA(HttpRequest.class))).andReturn(
+        new HttpResponse("")).anyTimes();
+    replay();
+    Multimap<String, String> services = 
fetcher.getServicesForContainer("default", "dontcare");
+    verify();
+    assertEquals(configuredServices, services);
+  }
+
+  public void testReadConfigEndpointsDown() throws Exception {
+    
EasyMock.expect(mockFetcher.fetch(EasyMock.isA(HttpRequest.class))).andReturn(
+        new HttpResponse("")).anyTimes();
+    replay();
+    Multimap<String, String> services = 
fetcher.getServicesForContainer("default", "dontcare");
+    verify();
+    assertEquals(configuredServices, services);
+  }
+
+  public void testReadConfigWithValidEndpoints() throws Exception {
+    List<String> endPoint1Services = ImmutableList.of("do.something", 
"delete.someting");
+    JSONObject service1 = new JSONObject();
+    service1.put("data", endPoint1Services);
+
+    List<String> endPoint2Services = ImmutableList.of("weather.get");
+    JSONObject service2 = new JSONObject();
+    service2.put("data", endPoint2Services);
+
+    
EasyMock.expect(mockFetcher.fetch(EasyMock.isA(HttpRequest.class))).andReturn(
+        new HttpResponse(service1.toString()));
+    
EasyMock.expect(mockFetcher.fetch(EasyMock.isA(HttpRequest.class))).andReturn(
+        new HttpResponse(service2.toString()));
+
+    replay();
+    Multimap<String, String> services = 
fetcher.getServicesForContainer("default", "dontcare");
+    verify();
+    Multimap<String, String> mergedServices = 
Multimaps.newLinkedHashMultimap(configuredServices);
+    mergedServices.putAll(endPoint1, endPoint1Services);
+    mergedServices.putAll(endPoint2, endPoint2Services);
+    assertEquals(mergedServices, Multimaps.newLinkedHashMultimap(services));
+  }
+
+  public void testReadConfigBadContainer() throws Exception {
+    Multimap<String, String> multimap = 
fetcher.getServicesForContainer("badcontainer", "dontcare");
+    assertEquals(0, multimap.size());
+  }
+}


Reply via email to