Return-Path: X-Original-To: apmail-brooklyn-commits-archive@minotaur.apache.org Delivered-To: apmail-brooklyn-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B69CA18449 for ; Mon, 1 Feb 2016 17:50:53 +0000 (UTC) Received: (qmail 70051 invoked by uid 500); 1 Feb 2016 17:50:44 -0000 Delivered-To: apmail-brooklyn-commits-archive@brooklyn.apache.org Received: (qmail 69980 invoked by uid 500); 1 Feb 2016 17:50:44 -0000 Mailing-List: contact commits-help@brooklyn.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@brooklyn.apache.org Delivered-To: mailing list commits@brooklyn.apache.org Received: (qmail 69727 invoked by uid 99); 1 Feb 2016 17:50:44 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 01 Feb 2016 17:50:44 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id D2E81E03BE; Mon, 1 Feb 2016 17:50:43 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: heneveld@apache.org To: commits@brooklyn.apache.org Date: Mon, 01 Feb 2016 17:50:53 -0000 Message-Id: <25d47db3542244308fbc9c5ae29222d5@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [11/51] [abbrv] [partial] brooklyn-server git commit: move subdir from incubator up a level as it is promoted to its own repo (first non-incubator commit!) http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java deleted file mode 100644 index 60fb061..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicLocationRegistry.java +++ /dev/null @@ -1,513 +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.core.location; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.ServiceLoader; -import java.util.Set; - -import org.apache.brooklyn.api.catalog.BrooklynCatalog; -import org.apache.brooklyn.api.catalog.CatalogItem; -import org.apache.brooklyn.api.location.Location; -import org.apache.brooklyn.api.location.LocationDefinition; -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.api.typereg.BrooklynTypeRegistry; -import org.apache.brooklyn.api.typereg.RegisteredType; -import org.apache.brooklyn.config.ConfigMap; -import org.apache.brooklyn.core.config.ConfigPredicates; -import org.apache.brooklyn.core.config.ConfigUtils; -import org.apache.brooklyn.core.location.internal.LocationInternal; -import org.apache.brooklyn.core.mgmt.internal.LocalLocationManager; -import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; -import org.apache.brooklyn.core.typereg.RegisteredTypePredicates; -import org.apache.brooklyn.util.collections.MutableList; -import org.apache.brooklyn.util.collections.MutableMap; -import org.apache.brooklyn.util.core.config.ConfigBag; -import org.apache.brooklyn.util.exceptions.Exceptions; -import org.apache.brooklyn.util.guava.Maybe; -import org.apache.brooklyn.util.guava.Maybe.Absent; -import org.apache.brooklyn.util.javalang.JavaClassNames; -import org.apache.brooklyn.util.text.Identifiers; -import org.apache.brooklyn.util.text.StringEscapes.JavaStringEscapes; -import org.apache.brooklyn.util.text.WildcardGlobs; -import org.apache.brooklyn.util.text.WildcardGlobs.PhraseTreatment; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Suppliers; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Sets; - -/** - * See {@link LocationRegistry} for general description. - *

- * TODO The relationship between the catalog and the location registry is a bit messy. - * For all existing code, the location registry is the definitive way to resolve - * locations. - *

- * Any location item added to the catalog must therefore be registered here. - * Whenever an item is added to the catalog, it will automatically call - * {@link #updateDefinedLocation(RegisteredType)}. Similarly, when a location - * is deleted from the catalog it will call {@link #removeDefinedLocation(RegisteredType)}. - *

- * However, the location item in the catalog has an unparsed blob of YAML, which contains - * important things like the type and the config of the location. This is only parsed when - * {@link BrooklynCatalog#createSpec(CatalogItem)} is called. We therefore jump through - * some hoops to wire together the catalog and the registry. - *

- * To add a location to the catalog, and then to resolve a location that is in the catalog, - * it goes through the following steps: - * - *

    - *
  1. Call {@link BrooklynCatalog#addItems(String)} - *
      - *
    1. This automatically calls {@link #updateDefinedLocation(RegisteredType)} - *
    2. A LocationDefinition is creating, using as its id the {@link RegisteredType#getSymbolicName()}. - * The definition's spec is {@code brooklyn.catalog::}, - *
    - *
  2. A blueprint can reference the catalog item using its symbolic name, - * such as the YAML {@code location: my-new-location}. - * (this feels similar to the "named locations"). - *
      - *
    1. This automatically calls {@link #resolve(String)}. - *
    2. The LocationDefinition is found by lookig up this name. - *
    3. The {@link LocationDefiniton.getSpec()} is retrieved; the right {@link LocationResolver} is - * found for it. - *
    4. This uses the {@link CatalogLocationResolver}, because the spec starts with {@code brooklyn.catalog:}. - *
    5. This resolver extracts from the spec the :, and looks up the - * location item using the {@link BrooklynTypeRegistry}. - *
    6. It then creates a {@link LocationSpec} by calling {@link BrooklynTypeRegistry#createSpec(RegisteredType)}. - *
        - *
      1. This first tries to use the type (that is in the YAML) as a simple Java class. - *
      2. If that fails, it will resolve the type using {@link #resolve(String, Boolean, Map)}, which - * returns an actual location object. - *
      3. It extracts from that location object the appropriate metadata to create a {@link LocationSpec}, - * returns the spec and discards the location object. - *
      - *
    7. The resolver creates the {@link Location} from the {@link LocationSpec} - *
    - *
- * - * TODO There is no concept of a location version in this registry. The version - * in the catalog is generally ignored. - */ -@SuppressWarnings({"rawtypes","unchecked"}) -public class BasicLocationRegistry implements LocationRegistry { - - // TODO save / serialize - // (we persist live locations, ie those in the LocationManager, but not "catalog" locations, ie those in this Registry) - - public static final Logger log = LoggerFactory.getLogger(BasicLocationRegistry.class); - - /** - * Splits a comma-separated list of locations (names or specs) into an explicit list. - * The splitting is very careful to handle commas embedded within specs, to split correctly. - */ - public static List expandCommaSeparateLocations(String locations) { - return WildcardGlobs.getGlobsAfterBraceExpansion("{"+locations+"}", false, PhraseTreatment.INTERIOR_NOT_EXPANDABLE, PhraseTreatment.INTERIOR_NOT_EXPANDABLE); - // don't do this, it tries to expand commas inside parentheses which is not good! -// QuotedStringTokenizer.builder().addDelimiterChars(",").buildList((String)id); - } - - private final ManagementContext mgmt; - /** map of defined locations by their ID */ - private final Map definedLocations = new LinkedHashMap(); - - protected final Map resolvers = new LinkedHashMap(); - - private final Set specsWarnedOnException = Sets.newConcurrentHashSet(); - - public BasicLocationRegistry(ManagementContext mgmt) { - this.mgmt = checkNotNull(mgmt, "mgmt"); - findServices(); - updateDefinedLocations(); - } - - protected void findServices() { - ServiceLoader loader = ServiceLoader.load(LocationResolver.class, mgmt.getCatalogClassLoader()); - MutableList loadedResolvers; - try { - loadedResolvers = MutableList.copyOf(loader); - } catch (Throwable e) { - log.warn("Error loading resolvers (rethrowing): "+e); - throw Exceptions.propagate(e); - } - - for (LocationResolver r: loadedResolvers) { - registerResolver(r); - } - if (log.isDebugEnabled()) log.debug("Location resolvers are: "+resolvers); - if (resolvers.isEmpty()) log.warn("No location resolvers detected: is src/main/resources correctly included?"); - } - - /** Registers the given resolver, invoking {@link LocationResolver#init(ManagementContext)} on the argument - * and returning true, unless the argument indicates false for {@link LocationResolver.EnableableLocationResolver#isEnabled()} */ - public boolean registerResolver(LocationResolver r) { - r.init(mgmt); - if (r instanceof LocationResolver.EnableableLocationResolver) { - if (!((LocationResolver.EnableableLocationResolver)r).isEnabled()) { - return false; - } - } - resolvers.put(r.getPrefix(), r); - return true; - } - - @Override - public Map getDefinedLocations() { - synchronized (definedLocations) { - return ImmutableMap.copyOf(definedLocations); - } - } - - @Override - public LocationDefinition getDefinedLocationById(String id) { - return definedLocations.get(id); - } - - @Override - public LocationDefinition getDefinedLocationByName(String name) { - synchronized (definedLocations) { - for (LocationDefinition l: definedLocations.values()) { - if (l.getName().equals(name)) return l; - } - return null; - } - } - - @Override - public void updateDefinedLocation(LocationDefinition l) { - synchronized (definedLocations) { - definedLocations.put(l.getId(), l); - } - } - - /** - * Converts the given item from the catalog into a LocationDefinition, and adds it - * to the registry (overwriting anything already registered with the id - * {@link CatalogItem#getCatalogItemId()}. - */ - public void updateDefinedLocation(CatalogItem> item) { - String id = item.getCatalogItemId(); - String symbolicName = item.getSymbolicName(); - String spec = CatalogLocationResolver.NAME + ":" + id; - Map config = ImmutableMap.of(); - BasicLocationDefinition locDefinition = new BasicLocationDefinition(symbolicName, symbolicName, spec, config); - - updateDefinedLocation(locDefinition); - } - - /** - * Converts the given item from the catalog into a LocationDefinition, and adds it - * to the registry (overwriting anything already registered with the id - * {@link RegisteredType#getId()}. - */ - public void updateDefinedLocation(RegisteredType item) { - String id = item.getId(); - String symbolicName = item.getSymbolicName(); - String spec = CatalogLocationResolver.NAME + ":" + id; - Map config = ImmutableMap.of(); - BasicLocationDefinition locDefinition = new BasicLocationDefinition(symbolicName, symbolicName, spec, config); - - updateDefinedLocation(locDefinition); - } - - public void removeDefinedLocation(CatalogItem> item) { - removeDefinedLocation(item.getSymbolicName()); - } - - @Override - public void removeDefinedLocation(String id) { - LocationDefinition removed; - synchronized (definedLocations) { - removed = definedLocations.remove(id); - } - if (removed == null && log.isDebugEnabled()) { - log.debug("{} was asked to remove location with id {} but no such location was registered", this, id); - } - } - - public void updateDefinedLocations() { - synchronized (definedLocations) { - // first read all properties starting brooklyn.location.named.xxx - // (would be nice to move to a better way, e.g. yaml, then deprecate this approach, but first - // we need ability/format for persisting named locations, and better support for adding+saving via REST/GUI) - int count = 0; - String NAMED_LOCATION_PREFIX = "brooklyn.location.named."; - ConfigMap namedLocationProps = mgmt.getConfig().submap(ConfigPredicates.nameStartsWith(NAMED_LOCATION_PREFIX)); - for (String k: namedLocationProps.asMapWithStringKeys().keySet()) { - String name = k.substring(NAMED_LOCATION_PREFIX.length()); - // If has a dot, then is a sub-property of a named location (e.g. brooklyn.location.named.prod1.user=bob) - if (!name.contains(".")) { - // this is a new named location - String spec = (String) namedLocationProps.asMapWithStringKeys().get(k); - // make up an ID - String id = Identifiers.makeRandomId(8); - Map config = ConfigUtils.filterForPrefixAndStrip(namedLocationProps.asMapWithStringKeys(), k+"."); - definedLocations.put(id, new BasicLocationDefinition(id, name, spec, config)); - count++; - } - } - if (log.isDebugEnabled()) - log.debug("Found "+count+" defined locations from properties (*.named.* syntax): "+definedLocations.values()); - if (getDefinedLocationByName("localhost")==null && !BasicOsDetails.Factory.newLocalhostInstance().isWindows() - && LocationConfigUtils.isEnabled(mgmt, "brooklyn.location.localhost")) { - log.debug("Adding a defined location for localhost"); - // add 'localhost' *first* - ImmutableMap oldDefined = ImmutableMap.copyOf(definedLocations); - definedLocations.clear(); - String id = Identifiers.makeRandomId(8); - definedLocations.put(id, localhost(id)); - definedLocations.putAll(oldDefined); - } - - for (RegisteredType item: mgmt.getTypeRegistry().getMatching(RegisteredTypePredicates.IS_LOCATION)) { - updateDefinedLocation(item); - count++; - } - } - } - - @VisibleForTesting - void disablePersistence() { - // persistence isn't enabled yet anyway (have to manually save things, - // defining the format and file etc) - } - - protected static BasicLocationDefinition localhost(String id) { - return new BasicLocationDefinition(id, "localhost", "localhost", null); - } - - /** to catch circular references */ - protected ThreadLocal> specsSeen = new ThreadLocal>(); - - @Override @Deprecated - public boolean canMaybeResolve(String spec) { - return getSpecResolver(spec) != null; - } - - @Override - public final Location resolve(String spec) { - return resolve(spec, true, null).get(); - } - - @Override @Deprecated - public final Location resolveIfPossible(String spec) { - if (!canMaybeResolve(spec)) return null; - return resolve(spec, null, null).orNull(); - } - - @Deprecated /** since 0.7.0 not used */ - public final Maybe resolve(String spec, boolean manage) { - return resolve(spec, manage, null); - } - - public Maybe resolve(String spec, Boolean manage, Map locationFlags) { - try { - locationFlags = MutableMap.copyOf(locationFlags); - if (manage!=null) { - locationFlags.put(LocalLocationManager.CREATE_UNMANAGED, !manage); - } - - Set seenSoFar = specsSeen.get(); - if (seenSoFar==null) { - seenSoFar = new LinkedHashSet(); - specsSeen.set(seenSoFar); - } - if (seenSoFar.contains(spec)) - return Maybe.absent(Suppliers.ofInstance(new IllegalStateException("Circular reference in definition of location '"+spec+"' ("+seenSoFar+")"))); - seenSoFar.add(spec); - - LocationResolver resolver = getSpecResolver(spec); - - if (resolver != null) { - try { - return Maybe.of(resolver.newLocationFromString(locationFlags, spec, this)); - } catch (RuntimeException e) { - return Maybe.absent(Suppliers.ofInstance(e)); - } - } - - // problem: but let's ensure that classpath is sane to give better errors in common IDE bogus case; - // and avoid repeated logging - String errmsg; - if (spec == null || specsWarnedOnException.add(spec)) { - if (resolvers.get("id")==null || resolvers.get("named")==null) { - log.error("Standard location resolvers not installed, location resolution will fail shortly. " - + "This usually indicates a classpath problem, such as when running from an IDE which " - + "has not properly copied META-INF/services from src/main/resources. " - + "Known resolvers are: "+resolvers.keySet()); - errmsg = "Unresolvable location '"+spec+"': " - + "Problem detected with location resolver configuration; " - + resolvers.keySet()+" are the only available location resolvers. " - + "More information can be found in the logs."; - } else { - log.debug("Location resolution failed for '"+spec+"' (if this is being loaded it will fail shortly): known resolvers are: "+resolvers.keySet()); - errmsg = "Unknown location '"+spec+"': " - + "either this location is not recognised or there is a problem with location resolver configuration."; - } - } else { - // For helpful log message construction: assumes classpath will not suddenly become wrong; might happen with OSGi though! - if (log.isDebugEnabled()) log.debug("Location resolution failed again for '"+spec+"' (throwing)"); - errmsg = "Unknown location '"+spec+"': " - + "either this location is not recognised or there is a problem with location resolver configuration."; - } - - return Maybe.absent(Suppliers.ofInstance(new NoSuchElementException(errmsg))); - - } finally { - specsSeen.remove(); - } - } - - @Override - public final Location resolve(String spec, Map locationFlags) { - return resolve(spec, null, locationFlags).get(); - } - - protected LocationResolver getSpecResolver(String spec) { - int colonIndex = spec.indexOf(':'); - int bracketIndex = spec.indexOf("("); - int dividerIndex = (colonIndex < 0) ? bracketIndex : (bracketIndex < 0 ? colonIndex : Math.min(bracketIndex, colonIndex)); - String prefix = dividerIndex >= 0 ? spec.substring(0, dividerIndex) : spec; - LocationResolver resolver = resolvers.get(prefix); - - if (resolver == null) - resolver = getSpecDefaultResolver(spec); - - return resolver; - } - - protected LocationResolver getSpecDefaultResolver(String spec) { - return getSpecFirstResolver(spec, "id", "named", "jclouds"); - } - protected LocationResolver getSpecFirstResolver(String spec, String ...resolversToCheck) { - for (String resolverId: resolversToCheck) { - LocationResolver resolver = resolvers.get(resolverId); - if (resolver!=null && resolver.accepts(spec, this)) - return resolver; - } - return null; - } - - /** providers default impl for {@link LocationResolver#accepts(String, LocationRegistry)} */ - public static boolean isResolverPrefixForSpec(LocationResolver resolver, String spec, boolean argumentRequired) { - if (spec==null) return false; - if (spec.startsWith(resolver.getPrefix()+":")) return true; - if (!argumentRequired && spec.equals(resolver.getPrefix())) return true; - return false; - } - - @Override - public List resolve(Iterable spec) { - List result = new ArrayList(); - for (Object id : spec) { - if (id==null) { - // drop a null entry - } if (id instanceof String) { - result.add(resolve((String) id)); - } else if (id instanceof Location) { - result.add((Location) id); - } else { - if (id instanceof Iterable) - throw new IllegalArgumentException("Cannot resolve '"+id+"' to a location; collections of collections not allowed"); - throw new IllegalArgumentException("Cannot resolve '"+id+"' to a location; unsupported type "+ - (id == null ? "null" : id.getClass().getName())); - } - } - return result; - } - - public List resolveList(Object l) { - if (l==null) l = Collections.emptyList(); - if (l instanceof String) l = JavaStringEscapes.unwrapJsonishListIfPossible((String)l); - if (l instanceof Iterable) return resolve((Iterable)l); - throw new IllegalArgumentException("Location list must be supplied as a collection or a string, not "+ - JavaClassNames.simpleClassName(l)+"/"+l); - } - - @Override - public Location resolve(LocationDefinition ld) { - return resolve(ld, null, null).get(); - } - - @Override @Deprecated - public Location resolveForPeeking(LocationDefinition ld) { - // TODO should clean up how locations are stored, figuring out whether they are shared or not; - // or maybe better, the API calls to this might just want to get the LocationSpec objects back - - // for now we use a 'CREATE_UNMANGED' flag to prevent management (leaks and logging) - return resolve(ld, ConfigBag.newInstance().configure(LocalLocationManager.CREATE_UNMANAGED, true).getAllConfig()); - } - - @Override @Deprecated - public Location resolve(LocationDefinition ld, Map flags) { - return resolveLocationDefinition(ld, flags, null); - } - - /** @deprecated since 0.7.0 not used (and optionalName was ignored anyway) */ - @Deprecated - public Location resolveLocationDefinition(LocationDefinition ld, Map locationFlags, String optionalName) { - return resolve(ld, null, locationFlags).get(); - } - - public Maybe resolve(LocationDefinition ld, Boolean manage, Map locationFlags) { - ConfigBag newLocationFlags = ConfigBag.newInstance(ld.getConfig()) - .putAll(locationFlags) - .putIfAbsentAndNotNull(LocationInternal.NAMED_SPEC_NAME, ld.getName()) - .putIfAbsentAndNotNull(LocationInternal.ORIGINAL_SPEC, ld.getName()); - Maybe result = resolve(ld.getSpec(), manage, newLocationFlags.getAllConfigRaw()); - if (result.isPresent()) - return result; - throw new IllegalStateException("Cannot instantiate location '"+ld+"' pointing at "+ld.getSpec()+": "+ - Exceptions.collapseText( ((Absent)result).getException() )); - } - - @Override - public Map getProperties() { - return mgmt.getConfig().asMapWithStringKeys(); - } - - @VisibleForTesting - public void putProperties(Map vals) { - ((ManagementContextInternal)mgmt).getBrooklynProperties().putAll(vals); - } - - @VisibleForTesting - public static void setupLocationRegistryForTesting(ManagementContext mgmt) { - // ensure localhost is added (even on windows) - LocationDefinition l = mgmt.getLocationRegistry().getDefinedLocationByName("localhost"); - if (l==null) mgmt.getLocationRegistry().updateDefinedLocation( - BasicLocationRegistry.localhost(Identifiers.makeRandomId(8)) ); - - ((BasicLocationRegistry)mgmt.getLocationRegistry()).disablePersistence(); - } -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicMachineDetails.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicMachineDetails.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicMachineDetails.java deleted file mode 100644 index b0a9bcd..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicMachineDetails.java +++ /dev/null @@ -1,183 +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.core.location; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.io.BufferedReader; -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nonnull; -import javax.annotation.concurrent.Immutable; - -import org.apache.brooklyn.api.location.HardwareDetails; -import org.apache.brooklyn.api.location.MachineDetails; -import org.apache.brooklyn.api.location.OsDetails; -import org.apache.brooklyn.api.mgmt.Task; -import org.apache.brooklyn.location.ssh.SshMachineLocation; -import org.apache.brooklyn.util.core.ResourceUtils; -import org.apache.brooklyn.util.core.task.DynamicTasks; -import org.apache.brooklyn.util.core.task.TaskTags; -import org.apache.brooklyn.util.core.task.ssh.internal.PlainSshExecTaskFactory; -import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper; -import org.apache.brooklyn.util.stream.Streams; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.annotations.Beta; -import com.google.common.base.CharMatcher; -import com.google.common.base.Function; -import com.google.common.base.Joiner; -import com.google.common.base.Objects; -import com.google.common.base.Splitter; -import com.google.common.base.Throwables; -import com.google.common.collect.Maps; -import com.google.common.io.CharStreams; - -@Immutable -public class BasicMachineDetails implements MachineDetails { - - public static final Logger LOG = LoggerFactory.getLogger(BasicMachineDetails.class); - - private final HardwareDetails hardwareDetails; - private final OsDetails osDetails; - - public BasicMachineDetails(HardwareDetails hardwareDetails, OsDetails osDetails) { - this.hardwareDetails = checkNotNull(hardwareDetails, "hardwareDetails"); - this.osDetails = checkNotNull(osDetails, "osDetails"); - } - - @Nonnull - @Override - public HardwareDetails getHardwareDetails() { - return hardwareDetails; - } - - @Nonnull - @Override - public OsDetails getOsDetails() { - return osDetails; - } - - @Override - public String toString() { - return Objects.toStringHelper(MachineDetails.class) - .add("os", osDetails) - .add("hardware", hardwareDetails) - .toString(); - } - - /** - * Creates a MachineDetails for the given location by SSHing to the machine and - * running a Bash script to gather data. Should only be called from within a - * task context. If this might not be the case then use {@link - * #taskForSshMachineLocation(SshMachineLocation)} instead. - */ - @Beta - public static BasicMachineDetails forSshMachineLocationLive(SshMachineLocation location) { - return TaskTags.markInessential(DynamicTasks.queueIfPossible(taskForSshMachineLocation(location)) - .orSubmitAsync() - .asTask()) - .getUnchecked(); - } - - /** - * @return A task that gathers machine details by SSHing to the machine and running - * a Bash script to gather data. - */ - public static Task taskForSshMachineLocation(SshMachineLocation location) { - BufferedReader reader = new BufferedReader(Streams.reader( - new ResourceUtils(BasicMachineDetails.class).getResourceFromUrl( - "classpath://org/apache/brooklyn/location/basic/os-details.sh"))); - List script; - try { - script = CharStreams.readLines(reader); - } catch (IOException e) { - LOG.error("Error reading os-details script", e); - throw Throwables.propagate(e); - } finally { - try { - reader.close(); - } catch (IOException e) { - // Not rethrowing e because it might obscure an exception caught by the first catch - LOG.error("Error closing os-details script reader", e); - } - } - Task task = new PlainSshExecTaskFactory(location, script) - .summary("Getting machine details for: " + location) - .requiringZeroAndReturningStdout() - .returning(taskToMachineDetailsFunction(location)) - .newTask() - .asTask(); - - return task; - } - - private static Function, BasicMachineDetails> taskToMachineDetailsFunction(final SshMachineLocation location) { - return new Function, BasicMachineDetails>() { - @Override - public BasicMachineDetails apply(ProcessTaskWrapper input) { - if (input.getExitCode() != 0) { - LOG.warn("Non-zero exit code when fetching machine details for {}; guessing anonymous linux", location); - return new BasicMachineDetails(new BasicHardwareDetails(null, null), - BasicOsDetails.Factory.ANONYMOUS_LINUX); - } - - String stdout = input.getStdout(); - if (LOG.isDebugEnabled()) { - LOG.debug("Found following details at {}: {}", location, stdout); - } - - Map details = Maps.newHashMap(Splitter.on(CharMatcher.anyOf("\r\n")) - .omitEmptyStrings() - .withKeyValueSeparator(":") - .split(stdout)); - - String name = details.remove("name"); - String version = details.remove("version"); - String architecture = details.remove("architecture"); - Integer ram = intOrNull(details, "ram"); - Integer cpuCount = intOrNull(details, "cpus"); - if (!details.isEmpty()) { - LOG.debug("Unused keys from os-details script: " + Joiner.on(", ").join(details.keySet())); - } - - OsDetails osDetails = new BasicOsDetails(name, architecture, version); - HardwareDetails hardwareDetails = new BasicHardwareDetails(cpuCount, ram); - BasicMachineDetails machineDetails = new BasicMachineDetails(hardwareDetails, osDetails); - - if (LOG.isDebugEnabled()) - LOG.debug("Machine details for {}: {}", location, machineDetails); - - return machineDetails; - } - - private Integer intOrNull(Map details, String key) { - try { - return Integer.valueOf(details.remove(key)); - } catch (NumberFormatException e) { - return null; - } - } - }; - } - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicMachineMetadata.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicMachineMetadata.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicMachineMetadata.java deleted file mode 100644 index 2590900..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicMachineMetadata.java +++ /dev/null @@ -1,84 +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.core.location; - -import com.google.common.base.Objects; - -import org.apache.brooklyn.api.location.MachineManagementMixins; - -public class BasicMachineMetadata implements MachineManagementMixins.MachineMetadata { - - final String id, name, primaryIp; - final Boolean isRunning; - final Object originalMetadata; - - public BasicMachineMetadata(String id, String name, String primaryIp, Boolean isRunning, Object originalMetadata) { - super(); - this.id = id; - this.name = name; - this.primaryIp = primaryIp; - this.isRunning = isRunning; - this.originalMetadata = originalMetadata; - } - - public String getId() { - return id; - } - - public String getName() { - return name; - } - - public String getPrimaryIp() { - return primaryIp; - } - - public Boolean isRunning() { - return isRunning; - } - - public Object getOriginalMetadata() { - return originalMetadata; - } - - @Override - public int hashCode() { - return Objects.hashCode(id, isRunning, name, originalMetadata, primaryIp); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - BasicMachineMetadata other = (BasicMachineMetadata) obj; - if (!Objects.equal(id, other.id)) return false; - if (!Objects.equal(name, other.name)) return false; - if (!Objects.equal(primaryIp, other.primaryIp)) return false; - if (!Objects.equal(isRunning, other.isRunning)) return false; - if (!Objects.equal(originalMetadata, other.originalMetadata)) return false; - return true; - } - - @Override - public String toString() { - return Objects.toStringHelper(this).add("id", id).add("name", name).add("originalMetadata", originalMetadata).toString(); - } - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicOsDetails.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicOsDetails.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicOsDetails.java deleted file mode 100644 index 8060562..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/BasicOsDetails.java +++ /dev/null @@ -1,123 +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.core.location; - -import java.util.regex.Pattern; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -import com.google.common.base.Objects; - -import org.apache.brooklyn.api.location.OsDetails; - -@Immutable -public class BasicOsDetails implements OsDetails { - - final String name, arch, version; - final boolean is64bit; - // (?i) forces matches to be case insensitive - public static final String UNIX_OS_NAME_PATTERNS = "(?i).*linux.*|centos|debian|fedora|gentoo|rhel|slackware|solaris|suse|ubuntu|coreos"; - - /** Sets is64Bit according to value of arch parameter. */ - public BasicOsDetails(String name, String arch, String version) { - this(name, arch, version, arch != null && arch.contains("64")); - } - - public BasicOsDetails(String name, String arch, String version, boolean is64Bit) { - this.name = name; this.arch = arch; this.version = version; this.is64bit = is64Bit; - } - - // TODO: Should be replaced with an enum like Jclouds' OsFamily and isX methods should - // switch against known cases - @Nullable - @Override - public String getName() { - return name; - } - - @Nullable - @Override - public String getArch() { - return arch; - } - - @Nullable - @Override - public String getVersion() { - return version; - } - - @Override - public boolean isWindows() { - //TODO confirm - return getName()!=null && getName().toLowerCase().contains("microsoft"); - } - - @Override - public boolean isLinux() { - return getName() != null && Pattern.matches(UNIX_OS_NAME_PATTERNS, getName()); - } - - @Override - public boolean isMac() { - return getName()!=null && getName().equals(OsNames.MAC_OS_X); - } - - @Override - public boolean is64bit() { - return is64bit; - } - - @Override - public String toString() { - return Objects.toStringHelper(OsDetails.class) - .omitNullValues() - .add("name", name) - .add("version", version) - .add("arch", arch) - .toString(); - } - - public static class OsNames { - public static final String MAC_OS_X = "Mac OS X"; - } - - public static class OsArchs { - public static final String X_86_64 = "x86_64"; -// public static final String X_86 = "x86"; -// // is this standard? or do we ever need the above? - public static final String I386 = "i386"; - } - - public static class OsVersions { - public static final String MAC_10_8 = "10.8"; - public static final String MAC_10_9 = "10.9"; - } - - public static class Factory { - public static OsDetails newLocalhostInstance() { - return new BasicOsDetails(System.getProperty("os.name"), System.getProperty("os.arch"), System.getProperty("os.version")); - } - - public static final OsDetails ANONYMOUS_LINUX = new BasicOsDetails("linux", OsArchs.I386, "unknown"); - public static final OsDetails ANONYMOUS_LINUX_64 = new BasicOsDetails("linux", OsArchs.X_86_64, "unknown"); - } - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java deleted file mode 100644 index 194e946..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/CatalogLocationResolver.java +++ /dev/null @@ -1,83 +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.core.location; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Map; - -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.api.typereg.RegisteredType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Given a location spec in the form {@code brooklyn.catalog::}, - * looks up the catalog to get its definition and creates such a location. - */ -public class CatalogLocationResolver implements LocationResolver { - - private static final Logger log = LoggerFactory.getLogger(CatalogLocationResolver.class); - - public static final String NAME = "brooklyn.catalog"; - - private ManagementContext managementContext; - - @Override - public void init(ManagementContext managementContext) { - this.managementContext = checkNotNull(managementContext, "managementContext"); - } - - @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) { - String id = spec.substring(NAME.length()+1); - RegisteredType item = managementContext.getTypeRegistry().get(id); - if (item.isDisabled()) { - throw new IllegalStateException("Illegal use of disabled catalog item "+item.getSymbolicName()+":"+item.getVersion()); - } else if (item.isDeprecated()) { - log.warn("Use of deprecated catalog item "+item.getSymbolicName()+":"+item.getVersion()); - } - - LocationSpec origLocSpec = (LocationSpec) managementContext.getTypeRegistry().createSpec(item, null, LocationSpec.class); - LocationSpec locSpec = LocationSpec.create(origLocSpec) - .configure(locationFlags); - return managementContext.getLocationManager().createLocation(locSpec); - } - - @Override - public String getPrefix() { - return NAME; - } - - /** - * accepts anything that looks like it will be a YAML catalog item (e.g. starting "brooklyn.locations") - */ - @Override - public boolean accepts(String spec, LocationRegistry registry) { - if (BasicLocationRegistry.isResolverPrefixForSpec(this, spec, false)) return true; - if (registry.getDefinedLocationByName(spec)!=null) return true; - return false; - } - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/DefinedLocationByIdResolver.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/DefinedLocationByIdResolver.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/DefinedLocationByIdResolver.java deleted file mode 100644 index 0438d1d..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/DefinedLocationByIdResolver.java +++ /dev/null @@ -1,74 +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.core.location; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Map; - -import org.apache.brooklyn.api.location.Location; -import org.apache.brooklyn.api.location.LocationDefinition; -import org.apache.brooklyn.api.location.LocationRegistry; -import org.apache.brooklyn.api.location.LocationResolver; -import org.apache.brooklyn.api.mgmt.ManagementContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * looks up based on ID in DefinedLocations map - */ -public class DefinedLocationByIdResolver implements LocationResolver { - - public static final Logger log = LoggerFactory.getLogger(DefinedLocationByIdResolver.class); - - public static final String ID = "id"; - - private volatile ManagementContext managementContext; - - @Override - public void init(ManagementContext managementContext) { - this.managementContext = checkNotNull(managementContext, "managementContext"); - } - - @SuppressWarnings({ "rawtypes" }) - @Override - public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) { - String id = spec; - if (spec.toLowerCase().startsWith(ID+":")) { - id = spec.substring( (ID+":").length() ); - } - LocationDefinition ld = registry.getDefinedLocationById(id); - ld.getSpec(); - return ((BasicLocationRegistry)registry).resolveLocationDefinition(ld, locationFlags, null); - } - - @Override - public String getPrefix() { - return ID; - } - - /** accepts anything starting id:xxx or just xxx where xxx is a defined location ID */ - @Override - public boolean accepts(String spec, LocationRegistry registry) { - if (BasicLocationRegistry.isResolverPrefixForSpec(this, spec, false)) return true; - if (registry.getDefinedLocationById(spec)!=null) return true; - return false; - } - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/DeprecatedKeysMappingBuilder.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/DeprecatedKeysMappingBuilder.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/DeprecatedKeysMappingBuilder.java deleted file mode 100644 index d5cb3c6..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/DeprecatedKeysMappingBuilder.java +++ /dev/null @@ -1,66 +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.core.location; - -import java.util.Map; - -import org.apache.brooklyn.config.ConfigKey; -import org.slf4j.Logger; - -import com.google.common.base.CaseFormat; -import com.google.common.collect.ImmutableMap; - -/** -* @deprecated since 0.6; for use only in converting deprecated flags; will be deleted in future version. -*/ -public class DeprecatedKeysMappingBuilder { - private final ImmutableMap.Builder builder = new ImmutableMap.Builder(); - private final Logger logger; - - public DeprecatedKeysMappingBuilder(Logger logger) { - this.logger = logger; - } - - public DeprecatedKeysMappingBuilder camelToHyphen(ConfigKey key) { - return camelToHyphen(key.getName()); - } - - public DeprecatedKeysMappingBuilder camelToHyphen(String key) { - String hyphen = toHyphen(key); - if (key.equals(hyphen)) { - logger.warn("Invalid attempt to convert camel-case key {} to deprecated hyphen-case: both the same", hyphen); - } else { - builder.put(hyphen, key); - } - return this; - } - - public DeprecatedKeysMappingBuilder putAll(Map vals) { - builder.putAll(vals); - return this; - } - - public Map build() { - return builder.build(); - } - - private String toHyphen(String word) { - return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, word); - } -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/HasSubnetHostname.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/HasSubnetHostname.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/HasSubnetHostname.java deleted file mode 100644 index 8f2cc4f..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/HasSubnetHostname.java +++ /dev/null @@ -1,32 +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.core.location; - -import com.google.common.annotations.Beta; - -@Beta -public interface HasSubnetHostname { - - /** returns a hostname for use internally within a subnet / VPC */ - @Beta - String getSubnetHostname(); - - /** returns an IP for use internally within a subnet / VPC */ - String getSubnetIp(); -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/LocationConfigKeys.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/LocationConfigKeys.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/LocationConfigKeys.java deleted file mode 100644 index e8e8db6..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/LocationConfigKeys.java +++ /dev/null @@ -1,79 +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.core.location; - -import java.io.File; -import java.util.Set; - -import org.apache.brooklyn.config.ConfigKey; -import org.apache.brooklyn.core.config.BasicConfigKey; -import org.apache.brooklyn.core.config.ConfigKeys; -import org.apache.brooklyn.util.os.Os; - -import com.google.common.base.CaseFormat; -import com.google.common.reflect.TypeToken; - -public class LocationConfigKeys { - - public static final ConfigKey LOCATION_ID = ConfigKeys.newStringConfigKey("id"); - public static final ConfigKey DISPLAY_NAME = ConfigKeys.newStringConfigKey("displayName"); - public static final ConfigKey ENABLED = ConfigKeys.newBooleanConfigKey("enabled", "Whether the location is enabled for listing and use " - + "(only supported for selected locations)", true); - - public static final ConfigKey ACCESS_IDENTITY = ConfigKeys.newStringConfigKey("identity"); - public static final ConfigKey ACCESS_CREDENTIAL = ConfigKeys.newStringConfigKey("credential"); - - public static final ConfigKey LATITUDE = new BasicConfigKey(Double.class, "latitude"); - public static final ConfigKey LONGITUDE = new BasicConfigKey(Double.class, "longitude"); - - public static final ConfigKey CLOUD_PROVIDER = ConfigKeys.newStringConfigKey("provider"); - public static final ConfigKey CLOUD_ENDPOINT = ConfigKeys.newStringConfigKey("endpoint"); - public static final ConfigKey CLOUD_REGION_ID = ConfigKeys.newStringConfigKey("region"); - public static final ConfigKey CLOUD_AVAILABILITY_ZONE_ID = ConfigKeys.newStringConfigKey("availabilityZone"); - - @SuppressWarnings("serial") - public static final ConfigKey> ISO_3166 = ConfigKeys.newConfigKey(new TypeToken>() {}, "iso3166", "ISO-3166 or ISO-3166-2 location codes"); - - public static final ConfigKey USER = ConfigKeys.newStringConfigKey("user", - "user account for normal access to the remote machine, defaulting to local user", System.getProperty("user.name")); - - public static final ConfigKey PASSWORD = ConfigKeys.newStringConfigKey("password", "password to use for ssh; note some images do not allow password-based ssh access"); - public static final ConfigKey PUBLIC_KEY_FILE = ConfigKeys.newStringConfigKey("publicKeyFile", "ssh public key file to use; if blank will infer from privateKeyFile by appending \".pub\""); - public static final ConfigKey PUBLIC_KEY_DATA = ConfigKeys.newStringConfigKey("publicKeyData", "ssh public key string to use (takes precedence over publicKeyFile)"); - public static final ConfigKey PRIVATE_KEY_FILE = ConfigKeys.newStringConfigKey("privateKeyFile", "a '" + File.pathSeparator + "' separated list of ssh private key files; uses first in list that can be read", - Os.fromHome(".ssh/id_rsa") + File.pathSeparator + Os.fromHome(".ssh/id_dsa")); - public static final ConfigKey PRIVATE_KEY_DATA = ConfigKeys.newStringConfigKey("privateKeyData", "ssh private key string to use (takes precedence over privateKeyFile)"); - public static final ConfigKey PRIVATE_KEY_PASSPHRASE = ConfigKeys.newStringConfigKey("privateKeyPassphrase"); - - /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated - public static final ConfigKey LEGACY_PUBLIC_KEY_FILE = ConfigKeys.convert(PUBLIC_KEY_FILE, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN); - /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated - public static final ConfigKey LEGACY_PUBLIC_KEY_DATA = ConfigKeys.convert(PUBLIC_KEY_DATA, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN); - /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated - public static final ConfigKey LEGACY_PRIVATE_KEY_FILE = ConfigKeys.convert(PRIVATE_KEY_FILE, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN); - /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated - public static final ConfigKey LEGACY_PRIVATE_KEY_DATA = ConfigKeys.convert(PRIVATE_KEY_DATA, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN); - /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated - public static final ConfigKey LEGACY_PRIVATE_KEY_PASSPHRASE = ConfigKeys.convert(PRIVATE_KEY_PASSPHRASE, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN); - - public static final ConfigKey CALLER_CONTEXT = new BasicConfigKey(Object.class, "callerContext", - "An object whose toString is used for logging, to indicate wherefore a VM is being created"); - public static final ConfigKey CLOUD_MACHINE_NAMER_CLASS = ConfigKeys.newStringConfigKey("cloudMachineNamer", "fully qualified class name of a class that extends CloudMachineNamer and has a single-parameter constructor that takes a ConfigBag"); - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/LocationConfigUtils.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/LocationConfigUtils.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/LocationConfigUtils.java deleted file mode 100644 index 64d31f9..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/location/LocationConfigUtils.java +++ /dev/null @@ -1,559 +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.core.location; - -import static org.apache.brooklyn.util.JavaGroovyEquivalents.groovyTruth; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.security.KeyPair; -import java.security.PublicKey; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.brooklyn.api.mgmt.ManagementContext; -import org.apache.brooklyn.config.ConfigKey; -import org.apache.brooklyn.core.BrooklynFeatureEnablement; -import org.apache.brooklyn.core.config.ConfigKeys; -import org.apache.brooklyn.core.location.cloud.CloudLocationConfig; -import org.apache.brooklyn.core.location.internal.LocationInternal; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.apache.brooklyn.util.collections.MutableMap; -import org.apache.brooklyn.util.collections.MutableSet; -import org.apache.brooklyn.util.core.ResourceUtils; -import org.apache.brooklyn.util.core.config.ConfigBag; -import org.apache.brooklyn.util.core.crypto.SecureKeys; -import org.apache.brooklyn.util.core.crypto.SecureKeys.PassphraseProblem; -import org.apache.brooklyn.util.crypto.AuthorizedKeysParser; -import org.apache.brooklyn.util.exceptions.Exceptions; -import org.apache.brooklyn.util.os.Os; -import org.apache.brooklyn.util.text.StringFunctions; -import org.apache.brooklyn.util.text.Strings; - -import com.google.common.annotations.Beta; -import com.google.common.base.Objects; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; - -public class LocationConfigUtils { - - private static final Logger log = LoggerFactory.getLogger(LocationConfigUtils.class); - - /** Creates an instance of {@link OsCredential} by inspecting {@link LocationConfigKeys#PASSWORD}; - * {@link LocationConfigKeys#PRIVATE_KEY_DATA} and {@link LocationConfigKeys#PRIVATE_KEY_FILE}; - * {@link LocationConfigKeys#PRIVATE_KEY_PASSPHRASE} if needed, and - * {@link LocationConfigKeys#PRIVATE_KEY_DATA} and {@link LocationConfigKeys#PRIVATE_KEY_FILE} - * (defaulting to the private key file + ".pub"). - **/ - public static OsCredential getOsCredential(ConfigBag config) { - return OsCredential.newInstance(config); - } - - /** Convenience class for holding private/public keys and passwords, inferring from config keys. - * See {@link LocationConfigUtils#getOsCredential(ConfigBag)}. */ - @Beta // would be nice to replace with a builder pattern - public static class OsCredential { - private final ConfigBag config; - private boolean preferPassword = false; - private boolean tryDefaultKeys = true; - private boolean requirePublicKey = true; - private boolean doKeyValidation = BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_VALIDATE_LOCATION_SSH_KEYS); - private boolean warnOnErrors = true; - private boolean throwOnErrors = false; - - private boolean dirty = true;; - - private String privateKeyData; - private String publicKeyData; - private String password; - - private OsCredential(ConfigBag config) { - this.config = config; - } - - /** throws if there are any problems */ - public OsCredential checkNotEmpty() { - checkNoErrors(); - - if (!hasKey() && !hasPassword()) { - if (warningMessages.size()>0) - throw new IllegalStateException("Could not find credentials: "+warningMessages); - else - throw new IllegalStateException("Could not find credentials"); - } - return this; - } - - /** throws if there were errors resolving (e.g. explicit keys, none of which were found/valid, or public key required and not found) - * @return */ - public OsCredential checkNoErrors() { - throwOnErrors(true); - dirty(); - infer(); - return this; - } - - public OsCredential logAnyWarnings() { - if (!warningMessages.isEmpty()) - log.warn("When reading credentials: "+warningMessages); - return this; - } - - public Set getWarningMessages() { - return warningMessages; - } - - /** returns either the key or password or null; if both a key and a password this prefers the key unless otherwise set - * via {@link #preferPassword()} */ - public synchronized String getPreferredCredential() { - infer(); - - if (isUsingPassword()) return password; - if (hasKey()) return privateKeyData; - return null; - } - - /** if there is no credential (ignores public key) */ - public boolean isEmpty() { - return !hasKey() && !hasPassword(); - } - public boolean hasKey() { - infer(); - // key has stricter non-blank check than password - return Strings.isNonBlank(privateKeyData); - } - public boolean hasPassword() { - infer(); - // blank, even empty passwords are allowed - return password!=null; - } - /** if a password is available, and either this is preferred over a key or there is no key */ - public boolean isUsingPassword() { - return hasPassword() && (!hasKey() || preferPassword); - } - - public String getPrivateKeyData() { - infer(); - return privateKeyData; - } - public String getPublicKeyData() { - infer(); - return publicKeyData; - } - public String getPassword() { - infer(); - return password; - } - - /** if both key and password supplied, prefer the key; the default */ - public OsCredential preferKey() { preferPassword = false; return dirty(); } - /** if both key and password supplied, prefer the password; see {@link #preferKey()} */ - public OsCredential preferPassword() { preferPassword = true; return dirty(); } - - /** if false, do not mind if there is no public key corresponding to any private key; - * defaults to true; only applies if a private key is set */ - public OsCredential requirePublicKey(boolean requirePublicKey) { - this.requirePublicKey = requirePublicKey; - return dirty(); - } - /** whether to check the private/public keys and passphrase are coherent; default true */ - public OsCredential doKeyValidation(boolean doKeyValidation) { - this.doKeyValidation = doKeyValidation; - return dirty(); - } - /** if true (the default) this will look at default locations set on keys */ - public OsCredential useDefaultKeys(boolean tryDefaultKeys) { - this.tryDefaultKeys = tryDefaultKeys; - return dirty(); - } - /** whether to log warnings on problems */ - public OsCredential warnOnErrors(boolean warnOnErrors) { - this.warnOnErrors = warnOnErrors; - return dirty(); - } - /** whether to throw on problems */ - public OsCredential throwOnErrors(boolean throwOnErrors) { - this.throwOnErrors = throwOnErrors; - return dirty(); - } - - private OsCredential dirty() { dirty = true; return this; } - - public static OsCredential newInstance(ConfigBag config) { - return new OsCredential(config); - } - - private synchronized void infer() { - if (!dirty) return; - warningMessages.clear(); - - log.debug("Inferring OS credentials"); - privateKeyData = config.get(LocationConfigKeys.PRIVATE_KEY_DATA); - password = config.get(LocationConfigKeys.PASSWORD); - publicKeyData = getKeyDataFromDataKeyOrFileKey(config, LocationConfigKeys.PUBLIC_KEY_DATA, LocationConfigKeys.PUBLIC_KEY_FILE); - - KeyPair privateKey = null; - - if (Strings.isBlank(privateKeyData)) { - // look up private key files - String privateKeyFiles = null; - boolean privateKeyFilesExplicitlySet = config.containsKey(LocationConfigKeys.PRIVATE_KEY_FILE); - if (privateKeyFilesExplicitlySet || (tryDefaultKeys && password==null)) - privateKeyFiles = config.get(LocationConfigKeys.PRIVATE_KEY_FILE); - if (Strings.isNonBlank(privateKeyFiles)) { - Iterator fi = Arrays.asList(privateKeyFiles.split(File.pathSeparator)).iterator(); - while (fi.hasNext()) { - String file = fi.next(); - if (Strings.isNonBlank(file)) { - try { - // real URL's won't actual work, due to use of path separator above - // not real important, but we get it for free if "files" is a list instead. - // using ResourceUtils is useful for classpath resources - if (file!=null) - privateKeyData = ResourceUtils.create().getResourceAsString(file); - // else use data already set - - privateKey = getValidatedPrivateKey(file); - - if (privateKeyData==null) { - // was cleared due to validation error - } else if (Strings.isNonBlank(publicKeyData)) { - log.debug("Loaded private key data from "+file+" (public key data explicitly set)"); - break; - } else { - String publicKeyFile = (file!=null ? file+".pub" : "(data)"); - try { - publicKeyData = ResourceUtils.create().getResourceAsString(publicKeyFile); - - log.debug("Loaded private key data from "+file+ - " and public key data from "+publicKeyFile); - break; - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - log.debug("No public key file "+publicKeyFile+"; will try extracting from private key"); - publicKeyData = AuthorizedKeysParser.encodePublicKey(privateKey.getPublic()); - - if (publicKeyData==null) { - if (requirePublicKey) { - addWarning("Unable to find or extract public key for "+file, "skipping"); - } else { - log.debug("Loaded private key data from "+file+" (public key data not found but not required)"); - break; - } - } else { - log.debug("Loaded private key data from "+file+" (public key data extracted)"); - break; - } - privateKeyData = null; - } - } - - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - String message = "Missing/invalid private key file "+file; - if (privateKeyFilesExplicitlySet) addWarning(message, (!fi.hasNext() ? "no more files to try" : "trying next file")+": "+e); - } - } - } - if (privateKeyFilesExplicitlySet && Strings.isBlank(privateKeyData)) - error("No valid private keys found", ""+warningMessages); - } - } else { - privateKey = getValidatedPrivateKey("(data)"); - } - - if (privateKeyData!=null) { - if (requirePublicKey && Strings.isBlank(publicKeyData)) { - if (privateKey!=null) { - publicKeyData = AuthorizedKeysParser.encodePublicKey(privateKey.getPublic()); - } - if (Strings.isBlank(publicKeyData)) { - error("If explicit "+LocationConfigKeys.PRIVATE_KEY_DATA.getName()+" is supplied, then " - + "the corresponding "+LocationConfigKeys.PUBLIC_KEY_DATA.getName()+" must also be supplied.", null); - } else { - log.debug("Public key data extracted"); - } - } - if (doKeyValidation && privateKey!=null && privateKey.getPublic()!=null && Strings.isNonBlank(publicKeyData)) { - PublicKey decoded = null; - try { - decoded = AuthorizedKeysParser.decodePublicKey(publicKeyData); - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - addWarning("Invalid public key: "+decoded); - } - if (decoded!=null && !privateKey.getPublic().equals( decoded )) { - error("Public key inferred from does not match public key extracted from private key", null); - } - } - } - - log.debug("OS credential inference: "+this); - dirty = false; - } - - private KeyPair getValidatedPrivateKey(String label) { - KeyPair privateKey = null; - String passphrase = config.get(CloudLocationConfig.PRIVATE_KEY_PASSPHRASE); - try { - privateKey = SecureKeys.readPem(new ByteArrayInputStream(privateKeyData.getBytes()), passphrase); - if (passphrase!=null) { - // get the unencrypted key data for our internal use (jclouds requires this) - privateKeyData = SecureKeys.toPem(privateKey); - } - } catch (PassphraseProblem e) { - if (doKeyValidation) { - log.debug("Encountered error handling key "+label+": "+e, e); - if (Strings.isBlank(passphrase)) - addWarning("Passphrase required for key '"+label+"'"); - else - addWarning("Invalid passphrase for key '"+label+"'"); - privateKeyData = null; - } - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - if (doKeyValidation) { - addWarning("Unable to parse private key from '"+label+"': unknown format"); - privateKeyData = null; - } - } - return privateKey; - } - - Set warningMessages = MutableSet.of(); - - private void error(String msg, String logExtension) { - addWarning(msg); - if (warnOnErrors) log.warn(msg+(logExtension==null ? "" : ": "+logExtension)); - if (throwOnErrors) throw new IllegalStateException(msg+(logExtension==null ? "" : "; "+logExtension)); - } - - private void addWarning(String msg) { - addWarning(msg, null); - } - private void addWarning(String msg, String debugExtension) { - log.debug(msg+(debugExtension==null ? "" : "; "+debugExtension)); - warningMessages.add(msg); - } - - @Override - public String toString() { - return getClass().getSimpleName()+"["+ - (Strings.isNonBlank(publicKeyData) ? publicKeyData : "no-public-key")+";"+ - (Strings.isNonBlank(privateKeyData) ? "private-key-present" : "no-private-key")+","+ - (password!=null ? "password(len="+password.length()+")" : "no-password")+"]"; - } - } - - /** @deprecated since 0.7.0, use #getOsCredential(ConfigBag) */ @Deprecated - public static String getPrivateKeyData(ConfigBag config) { - return getKeyData(config, LocationConfigKeys.PRIVATE_KEY_DATA, LocationConfigKeys.PRIVATE_KEY_FILE); - } - - /** @deprecated since 0.7.0, use #getOsCredential(ConfigBag) */ @Deprecated - public static String getPublicKeyData(ConfigBag config) { - String data = getKeyData(config, LocationConfigKeys.PUBLIC_KEY_DATA, LocationConfigKeys.PUBLIC_KEY_FILE); - if (groovyTruth(data)) return data; - - String privateKeyFile = config.get(LocationConfigKeys.PRIVATE_KEY_FILE); - if (groovyTruth(privateKeyFile)) { - List privateKeyFiles = Arrays.asList(privateKeyFile.split(File.pathSeparator)); - List publicKeyFiles = ImmutableList.copyOf(Iterables.transform(privateKeyFiles, StringFunctions.append(".pub"))); - List publicKeyFilesTidied = tidyFilePaths(publicKeyFiles); - - String fileData = getFileContents(publicKeyFilesTidied); - if (groovyTruth(fileData)) { - if (log.isDebugEnabled()) log.debug("Loaded "+LocationConfigKeys.PUBLIC_KEY_DATA.getName()+" from inferred files, based on "+LocationConfigKeys.PRIVATE_KEY_FILE.getName() + ": used " + publicKeyFilesTidied + " for "+config.getDescription()); - config.put(LocationConfigKeys.PUBLIC_KEY_DATA, fileData); - return fileData; - } else { - log.info("Not able to load "+LocationConfigKeys.PUBLIC_KEY_DATA.getName()+" from inferred files, based on "+LocationConfigKeys.PRIVATE_KEY_FILE.getName() + ": tried " + publicKeyFilesTidied + " for "+config.getDescription()); - } - } - - return null; - } - - /** @deprecated since 0.7.0, use #getOsCredential(ConfigBag) */ @Deprecated - public static String getKeyData(ConfigBag config, ConfigKey dataKey, ConfigKey fileKey) { - return getKeyDataFromDataKeyOrFileKey(config, dataKey, fileKey); - } - - private static String getKeyDataFromDataKeyOrFileKey(ConfigBag config, ConfigKey dataKey, ConfigKey fileKey) { - boolean unused = config.isUnused(dataKey); - String data = config.get(dataKey); - if (groovyTruth(data) && !unused) { - return data; - } - - String file = config.get(fileKey); - if (groovyTruth(file)) { - List files = Arrays.asList(file.split(File.pathSeparator)); - List filesTidied = tidyFilePaths(files); - String fileData = getFileContents(filesTidied); - if (fileData == null) { - log.warn("Invalid file" + (files.size() > 1 ? "s" : "") + " for " + fileKey + " (given " + files + - (files.equals(filesTidied) ? "" : "; converted to " + filesTidied) + ") " + - "may fail provisioning " + config.getDescription()); - } else if (groovyTruth(data)) { - if (!fileData.trim().equals(data.trim())) - log.warn(dataKey.getName()+" and "+fileKey.getName()+" both specified; preferring the former"); - } else { - data = fileData; - config.put(dataKey, data); - config.get(dataKey); - } - } - - return data; - } - - /** - * Reads the given file(s) in-order, returning the contents of the first file that can be read. - * Returns the file contents, or null if none of the files can be read. - * - * @param files list of file paths - */ - private static String getFileContents(Iterable files) { - Iterator fi = files.iterator(); - while (fi.hasNext()) { - String file = fi.next(); - if (groovyTruth(file)) { - try { - // see comment above - String result = ResourceUtils.create().getResourceAsString(file); - if (result!=null) return result; - log.debug("Invalid file "+file+" ; " + (!fi.hasNext() ? "no more files to try" : "trying next file")+" (null)"); - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - log.debug("Invalid file "+file+" ; " + (!fi.hasNext() ? "no more files to try" : "trying next file"), e); - } - } - } - return null; - } - - private static List tidyFilePaths(Iterable files) { - List result = Lists.newArrayList(); - for (String file : files) { - result.add(Os.tidyPath(file)); - } - return result; - } - - /** @deprecated since 0.6.0 use configBag.getWithDeprecation */ - @Deprecated - @SuppressWarnings("unchecked") - public static T getConfigCheckingDeprecatedAlternatives(ConfigBag configBag, ConfigKey preferredKey, - ConfigKey ...deprecatedKeys) { - T value1 = (T) configBag.getWithDeprecation(preferredKey, deprecatedKeys); - T value2 = getConfigCheckingDeprecatedAlternativesInternal(configBag, preferredKey, deprecatedKeys); - if (!Objects.equal(value1, value2)) { - // points to a bug in one of the get-with-deprecation methods - log.warn("Deprecated getConfig with deprecated keys "+Arrays.toString(deprecatedKeys)+" gets different value with " + - "new strategy "+preferredKey+" ("+value1+") and old ("+value2+"); preferring old value for now, but this behaviour will change"); - return value2; - } - return value1; - } - - @SuppressWarnings("unchecked") - private static T getConfigCheckingDeprecatedAlternativesInternal(ConfigBag configBag, ConfigKey preferredKey, - ConfigKey ...deprecatedKeys) { - ConfigKey keyProvidingValue = null; - T value = null; - boolean found = false; - if (configBag.containsKey(preferredKey)) { - value = configBag.get(preferredKey); - found = true; - keyProvidingValue = preferredKey; - } - - for (ConfigKey deprecatedKey: deprecatedKeys) { - T altValue = null; - boolean altFound = false; - if (configBag.containsKey(deprecatedKey)) { - altValue = (T) configBag.get(deprecatedKey); - altFound = true; - - if (altFound) { - if (found) { - if (Objects.equal(value, altValue)) { - // fine -- nothing - } else { - log.warn("Detected deprecated key "+deprecatedKey+" with value "+altValue+" used in addition to "+keyProvidingValue+" " + - "with value "+value+" for "+configBag.getDescription()+"; ignoring"); - configBag.remove(deprecatedKey); - } - } else { - log.warn("Detected deprecated key "+deprecatedKey+" with value "+altValue+" used instead of recommended "+preferredKey+"; " + - "promoting to preferred key status; will not be supported in future versions"); - configBag.put(preferredKey, altValue); - configBag.remove(deprecatedKey); - value = altValue; - found = true; - keyProvidingValue = deprecatedKey; - } - } - } - } - - if (found) { - return value; - } else { - return configBag.get(preferredKey); // get the default - } - } - - public static Map,String> finalAndOriginalSpecs(String finalSpec, Object ...sourcesForOriginalSpec) { - // yuck!: TODO should clean up how these things get passed around - Map,String> result = MutableMap.of(); - if (finalSpec!=null) - result.put(LocationInternal.FINAL_SPEC, finalSpec); - - String originalSpec = null; - for (Object source: sourcesForOriginalSpec) { - if (source instanceof CharSequence) originalSpec = source.toString(); - else if (source instanceof Map) { - if (originalSpec==null) originalSpec = Strings.toString( ((Map)source).get(LocationInternal.ORIGINAL_SPEC) ); - if (originalSpec==null) originalSpec = Strings.toString( ((Map)source).get(LocationInternal.ORIGINAL_SPEC.getName()) ); - } - if (originalSpec!=null) break; - } - if (originalSpec==null) originalSpec = finalSpec; - if (originalSpec!=null) - result.put(LocationInternal.ORIGINAL_SPEC, originalSpec); - - return result; - } - - public static boolean isEnabled(ManagementContext mgmt, String prefix) { - ConfigKey key = ConfigKeys.newConfigKeyWithPrefix(prefix+".", LocationConfigKeys.ENABLED); - Boolean enabled = mgmt.getConfig().getConfig(key); - if (enabled!=null) return enabled.booleanValue(); - return true; - } - - -}