http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/538324e1/core/src/main/java/org/apache/brooklyn/location/cloud/names/AbstractCloudMachineNamer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/names/AbstractCloudMachineNamer.java b/core/src/main/java/org/apache/brooklyn/location/cloud/names/AbstractCloudMachineNamer.java deleted file mode 100644 index 8230d59..0000000 --- a/core/src/main/java/org/apache/brooklyn/location/cloud/names/AbstractCloudMachineNamer.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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.location.cloud.names; - -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.api.objs.HasShortName; -import org.apache.brooklyn.location.cloud.CloudLocationConfig; -import org.apache.brooklyn.util.core.config.ConfigBag; -import org.apache.brooklyn.util.text.Identifiers; -import org.apache.brooklyn.util.text.Strings; - -import com.google.common.annotations.Beta; -import com.google.common.base.CharMatcher; - -/** - * Implements <b>most</b> of {@link CloudMachineNamer}, - * leaving just one method -- {@link #generateNewIdOfLength(int)} -- - * for subclasses to provide. - * <p> - * {@link CloudLocationConfig#VM_NAME_MAX_LENGTH} is used to find the VM length, - * unless {@link #getCustomMaxNameLength(ConfigBag)} is overridden or - * {@link #setDefaultMachineNameMaxLength(int)} invoked on the instance supplied. - */ -public abstract class AbstractCloudMachineNamer implements CloudMachineNamer { - - int defaultMachineNameMaxLength = CloudLocationConfig.VM_NAME_MAX_LENGTH.getDefaultValue(); - int defaultMachineNameSaltLength = CloudLocationConfig.VM_NAME_SALT_LENGTH.getDefaultValue(); - protected String separator = "-"; - - public String generateNewMachineUniqueName(ConfigBag setup) { - return generateNewIdReservingLength(setup, 0); - } - - public String generateNewMachineUniqueNameFromGroupId(ConfigBag setup, String groupId) { - int availSaltLength = getMaxNameLength(setup) - (groupId.length() + separator.length()); - int requestedSaltLength = getLengthForMachineUniqueNameSalt(setup, false); - if (availSaltLength <= 0 || requestedSaltLength <= 0) { - return groupId; - } - - return sanitize(groupId + separator + Identifiers.makeRandomId(Math.min(requestedSaltLength, availSaltLength))).toLowerCase(); - } - - public String generateNewGroupId(ConfigBag setup) { - return sanitize(generateNewIdReservingLength(setup, getLengthForMachineUniqueNameSalt(setup, true))).toLowerCase(); - } - - protected String generateNewIdReservingLength(ConfigBag setup, int lengthToReserve) { - int len = getMaxNameLength(setup); - // decrement by e.g. 9 chars because jclouds adds that (dash plus 8 for hex id) - len -= lengthToReserve; - if (len<=0) return ""; - return Strings.maxlen(generateNewIdOfLength(setup, len), len); - } - - /** Method for subclasses to provide to construct the context-specific part of an identifier, - * for use in {@link #generateNewGroupId()} and {@link #generateNewMachineUniqueName()}. - * - * @param maxLengthHint an indication of the maximum length permitted for the ID generated, - * supplied for implementations which wish to use this information to decide what to truncate. - * (This class will truncate any return values longer than this.) - */ - protected abstract String generateNewIdOfLength(ConfigBag setup, int maxLengthHint); - - /** Returns the max length of a VM name for the cloud specified in setup; - * this value is typically decremented by 9 to make room for jclouds labels; - * delegates to {@link #getCustomMaxNameLength()} when - * {@link CloudLocationConfig#VM_NAME_MAX_LENGTH} is not set */ - public int getMaxNameLength(ConfigBag setup) { - if (setup.containsKey(CloudLocationConfig.VM_NAME_MAX_LENGTH)) { - // if a length is set explicitly, use that (but intercept default behaviour) - return setup.get(CloudLocationConfig.VM_NAME_MAX_LENGTH); - } - - Integer custom = getCustomMaxNameLength(setup); - if (custom!=null) return custom; - - // return the default - return defaultMachineNameMaxLength; - } - - // sometimes we create salt string, sometimes jclouds does - public int getLengthForMachineUniqueNameSalt(ConfigBag setup, boolean includeSeparator) { - int saltLen; - if (setup.containsKey(CloudLocationConfig.VM_NAME_SALT_LENGTH)) { - saltLen = setup.get(CloudLocationConfig.VM_NAME_SALT_LENGTH); - } else { - // default value comes from key, but custom default can be set - saltLen = defaultMachineNameSaltLength; - } - - if (saltLen>0 && includeSeparator) - saltLen += separator.length(); - - return saltLen; - } - - public AbstractCloudMachineNamer setDefaultMachineNameMaxLength(int defaultMaxLength) { - this.defaultMachineNameMaxLength = defaultMaxLength; - return this; - } - - /** Number of chars to use or reserve for the machine identifier when constructing a group identifier; - * jclouds for instance uses "-" plus 8 */ - public AbstractCloudMachineNamer setDefaultMachineNameSeparatorAndSaltLength(String separator, int defaultMachineUniqueNameSaltLength) { - this.separator = separator; - this.defaultMachineNameSaltLength = defaultMachineUniqueNameSaltLength; - return this; - } - - /** Method for overriding to provide custom logic when an explicit config key is not set for the machine length. */ - public Integer getCustomMaxNameLength(ConfigBag setup) { - return null; - } - - protected static String shortName(Object x) { - if (x instanceof HasShortName) { - return ((HasShortName)x).getShortName(); - } - if (x instanceof Entity) { - return ((Entity)x).getDisplayName(); - } - return x.toString(); - } - - @Beta //probably won't live here long-term - public static String sanitize(String s) { - return CharMatcher.inRange('A', 'Z') - .or(CharMatcher.inRange('a', 'z')) - .or(CharMatcher.inRange('0', '9')) - .negate() - .trimAndCollapseFrom(s, '-'); - } -}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/538324e1/core/src/main/java/org/apache/brooklyn/location/cloud/names/BasicCloudMachineNamer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/names/BasicCloudMachineNamer.java b/core/src/main/java/org/apache/brooklyn/location/cloud/names/BasicCloudMachineNamer.java deleted file mode 100644 index 4caaf12..0000000 --- a/core/src/main/java/org/apache/brooklyn/location/cloud/names/BasicCloudMachineNamer.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.location.cloud.names; - -import org.apache.brooklyn.api.entity.Application; -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.location.cloud.CloudLocationConfig; -import org.apache.brooklyn.util.core.config.ConfigBag; -import org.apache.brooklyn.util.text.Identifiers; -import org.apache.brooklyn.util.text.StringShortener; -import org.apache.brooklyn.util.text.Strings; - -/** - * Standard implementation of {@link CloudMachineNamer}, - * which looks at several of the properties of the context (entity) - * and is clever about abbreviating them. */ -public class BasicCloudMachineNamer extends AbstractCloudMachineNamer { - - @Override - protected String generateNewIdOfLength(ConfigBag setup, int len) { - Object context = setup.peek(CloudLocationConfig.CALLER_CONTEXT); - Entity entity = null; - if (context instanceof Entity) entity = (Entity) context; - - StringShortener shortener = Strings.shortener().separator("-"); - shortener.append("system", "brooklyn"); - - // randId often not necessary, as an 8-char hex identifier is added later (in jclouds? can we override?) - // however it can be useful to have this early in the string, to prevent collisions in places where it is abbreviated - shortener.append("randId", Identifiers.makeRandomId(4)); - - String user = System.getProperty("user.name"); - if (!"brooklyn".equals(user)) - // include user; unless the user is 'brooklyn', as 'brooklyn-brooklyn-' is just silly! - shortener.append("user", user); - - if (entity!=null) { - Application app = entity.getApplication(); - if (app!=null) { - shortener.append("app", shortName(app)) - .append("appId", app.getId()); - } - shortener.append("entity", shortName(entity)) - .append("entityId", entity.getId()); - } else if (context!=null) { - shortener.append("context", context.toString()); - } - - shortener.truncate("user", 12) - .truncate("app", 16) - .truncate("entity", 16) - .truncate("appId", 4) - .truncate("entityId", 4) - .truncate("context", 12); - - shortener.canTruncate("user", 8) - .canTruncate("app", 5) - .canTruncate("entity", 5) - .canTruncate("system", 2) - .canTruncate("app", 3) - .canTruncate("entity", 3) - .canRemove("app") - .canTruncate("user", 4) - .canRemove("entity") - .canTruncate("context", 4) - .canTruncate("randId", 2) - .canRemove("user") - .canTruncate("appId", 2) - .canRemove("appId"); - - String s = shortener.getStringOfMaxLength(len); - return sanitize(s).toLowerCase(); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/538324e1/core/src/main/java/org/apache/brooklyn/location/cloud/names/CloudMachineNamer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/names/CloudMachineNamer.java b/core/src/main/java/org/apache/brooklyn/location/cloud/names/CloudMachineNamer.java deleted file mode 100644 index 9ab52c4..0000000 --- a/core/src/main/java/org/apache/brooklyn/location/cloud/names/CloudMachineNamer.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.location.cloud.names; - -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.api.location.Location; -import org.apache.brooklyn.location.cloud.CloudLocationConfig; -import org.apache.brooklyn.util.core.config.ConfigBag; - -/** - * Interface used to construct names for individual cloud machines and for groups of machines. - * <p> - * Implementations <b>must</b> provide a constructor which takes a single argument, - * being the {@link ConfigBag} for the context where the machine is being created - * (usually a {@link Location}). - * <p> - * With that bag, the config key {@link CloudLocationConfig#CALLER_CONTEXT} - * typically contains the {@link Entity} for which the machine is being created. - */ -public interface CloudMachineNamer { - - /** - * Generate a name for a new machine, based on context. - * <p> - * The name should normally be unique, as a context might produce multiple machines, - * for example basing it partially on information from the context but also including some random salt. - */ - public String generateNewMachineUniqueName(ConfigBag setup); - /** - * Generate a name stem for a group of machines, based on context. - * <p> - * The name does not need to be unique, as uniqueness will be applied by {@link #generateNewMachineUniqueNameFromGroupId(String)}. - */ - public String generateNewGroupId(ConfigBag setup); - - /** - * Generate a unique name from the given name stem. - * <p> - * The name stem is normally based on context information so the usual - * function of this method is to apply a suffix which helps to uniquely distinguish between machines - * in cases where the same name stem ({@link #generateNewGroupId()}) is used for multiple machines. - */ - public String generateNewMachineUniqueNameFromGroupId(ConfigBag setup, String groupId); - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/538324e1/core/src/main/java/org/apache/brooklyn/location/cloud/names/CustomMachineNamer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/names/CustomMachineNamer.java b/core/src/main/java/org/apache/brooklyn/location/cloud/names/CustomMachineNamer.java deleted file mode 100644 index cfb4c24..0000000 --- a/core/src/main/java/org/apache/brooklyn/location/cloud/names/CustomMachineNamer.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.location.cloud.names; - -import java.util.Map; - -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.config.ConfigKey; -import org.apache.brooklyn.core.config.ConfigKeys; -import org.apache.brooklyn.core.entity.EntityInternal; -import org.apache.brooklyn.location.cloud.CloudLocationConfig; -import org.apache.brooklyn.util.core.config.ConfigBag; -import org.apache.brooklyn.util.core.text.TemplateProcessor; -import org.apache.brooklyn.util.text.Strings; - -import com.google.common.collect.ImmutableMap; -import com.google.common.reflect.TypeToken; - -/** Provides a machine namer which looks at a location config key {@link #MACHINE_NAME_TEMPLATE} - * to construct the hostname. - * For instance, setting this to <code>${config.entity_hostname}</code> - * will take the hostname from an <code>entity_hostname</code> key passed as entity <code>brooklyn.config</code>. - * <p> - * Note that this is not jclouds aware, so jclouds-specific cloud max lengths are not observed with this class. - */ -public class CustomMachineNamer extends BasicCloudMachineNamer { - - public static final ConfigKey<String> MACHINE_NAME_TEMPLATE = ConfigKeys.newStringConfigKey("custom.machine.namer.machine", - "Freemarker template format for custom machine name", "${entity.displayName}"); - @SuppressWarnings("serial") - public static final ConfigKey<Map<String, ?>> EXTRA_SUBSTITUTIONS = ConfigKeys.newConfigKey(new TypeToken<Map<String, ?>>() {}, - "custom.machine.namer.substitutions", "Additional substitutions to be used in the template", ImmutableMap.<String, Object>of()); - - @Override - protected String generateNewIdOfLength(ConfigBag setup, int len) { - Object context = setup.peek(CloudLocationConfig.CALLER_CONTEXT); - Entity entity = null; - if (context instanceof Entity) { - entity = (Entity) context; - } - - String template = setup.get(MACHINE_NAME_TEMPLATE); - - String processed; - if (entity == null) { - processed = TemplateProcessor.processTemplateContents(template, setup.get(EXTRA_SUBSTITUTIONS)); - } else { - processed = TemplateProcessor.processTemplateContents(template, (EntityInternal)entity, setup.get(EXTRA_SUBSTITUTIONS)); - } - - processed = Strings.removeFromStart(processed, "#ftl\n"); - - return sanitize(processed); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/538324e1/core/src/main/java/org/apache/brooklyn/location/core/AbstractLocation.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/core/AbstractLocation.java b/core/src/main/java/org/apache/brooklyn/location/core/AbstractLocation.java deleted file mode 100644 index f286b05..0000000 --- a/core/src/main/java/org/apache/brooklyn/location/core/AbstractLocation.java +++ /dev/null @@ -1,709 +0,0 @@ -/* - * 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.location.core; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static org.apache.brooklyn.util.GroovyJavaMethods.elvis; -import static org.apache.brooklyn.util.JavaGroovyEquivalents.groovyTruth; - -import java.io.Closeable; -import java.util.Collection; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.brooklyn.api.location.Location; -import org.apache.brooklyn.api.location.LocationSpec; -import org.apache.brooklyn.api.mgmt.Task; -import org.apache.brooklyn.api.mgmt.rebind.RebindSupport; -import org.apache.brooklyn.api.mgmt.rebind.mementos.LocationMemento; -import org.apache.brooklyn.api.objs.Configurable; -import org.apache.brooklyn.config.ConfigInheritance; -import org.apache.brooklyn.config.ConfigKey; -import org.apache.brooklyn.config.ConfigKey.HasConfigKey; -import org.apache.brooklyn.core.BrooklynFeatureEnablement; -import org.apache.brooklyn.core.config.BasicConfigKey; -import org.apache.brooklyn.core.config.ConfigKeys; -import org.apache.brooklyn.core.internal.storage.BrooklynStorage; -import org.apache.brooklyn.core.internal.storage.Reference; -import org.apache.brooklyn.core.internal.storage.impl.BasicReference; -import org.apache.brooklyn.core.mgmt.internal.LocalLocationManager; -import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; -import org.apache.brooklyn.core.mgmt.rebind.BasicLocationRebindSupport; -import org.apache.brooklyn.core.objs.AbstractBrooklynObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.apache.brooklyn.location.core.internal.LocationDynamicType; -import org.apache.brooklyn.location.core.internal.LocationInternal; -import org.apache.brooklyn.location.geo.HasHostGeoInfo; -import org.apache.brooklyn.location.geo.HostGeoInfo; -import org.apache.brooklyn.util.collections.SetFromLiveMap; -import org.apache.brooklyn.util.core.config.ConfigBag; -import org.apache.brooklyn.util.core.flags.FlagUtils; -import org.apache.brooklyn.util.core.flags.TypeCoercions; -import org.apache.brooklyn.util.guava.Maybe; -import org.apache.brooklyn.util.stream.Streams; - -import com.google.common.base.Objects; -import com.google.common.base.Objects.ToStringHelper; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.common.reflect.TypeToken; - -/** - * A basic implementation of the {@link Location} interface. - * - * This provides an implementation which works according to the requirements of - * the interface documentation, and is ready to be extended to make more specialized locations. - * - * Override {@link #configure(Map)} to add special initialization logic. - */ -public abstract class AbstractLocation extends AbstractBrooklynObject implements LocationInternal, HasHostGeoInfo, Configurable { - - private static final long serialVersionUID = -7495805474138619830L; - - /** @deprecated since 0.7.0 shouldn't be public */ - @Deprecated - public static final Logger LOG = LoggerFactory.getLogger(AbstractLocation.class); - - public static final ConfigKey<Location> PARENT_LOCATION = new BasicConfigKey<Location>(Location.class, "parentLocation"); - - public static final ConfigKey<Boolean> TEMPORARY_LOCATION = ConfigKeys.newBooleanConfigKey("temporaryLocation", - "Indicates that the location is a temporary location that has been created to test connectivity, and that" + - "the location's events should not be recorded by usage listeners", false); - - private final AtomicBoolean configured = new AtomicBoolean(); - - private Reference<Long> creationTimeUtc = new BasicReference<Long>(System.currentTimeMillis()); - - // _not_ set from flag; configured explicitly in configure, because we also need to update the parent's list of children - private Reference<Location> parent = new BasicReference<Location>(); - - // NB: all accesses should be synchronized - private Set<Location> children = Sets.newLinkedHashSet(); - - private Reference<String> name = new BasicReference<String>(); - private boolean displayNameAutoGenerated = true; - - private Reference<HostGeoInfo> hostGeoInfo = new BasicReference<HostGeoInfo>(); - - private BasicConfigurationSupport config = new BasicConfigurationSupport(); - - private ConfigBag configBag = new ConfigBag(); - - private volatile boolean managed; - - private boolean inConstruction; - - private Reference<Map<Class<?>, Object>> extensions = new BasicReference<Map<Class<?>, Object>>(Maps.<Class<?>, Object>newConcurrentMap()); - - private final LocationDynamicType locationType; - - /** - * Construct a new instance of an AbstractLocation. - */ - public AbstractLocation() { - this(Maps.newLinkedHashMap()); - } - - /** - * Construct a new instance of an AbstractLocation. - * - * The properties map recognizes the following keys: - * <ul> - * <li>name - a name for the location - * <li>parentLocation - the parent {@link Location} - * </ul> - * - * Other common properties (retrieved via get/findLocationProperty) include: - * <ul> - * <li>latitude - * <li>longitude - * <li>displayName - * <li>iso3166 - list of iso3166-2 code strings - * <li>timeZone - * <li>abbreviatedName - * </ul> - */ - public AbstractLocation(Map<?,?> properties) { - super(properties); - inConstruction = true; - - // When one calls getConfig(key), we want to use the default value specified on *this* location - // if it overrides the default config, by using the type object - locationType = new LocationDynamicType(this); - - if (isLegacyConstruction()) { - AbstractBrooklynObject checkWeGetThis = configure(properties); - assert this.equals(checkWeGetThis) : this+" configure method does not return itself; returns "+checkWeGetThis+" instead of "+this; - - boolean deferConstructionChecks = (properties.containsKey("deferConstructionChecks") && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class)); - if (!deferConstructionChecks) { - FlagUtils.checkRequiredFields(this); - } - } - - inConstruction = false; - } - - protected void assertNotYetManaged() { - if (!inConstruction && Locations.isManaged(this)) { - LOG.warn("Configuration being made to {} after deployment; may not be supported in future versions", this); - } - //throw new IllegalStateException("Cannot set configuration "+key+" on active location "+this) - } - - public void setManagementContext(ManagementContextInternal managementContext) { - super.setManagementContext(managementContext); - if (displayNameAutoGenerated && getId() != null) name.set(getClass().getSimpleName()+":"+getId().substring(0, Math.min(getId().length(),4))); - - if (BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_USE_BROOKLYN_LIVE_OBJECTS_DATAGRID_STORAGE)) { - Location oldParent = parent.get(); - Set<Location> oldChildren = children; - Map<String, Object> oldConfig = configBag.getAllConfig(); - Long oldCreationTimeUtc = creationTimeUtc.get(); - String oldDisplayName = name.get(); - HostGeoInfo oldHostGeoInfo = hostGeoInfo.get(); - - parent = managementContext.getStorage().getReference(getId()+"-parent"); - children = SetFromLiveMap.create(managementContext.getStorage().<Location,Boolean>getMap(getId()+"-children")); - creationTimeUtc = managementContext.getStorage().getReference(getId()+"-creationTime"); - hostGeoInfo = managementContext.getStorage().getReference(getId()+"-hostGeoInfo"); - name = managementContext.getStorage().getReference(getId()+"-displayName"); - - // Only override stored defaults if we have actual values. We might be in setManagementContext - // because we are reconstituting an existing entity in a new brooklyn management-node (in which - // case believe what is already in the storage), or we might be in the middle of creating a new - // entity. Normally for a new entity (using EntitySpec creation approach), this will get called - // before setting the parent etc. However, for backwards compatibility we still support some - // things calling the entity's constructor directly. - if (oldParent != null) parent.set(oldParent); - if (oldChildren.size() > 0) children.addAll(oldChildren); - if (creationTimeUtc.isNull()) creationTimeUtc.set(oldCreationTimeUtc); - if (hostGeoInfo.isNull()) hostGeoInfo.set(oldHostGeoInfo); - if (name.isNull()) { - name.set(oldDisplayName); - } else { - displayNameAutoGenerated = false; - } - - configBag = ConfigBag.newLiveInstance(managementContext.getStorage().<String,Object>getMap(getId()+"-config")); - if (oldConfig.size() > 0) { - configBag.putAll(oldConfig); - } - } - } - - /** - * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly; - * see overridden method for more info - */ - @SuppressWarnings("serial") - @Override - @Deprecated - public AbstractLocation configure(Map<?,?> properties) { - assertNotYetManaged(); - - boolean firstTime = !configured.getAndSet(true); - - configBag.putAll(properties); - - if (properties.containsKey(PARENT_LOCATION.getName())) { - // need to ensure parent's list of children is also updated - setParent(configBag.get(PARENT_LOCATION)); - - // don't include parentLocation in configBag, as breaks rebind - configBag.remove(PARENT_LOCATION); - } - - // NB: flag-setting done here must also be done in BasicLocationRebindSupport - FlagUtils.setFieldsFromFlagsWithBag(this, properties, configBag, firstTime); - FlagUtils.setAllConfigKeys(this, configBag, false); - - if (properties.containsKey("displayName")) { - name.set((String) removeIfPossible(properties, "displayName")); - displayNameAutoGenerated = false; - } else if (properties.containsKey("name")) { - name.set((String) removeIfPossible(properties, "name")); - displayNameAutoGenerated = false; - } else if (isLegacyConstruction()) { - name.set(getClass().getSimpleName()+":"+getId().substring(0, Math.min(getId().length(),4))); - displayNameAutoGenerated = true; - } - - // TODO Explicitly dealing with iso3166 here because want custom splitter rule comma-separated string. - // Is there a better way to do it (e.g. more similar to latitude, where configKey+TypeCoercion is enough)? - if (groovyTruth(properties.get("iso3166"))) { - Object rawCodes = removeIfPossible(properties, "iso3166"); - Set<String> codes; - if (rawCodes instanceof CharSequence) { - codes = ImmutableSet.copyOf(Splitter.on(",").trimResults().split((CharSequence)rawCodes)); - } else { - codes = TypeCoercions.coerce(rawCodes, new TypeToken<Set<String>>() {}); - } - configBag.put(LocationConfigKeys.ISO_3166, codes); - } - - return this; - } - - // TODO ensure no callers rely on 'remove' semantics, and don't remove; - // or perhaps better use a config bag so we know what is used v unused - private static Object removeIfPossible(Map<?,?> map, Object key) { - try { - return map.remove(key); - } catch (Exception e) { - return map.get(key); - } - } - - public boolean isManaged() { - return getManagementContext() != null && managed; - } - - public void onManagementStarted() { - if (displayNameAutoGenerated) name.set(getClass().getSimpleName()+":"+getId().substring(0, Math.min(getId().length(),4))); - this.managed = true; - } - - public void onManagementStopped() { - this.managed = false; - if (getManagementContext().isRunning()) { - BrooklynStorage storage = ((ManagementContextInternal)getManagementContext()).getStorage(); - storage.remove(getId()+"-parent"); - storage.remove(getId()+"-children"); - storage.remove(getId()+"-creationTime"); - storage.remove(getId()+"-hostGeoInfo"); - storage.remove(getId()+"-displayName"); - storage.remove(getId()+"-config"); - } - } - - @Override - public String getDisplayName() { - return name.get(); - } - - protected boolean isDisplayNameAutoGenerated() { - return displayNameAutoGenerated; - } - - @Override - public Location getParent() { - return parent.get(); - } - - @Override - public Collection<Location> getChildren() { - synchronized (children) { - return ImmutableList.copyOf(children); - } - } - - @Override - public void setParent(Location newParent) { - setParent(newParent, true); - } - - public void setParent(Location newParent, boolean updateChildListParents) { - if (newParent == this) { - throw new IllegalArgumentException("Location cannot be its own parent: "+this); - } - if (newParent == parent.get()) { - return; // no-op; already have desired parent - } - - if (parent.get() != null) { - Location oldParent = parent.get(); - parent.set(null); - if (updateChildListParents) - ((AbstractLocation)oldParent).removeChild(this); - } - // TODO Should we support a location changing parent? The resulting unmanage/manage might cause problems. - // The code above suggests we do, but maybe we should warn or throw error, or at least test it! - - parent.set(newParent); - if (newParent != null) { - if (updateChildListParents) - ((AbstractLocation)newParent).addChild(this); - } - - onChanged(); - } - - @Override - public ConfigurationSupportInternal config() { - return config ; - } - - private class BasicConfigurationSupport implements ConfigurationSupportInternal { - - @Override - public <T> T get(ConfigKey<T> key) { - if (hasConfig(key, false)) return getLocalBag().get(key); - if (getParent() != null && isInherited(key)) { - return getParent().getConfig(key); - } - - // In case this entity class has overridden the given key (e.g. to set default), then retrieve this entity's key - // TODO when locations become entities, the duplication of this compared to EntityConfigMap.getConfig will disappear. - @SuppressWarnings("unchecked") - ConfigKey<T> ownKey = (ConfigKey<T>) elvis(locationType.getConfigKey(key.getName()), key); - - return ownKey.getDefaultValue(); - } - - @Override - public <T> T get(HasConfigKey<T> key) { - return get(key.getConfigKey()); - } - - @Override - public <T> T set(ConfigKey<T> key, T val) { - T result = configBag.put(key, val); - onChanged(); - return result; - } - - @Override - public <T> T set(HasConfigKey<T> key, T val) { - return set(key.getConfigKey(), val); - } - - @Override - public <T> T set(ConfigKey<T> key, Task<T> val) { - // TODO Support for locations - throw new UnsupportedOperationException(); - } - - @Override - public <T> T set(HasConfigKey<T> key, Task<T> val) { - // TODO Support for locations - throw new UnsupportedOperationException(); - } - - @Override - public ConfigBag getBag() { - ConfigBag result = ConfigBag.newInstanceExtending(configBag, ImmutableMap.of()); - Location p = getParent(); - if (p!=null) result.putIfAbsent(((LocationInternal)p).config().getBag()); - return result; - } - - @Override - public ConfigBag getLocalBag() { - return configBag; - } - - @Override - public Maybe<Object> getRaw(ConfigKey<?> key) { - if (hasConfig(key, false)) return Maybe.of(getLocalBag().getStringKey(key.getName())); - if (getParent() != null && isInherited(key)) return ((LocationInternal)getParent()).config().getRaw(key); - return Maybe.absent(); - } - - @Override - public Maybe<Object> getRaw(HasConfigKey<?> key) { - return getRaw(key.getConfigKey()); - } - - @Override - public Maybe<Object> getLocalRaw(ConfigKey<?> key) { - if (hasConfig(key, false)) return Maybe.of(getLocalBag().getStringKey(key.getName())); - return Maybe.absent(); - } - - @Override - public Maybe<Object> getLocalRaw(HasConfigKey<?> key) { - return getLocalRaw(key.getConfigKey()); - } - - @Override - public void addToLocalBag(Map<String, ?> vals) { - configBag.putAll(vals); - } - - @Override - public void removeFromLocalBag(String key) { - configBag.remove(key); - } - - @Override - public void refreshInheritedConfig() { - // no-op for location - } - - @Override - public void refreshInheritedConfigOfChildren() { - // no-op for location - } - - private boolean hasConfig(ConfigKey<?> key, boolean includeInherited) { - if (includeInherited && isInherited(key)) { - return getBag().containsKey(key); - } else { - return getLocalBag().containsKey(key); - } - } - - private boolean isInherited(ConfigKey<?> key) { - ConfigInheritance inheritance = key.getInheritance(); - if (inheritance==null) inheritance = getDefaultInheritance(); - return inheritance.isInherited(key, getParent(), AbstractLocation.this); - } - - private ConfigInheritance getDefaultInheritance() { - return ConfigInheritance.ALWAYS; - } - } - - @Override - public <T> T getConfig(HasConfigKey<T> key) { - return config().get(key); - } - - @Override - public <T> T getConfig(ConfigKey<T> key) { - return config().get(key); - } - - @Override - @Deprecated - public boolean hasConfig(ConfigKey<?> key, boolean includeInherited) { - return config.hasConfig(key, includeInherited); - } - - @Override - @Deprecated - public Map<String,Object> getAllConfig(boolean includeInherited) { - // TODO Have no information about what to include/exclude inheritance wise. - // however few things use getAllConfigBag() - ConfigBag bag = (includeInherited ? config().getBag() : config().getLocalBag()); - return bag.getAllConfig(); - } - - @Override - @Deprecated - public ConfigBag getAllConfigBag() { - // TODO see comments in EntityConfigMap and on interface methods. - // here ConfigBag is used exclusively so - // we have no information about what to include/exclude inheritance wise. - // however few things use getAllConfigBag() - return config().getBag(); - } - - @Override - public ConfigBag getLocalConfigBag() { - return config().getLocalBag(); - } - - /** - * @deprecated since 0.7; use {@link #getLocalConfigBag()} - * @since 0.6 - */ - @Deprecated - public ConfigBag getRawLocalConfigBag() { - return config().getLocalBag(); - } - - @Override - @Deprecated - public <T> T setConfig(ConfigKey<T> key, T value) { - return config().set(key, value); - } - - /** - * @since 0.6.0 (?) - use getDisplayName - * @deprecated since 0.7.0; use {@link #getDisplayName()} - */ - @Deprecated - public void setName(String newName) { - setDisplayName(newName); - } - - public void setDisplayName(String newName) { - name.set(newName); - displayNameAutoGenerated = false; - onChanged(); - } - - @Override - public boolean equals(Object o) { - if (! (o instanceof Location)) { - return false; - } - - Location l = (Location) o; - return getId().equals(l.getId()); - } - - @Override - public int hashCode() { - return getId().hashCode(); - } - - @Override - public boolean containsLocation(Location potentialDescendent) { - Location loc = potentialDescendent; - while (loc != null) { - if (this == loc) return true; - loc = loc.getParent(); - } - return false; - } - - protected <T extends Location> T addChild(LocationSpec<T> spec) { - T child = getManagementContext().getLocationManager().createLocation(spec); - addChild(child); - return child; - } - - @SuppressWarnings("deprecation") - public void addChild(Location child) { - // Previously, setParent delegated to addChildLocation and we sometimes ended up with - // duplicate entries here. Instead this now uses a similar scheme to - // AbstractLocation.setParent/addChild (with any weaknesses for distribution that such a - // scheme might have...). - // - // We continue to use a list to allow identical-looking locations, but they must be different - // instances. - - synchronized (children) { - for (Location contender : children) { - if (contender == child) { - // don't re-add; no-op - return; - } - } - - children.add(child); - } - - if (isManaged()) { - if (!getManagementContext().getLocationManager().isManaged(child)) { - Locations.manage(child, getManagementContext()); - } - } else if (getManagementContext() != null) { - if (((LocalLocationManager)getManagementContext().getLocationManager()).getLocationEvenIfPreManaged(child.getId()) == null) { - ((ManagementContextInternal)getManagementContext()).prePreManage(child); - } - } - - children.add(child); - child.setParent(this); - - onChanged(); - } - - public boolean removeChild(Location child) { - boolean removed; - synchronized (children) { - removed = children.remove(child); - } - if (removed) { - if (child instanceof Closeable) { - Streams.closeQuietly((Closeable)child); - } - child.setParent(null); - - if (isManaged()) { - getManagementContext().getLocationManager().unmanage(child); - } - } - onChanged(); - return removed; - } - - protected void onChanged() { - // currently changes simply trigger re-persistence; there is no intermediate listener as we do for EntityChangeListener - if (isManaged()) { - getManagementContext().getRebindManager().getChangeListener().onChanged(this); - } - } - - /** Default String representation is simplified name of class, together with selected fields. */ - @Override - public String toString() { - return string().toString(); - } - - @Override - public String toVerboseString() { - return toString(); - } - - /** override this, adding to the returned value, to supply additional fields to include in the toString */ - protected ToStringHelper string() { - return Objects.toStringHelper(getClass()).add("id", getId()).add("name", name); - } - - @Override - public HostGeoInfo getHostGeoInfo() { return hostGeoInfo.get(); } - - public void setHostGeoInfo(HostGeoInfo hostGeoInfo) { - if (hostGeoInfo!=null) { - this.hostGeoInfo.set(hostGeoInfo); - setConfig(LocationConfigKeys.LATITUDE, hostGeoInfo.latitude); - setConfig(LocationConfigKeys.LONGITUDE, hostGeoInfo.longitude); - } - } - - @Override - public RebindSupport<LocationMemento> getRebindSupport() { - return new BasicLocationRebindSupport(this); - } - - @Override - public boolean hasExtension(Class<?> extensionType) { - return extensions.get().containsKey(checkNotNull(extensionType, "extensionType")); - } - - @Override - @SuppressWarnings("unchecked") - public <T> T getExtension(Class<T> extensionType) { - Object extension = extensions.get().get(checkNotNull(extensionType, "extensionType")); - if (extension == null) { - throw new IllegalArgumentException("No extension of type "+extensionType+" registered for location "+this); - } - return (T) extension; - } - - @Override - public <T> void addExtension(Class<T> extensionType, T extension) { - checkNotNull(extensionType, "extensionType"); - checkNotNull(extension, "extension"); - checkArgument(extensionType.isInstance(extension), "extension %s does not implement %s", extension, extensionType); - extensions.get().put(extensionType, extension); - } - - @Override - public Map<String, String> toMetadataRecord() { - ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); - if (getDisplayName() != null) builder.put("displayName", getDisplayName()); - if (getParent() != null && getParent().getDisplayName() != null) { - builder.put("parentDisplayName", getParent().getDisplayName()); - } - return builder.build(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/538324e1/core/src/main/java/org/apache/brooklyn/location/core/AbstractLocationResolver.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/core/AbstractLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/core/AbstractLocationResolver.java deleted file mode 100644 index c7e80bc..0000000 --- a/core/src/main/java/org/apache/brooklyn/location/core/AbstractLocationResolver.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 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.location.core; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.brooklyn.api.location.Location; -import org.apache.brooklyn.api.location.LocationRegistry; -import org.apache.brooklyn.api.location.LocationResolver; -import org.apache.brooklyn.api.location.LocationSpec; -import org.apache.brooklyn.api.mgmt.ManagementContext; -import org.apache.brooklyn.location.core.internal.LocationInternal; -import org.apache.brooklyn.util.collections.MutableMap; -import org.apache.brooklyn.util.core.config.ConfigBag; -import org.apache.brooklyn.util.text.KeyValueParser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.ImmutableList; - -/** - * Examples of valid specs: - * <ul> - * <li>byon(hosts=myhost) - * <li>byon(hosts=myhost,myhost2) - * <li>byon(hosts="myhost, myhost2") - * <li>byon(hosts=myhost,myhost2, name=abc) - * <li>byon(hosts="myhost, myhost2", name="my location name") - * </ul> - * - * @author aled - */ -@SuppressWarnings({"unchecked","rawtypes"}) -public abstract class AbstractLocationResolver implements LocationResolver { - - public static final Logger log = LoggerFactory.getLogger(AbstractLocationResolver.class); - - protected volatile ManagementContext managementContext; - - protected volatile SpecParser specParser; - - protected abstract Class<? extends Location> getLocationType(); - - protected abstract SpecParser getSpecParser(); - - @Override - public void init(ManagementContext managementContext) { - this.managementContext = checkNotNull(managementContext, "managementContext"); - this.specParser = getSpecParser(); - } - - @Override - public boolean accepts(String spec, LocationRegistry registry) { - return BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true); - } - - @Override - public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) { - ConfigBag config = extractConfig(locationFlags, spec, registry); - Map globalProperties = registry.getProperties(); - String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName()); - - if (registry != null) { - LocationPropertiesFromBrooklynProperties.setLocalTempDir(globalProperties, config); - } - - return managementContext.getLocationManager().createLocation(LocationSpec.create(getLocationType()) - .configure(config.getAllConfig()) - .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation))); - } - - protected ConfigBag extractConfig(Map<?,?> locationFlags, String spec, LocationRegistry registry) { - Map globalProperties = registry.getProperties(); - ParsedSpec parsedSpec = specParser.parse(spec); - String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName()); - - // prefer args map over location flags - Map<String, Object> filteredProperties = getFilteredLocationProperties(getPrefix(), namedLocation, globalProperties); - ConfigBag flags = ConfigBag.newInstance(parsedSpec.argsMap).putIfAbsent(locationFlags).putIfAbsent(filteredProperties); - - return flags; - } - - protected Map<String, Object> getFilteredLocationProperties(String provider, String namedLocation, Map<String, ?> globalProperties) { - return new LocationPropertiesFromBrooklynProperties().getLocationProperties(getPrefix(), namedLocation, globalProperties); - } - - protected static class ParsedSpec { - public final String spec; - public final List<String> partsList; - public final Map<String,String> argsMap; - - ParsedSpec(String spec, List<String> partsList, Map<String,String> argsMap) { - this.spec = spec; - this.partsList = ImmutableList.copyOf(partsList); - this.argsMap = Collections.unmodifiableMap(MutableMap.copyOf(argsMap)); - } - } - - /** - * Parses a spec, by default of the general form "prefix:parts1:part2(arg1=val1,arg2=val2)" - */ - protected static class SpecParser { - - protected final String prefix; - protected final Pattern pattern; - private String exampleUsage; - - public SpecParser(String prefix) { - this.prefix = prefix; - pattern = Pattern.compile("("+prefix+"|"+prefix.toLowerCase()+"|"+prefix.toUpperCase()+")" + "(:)?" + "(\\((.*)\\))?$"); - } - - public SpecParser(String prefix, Pattern pattern) { - this.prefix = prefix; - this.pattern = pattern; - } - - public SpecParser setExampleUsage(String exampleUsage) { - this.exampleUsage = exampleUsage; - return this; - } - - protected String getUsage(String spec) { - if (exampleUsage == null) { - return "Spec should be in the form "+pattern; - } else { - return "for example, "+exampleUsage; - } - } - - protected void checkParsedSpec(ParsedSpec parsedSpec) { - // If someone tries "byon:(),byon:()" as a single spec, we get weird key-values! - for (String key : parsedSpec.argsMap.keySet()) { - if (key.contains(":") || key.contains("{") || key.contains("}") || key.contains("(") || key.contains(")")) { - throw new IllegalArgumentException("Invalid byon spec: "+parsedSpec.spec+" (key="+key+")"); - } - } - String name = parsedSpec.argsMap.get("name"); - if (parsedSpec.argsMap.containsKey("name") && (name == null || name.isEmpty())) { - throw new IllegalArgumentException("Invalid location '"+parsedSpec.spec+"'; if name supplied then value must be non-empty"); - } - String displayName = parsedSpec.argsMap.get("displayName"); - if (parsedSpec.argsMap.containsKey("displayName") && (displayName == null || displayName.isEmpty())) { - throw new IllegalArgumentException("Invalid location '"+parsedSpec.spec+"'; if displayName supplied then value must be non-empty"); - } - } - - public ParsedSpec parse(String spec) { - Matcher matcher = pattern.matcher(spec); - if (!matcher.matches()) { - throw new IllegalArgumentException("Invalid location '"+spec+"'; "+getUsage(spec)); - } - - String argsPart = matcher.group(3); - if (argsPart != null && argsPart.startsWith("(") && argsPart.endsWith(")")) { - // TODO Hacky; hosts("1.1.1.1") returns argsPart=("1.1.1.1") - argsPart = argsPart.substring(1, argsPart.length()-1); - } - Map<String, String> argsMap = KeyValueParser.parseMap(argsPart); - ParsedSpec result = new ParsedSpec(spec, ImmutableList.<String>of(), argsMap); - checkParsedSpec(result); - return result; - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/538324e1/core/src/main/java/org/apache/brooklyn/location/core/AggregatingMachineProvisioningLocation.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/core/AggregatingMachineProvisioningLocation.java b/core/src/main/java/org/apache/brooklyn/location/core/AggregatingMachineProvisioningLocation.java deleted file mode 100644 index 6ea9ec9..0000000 --- a/core/src/main/java/org/apache/brooklyn/location/core/AggregatingMachineProvisioningLocation.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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.location.core; - -import static com.google.common.base.Preconditions.checkState; - -import java.io.Closeable; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.brooklyn.api.location.MachineLocation; -import org.apache.brooklyn.api.location.MachineProvisioningLocation; -import org.apache.brooklyn.api.location.NoMachinesAvailableException; -import org.apache.brooklyn.util.core.flags.SetFromFlag; -import org.apache.brooklyn.util.stream.Streams; - -import com.google.common.base.Objects; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -/** - * Takes a list of other provisioners, and round-robins across them when obtaining a machine. - */ -public class AggregatingMachineProvisioningLocation<T extends MachineLocation> extends AbstractLocation - implements MachineProvisioningLocation<T>, Closeable { - - private static final long serialVersionUID = -8818006672883481775L; - - private Object lock; - - @SetFromFlag - protected List<MachineProvisioningLocation<T>> provisioners; - - @SetFromFlag - protected Map<T, MachineProvisioningLocation<T>> inUse; - - protected final AtomicInteger obtainCounter = new AtomicInteger(); - - public AggregatingMachineProvisioningLocation() { - this(Maps.newLinkedHashMap()); - } - - public AggregatingMachineProvisioningLocation(Map properties) { - super(properties); - - if (isLegacyConstruction()) { - init(); - } - } - - @Override - public void init() { - super.init(); - } - - @Override - public String toVerboseString() { - return Objects.toStringHelper(this).omitNullValues() - .add("id", getId()).add("name", getDisplayName()) - .add("provisioners", provisioners) - .toString(); - } - - @Override - public AbstractLocation configure(Map<?,?> properties) { - if (lock == null) { - lock = new Object(); - provisioners = Lists.<MachineProvisioningLocation<T>>newArrayList(); - inUse = Maps.<T, MachineProvisioningLocation<T>>newLinkedHashMap(); - } - return super.configure(properties); - } - - @Override - public AggregatingMachineProvisioningLocation<T> newSubLocation(Map<?,?> newFlags) { - throw new UnsupportedOperationException(); - } - - @Override - public void close() { - for (MachineProvisioningLocation<?> provisioner : provisioners) { - if (provisioner instanceof Closeable) { - Streams.closeQuietly((Closeable)provisioner); - } - } - } - - public T obtain() throws NoMachinesAvailableException { - return obtain(Maps.<String,Object>newLinkedHashMap()); - } - - @Override - public T obtain(Map<?,?> flags) throws NoMachinesAvailableException { - checkState(provisioners.size() > 0, "no provisioners!"); - int index = obtainCounter.getAndIncrement(); - for (int i = 0; i < provisioners.size(); i++) { - MachineProvisioningLocation<T> provisioner = provisioners.get(index++ % provisioners.size()); - try { - T machine = provisioner.obtain(flags); - inUse.put(machine, provisioner); - return machine; - } catch (NoMachinesAvailableException e) { - // move on; try next - } - } - throw new NoMachinesAvailableException("No machines available in "+toString()); - } - - @Override - public void release(T machine) { - MachineProvisioningLocation<T> provisioner = inUse.remove(machine); - if (provisioner != null) { - provisioner.release(machine); - } else { - throw new IllegalStateException("Request to release machine "+machine+", but this machine is not currently allocated"); - } - } - - @Override - public Map<String,Object> getProvisioningFlags(Collection<String> tags) { - return Maps.<String,Object>newLinkedHashMap(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/538324e1/core/src/main/java/org/apache/brooklyn/location/core/BasicHardwareDetails.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/core/BasicHardwareDetails.java b/core/src/main/java/org/apache/brooklyn/location/core/BasicHardwareDetails.java deleted file mode 100644 index 09059ec..0000000 --- a/core/src/main/java/org/apache/brooklyn/location/core/BasicHardwareDetails.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.location.core; - -import javax.annotation.concurrent.Immutable; - -import com.google.common.base.Objects; - -import org.apache.brooklyn.api.location.HardwareDetails; - -@Immutable -public class BasicHardwareDetails implements HardwareDetails { - - private final Integer cpuCount; - private final Integer ram; - - public BasicHardwareDetails(Integer cpuCount, Integer ram) { - this.cpuCount = cpuCount; - this.ram = ram; - } - - @Override - public Integer getCpuCount() { - return cpuCount; - } - - @Override - public Integer getRam() { - return ram; - } - - @Override - public String toString() { - return Objects.toStringHelper(HardwareDetails.class) - .omitNullValues() - .add("cpuCount", cpuCount) - .add("ram", ram) - .toString(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/538324e1/core/src/main/java/org/apache/brooklyn/location/core/BasicLocationDefinition.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/core/BasicLocationDefinition.java b/core/src/main/java/org/apache/brooklyn/location/core/BasicLocationDefinition.java deleted file mode 100644 index df9c641..0000000 --- a/core/src/main/java/org/apache/brooklyn/location/core/BasicLocationDefinition.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.location.core; - -import java.util.Map; - -import org.apache.brooklyn.api.location.LocationDefinition; -import org.apache.brooklyn.util.text.Identifiers; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; - -public class BasicLocationDefinition implements LocationDefinition { - - private final String id; - private final String name; - private final String spec; - private final Map<String,Object> config; - - public BasicLocationDefinition(String name, String spec, Map<String,? extends Object> config) { - this(Identifiers.makeRandomId(8), name, spec, config); - } - - public BasicLocationDefinition(String id, String name, String spec, Map<String,? extends Object> config) { - this.id = Preconditions.checkNotNull(id); - this.name = name; - this.spec = Preconditions.checkNotNull(spec); - this.config = config==null ? ImmutableMap.<String, Object>of() : ImmutableMap.<String, Object>copyOf(config); - } - - public String getId() { - return id; - } - - public String getName() { - return name; - } - - public String getSpec() { - return spec; - } - - @Override - public Map<String, Object> getConfig() { - return config; - } - - @Override - public boolean equals(Object o) { - if (this==o) return true; - if ((o instanceof LocationDefinition) && id.equals(((LocationDefinition)o).getId())) return true; - return false; - } - - @Override - public int hashCode() { - return id.hashCode(); - } - - @Override - public String toString() { - return "LocationDefinition{" + - "id='" + getId() + '\'' + - ", name='" + getName() + '\'' + - ", spec='" + getSpec() + '\'' + - ", config=" + getConfig() + - '}'; - } -}
