Repository: brooklyn-server
Updated Branches:
  refs/heads/master 84eba7e31 -> 17e3d1fdf


BROOKLYN-421: add tests for catalog library loading


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

Branch: refs/heads/master
Commit: 0fc7820dba7ce149fb172527b0bca66d058fe7af
Parents: b294f41
Author: Aled Sage <aled.s...@gmail.com>
Authored: Thu Dec 22 12:26:33 2016 +0000
Committer: Aled Sage <aled.s...@gmail.com>
Committed: Thu Jan 5 16:52:34 2017 +0000

----------------------------------------------------------------------
 .../catalog/CatalogOsgiLibraryTest.java         | 285 +++++++++++++++++++
 .../TestHttpRecordingRequestInterceptor.java    |  55 ++++
 .../test/http/TestHttpRequestHandler.java       |   6 +
 .../brooklyn/test/http/TestHttpServer.java      |   4 +-
 4 files changed, 348 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0fc7820d/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiLibraryTest.java
----------------------------------------------------------------------
diff --git 
a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiLibraryTest.java
 
b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiLibraryTest.java
new file mode 100644
index 0000000..94adcdd
--- /dev/null
+++ 
b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiLibraryTest.java
@@ -0,0 +1,285 @@
+/*
+ * 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.camp.brooklyn.catalog;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Map;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.core.config.external.AbstractExternalConfigSupplier;
+import org.apache.brooklyn.core.mgmt.internal.ExternalConfigSupplierRegistry;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.entity.stock.BasicApplication;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.http.TestHttpRecordingRequestInterceptor;
+import org.apache.brooklyn.test.http.TestHttpRequestHandler;
+import org.apache.brooklyn.test.http.TestHttpServer;
+import org.apache.brooklyn.test.support.TestResourceUnavailableException;
+import org.apache.brooklyn.util.net.Urls;
+import org.apache.brooklyn.util.osgi.OsgiTestResources;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.http.Header;
+import org.apache.http.HttpRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.io.BaseEncoding;
+import com.google.common.net.UrlEscapers;
+
+public class CatalogOsgiLibraryTest extends AbstractYamlTest {
+    
+    @SuppressWarnings("unused")
+    private static final Logger log = 
LoggerFactory.getLogger(CatalogOsgiLibraryTest.class);
+
+    private TestHttpServer webServer;
+    private TestHttpRecordingRequestInterceptor requestInterceptor;
+    
+    private String jarName = 
OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SYMBOLIC_NAME_FINAL_PART + ".jar";
+    private String malformedJarName = "thisIsNotAJar.jar";
+    private String classpathUrl = "classpath:" + 
OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH;
+    private URL jarUrl;
+    private URL malformedJarUrl;
+    
+    @BeforeMethod(alwaysRun = true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        
+        // Load the bytes of the jar
+        
TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), 
"/brooklyn/osgi/" + jarName);
+        InputStream resource = 
getClass().getResourceAsStream("/brooklyn/osgi/" + jarName);
+        final byte[] jarBytes = Streams.readFullyAndClose(resource);
+        
+        // Start a mock web-server that will return the jar
+        requestInterceptor = new TestHttpRecordingRequestInterceptor();
+        webServer = new TestHttpServer()
+                .handler("/" + jarName, new 
TestHttpRequestHandler().code(200).response(jarBytes))
+                .handler("/" + malformedJarName, new 
TestHttpRequestHandler().code(200).response("simulating-malformed-jar"))
+                .interceptor(requestInterceptor)
+                .start();
+        jarUrl = new URL(Urls.mergePaths(webServer.getUrl(), jarName));
+        malformedJarUrl = new URL(Urls.mergePaths(webServer.getUrl(), 
malformedJarName));
+    }
+
+    @AfterMethod(alwaysRun = true)
+    @Override
+    public void tearDown() throws Exception {
+        try {
+            if (webServer != null) webServer.stop();
+        } finally {
+            super.tearDown();
+        }
+    }
+    
+    @Override
+    protected boolean disableOsgi() {
+        return false;
+    }
+
+    @Test
+    public void testLibraryStringWithClasspathUrl() throws Exception {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: simple-osgi-library",
+                "  version: \"1.0\"",
+                "  itemType: template",
+                "  libraries:",
+                "  - " + classpathUrl,
+                "  item:",
+                "    services:",
+                "    - type: 
org.apache.brooklyn.test.osgi.entities.SimpleApplication");
+
+        CatalogItem<?, ?> item = 
mgmt().getCatalog().getCatalogItem("simple-osgi-library", "1.0");
+        assertCatalogLibraryUrl(item, classpathUrl);
+    }
+
+    @Test
+    public void testLibraryMapWithClasspathUrl() throws Exception {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: simple-osgi-library",
+                "  version: \"1.0\"",
+                "  itemType: template",
+                "  libraries:",
+                "  - url: " + classpathUrl,
+                "  item:",
+                "    services:",
+                "    - type: 
org.apache.brooklyn.test.osgi.entities.SimpleApplication");
+
+        CatalogItem<?, ?> item = 
mgmt().getCatalog().getCatalogItem("simple-osgi-library", "1.0");
+        assertCatalogLibraryUrl(item, classpathUrl);
+    }
+
+    @Test
+    public void testLibraryHttpUrl() throws Exception {
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: simple-osgi-library",
+                "  version: \"1.0\"",
+                "  itemType: template",
+                "  libraries:",
+                "  - " + jarUrl,
+                "  item:",
+                "    services:",
+                "    - type: 
org.apache.brooklyn.test.osgi.entities.SimpleApplication");
+
+        CatalogItem<?, ?> item = 
mgmt().getCatalog().getCatalogItem("simple-osgi-library", "1.0");
+        assertCatalogLibraryUrl(item, jarUrl.toString());
+    }
+
+    @Test
+    public void testLibraryUrlDoesNotExist() throws Exception {
+        String wrongUrl = "classpath:/path/does/not/exist/aefjaifjie3kdd.jar";
+        try {
+            addCatalogItems(
+                    "brooklyn.catalog:",
+                    "  id: simple-osgi-library",
+                    "  version: \"1.0\"",
+                    "  itemType: template",
+                    "  libraries:",
+                    "  - " + wrongUrl,
+                    "  item:",
+                    "    services:",
+                    "    - type: " + BasicApplication.class.getName());
+            Asserts.shouldHaveFailedPreviously();
+        } catch (Exception e) {
+            if (!e.toString().contains("Bundle from " + wrongUrl + " failed to 
install")) {
+                throw e;
+            }
+        }
+    }
+
+    @Test
+    public void testLibraryMalformed() throws Exception {
+        try {
+            addCatalogItems(
+                    "brooklyn.catalog:",
+                    "  id: simple-osgi-library",
+                    "  version: \"1.0\"",
+                    "  itemType: template",
+                    "  libraries:",
+                    "  - " + malformedJarUrl,
+                    "  item:",
+                    "    services:",
+                    "    - type: " + BasicApplication.class.getName());
+            Asserts.shouldHaveFailedPreviously();
+        } catch (Exception e) {
+            if (!e.toString().contains("not a jar file")) {
+                throw e;
+            }
+        }
+    }
+
+    @Test
+    public void testLibraryUrlUsingExternalizedConfig() throws Exception {
+        // Add an externalized config provider, which will return us the url
+        Map<String, String> externalConfig = ImmutableMap.of("url", 
classpathUrl);
+        ExternalConfigSupplierRegistry externalConfigProviderRegistry = 
((ManagementContextInternal)mgmt()).getExternalConfigProviderRegistry();
+        externalConfigProviderRegistry.addProvider("myprovider", new 
MyExternalConfigSupplier(mgmt(), "myprovider", externalConfig));
+
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: simple-osgi-library",
+                "  version: \"1.0\"",
+                "  itemType: template",
+                "  libraries:",
+                "  - $brooklyn:external(\"myprovider\", \"url\")",
+                "  item:",
+                "    services:",
+                "    - type: 
org.apache.brooklyn.test.osgi.entities.SimpleApplication");
+
+        CatalogItem<?, ?> item = 
mgmt().getCatalog().getCatalogItem("simple-osgi-library", "1.0");
+        assertCatalogLibraryUrl(item, classpathUrl);
+    }
+    
+    // TODO See https://issues.apache.org/jira/browse/BROOKLYN-421
+    //      Need to somehow escape the username and password (or include them 
explicitly as a 
+    //      "Authorization" header instead of embedding them in the URI).
+    @Test(groups="Broken")
+    public void testLibraryUrlUsingExternalizedConfigForCredentials() throws 
Exception {
+        String username = "myu...@mydomain.com";
+        String password = "Myp4ss@?/:!";
+        
+        // Add an externalized config provider, which will return us a 
username + password
+        Map<String, String> externalConfig = ImmutableMap.of("username", 
username, "password", password);
+        ExternalConfigSupplierRegistry externalConfigProviderRegistry = 
((ManagementContextInternal)mgmt()).getExternalConfigProviderRegistry();
+        externalConfigProviderRegistry.addProvider("myprovider", new 
MyExternalConfigSupplier(mgmt(), "myprovider", externalConfig));
+
+        addCatalogItems(
+                "brooklyn.catalog:",
+                "  id: simple-osgi-library",
+                "  version: \"1.0\"",
+                "  itemType: template",
+                "  libraries:",
+                "  - $brooklyn:formatString:",
+                "    - http://%s:%s@"; + jarUrl.getHost() + ":" + 
jarUrl.getPort() + jarUrl.getPath(),
+                "    - $brooklyn:external(\"myprovider\", \"username\")",
+                "    - $brooklyn:external(\"myprovider\", \"password\")",
+                "  item:",
+                "    services:",
+                "    - type: 
org.apache.brooklyn.test.osgi.entities.SimpleApplication");
+
+        // Expect basic-auth used when retrieving jar
+        HttpRequest req = requestInterceptor.getLastRequest();
+        Header[] authHeaders = req.getHeaders("Authorization");
+        assertEquals(authHeaders.length, 1, "authHeaders=" + 
Arrays.toString(authHeaders));
+        String authHeader = authHeaders[0].getValue();
+        String expectedHeader = "Basic " + 
BaseEncoding.base64().encode((username + ":" + 
password).getBytes(StandardCharsets.UTF_8));
+        assertEquals(authHeader, expectedHeader, "headers=" + 
Arrays.toString(req.getAllHeaders()));
+
+        // Expect url to have been correctly escaped
+        String escapedUsername = 
UrlEscapers.urlFragmentEscaper().escape(username);
+        String escapedPassword = 
UrlEscapers.urlFragmentEscaper().escape(password);
+        String expectedUrl = "http://"; + escapedUsername + ":" + 
escapedPassword+ "@" + jarUrl.getHost() + ":" + jarUrl.getPort() + 
jarUrl.getPath();
+        
+        CatalogItem<?, ?> item = 
mgmt().getCatalog().getCatalogItem("simple-osgi-library", "1.0");
+        assertCatalogLibraryUrl(item, expectedUrl);
+    }
+    
+    public static class MyExternalConfigSupplier extends 
AbstractExternalConfigSupplier {
+        private final Map<String, String> conf;
+
+        public MyExternalConfigSupplier(ManagementContext mgmt, String name, 
Map<String, String> conf) {
+            super(mgmt, name);
+            this.conf = conf;
+        }
+
+        @Override public String get(String key) {
+            return conf.get(key);
+        }
+    }
+    
+    protected void assertCatalogLibraryUrl(CatalogItem<?,?> item, String 
expectedUrl) {
+        CatalogBundle library = Iterables.getOnlyElement(item.getLibraries());
+        assertEquals(library.getUrl(), expectedUrl);
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0fc7820d/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpRecordingRequestInterceptor.java
----------------------------------------------------------------------
diff --git 
a/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpRecordingRequestInterceptor.java
 
b/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpRecordingRequestInterceptor.java
new file mode 100644
index 0000000..aeba4b7
--- /dev/null
+++ 
b/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpRecordingRequestInterceptor.java
@@ -0,0 +1,55 @@
+/*
+ * 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.test.http;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.protocol.HttpContext;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+public class TestHttpRecordingRequestInterceptor implements 
HttpRequestInterceptor {
+
+    private final List<HttpRequest> requests = 
Collections.synchronizedList(Lists.<HttpRequest>newArrayList());
+    
+    public List<HttpRequest> getRequests() {
+        synchronized (requests) {
+            return ImmutableList.copyOf(requests);
+        }
+    }
+    
+    public HttpRequest getLastRequest() {
+        synchronized (requests) {
+            if (requests.isEmpty()) throw new NoSuchElementException("No 
http-requests received");
+            return requests.get(requests.size()-1);
+        }
+    }
+    
+    @Override
+    public void process(HttpRequest request, HttpContext context) throws 
HttpException, IOException {
+        requests.add(request);
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0fc7820d/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpRequestHandler.java
----------------------------------------------------------------------
diff --git 
a/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpRequestHandler.java
 
b/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpRequestHandler.java
index 18f5c44..af47c8a 100644
--- 
a/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpRequestHandler.java
+++ 
b/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpRequestHandler.java
@@ -30,6 +30,7 @@ import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
+import org.apache.http.entity.ByteArrayEntity;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.message.BasicHeader;
 import org.apache.http.protocol.HttpContext;
@@ -49,6 +50,11 @@ public class TestHttpRequestHandler implements 
HttpRequestHandler {
         return this;
     }
 
+    public TestHttpRequestHandler response(byte[] response) {
+        this.entity = new ByteArrayEntity(response);
+        return this;
+    }
+
     public TestHttpRequestHandler code(int responseCode) {
         this.responseCode = responseCode;
         return this;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/0fc7820d/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpServer.java
----------------------------------------------------------------------
diff --git 
a/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpServer.java 
b/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpServer.java
index b114b0a..3a34deb 100644
--- 
a/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpServer.java
+++ 
b/utils/common/src/main/java/org/apache/brooklyn/test/http/TestHttpServer.java
@@ -59,7 +59,7 @@ public class TestHttpServer {
         return this;
     }
 
-    public TestHttpServer requestInterceptors(List<HttpResponseInterceptor> 
interceptors) {
+    public TestHttpServer responseInterceptors(List<HttpResponseInterceptor> 
interceptors) {
         checkNotStarted();
         this.responseInterceptors = interceptors;
         return this;
@@ -71,7 +71,7 @@ public class TestHttpServer {
         return this;
     }
 
-    public TestHttpServer responseInterceptors(List<HttpRequestInterceptor> 
interceptors) {
+    public TestHttpServer requestInterceptors(List<HttpRequestInterceptor> 
interceptors) {
         checkNotStarted();
         this.requestInterceptors = interceptors;
         return this;

Reply via email to