http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/README.md ---------------------------------------------------------------------- diff --git a/README.md b/README.md index 13f1272..07f69e6 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,7 @@ -### HISTORIC REPO: Apache Brooklyn has graduated! +# [](http://brooklyn.apache.org/) -This is the historical **incubator** repo for Apache Brooklyn. -This version of the codebase is no longer active. - -**You're probably in the wrong place.** - -Visit: - -* **The Active Codebase**: at [http://github.com/apache/brooklyn/](http://github.com/apache/brooklyn/) -* **The Apache Brooklyn Homepage**: at [http://brooklyn.apache.org/](http://brooklyn.apache.org/) - -### About the Incubator Project - -Apache Brooklyn was in the Apache Incubator until the end of 2015, on version `0.9.0-SNAPSHOT`. -At this time it graduated to become a top-level Apache Software Foundation project, -and the code moved from `incubator-brooklyn` to `brooklyn` and several other projects `brooklyn-*`. - -Versions `0.8.0-incubating` and before can be found in and built from this repo, -along with the last commit to `0.9.0-SNAPSHOT` from which development has continued -in `apache/brooklyn` and sub-projects. - -The sub-directories in this project correspond to multiple separate repositories now in the `apache` org. -The link above to **[the Active Codebase](http://github.com/apache/brooklyn/)** started life exactly -as a copy of [`brooklyn/`](brooklyn/) in this folder, -as an uber-project for the other `brooklyn-*` folders, including the `server` and the `ui`, -which are now top-level repos in the `apache` org. - - -### To Build - -This historic version of the code can be built with: - - mvn clean install - -This creates a build of the last incubator SNAPSHOT version in `usage/dist/target/brooklyn-dist`. Run -with `bin/brooklyn launch`. Although really you probably want **[the Active Codebase](http://github.com/apache/brooklyn/)**. +### Apache Brooklyn Server Sub-Project +This repo contains the core elements to run a Brooklyn server, +from the API and utils through to the core implementation and the REST server.
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/pom.xml ---------------------------------------------------------------------- diff --git a/api/pom.xml b/api/pom.xml new file mode 100644 index 0000000..f1994f4 --- /dev/null +++ b/api/pom.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <packaging>jar</packaging> + + <artifactId>brooklyn-api</artifactId> + <name>Brooklyn API</name> + + <description> + API classes for Brooklyn + </description> + + <parent> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-parent</artifactId> + <version>0.9.0-SNAPSHOT</version> <!-- BROOKLYN_VERSION --> + <relativePath>../parent/pom.xml</relativePath> + </parent> + + <dependencies> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-utils-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> + <groupId>com.google.code.findbugs</groupId> + <artifactId>jsr305</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-utils-test-support</artifactId> + <scope>test</scope> + <version>${project.version}</version> + </dependency> + </dependencies> + +</project> http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/catalog/BrooklynCatalog.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/catalog/BrooklynCatalog.java b/api/src/main/java/org/apache/brooklyn/api/catalog/BrooklynCatalog.java new file mode 100644 index 0000000..b47d4b1 --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/catalog/BrooklynCatalog.java @@ -0,0 +1,141 @@ +/* + * 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.api.catalog; + +import java.util.Collection; +import java.util.NoSuchElementException; + +import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Predicate; + +public interface BrooklynCatalog { + /** + * Version set in catalog when creator does not supply a version, to mean a low priority item; + * and used when requesting to indicate the best version. + * (See {@link #getCatalogItem(String, String)} for discussion of the best version.) + */ + static String DEFAULT_VERSION = "0.0.0_DEFAULT_VERSION"; + + /** @return The item matching the given given + * {@link CatalogItem#getSymbolicName() symbolicName} + * and optionally {@link CatalogItem#getVersion()}, + * taking the best version if the version is {@link #DEFAULT_VERSION} or null, + * returning null if no matches are found. */ + CatalogItem<?,?> getCatalogItem(String symbolicName, String version); + + /** @return Deletes the item with the given {@link CatalogItem#getSymbolicName() + * symbolicName} and version + * @throws NoSuchElementException if not found */ + void deleteCatalogItem(String symbolicName, String version); + + /** variant of {@link #getCatalogItem(String, String)} which checks (and casts) type for convenience + * (returns null if type does not match) */ + <T,SpecT> CatalogItem<T,SpecT> getCatalogItem(Class<T> type, String symbolicName, String version); + + /** @return All items in the catalog */ + <T,SpecT> Iterable<CatalogItem<T,SpecT>> getCatalogItems(); + + /** convenience for filtering items in the catalog; see CatalogPredicates for useful filters */ + <T,SpecT> Iterable<CatalogItem<T,SpecT>> getCatalogItems(Predicate<? super CatalogItem<T,SpecT>> filter); + + /** persists the catalog item to the object store, if persistence is enabled */ + public void persist(CatalogItem<?, ?> catalogItem); + + /** @return The classloader which should be used to load classes and entities; + * this includes all the catalog's classloaders in the right order. + * This is a wrapper which will update as the underlying catalog items change, + * so it is safe for callers to keep a handle on this. */ + public ClassLoader getRootClassLoader(); + + /** creates a spec for the given catalog item, throwing exceptions if any problems */ + // TODO this should be cached on the item and renamed getSpec(...), else we re-create it too often (every time catalog is listed) + <T, SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT createSpec(CatalogItem<T, SpecT> item); + + /** + * Adds an item (represented in yaml) to the catalog. + * Fails if the same version exists in catalog. + * + * @throws IllegalArgumentException if the yaml was invalid + * @deprecated since 0.7.0 use {@link #addItems(String, boolean)} + */ + @Deprecated + CatalogItem<?,?> addItem(String yaml); + + /** + * Adds an item (represented in yaml) to the catalog. + * + * @param forceUpdate If true allows catalog update even when an + * item exists with the same symbolicName and version + * + * @throws IllegalArgumentException if the yaml was invalid + * @deprecated since 0.7.0 use {@link #addItems(String, boolean)} + */ + @Deprecated + CatalogItem<?,?> addItem(String yaml, boolean forceUpdate); + + /** + * Adds items (represented in yaml) to the catalog. + * Fails if the same version exists in catalog. + * + * @throws IllegalArgumentException if the yaml was invalid + */ + Iterable<? extends CatalogItem<?,?>> addItems(String yaml); + + /** + * Adds items (represented in yaml) to the catalog. + * + * @param forceUpdate If true allows catalog update even when an + * item exists with the same symbolicName and version + * + * @throws IllegalArgumentException if the yaml was invalid + */ + Iterable<? extends CatalogItem<?,?>> addItems(String yaml, boolean forceUpdate); + + /** + * adds an item to the 'manual' catalog; + * this does not update the classpath or have a record to the java Class + * + * @deprecated since 0.7.0 Construct catalogs with yaml (referencing OSGi bundles) instead + */ + // TODO maybe this should stay on the API? -AH Apr 2015 + @Deprecated + void addItem(CatalogItem<?,?> item); + + /** + * Creates a catalog item and adds it to the 'manual' catalog, + * with the corresponding Class definition (loaded by a classloader) + * registered and available in the classloader. + * <p> + * Note that the class will be available for this session only, + * although the record of the item will appear in the catalog DTO if exported, + * so it is recommended to edit the 'manual' catalog DTO if using it to + * generate a catalog, either adding the appropriate classpath URL or removing this entry. + * + * @deprecated since 0.7.0 Construct catalogs with OSGi bundles instead. + * This is used in a handful of tests which should be rewritten to refer to OSGi bundles. + */ + @Deprecated + @VisibleForTesting + CatalogItem<?,?> addItem(Class<?> clazz); + + void reset(Collection<CatalogItem<?, ?>> entries); + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/catalog/Catalog.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/catalog/Catalog.java b/api/src/main/java/org/apache/brooklyn/api/catalog/Catalog.java new file mode 100644 index 0000000..1c6b680 --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/catalog/Catalog.java @@ -0,0 +1,42 @@ +/* + * 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.api.catalog; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * annotation that can be placed on an Application (template), entity or policy + * to give metadata for when used in a catalog and to indicate inclusion in annotation-scanned catalogs + * <p> + * the "id" field used in the catalog is not exposed here but is always taken as the Class.getName() of the annotated item + * if loaded from an annotation. (the "type" field unsurprisingly is given the same value). + * {@link #name()}, if not supplied, is the SimpleName of the class. + */ +@Retention(value = RetentionPolicy.RUNTIME) +@Target(value = { ElementType.TYPE }) +public @interface Catalog { + + String name() default ""; + String description() default ""; + String iconUrl() default ""; + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogConfig.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogConfig.java b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogConfig.java new file mode 100644 index 0000000..88d72cb --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogConfig.java @@ -0,0 +1,38 @@ +/* + * 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.api.catalog; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(value = RetentionPolicy.RUNTIME) +@Target(value = { ElementType.FIELD }) +public @interface CatalogConfig { + + /** a label to be displayed when a config key is exposed as editable in the catalog */ + String label(); + + /** a priority used to determine the order in which config keys are displayed when presenting as editable in the catalog; + * a higher value appears higher in the list. the default is 1. + * (negative values may be used to indicate advanced config which might not be shown unless requested.) */ + double priority() default 1; + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/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 new file mode 100644 index 0000000..795e393 --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.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.api.catalog; + +import java.util.Collection; + +import javax.annotation.Nullable; + +import org.apache.brooklyn.api.entity.Application; +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.entity.EntitySpec; +import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; +import org.apache.brooklyn.api.location.Location; +import org.apache.brooklyn.api.location.LocationSpec; +import org.apache.brooklyn.api.mgmt.rebind.RebindSupport; +import org.apache.brooklyn.api.mgmt.rebind.Rebindable; +import org.apache.brooklyn.api.mgmt.rebind.mementos.CatalogItemMemento; +import org.apache.brooklyn.api.objs.BrooklynObject; +import org.apache.brooklyn.api.policy.Policy; +import org.apache.brooklyn.api.policy.PolicySpec; +import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl; + +import com.google.common.annotations.Beta; + +@Beta +public interface CatalogItem<T,SpecT> extends BrooklynObject, Rebindable { + + public static enum CatalogItemType { + TEMPLATE, + ENTITY, + POLICY, + LOCATION; + + public static CatalogItemType ofSpecClass(Class<? extends AbstractBrooklynObjectSpec<?, ?>> type) { + if (type==null) return null; + if (PolicySpec.class.isAssignableFrom(type)) return POLICY; + if (LocationSpec.class.isAssignableFrom(type)) return LOCATION; + if (EntitySpec.class.isAssignableFrom(type)) return ENTITY; + return null; + } + public static CatalogItemType ofTargetClass(Class<? extends BrooklynObject> type) { + if (type==null) return null; + if (Policy.class.isAssignableFrom(type)) return POLICY; + if (Location.class.isAssignableFrom(type)) return LOCATION; + if (Application.class.isAssignableFrom(type)) return TEMPLATE; + if (Entity.class.isAssignableFrom(type)) return ENTITY; + return null; + } + } + + public static interface CatalogBundle extends OsgiBundleWithUrl { + /** @deprecated since 0.9.0, use {@link #isNameResolved()} */ + public boolean isNamed(); + } + + /** + * @throws UnsupportedOperationException; config not supported for catalog items + */ + @Override + ConfigurationSupport config(); + + /** + * @throws UnsupportedOperationException; subscriptions are not supported for catalog items + */ + @Override + SubscriptionSupport subscriptions(); + + /** @deprecated since 0.7.0 in favour of {@link CatalogBundle}, kept for rebind compatibility */ + @Deprecated + public static interface CatalogItemLibraries { + Collection<String> getBundles(); + } + + public CatalogItemType getCatalogItemType(); + + /** @return The high-level type of this entity, e.g. Entity (not a specific Entity class) */ + public Class<T> getCatalogItemJavaType(); + + /** @return The type of the spec e.g. EntitySpec corresponding to {@link #getCatalogItemJavaType()} */ + public Class<SpecT> getSpecType(); + + /** + * @return The underlying java type of the item represented, if not described via a YAML spec. + * Normally null (and the type comes from yaml). + * @deprecated since 0.9.0. Use plan based items instead ({@link #getPlanYaml()}) + */ + @Deprecated + @Nullable public String getJavaType(); + + /** @deprecated since 0.7.0. Use {@link #getDisplayName} */ + @Deprecated + public String getName(); + + /** @deprecated since 0.7.0. Use {@link #getSymbolicName} */ + @Deprecated + public String getRegisteredTypeName(); + + @Nullable public String getDescription(); + + @Nullable public String getIconUrl(); + + public String getSymbolicName(); + + public String getVersion(); + + public Collection<CatalogBundle> getLibraries(); + + public String toXmlString(); + + /** @return The underlying YAML for this item, if known; + * currently including `services:` or `brooklyn.policies:` prefix (but this will likely be removed) */ + @Nullable public String getPlanYaml(); + + @Override + RebindSupport<CatalogItemMemento> getRebindSupport(); + + /** Built up from {@link #getSymbolicName()} and {@link #getVersion()}. + * + * (It is a bit self-referential having this method on this type of {@link BrooklynObject}, + * but it is easier this than making the interface hierarchy more complicated.) */ + @Override + public String getCatalogItemId(); + + public void setDeprecated(boolean deprecated); + + public void setDisabled(boolean disabled); + + /** + * @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/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/effector/Effector.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/effector/Effector.java b/api/src/main/java/org/apache/brooklyn/api/effector/Effector.java new file mode 100644 index 0000000..82ce6ee --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/effector/Effector.java @@ -0,0 +1,56 @@ +/* + * 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.api.effector; + +import java.io.Serializable; +import java.util.List; + +import javax.management.MBeanOperationInfo; + +import org.apache.brooklyn.api.entity.Entity; + +/** + * An operation of some kind, carried out by an {@link Entity}. + * + * Similar to the concepts in the JMX {@link MBeanOperationInfo} class. + */ +public interface Effector<T> extends Serializable { + /** + * human-friendly name of the effector (although frequently this uses java method naming convention) + */ + String getName(); + + Class<T> getReturnType(); + + /** + * canonical name of return type (in case return type does not resolve after serialization) + */ + String getReturnTypeName(); + + /** + * parameters expected by method, including name and type, optional description and default value + */ + List<ParameterType<?>> getParameters(); + + /** + * optional description for the effector + */ + String getDescription(); + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/effector/ParameterType.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/effector/ParameterType.java b/api/src/main/java/org/apache/brooklyn/api/effector/ParameterType.java new file mode 100644 index 0000000..7f0736d --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/effector/ParameterType.java @@ -0,0 +1,48 @@ +/* + * 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.api.effector; + +import java.io.Serializable; + +import javax.management.MBeanParameterInfo; + +/** + * Similar to the concepts in the JMX {@link MBeanParameterInfo} class. + * + * @see Effector + */ +public interface ParameterType<T> extends Serializable { + + public String getName(); + + public Class<T> getParameterClass(); + + /** + * The canonical name of the parameter class; especially useful if the class + * cannot be resolved after deserialization. + */ + public String getParameterClassName(); + + public String getDescription(); + + /** + * @return The default value for this parameter, if not supplied during an effector call. + */ + public T getDefaultValue(); +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/entity/Application.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/Application.java b/api/src/main/java/org/apache/brooklyn/api/entity/Application.java new file mode 100644 index 0000000..402d004 --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/entity/Application.java @@ -0,0 +1,34 @@ +/* + * 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.api.entity; + +import org.apache.brooklyn.api.mgmt.ManagementContext; + + +/** + * An application is the root of the entity hierarchy. In the parent-child relationship, it is + * the top-level entity under which the application's entities are all places. + * + * The recommended ways to write a new application are to either extend {@link org.apache.brooklyn.entity.factory.ApplicationBuilder} + * or to extend {@link org.apache.brooklyn.core.entity.AbstractApplication}. + */ +public interface Application extends Entity { + + ManagementContext getManagementContext(); +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java b/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java new file mode 100644 index 0000000..14d3c23 --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java @@ -0,0 +1,442 @@ +/* + * 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.api.entity; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; + +import javax.annotation.Nullable; + +import org.apache.brooklyn.api.effector.Effector; +import org.apache.brooklyn.api.location.Location; +import org.apache.brooklyn.api.mgmt.Task; +import org.apache.brooklyn.api.objs.BrooklynObject; +import org.apache.brooklyn.api.objs.EntityAdjunct; +import org.apache.brooklyn.api.policy.Policy; +import org.apache.brooklyn.api.policy.PolicySpec; +import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.api.sensor.Enricher; +import org.apache.brooklyn.api.sensor.EnricherSpec; +import org.apache.brooklyn.api.sensor.Feed; +import org.apache.brooklyn.api.sensor.Sensor; +import org.apache.brooklyn.api.sensor.SensorEvent; +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.config.ConfigKey.HasConfigKey; +import org.apache.brooklyn.util.guava.Maybe; + +import com.google.common.annotations.Beta; +import com.google.common.base.Function; + +/** + * The basic interface for a Brooklyn entity. + * <p> + * Implementors of entities are strongly encouraged to extend {@link org.apache.brooklyn.core.entity.AbstractEntity}. + * <p> + * To instantiate an entity, see {@code managementContext.getEntityManager().createEntity(entitySpec)}. + * Also see {@link org.apache.brooklyn.core.entity.factory.ApplicationBuilder}, + * {@link org.apache.brooklyn.core.entity.AbstractEntity#addChild(EntitySpec)}, and + * {@link org.apache.brooklyn.api.entity.EntitySpec}. + * <p> + * + * @see org.apache.brooklyn.core.entity.AbstractEntity + */ +public interface Entity extends BrooklynObject { + /** + * The unique identifier for this entity. + */ + @Override + String getId(); + + /** + * Returns the creation time for this entity, in UTC. + */ + long getCreationTime(); + + /** + * A display name; recommended to be a concise single-line description. + */ + String getDisplayName(); + + /** + * A URL pointing to an image which can be used to represent this entity. + */ + @Nullable String getIconUrl(); + + /** + * Information about the type of this entity; analogous to Java's object.getClass. + */ + EntityType getEntityType(); + + /** + * @return the {@link Application} this entity is registered with, or null if not registered. + */ + Application getApplication(); + + /** + * @return the id of the {@link Application} this entity is registered with, or null if not registered. + */ + String getApplicationId(); + + /** + * The parent of this entity, null if no parent. + * + * The parent is normally the entity responsible for creating/destroying/managing this entity. + * + * @see #setParent(Entity) + * @see #clearParent + */ + Entity getParent(); + + /** + * Return the entities that are children of (i.e. "owned by") this entity + */ + Collection<Entity> getChildren(); + + /** + * Sets the entity's display name. + */ + void setDisplayName(String displayName); + + /** + * Sets the parent (i.e. "owner") of this entity. Returns this entity, for convenience. + * + * @see #getParent + * @see #clearParent + */ + Entity setParent(Entity parent); + + /** + * Clears the parent (i.e. "owner") of this entity. Also cleans up any references within its parent entity. + * + * @see #getParent + * @see #setParent + */ + void clearParent(); + + /** + * Add a child {@link Entity}, and set this entity as its parent, + * returning the added child. + * <p> + * As with {@link #addChild(EntitySpec)} the child is <b>not</b> brought under management + * as part of this call. It should not be managed prior to this call either. + */ + <T extends Entity> T addChild(T child); + + /** + * Creates an {@link Entity} from the given spec and adds it, setting this entity as the parent, + * returning the added child. + * <p> + * The added child is <b>not</b> managed as part of this call, even if the parent is managed, + * so if adding post-management an explicit call to manage the child will be needed; + * see the convenience method <code>Entities.manage(...)</code>. + * */ + <T extends Entity> T addChild(EntitySpec<T> spec); + + /** + * Removes the specified child {@link Entity}; its parent will be set to null. + * + * @return True if the given entity was contained in the set of children + */ + boolean removeChild(Entity child); + + /** + * @return an immutable thread-safe view of the policies. + * + * @deprecated since 0.9.0; see {@link PolicySupport#getPolicies()} + */ + @Deprecated + Collection<Policy> getPolicies(); + + /** + * @return an immutable thread-safe view of the enrichers. + * + * @deprecated since 0.9.0; see {@link EnricherSupport#getEnrichers()} + */ + @Deprecated + Collection<Enricher> getEnrichers(); + + /** + * The {@link Collection} of {@link Group}s that this entity is a member of. + * + * Groupings can be used to allow easy management/monitoring of a group of entities. + * + * @deprecated since 0.9.0; see {@link GroupSupport#getGroups()} and {@link #groups()} + */ + @Deprecated + Collection<Group> getGroups(); + + /** + * Add this entity as a member of the given {@link Group}. Called by framework. + * <p> + * Users should call {@link Group#addMember(Entity)} instead; this method will then + * automatically be called. However, the reverse is not true (calling this method will + * not tell the group; this behaviour may change in a future release!) + * + * @deprecated since 0.9.0; see {@link GroupSupport#add()} and {@link #groups()} + */ + @Deprecated + void addGroup(Group group); + + /** + * Removes this entity as a member of the given {@link Group}. Called by framework. + * <p> + * Users should call {@link Group#removeMember(Entity)} instead; this method will then + * automatically be called. However, the reverse is not true (calling this method will + * not tell the group; this behaviour may change in a future release!) + * + * @deprecated since 0.9.0; see {@link GroupSupport#remove()} and {@link #groups()} + */ + @Deprecated + void removeGroup(Group group); + + /** + * Return all the {@link Location}s this entity is deployed to. + */ + Collection<Location> getLocations(); + + /** + * Convenience for calling {@link SensorSupport#get(AttributeSensor)}, + * via code like {@code sensors().get(key)}. + */ + <T> T getAttribute(AttributeSensor<T> sensor); + + /** + * @see {@link #getConfig(ConfigKey)} + */ + <T> T getConfig(HasConfigKey<T> key); + + /** + * Returns the uncoerced value for this config key as set on this entity, if available, + * not following any inheritance chains and not taking any default. + * + * @deprecated since 0.7.0; use {@code ((EntityInternal)entity).config().getRaw()} or + * {@code ((EntityInternal)entity).config().getLocalRaw()} + */ + @Deprecated + Maybe<Object> getConfigRaw(ConfigKey<?> key, boolean includeInherited); + + /** + * @see {@link #getConfigRaw(ConfigKey, boolean)}. + * + * @deprecated since 0.7.0 + */ + @Deprecated + Maybe<Object> getConfigRaw(HasConfigKey<?> key, boolean includeInherited); + + /** + * Invokes the given effector, with the given parameters to that effector. + */ + <T> Task<T> invoke(Effector<T> eff, Map<String,?> parameters); + + /** + * Adds the given policy to this entity. Also calls policy.setEntity if available. + * + * @deprecated since 0.9.0; see {@link PolicySupport#add(Policy)} + */ + @Deprecated + void addPolicy(Policy policy); + + /** + * Adds the given policy to this entity. Also calls policy.setEntity if available. + * + * @deprecated since 0.9.0; see {@link PolicySupport#add(PolicySpec)} + */ + @Deprecated + <T extends Policy> T addPolicy(PolicySpec<T> policy); + + /** + * Removes the given policy from this entity. + * @return True if the policy existed at this entity; false otherwise + * + * @deprecated since 0.9.0; see {@link PolicySupport#remove(Policy)} + */ + @Deprecated + boolean removePolicy(Policy policy); + + /** + * Adds the given enricher to this entity. Also calls enricher.setEntity if available. + * + * @deprecated since 0.9.0; see {@link EnricherSupport#add(Enricher)} + */ + @Deprecated + void addEnricher(Enricher enricher); + + /** + * Adds the given enricher to this entity. Also calls enricher.setEntity if available. + * + * @deprecated since 0.9.0; see {@link EnricherSupport#add(EnricherSpec)} + */ + @Deprecated + <T extends Enricher> T addEnricher(EnricherSpec<T> enricher); + + /** + * Removes the given enricher from this entity. + * @return True if the policy enricher at this entity; false otherwise + * + * @deprecated since 0.9.0; see {@link EnricherSupport#remove(Enricher)} + */ + @Deprecated + boolean removeEnricher(Enricher enricher); + + /** + * Adds the given feed to this entity. Also calls feed.setEntity if available. + */ + <T extends Feed> T addFeed(T feed); + + SensorSupport sensors(); + + PolicySupport policies(); + + EnricherSupport enrichers(); + + GroupSupport groups(); + + @Override + RelationSupport<Entity> relations(); + + @Beta + public interface SensorSupport { + + /** + * Gets the value of the given attribute on this entity, or null if has not been set. + * + * Attributes can be things like workrate and status information, as well as + * configuration (e.g. url/jmxHost/jmxPort), etc. + */ + <T> T get(AttributeSensor<T> key); + + /** + * Sets the {@link AttributeSensor} data for the given attribute to the specified value. + * + * This can be used to "enrich" the entity, such as adding aggregated information, + * rolling averages, etc. + * + * @return the old value for the attribute (possibly {@code null}) + */ + <T> T set(AttributeSensor<T> attribute, T val); + + /** + * Atomically modifies the {@link AttributeSensor}, ensuring that only one modification is done + * at a time. + * + * If the modifier returns {@link Maybe#absent()} then the attribute will be + * left unmodified, and the existing value will be returned. + * + * For details of the synchronization model used to achieve this, refer to the underlying + * attribute store (e.g. AttributeMap). + * + * @return the old value for the attribute (possibly {@code null}) + * @since 0.7.0-M2 + */ + @Beta + <T> T modify(AttributeSensor<T> attribute, Function<? super T, Maybe<T>> modifier); + + /** + * Emits a {@link SensorEvent} event on behalf of this entity (as though produced by this entity). + * <p> + * Note that for attribute sensors it is nearly always recommended to use setAttribute, + * as this method will not update local values. + */ + <T> void emit(Sensor<T> sensor, T value); + } + + public interface AdjunctSupport<T extends EntityAdjunct> extends Iterable<T> { + /** + * @return A read-only thread-safe iterator over all the instances. + */ + Iterator<T> iterator(); + + int size(); + boolean isEmpty(); + + /** + * Adds an instance. + */ + void add(T val); + + /** + * Removes an instance. + */ + boolean remove(T val); + } + + @Beta + public interface PolicySupport extends AdjunctSupport<Policy> { + /** + * Adds the given policy to this entity. Also calls policy.setEntity if available. + */ + @Override + void add(Policy policy); + + /** + * Removes the given policy from this entity. + * @return True if the policy existed at this entity; false otherwise + */ + @Override + boolean remove(Policy policy); + + /** + * Adds the given policy to this entity. Also calls policy.setEntity if available. + */ + <T extends Policy> T add(PolicySpec<T> enricher); + } + + @Beta + public interface EnricherSupport extends AdjunctSupport<Enricher> { + /** + * Adds the given enricher to this entity. Also calls enricher.setEntity if available. + */ + @Override + void add(Enricher enricher); + + /** + * Removes the given enricher from this entity. + * @return True if the policy enricher at this entity; false otherwise + */ + @Override + boolean remove(Enricher enricher); + + /** + * Adds the given enricher to this entity. Also calls enricher.setEntity if available. + */ + <T extends Enricher> T add(EnricherSpec<T> enricher); + } + + /** + * For managing/querying the group membership of this entity. + * + * Groupings can be used to allow easy management/monitoring of a group of entities. + * + * To add/remove this entity from a group, users should call {@link Group#addMember(Entity)} + * and {@link Group#removeMember(Entity)}. In a future release, add/remove methods may be + * added here. + */ + @Beta + public interface GroupSupport extends Iterable<Group> { + /** + * A read-only thread-safe iterator over all the {@link Group}s that this entity is a member of. + */ + @Override + Iterator<Group> iterator(); + + int size(); + boolean isEmpty(); + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/entity/EntityInitializer.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/EntityInitializer.java b/api/src/main/java/org/apache/brooklyn/api/entity/EntityInitializer.java new file mode 100644 index 0000000..a9f407a --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/entity/EntityInitializer.java @@ -0,0 +1,50 @@ +/* + * 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.api.entity; + +import java.util.Map; + +import org.apache.brooklyn.api.objs.EntityAdjunct; +import org.apache.brooklyn.api.policy.Policy; +import org.apache.brooklyn.api.sensor.Feed; + +/** + * Instances of this class supply logic which can be used to initialize entities. + * These can be added to an {@link EntitySpec} programmatically, or declared as part + * of YAML recipes in a <code>brooklyn.initializers</code> section. + * In the case of the latter, implementing classes should define a no-arg constructor + * or a {@link Map} constructor so that YAML parameters can be supplied. + * <p> + * Note that initializers are only invoked on first creation; they are not called + * during a rebind. Instead, the typical pattern is that initializers will create + * {@link EntityAdjunct} instances such as {@link Policy} and {@link Feed} + * which will be attached during rebind. + **/ +public interface EntityInitializer { + + /** Applies initialization logic to a just-built entity. + * Invoked immediately after the "init" call on the AbstractEntity constructed. + * + * @param entity guaranteed to be the actual implementation instance, + * thus guaranteed to be castable to EntityInternal which is often desired, + * or to the type at hand (it is not even a proxy) + */ + public void apply(EntityLocal entity); + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/entity/EntityLocal.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/EntityLocal.java b/api/src/main/java/org/apache/brooklyn/api/entity/EntityLocal.java new file mode 100644 index 0000000..aeb7249 --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/entity/EntityLocal.java @@ -0,0 +1,175 @@ +/* + * 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.api.entity; + +import java.util.Map; + +import org.apache.brooklyn.api.mgmt.SubscriptionContext; +import org.apache.brooklyn.api.mgmt.SubscriptionHandle; +import org.apache.brooklyn.api.mgmt.SubscriptionManager; +import org.apache.brooklyn.api.mgmt.Task; +import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.api.sensor.Sensor; +import org.apache.brooklyn.api.sensor.SensorEventListener; +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.config.ConfigKey.HasConfigKey; +import org.apache.brooklyn.util.guava.Maybe; + +import com.google.common.annotations.Beta; +import com.google.common.base.Function; + +/** + * Extended Entity interface for use in places where the caller should have certain privileges, + * such as setting attribute values, adding policies, etc. + * + * FIXME Moved from core project to api project because of bug in groovy's covariant return types. + * EntityDriver needs to return EntityLocal rather than Entity, to avoid changing a whole load + * of sub-types. + * FIXME Add {@link setAttribute(AttributeSensorAndConfigKey<?,T>)} back in if/when move it back, + * or if we extract an interface for AttributeSensorAndConfigKey. + * + * @deprecated since 0.9.0; use {@link Entity} or {@link org.apache.brooklyn.core.entity.EntityInternal} + */ +public interface EntityLocal extends Entity { + + // FIXME Rename to something other than EntityLocal. + // Separate out what is specific to "local jvm", and what is here for an SPI rather than API. + + /** + * @deprecated since 0.7.0; use {@link #config()}, such as {@code entity.config().set(key, val)} + */ + @Deprecated + <T> T setConfig(ConfigKey<T> key, T val); + + /** + * @deprecated since 0.7.0; use {@link #config()}, such as {@code entity.config().set(key, val)} + */ + @Deprecated + <T> T setConfig(ConfigKey<T> key, Task<T> val); + + /** + * @deprecated since 0.7.0; use {@link #config()}, such as {@code entity.config().set(key, val)} + */ + @Deprecated + <T> T setConfig(HasConfigKey<T> key, T val); + + /** + * @deprecated since 0.7.0; use {@link #config()}, such as {@code entity.config().set(key, val)} + */ + @Deprecated + <T> T setConfig(HasConfigKey<T> key, Task<T> val); + + /** + * @deprecated since 0.8.0; use {@link SensorSupport#set(AttributeSensor, Object)} via code like {@code sensors().set(attribute, val)}. + */ + <T> T setAttribute(AttributeSensor<T> attribute, T val); + + /** + * @deprecated since 0.8.0; use {@link SensorSupport#modify(AttributeSensor, Function)} via code like {@code sensors().modify(attribute, modifier)}. + */ + @Beta + <T> T modifyAttribute(AttributeSensor<T> attribute, Function<? super T, Maybe<T>> modifier); + + /** + * @deprecated since 0.8.0; use {@link SensorSupport#emit(Sensor, Object)} via code like {@code sensors().emit(sensor, val)}. + */ + <T> void emit(Sensor<T> sensor, T value); + + /** + * @deprecated in 0.5; use {@link #getConfig(ConfigKey)} + */ + <T> T getConfig(ConfigKey<T> key, T defaultValue); + + /** + * @deprecated in 0.5; use {@link #getConfig(HasConfigKey)} + */ + <T> T getConfig(HasConfigKey<T> key, T defaultValue); + + /** + * Allow us to subscribe to data from a {@link Sensor} on another entity. + * + * @return a subscription id which can be used to unsubscribe + * + * @see SubscriptionManager#subscribe(Map, Entity, Sensor, SensorEventListener) + * + * @deprecated since 0.9.0; see {@link SubscriptionSupportInternal#getSubscriptionContext()}, e.g. with {@code subscriptions().getSubscriptionContext()} + */ + @Deprecated + @Beta + <T> SubscriptionHandle subscribe(Entity producer, Sensor<T> sensor, SensorEventListener<? super T> listener); + + /** + * @see SubscriptionManager#subscribeToChildren(Map, Entity, Sensor, SensorEventListener) + * + * @deprecated since 0.9.0; see {@link SubscriptionSupport#subscribeToChildren(Entity, Sensor, SensorEventListener)}, e.g. with {@code subscriptions().subscribeToChildren(...)} + */ + @Deprecated + @Beta + <T> SubscriptionHandle subscribeToChildren(Entity parent, Sensor<T> sensor, SensorEventListener<? super T> listener); + + /** + * @see SubscriptionManager#subscribeToMembers(Group, Sensor, SensorEventListener) + * + * @deprecated since 0.9.0; see {@link SubscriptionSupport#subscribeToMembers(Entity, Sensor, SensorEventListener)}, e.g. with {@code subscriptions().subscribeToMembers(...)} + */ + @Deprecated + @Beta + <T> SubscriptionHandle subscribeToMembers(Group group, Sensor<T> sensor, SensorEventListener<? super T> listener); + + /** + * Unsubscribes from the given producer. + * + * @see SubscriptionContext#unsubscribe(SubscriptionHandle) + * + * @deprecated since 0.9.0; see {@link SubscriptionSupport#unsubscribe(Entity)}, e.g. with {@code subscriptions().unsubscribe(...)} + */ + @Deprecated + @Beta + boolean unsubscribe(Entity producer); + + /** + * Unsubscribes the given handle. + * + * @see SubscriptionContext#unsubscribe(SubscriptionHandle) + * + * @deprecated since 0.9.0; see {@link SubscriptionSupport#unsubscribe(Entity, SubscriptionHandle)}, e.g. with {@code subscriptions().unsubscribe(...)} + */ + @Deprecated + @Beta + boolean unsubscribe(Entity producer, SubscriptionHandle handle); + + /** + * Removes all policy from this entity. + * @return True if any policies existed at this entity; false otherwise + * + * @deprecated since 0.9.0; see {@link PolicySupportInternal#removeAllPolicies()}, e.g. {@code ((EntityInternal)entity).policies().removeAllPolicies()} + */ + @Deprecated + boolean removeAllPolicies(); + + /** + * Removes all enricher from this entity. + * Use with caution as some entities automatically register enrichers; this will remove those enrichers as well. + * @return True if any enrichers existed at this entity; false otherwise + * + * @deprecated since 0.9.0; see {@link EnricherSupportInternal#removeAllEnrichers()}, e.g. {@code ((EntityInternal)entity).enrichers().removeAllEnrichers()} + */ + @Deprecated + boolean removeAllEnrichers(); +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/entity/EntitySpec.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/EntitySpec.java b/api/src/main/java/org/apache/brooklyn/api/entity/EntitySpec.java new file mode 100644 index 0000000..58cf946 --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/entity/EntitySpec.java @@ -0,0 +1,401 @@ +/* + * 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.api.entity; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.annotation.Nullable; + +import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; +import org.apache.brooklyn.api.location.Location; +import org.apache.brooklyn.api.policy.Policy; +import org.apache.brooklyn.api.policy.PolicySpec; +import org.apache.brooklyn.api.sensor.Enricher; +import org.apache.brooklyn.api.sensor.EnricherSpec; +import org.apache.brooklyn.util.collections.MutableList; + +import com.google.common.base.Function; +import com.google.common.base.Throwables; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +/** + * Gives details of an entity to be created. It describes the entity's configuration, and is + * reusable to create multiple entities with the same configuration. + * + * To create an EntitySpec, it is strongly encouraged to use {@link #create(Class)} etc. + * Users who need to implement this are strongly encouraged to extend + * {@link org.apache.brooklyn.api.entity.EntitySpec}. + * + * @param <T> The type of entity to be created + * + * @author aled + */ +public class EntitySpec<T extends Entity> extends AbstractBrooklynObjectSpec<T,EntitySpec<T>> { + + private static final long serialVersionUID = -2247153452919128990L; + + /** + * Creates a new {@link EntitySpec} instance for an entity of the given type. The returned + * {@link EntitySpec} can then be customized. + * + * @param type An {@link Entity} interface + */ + public static <T extends Entity> EntitySpec<T> create(Class<T> type) { + return new EntitySpec<T>(type); + } + + /** + * Creates a new {@link EntitySpec} instance for an entity of the given type. The returned + * {@link EntitySpec} can then be customized. + * + * @param type An {@link Entity} interface + * @param implType An {@link Entity} implementation, which implements the {@code type} interface + */ + public static <T extends Entity, U extends T> EntitySpec<T> create(Class<T> type, Class<U> implType) { + return new EntitySpec<T>(type).impl(implType); + } + + /** + * Creates a new {@link EntitySpec} instance with the given config, for an entity of the given type. + * + * This is primarily for groovy code; equivalent to {@code EntitySpec.create(type).configure(config)}. + * + * @param config The spec's configuration (see {@link EntitySpec#configure(Map)}). + * @param type An {@link Entity} interface + */ + public static <T extends Entity> EntitySpec<T> create(Map<?,?> config, Class<T> type) { + return EntitySpec.create(type).configure(config); + } + + /** + * Copies entity spec so its configuration can be overridden without modifying the + * original entity spec. + */ + public static <T extends Entity> EntitySpec<T> create(EntitySpec<T> spec) { + return create(spec.getType()).copyFrom(spec); + } + + public static <T extends Entity> EntitySpec<T> newInstance(Class<T> type) { + return new EntitySpec<T>(type); + } + + private Class<? extends T> impl; + private Entity parent; + private final List<Policy> policies = Lists.newArrayList(); + private final List<PolicySpec<?>> policySpecs = Lists.newArrayList(); + private final List<Enricher> enrichers = Lists.newArrayList(); + private final List<EnricherSpec<?>> enricherSpecs = Lists.newArrayList(); + private final List<Location> locations = Lists.newArrayList(); + private final Set<Class<?>> additionalInterfaces = Sets.newLinkedHashSet(); + private final List<EntityInitializer> entityInitializers = Lists.newArrayList(); + private final List<EntitySpec<?>> children = Lists.newArrayList(); + private final List<Entity> members = Lists.newArrayList(); + private final List<Group> groups = Lists.newArrayList(); + private volatile boolean immutable; + + public EntitySpec(Class<T> type) { + super(type); + } + + @Override + protected EntitySpec<T> copyFrom(EntitySpec<T> otherSpec) { + super.copyFrom(otherSpec) + .additionalInterfaces(otherSpec.getAdditionalInterfaces()) + .policySpecs(otherSpec.getPolicySpecs()) + .policies(otherSpec.getPolicies()) + .enricherSpecs(otherSpec.getEnricherSpecs()) + .enrichers(otherSpec.getEnrichers()) + .addInitializers(otherSpec.getInitializers()) + .children(copyFromSpecs(otherSpec.getChildren())) + .members(otherSpec.getMembers()) + .groups(otherSpec.getGroups()) + .locations(otherSpec.getLocations()); + + if (otherSpec.getParent() != null) parent(otherSpec.getParent()); + if (otherSpec.getImplementation() != null) impl(otherSpec.getImplementation()); + + return this; + } + + private List<EntitySpec<?>> copyFromSpecs(List<EntitySpec<?>> children) { + return Lists.<EntitySpec<?>,EntitySpec<?>>transform(children, new Function<EntitySpec<?>, EntitySpec<?>>() { + @Nullable + @Override + public EntitySpec<?> apply(@Nullable EntitySpec<?> entitySpec) { + return create(entitySpec); + } + }); + } + + @Override + @SuppressWarnings("unchecked") + public Class<T> getType() { + return (Class<T>)super.getType(); + } + + @Override + protected void checkValidType(Class<? extends T> type) { + // EntitySpec does nothing. Other specs do check it's an implementation etc. + } + + /** + * @return The implementation of the entity; if not null. this overrides any defaults or other configuration + * + * @see ImplementedBy on the entity interface classes for how defaults are defined. + * @see EntityTypeRegistry for how implementations can be defined globally + */ + @Nullable + public Class<? extends T> getImplementation() { + return impl; + } + + /** + * @return Additional interfaces (other than just {@link #getType()}) that this entity implements; + * important for when accessing entity through a proxy to determine which interfaces the proxy exposes. + */ + public Set<Class<?>> getAdditionalInterfaces() { + return additionalInterfaces; + } + + /** @return {@link EntityInitializer} objects which customize the entity to be created */ + public List<EntityInitializer> getInitializers() { + return entityInitializers; + } + + public List<EntitySpec<?>> getChildren() { + return children; + } + + public List<Entity> getMembers() { + return members; + } + + public List<Group> getGroups() { + return groups; + } + + /** + * @return The entity's parent + */ + public Entity getParent() { + return parent; + } + + public List<PolicySpec<?>> getPolicySpecs() { + return policySpecs; + } + + public List<Policy> getPolicies() { + return policies; + } + + public List<EnricherSpec<?>> getEnricherSpecs() { + return enricherSpecs; + } + + public List<Enricher> getEnrichers() { + return enrichers; + } + + public List<Location> getLocations() { + return locations; + } + + public EntitySpec<T> impl(Class<? extends T> val) { + checkMutable(); + checkIsImplementation(checkNotNull(val, "impl"), getType()); + checkIsNewStyleImplementation(val); + impl = val; + return this; + } + + public EntitySpec<T> additionalInterfaces(Class<?>... vals) { + checkMutable(); + for (Class<?> val : vals) { + additionalInterfaces.add(val); + } + return this; + } + + public EntitySpec<T> additionalInterfaces(Iterable<Class<?>> val) { + checkMutable(); + additionalInterfaces.addAll(Sets.newLinkedHashSet(val)); + return this; + } + + public EntitySpec<T> addInitializer(EntityInitializer initializer) { + checkMutable(); + entityInitializers.add(initializer); + return this; + } + + public EntitySpec<T> addInitializers(Iterable<? extends EntityInitializer> initializers) { + checkMutable(); + Iterables.addAll(entityInitializers, initializers); + return this; + } + + /** The supplied class must have a public no-arg constructor. */ + public EntitySpec<T> addInitializer(Class<? extends EntityInitializer> initializerType) { + checkMutable(); + try { + entityInitializers.add(initializerType.newInstance()); + } catch (Exception e) { + throw Throwables.propagate(e); + } + return this; + } + + public EntitySpec<T> children(Iterable<? extends EntitySpec<?>> children) { + checkMutable(); + Iterables.addAll(this.children, children); + return this; + } + + /** The supplied class must have a public no-arg constructor. */ + public EntitySpec<T> child(EntitySpec<?> child) { + checkMutable(); + children.add(child); + return this; + } + + public EntitySpec<T> members(Iterable<? extends Entity> members) { + checkMutable(); + Iterables.addAll(this.members, members); + return this; + } + + public EntitySpec<T> member(Entity member) { + checkMutable(); + members.add(member); + return this; + } + + public EntitySpec<T> groups(Iterable<? extends Group> groups) { + checkMutable(); + Iterables.addAll(this.groups, groups); + return this; + } + + public EntitySpec<T> group(Group group) { + checkMutable(); + groups.add(group); + return this; + } + + public EntitySpec<T> parent(Entity val) { + checkMutable(); + parent = checkNotNull(val, "parent"); + return this; + } + + /** adds a policy to the spec */ + public <V> EntitySpec<T> policy(Policy val) { + checkMutable(); + policies.add(checkNotNull(val, "policy")); + return this; + } + + /** adds a policy to the spec */ + public <V> EntitySpec<T> policy(PolicySpec<?> val) { + checkMutable(); + policySpecs.add(checkNotNull(val, "policySpec")); + return this; + } + + /** adds the supplied policies to the spec */ + public <V> EntitySpec<T> policySpecs(Iterable<? extends PolicySpec<?>> val) { + checkMutable(); + policySpecs.addAll(MutableList.copyOf(checkNotNull(val, "policySpecs"))); + return this; + } + + /** adds the supplied policies to the spec */ + public <V> EntitySpec<T> policies(Iterable<? extends Policy> val) { + checkMutable(); + policies.addAll(MutableList.copyOf(checkNotNull(val, "policies"))); + return this; + } + + /** adds a policy to the spec */ + public <V> EntitySpec<T> enricher(Enricher val) { + checkMutable(); + enrichers.add(checkNotNull(val, "enricher")); + return this; + } + + /** adds a policy to the spec */ + public <V> EntitySpec<T> enricher(EnricherSpec<?> val) { + checkMutable(); + enricherSpecs.add(checkNotNull(val, "enricherSpec")); + return this; + } + + /** adds the supplied policies to the spec */ + public <V> EntitySpec<T> enricherSpecs(Iterable<? extends EnricherSpec<?>> val) { + checkMutable(); + enricherSpecs.addAll(MutableList.copyOf(checkNotNull(val, "enricherSpecs"))); + return this; + } + + /** adds the supplied policies to the spec */ + public <V> EntitySpec<T> enrichers(Iterable<? extends Enricher> val) { + checkMutable(); + enrichers.addAll(MutableList.copyOf(checkNotNull(val, "enrichers"))); + return this; + } + + /** adds a location to the spec */ + public <V> EntitySpec<T> location(Location val) { + checkMutable(); + locations.add(checkNotNull(val, "location")); + return this; + } + + /** clears locations defined in the spec */ + public <V> EntitySpec<T> clearLocations() { + checkMutable(); + locations.clear(); + return this; + } + + /** adds the supplied locations to the spec */ + public <V> EntitySpec<T> locations(Iterable<? extends Location> val) { + checkMutable(); + locations.addAll(MutableList.copyOf(checkNotNull(val, "locations"))); + return this; + } + + /** "seals" this spec, preventing any future changes */ + public EntitySpec<T> immutable() { + immutable = true; + return this; + } + + private void checkMutable() { + if (immutable) throw new IllegalStateException("Cannot modify immutable entity spec "+this); + } + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/entity/EntityType.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/EntityType.java b/api/src/main/java/org/apache/brooklyn/api/entity/EntityType.java new file mode 100644 index 0000000..1c3f7b5 --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/entity/EntityType.java @@ -0,0 +1,73 @@ +/* + * 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.api.entity; + +import java.util.NoSuchElementException; +import java.util.Set; + +import org.apache.brooklyn.api.effector.Effector; +import org.apache.brooklyn.api.objs.BrooklynType; +import org.apache.brooklyn.api.sensor.Sensor; +import org.apache.brooklyn.util.guava.Maybe; + +/** + * Gives type information for an {@link Entity}. It is an immutable snapshot. + * + * It reflects a given entity at the time the snapshot was created: if sensors + * were added or removed on-the-fly then those changes will be included in subsequent + * snapshots. Therefore instances of a given class of entity could have different + * EntityTypes. + */ +public interface EntityType extends BrooklynType { + + /** + * Sensors available on this entity. + */ + Set<Sensor<?>> getSensors(); + + /** + * Effectors available on this entity. + */ + Set<Effector<?>> getEffectors(); + + /** @return an effector with the given name, if it exists. + */ + public Maybe<Effector<?>> getEffectorByName(String name); + + /** + * @return the matching effector on this entity + * @throws NoSuchElementException If there is no exact match for this signature + * <p> + * @deprecated since 0.7.0 use {@link #getEffectorByName(String)}; + * use of multiple effectors with the same name is not supported by the EntityDynamicType implementation, + * so should be discouraged. overloading can be achieved by inspecting the parameters map. + */ + @Deprecated + Effector<?> getEffector(String name, Class<?>... parameterTypes); + + /** + * The Sensor with the given name, or null if not found. + */ + Sensor<?> getSensor(String name); + + /** + * @return True if has the sensor with the given name; false otherwise. + */ + boolean hasSensor(String name); +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/entity/EntityTypeRegistry.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/EntityTypeRegistry.java b/api/src/main/java/org/apache/brooklyn/api/entity/EntityTypeRegistry.java new file mode 100644 index 0000000..4747e5b --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/entity/EntityTypeRegistry.java @@ -0,0 +1,63 @@ +/* + * 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.api.entity; + +import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity; +import org.apache.brooklyn.api.entity.drivers.EntityDriver; +import org.apache.brooklyn.api.location.Location; + +/** + * A registry of the entity implementations to be used when creating an entity of a given type. + * + * A given implementation can only be associated with one entity type interface. + */ +public interface EntityTypeRegistry { + + /** + * Returns the implementation to be used for the given entity type. + * + * @param entity the {@link DriverDependentEntity} to create the {@link EntityDriver} for. + * @param location the {@link Location} where the {@link DriverDependentEntity} is running. + * @param <D> + * @return the creates EntityDriver. + * @throws IllegalArgumentException If no implementation registered, and the given interface is not annotated with {@link ImplementedBy} + * @throws IllegalStateException If the given type is not an interface, or if the implementation class is not a concrete class implementing it + */ + <T extends Entity> Class<? extends T> getImplementedBy(Class<T> type); + + /** + * Returns the interface of this entity implementation. + * E.g. for use as the fully qualified name in {@code entity.getEntityType().getName()}. + * + * @throws IllegalArgumentException If no interface is registered against this implementation, + * and no super-type of the class is annotated with {@link ImplementedBy} to point at the given class + */ + <T extends Entity> Class<? super T> getEntityTypeOf(Class<T> type); + + /** + * Registers the implementation to use for a given entity type. + * + * The implementation must be a non-abstract class implementing the given type, and must + * have a no-argument constructor. + * + * @throws IllegalArgumentException If this implementation has already been registered for a different type + * @throws IllegalStateException If the implClazz is not a concrete class, or does not implement type + */ + <T extends Entity> EntityTypeRegistry registerImplementation(Class<T> type, Class<? extends T> implClazz); +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/entity/Group.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/Group.java b/api/src/main/java/org/apache/brooklyn/api/entity/Group.java new file mode 100644 index 0000000..05f80e1 --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/entity/Group.java @@ -0,0 +1,71 @@ +/* + * 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.api.entity; + +import java.util.Collection; + +/** + * An {@link Entity} that groups together other entities. + * + * The grouping can be for any purpose, such as allowing easy management/monitoring of + * a group of entities. The grouping could be static (i.e. a fixed set of entities) + * or dynamic (i.e. contains all entities that match some filter). + */ +public interface Group extends Entity { + + /** + * Return the entities that are members of this group. + */ + Collection<Entity> getMembers(); + + /** + * @return True if it is a member of this group. + */ + boolean hasMember(Entity member); + + /** + * Adds the given member, returning true if this modifies the set of members (i.e. it was not already a member). + */ + boolean addMember(Entity member); + + /** + * Removes the given member, returning true if this modifies the set of members (i.e. it was a member). + */ + boolean removeMember(Entity member); + + /** + * @return The number of members in this group. + */ + Integer getCurrentSize(); + + /** As {@link #addChild(EntitySpec)} followed by {@link #addMember(Entity)} */ + <T extends Entity> T addMemberChild(EntitySpec<T> spec); + + /** As {@link #addChild(Entity)} followed by {@link #addMember(Entity)} */ + <T extends Entity> T addMemberChild(T child); + + /** As in super, but note this does NOT by default add it as a member; see {@link #addMemberChild(EntitySpec)} */ + @Override + <T extends Entity> T addChild(EntitySpec<T> spec); + + /** As in super, but note this does NOT by default add it as a member; see {@link #addMemberChild(Entity)} */ + @Override + <T extends Entity> T addChild(T child); + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/entity/ImplementedBy.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/ImplementedBy.java b/api/src/main/java/org/apache/brooklyn/api/entity/ImplementedBy.java new file mode 100644 index 0000000..f0ee6a1 --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/entity/ImplementedBy.java @@ -0,0 +1,46 @@ +/* + * 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.api.entity; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * A pointer to the default implementation of an entity. + * + * A common naming convention is for the implementation class to have the suffix "Impl", + * but this is not required. + * + * See {@link EntityTypeRegistry} for how to override the implementation to be used, if + * the class referenced by this annotation is not desired. + * + * @author aled + */ +@Retention(RUNTIME) +@Target(TYPE) +public @interface ImplementedBy { + + /** + * The implementation type. + */ + Class<? extends Entity> value(); +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/DriverDependentEntity.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/drivers/DriverDependentEntity.java b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/DriverDependentEntity.java new file mode 100644 index 0000000..b59e9cc --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/DriverDependentEntity.java @@ -0,0 +1,36 @@ +/* + * 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.api.entity.drivers; + +import javax.annotation.Nullable; + +import org.apache.brooklyn.api.entity.Entity; + +/** + * An Entity that needs to have a driver. + * + * @param <D> + */ +public interface DriverDependentEntity<D extends EntityDriver> extends Entity { + + Class<D> getDriverInterface(); + + @Nullable D getDriver(); + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java new file mode 100644 index 0000000..e2bb0bd --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java @@ -0,0 +1,54 @@ +/* + * 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.api.entity.drivers; + +import org.apache.brooklyn.api.entity.EntityLocal; +import org.apache.brooklyn.api.location.Location; + +import com.google.common.annotations.Beta; + +/** + * The EntityDriver provides an abstraction between the Entity and the environment (the {@link Location} it is running + * in, so that an entity is not tightly coupled to a specific Location. E.g. you could have a TomcatEntity that uses + * a TomcatDriver (an interface) and you could have different driver implementations like the + * TomcatSshDriver/TomcatWindowsDriver and if in the future support for Puppet needs to be added, a TomcatPuppetDriver + * could be added. + * + * @author Peter Veentjer. + * @see DriverDependentEntity + * @see EntityDriverManager + */ +public interface EntityDriver { + + /** + * The entity instance that this is a driver for. + * + * FIXME The signature of this will change to return Entity instead of EntityLocal. + * This is a temporary workaround for groovy not supporting covariant return types, + * see http://jira.codehaus.org/browse/GROOVY-5418. It is fixed in groovy 2.0.4 so + * we will need to upgrade from 1.8.6 first. + */ + @Beta + EntityLocal getEntity(); + + /** + * The location the entity is running in. + */ + Location getLocation(); +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java new file mode 100644 index 0000000..b2ad37e --- /dev/null +++ b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java @@ -0,0 +1,49 @@ +/* + * 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.api.entity.drivers; + +import org.apache.brooklyn.api.location.Location; + +/** + * Responsible for creating a driver for a given entity/location. Also used for customizing which + * type of driver should be used by entities in given locations. + * + * The idea is that an entity should not be tightly coupled to a specific driver implementation, + * so that there is flexibility for driver changes, without changing the entity itself. The + * advantage is that drivers can easily be reconfigured, replaced or new drivers for different + * environments can be added, without needing to modify Brooklyn. + * + * To obtain an instance of a driver, use {@link #build(DriverDependentEntity, Location)}. + * This will use the registered driver types, or if one is not registered will fallback to the + * default strategy. + */ +public interface EntityDriverManager { + + /** + * Builds a new {@link EntityDriver} for the given entity/location. + * + * @param entity the {@link DriverDependentEntity} to create the {@link EntityDriver} for. + * @param location the {@link Location} where the {@link DriverDependentEntity} is running. + * @param <D> + * @return the creates EntityDriver. + */ + <D extends EntityDriver> D build(DriverDependentEntity<D> entity, Location location); + + <D extends EntityDriver> void registerDriver(Class<D> driverInterface, Class<? extends Location> locationClazz, Class<? extends D> driverClazz); +}
