You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2015/08/26 14:24:25 UTC

[1/3] incubator-brooklyn git commit: CatalogPredicates: test + not anonymous classes

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 918c162b3 -> b4547d95c


CatalogPredicates: test + not anonymous classes


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

Branch: refs/heads/master
Commit: c1793c99c828bcecce3a7fc3fe9759eea80e4df0
Parents: 918c162
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 19 14:38:40 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 26 09:24:31 2015 +0100

----------------------------------------------------------------------
 .../core/catalog/CatalogPredicates.java         | 145 ++++++++++++++++--
 .../core/catalog/CatalogPredicatesTest.java     | 153 +++++++++++++++++++
 2 files changed, 288 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c1793c99/core/src/main/java/org/apache/brooklyn/core/catalog/CatalogPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/CatalogPredicates.java b/core/src/main/java/org/apache/brooklyn/core/catalog/CatalogPredicates.java
index f5ed326..e30d278 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/CatalogPredicates.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/CatalogPredicates.java
@@ -39,21 +39,49 @@ import com.google.common.base.Predicate;
 public class CatalogPredicates {
 
     public static <T,SpecT> Predicate<CatalogItem<T,SpecT>> isCatalogItemType(final CatalogItemType ciType) {
-        return new Predicate<CatalogItem<T,SpecT>>() {
+        // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state
+        new Predicate<CatalogItem<T,SpecT>>() {
             @Override
             public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
                 return (item != null) && item.getCatalogItemType()==ciType;
             }
         };
+        return new CatalogItemTypeEquals<T, SpecT>(ciType);
+    }
+
+    private static class CatalogItemTypeEquals<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
+        private final CatalogItemType ciType;
+        
+        public CatalogItemTypeEquals(final CatalogItemType ciType) {
+            this.ciType = ciType;
+        }
+        @Override
+        public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
+            return (item != null) && item.getCatalogItemType()==ciType;
+        }
     }
 
     public static <T,SpecT> Predicate<CatalogItem<T,SpecT>> deprecated(final boolean deprecated) {
-        return new Predicate<CatalogItem<T,SpecT>>() {
+        // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state
+        new Predicate<CatalogItem<T,SpecT>>() {
             @Override
             public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
                 return (item != null) && item.isDeprecated() == deprecated;
             }
         };
+        return new DeprecatedEquals<T, SpecT>(deprecated);
+    }
+
+    private static class DeprecatedEquals<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
+        private final boolean deprecated;
+        
+        public DeprecatedEquals(boolean deprecated) {
+            this.deprecated = deprecated;
+        }
+        @Override
+        public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
+            return (item != null) && item.isDeprecated() == deprecated;
+        }
     }
 
     public static final Predicate<CatalogItem<Application,EntitySpec<? extends Application>>> IS_TEMPLATE = 
@@ -65,7 +93,20 @@ public class CatalogPredicates {
     public static final Predicate<CatalogItem<Location,LocationSpec<?>>> IS_LOCATION = 
             CatalogPredicates.<Location,LocationSpec<?>>isCatalogItemType(CatalogItemType.LOCATION);
     
-    public static final Function<CatalogItem<?,?>,String> ID_OF_ITEM_TRANSFORMER = new Function<CatalogItem<?,?>, String>() {
+    // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state
+    @SuppressWarnings("unused")
+    private static final Function<CatalogItem<?,?>,String> ID_OF_ITEM_TRANSFORMER_ANONYMOUS = new Function<CatalogItem<?,?>, String>() {
+        @Override @Nullable
+        public String apply(@Nullable CatalogItem<?,?> input) {
+            if (input==null) return null;
+            return input.getId();
+        }
+    };
+
+    // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state
+    public static final Function<CatalogItem<?,?>,String> ID_OF_ITEM_TRANSFORMER = new IdOfItemTransformer();
+    
+    private static class IdOfItemTransformer implements Function<CatalogItem<?,?>,String> {
         @Override @Nullable
         public String apply(@Nullable CatalogItem<?,?> input) {
             if (input==null) return null;
@@ -80,12 +121,26 @@ public class CatalogPredicates {
     }
 
     public static <T,SpecT> Predicate<CatalogItem<T,SpecT>> displayName(final Predicate<? super String> filter) {
-        return new Predicate<CatalogItem<T,SpecT>>() {
+        // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state
+        new Predicate<CatalogItem<T,SpecT>>() {
             @Override
             public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
                 return (item != null) && filter.apply(item.getDisplayName());
             }
         };
+        return new DisplayNameMatches<T,SpecT>(filter);
+    }
+
+    private static class DisplayNameMatches<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
+        private final Predicate<? super String> filter;
+        
+        public DisplayNameMatches(Predicate<? super String> filter) {
+            this.filter = filter;
+        }
+        @Override
+        public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
+            return (item != null) && filter.apply(item.getDisplayName());
+        }
     }
 
     @Deprecated
@@ -94,49 +149,119 @@ public class CatalogPredicates {
     }
 
     public static <T,SpecT> Predicate<CatalogItem<T,SpecT>> symbolicName(final Predicate<? super String> filter) {
-        return new Predicate<CatalogItem<T,SpecT>>() {
+        // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state
+        new Predicate<CatalogItem<T,SpecT>>() {
             @Override
             public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
                 return (item != null) && filter.apply(item.getSymbolicName());
             }
         };
+        return new SymbolicNameMatches<T,SpecT>(filter);
+    }
+    
+    private static class SymbolicNameMatches<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
+        private final Predicate<? super String> filter;
+        
+        public SymbolicNameMatches(Predicate<? super String> filter) {
+            this.filter = filter;
+        }
+        @Override
+        public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
+            return (item != null) && filter.apply(item.getSymbolicName());
+        }
     }
 
     public static <T,SpecT> Predicate<CatalogItem<T,SpecT>> javaType(final Predicate<? super String> filter) {
-        return new Predicate<CatalogItem<T,SpecT>>() {
+        // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state
+        new Predicate<CatalogItem<T,SpecT>>() {
             @Override
             public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
                 return (item != null) && filter.apply(item.getJavaType());
             }
         };
+        return new JavaTypeMatches<T, SpecT>(filter);
+    }
+    
+    private static class JavaTypeMatches<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
+        private final Predicate<? super String> filter;
+        
+        public JavaTypeMatches(Predicate<? super String> filter) {
+            this.filter = filter;
+        }
+        @Override
+        public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
+            return (item != null) && filter.apply(item.getJavaType());
+        }
     }
 
     public static <T,SpecT> Predicate<CatalogItem<T,SpecT>> xml(final Predicate<? super String> filter) {
-        return new Predicate<CatalogItem<T,SpecT>>() {
+        // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state
+        new Predicate<CatalogItem<T,SpecT>>() {
             @Override
             public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
                 return (item != null) && filter.apply(item.toXmlString());
             }
         };
+        return new XmlMatches<T,SpecT>(filter);
+    }
+    
+    private static class XmlMatches<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
+        private final Predicate<? super String> filter;
+        
+        public XmlMatches(Predicate<? super String> filter) {
+            this.filter = filter;
+        }
+        @Override
+        public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
+            return (item != null) && filter.apply(item.toXmlString());
+        }
     }
 
     public static <T,SpecT> Predicate<CatalogItem<T,SpecT>> entitledToSee(final ManagementContext mgmt) {
-        return new Predicate<CatalogItem<T,SpecT>>() {
+        // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state
+        new Predicate<CatalogItem<T,SpecT>>() {
             @Override
             public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
                 return (item != null) && 
                     Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_CATALOG_ITEM, item.getCatalogItemId());
             }
         };
+        return new EntitledToSee<T, SpecT>(mgmt);
+    }
+    
+    private static class EntitledToSee<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
+        private final ManagementContext mgmt;
+        
+        public EntitledToSee(ManagementContext mgmt) {
+            this.mgmt = mgmt;
+        }
+        @Override
+        public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
+            return (item != null) && 
+                    Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_CATALOG_ITEM, item.getCatalogItemId());
+        }
     }
  
     public static <T,SpecT> Predicate<CatalogItem<T,SpecT>> isBestVersion(final ManagementContext mgmt) {
-        return new Predicate<CatalogItem<T,SpecT>>() {
+        // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state
+        new Predicate<CatalogItem<T,SpecT>>() {
             @Override
             public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
                 return CatalogUtils.isBestVersion(mgmt, item);
             }
         };
+        return new IsBestVersion<T, SpecT>(mgmt);
+    }
+    
+    private static class IsBestVersion<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
+        private final ManagementContext mgmt;
+        
+        public IsBestVersion(ManagementContext mgmt) {
+            this.mgmt = mgmt;
+        }
+        @Override
+        public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
+            return CatalogUtils.isBestVersion(mgmt, item);
+        }
     }
-
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c1793c99/core/src/test/java/org/apache/brooklyn/core/catalog/CatalogPredicatesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/CatalogPredicatesTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/CatalogPredicatesTest.java
new file mode 100644
index 0000000..32860a4
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/catalog/CatalogPredicatesTest.java
@@ -0,0 +1,153 @@
+/*
+ * 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;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.apache.brooklyn.api.catalog.BrooklynCatalog;
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
+import org.apache.brooklyn.core.management.internal.LocalManagementContext;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicates;
+
+import brooklyn.entity.basic.Entities;
+
+public class CatalogPredicatesTest {
+    private LocalManagementContext mgmt;
+    private BrooklynCatalog catalog;
+    
+    @BeforeMethod(alwaysRun = true)
+    public void setUp() throws Exception {
+        mgmt = LocalManagementContextForTests.newInstance();
+        catalog = mgmt.getCatalog();
+    }
+    
+    @AfterMethod(alwaysRun = true)
+    public void tearDown() throws Exception {
+        if (mgmt != null) Entities.destroyAll(mgmt);
+    }
+
+    @Test
+    public void testDisplayName() {
+        CatalogItem<Entity, EntitySpec<?>> item = createItem(CatalogItemBuilder.newEntity("foo", "1.0")
+                .plan("services:\n- type: brooklyn.entity.basic.BasicEntity")
+                .displayName("myname")
+                .build());
+
+        assertTrue(CatalogPredicates.<Entity,EntitySpec<?>>displayName(Predicates.equalTo("myname")).apply(item));
+        assertFalse(CatalogPredicates.<Entity,EntitySpec<?>>displayName(Predicates.equalTo("wrongname")).apply(item));
+    }
+    
+    @Test
+    public void testDeprecated() {
+        CatalogItem<Entity, EntitySpec<?>> item = createItem(CatalogItemBuilder.newEntity("foo", "1.0")
+                .plan("services:\n- type: brooklyn.entity.basic.BasicEntity")
+                .build());
+
+        assertTrue(CatalogPredicates.<Entity,EntitySpec<?>>deprecated(false).apply(item));
+        assertFalse(CatalogPredicates.<Entity,EntitySpec<?>>deprecated(true).apply(item));
+        
+        item = deprecateItem(item);
+        
+        assertFalse(CatalogPredicates.<Entity,EntitySpec<?>>deprecated(false).apply(item));
+        assertTrue(CatalogPredicates.<Entity,EntitySpec<?>>deprecated(true).apply(item));
+    }
+    
+    @Test
+    public void testIsCatalogItemType() {
+        CatalogItem<Entity, EntitySpec<?>> item = createItem(CatalogItemBuilder.newEntity("foo", "1.0")
+                .plan("services:\n- type: brooklyn.entity.basic.BasicEntity")
+                .build());
+
+        assertTrue(CatalogPredicates.<Entity,EntitySpec<?>>isCatalogItemType(CatalogItemType.ENTITY).apply(item));
+        assertFalse(CatalogPredicates.<Entity,EntitySpec<?>>isCatalogItemType(CatalogItemType.LOCATION).apply(item));
+    }
+    
+    @Test
+    public void testSymbolicName() {
+        CatalogItem<Entity, EntitySpec<?>> item = createItem(CatalogItemBuilder.newEntity("foo", "1.0")
+                .plan("services:\n- type: brooklyn.entity.basic.BasicEntity")
+                .build());
+
+        assertTrue(CatalogPredicates.<Entity,EntitySpec<?>>symbolicName(Predicates.equalTo("foo")).apply(item));
+        assertFalse(CatalogPredicates.<Entity,EntitySpec<?>>symbolicName(Predicates.equalTo("wrongname")).apply(item));
+    }
+
+    @Test
+    public void testIsBestVersion() {
+        CatalogItem<Entity, EntitySpec<?>> itemV1 = createItem(CatalogItemBuilder.newEntity("foo", "1.0")
+                .plan("services:\n- type: brooklyn.entity.basic.BasicEntity")
+                .build());
+        CatalogItem<Entity, EntitySpec<?>> itemV2 = createItem(CatalogItemBuilder.newEntity("foo", "2.0")
+                .plan("services:\n- type: brooklyn.entity.basic.BasicEntity")
+                .build());
+        CatalogItem<Entity, EntitySpec<?>> itemV3Disabled = createItem(CatalogItemBuilder.newEntity("foo", "3.0")
+                .disabled(true)
+                .plan("services:\n- type: brooklyn.entity.basic.BasicEntity")
+                .build());
+
+        assertTrue(CatalogPredicates.<Entity,EntitySpec<?>>isBestVersion(mgmt).apply(itemV2));
+        assertFalse(CatalogPredicates.<Entity,EntitySpec<?>>isBestVersion(mgmt).apply(itemV1));
+        assertFalse(CatalogPredicates.<Entity,EntitySpec<?>>isBestVersion(mgmt).apply(itemV3Disabled));
+    }
+
+    @Test
+    public void testEntitledToSee() {
+        // TODO No entitlements configured, so everything allowed - therefore test not thorough enough!
+        CatalogItem<Entity, EntitySpec<?>> item = createItem(CatalogItemBuilder.newEntity("foo", "1.0")
+                .plan("services:\n- type: brooklyn.entity.basic.BasicEntity")
+                .build());
+
+        assertTrue(CatalogPredicates.<Entity,EntitySpec<?>>entitledToSee(mgmt).apply(item));
+    }
+
+    @SuppressWarnings("deprecation")
+    @Test
+    public void testJavaType() {
+        CatalogItem<Entity, EntitySpec<?>> item = createItem(CatalogItemBuilder.newEntity("foo", "1.0")
+                .javaType("brooklyn.entity.basic.BasicEntity")
+                .build());
+
+        assertTrue(CatalogPredicates.<Entity,EntitySpec<?>>javaType(Predicates.equalTo("brooklyn.entity.basic.BasicEntity")).apply(item));
+        assertFalse(CatalogPredicates.<Entity,EntitySpec<?>>javaType(Predicates.equalTo("wrongtype")).apply(item));
+    }
+
+    @SuppressWarnings("deprecation")
+    protected <T, SpecT> CatalogItem<T, SpecT> createItem(CatalogItem<T, SpecT> item) {
+        catalog.addItem(item);
+        return item;
+    }
+    
+    @SuppressWarnings("unchecked")
+    protected <T, SpecT> CatalogItem<T, SpecT> deprecateItem(CatalogItem<T, SpecT> orig) {
+        CatalogItem<T, SpecT> item = (CatalogItem<T, SpecT>) catalog.getCatalogItem(orig.getSymbolicName(), orig.getVersion());
+        item.setDeprecated(true);
+        catalog.persist(item);
+        return item;
+    }
+}


[2/3] incubator-brooklyn git commit: Adds CatalogItem.disabled

Posted by al...@apache.org.
Adds CatalogItem.disabled

- BrooklynCatalog filters these out for getDefaultVersion
- REST’s CatalogResource filters these out for listApplications,
  listEntities, listLocations and listPolicies.
- Applications refuse to deploy when referenced catalog item is disabled
- log.warn when deprecated catalog item is used.


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

Branch: refs/heads/master
Commit: da70a8e3acffe216b3366ee38a24d3c158c1a00f
Parents: c1793c9
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 19 14:46:33 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 26 11:10:14 2015 +0100

----------------------------------------------------------------------
 .../brooklyn/api/catalog/CatalogItem.java       |   9 +-
 .../rebind/mementos/CatalogItemMemento.java     |   1 +
 .../brooklyn/camp/spi/resolve/PdpProcessor.java |   2 +-
 .../core/catalog/CatalogPredicates.java         |  64 ++++-
 .../catalog/internal/BasicBrooklynCatalog.java  |   4 +-
 .../catalog/internal/CatalogItemBuilder.java    |   5 +
 .../core/catalog/internal/CatalogItemDo.java    |  10 +
 .../internal/CatalogItemDtoAbstract.java        |  11 +
 .../core/location/CatalogLocationResolver.java  |   6 +
 .../rebind/BasicCatalogItemRebindSupport.java   |   1 +
 .../rebind/dto/BasicCatalogItemMemento.java     |  17 +-
 .../mgmt/rebind/dto/MementosGenerators.java     |   3 +-
 .../core/catalog/CatalogPredicatesTest.java     |  31 ++-
 .../catalog/internal/CatalogVersioningTest.java |  20 ++
 .../core/mgmt/rebind/RebindOptions.java         |   9 +
 .../core/mgmt/rebind/RebindTestUtils.java       |   8 +
 .../BrooklynComponentTemplateResolver.java      |  27 +-
 .../camp/brooklyn/AbstractYamlRebindTest.java   |  11 +-
 .../brooklyn/catalog/CatalogYamlRebindTest.java | 249 +++++++++++++++++--
 .../apache/brooklyn/rest/api/CatalogApi.java    |  31 ++-
 .../rest/resources/ApplicationResource.java     |  19 +-
 .../rest/resources/CatalogResource.java         |  48 +++-
 .../rest/resources/ApplicationResourceTest.java | 141 +++++++++--
 .../rest/resources/CatalogResourceTest.java     | 150 ++++++++---
 24 files changed, 760 insertions(+), 117 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
index 1164ae1..3758d08 100644
--- a/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
+++ b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
@@ -100,8 +100,15 @@ public interface CatalogItem<T,SpecT> extends BrooklynObject, Rebindable {
 
     public void setDeprecated(boolean deprecated);
 
+    public void setDisabled(boolean disabled);
+
     /**
-     * @return True if the item has been deprecated and should not be shown in the catalog
+     * @return True if the item has been deprecated (i.e. its use is discouraged)
      */
     boolean isDeprecated();
+    
+    /**
+     * @return True if the item has been disabled (i.e. its use is forbidden, except for pre-existing apps)
+     */
+    boolean isDisabled();
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java
index 9f8bdca..ad16b4a 100644
--- a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/CatalogItemMemento.java
@@ -46,4 +46,5 @@ public interface CatalogItemMemento extends Memento {
 
     boolean isDeprecated();
 
+    boolean isDisabled();
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/camp/camp-base/src/main/java/org/apache/brooklyn/camp/spi/resolve/PdpProcessor.java
----------------------------------------------------------------------
diff --git a/camp/camp-base/src/main/java/org/apache/brooklyn/camp/spi/resolve/PdpProcessor.java b/camp/camp-base/src/main/java/org/apache/brooklyn/camp/spi/resolve/PdpProcessor.java
index 61c0302..49e7ee1 100644
--- a/camp/camp-base/src/main/java/org/apache/brooklyn/camp/spi/resolve/PdpProcessor.java
+++ b/camp/camp-base/src/main/java/org/apache/brooklyn/camp/spi/resolve/PdpProcessor.java
@@ -163,7 +163,7 @@ public class PdpProcessor {
                     return;
             }
         }
-        throw new UnsupportedOperationException("Deployment plan item "+deploymentPlanItem+" cannot be matched");
+        throw new IllegalArgumentException("Deployment plan item "+deploymentPlanItem+" cannot be matched");
     }
 
     // ----------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/core/src/main/java/org/apache/brooklyn/core/catalog/CatalogPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/CatalogPredicates.java b/core/src/main/java/org/apache/brooklyn/core/catalog/CatalogPredicates.java
index e30d278..8d5ea9e 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/CatalogPredicates.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/CatalogPredicates.java
@@ -46,13 +46,16 @@ public class CatalogPredicates {
                 return (item != null) && item.getCatalogItemType()==ciType;
             }
         };
-        return new CatalogItemTypeEquals<T, SpecT>(ciType);
+        return new CatalogItemTypeEqualTo<T, SpecT>(ciType);
     }
 
-    private static class CatalogItemTypeEquals<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
+    /**
+     * @since 0.8.0
+     */
+    private static class CatalogItemTypeEqualTo<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
         private final CatalogItemType ciType;
         
-        public CatalogItemTypeEquals(final CatalogItemType ciType) {
+        public CatalogItemTypeEqualTo(final CatalogItemType ciType) {
             this.ciType = ciType;
         }
         @Override
@@ -69,13 +72,16 @@ public class CatalogPredicates {
                 return (item != null) && item.isDeprecated() == deprecated;
             }
         };
-        return new DeprecatedEquals<T, SpecT>(deprecated);
+        return new DeprecatedEqualTo<T, SpecT>(deprecated);
     }
 
-    private static class DeprecatedEquals<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
+    /**
+     * @since 0.8.0
+     */
+    private static class DeprecatedEqualTo<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
         private final boolean deprecated;
         
-        public DeprecatedEquals(boolean deprecated) {
+        public DeprecatedEqualTo(boolean deprecated) {
             this.deprecated = deprecated;
         }
         @Override
@@ -84,6 +90,28 @@ public class CatalogPredicates {
         }
     }
 
+    /**
+     * @since 0.8.0
+     */
+    public static <T,SpecT> Predicate<CatalogItem<T,SpecT>> disabled(boolean disabled) {
+        return new DisabledEqualTo<T, SpecT>(disabled);
+    }
+
+    /**
+     * @since 0.8.0
+     */
+    private static class DisabledEqualTo<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
+        private final boolean disabled;
+        
+        public DisabledEqualTo(boolean disabled) {
+            this.disabled = disabled;
+        }
+        @Override
+        public boolean apply(@Nullable CatalogItem<T,SpecT> item) {
+            return (item != null) && item.isDisabled() == disabled;
+        }
+    }
+
     public static final Predicate<CatalogItem<Application,EntitySpec<? extends Application>>> IS_TEMPLATE = 
             CatalogPredicates.<Application,EntitySpec<? extends Application>>isCatalogItemType(CatalogItemType.TEMPLATE);
     public static final Predicate<CatalogItem<Entity,EntitySpec<?>>> IS_ENTITY = 
@@ -106,6 +134,9 @@ public class CatalogPredicates {
     // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state
     public static final Function<CatalogItem<?,?>,String> ID_OF_ITEM_TRANSFORMER = new IdOfItemTransformer();
     
+    /**
+     * @since 0.8.0
+     */
     private static class IdOfItemTransformer implements Function<CatalogItem<?,?>,String> {
         @Override @Nullable
         public String apply(@Nullable CatalogItem<?,?> input) {
@@ -120,6 +151,9 @@ public class CatalogPredicates {
         return displayName(filter);
     }
 
+    /**
+     * @since 0.7.0
+     */
     public static <T,SpecT> Predicate<CatalogItem<T,SpecT>> displayName(final Predicate<? super String> filter) {
         // TODO PERSISTENCE WORKAROUND kept anonymous function in case referenced in persisted state
         new Predicate<CatalogItem<T,SpecT>>() {
@@ -131,6 +165,9 @@ public class CatalogPredicates {
         return new DisplayNameMatches<T,SpecT>(filter);
     }
 
+    /**
+     * @since 0.8.0
+     */
     private static class DisplayNameMatches<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
         private final Predicate<? super String> filter;
         
@@ -159,6 +196,9 @@ public class CatalogPredicates {
         return new SymbolicNameMatches<T,SpecT>(filter);
     }
     
+    /**
+     * @since 0.8.0
+     */
     private static class SymbolicNameMatches<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
         private final Predicate<? super String> filter;
         
@@ -182,6 +222,9 @@ public class CatalogPredicates {
         return new JavaTypeMatches<T, SpecT>(filter);
     }
     
+    /**
+     * @since 0.8.0
+     */
     private static class JavaTypeMatches<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
         private final Predicate<? super String> filter;
         
@@ -205,6 +248,9 @@ public class CatalogPredicates {
         return new XmlMatches<T,SpecT>(filter);
     }
     
+    /**
+     * @since 0.8.0
+     */
     private static class XmlMatches<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
         private final Predicate<? super String> filter;
         
@@ -229,6 +275,9 @@ public class CatalogPredicates {
         return new EntitledToSee<T, SpecT>(mgmt);
     }
     
+    /**
+     * @since 0.8.0
+     */
     private static class EntitledToSee<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
         private final ManagementContext mgmt;
         
@@ -253,6 +302,9 @@ public class CatalogPredicates {
         return new IsBestVersion<T, SpecT>(mgmt);
     }
     
+    /**
+     * @since 0.8.0
+     */
     private static class IsBestVersion<T,SpecT> implements Predicate<CatalogItem<T,SpecT>> {
         private final ManagementContext mgmt;
         

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
index a25bc73..b2ec24d 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
@@ -195,7 +195,9 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
     }
 
     private String getDefaultVersion(String symbolicName) {
-        Iterable<CatalogItem<Object, Object>> versions = getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName)));
+        Iterable<CatalogItem<Object, Object>> versions = getCatalogItems(Predicates.and(
+                CatalogPredicates.disabled(false),
+                CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))));
         Collection<CatalogItem<Object, Object>> orderedVersions = sortVersionsDesc(versions);
         if (!orderedVersions.isEmpty()) {
             return orderedVersions.iterator().next().getVersion();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java
index e157a51..8918a74 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemBuilder.java
@@ -99,6 +99,11 @@ public class CatalogItemBuilder<CatalogItemType extends CatalogItemDtoAbstract<?
         return this;
     }
 
+    public CatalogItemBuilder<CatalogItemType> disabled(boolean disabled) {
+        dto.setDisabled(disabled);
+        return this;
+    }
+
     public CatalogItemBuilder<CatalogItemType> libraries(Collection<CatalogBundle> libraries) {
         dto.setLibraries(libraries);
         return this;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java
index 4312f6b..5029d8d 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDo.java
@@ -92,6 +92,16 @@ public class CatalogItemDo<T,SpecT> implements CatalogItem<T,SpecT>, BrooklynObj
     }
 
     @Override
+    public void setDisabled(boolean diabled) {
+        itemDto.setDisabled(diabled);
+    }
+
+    @Override
+    public boolean isDisabled() {
+        return itemDto.isDisabled();
+    }
+
+    @Override
     public void setCatalogItemId(String id) {
         itemDto.setCatalogItemId(id);
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
index c8be5f7..b281941 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
@@ -63,6 +63,7 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
     private @SetFromFlag Collection<CatalogBundle> libraries;
     private @SetFromFlag Set<Object> tags = Sets.newLinkedHashSet();
     private @SetFromFlag boolean deprecated;
+    private @SetFromFlag boolean disabled;
 
     /**
      * Config not supported for catalog item. See {@link #getPlanYaml()}.
@@ -146,6 +147,16 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO
         this.deprecated = deprecated;
     }
 
+    @Override
+    public boolean isDisabled() {
+        return disabled;
+    }
+
+    @Override
+    public void setDisabled(boolean disabled) {
+        this.disabled = disabled;
+    }
+
     @Nonnull
     @Override
     public Collection<CatalogBundle> getLibraries() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java b/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java
index 2dd832c..2cc7b9f 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java
@@ -55,6 +55,12 @@ public class CatalogLocationResolver implements LocationResolver {
     public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
         String id = spec.substring(NAME.length()+1);
         CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(managementContext, id);
+        if (item.isDisabled()) {
+            throw new IllegalStateException("Illegal use of disabled catalog item "+item.getSymbolicName()+":"+item.getVersion());
+        } else if (item.isDeprecated()) {
+            log.warn("Use of deprecated catalog item "+item.getSymbolicName()+":"+item.getVersion());
+        }
+        
         LocationSpec<?> origLocSpec = managementContext.getCatalog().createSpec((CatalogItem<Location, LocationSpec<?>>)item);
         LocationSpec<?> locSpec = LocationSpec.create(origLocSpec)
                 .configure(locationFlags);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicCatalogItemRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicCatalogItemRebindSupport.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicCatalogItemRebindSupport.java
index edfcb08..c8f2dfc 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicCatalogItemRebindSupport.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicCatalogItemRebindSupport.java
@@ -51,6 +51,7 @@ public class BasicCatalogItemRebindSupport extends AbstractBrooklynObjectRebindS
                 .put("libraries", memento.getLibraries())
                 .put("planYaml", memento.getPlanYaml())
                 .put("deprecated", memento.isDeprecated())
+                .put("disabled", memento.isDisabled())
                 .build(), instance);
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicCatalogItemMemento.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicCatalogItemMemento.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicCatalogItemMemento.java
index 93892cd..be21dde 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicCatalogItemMemento.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicCatalogItemMemento.java
@@ -53,6 +53,7 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
         protected Class<?> catalogItemJavaType;
         protected Class<?> specType;
         protected boolean deprecated;
+        protected boolean disabled;
 
         public Builder description(String description) {
             this.description = description;
@@ -109,6 +110,11 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
             return self();
         }
 
+        public Builder disabled(boolean disabled) {
+            this.disabled = disabled;
+            return self();
+        }
+
         public Builder from(CatalogItemMemento other) {
             super.from(other);
             description = other.getDescription();
@@ -122,6 +128,7 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
             catalogItemJavaType = other.getCatalogItemJavaType();
             specType = other.getSpecType();
             deprecated = other.isDeprecated();
+            disabled = other.isDisabled();
             return self();
         }
 
@@ -141,6 +148,7 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
     private Class<?> catalogItemJavaType;
     private Class<?> specType;
     private boolean deprecated;
+    private boolean disabled;
 
     @SuppressWarnings("unused") // For deserialisation
     private BasicCatalogItemMemento() {}
@@ -158,6 +166,7 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
         this.specType = builder.specType;
         this.javaType = builder.javaType;
         this.deprecated = builder.deprecated;
+        this.disabled = builder.disabled;
     }
 
     @Override
@@ -225,6 +234,11 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
     }
 
     @Override
+    public boolean isDisabled() {
+        return disabled;
+    }
+
+    @Override
     protected void setCustomFields(Map<String, Object> fields) {
         if (!fields.isEmpty()) {
             throw new UnsupportedOperationException("Cannot set custom fields on " + this + ". " +
@@ -250,7 +264,8 @@ public class BasicCatalogItemMemento extends AbstractMemento implements CatalogI
                 .add("catalogItemType", getCatalogItemType())
                 .add("javaType", getJavaType())
                 .add("specType", getSpecType())
-                .add("deprecated", isDeprecated());
+                .add("deprecated", isDeprecated())
+                .add("disabled", isDisabled());
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java
index 36daf49..b49bf52 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java
@@ -424,7 +424,8 @@ public class MementosGenerators {
             .specType(catalogItem.getSpecType())
             .version(catalogItem.getVersion())
             .planYaml(catalogItem.getPlanYaml())
-            .deprecated(catalogItem.isDeprecated());
+            .deprecated(catalogItem.isDeprecated())
+            .disabled(catalogItem.isDisabled());
         return builder.build();
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/core/src/test/java/org/apache/brooklyn/core/catalog/CatalogPredicatesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/CatalogPredicatesTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/CatalogPredicatesTest.java
index 32860a4..e858061 100644
--- a/core/src/test/java/org/apache/brooklyn/core/catalog/CatalogPredicatesTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/catalog/CatalogPredicatesTest.java
@@ -25,17 +25,17 @@ import org.apache.brooklyn.api.catalog.BrooklynCatalog;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
 import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.entity.EntitySpec;
 import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
-import org.apache.brooklyn.core.management.internal.LocalManagementContext;
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import com.google.common.base.Predicates;
 
-import brooklyn.entity.basic.Entities;
 
 public class CatalogPredicatesTest {
     private LocalManagementContext mgmt;
@@ -79,6 +79,21 @@ public class CatalogPredicatesTest {
     }
     
     @Test
+    public void testDisabled() {
+        CatalogItem<Entity, EntitySpec<?>> item = createItem(CatalogItemBuilder.newEntity("foo", "1.0")
+                .plan("services:\n- type: brooklyn.entity.basic.BasicEntity")
+                .build());
+
+        assertTrue(CatalogPredicates.<Entity,EntitySpec<?>>disabled(false).apply(item));
+        assertFalse(CatalogPredicates.<Entity,EntitySpec<?>>disabled(true).apply(item));
+        
+        item = disableItem(item);
+        
+        assertFalse(CatalogPredicates.<Entity,EntitySpec<?>>disabled(false).apply(item));
+        assertTrue(CatalogPredicates.<Entity,EntitySpec<?>>disabled(true).apply(item));
+    }
+    
+    @Test
     public void testIsCatalogItemType() {
         CatalogItem<Entity, EntitySpec<?>> item = createItem(CatalogItemBuilder.newEntity("foo", "1.0")
                 .plan("services:\n- type: brooklyn.entity.basic.BasicEntity")
@@ -150,4 +165,12 @@ public class CatalogPredicatesTest {
         catalog.persist(item);
         return item;
     }
+    
+    @SuppressWarnings("unchecked")
+    protected <T, SpecT> CatalogItem<T, SpecT> disableItem(CatalogItem<T, SpecT> orig) {
+        CatalogItem<T, SpecT> item = (CatalogItem<T, SpecT>) catalog.getCatalogItem(orig.getSymbolicName(), orig.getVersion());
+        item.setDisabled(true);
+        catalog.persist(item);
+        return item;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogVersioningTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogVersioningTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogVersioningTest.java
index e14e291..e7eeba9 100644
--- a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogVersioningTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogVersioningTest.java
@@ -119,6 +119,20 @@ public class CatalogVersioningTest {
     }
     
     @Test
+    public void testGetLatestSkipsDisabled() {
+        String symbolicName = "sampleId";
+        String v1 = "0.1.0";
+        String v2 = "0.2.0";
+        createCatalogItem(symbolicName, v1);
+        createCatalogItem(symbolicName, v2);
+        disableCatalogItem(symbolicName, v2);
+        
+        CatalogItem<?, ?> item = catalog.getCatalogItem(symbolicName, BasicBrooklynCatalog.DEFAULT_VERSION);
+        assertEquals(item.getSymbolicName(), symbolicName);
+        assertEquals(item.getVersion(), v1);
+    }
+    
+    @Test
     public void testDelete() {
         String symbolicName = "sampleId";
         String version = "0.1.0";
@@ -147,6 +161,12 @@ public class CatalogVersioningTest {
                 .build());
     }
 
+    private void disableCatalogItem(String symbolicName, String version) {
+        CatalogItem<?, ?> item = catalog.getCatalogItem(symbolicName, version);
+        item.setDisabled(true);
+        catalog.persist(item);
+    }
+
     private void assertSingleCatalogItem(String symbolicName, String version) {
         Iterable<CatalogItem<Object, Object>> items = catalog.getCatalogItems(CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName)));
         CatalogItem<Object, Object> item = Iterables.getOnlyElement(items);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindOptions.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindOptions.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindOptions.java
index 71ce08a..eea64d6 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindOptions.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindOptions.java
@@ -22,8 +22,11 @@ import java.io.File;
 
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.mgmt.rebind.RebindExceptionHandler;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister;
 import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
 
+import com.google.common.base.Function;
+
 /**
  * See {@link RebindTestFixture#rebind(RebindOptions)} and {@link RebindTestUtils#rebind(RebindOptions)}.
  */
@@ -35,6 +38,7 @@ public class RebindOptions {
     public ManagementContext newManagementContext;
     public File mementoDir;
     public File mementoDirBackup;
+    public Function<BrooklynMementoPersister, Void> stateTransformer;
     public ClassLoader classLoader;
     public PersistenceObjectStore objectStore;
     
@@ -50,6 +54,7 @@ public class RebindOptions {
         result.newManagementContext(options.newManagementContext);
         result.mementoDir(options.mementoDir);
         result.mementoDirBackup(options.mementoDirBackup);
+        result.stateTransformer(options.stateTransformer);
         result.classLoader(options.classLoader);
         result.objectStore(options.objectStore);
         return result;
@@ -82,6 +87,10 @@ public class RebindOptions {
         this.mementoDirBackup = val;
         return this;
     }
+    public RebindOptions stateTransformer(Function<BrooklynMementoPersister, Void> val) {
+        this.stateTransformer = val;
+        return this;
+    }
     public RebindOptions classLoader(ClassLoader val) {
         this.classLoader = val;
         return this;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestUtils.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestUtils.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestUtils.java
index e5696c2f..24c8024 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestUtils.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestUtils.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
 import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
 import org.apache.brooklyn.api.mgmt.rebind.RebindExceptionHandler;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMemento;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoRawData;
 import org.apache.brooklyn.api.objs.BrooklynObjectType;
 import org.apache.brooklyn.api.objs.Identifiable;
@@ -60,6 +61,7 @@ import org.apache.brooklyn.util.time.Duration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Maps;
@@ -386,6 +388,7 @@ public class RebindTestUtils {
         boolean hasPersister = newManagementContext != null && newManagementContext.getRebindManager().getPersister() != null;
         boolean checkSerializable = options.checkSerializable;
         boolean terminateOrigManagementContext = options.terminateOrigManagementContext;
+        Function<BrooklynMementoPersister, Void> stateTransformer = options.stateTransformer;
         
         LOG.info("Rebinding app, using mementoDir " + mementoDir + "; object store " + objectStore);
 
@@ -425,6 +428,11 @@ public class RebindTestUtils {
             FileUtil.setFilePermissionsTo700(mementoDirBackup);
         }
         
+        if (stateTransformer != null) {
+            BrooklynMementoPersister persister = newManagementContext.getRebindManager().getPersister();
+            stateTransformer.apply(persister);
+        }
+        
         List<Application> newApps = newManagementContext.getRebindManager().rebind(classLoader, exceptionHandler, ManagementNodeState.MASTER);
         newManagementContext.getRebindManager().startPersistence();
         return newApps;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
index 6fc71e8..52e6fb1 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
@@ -175,11 +175,18 @@ public class BrooklynComponentTemplateResolver {
     }
 
     protected boolean canResolve() {
-        if (typeResolver.getCatalogItem(this, type)!=null)
-            return true;
-        if (loader.tryLoadClass(getJavaType(), Entity.class).isPresent())
-            return true;
-        return false;
+        CatalogItem<Entity, EntitySpec<?>> item = typeResolver.getCatalogItem(this, type);
+        if (item == null) {
+            return loader.tryLoadClass(getJavaType(), Entity.class).isPresent();
+        }
+        
+        if (item.isDisabled()) {
+            log.warn("Disallowed attempt to use disabled catalog item "+item.getId());
+            return false;
+        } else if (item.isDeprecated()) {
+            log.warn("Use of deprecated catalog item "+item.getId());
+        }
+        return true;
     }
 
     /** returns the entity class, if needed in contexts which scan its statics for example */
@@ -223,9 +230,17 @@ public class BrooklynComponentTemplateResolver {
     @SuppressWarnings({ "unchecked" })
     protected <T extends Entity> EntitySpec<T> createSpec(Set<String> encounteredCatalogTypes) {
         CatalogItem<Entity, EntitySpec<?>> item = getServiceTypeResolver().getCatalogItem(this, getDeclaredType());
+        if (item == null) {
+            // ignore; presumably a java type or some such?
+        } else if (item.isDisabled()) {
+            throw new IllegalStateException("Illegal use of disabled catalog item "+item.getSymbolicName()+":"+item.getVersion());
+        } else if (item.isDeprecated()) {
+            log.warn("Use of deprecated catalog item "+item.getSymbolicName()+":"+item.getVersion());
+        }
+        
         if (encounteredCatalogTypes==null) encounteredCatalogTypes = MutableSet.of();
         
-        //Take the symoblicName part of the catalog item only for recursion detection to prevent
+        //Take the symbolicName part of the catalog item only for recursion detection to prevent
         //cross referencing of different versions. Not interested in non-catalog item types.
         //Prevent catalog items self-referencing even if explicitly different version.
         boolean firstOccurrence = (item == null || encounteredCatalogTypes.add(item.getSymbolicName()));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
index 2b394f7..6982507 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java
@@ -22,6 +22,7 @@ import java.io.Reader;
 import java.io.StringReader;
 import java.util.Set;
 
+import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.mgmt.Task;
@@ -111,7 +112,7 @@ public class AbstractYamlRebindTest extends RebindTestFixture<StartableApplicati
     ///////////////////////////////////////////////////
     
     protected void waitForApplicationTasks(Entity app) {
-        Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(origManagementContext.getExecutionManager(), app);
+        Set<Task<?>> tasks = BrooklynTaskTags.getTasksInEntityContext(mgmt().getExecutionManager(), app);
         getLogger().info("Waiting on " + tasks.size() + " task(s)");
         for (Task<?> t : tasks) {
             t.blockUntilEnded();
@@ -144,11 +145,11 @@ public class AbstractYamlRebindTest extends RebindTestFixture<StartableApplicati
             throw e;
         }
         getLogger().info("Test - created " + assembly);
-        final Entity app = origManagementContext.getEntityManager().getEntity(assembly.getId());
+        final Entity app = mgmt().getEntityManager().getEntity(assembly.getId());
         getLogger().info("App - " + app);
         
         // wait for app to have started
-        Set<Task<?>> tasks = origManagementContext.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
+        Set<Task<?>> tasks = mgmt().getExecutionManager().getTasksWithAllTags(ImmutableList.of(
                 BrooklynTaskTags.EFFECTOR_TAG, 
                 BrooklynTaskTags.tagForContextEntity(app), 
                 BrooklynTaskTags.tagForEffectorCall(app, "start", ConfigBag.newInstance(ImmutableMap.of("locations", ImmutableMap.of())))));
@@ -175,8 +176,8 @@ public class AbstractYamlRebindTest extends RebindTestFixture<StartableApplicati
         addCatalogItems(joinLines(catalogYaml));
     }
 
-    protected void addCatalogItems(String catalogYaml) {
-        mgmt().getCatalog().addItems(catalogYaml, forceUpdate);
+    protected Iterable<? extends CatalogItem<?,?>> addCatalogItems(String catalogYaml) {
+        return mgmt().getCatalog().addItems(catalogYaml, forceUpdate);
     }
 
     protected void deleteCatalogEntity(String catalogItem) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
index 77f0d51..2956478 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
@@ -18,9 +18,27 @@
  */
 package org.apache.brooklyn.camp.brooklyn.catalog;
 
+import static com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.sensor.Enricher;
 import org.apache.brooklyn.camp.brooklyn.AbstractYamlRebindTest;
@@ -28,13 +46,24 @@ import org.apache.brooklyn.core.BrooklynFeatureEnablement;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.entity.StartableApplication;
+import org.apache.brooklyn.core.mgmt.persist.BrooklynMementoPersisterToObjectStore;
+import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
+import org.apache.brooklyn.core.mgmt.rebind.RebindOptions;
 import org.apache.brooklyn.core.test.policy.TestEnricher;
 import org.apache.brooklyn.core.test.policy.TestPolicy;
 import org.apache.brooklyn.entity.stock.BasicEntity;
+import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
 
+import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
 public class CatalogYamlRebindTest extends AbstractYamlRebindTest {
@@ -46,6 +75,9 @@ public class CatalogYamlRebindTest extends AbstractYamlRebindTest {
     
     enum RebindWithCatalogTestMode {
         NO_OP,
+        STRIP_DEPRECATION_AND_ENABLEMENT_FROM_CATALOG_ITEM,
+        DEPRECATE_CATALOG,
+        DISABLE_CATALOG,
         DELETE_CATALOG,
         REPLACE_CATALOG_WITH_NEWER_VERSION;
     }
@@ -55,6 +87,16 @@ public class CatalogYamlRebindTest extends AbstractYamlRebindTest {
         runRebindWithCatalogAndApp(RebindWithCatalogTestMode.NO_OP);
     }
     
+    @Test
+    public void testRebindWithCatalogDeprecatedAndAppExisting() throws Exception {
+        runRebindWithCatalogAndApp(RebindWithCatalogTestMode.DEPRECATE_CATALOG);
+    }
+    
+    @Test
+    public void testRebindWithCatalogDisabledAndAppExisting() throws Exception {
+        runRebindWithCatalogAndApp(RebindWithCatalogTestMode.DISABLE_CATALOG);
+    }
+    
     // See https://issues.apache.org/jira/browse/BROOKLYN-149.
     // Deletes the catalog item before rebind, but the referenced types are still on the 
     // default classpath.
@@ -72,13 +114,22 @@ public class CatalogYamlRebindTest extends AbstractYamlRebindTest {
         runRebindWithCatalogAndApp(RebindWithCatalogTestMode.REPLACE_CATALOG_WITH_NEWER_VERSION);
     }
     
+    /**
+     * Old persisted state for catalog items may not have a "deprecated" or "disabled"
+     * value. Need to check that their absence will default to false.
+     */
+    @Test
+    public void testRebindWithCatalogPropertiesForDeprecationAndEnablementAbsent() throws Exception {
+        runRebindWithCatalogAndApp(RebindWithCatalogTestMode.STRIP_DEPRECATION_AND_ENABLEMENT_FROM_CATALOG_ITEM);
+    }
+
     @SuppressWarnings("unused")
     protected void runRebindWithCatalogAndApp(RebindWithCatalogTestMode mode) throws Exception {
-        String symbolicName = "my.catalog.app.id.load";
-        String version = "0.1.2";
-        String catalogFormat = Joiner.on("\n").join(
+        String appSymbolicName = "my.catalog.app.id.load";
+        String appVersion = "0.1.0";
+        String appCatalogFormat = Joiner.on("\n").join(
                 "brooklyn.catalog:",
-                "  id: " + symbolicName,
+                "  id: " + appSymbolicName,
                 "  version: %s",
                 "  item:",
                 "    type: "+ BasicEntity.class.getName(),
@@ -87,45 +138,203 @@ public class CatalogYamlRebindTest extends AbstractYamlRebindTest {
                 "    brooklyn.policies:",
                 "    - type: "+TestPolicy.class.getName());
         
-        // Create the catalog item
-        addCatalogItems(String.format(catalogFormat, version));
-
+        String locSymbolicName = "my.catalog.loc.id.load";
+        String locVersion = "1.0.0";
+        String locCatalogFormat = Joiner.on("\n").join(
+                "brooklyn.catalog:",
+                "  id: " + locSymbolicName,
+                "  version: %s",
+                "  item.type: location",
+                "  item:",
+                "    type: localhost");
+        
+        // Create the catalog items
+        CatalogItem<?, ?> appItem = Iterables.getOnlyElement(addCatalogItems(String.format(appCatalogFormat, appVersion)));
+        CatalogItem<?, ?> locItem = Iterables.getOnlyElement(addCatalogItems(String.format(locCatalogFormat, locVersion)));
+        final String appItemId = appItem.getId();
+        final String locItemId = locItem.getId();
+        
         // Create an app, using that catalog item
         String yaml = "name: simple-app-yaml\n" +
-                "location: localhost\n" +
+                "location: \"brooklyn.catalog:"+CatalogUtils.getVersionedId(locSymbolicName, locVersion)+"\"\n" +
                 "services: \n" +
-                "- type: "+CatalogUtils.getVersionedId(symbolicName, version);
+                "- type: "+CatalogUtils.getVersionedId(appSymbolicName, appVersion);
         origApp = (StartableApplication) createAndStartApplication(yaml);
         BasicEntity origEntity = (BasicEntity) Iterables.getOnlyElement(origApp.getChildren());
         TestPolicy origPolicy = (TestPolicy) Iterables.getOnlyElement(origEntity.getPolicies());
         TestEnricher origEnricher = (TestEnricher) Iterables.tryFind(origEntity.getEnrichers(), Predicates.instanceOf(TestEnricher.class)).get();
-        assertEquals(origEntity.getCatalogItemId(), symbolicName+":"+version);
+        assertEquals(origEntity.getCatalogItemId(), appSymbolicName+":"+appVersion);
 
         // Depending on test-mode, delete the catalog item, and then rebind
         switch (mode) {
+            case DEPRECATE_CATALOG:
+                appItem = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), appSymbolicName+":"+appVersion);
+                appItem.setDeprecated(true);
+                mgmt().getCatalog().persist(appItem);
+                locItem = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), locSymbolicName+":"+locVersion);
+                locItem.setDeprecated(true);
+                mgmt().getCatalog().persist(locItem);
+                break;
+            case DISABLE_CATALOG:
+                appItem = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), appSymbolicName+":"+appVersion);
+                appItem.setDisabled(true);
+                mgmt().getCatalog().persist(appItem);
+                locItem = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), locSymbolicName+":"+locVersion);
+                locItem.setDisabled(true);
+                mgmt().getCatalog().persist(locItem);
+                break;
             case DELETE_CATALOG:
-                mgmt().getCatalog().deleteCatalogItem(symbolicName, version);
+                mgmt().getCatalog().deleteCatalogItem(appSymbolicName, appVersion);
+                mgmt().getCatalog().deleteCatalogItem(locSymbolicName, locVersion);
                 break;
             case REPLACE_CATALOG_WITH_NEWER_VERSION:
-                mgmt().getCatalog().deleteCatalogItem(symbolicName, version);
-                version = "0.1.3";
-                addCatalogItems(String.format(catalogFormat, version));
+                mgmt().getCatalog().deleteCatalogItem(appSymbolicName, appVersion);
+                mgmt().getCatalog().deleteCatalogItem(locSymbolicName, locVersion);
+                appVersion = "0.2.0";
+                locVersion = "1.1.0";
+                addCatalogItems(String.format(appCatalogFormat, appVersion));
+                addCatalogItems(String.format(locCatalogFormat, locVersion));
                 break;
+            case STRIP_DEPRECATION_AND_ENABLEMENT_FROM_CATALOG_ITEM:
             case NO_OP:
-                // no-op
+                break; // no-op
+            default:
+                throw new IllegalStateException("Unknown mode: "+mode);
+        }
+
+        // Rebind
+        if (mode == RebindWithCatalogTestMode.STRIP_DEPRECATION_AND_ENABLEMENT_FROM_CATALOG_ITEM) {
+            // Edit the persisted state to remove the "deprecated" and "enablement" tags for our catalog items
+            rebind(RebindOptions.create()
+                    .stateTransformer(new Function<BrooklynMementoPersister, Void>() {
+                        @Override public Void apply(BrooklynMementoPersister input) {
+                            PersistenceObjectStore objectStore = ((BrooklynMementoPersisterToObjectStore)input).getObjectStore();
+                            String appItemMemento = checkNotNull(objectStore.newAccessor("catalog/"+appItemId.replace(":", "_")).get(), "appItem in catalog");
+                            String locItemMemento = checkNotNull(objectStore.newAccessor("catalog/"+locItemId.replace(":", "_")).get(), "locItem in catalog");
+                            String newAppItemMemento = removeFromXml(appItemMemento, ImmutableList.of("catalogItem/deprecated", "catalogItem/disabled"));
+                            String newLocItemMemento = removeFromXml(appItemMemento, ImmutableList.of("catalogItem/deprecated", "catalogItem/disabled"));
+                            objectStore.newAccessor("catalog/"+appItemId).put(newAppItemMemento);
+                            objectStore.newAccessor("catalog/"+locItemId).put(newLocItemMemento);
+                            return null;
+                        }}));
+        } else {
+            rebind();
         }
-        
-        rebind();
 
-        // Ensure app is still there
+        // Ensure app is still there, and that it is usabe - e.g. "stop" effector functions as expected
         BasicEntity newEntity = (BasicEntity) Iterables.getOnlyElement(newApp.getChildren());
         Policy newPolicy = Iterables.getOnlyElement(newEntity.getPolicies());
         Enricher newEnricher = Iterables.tryFind(newEntity.getEnrichers(), Predicates.instanceOf(TestEnricher.class)).get();
-        assertEquals(newEntity.getCatalogItemId(), symbolicName+":"+version);
+        assertEquals(newEntity.getCatalogItemId(), appSymbolicName+":"+appVersion);
 
-        // Ensure app is still usable - e.g. "stop" effector functions as expected
         newApp.stop();
         assertFalse(Entities.isManaged(newApp));
         assertFalse(Entities.isManaged(newEntity));
+        
+        // Ensure catalog item is as expecpted
+        CatalogItem<?, ?> newAppItem = mgmt().getCatalog().getCatalogItem(appSymbolicName, appVersion);
+        CatalogItem<?, ?> newLocItem = mgmt().getCatalog().getCatalogItem(locSymbolicName, locVersion);
+
+        boolean itemDeployable;
+        switch (mode) {
+        case DISABLE_CATALOG:
+            assertTrue(newAppItem.isDisabled());
+            assertTrue(newLocItem.isDisabled());
+            itemDeployable = false;
+            break;
+        case DELETE_CATALOG:
+            assertNull(newAppItem);
+            assertNull(newLocItem);
+            itemDeployable = false;
+            break;
+        case DEPRECATE_CATALOG:
+            assertTrue(newAppItem.isDeprecated());
+            assertTrue(newLocItem.isDeprecated());
+            itemDeployable = true;
+            break;
+        case NO_OP:
+        case STRIP_DEPRECATION_AND_ENABLEMENT_FROM_CATALOG_ITEM:
+        case REPLACE_CATALOG_WITH_NEWER_VERSION:
+            assertNotNull(newAppItem);
+            assertNotNull(newLocItem);
+            assertFalse(newAppItem.isDeprecated());
+            assertFalse(newAppItem.isDisabled());
+            assertFalse(newLocItem.isDeprecated());
+            assertFalse(newLocItem.isDisabled());
+            itemDeployable = true;
+            break;
+        default:
+            throw new IllegalStateException("Unknown mode: "+mode);
+        }
+
+        // Try to deploy a new app
+        String yaml2 = "name: simple-app-yaml2\n" +
+                "location: \"brooklyn.catalog:"+CatalogUtils.getVersionedId(locSymbolicName, locVersion)+"\"\n" +
+                "services: \n" +
+                "- type: "+CatalogUtils.getVersionedId(appSymbolicName, appVersion);
+
+        if (itemDeployable) {
+            StartableApplication app2 = (StartableApplication) createAndStartApplication(yaml2);
+            BasicEntity entity2 = (BasicEntity) Iterables.getOnlyElement(app2.getChildren());
+            assertEquals(entity2.getCatalogItemId(), appSymbolicName+":"+appVersion);
+        } else {
+            try {
+                StartableApplication app2 = (StartableApplication) createAndStartApplication(yaml2);
+                fail();
+            } catch (Exception e) {
+                if (mode == RebindWithCatalogTestMode.DELETE_CATALOG) {
+                    if (!e.toString().contains("cannot be matched")) throw e;
+                } else {
+                    assertEquals(mode, RebindWithCatalogTestMode.DISABLE_CATALOG);
+                    if (!e.toString().contains("cannot be matched")) throw e;
+                }
+            }
+        }
+    }
+    
+    /**
+     * Given the "/"-separated path for the elements to be removed, it removes these from the xml
+     * and returns the transformed XML.
+     */
+    private String removeFromXml(String xml, List<String> elementsToRemove) {
+        try {
+            InputSource source = new InputSource(new StringReader(xml));
+            Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source);
+
+            for (String elementToRemove : elementsToRemove) {
+                Node current = null;
+                boolean first = true;
+                for (String tag : elementToRemove.split("/")) {
+                    NodeList matches;
+                    if (first) {
+                        matches = doc.getElementsByTagName(tag);
+                        first = false;
+                    } else {
+                        matches = ((Element)current).getElementsByTagName(tag);
+                    }
+                    if (matches.getLength() > 0) {
+                        current = matches.item(0);
+                    } else {
+                        current = null;
+                        break;
+                    }
+                }
+                if (current != null) {
+                    current.getParentNode().removeChild(current);
+                }
+            }
+          
+            DOMSource domSource = new DOMSource(doc);
+            StringWriter writer = new StringWriter();
+            StreamResult result = new StreamResult(writer);
+            Transformer transformer = TransformerFactory.newInstance().newTransformer();
+            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+            transformer.transform(domSource, result);
+            
+            return writer.toString();
+          
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java
index 818038f..fcbf337 100644
--- a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java
@@ -314,12 +314,39 @@ public interface CatalogApi {
         @ApiParam(name = "version", value = "version identifier of catalog item (application, entity, policy, location)", required=true)
         @PathParam("version") String version);
 
+    /**
+     * @deprecated since 0.8.0; use "/entities/{itemId}/deprecated" with payload of true/false
+     */
+    @Deprecated
     @POST
     @Path("/entities/{itemId}/deprecated/{deprecated}")
-    public void setDeprecated(
+    public void setDeprecatedLegacy(
         @ApiParam(name = "itemId", value = "The ID of the catalog item to be deprecated", required = true)
         @PathParam("itemId") String itemId,
         @ApiParam(name = "deprecated", value = "Whether or not the catalog item is deprecated", required = true)
         @PathParam("deprecated") boolean deprecated);
+    
+    @POST
+    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_PLAIN})
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Undefined catalog item"),
+    })
+    @Path("/entities/{itemId}/deprecated")
+    public void setDeprecated(
+        @ApiParam(name = "itemId", value = "The ID of the catalog item to be deprecated", required = true)
+        @PathParam("itemId") String itemId,
+        @ApiParam(name = "deprecated", value = "Whether or not the catalog item is deprecated", required = true)
+        boolean deprecated);
+    
+    @POST
+    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_PLAIN})
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Undefined catalog item"),
+    })
+    @Path("/entities/{itemId}/disabled")
+    public void setDisabled(
+        @ApiParam(name = "itemId", value = "The ID of the catalog item to be disabled", required = true)
+        @PathParam("itemId") String itemId,
+        @ApiParam(name = "disabled", value = "Whether or not the catalog item is disabled", required = true)
+        boolean disabled);
 }
-

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
index 25e80e0..33752b2 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
@@ -272,7 +272,7 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
         }
 
         log.debug("Creating app from yaml:\n{}", yaml);
-        EntitySpec<? extends Application> spec = EntityManagementUtils.createEntitySpecForApplication(mgmt(), yaml);
+        EntitySpec<? extends Application> spec = createEntitySpecForApplication(yaml);
         
         if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.DEPLOY_APPLICATION, spec)) {
             throw WebResourceUtils.unauthorized("User '%s' is not authorized to start application %s",
@@ -330,7 +330,7 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
 
         //TODO infer encoding from request
         String potentialYaml = new String(inputToAutodetectType);
-        EntitySpec<? extends Application> spec = EntityManagementUtils.createEntitySpecForApplication(mgmt(), potentialYaml);
+        EntitySpec<? extends Application> spec = createEntitySpecForApplication(potentialYaml);
 
         // TODO not json - try ZIP, etc
 
@@ -362,6 +362,21 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
         return status(ACCEPTED).entity(ts).build();
     }
 
+    private EntitySpec<? extends Application> createEntitySpecForApplication(String potentialYaml) {
+        try {
+            return EntityManagementUtils.createEntitySpecForApplication(mgmt(), potentialYaml);
+        } catch (IllegalStateException e) {
+            // An IllegalArgumentException for creating the entity spec gets wrapped in a ISE.
+            // But we want to return a 400 rather than 500, so ensure we throw IAE.
+            if (e.getCause() != null && Exceptions.getFirstInteresting(e.getCause()) instanceof IllegalArgumentException) {
+                IllegalArgumentException iae = (IllegalArgumentException) Exceptions.getFirstInteresting(e.getCause());
+                throw new IllegalArgumentException("Cannot create spec for app: "+iae.getMessage(), e);
+            } else {
+                throw e;
+            }
+        }
+    }
+    
     private void checkApplicationTypesAreValid(ApplicationSpec applicationSpec) {
         String appType = applicationSpec.getType();
         if (appType != null) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
index 972a134..3dc578b 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
@@ -33,8 +33,6 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
 import org.apache.brooklyn.api.entity.Application;
@@ -67,6 +65,8 @@ import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.StringPredicates;
 import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
@@ -216,15 +216,21 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
 
     @Override
     public List<CatalogEntitySummary> listEntities(String regex, String fragment, boolean allVersions) {
-        List<CatalogItemSummary> result = getCatalogItemSummariesMatchingRegexFragment(CatalogPredicates.IS_ENTITY, regex, fragment, allVersions);
+        Predicate<CatalogItem<Entity, EntitySpec<?>>> filter =
+                Predicates.and(
+                        CatalogPredicates.IS_ENTITY,
+                        CatalogPredicates.<Entity, EntitySpec<?>>disabled(false));
+        List<CatalogItemSummary> result = getCatalogItemSummariesMatchingRegexFragment(filter, regex, fragment, allVersions);
         return castList(result, CatalogEntitySummary.class);
     }
 
     @Override
     public List<CatalogItemSummary> listApplications(String regex, String fragment, boolean allVersions) {
         Predicate<CatalogItem<Application, EntitySpec<? extends Application>>> filter =
-                Predicates.and(CatalogPredicates.<Application,EntitySpec<? extends Application>>deprecated(false),
-                        CatalogPredicates.IS_TEMPLATE);
+                Predicates.and(
+                        CatalogPredicates.IS_TEMPLATE,
+                        CatalogPredicates.<Application,EntitySpec<? extends Application>>deprecated(false),
+                        CatalogPredicates.<Application,EntitySpec<? extends Application>>disabled(false));
         return getCatalogItemSummariesMatchingRegexFragment(filter, regex, fragment, allVersions);
     }
 
@@ -279,7 +285,11 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
 
     @Override
     public List<CatalogPolicySummary> listPolicies(String regex, String fragment, boolean allVersions) {
-        List<CatalogItemSummary> result = getCatalogItemSummariesMatchingRegexFragment(CatalogPredicates.IS_POLICY, regex, fragment, allVersions);
+        Predicate<CatalogItem<Policy, PolicySpec<?>>> filter =
+                Predicates.and(
+                        CatalogPredicates.IS_POLICY,
+                        CatalogPredicates.<Policy, PolicySpec<?>>disabled(false));
+        List<CatalogItemSummary> result = getCatalogItemSummariesMatchingRegexFragment(filter, regex, fragment, allVersions);
         return castList(result, CatalogPolicySummary.class);
     }
 
@@ -321,7 +331,11 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
 
     @Override
     public List<CatalogLocationSummary> listLocations(String regex, String fragment, boolean allVersions) {
-        List<CatalogItemSummary> result = getCatalogItemSummariesMatchingRegexFragment(CatalogPredicates.IS_LOCATION, regex, fragment, allVersions);
+        Predicate<CatalogItem<Location, LocationSpec<?>>> filter =
+                Predicates.and(
+                        CatalogPredicates.IS_LOCATION,
+                        CatalogPredicates.<Location, LocationSpec<?>>disabled(false));
+        List<CatalogItemSummary> result = getCatalogItemSummariesMatchingRegexFragment(filter, regex, fragment, allVersions);
         return castList(result, CatalogLocationSummary.class);
     }
 
@@ -405,6 +419,13 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
     }
 
     @Override
+    public void setDeprecatedLegacy(String itemId, boolean deprecated) {
+        log.warn("Use of deprecated \"/v1/catalog/entities/{itemId}/deprecated/{deprecated}\" for "+itemId
+                +"; use \"/v1/catalog/entities/{itemId}/deprecated\" with request body");
+        setDeprecated(itemId, deprecated);
+    }
+    
+    @Override
     public void setDeprecated(String itemId, boolean deprecated) {
         if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_CATALOG_ITEM, StringAndArgument.of(itemId, "deprecated"))) {
             throw WebResourceUtils.unauthorized("User '%s' is not authorized to modify catalog",
@@ -417,6 +438,19 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
         mgmt().getCatalog().persist(item);
     }
 
+    @Override
+    public void setDisabled(String itemId, boolean disabled) {
+        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_CATALOG_ITEM, StringAndArgument.of(itemId, "disabled"))) {
+            throw WebResourceUtils.unauthorized("User '%s' is not authorized to modify catalog",
+                    Entitlements.getEntitlementContext().user());
+        }
+        CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), itemId);
+        if (item==null)
+            throw WebResourceUtils.notFound("Catalog item with id '%s' not found", itemId);
+        item.setDisabled(disabled);
+        mgmt().getCatalog().persist(item);
+    }
+
     private Response getCatalogItemIcon(CatalogItem<?, ?> result) {
         String url = result.getIconUrl();
         if (url==null) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
index fd495d8..1d342d2 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
@@ -26,6 +26,7 @@ import static org.testng.Assert.assertTrue;
 import java.io.IOException;
 import java.net.URI;
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.TimeoutException;
@@ -34,28 +35,6 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.test.HttpTestUtils;
-import org.apache.brooklyn.util.collections.CollectionFunctionals;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.GenericType;
-import com.sun.jersey.api.client.UniformInterfaceException;
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.core.util.MultivaluedMapImpl;
-
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.EntityLocal;
 import org.apache.brooklyn.core.entity.Attributes;
@@ -72,6 +51,8 @@ import org.apache.brooklyn.entity.stock.BasicEntity;
 import org.apache.brooklyn.rest.domain.ApiError;
 import org.apache.brooklyn.rest.domain.ApplicationSpec;
 import org.apache.brooklyn.rest.domain.ApplicationSummary;
+import org.apache.brooklyn.rest.domain.CatalogEntitySummary;
+import org.apache.brooklyn.rest.domain.CatalogItemSummary;
 import org.apache.brooklyn.rest.domain.EffectorSummary;
 import org.apache.brooklyn.rest.domain.EntityConfigSummary;
 import org.apache.brooklyn.rest.domain.EntitySpec;
@@ -86,6 +67,29 @@ import org.apache.brooklyn.rest.testing.mocks.NameMatcherGroup;
 import org.apache.brooklyn.rest.testing.mocks.RestMockApp;
 import org.apache.brooklyn.rest.testing.mocks.RestMockAppBuilder;
 import org.apache.brooklyn.rest.testing.mocks.RestMockSimpleEntity;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.HttpTestUtils;
+import org.apache.brooklyn.util.collections.CollectionFunctionals;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.http.HttpHeaders;
+import org.apache.http.entity.ContentType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.GenericType;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.core.util.MultivaluedMapImpl;
 
 @Test(singleThreaded = true)
 public class ApplicationResourceTest extends BrooklynRestResourceTest {
@@ -595,4 +599,97 @@ public class ApplicationResourceTest extends BrooklynRestResourceTest {
                 EntityFunctions.applications(getManagementContext()),
                 Predicates.compose(Predicates.equalTo(size-1), CollectionFunctionals.sizeFunction()) );
     }
+
+    @Test
+    public void testDisabledApplicationCatalog() throws TimeoutException, InterruptedException {
+        String itemSymbolicName = "my.catalog.item.id.for.disabling";
+        String itemVersion = "1.0";
+        String serviceType = "org.apache.brooklyn.entity.stock.BasicApplication";
+        
+        // Deploy the catalog item
+        addTestCatalogItem(itemSymbolicName, "template", itemVersion, serviceType);
+        List<CatalogEntitySummary> itemSummaries = client().resource("/v1/catalog/applications")
+                .queryParam("fragment", itemSymbolicName).queryParam("allVersions", "true").get(new GenericType<List<CatalogEntitySummary>>() {});
+        CatalogItemSummary itemSummary = Iterables.getOnlyElement(itemSummaries);
+        String itemVersionedId = String.format("%s:%s", itemSummary.getSymbolicName(), itemSummary.getVersion());
+        assertEquals(itemSummary.getId(), itemVersionedId);
+
+        try {
+            // Create an app before disabling: this should work
+            String yaml = "{ name: my-app, location: localhost, services: [ { type: \""+itemVersionedId+"\" } ] }";
+            ClientResponse response = client().resource("/v1/applications")
+                    .entity(yaml, "application/x-yaml")
+                    .post(ClientResponse.class);
+            assertTrue(response.getStatus()/100 == 2, "response is "+response);
+            waitForPageFoundResponse("/v1/applications/my-app", ApplicationSummary.class);
+    
+            // Deprecate
+            deprecateCatalogItem(itemSymbolicName, itemVersion, true);
+
+            // Create an app when deprecated: this should work
+            String yaml2 = "{ name: my-app2, location: localhost, services: [ { type: \""+itemVersionedId+"\" } ] }";
+            ClientResponse response2 = client().resource("/v1/applications")
+                    .entity(yaml2, "application/x-yaml")
+                    .post(ClientResponse.class);
+            assertTrue(response2.getStatus()/100 == 2, "response is "+response2);
+            waitForPageFoundResponse("/v1/applications/my-app2", ApplicationSummary.class);
+    
+            // Disable
+            disableCatalogItem(itemSymbolicName, itemVersion, true);
+
+            // Now try creating an app; this should fail because app is disabled
+            String yaml3 = "{ name: my-app3, location: localhost, services: [ { type: \""+itemVersionedId+"\" } ] }";
+            ClientResponse response3 = client().resource("/v1/applications")
+                    .entity(yaml3, "application/x-yaml")
+                    .post(ClientResponse.class);
+            assertTrue(response3.getStatus()/100 == 4, "response is "+response3);
+            assertTrue(response3.getEntity(String.class).contains("cannot be matched"));
+            waitForPageNotFoundResponse("/v1/applications/my-app3", ApplicationSummary.class);
+            
+        } finally {
+            client().resource("/v1/applications/my-app")
+                    .delete(ClientResponse.class);
+
+            client().resource("/v1/applications/my-app2")
+                    .delete(ClientResponse.class);
+
+            client().resource("/v1/applications/my-app3")
+                    .delete(ClientResponse.class);
+
+            client().resource("/v1/catalog/entities/"+itemVersionedId+"/"+itemVersion)
+                    .delete(ClientResponse.class);
+        }
+    }
+
+    private void deprecateCatalogItem(String symbolicName, String version, boolean deprecated) {
+        String id = String.format("%s:%s", symbolicName, version);
+        ClientResponse response = client().resource(String.format("/v1/catalog/entities/%s/deprecated", id))
+                    .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
+                    .post(ClientResponse.class, deprecated);
+        assertEquals(response.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+    }
+    
+    private void disableCatalogItem(String symbolicName, String version, boolean disabled) {
+        String id = String.format("%s:%s", symbolicName, version);
+        ClientResponse response = client().resource(String.format("/v1/catalog/entities/%s/disabled", id))
+                .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
+                .post(ClientResponse.class, disabled);
+        assertEquals(response.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+    }
+
+    private void addTestCatalogItem(String catalogItemId, String itemType, String version, String service) {
+        String yaml =
+                "brooklyn.catalog:\n"+
+                "  id: " + catalogItemId + "\n"+
+                "  name: My Catalog App\n"+
+                (itemType!=null ? "  item_type: "+itemType+"\n" : "")+
+                "  description: My description\n"+
+                "  icon_url: classpath:///redis-logo.png\n"+
+                "  version: " + version + "\n"+
+                "\n"+
+                "services:\n"+
+                "- type: " + service + "\n";
+
+        client().resource("/v1/catalog").post(yaml);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/da70a8e3/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResourceTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResourceTest.java
index b2991b2..3ce0e56 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResourceTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/CatalogResourceTest.java
@@ -33,13 +33,6 @@ import java.util.Set;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
-import org.eclipse.jetty.http.HttpStatus;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-import org.testng.reporters.Files;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
@@ -51,6 +44,15 @@ import org.apache.brooklyn.rest.domain.CatalogLocationSummary;
 import org.apache.brooklyn.rest.domain.CatalogPolicySummary;
 import org.apache.brooklyn.rest.testing.BrooklynRestResourceTest;
 import org.apache.brooklyn.test.support.TestResourceUnavailableException;
+import org.apache.http.HttpHeaders;
+import org.apache.http.entity.ContentType;
+import org.eclipse.jetty.http.HttpStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.testng.reporters.Files;
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.Iterables;
@@ -254,7 +256,31 @@ public class CatalogResourceTest extends BrooklynRestResourceTest {
         client().resource("/v1/catalog").post(yaml);
     }
 
+    private enum DeprecateStyle {
+        NEW_STYLE,
+        LEGACY_STYLE
+    }
+    private void deprecateCatalogItem(DeprecateStyle style, String symbolicName, String version, boolean deprecated) {
+        String id = String.format("%s:%s", symbolicName, version);
+        ClientResponse response;
+        if (style == DeprecateStyle.NEW_STYLE) {
+            response = client().resource(String.format("/v1/catalog/entities/%s/deprecated", id))
+                    .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
+                    .post(ClientResponse.class, deprecated);
+        } else {
+            response = client().resource(String.format("/v1/catalog/entities/%s/deprecated/%s", id, deprecated))
+                    .post(ClientResponse.class);
+        }
+        assertEquals(response.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+    }
 
+    private void disableCatalogItem(String symbolicName, String version, boolean disabled) {
+        String id = String.format("%s:%s", symbolicName, version);
+        ClientResponse getDisableResponse = client().resource(String.format("/v1/catalog/entities/%s/disabled", id))
+                .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
+                .post(ClientResponse.class, disabled);
+        assertEquals(getDisableResponse.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+    }
 
     @Test
     public void testListPolicies() {
@@ -352,39 +378,87 @@ public class CatalogResourceTest extends BrooklynRestResourceTest {
 
     @Test
     public void testSetDeprecated() {
-        String itemId = "my.catalog.item.id.for.deprecation";
-        String serviceType = "org.apache.brooklyn.entity.stock.BasicApplication";
-        addTestCatalogItem(itemId, "template", TEST_VERSION, serviceType);
-        addTestCatalogItem(itemId, "template", "2.0", serviceType);
-        List<CatalogEntitySummary> applications = client().resource("/v1/catalog/applications")
-                .queryParam("fragment", itemId).queryParam("allVersions", "true").get(new GenericType<List<CatalogEntitySummary>>() {});
-        assertEquals(applications.size(), 2);
-        CatalogItemSummary summary0 = applications.get(0);
-        CatalogItemSummary summary1 = applications.get(1);
-
-        // Ensure that the ID required by the API is in the 'usual' format of name:id
-        String id = String.format("%s:%s", summary0.getSymbolicName(), summary0.getVersion());
-        assertEquals(summary0.getId(), id);
-        ClientResponse getDeprecationResponse = client().resource(String.format("/v1/catalog/entities/%s/deprecated/true", id))
-                .post(ClientResponse.class);
-
-        assertEquals(getDeprecationResponse.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
-
-        List<CatalogEntitySummary> applicationsAfterDeprecation = client().resource("/v1/catalog/applications")
-                .queryParam("fragment", "basicapp").queryParam("allVersions", "true").get(new GenericType<List<CatalogEntitySummary>>() {});
-
-        assertEquals(applicationsAfterDeprecation.size(), 1);
-        assertTrue(applicationsAfterDeprecation.contains(summary1));
-
-        ClientResponse getUnDeprecationResponse = client().resource(String.format("/v1/catalog/entities/%s/deprecated/false", summary0.getId()))
-                .post(ClientResponse.class);
-
-        assertEquals(getUnDeprecationResponse.getStatus(), Response.Status.NO_CONTENT.getStatusCode());
+        runSetDeprecated(DeprecateStyle.NEW_STYLE);
+    }
+    
+    // Uses old-style "/v1/catalog/{itemId}/deprecated/true", rather than the "true" in the request body.
+    @Test
+    @Deprecated
+    public void testSetDeprecatedLegacy() {
+        runSetDeprecated(DeprecateStyle.LEGACY_STYLE);
+    }
 
-        List<CatalogEntitySummary> applicationsAfterUnDeprecation = client().resource("/v1/catalog/applications")
-                .queryParam("fragment", "basicapp").queryParam("allVersions", "true").get(new GenericType<List<CatalogEntitySummary>>() {});
+    protected void runSetDeprecated(DeprecateStyle style) {
+        String symbolicName = "my.catalog.item.id.for.deprecation";
+        String serviceType = "org.apache.brooklyn.entity.stock.BasicApplication";
+        addTestCatalogItem(symbolicName, "template", TEST_VERSION, serviceType);
+        addTestCatalogItem(symbolicName, "template", "2.0", serviceType);
+        try {
+            List<CatalogEntitySummary> applications = client().resource("/v1/catalog/applications")
+                    .queryParam("fragment", symbolicName).queryParam("allVersions", "true").get(new GenericType<List<CatalogEntitySummary>>() {});
+            assertEquals(applications.size(), 2);
+            CatalogItemSummary summary0 = applications.get(0);
+            CatalogItemSummary summary1 = applications.get(1);
+    
+            // Deprecate: that app should be excluded
+            deprecateCatalogItem(style, summary0.getSymbolicName(), summary0.getVersion(), true);
+    
+            List<CatalogEntitySummary> applicationsAfterDeprecation = client().resource("/v1/catalog/applications")
+                    .queryParam("fragment", "basicapp").queryParam("allVersions", "true").get(new GenericType<List<CatalogEntitySummary>>() {});
+    
+            assertEquals(applicationsAfterDeprecation.size(), 1);
+            assertTrue(applicationsAfterDeprecation.contains(summary1));
+    
+            // Un-deprecate: that app should be included again
+            deprecateCatalogItem(style, summary0.getSymbolicName(), summary0.getVersion(), false);
+    
+            List<CatalogEntitySummary> applicationsAfterUnDeprecation = client().resource("/v1/catalog/applications")
+                    .queryParam("fragment", "basicapp").queryParam("allVersions", "true").get(new GenericType<List<CatalogEntitySummary>>() {});
+    
+            assertEquals(applications, applicationsAfterUnDeprecation);
+        } finally {
+            client().resource("/v1/catalog/entities/"+symbolicName+"/"+TEST_VERSION)
+                    .delete(ClientResponse.class);
+            client().resource("/v1/catalog/entities/"+symbolicName+"/"+"2.0")
+                    .delete(ClientResponse.class);
+        }
+    }
 
-        assertEquals(applications, applicationsAfterUnDeprecation);
+    @Test
+    public void testSetDisabled() {
+        String symbolicName = "my.catalog.item.id.for.disabling";
+        String serviceType = "org.apache.brooklyn.entity.stock.BasicApplication";
+        addTestCatalogItem(symbolicName, "template", TEST_VERSION, serviceType);
+        addTestCatalogItem(symbolicName, "template", "2.0", serviceType);
+        try {
+            List<CatalogEntitySummary> applications = client().resource("/v1/catalog/applications")
+                    .queryParam("fragment", symbolicName).queryParam("allVersions", "true").get(new GenericType<List<CatalogEntitySummary>>() {});
+            assertEquals(applications.size(), 2);
+            CatalogItemSummary summary0 = applications.get(0);
+            CatalogItemSummary summary1 = applications.get(1);
+    
+            // Disable: that app should be excluded
+            disableCatalogItem(summary0.getSymbolicName(), summary0.getVersion(), true);
+    
+            List<CatalogEntitySummary> applicationsAfterDisabled = client().resource("/v1/catalog/applications")
+                    .queryParam("fragment", "basicapp").queryParam("allVersions", "true").get(new GenericType<List<CatalogEntitySummary>>() {});
+    
+            assertEquals(applicationsAfterDisabled.size(), 1);
+            assertTrue(applicationsAfterDisabled.contains(summary1));
+    
+            // Un-disable: that app should be included again
+            disableCatalogItem(summary0.getSymbolicName(), summary0.getVersion(), false);
+    
+            List<CatalogEntitySummary> applicationsAfterUnDisabled = client().resource("/v1/catalog/applications")
+                    .queryParam("fragment", "basicapp").queryParam("allVersions", "true").get(new GenericType<List<CatalogEntitySummary>>() {});
+    
+            assertEquals(applications, applicationsAfterUnDisabled);
+        } finally {
+            client().resource("/v1/catalog/entities/"+symbolicName+"/"+TEST_VERSION)
+                    .delete(ClientResponse.class);
+            client().resource("/v1/catalog/entities/"+symbolicName+"/"+"2.0")
+                    .delete(ClientResponse.class);
+        }
     }
 
     @Test


[3/3] incubator-brooklyn git commit: This closes #850

Posted by al...@apache.org.
This closes #850


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

Branch: refs/heads/master
Commit: b4547d95ca650498f4daf1f2e2a79c9bdaa8b1fd
Parents: 918c162 da70a8e
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 26 13:25:01 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 26 13:25:01 2015 +0100

----------------------------------------------------------------------
 .../brooklyn/api/catalog/CatalogItem.java       |   9 +-
 .../rebind/mementos/CatalogItemMemento.java     |   1 +
 .../brooklyn/camp/spi/resolve/PdpProcessor.java |   2 +-
 .../core/catalog/CatalogPredicates.java         | 197 ++++++++++++++-
 .../catalog/internal/BasicBrooklynCatalog.java  |   4 +-
 .../catalog/internal/CatalogItemBuilder.java    |   5 +
 .../core/catalog/internal/CatalogItemDo.java    |  10 +
 .../internal/CatalogItemDtoAbstract.java        |  11 +
 .../core/location/CatalogLocationResolver.java  |   6 +
 .../rebind/BasicCatalogItemRebindSupport.java   |   1 +
 .../rebind/dto/BasicCatalogItemMemento.java     |  17 +-
 .../mgmt/rebind/dto/MementosGenerators.java     |   3 +-
 .../core/catalog/CatalogPredicatesTest.java     | 176 +++++++++++++
 .../catalog/internal/CatalogVersioningTest.java |  20 ++
 .../core/mgmt/rebind/RebindOptions.java         |   9 +
 .../core/mgmt/rebind/RebindTestUtils.java       |   8 +
 .../BrooklynComponentTemplateResolver.java      |  27 +-
 .../camp/brooklyn/AbstractYamlRebindTest.java   |  11 +-
 .../brooklyn/catalog/CatalogYamlRebindTest.java | 249 +++++++++++++++++--
 .../apache/brooklyn/rest/api/CatalogApi.java    |  31 ++-
 .../rest/resources/ApplicationResource.java     |  19 +-
 .../rest/resources/CatalogResource.java         |  48 +++-
 .../rest/resources/ApplicationResourceTest.java | 141 +++++++++--
 .../rest/resources/CatalogResourceTest.java     | 150 ++++++++---
 24 files changed, 1038 insertions(+), 117 deletions(-)
----------------------------------------------------------------------