You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2015/05/22 11:04:48 UTC

[03/23] incubator-brooklyn git commit: allow "addition" of a catalog item which already exists if it's exactly the same

allow "addition" of a catalog item which already exists if it's exactly the same

adds equals and hashCode to CatlogItemDto and CatalogBundleDto


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

Branch: refs/heads/master
Commit: fab1caf220f0d6eae661c4951683ee46b3eedf77
Parents: 48ce0df
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Wed May 6 23:02:03 2015 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri May 8 18:22:22 2015 +0100

----------------------------------------------------------------------
 .../catalog/internal/BasicBrooklynCatalog.java  | 22 ++++++++++++--
 .../catalog/internal/CatalogBundleDto.java      | 19 ++++++++++++
 .../internal/CatalogItemDtoAbstract.java        | 32 ++++++++++++++++++++
 .../brooklyn/catalog/CatalogYamlEntityTest.java | 20 ++++++++++--
 .../catalog/CatalogYamlVersioningTest.java      | 11 +++++--
 usage/cli/src/main/java/brooklyn/cli/Main.java  |  2 +-
 6 files changed, 96 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fab1caf2/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
index 2e31532..7e4763d 100644
--- a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
@@ -1045,7 +1045,12 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
     }
     
     private CatalogItem<?,?> addItemDto(CatalogItemDtoAbstract<?, ?> itemDto, boolean forceUpdate) {
-        checkItemNotExists(itemDto, forceUpdate);
+        CatalogItem<?, ?> existingDto = checkItemIsDuplicateOrDisallowed(itemDto, true, forceUpdate);
+        if (existingDto!=null) {
+            // it's a duplicate, and not forced, just return it
+            log.trace("Using existing duplicate for catalog item {}", itemDto.getId());
+            return existingDto;
+        }
 
         if (manualAdditionsCatalog==null) loadManualAdditionsCatalog();
         manualAdditionsCatalog.addEntry(itemDto);
@@ -1067,8 +1072,19 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         return itemDto;
     }
 
-    private void checkItemNotExists(CatalogItem<?,?> itemDto, boolean forceUpdate) {
-        if (!forceUpdate && getCatalogItemDo(itemDto.getSymbolicName(), itemDto.getVersion()) != null) {
+    /** returns item DTO if item is an allowed duplicate, null if it should be added, or false if the item is an allowed duplicate,
+     * throwing if item cannot be added */
+    private CatalogItem<?, ?> checkItemIsDuplicateOrDisallowed(CatalogItem<?,?> itemDto, boolean allowDuplicates, boolean forceUpdate) {
+        if (forceUpdate) return null;
+        CatalogItemDo<?, ?> existingItem = getCatalogItemDo(itemDto.getSymbolicName(), itemDto.getVersion());
+        if (existingItem == null) return null;
+        // check if they are equal
+        CatalogItem<?, ?> existingDto = existingItem.getDto();
+        if (existingDto.equals(itemDto)) {
+            if (allowDuplicates) return existingItem;
+            throw new IllegalStateException("Updating existing catalog entries, even with the same content, is forbidden: " +
+                    itemDto.getSymbolicName() + ":" + itemDto.getVersion() + ". Use forceUpdate argument to override.");
+        } else {
             throw new IllegalStateException("Updating existing catalog entries is forbidden: " +
                     itemDto.getSymbolicName() + ":" + itemDto.getVersion() + ". Use forceUpdate argument to override.");
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fab1caf2/core/src/main/java/brooklyn/catalog/internal/CatalogBundleDto.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogBundleDto.java b/core/src/main/java/brooklyn/catalog/internal/CatalogBundleDto.java
index 35353c4..5cbd23a 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogBundleDto.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogBundleDto.java
@@ -71,4 +71,23 @@ public class CatalogBundleDto implements CatalogBundle {
                 .add("url", url)
                 .toString();
     }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(symbolicName, version, url);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        CatalogBundleDto other = (CatalogBundleDto) obj;
+        if (!Objects.equal(symbolicName, other.symbolicName)) return false;
+        if (!Objects.equal(version, other.version)) return false;
+        if (!Objects.equal(url, other.url)) return false;
+        return true;
+    }
+    
+    
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fab1caf2/core/src/main/java/brooklyn/catalog/internal/CatalogItemDtoAbstract.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogItemDtoAbstract.java b/core/src/main/java/brooklyn/catalog/internal/CatalogItemDtoAbstract.java
index 523cd79..c6ff97e 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogItemDtoAbstract.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogItemDtoAbstract.java
@@ -39,6 +39,7 @@ import brooklyn.util.collections.MutableList;
 import brooklyn.util.flags.FlagUtils;
 import brooklyn.util.flags.SetFromFlag;
 
+import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
@@ -162,6 +163,37 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
     }
 
     @Override
+    public int hashCode() {
+        return Objects.hashCode(symbolicName, planYaml, javaType, nullIfEmpty(libraries), version, getCatalogItemId());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        CatalogItemDtoAbstract<?,?> other = (CatalogItemDtoAbstract<?,?>) obj;
+        if (!Objects.equal(symbolicName, other.symbolicName)) return false;
+        if (!Objects.equal(planYaml, other.planYaml)) return false;
+        if (!Objects.equal(javaType, other.javaType)) return false;
+        if (!Objects.equal(nullIfEmpty(libraries), nullIfEmpty(other.libraries))) return false;
+        if (!Objects.equal(getCatalogItemId(), other.getCatalogItemId())) return false;
+        if (!Objects.equal(version, other.version)) return false;
+        if (!Objects.equal(deprecated, other.deprecated)) return false;
+        if (!Objects.equal(description, other.description)) return false;
+        if (!Objects.equal(displayName, other.displayName)) return false;
+        if (!Objects.equal(iconUrl, other.iconUrl)) return false;
+        if (!Objects.equal(tags, other.tags)) return false;
+        // 'type' not checked, because deprecated, we might want to allow removal in future
+        return true;
+    }
+
+    private static <T> Collection<T> nullIfEmpty(Collection<T> coll) {
+        if (coll==null || coll.isEmpty()) return null;
+        return coll;
+    }
+
+    @Override
     public String toString() {
         return getClass().getSimpleName()+"["+getId()+"/"+getDisplayName()+"]";
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fab1caf2/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
index 1e321dc..9353108 100644
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlEntityTest.java
@@ -486,14 +486,23 @@ public class CatalogYamlEntityTest extends AbstractYamlTest {
                     OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL + "}");
         }
     }
+
+    @Test
+    public void testUpdatingItemAllowedIfSame() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+        String id = "my.catalog.app.id.duplicate";
+        addCatalogOSGiEntity(id);
+        addCatalogOSGiEntity(id);
+    }
     
     @Test(expectedExceptions = IllegalStateException.class)
-    public void testUpdatingItemFails() {
+    public void testUpdatingItemFailsIfDifferent() {
         TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
 
         String id = "my.catalog.app.id.duplicate";
         addCatalogOSGiEntity(id);
-        addCatalogOSGiEntity(id);
+        addCatalogOSGiEntity(id, SIMPLE_ENTITY_TYPE, true);
     }
 
     @Test
@@ -620,6 +629,10 @@ public class CatalogYamlEntityTest extends AbstractYamlTest {
     }
 
     private void addCatalogOSGiEntity(String symbolicName, String serviceType) {
+        addCatalogOSGiEntity(symbolicName, serviceType, false);
+    }
+    
+    private void addCatalogOSGiEntity(String symbolicName, String serviceType, boolean extraLib) {
         addCatalogItem(
             "brooklyn.catalog:",
             "  id: " + symbolicName,
@@ -628,7 +641,8 @@ public class CatalogYamlEntityTest extends AbstractYamlTest {
             "  icon_url: classpath://path/to/myicon.jpg",
             "  version: " + TEST_VERSION,
             "  libraries:",
-            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL,
+            "  - url: " + OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL +
+            (extraLib ? "\n"+"  - url: "+OsgiStandaloneTest.BROOKLYN_OSGI_TEST_A_0_1_0_URL : ""),
             "  item:",
             "    type: " + serviceType);
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fab1caf2/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
index c1176ea..dda60dc 100644
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlVersioningTest.java
@@ -66,12 +66,13 @@ public class CatalogYamlVersioningTest extends AbstractYamlTest {
     }
 
     @Test
-    public void testAddSameVersionFails() {
+    public void testAddSameVersionFailsWhenIconIsDifferent() {
         String symbolicName = "sampleId";
         String version = "0.1.0";
         addCatalogEntity(symbolicName, version);
+        addCatalogEntity(symbolicName, version);
         try {
-            addCatalogEntity(symbolicName, version);
+            addCatalogEntity(symbolicName, version, BasicEntity.class.getName(), "classpath:/another/icon.png");
             fail("Expected to fail");
         } catch (IllegalStateException e) {
             assertEquals(e.getMessage(), "Updating existing catalog entries is forbidden: " + symbolicName + ":" + version + ". Use forceUpdate argument to override.");
@@ -238,12 +239,16 @@ public class CatalogYamlVersioningTest extends AbstractYamlTest {
     }
 
     private void addCatalogEntity(String symbolicName, String version, String type) {
+        addCatalogEntity(symbolicName, version, type, "classpath://path/to/myicon.jpg");
+    }
+    
+    private void addCatalogEntity(String symbolicName, String version, String type, String iconUrl) {
         addCatalogItem(
             "brooklyn.catalog:",
             "  id: " + symbolicName,
             "  name: My Catalog App",
             "  description: My description",
-            "  icon_url: classpath://path/to/myicon.jpg",
+            "  icon_url: "+iconUrl,
             (version != null ? "  version: " + version : ""),
             "",
             "services:",

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fab1caf2/usage/cli/src/main/java/brooklyn/cli/Main.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/brooklyn/cli/Main.java b/usage/cli/src/main/java/brooklyn/cli/Main.java
index ad6aeb1..e6330ea 100644
--- a/usage/cli/src/main/java/brooklyn/cli/Main.java
+++ b/usage/cli/src/main/java/brooklyn/cli/Main.java
@@ -219,7 +219,7 @@ public class Main extends AbstractMain {
 
         @Option(name = { "--catalogInitial" }, title = "catalog initial bom URI",
             description = "Specifies a catalog.bom URI to be used to populate the initial catalog, "
-                + "if nothing is yet persisted in the catalog (or if it is reset)")
+                + "loaded on first run, or when persistence is off/empty or the catalog is reset")
         public String catalogInitial;
 
         @Option(name = { "--catalogReset" },