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());
+ }
+}