brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject [1/2] brooklyn-server git commit: BROOKLYN-351: fix jclouds provider/api caching
Date Tue, 27 Sep 2016 06:39:35 GMT
Repository: brooklyn-server
Updated Branches:
  refs/heads/master 63b368d07 -> b964e8be1


BROOKLYN-351: fix jclouds provider/api caching


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/819632dc
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/819632dc
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/819632dc

Branch: refs/heads/master
Commit: 819632dc06557eba5d1b250ebf2b22099d29d5f7
Parents: 63b368d
Author: Aled Sage <aled.sage@gmail.com>
Authored: Mon Sep 26 20:54:56 2016 +0100
Committer: Aled Sage <aled.sage@gmail.com>
Committed: Mon Sep 26 21:24:00 2016 +0100

----------------------------------------------------------------------
 .../jclouds/JcloudsLocationResolver.java        |  30 +---
 .../jclouds/JcloudsProviderAndApiLoader.java    |  99 +++++++++++++
 .../JcloudsProviderAndApiLoaderTest.java        | 142 +++++++++++++++++++
 3 files changed, 243 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/819632dc/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
index 239777a..f2a14bc 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
@@ -36,16 +36,9 @@ import org.apache.brooklyn.core.location.LocationConfigUtils;
 import org.apache.brooklyn.core.location.internal.LocationInternal;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.text.Strings;
-import org.jclouds.apis.ApiMetadata;
-import org.jclouds.apis.Apis;
-import org.jclouds.providers.ProviderMetadata;
-import org.jclouds.providers.Providers;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-
 @SuppressWarnings("rawtypes")
 public class JcloudsLocationResolver implements LocationResolver {
 
@@ -53,25 +46,6 @@ public class JcloudsLocationResolver implements LocationResolver {
     
     private static final String JCLOUDS = "jclouds";
     
-    public static final Map<String,ProviderMetadata> PROVIDERS = getProvidersMap();
-    public static final Map<String,ApiMetadata> APIS = getApisMap();
-    
-    private static Map<String,ProviderMetadata> getProvidersMap() {
-        Map<String,ProviderMetadata> result = Maps.newLinkedHashMap();
-        for (ProviderMetadata p: Providers.all()) {
-            result.put(p.getId(), p);
-        }
-        return ImmutableMap.copyOf(result);
-    }
-
-    private static Map<String,ApiMetadata> getApisMap() {
-        Map<String,ApiMetadata> result = Maps.newLinkedHashMap();
-        for (ApiMetadata api: Apis.all()) {
-            result.put(api.getId(), api);
-        }
-        return ImmutableMap.copyOf(result);
-    }
-
     public static final Collection<String> AWS_REGIONS = Arrays.asList(
             // from http://docs.amazonwebservices.com/general/latest/gr/rande.html as of
Apr 2012.
             // it is suggested not to maintain this list here, instead to require aws-ec2
explicitly named.
@@ -137,11 +111,11 @@ public class JcloudsLocationResolver implements LocationResolver {
         }
 
         public boolean isProvider() {
-            return PROVIDERS.containsKey(providerOrApi);
+            return JcloudsProviderAndApiLoader.isProvider(providerOrApi);
         }
 
         public boolean isApi() {
-            return APIS.containsKey(providerOrApi);
+            return JcloudsProviderAndApiLoader.isApi(providerOrApi);
         }
         
         public String getProviderOrApi() {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/819632dc/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsProviderAndApiLoader.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsProviderAndApiLoader.java
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsProviderAndApiLoader.java
new file mode 100644
index 0000000..b870e3f
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsProviderAndApiLoader.java
@@ -0,0 +1,99 @@
+/*
+ * 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.brooklyn.location.jclouds;
+
+import java.util.Map;
+import java.util.ServiceLoader;
+
+import org.apache.brooklyn.util.text.Strings;
+import org.jclouds.apis.ApiMetadata;
+import org.jclouds.apis.ApiPredicates;
+import org.jclouds.osgi.ApiRegistry;
+import org.jclouds.osgi.ProviderRegistry;
+import org.jclouds.providers.ProviderMetadata;
+import org.jclouds.providers.ProviderPredicates;
+import org.jclouds.providers.Providers;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+
+/**
+ * Retrieves a given jclouds provider or API. It stores the service-loader providers so as
to 
+ * avoid repeatedly calling the {@link java.util.ServiceLoader}. This is fairly safe to do,

+ * as they are normally only available if using a classic "java main" rather than an OSGi
+ * container. For the latter, we query jclouds each time so that the list can be dynamic
as
+ * bundles are added/removed.
+ */
+@Beta
+public class JcloudsProviderAndApiLoader {
+
+    public static final Logger log = LoggerFactory.getLogger(JcloudsProviderAndApiLoader.class);
+    
+    private enum LazyServiceLoader {
+        INSTANCE;
+
+        public final Map<String,ProviderMetadata> providers;
+        public final Map<String,ApiMetadata> apis;
+        
+        LazyServiceLoader() {
+            Map<String,ProviderMetadata> providersTmp = Maps.newLinkedHashMap();
+            for (ProviderMetadata p: Providers.fromServiceLoader()) {
+                providersTmp.put(p.getId(), p);
+            }
+            providers = ImmutableMap.copyOf(providersTmp);
+            
+            // Unfortunately Apis.fromServiceLoader() is private
+            Map<String,ApiMetadata> apisTmp = Maps.newLinkedHashMap();
+            ServiceLoader.load(ApiMetadata.class);
+            for (ApiMetadata p: ServiceLoader.load(ApiMetadata.class)) {
+                apisTmp.put(p.getId(), p);
+            }
+            apis = ImmutableMap.copyOf(apisTmp);
+        }
+    }
+    
+    public static boolean isProvider(String id) {
+        if (Strings.isBlank(id)) return false;
+        return getProvider(id).isPresent();
+    }
+
+    public static boolean isApi(String id) {
+        if (Strings.isBlank(id)) return false;
+        return getApi(id).isPresent();
+    }
+    
+    public static Optional<ProviderMetadata> getProvider(String id) {
+        if (LazyServiceLoader.INSTANCE.providers.containsKey(id)) {
+            return Optional.of(LazyServiceLoader.INSTANCE.providers.get(id));
+        }
+        return Iterables.tryFind(ProviderRegistry.fromRegistry(), ProviderPredicates.id(id));
+    }
+
+    public static Optional<ApiMetadata> getApi(String id) {
+        if (LazyServiceLoader.INSTANCE.apis.containsKey(id)) {
+            return Optional.of(LazyServiceLoader.INSTANCE.apis.get(id));
+        }
+        return Iterables.tryFind(ApiRegistry.fromRegistry(), ApiPredicates.id(id));
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/819632dc/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsProviderAndApiLoaderTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsProviderAndApiLoaderTest.java
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsProviderAndApiLoaderTest.java
new file mode 100644
index 0000000..5dfaca1
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsProviderAndApiLoaderTest.java
@@ -0,0 +1,142 @@
+/*
+ * 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.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.net.URI;
+
+import org.jclouds.apis.ApiMetadata;
+import org.jclouds.apis.internal.BaseApiMetadata;
+import org.jclouds.aws.ec2.AWSEC2ApiMetadata;
+import org.jclouds.osgi.ApiRegistry;
+import org.jclouds.osgi.ProviderRegistry;
+import org.jclouds.providers.ProviderMetadata;
+import org.jclouds.providers.internal.BaseProviderMetadata;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Optional;
+
+public class JcloudsProviderAndApiLoaderTest {
+
+    @Test
+    public void testGetProvider() throws Exception {
+        assertIsProvider("aws-ec2");
+    }
+    
+    @Test
+    public void testGetApi() throws Exception {
+        assertIsApi("ec2");
+    }
+    
+    @Test
+    public void testRegisteredProvider() throws Exception {
+        String id = "my-example-provider";
+        assertFalse(JcloudsProviderAndApiLoader.isProvider(id));
+        
+        ProviderMetadata provider = new BaseProviderMetadata.Builder()
+                .id(id)
+                .name("My Example Provider")
+                .apiMetadata(new AWSEC2ApiMetadata())
+                .build();
+        ProviderRegistry.registerProvider(provider);
+        try {
+            assertIsProvider(id);
+            
+            ProviderRegistry.unregisterProvider(provider);
+            assertFalse(JcloudsProviderAndApiLoader.isProvider(id));
+            
+        } finally {
+            ProviderRegistry.unregisterProvider(provider);
+        }
+    }
+    
+    @Test
+    public void testRegisteredApi() throws Exception {
+        String id = "my-example-api";
+        assertFalse(JcloudsProviderAndApiLoader.isApi(id));
+        
+        ApiMetadata api = new MyExampleApiMetadata.Builder()
+                .id(id)
+                .name("My Example API")
+                .identityName("myIdName")
+                .documentation(URI.create("http://myexampleapi/docs"))
+                .build();
+        ApiRegistry.registerApi(api);
+        try {
+            assertIsApi(id);
+            
+            ApiRegistry.unRegisterApi(api);
+            assertFalse(JcloudsProviderAndApiLoader.isApi(id));
+            
+        } finally {
+            ApiRegistry.unRegisterApi(api);
+        }
+    }
+    
+    private void assertIsProvider(String id) {
+        Optional<ProviderMetadata> result = JcloudsProviderAndApiLoader.getProvider(id);
+        assertTrue(result.isPresent());
+        assertEquals(result.get().getId(), id);
+        
+        Optional<ApiMetadata> result2 = JcloudsProviderAndApiLoader.getApi(id);
+        assertFalse(result2.isPresent(), "result="+result2);
+        
+        assertTrue(JcloudsProviderAndApiLoader.isProvider(id));
+        assertFalse(JcloudsProviderAndApiLoader.isApi(id));
+    }
+
+    private void assertIsApi(String id) {
+        Optional<ApiMetadata> result = JcloudsProviderAndApiLoader.getApi(id);
+        assertTrue(result.isPresent());
+        assertEquals(result.get().getId(), id);
+        
+        Optional<ProviderMetadata> result2 = JcloudsProviderAndApiLoader.getProvider(id);
+        assertFalse(result2.isPresent(), "result="+result2);
+        
+        assertTrue(JcloudsProviderAndApiLoader.isApi(id));
+        assertFalse(JcloudsProviderAndApiLoader.isProvider(id));
+    }
+    
+    static class MyExampleApiMetadata extends BaseApiMetadata {
+        public MyExampleApiMetadata() {
+            super(new Builder());
+        }
+        
+        public MyExampleApiMetadata(Builder builder) {
+            super(builder);
+        }
+        
+        static class Builder extends BaseApiMetadata.Builder<Builder> {
+            protected Builder self() {
+                return this;
+            }
+            @Override
+            public MyExampleApiMetadata build() {
+                return new MyExampleApiMetadata(this);
+            }
+        }
+        
+        @Override public org.jclouds.apis.ApiMetadata.Builder<?> toBuilder() {
+            throw new UnsupportedOperationException();
+        }
+    }
+}


Mime
View raw message