You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sv...@apache.org on 2016/04/20 18:37:36 UTC

[1/3] brooklyn-server git commit: Add catalog.bom application white/blacklists.

Repository: brooklyn-server
Updated Branches:
  refs/heads/master fee7438f9 -> bc0362bac


Add catalog.bom application white/blacklists.

Any bundle with a catalog.bom file may specify applications to
appear in the catalog (itemType: template).

It is desirable to have a config time mechanism to control what
bundles are allowed to present applications in the catalog and
what aren't.

This change adds a white/blacklist mechanism to the catalog.bom
bundle scanning. Each list takes the form of a CSV whitelist of
regexes to match against bundle symbolic ids.  A bundle will be
allowed to add an application (template) to the catalog if its
bundle id matches one of the regexes on the whitelist, and also
does not match one of the regexes on the blacklist.

The configuration keys and default values for the lists are:

brooklyn.catalog.osgi.application.whitelist=.*
brooklyn.catalog.osgi.application.blacklist=

(i.e. by default accept all bundles).

these values are specified in the file org.apache.brooklyn.core.catalog.bomscanner.cfg

Note that two 'default' example applications are supplied in the bom
for brooklyn-software-base.


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

Branch: refs/heads/master
Commit: 7046ba59cefd7e82ffad3f97057b3646915d1f08
Parents: 06f68e1
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Thu Apr 7 09:34:54 2016 +0100
Committer: Geoff Macartney <ge...@cloudsoftcorp.com>
Committed: Thu Apr 14 16:59:30 2016 +0100

----------------------------------------------------------------------
 .../catalog/internal/CatalogBomScanner.java     | 105 +++++++++++++---
 core/src/main/resources/catalog.bom             |   3 +-
 ....apache.brooklyn.core.catalog.bomscanner.cfg |  27 +++++
 .../resources/OSGI-INF/blueprint/blueprint.xml  |   8 +-
 policy/src/main/resources/catalog.bom           |   3 +-
 server-cli/src/main/resources/catalog.bom       |   1 -
 software/base/src/main/resources/catalog.bom    | 121 ++++++++++++++++++-
 test-framework/src/main/resources/catalog.bom   |   3 +-
 .../entities/src/main/resources/catalog.bom     |   5 +-
 .../src/main/resources/catalog.bom              |   3 +-
 .../src/main/resources/catalog.bom              |   3 +-
 .../src/main/resources/catalog.bom              |   3 +-
 .../org/apache/brooklyn/util/text/Strings.java  |  13 ++
 13 files changed, 263 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7046ba59/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java
index 01d25f5..9c14d6d 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java
@@ -21,12 +21,12 @@ package org.apache.brooklyn.core.catalog.internal;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
-import org.apache.brooklyn.api.catalog.BrooklynCatalog;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.yaml.Yamls;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleEvent;
@@ -34,6 +34,7 @@ import org.osgi.framework.ServiceReference;
 import org.osgi.util.tracker.BundleTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.yaml.snakeyaml.DumperOptions;
 import org.yaml.snakeyaml.Yaml;
 
 import java.io.IOException;
@@ -42,17 +43,26 @@ import java.net.URL;
 import java.util.List;
 import java.util.Map;
 
+import static org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType.TEMPLATE;
+
 public class CatalogBomScanner {
 
+    private final String ACCEPT_ALL_BY_DEFAULT = ".*";
+
     private static final Logger LOG = LoggerFactory.getLogger(CatalogBomScanner.class);
     private static final String CATALOG_BOM_URL = "catalog.bom";
     private static final String BROOKLYN_CATALOG = "brooklyn.catalog";
     private static final String BROOKLYN_LIBRARIES = "brooklyn.libraries";
 
+    private List<String> whiteList = ImmutableList.of(ACCEPT_ALL_BY_DEFAULT);
+    private List<String> blackList = ImmutableList.of();
+
     private CatalogPopulator catalogTracker;
 
     public void bind(ServiceReference<ManagementContext> managementContext) throws Exception {
-        LOG.debug("Binding management context");
+        LOG.debug("Binding management context with whiteList [{}] and blacklist [{}]",
+            Strings.join(getWhiteList(), "; "),
+            Strings.join(getBlackList(), "; "));
         catalogTracker = new CatalogPopulator(managementContext);
     }
 
@@ -71,9 +81,35 @@ public class CatalogBomScanner {
         };
     }
 
+    public List<String> getWhiteList() {
+        return whiteList;
+    }
+
+    public void setWhiteList(List<String> whiteList) {
+        this.whiteList = whiteList;
+    }
+
+    public void setWhiteList(String whiteListText) {
+        LOG.debug("Setting whiteList to ", whiteListText);
+        this.whiteList = Strings.parseCsv(whiteListText, ",");
+    }
+
+    public List<String> getBlackList() {
+        return blackList;
+    }
+
+    public void setBlackList(List<String> blackList) {
+        this.blackList = blackList;
+    }
+
+    public void setBlackList(String blackListText) {
+        LOG.debug("Setting blackList to ", blackListText);
+        this.blackList = Strings.parseCsv(blackListText, ",");
+    }
 
     public class CatalogPopulator extends BundleTracker<Iterable<? extends CatalogItem<?, ?>>> {
 
+
         private ServiceReference<ManagementContext> mgmtContextReference;
         private ManagementContext managementContext;
 
@@ -121,25 +157,27 @@ public class CatalogBomScanner {
                 return;
             }
             LOG.debug("Unloading catalog BOM entries from {} {} {}", bundleIds(bundle));
-            final BrooklynCatalog catalog = getManagementContext().getCatalog();
             for (CatalogItem<?, ?> item : items) {
                 LOG.debug("Unloading {} {} from catalog", item.getSymbolicName(), item.getVersion());
 
-                try {
-                    catalog.deleteCatalogItem(item.getSymbolicName(), item.getVersion());
-                } catch (Exception e) {
-                    // Gobble exception to avoid possibility of causing problems stopping bundle.
-                    LOG.warn("Caught {} unloading {} {} from catalog, ignoring", new String [] {
-                        e.getMessage(), item.getSymbolicName(), item.getVersion()
-                    });
-                    Exceptions.propagateIfFatal(e);
-                }
+                removeFromCatalog(item);
+            }
+        }
+
+        private void removeFromCatalog(CatalogItem<?, ?> item) {
+            try {
+                getManagementContext().getCatalog().deleteCatalogItem(item.getSymbolicName(), item.getVersion());
+            } catch (Exception e) {
+                Exceptions.propagateIfFatal(e);
+                LOG.warn(Strings.join(new String[] {
+                    "Failed to remove", item.getSymbolicName(), item.getVersion(), "{} {} from catalog"
+                }, " "), e);
             }
         }
 
         private Iterable<? extends CatalogItem<?, ?>> scanForCatalog(Bundle bundle) {
 
-            Iterable<? extends CatalogItem<?, ?>> catalogItems = ImmutableList.of();
+            Iterable<? extends CatalogItem<?, ?>> catalogItems = MutableList.of();
 
             final URL bom = bundle.getResource(CATALOG_BOM_URL);
             if (null != bom) {
@@ -155,9 +193,40 @@ public class CatalogBomScanner {
                 LOG.debug("No BOM found in {} {} {}", bundleIds(bundle));
             }
 
+            if (!passesWhiteAndBlacklists(bundle)) {
+                catalogItems = removeAnyApplications(catalogItems);
+            }
+
             return catalogItems;
         }
 
+        private Iterable<? extends CatalogItem<?, ?>> removeAnyApplications(Iterable<? extends CatalogItem<?, ?>> catalogItems) {
+            List<CatalogItem<?, ?>> result = MutableList.of();
+
+            for (CatalogItem<?, ?> item: catalogItems) {
+                if (TEMPLATE.equals(item.getCatalogItemType())) {
+                    removeFromCatalog(item);
+                } else {
+                    result.add(item);
+                }
+            }
+            return result;
+        }
+
+        private boolean passesWhiteAndBlacklists(Bundle bundle) {
+            return on(bundle, getWhiteList()) && !on(bundle, getBlackList());
+        }
+
+        private boolean on(Bundle bundle, List<String> list) {
+            for (String candidate : list) {
+                final String symbolicName = bundle.getSymbolicName();
+                if (symbolicName.matches(candidate.trim())) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
         private String addLibraryDetails(Bundle bundle, String bomText) {
             final Map<String, Object> bom = (Map<String, Object>)Iterables.getOnlyElement(Yamls.parseAll(bomText));
             final Object catalog = bom.get(BROOKLYN_CATALOG);
@@ -168,11 +237,18 @@ public class CatalogBomScanner {
                     LOG.warn("Unexpected syntax for {} (expected Map), ignoring", BROOKLYN_CATALOG);
                 }
             }
-            final String updatedBom = new Yaml().dump(bom);
+            final String updatedBom = backToYaml(bom);
             LOG.trace("Updated catalog bom:\n{}", updatedBom);
             return updatedBom;
         }
 
+        private String backToYaml(Map<String, Object> bom) {
+            final DumperOptions options = new DumperOptions();
+            options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
+            options.setPrettyFlow(true);
+            return new Yaml(options).dump(bom);
+        }
+
         private void addLibraryDetails(Bundle bundle, Map<String, Object> catalog) {
             if (!catalog.containsKey(BROOKLYN_LIBRARIES)) {
                 catalog.put(BROOKLYN_LIBRARIES, MutableList.of());
@@ -198,4 +274,5 @@ public class CatalogBomScanner {
 
     }
 
+
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7046ba59/core/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/core/src/main/resources/catalog.bom b/core/src/main/resources/catalog.bom
index 735b582..de388c3 100644
--- a/core/src/main/resources/catalog.bom
+++ b/core/src/main/resources/catalog.bom
@@ -16,8 +16,7 @@
 # under the License.
 
 brooklyn.catalog:
-    version: 0.9.0
-    scanJavaAnnotations: true
+    version: 0.10.0-SNAPSHOT # BROOKLYN_VERSION
     items:
     - id: org.apache.brooklyn.entity.group.QuarantineGroup
       item:

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7046ba59/karaf/apache-brooklyn/src/main/resources/etc/org.apache.brooklyn.core.catalog.bomscanner.cfg
----------------------------------------------------------------------
diff --git a/karaf/apache-brooklyn/src/main/resources/etc/org.apache.brooklyn.core.catalog.bomscanner.cfg b/karaf/apache-brooklyn/src/main/resources/etc/org.apache.brooklyn.core.catalog.bomscanner.cfg
new file mode 100644
index 0000000..242dfd6
--- /dev/null
+++ b/karaf/apache-brooklyn/src/main/resources/etc/org.apache.brooklyn.core.catalog.bomscanner.cfg
@@ -0,0 +1,27 @@
+################################################################################
+#
+#    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.
+#
+################################################################################
+
+# CSV Whitelist of regular expressions to match bundle symbolic id if bundle is to be permitted to add
+# applications (templates) to the catalog
+whiteList=.*
+
+# CSV Blacklist of regular expressions to match bundle symbolic id to prevent selected whitelisted bundles
+# adding applications (templates) to the catalog
+blackList=
+

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7046ba59/karaf/init/src/main/resources/OSGI-INF/blueprint/blueprint.xml
----------------------------------------------------------------------
diff --git a/karaf/init/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/karaf/init/src/main/resources/OSGI-INF/blueprint/blueprint.xml
index 36c0fef..ccaea29 100644
--- a/karaf/init/src/main/resources/OSGI-INF/blueprint/blueprint.xml
+++ b/karaf/init/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -93,13 +93,15 @@ limitations under the License.
         </interfaces>
     </service>
 
+    <bean id="bomScanner" class="org.apache.brooklyn.core.catalog.internal.CatalogBomScanner" >
+        <cm:managed-properties persistent-id="org.apache.brooklyn.core.catalog.bomscanner" update-strategy="container-managed"/>
+    </bean>
+
     <reference-list id="managementContextReferences"
                     interface="org.apache.brooklyn.api.mgmt.ManagementContext"
                     availability="optional">
 
-        <reference-listener bind-method="bind" unbind-method="unbind">
-            <bean class="org.apache.brooklyn.core.catalog.internal.CatalogBomScanner" />
-        </reference-listener>
+        <reference-listener bind-method="bind" unbind-method="unbind" ref="bomScanner"/>
     </reference-list>
 
 </blueprint>

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7046ba59/policy/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/policy/src/main/resources/catalog.bom b/policy/src/main/resources/catalog.bom
index 439a443..d8c7d79 100644
--- a/policy/src/main/resources/catalog.bom
+++ b/policy/src/main/resources/catalog.bom
@@ -16,8 +16,7 @@
 # under the License.
 
 brooklyn.catalog:
-    version: 0.9.0
-    scanJavaAnnotations: true
+    version: 0.10.0-SNAPSHOT # BROOKLYN_VERSION
     items:
     - id: org.apache.brooklyn.policy.ha.ConnectionFailureDetector
       item:

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7046ba59/server-cli/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/server-cli/src/main/resources/catalog.bom b/server-cli/src/main/resources/catalog.bom
index f5bc2a5..ec9e3d1 100644
--- a/server-cli/src/main/resources/catalog.bom
+++ b/server-cli/src/main/resources/catalog.bom
@@ -7,7 +7,6 @@ brooklyn.catalog:
   items:
 
   # load everything in the classpath with a @Catalog annotation
-  - scanJavaAnnotations: true
 
   - id: server
     description: |

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7046ba59/software/base/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/catalog.bom b/software/base/src/main/resources/catalog.bom
index 001114a..3dbbaa4 100644
--- a/software/base/src/main/resources/catalog.bom
+++ b/software/base/src/main/resources/catalog.bom
@@ -16,8 +16,7 @@
 # under the License.
 
 brooklyn.catalog:
-    version: 0.9.0
-    scanJavaAnnotations: true
+    version: 0.10.0-SNAPSHOT # BROOKLYN_VERSION
     items:
     - id: org.apache.brooklyn.entity.machine.MachineEntity
       item:
@@ -70,3 +69,121 @@ brooklyn.catalog:
         type: org.apache.brooklyn.entity.machine.pool.ServerPool
         name: Server Pool
         description: Creates a pre-allocated server pool, which other applications can deploy to
+
+    - id: server-template
+      itemType: template
+      name: "Template: Server"
+      description: |
+        Sample YAML to provision a server in a cloud with illustrative VM properties
+      item:
+        name: Server (Brooklyn Example)
+
+        # this basic example shows how Brooklyn can provision a single raw VM
+        # in the cloud or location of your choice
+
+        services:
+        - type:           org.apache.brooklyn.entity.software.base.EmptySoftwareProcess
+          name:           My VM
+
+        # location can be e.g. `softlayer` or `jclouds:openstack-nova:https://9.9.9.9:9999/v2.0/`,
+        # or `localhost` or `byon:(hosts="10.9.1.1,10.9.1.2,produser2@10.9.2.{10,11,20-29}")`
+        location:
+          jclouds:aws-ec2:
+            # edit these to use your credential (or delete if credentials specified in brooklyn.properties)
+            identity:     <REPLACE>
+            credential:   <REPLACE>
+
+            region:       eu-central-1
+
+            # we want Ubuntu, with a lot of RAM
+            osFamily:     ubuntu
+            minRam:       8gb
+
+            # set up this user and password (default is to authorize a public key)
+            user:         sample
+            password:     s4mpl3
+
+
+    - id: bash-web-server-template
+      itemType: template
+      name: "Template: Bash Web Server"
+      description: |
+        Sample YAML building on Template "Server",
+        adding bash commands to launch a Python-based web server
+        on port 8020
+      item:
+        name: Python Web Server (Brooklyn Example)
+
+        # this example builds on the previous one,
+        # adding some scripts to initialize the VM
+
+        services:
+        - type:           org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
+          name:           My Bash Web Server VM
+          brooklyn.config:
+            install.command: |
+              # install python if not present
+              which python || \
+                { apt-get update && apt-get install python ; } || \
+                { yum update && yum install python ; } || \
+                { echo WARNING: cannot install python && exit 1 ; }
+
+            customize.command: |
+              # create the web page to serve
+              cat > index.html << EOF
+
+              Hello world.
+              <p>
+              I am ${ENTITY_INFO}, ${MESSAGE:-a Brooklyn sample}.
+              <p>
+              Created at: `date`
+              <p>
+              I am running at ${HOSTNAME}, with on-box IP configuration:
+              <pre>
+              `ifconfig | grep inet`
+              </pre>
+
+              EOF
+
+            launch.command: |
+              # launch in background (ensuring no streams open), and record PID to file
+              nohup python -m SimpleHTTPServer ${PORT:-8020} < /dev/null > output.txt 2>&1 &
+              echo $! > ${PID_FILE:-pid.txt}
+              sleep 5
+              ps -p `cat ${PID_FILE:-pid.txt}`
+              if [ $? -ne 0 ] ; then
+                cat output.txt
+                echo WARNING: python web server not running
+                exit 1
+              fi
+
+            shell.env:
+              HOSTNAME:     $brooklyn:attributeWhenReady("host.name")
+              PORT:         $brooklyn:config("my.app.port")
+              ENTITY_INFO:  $brooklyn:component("this", "")
+              MESSAGE:      $brooklyn:config("my.message")
+
+            # custom
+            my.app.port:  8020
+            my.message:   "good to meet you"
+
+          brooklyn.enrichers:
+          # publish the URL as a sensor; the GUI will pick this up (main.uri)
+          - type: org.apache.brooklyn.enricher.stock.Transformer
+            brooklyn.config:
+              uniqueTag: url-generator
+              enricher.sourceSensor: host.subnet.hostname
+              # use the definition from Attributes class, as it has a RendererHint so GUI makes it a link
+              enricher.targetSensor: $brooklyn:sensor("org.apache.brooklyn.core.entity.Attributes", "main.uri")
+              enricher.targetValue:
+                $brooklyn:formatString:
+                - "http://%s:%s/"
+                - $brooklyn:attributeWhenReady("host.subnet.hostname")
+                - $brooklyn:config("my.app.port")
+
+        location:
+          jclouds:aws-ec2:
+            region:       eu-central-1
+            # edit these (or delete if credentials specified in brooklyn.properties)
+            identity:     <REPLACE>
+            credential:   <REPLACE>

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7046ba59/test-framework/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/test-framework/src/main/resources/catalog.bom b/test-framework/src/main/resources/catalog.bom
index bd1b077..f912b4f 100644
--- a/test-framework/src/main/resources/catalog.bom
+++ b/test-framework/src/main/resources/catalog.bom
@@ -16,8 +16,7 @@
 # under the License.
 
 brooklyn.catalog:
-    version: 0.9.0
-    scanJavaAnnotations: true
+    version: 0.10.0-SNAPSHOT # BROOKLYN_VERSION
     items:
     - id: org.apache.brooklyn.test.framework.SimpleShellCommandTest
       item:

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7046ba59/utils/common/dependencies/osgi/entities/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/utils/common/dependencies/osgi/entities/src/main/resources/catalog.bom b/utils/common/dependencies/osgi/entities/src/main/resources/catalog.bom
index bfc1fe5..3531e4c 100644
--- a/utils/common/dependencies/osgi/entities/src/main/resources/catalog.bom
+++ b/utils/common/dependencies/osgi/entities/src/main/resources/catalog.bom
@@ -17,11 +17,10 @@
 
 
 brooklyn.catalog:
-    version: 0.9.0
-    scanJavaAnnotations: true
+    version: 0.10.0-SNAPSHOT # BROOKLYN_VERSION
     description: For testing loading catalog.bom with catalog scan
     displayName: I Haz Catalog
     items:
     -   id: simpleTest
         item:
-            type: org.apache.brooklyn.test.osgi.entities.SimpleEntity
\ No newline at end of file
+            type: org.apache.brooklyn.test.osgi.entities.SimpleEntity

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7046ba59/utils/common/dependencies/osgi/more-entities-v1/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/utils/common/dependencies/osgi/more-entities-v1/src/main/resources/catalog.bom b/utils/common/dependencies/osgi/more-entities-v1/src/main/resources/catalog.bom
index 863f660..ee9ce03 100644
--- a/utils/common/dependencies/osgi/more-entities-v1/src/main/resources/catalog.bom
+++ b/utils/common/dependencies/osgi/more-entities-v1/src/main/resources/catalog.bom
@@ -16,8 +16,7 @@
 # under the License.
 
 brooklyn.catalog:
-    version: 0.9.0
-    scanJavaAnnotations: true
+    version: 0.10.0-SNAPSHOT # BROOKLYN_VERSION
     items:
     - id: org.apache.brooklyn.test.osgi.entities.more.MoreEntity
       item:

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7046ba59/utils/common/dependencies/osgi/more-entities-v2-evil-twin/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/utils/common/dependencies/osgi/more-entities-v2-evil-twin/src/main/resources/catalog.bom b/utils/common/dependencies/osgi/more-entities-v2-evil-twin/src/main/resources/catalog.bom
index 863f660..ee9ce03 100644
--- a/utils/common/dependencies/osgi/more-entities-v2-evil-twin/src/main/resources/catalog.bom
+++ b/utils/common/dependencies/osgi/more-entities-v2-evil-twin/src/main/resources/catalog.bom
@@ -16,8 +16,7 @@
 # under the License.
 
 brooklyn.catalog:
-    version: 0.9.0
-    scanJavaAnnotations: true
+    version: 0.10.0-SNAPSHOT # BROOKLYN_VERSION
     items:
     - id: org.apache.brooklyn.test.osgi.entities.more.MoreEntity
       item:

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7046ba59/utils/common/dependencies/osgi/more-entities-v2/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/utils/common/dependencies/osgi/more-entities-v2/src/main/resources/catalog.bom b/utils/common/dependencies/osgi/more-entities-v2/src/main/resources/catalog.bom
index 75cc2e2..40a860f 100644
--- a/utils/common/dependencies/osgi/more-entities-v2/src/main/resources/catalog.bom
+++ b/utils/common/dependencies/osgi/more-entities-v2/src/main/resources/catalog.bom
@@ -16,8 +16,7 @@
 # under the License.
 
 brooklyn.catalog:
-    version: 0.9.0
-    scanJavaAnnotations: true
+    version: 0.10.0-SNAPSHOT # BROOKLYN_VERSION
     items:
     - id: org.apache.brooklyn.test.osgi.entities.more.MorePolicy
       item:

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7046ba59/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java b/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
index d092abb..96c81b1 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
@@ -916,4 +916,17 @@ public class Strings {
         return maxlenWithEllipsis(xs, optionalMax-8)+"/"+Integer.toHexString(xs.hashCode());
     }
 
+
+    /**
+     * Parses a string as comma separated values and returns a list of the entries with whitespace removed.
+     * @param csv
+     * @param separators
+     */
+    public static List<String> parseCsv(String csv, String separators) {
+        List<String> result = MutableList.of();
+        for (String value: csv.split(separators)) {
+            result.add(value.trim());
+        }
+        return result;
+    }
 }


[3/3] brooklyn-server git commit: Closes #106

Posted by sv...@apache.org.
Closes #106

Add catalog.bom application white/blacklists.

Note this PR depends on https://github.com/apache/brooklyn-server/pull/100 and should be merged after it.

It is desirable to have a config time mechanism to control what
bundles are allowed to present applications in the catalog and
what aren't.

This change adds a white/blacklist mechanism to the catalog.bom
bundle scanning. Each list takes the form of a CSV whitelist of
regexes to match against bundle symbolic ids.  A bundle will be
allowed to add an application (template) to the catalog if its
bundle id matches one of the regexes on the whitelist, and also
does not match one of the regexes on the blacklist.

The configuration keys and default values for the lists are:

brooklyn.catalog.osgi.application.whitelist=.*
brooklyn.catalog.osgi.application.blacklist=

(i.e. by default accept all bundles).

these values are specified in the file org.apache.brooklyn.core.catalog.bomscanner.cfg

Note that two 'default'  example applications are supplied in the bom
for brooklyn-software-base.


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

Branch: refs/heads/master
Commit: bc0362bacd0724777aae3a2cda6f25b7ed2c4322
Parents: fee7438 3277583
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Wed Apr 20 17:37:26 2016 +0100
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Wed Apr 20 17:37:26 2016 +0100

----------------------------------------------------------------------
 .../catalog/internal/CatalogBomScanner.java     | 107 ++++++++++--
 core/src/main/resources/catalog.bom             |   3 +-
 ....apache.brooklyn.core.catalog.bomscanner.cfg |  27 +++
 .../resources/OSGI-INF/blueprint/blueprint.xml  |   8 +-
 .../catalog/internal/CatalogBomScannerTest.java | 173 +++++++++++++++++++
 policy/src/main/resources/catalog.bom           |   3 +-
 server-cli/src/main/resources/catalog.bom       |   1 -
 software/base/src/main/resources/catalog.bom    | 121 ++++++++++++-
 test-framework/src/main/resources/catalog.bom   |   3 +-
 .../entities/src/main/resources/catalog.bom     |   5 +-
 .../src/main/resources/catalog.bom              |   3 +-
 .../src/main/resources/catalog.bom              |   3 +-
 .../src/main/resources/catalog.bom              |   3 +-
 .../org/apache/brooklyn/util/text/Strings.java  |  21 +++
 .../apache/brooklyn/util/text/StringsTest.java  |  26 +++
 15 files changed, 472 insertions(+), 35 deletions(-)
----------------------------------------------------------------------



[2/3] brooklyn-server git commit: Add integration tests for CatalogBomScanner.

Posted by sv...@apache.org.
Add integration tests for CatalogBomScanner.


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

Branch: refs/heads/master
Commit: 3277583f5e64722ffbfaee6f4eda7b5c7ffd357b
Parents: 7046ba5
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Fri Apr 15 16:58:57 2016 +0100
Committer: Geoff Macartney <ge...@cloudsoftcorp.com>
Committed: Wed Apr 20 17:28:54 2016 +0100

----------------------------------------------------------------------
 .../catalog/internal/CatalogBomScanner.java     |  10 +-
 .../catalog/internal/CatalogBomScannerTest.java | 173 +++++++++++++++++++
 .../org/apache/brooklyn/util/text/Strings.java  |  16 +-
 .../apache/brooklyn/util/text/StringsTest.java  |  26 +++
 4 files changed, 217 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/3277583f/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java
index 9c14d6d..ae2885a 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java
@@ -91,7 +91,7 @@ public class CatalogBomScanner {
 
     public void setWhiteList(String whiteListText) {
         LOG.debug("Setting whiteList to ", whiteListText);
-        this.whiteList = Strings.parseCsv(whiteListText, ",");
+        this.whiteList = Strings.parseCsv(whiteListText);
     }
 
     public List<String> getBlackList() {
@@ -104,7 +104,7 @@ public class CatalogBomScanner {
 
     public void setBlackList(String blackListText) {
         LOG.debug("Setting blackList to ", blackListText);
-        this.blackList = Strings.parseCsv(blackListText, ",");
+        this.blackList = Strings.parseCsv(blackListText);
     }
 
     public class CatalogPopulator extends BundleTracker<Iterable<? extends CatalogItem<?, ?>>> {
@@ -170,7 +170,7 @@ public class CatalogBomScanner {
             } catch (Exception e) {
                 Exceptions.propagateIfFatal(e);
                 LOG.warn(Strings.join(new String[] {
-                    "Failed to remove", item.getSymbolicName(), item.getVersion(), "{} {} from catalog"
+                    "Failed to remove", item.getSymbolicName(), item.getVersion(), "from catalog"
                 }, " "), e);
             }
         }
@@ -200,7 +200,9 @@ public class CatalogBomScanner {
             return catalogItems;
         }
 
-        private Iterable<? extends CatalogItem<?, ?>> removeAnyApplications(Iterable<? extends CatalogItem<?, ?>> catalogItems) {
+        private Iterable<? extends CatalogItem<?, ?>> removeAnyApplications(
+            Iterable<? extends CatalogItem<?, ?>> catalogItems) {
+
             List<CatalogItem<?, ?>> result = MutableList.of();
 
             for (CatalogItem<?, ?> item: catalogItems) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/3277583f/karaf/itest/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScannerTest.java
----------------------------------------------------------------------
diff --git a/karaf/itest/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScannerTest.java b/karaf/itest/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScannerTest.java
new file mode 100644
index 0000000..137ede4
--- /dev/null
+++ b/karaf/itest/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScannerTest.java
@@ -0,0 +1,173 @@
+/*
+ * 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.core.catalog.internal;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.BrooklynVersion;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.IntegrationTest;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.karaf.features.BootFinished;
+import org.apache.karaf.features.FeaturesService;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.karaf.options.KarafDistributionOption;
+import org.ops4j.pax.exam.karaf.options.LogLevelOption;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerClass;
+import org.ops4j.pax.exam.spi.reactors.PerMethod;
+import org.ops4j.pax.exam.util.Filter;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+
+import java.util.Dictionary;
+
+import static org.apache.brooklyn.KarafTestUtils.defaultOptionsWith;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
+import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.logLevel;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerMethod.class)
+public class CatalogBomScannerTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(CatalogBomScannerTest.class);
+    public static final String KARAF_INIT_BLUEPRINT_BOMSCANNER_PID = "org.apache.brooklyn.core.catalog.bomscanner";
+
+    @Inject
+    protected FeaturesService featuresService;
+
+    @Inject
+    protected ConfigurationAdmin configAdmin;
+
+    @Inject
+    protected ManagementContext managementContext;
+
+    /**
+     * To make sure the tests run only when the boot features are fully
+     * installed
+     */
+    @Inject
+    @Filter(timeout = 120000)
+    BootFinished bootFinished;
+
+
+    @Configuration
+    public static Option[] configuration() throws Exception {
+        return defaultOptionsWith(
+            logLevel(LogLevelOption.LogLevel.DEBUG),
+            editConfigurationFilePut("etc/org.ops4j.pax.logging.cfg", "log4j.logger.org.apache.brooklyn", "DEBUG"),
+            keepRuntimeFolder()
+            // Uncomment this for remote debugging the tests on port 5005
+//             , KarafDistributionOption.debugConfiguration()
+        );
+    }
+
+
+    @Test
+    @Category(IntegrationTest.class)
+    public void shouldFindBrooklynSoftwareBaseCatalogExampleServer() throws Exception {
+        final CatalogItem<?, ?> catalogItem = managementContext.getCatalog()
+            .getCatalogItem("server-template", BrooklynVersion.get());  // from brooklyn-software-base catalog.bom
+        assertNotNull(catalogItem);
+        assertEquals("Template: Server", catalogItem.getDisplayName());
+    }
+
+
+
+    @Test
+    @Category(IntegrationTest.class)
+    public void shouldFindWebAppCatalogExampleOnlyAfterItsFeatureIsInstalled() throws Exception {
+
+        final CatalogItem<?, ?> catalogItem = managementContext.getCatalog()
+            .getCatalogItem("load-balancer", BrooklynVersion.get());  // from brooklyn-software-webapp
+        assertNull(catalogItem);
+
+        featuresService.installFeature("brooklyn-software-webapp", BrooklynVersion.get());
+
+        Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Runnable() {
+            @Override
+            public void run() {
+                final CatalogItem<?, ?> lb = managementContext.getCatalog()
+                    .getCatalogItem("load-balancer", BrooklynVersion.get());
+                assertNotNull(lb);
+            }
+        });
+    }
+
+
+
+    @Test
+    @Category(IntegrationTest.class)
+    public void shouldNotFindNoSqlCatalogExampleIfItIsBlacklisted() throws Exception {
+
+        // verify no NoSQL entities are loaded yet
+        final String riakTemplate = "bash-web-and-riak-template"; // from brooklyn-software-nosql
+        CatalogItem<?, ?> catalogItem = getCatalogItem(riakTemplate);
+        assertNull(catalogItem);
+
+        final String redisStore = "org.apache.brooklyn.entity.nosql.redis.RedisStore"; // ditto
+        catalogItem = getCatalogItem(redisStore);
+        assertNull(catalogItem);
+
+        // blacklist the org.apache.brooklyn.software-nosql bundle
+        final org.osgi.service.cm.Configuration bomScannerConfig =
+            configAdmin.getConfiguration(KARAF_INIT_BLUEPRINT_BOMSCANNER_PID);
+        final Dictionary<String, Object> bomProps = bomScannerConfig.getProperties();
+        assertEquals(".*", bomProps.get("whiteList"));
+        assertEquals("", bomProps.get("blackList"));
+
+        bomProps.put("blackList", ".*nosql.*");
+        bomScannerConfig.update(bomProps);
+
+        // install the NoSQL feature
+        featuresService.installFeature("brooklyn-software-nosql", BrooklynVersion.get());
+
+        // verify that the non-template entity org.apache.brooklyn.entity.nosql.redis.RedisStore gets added to catalog
+        Asserts.succeedsEventually(MutableMap.of("timeout", Duration.TEN_SECONDS), new Runnable() {
+            @Override
+            public void run() {
+                final CatalogItem<?, ?> redis = managementContext.getCatalog()
+                    .getCatalogItem(redisStore, BrooklynVersion.get());
+                assertNotNull(redis);
+            }
+        });
+
+        // verify that the template application hasn't made it into the catalog (because it's blacklisted)
+        catalogItem = getCatalogItem(riakTemplate);
+        assertNull(catalogItem);
+    }
+
+    private CatalogItem<?, ?> getCatalogItem(String itemName) {
+        return managementContext.getCatalog().getCatalogItem(itemName, BrooklynVersion.get());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/3277583f/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java b/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
index 96c81b1..6e3afab 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/text/Strings.java
@@ -919,14 +919,22 @@ public class Strings {
 
     /**
      * Parses a string as comma separated values and returns a list of the entries with whitespace removed.
-     * @param csv
-     * @param separators
+     * @param csv The "comma" separated values.
+     * @param separatorRegex Regex of separatorRegex.
      */
-    public static List<String> parseCsv(String csv, String separators) {
+    public static List<String> parseCsv(String csv, String separatorRegex) {
         List<String> result = MutableList.of();
-        for (String value: csv.split(separators)) {
+        final String input = csv.trim();
+        if ("".equals(input)) {
+            return result;
+        }
+        for (String value: input.split(separatorRegex)) {
             result.add(value.trim());
         }
         return result;
     }
+
+    public static List<String> parseCsv(String csv) {
+        return parseCsv(csv, ",");
+    }
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/3277583f/utils/common/src/test/java/org/apache/brooklyn/util/text/StringsTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/text/StringsTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/text/StringsTest.java
index a861a10..cc758ab 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/text/StringsTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/text/StringsTest.java
@@ -23,6 +23,7 @@ import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 
 import java.util.Arrays;
+import java.util.List;
 
 import org.apache.brooklyn.test.FixedLocaleTest;
 import org.apache.brooklyn.util.collections.MutableMap;
@@ -359,4 +360,29 @@ public class StringsTest extends FixedLocaleTest {
         Assert.assertEquals(Strings.getRemainderOfLineAfter("the message is hello", null), null);
         Assert.assertEquals(Strings.getRemainderOfLineAfter("the message is hello", "foo"), null);
     }
+
+    @Test
+    public void shouldParseCsv() {
+
+        final String commaSeparated = "liberty, equality, fraternity";
+        final List<String> ideals = Strings.parseCsv(commaSeparated);
+        Assert.assertTrue(ideals.contains("liberty"));
+        Assert.assertTrue(ideals.contains("equality"));
+        Assert.assertTrue(ideals.contains("fraternity"));
+
+        final String assortedWords = "this, that; the, other";
+        final List<String> thisAndThat = Strings.parseCsv(assortedWords, "[,;]");
+        Assert.assertEquals(4, thisAndThat.size());
+        Assert.assertTrue(thisAndThat.contains("this"));
+        Assert.assertTrue(thisAndThat.contains("that"));
+        Assert.assertTrue(thisAndThat.contains("the"));
+        Assert.assertTrue(thisAndThat.contains("other"));
+
+        final List<String> differentSep = Strings.parseCsv(assortedWords, "@");
+        Assert.assertEquals(1, differentSep.size());
+        Assert.assertTrue(differentSep.contains(assortedWords));
+
+        Assert.assertEquals(0, Strings.parseCsv("", ",").size());
+        Assert.assertEquals(0, Strings.parseCsv("        ", ",").size());
+    }
 }