http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/main/java/org/apache/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java b/core/src/main/java/org/apache/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java deleted file mode 100644 index 0e54806..0000000 --- a/core/src/main/java/org/apache/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java +++ /dev/null @@ -1,277 +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.entity.drivers; - -import java.lang.reflect.Constructor; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity; -import org.apache.brooklyn.api.entity.drivers.EntityDriver; -import org.apache.brooklyn.api.location.Location; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.apache.brooklyn.location.paas.PaasLocation; -import org.apache.brooklyn.location.ssh.SshMachineLocation; -import org.apache.brooklyn.location.winrm.WinRmMachineLocation; -import org.apache.brooklyn.util.collections.MutableList; -import org.apache.brooklyn.util.collections.MutableMap; -import org.apache.brooklyn.util.exceptions.Exceptions; -import org.apache.brooklyn.util.exceptions.ReferenceWithError; -import org.apache.brooklyn.util.text.Strings; - -/** - * Follows a class naming convention: the driver interface typically ends in "Driver", and the implementation - * must match the driver interface name but with a suffix like "SshDriver" instead of "Driver". - * Other rules can be added using {@link #addRule(String, DriverInferenceRule)} or - * {@link #addClassFullNameMapping(String, String)}. - * <p> - * Reflectively instantiates and returns the driver, based on the location passed in, - * in {@link #build(DriverDependentEntity, Location)}. - * - * @author Peter Veentjer, Alex Heneveld - */ -public class ReflectiveEntityDriverFactory { - - private static final Logger LOG = LoggerFactory.getLogger(ReflectiveEntityDriverFactory.class); - - /** Rules, keyed by a unique identifier. Executed in order of most-recently added first. */ - protected final Map<String,DriverInferenceRule> rules = MutableMap.of(); - - public ReflectiveEntityDriverFactory() { - addRule(DriverInferenceForSshLocation.DEFAULT_IDENTIFIER, new DriverInferenceForSshLocation()); - addRule(DriverInferenceForPaasLocation.DEFAULT_IDENTIFIER, new DriverInferenceForPaasLocation()); - addRule(DriverInferenceForWinRmLocation.DEFAULT_IDENTIFIER, new DriverInferenceForWinRmLocation()); - } - - public interface DriverInferenceRule { - public <D extends EntityDriver> ReferenceWithError<Class<? extends D>> resolve(DriverDependentEntity<D> entity, Class<D> driverInterface, Location location); - } - - public static abstract class AbstractDriverInferenceRule implements DriverInferenceRule { - - @Override - public <D extends EntityDriver> ReferenceWithError<Class<? extends D>> resolve(DriverDependentEntity<D> entity, Class<D> driverInterface, Location location) { - try { - String newName = inferDriverClassName(entity, driverInterface, location); - if (newName==null) return null; - - return loadDriverClass(newName, entity, driverInterface); - - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - return ReferenceWithError.newInstanceThrowingError(null, e); - } - } - - public abstract <D extends EntityDriver> String inferDriverClassName(DriverDependentEntity<D> entity, Class<D> driverInterface, Location location); - - protected <D extends EntityDriver> ReferenceWithError<Class<? extends D>> loadDriverClass(String className, DriverDependentEntity<D> entity, Class<D> driverInterface) { - ReferenceWithError<Class<? extends D>> r1 = loadClass(className, entity.getClass().getClassLoader()); - if (!r1.hasError()) return r1; - ReferenceWithError<Class<? extends D>> r2 = loadClass(className, driverInterface.getClass().getClassLoader()); - if (!r2.hasError()) return r2; - return r1; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected <D extends EntityDriver> ReferenceWithError<Class<? extends D>> loadClass(String className, ClassLoader classLoader) { - try { - return (ReferenceWithError<Class<? extends D>>)(ReferenceWithError) ReferenceWithError.newInstanceWithoutError((Class<? extends EntityDriver>)classLoader.loadClass(className)); - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - return ReferenceWithError.newInstanceThrowingError(null, e); - } - } - } - - public static abstract class AbstractDriverInferenceRenamingInferenceRule extends AbstractDriverInferenceRule { - - protected final String expectedPattern; - protected final String replacement; - - public AbstractDriverInferenceRenamingInferenceRule(String expectedPattern, String replacement) { - this.expectedPattern = expectedPattern; - this.replacement = replacement; - } - - public String getIdentifier() { - return getClass().getName()+"["+expectedPattern+"]"; - } - - @Override - public String toString() { - return getClass().getName()+"["+expectedPattern+"->"+replacement+"]"; - } - } - - public static class DriverInferenceByRenamingClassFullName extends AbstractDriverInferenceRenamingInferenceRule { - - public DriverInferenceByRenamingClassFullName(String expectedClassFullName, String newClassFullName) { - super(expectedClassFullName, newClassFullName); - } - - @Override - public <D extends EntityDriver> String inferDriverClassName(DriverDependentEntity<D> entity, Class<D> driverInterface, Location location) { - if (driverInterface.getName().equals(expectedPattern)) { - return replacement; - } - return null; - } - } - - public static class DriverInferenceByRenamingClassSimpleName extends AbstractDriverInferenceRenamingInferenceRule { - - public DriverInferenceByRenamingClassSimpleName(String expectedClassSimpleName, String newClassSimpleName) { - super(expectedClassSimpleName, newClassSimpleName); - } - - @Override - public <D extends EntityDriver> String inferDriverClassName(DriverDependentEntity<D> entity, Class<D> driverInterface, Location location) { - if (driverInterface.getSimpleName().equals(expectedPattern)) { - // i'd like to do away with drivers altogether, but if people *really* need to use this and suppress the warning, - // they can use the full class rename - LOG.warn("Using discouraged driver simple class rename to find "+replacement+" for "+expectedPattern+"; it is recommended to set getDriverInterface() or newDriver() appropriately"); - return Strings.removeFromEnd(driverInterface.getName(), expectedPattern)+replacement; - } - return null; - } - } - - public static class DriverInferenceForSshLocation extends AbstractDriverInferenceRule { - - public static final String DEFAULT_IDENTIFIER = "ssh-location-driver-inference-rule"; - - @Override - public <D extends EntityDriver> String inferDriverClassName(DriverDependentEntity<D> entity, Class<D> driverInterface, Location location) { - String driverInterfaceName = driverInterface.getName(); - if (!(location instanceof SshMachineLocation)) return null; - if (!driverInterfaceName.endsWith("Driver")) { - throw new IllegalArgumentException(String.format("Driver name [%s] doesn't end with 'Driver'; cannot auto-detect SshDriver class name", driverInterfaceName)); - } - return Strings.removeFromEnd(driverInterfaceName, "Driver")+"SshDriver"; - } - } - - public static class DriverInferenceForPaasLocation extends AbstractDriverInferenceRule { - - public static final String DEFAULT_IDENTIFIER = "paas-location-driver-inference-rule"; - - @Override - public <D extends EntityDriver> String inferDriverClassName(DriverDependentEntity<D> entity, Class<D> driverInterface, Location location) { - String driverInterfaceName = driverInterface.getName(); - if (!(location instanceof PaasLocation)) return null; - if (!driverInterfaceName.endsWith("Driver")) { - throw new IllegalArgumentException(String.format("Driver name [%s] doesn't end with 'Driver'; cannot auto-detect PaasDriver class name", driverInterfaceName)); - } - return Strings.removeFromEnd(driverInterfaceName, "Driver") + ((PaasLocation) location).getPaasProviderName() + "Driver"; - } - } - - public static class DriverInferenceForWinRmLocation extends AbstractDriverInferenceRule { - - public static final String DEFAULT_IDENTIFIER = "winrm-location-driver-inference-rule"; - - @Override - public <D extends EntityDriver> String inferDriverClassName(DriverDependentEntity<D> entity, Class<D> driverInterface, Location location) { - String driverInterfaceName = driverInterface.getName(); - if (!(location instanceof WinRmMachineLocation)) return null; - if (!driverInterfaceName.endsWith("Driver")) { - throw new IllegalArgumentException(String.format("Driver name [%s] doesn't end with 'Driver'; cannot auto-detect WinRmDriver class name", driverInterfaceName)); - } - return Strings.removeFromEnd(driverInterfaceName, "Driver")+"WinRmDriver"; - } - } - - /** adds a rule; possibly replacing an old one if one exists with the given identifier. the new rule is added after all previous ones. - * @return the replaced rule, or null if there was no old rule */ - public DriverInferenceRule addRule(String identifier, DriverInferenceRule rule) { - DriverInferenceRule oldRule = rules.remove(identifier); - rules.put(identifier, rule); - LOG.debug("Added driver mapping rule "+rule); - return oldRule; - } - - public DriverInferenceRule addClassFullNameMapping(String expectedClassFullName, String newClassFullName) { - DriverInferenceByRenamingClassFullName rule = new DriverInferenceByRenamingClassFullName(expectedClassFullName, newClassFullName); - return addRule(rule.getIdentifier(), rule); - } - - public DriverInferenceRule addClassSimpleNameMapping(String expectedClassSimpleName, String newClassSimpleName) { - DriverInferenceByRenamingClassSimpleName rule = new DriverInferenceByRenamingClassSimpleName(expectedClassSimpleName, newClassSimpleName); - return addRule(rule.getIdentifier(), rule); - } - - public <D extends EntityDriver> D build(DriverDependentEntity<D> entity, Location location){ - Class<D> driverInterface = entity.getDriverInterface(); - Class<? extends D> driverClass = null; - List<Throwable> exceptions = MutableList.of(); - if (driverInterface.isInterface()) { - List<DriverInferenceRule> ruleListInExecutionOrder = MutableList.copyOf(rules.values()); - Collections.reverse(ruleListInExecutionOrder); - // above puts rules in order with most recently added first - for (DriverInferenceRule rule: ruleListInExecutionOrder) { - ReferenceWithError<Class<? extends D>> clazzR = rule.resolve(entity, driverInterface, location); - if (clazzR!=null) { - if (!clazzR.hasError()) { - Class<? extends D> clazz = clazzR.get(); - if (clazz!=null) { - driverClass = clazz; - break; - } - } else { - exceptions.add(clazzR.getError()); - } - } - } - } else { - driverClass = driverInterface; - } - LOG.debug("Driver for "+driverInterface.getName()+" in "+location+" is: "+driverClass); - - if (driverClass==null) { - if (exceptions.isEmpty()) - throw new RuntimeException("No drivers could be found for "+driverInterface.getName()+"; " - + "currently only SshMachineLocation is supported for autodetection (location "+location+")"); - else throw Exceptions.create("No drivers could be loaded for "+driverInterface.getName()+" in "+location, exceptions); - } - - try { - Constructor<? extends D> constructor = getConstructor(driverClass); - constructor.setAccessible(true); - return constructor.newInstance(entity, location); - } catch (Exception e) { - LOG.warn("Unable to instantiate "+driverClass+" (rethrowing): "+e); - throw Exceptions.propagate(e); - } - } - - @SuppressWarnings("unchecked") - private <D extends EntityDriver> Constructor<D> getConstructor(Class<D> driverClass) { - for (Constructor<?> constructor : driverClass.getConstructors()) { - if (constructor.getParameterTypes().length == 2) { - return (Constructor<D>) constructor; - } - } - - throw new RuntimeException(String.format("Class [%s] has no constructor with 2 arguments", driverClass.getName())); - } - -}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/main/java/org/apache/brooklyn/entity/drivers/RegistryEntityDriverFactory.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/drivers/RegistryEntityDriverFactory.java b/core/src/main/java/org/apache/brooklyn/entity/drivers/RegistryEntityDriverFactory.java deleted file mode 100644 index 5cbf4e5..0000000 --- a/core/src/main/java/org/apache/brooklyn/entity/drivers/RegistryEntityDriverFactory.java +++ /dev/null @@ -1,127 +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.entity.drivers; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity; -import org.apache.brooklyn.api.entity.drivers.EntityDriver; -import org.apache.brooklyn.api.entity.drivers.EntityDriverManager; -import org.apache.brooklyn.api.location.Location; - -import com.google.common.base.Objects; -import com.google.common.base.Throwables; - -/** - * A registry of driver classes, keyed off the driver-interface + location type it is for. - * - * @author Aled Sage - */ -public class RegistryEntityDriverFactory implements EntityDriverManager { - - private final Map<DriverLocationTuple, Class<? extends EntityDriver>> registry = new LinkedHashMap<DriverLocationTuple, Class<? extends EntityDriver>>(); - - @Override - public <D extends EntityDriver> D build(DriverDependentEntity<D> entity, Location location) { - Class<? extends D> driverClass = lookupDriver(entity.getDriverInterface(), location); - return newDriverInstance(driverClass, entity, location); - } - - public boolean hasDriver(DriverDependentEntity<?> entity, Location location) { - return lookupDriver(entity.getDriverInterface(), location) != null; - } - - public <D extends EntityDriver> void registerDriver(Class<D> driverInterface, Class<? extends Location> locationClazz, Class<? extends D> driverClazz) { - synchronized (registry) { - registry.put(new DriverLocationTuple(driverInterface, locationClazz), driverClazz); - } - } - - @SuppressWarnings("unchecked") - private <D extends EntityDriver> Class<? extends D> lookupDriver(Class<D> driverInterface, Location location) { - synchronized (registry) { - for (DriverLocationTuple contender : registry.keySet()) { - if (contender.matches(driverInterface, location)) { - return (Class<? extends D>) registry.get(contender); - } - } - } - return null; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private <D> Constructor<D> getConstructor(Class<? extends D> driverClass) { - for (Constructor constructor : driverClass.getConstructors()) { - if (constructor.getParameterTypes().length == 2) { - return constructor; - } - } - - //TODO: - throw new RuntimeException(String.format("Class [%s] has no constructor with 2 arguments",driverClass.getName())); - } - - private <D> D newDriverInstance(Class<D> driverClass, Entity entity, Location location) { - Constructor<D> constructor = getConstructor(driverClass); - try { - constructor.setAccessible(true); - return constructor.newInstance(entity, location); - } catch (InstantiationException e) { - throw Throwables.propagate(e); - } catch (IllegalAccessException e) { - throw Throwables.propagate(e); - } catch (InvocationTargetException e) { - throw Throwables.propagate(e); - } - } - - private static class DriverLocationTuple { - private final Class<? extends EntityDriver> driverInterface; - private final Class<? extends Location> locationClazz; - - public DriverLocationTuple(Class<? extends EntityDriver> driverInterface, Class<? extends Location> locationClazz) { - this.driverInterface = checkNotNull(driverInterface, "driver interface"); - this.locationClazz = checkNotNull(locationClazz, "location class"); - } - - public boolean matches(Class<? extends EntityDriver> driver, Location location) { - return driverInterface.isAssignableFrom(driver) && locationClazz.isInstance(location); - } - - @Override - public int hashCode() { - return Objects.hashCode(driverInterface, locationClazz); - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof DriverLocationTuple)) { - return false; - } - DriverLocationTuple o = (DriverLocationTuple) other; - return driverInterface.equals(o.driverInterface) && locationClazz.equals(o.locationClazz); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadRequirement.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadRequirement.java b/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadRequirement.java deleted file mode 100644 index 6bbfc94..0000000 --- a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadRequirement.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.entity.drivers.downloads; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Map; - -import org.apache.brooklyn.api.entity.drivers.EntityDriver; -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadRequirement; -import org.apache.brooklyn.util.collections.MutableMap; - -import com.google.common.base.Objects; -import com.google.common.collect.ImmutableMap; - -public class BasicDownloadRequirement implements DownloadRequirement { - - private final EntityDriver entityDriver; - private final String addonName; - private final Map<String, ?> properties; - - /** - * Copies the given DownloadRequirement, but overriding the original properties with the given additional properties. - */ - public static BasicDownloadRequirement copy(DownloadRequirement req, Map<String,?> additionalProperties) { - Map<String,?> props = MutableMap.<String,Object>builder().putAll(req.getProperties()).putAll(additionalProperties).build(); - if (req.getAddonName() == null) { - return new BasicDownloadRequirement(req.getEntityDriver(), props); - } else { - return new BasicDownloadRequirement(req.getEntityDriver(), req.getAddonName(), props); - } - } - - public BasicDownloadRequirement(EntityDriver driver) { - this(driver, ImmutableMap.<String,Object>of()); - } - - public BasicDownloadRequirement(EntityDriver driver, Map<String, ?> properties) { - this.entityDriver = checkNotNull(driver, "entityDriver"); - this.addonName = null; - this.properties = checkNotNull(properties, "properties"); - } - - public BasicDownloadRequirement(EntityDriver entityDriver, String addonName, Map<String, ?> properties) { - this.entityDriver = checkNotNull(entityDriver, "entityDriver"); - this.addonName = checkNotNull(addonName, "addonName"); - this.properties = checkNotNull(properties, "properties"); - } - - @Override - public EntityDriver getEntityDriver() { - return entityDriver; - } - - @Override - public String getAddonName() { - return addonName; - } - - @Override - public Map<String, ?> getProperties() { - return properties; - } - - @Override - public String toString() { - return Objects.toStringHelper(this).add("driver", entityDriver).add("addon", addonName).omitNullValues().toString(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadResolver.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadResolver.java b/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadResolver.java deleted file mode 100644 index 21b260f..0000000 --- a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadResolver.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.entity.drivers.downloads; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.List; - -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolver; - -import com.google.common.base.Objects; -import com.google.common.collect.ImmutableList; - -public class BasicDownloadResolver implements DownloadResolver { - - private final List<String> targets; - private final String filename; - private final String unpackDirectoryName; - - public BasicDownloadResolver(Iterable<String> targets, String filename) { - this(targets, filename, null); - } - - public BasicDownloadResolver(Iterable<String> targets, String filename, String unpackDirectoryName) { - this.targets = ImmutableList.copyOf(checkNotNull(targets, "targets")); - this.filename = checkNotNull(filename, "filename"); - this.unpackDirectoryName = unpackDirectoryName; - } - - @Override - public List<String> getTargets() { - return targets; - } - - @Override - public String getFilename() { - return filename; - } - - @Override - public String getUnpackedDirectoryName(String defaultVal) { - return unpackDirectoryName == null ? defaultVal : unpackDirectoryName; - } - - @Override - public String toString() { - return Objects.toStringHelper(this).add("targets", targets).add("filename", filename) - .add("unpackDirName", unpackDirectoryName).omitNullValues().toString(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadTargets.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadTargets.java b/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadTargets.java deleted file mode 100644 index ebce783..0000000 --- a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadTargets.java +++ /dev/null @@ -1,121 +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.entity.drivers.downloads; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.List; - -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadTargets; -import org.apache.brooklyn.util.collections.MutableList; - -import com.google.common.base.Objects; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; - -public class BasicDownloadTargets implements DownloadTargets { - - private static final DownloadTargets EMPTY = builder().build(); - - public static DownloadTargets empty() { - return EMPTY; - } - - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - private List<String> primaries = Lists.newArrayList(); - private List<String> fallbacks = Lists.newArrayList(); - private boolean canContinueResolving = true; - - public Builder addAll(DownloadTargets other) { - addPrimaries(other.getPrimaryLocations()); - addFallbacks(other.getFallbackLocations()); - return this; - } - - public Builder addPrimary(String val) { - checkNotNull(val, "val"); - if (!primaries.contains(val)) primaries.add(val); - return this; - } - - public Builder addPrimaries(Iterable<String> vals) { - for (String val : checkNotNull(vals, "vals")) { - addPrimary(val); - } - return this; - } - - public Builder addFallback(String val) { - checkNotNull(val, "val"); - if (!fallbacks.contains(val)) fallbacks.add(val); - return this; - } - - public Builder addFallbacks(Iterable<String> vals) { - for (String val : checkNotNull(vals, "vals")) { - addFallback(val); - } - return this; - } - - public Builder canContinueResolving(boolean val) { - canContinueResolving = val; - return this; - } - - public BasicDownloadTargets build() { - return new BasicDownloadTargets(this); - } - } - - private final List<String> primaries; - private final List<String> fallbacks; - private final boolean canContinueResolving; - - protected BasicDownloadTargets(Builder builder) { - primaries = ImmutableList.copyOf(builder.primaries); - fallbacks = MutableList.<String>builder().addAll(builder.fallbacks).removeAll(builder.primaries).build().asUnmodifiable(); - canContinueResolving = builder.canContinueResolving; - } - - @Override - public List<String> getPrimaryLocations() { - return primaries; - } - - @Override - public List<String> getFallbackLocations() { - return fallbacks; - } - - @Override - public boolean canContinueResolving() { - return canContinueResolving; - } - - @Override - public String toString() { - return Objects.toStringHelper(this).add("primaries", primaries).add("fallbacks", fallbacks) - .add("canContinueResolving", canContinueResolving).toString(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadsManager.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadsManager.java b/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadsManager.java deleted file mode 100644 index a52d1b9..0000000 --- a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/BasicDownloadsManager.java +++ /dev/null @@ -1,161 +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.entity.drivers.downloads; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.brooklyn.api.entity.drivers.EntityDriver; -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolver; -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager; -import org.apache.brooklyn.config.StringConfigMap; -import org.apache.brooklyn.util.text.Strings; - -import com.google.common.base.Function; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; - -public class BasicDownloadsManager implements DownloadResolverManager { - - private final List<Function<? super DownloadRequirement, ? extends DownloadTargets>> producers = Lists.newCopyOnWriteArrayList(); - - private final List<Function<? super DownloadRequirement, String>> filenameProducers = Lists.newCopyOnWriteArrayList(); - - /** - * The default is (in-order) to: - * <ol> - * <li>Use the local repo, if any (defaulting to $HOME/.brooklyn/repository) - * <li>Use brooklyn properties for any download overrides defined there (see {@link DownloadProducerFromProperties} - * <li>Use the entity's Attributes.DOWNLOAD_URL - * <li>Use the cloudsoft fallback repo - * </ol> - * @param config - */ - public static BasicDownloadsManager newDefault(StringConfigMap config) { - BasicDownloadsManager result = new BasicDownloadsManager(); - - // In-order, will look up: local repo, overrides defined in the properties, and then - // the entity's attribute to get the download URL - DownloadProducerFromLocalRepo localRepoProducer = new DownloadProducerFromLocalRepo(config); - DownloadProducerFromProperties propertiesProducer = new DownloadProducerFromProperties(config); - DownloadProducerFromUrlAttribute attributeProducer = new DownloadProducerFromUrlAttribute(); - DownloadProducerFromCloudsoftRepo cloudsoftRepoProducer = new DownloadProducerFromCloudsoftRepo(config); - - result.registerProducer(localRepoProducer); - result.registerProducer(propertiesProducer); - result.registerProducer(attributeProducer); - result.registerProducer(cloudsoftRepoProducer); - - result.registerFilenameProducer(FilenameProducers.fromFilenameProperty()); - result.registerFilenameProducer(FilenameProducers.firstPrimaryTargetOf(propertiesProducer)); - result.registerFilenameProducer(FilenameProducers.firstPrimaryTargetOf(attributeProducer)); - - return result; - } - - public static BasicDownloadsManager newEmpty() { - return new BasicDownloadsManager(); - } - - @Override - public void registerPrimaryProducer(Function<? super DownloadRequirement, ? extends DownloadTargets> producer) { - producers.add(0, checkNotNull(producer, "resolver")); - } - - @Override - public void registerProducer(Function<? super DownloadRequirement, ? extends DownloadTargets> producer) { - producers.add(checkNotNull(producer, "resolver")); - } - - @Override - public void registerFilenameProducer(Function<? super DownloadRequirement, String> producer) { - filenameProducers.add(checkNotNull(producer, "producer")); - } - - @Override - public DownloadResolver newDownloader(EntityDriver driver) { - return newDownloader(new BasicDownloadRequirement(driver)); - } - - @Override - public DownloadResolver newDownloader(EntityDriver driver, Map<String, ?> properties) { - return newDownloader(new BasicDownloadRequirement(driver, properties)); - } - - @Override - public DownloadResolver newDownloader(EntityDriver driver, String addonName, Map<String, ?> addonProperties) { - return newDownloader(new BasicDownloadRequirement(driver, addonName, addonProperties)); - } - - private DownloadResolver newDownloader(DownloadRequirement req) { - // Infer filename - String filename = null; - for (Function<? super DownloadRequirement, String> filenameProducer : filenameProducers) { - filename = filenameProducer.apply(req); - if (!Strings.isBlank(filename)) break; - } - - // If a filename-producer has given us the filename, then augment the DownloadRequirement with that - // (so that local-repo substitutions etc can use that explicit filename) - DownloadRequirement wrappedReq; - if (filename == null) { - wrappedReq = req; - } else { - wrappedReq = BasicDownloadRequirement.copy(req, ImmutableMap.of("filename", filename)); - } - - // Get ordered download targets to be tried - List<String> primaries = Lists.newArrayList(); - List<String> fallbacks = Lists.newArrayList(); - for (Function<? super DownloadRequirement, ? extends DownloadTargets> producer : producers) { - DownloadTargets vals = producer.apply(wrappedReq); - primaries.addAll(vals.getPrimaryLocations()); - fallbacks.addAll(vals.getFallbackLocations()); - if (!vals.canContinueResolving()) { - break; - } - } - - Set<String> result = Sets.newLinkedHashSet(); - result.addAll(primaries); - result.addAll(fallbacks); - - if (result.isEmpty()) { - throw new IllegalArgumentException("No downloads matched for "+req); - } - - // If filename-producers didn't give any explicit filename, then infer from download results - if (filename == null) { - for (String target : result) { - filename = FilenameProducers.inferFilename(target); - if (!Strings.isBlank(filename)) break; - } - } - if (Strings.isBlank(filename)) { - throw new IllegalArgumentException("No filenames matched for "+req+" (targets "+result+")"); - } - - // And return the result - return new BasicDownloadResolver(result, filename); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromCloudsoftRepo.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromCloudsoftRepo.java b/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromCloudsoftRepo.java deleted file mode 100644 index bf0e679..0000000 --- a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromCloudsoftRepo.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.entity.drivers.downloads; - -import java.util.Map; - -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadRequirement; -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadTargets; -import org.apache.brooklyn.config.ConfigKey; -import org.apache.brooklyn.config.StringConfigMap; -import org.apache.brooklyn.core.config.BasicConfigKey; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Function; - -public class DownloadProducerFromCloudsoftRepo implements Function<DownloadRequirement, DownloadTargets> { - - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(DownloadProducerFromCloudsoftRepo.class); - - public static final ConfigKey<String> CLOUDSOFT_REPO_URL = BasicConfigKey.builder(String.class) - .name(DownloadProducerFromProperties.DOWNLOAD_CONF_PREFIX+"repo.cloudsoft.url") - .description("Whether to use the cloudsoft repo for downloading entities, during installs") - .defaultValue("http://downloads.cloudsoftcorp.com/brooklyn/repository") - .build(); - - public static final ConfigKey<Boolean> CLOUDSOFT_REPO_ENABLED = BasicConfigKey.builder(Boolean.class) - .name(DownloadProducerFromProperties.DOWNLOAD_CONF_PREFIX+"repo.cloudsoft.enabled") - .description("Whether to use the cloudsoft repo for downloading entities, during installs") - .defaultValue(true) - .build(); - - public static final String CLOUDSOFT_REPO_URL_PATTERN = "%s/"+ - "${simpletype}/${version}/"+ - "<#if filename??>"+ - "${filename}" + - "<#else>"+ - "<#if addon??>"+ - "${simpletype?lower_case}-${addon?lower_case}-${addonversion?lower_case}.${fileSuffix!\"tar.gz\"}"+ - "<#else>"+ - "${simpletype?lower_case}-${version?lower_case}.${fileSuffix!\"tar.gz\"}"+ - "</#if>"+ - "</#if>"; - - - private final StringConfigMap config; - - public DownloadProducerFromCloudsoftRepo(StringConfigMap config) { - this.config = config; - } - - public DownloadTargets apply(DownloadRequirement req) { - Boolean enabled = config.getConfig(CLOUDSOFT_REPO_ENABLED); - String baseUrl = config.getConfig(CLOUDSOFT_REPO_URL); - String url = String.format(CLOUDSOFT_REPO_URL_PATTERN, baseUrl); - - if (enabled) { - Map<String, ?> subs = DownloadSubstituters.getBasicSubstitutions(req); - String result = DownloadSubstituters.substitute(url, subs); - return BasicDownloadTargets.builder().addPrimary(result).build(); - - } else { - return BasicDownloadTargets.empty(); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepo.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepo.java b/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepo.java deleted file mode 100644 index 34ab0d1..0000000 --- a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepo.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.entity.drivers.downloads; - -import java.util.Map; - -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadRequirement; -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadTargets; -import org.apache.brooklyn.config.ConfigKey; -import org.apache.brooklyn.config.StringConfigMap; -import org.apache.brooklyn.core.config.BasicConfigKey; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Function; - -public class DownloadProducerFromLocalRepo implements Function<DownloadRequirement, DownloadTargets> { - - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(DownloadProducerFromLocalRepo.class); - - public static final ConfigKey<String> LOCAL_REPO_PATH = BasicConfigKey.builder(String.class) - .name(DownloadProducerFromProperties.DOWNLOAD_CONF_PREFIX+"repo.local.path") - .description("Fully qualified path of the local repo") - .defaultValue("$HOME/.brooklyn/repository") - .build(); - - public static final ConfigKey<Boolean> LOCAL_REPO_ENABLED = BasicConfigKey.builder(Boolean.class) - .name(DownloadProducerFromProperties.DOWNLOAD_CONF_PREFIX+"repo.local.enabled") - .description("Whether to use the local repo for downloading entities, during installs") - .defaultValue(true) - .build(); - - // TODO explain why this is this in lower_case! it's surprising - public static final String LOCAL_REPO_URL_PATTERN = "file://%s/"+ - "${simpletype}/${version}/"+ - "<#if filename??>"+ - "${filename}" + - "<#else>"+ - "<#if addon??>"+ - "${simpletype?lower_case}-${addon?lower_case}-${addonversion?lower_case}.${fileSuffix!\"tar.gz\"}"+ - "<#else>"+ - "${simpletype?lower_case}-${version?lower_case}.${fileSuffix!\"tar.gz\"}"+ - "</#if>"+ - "</#if>"; - - - private final StringConfigMap config; - - public DownloadProducerFromLocalRepo(StringConfigMap config) { - this.config = config; - } - - public DownloadTargets apply(DownloadRequirement req) { - Boolean enabled = config.getConfig(LOCAL_REPO_ENABLED); - String path = config.getConfig(LOCAL_REPO_PATH); - String url = String.format(LOCAL_REPO_URL_PATTERN, path); - - if (enabled) { - Map<String, ?> subs = DownloadSubstituters.getBasicSubstitutions(req); - String result = DownloadSubstituters.substitute(url, subs); - return BasicDownloadTargets.builder().addPrimary(result).build(); - - } else { - return BasicDownloadTargets.empty(); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromProperties.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromProperties.java b/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromProperties.java deleted file mode 100644 index 60c2b6b..0000000 --- a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromProperties.java +++ /dev/null @@ -1,344 +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.entity.drivers.downloads; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.List; -import java.util.Map; - -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.api.entity.drivers.EntityDriver; -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadRequirement; -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadTargets; -import org.apache.brooklyn.config.StringConfigMap; -import org.apache.brooklyn.entity.core.Attributes; -import org.apache.brooklyn.util.text.Strings; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -/** - * Based on the contents of brooklyn properties, sets up rules for resolving where to - * download artifacts from, for installing entities. - * - * By default, these rules override the DOWNLOAD_URL defined on the entities in code. - * Global properties can be specified that apply to all entities. Entity-specific properties - * can also be specified (which override the global properties for that entity type). - * - * Below is an example of realistic configuration for an enterprise who have an in-house - * repository that must be used for everything, rather than going out to the public internet. - * <pre> - * {@code - * // FIXME Check format for including addonname- only if addonname is non-null? - * // FIXME Use this in a testng test case - * brooklyn.downloads.all.url=http://downloads.acme.com/brookyn/repository/${simpletype}/${simpletype}-${addon?? addon-}${version}.${fileSuffix!.tar.gz} - * } - * </pre> - * - * To illustrate the features and variations one can use, below is an example of global - * properties that can be specified. The semicolon-separated list of URLs will be tried in-order - * until one succeeds. The fallback url says to use that if all other URLs fail (or no others are - * specified). - * <pre> - * {@code - * brooklyn.downloads.all.url=http://myurl1/${simpletype}-${version}.tar.gz; http://myurl2/${simpletype}-${version}.tar.gz - * brooklyn.downloads.all.fallbackurl=http://myurl3/${simpletype}-${version}.tar.gz - * } - * </pre> - * - * Similarly, entity-specific properties can be defined. All "global properties" will also apply - * to this entity type, unless explicitly overridden. - * <pre> - * {@code - * brooklyn.downloads.entity.tomcatserver.url=http://mytomcaturl1/tomcat-${version}.tar.gz - * brooklyn.downloads.entity.tomcatserver.fallbackurl=http://myurl2/tomcat-${version}.tar.gz - * } - * </pre> - * - * Downloads for entity-specific add-ons can also be defined. All "global properties" will also apply - * to this entity type, unless explicitly overridden. - * <pre> - * {@code - * brooklyn.downloads.entity.nginxcontroller.addon.stickymodule.url=http://myurl1/nginx-stickymodule-${version}.tar.gz - * brooklyn.downloads.entity.nginxcontroller.addon.stickymodule.fallbackurl=http://myurl2/nginx-stickymodule-${version}.tar.gz - * } - * </pre> - * - * If no explicit URLs are supplied, then by default it will use the DOWNLOAD_URL attribute - * of the entity (if supplied), followed by the fallbackurl if that fails. - * - * A URL can be a "template", where things of the form ${version} will be substituted for the value - * of "version" provided for that entity. The freemarker template engine is used to convert URLs - * (see <a href="http://freemarker.org">http://freemarker.org</a>). For example, one could use the URL: - * <pre> - * {@code - * http://repo.acme.com/${simpletype}-${version}.${fileSuffix!tar.gz} - * } - * </pre> - * The following substitutions are available automatically for a template: - * <ul> - * <li>entity: the {@link Entity} instance - * <li>driver: the {@link EntityDriver} instance being used for the Entity - * <li>simpletype: the unqualified name of the entity type - * <li>type: the fully qualified name of the entity type - * <li>addon: the name of the entity add-on, or null if it's the core entity artifact - * <li>version: the version number of the entity to be installed (or of the add-on) - * </ul> - */ -public class DownloadProducerFromProperties implements Function<DownloadRequirement, DownloadTargets> { - - /* FIXME: expose config for canContinueResolving. - * ... then it uses only the overrides in the properties file. This, in combination with - * setting something like {@code brooklyn.downloads.all.url=http://acme.com/repo/${simpletype}/${simpletype}-${version}.tar.gz}, - * allows an enterprise to ensure that entities never go to the public internet during installation. - * - * But also need to override things like nginx downlaod url for the stick module and pcre. - */ - - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(DownloadProducerFromProperties.class); - - public static final String DOWNLOAD_CONF_PREFIX = "brooklyn.downloads."; - - private final StringConfigMap config; - - public DownloadProducerFromProperties(StringConfigMap config) { - this.config = config; - } - - public DownloadTargets apply(DownloadRequirement downloadRequirement) { - List<Rule> rules = generateRules(); - BasicDownloadTargets.Builder result = BasicDownloadTargets.builder(); - for (Rule rule : rules) { - if (rule.matches(downloadRequirement.getEntityDriver(), downloadRequirement.getAddonName())) { - result.addAll(rule.resolve(downloadRequirement)); - } - } - - return result.build(); - } - - /** - * Produces a set of URL-generating rules, based on the brooklyn properties. These - * rules will be applied in-order until one of them returns a non-empty result. - */ - private List<Rule> generateRules() { - List<Rule> result = Lists.newArrayList(); - Map<String, String> subconfig = filterAndStripPrefix(config.asMapWithStringKeys(), DOWNLOAD_CONF_PREFIX); - - // If exists, use things like: - // brooklyn.downloads.all.fallbackurl=... - // brooklyn.downloads.all.url=... - // But only if not overridden by more entity-specify value - Map<String, String> forall = filterAndStripPrefix(subconfig, "all."); - String fallbackUrlForAll = forall.get("fallbackurl"); - String urlForAll = forall.get("url"); - - // If exists, use things like: - // brooklyn.downloads.entity.JBoss7Server.url=... - Map<String, String> forSpecificEntities = filterAndStripPrefix(subconfig, "entity."); - Map<String, Map<String,String>> splitBySpecificEntity = splitByPrefix(forSpecificEntities); - for (Map.Entry<String, Map<String,String>> entry : splitBySpecificEntity.entrySet()) { - String entityType = entry.getKey(); - Map<String, String> forentity = entry.getValue(); - String urlForEntity = forentity.get("url"); - if (urlForEntity == null) urlForEntity = urlForAll; - String fallbackUrlForEntity = forentity.get("fallbackurl"); - if (fallbackUrlForEntity == null) fallbackUrlForEntity = fallbackUrlForAll; - - result.add(new EntitySpecificRule(entityType, urlForEntity, fallbackUrlForEntity)); - - // If exists, use things like: - // brooklyn.downloads.entity.nginxcontroller.addon.stickymodule.url=... - Map<String, String> forSpecificAddons = filterAndStripPrefix(forentity, "addon."); - Map<String, Map<String,String>> splitBySpecificAddon = splitByPrefix(forSpecificAddons); - for (Map.Entry<String, Map<String,String>> entry2 : splitBySpecificAddon.entrySet()) { - String addonName = entry2.getKey(); - Map<String, String> foraddon = entry2.getValue(); - String urlForAddon = foraddon.get("url"); - if (urlForAddon == null) urlForAddon = urlForEntity; - String fallbackUrlForAddon = foraddon.get("fallbackurl"); - if (fallbackUrlForEntity == null) fallbackUrlForAddon = fallbackUrlForEntity; - - result.add(new EntityAddonSpecificRule(entityType, addonName, urlForAddon, fallbackUrlForAddon)); - } - } - - if (!forall.isEmpty()) { - result.add(new UniversalRule(urlForAll, fallbackUrlForAll)); - } - - return result; - } - - /** - * Returns a sub-map of config for keys that started with the given prefix, but where the returned - * map's keys do not include the prefix. - */ - private static Map<String,String> filterAndStripPrefix(Map<String,?> config, String prefix) { - Map<String,String> result = Maps.newLinkedHashMap(); - for (Map.Entry<String,?> entry : config.entrySet()) { - String key = entry.getKey(); - if (key.startsWith(prefix)) { - Object value = entry.getValue(); - result.put(key.substring(prefix.length()), (value == null) ? null : value.toString()); - } - } - return result; - } - - /** - * Splits the map up into multiple maps, using the key's prefix up to the first dot to - * tell which map to include it in. This prefix is used as the key in the map-of-maps, and - * is omitted in the contained map. - * - * For example, given [a.b:v1, a.c:v2, d.e:v3], it will return [ a:[b:v1, c:v2], d:[e:v3] ] - */ - private static Map<String,Map<String,String>> splitByPrefix(Map<String,String> config) { - Map<String,Map<String,String>> result = Maps.newLinkedHashMap(); - - for (Map.Entry<String,String> entry : config.entrySet()) { - String key = entry.getKey(); - String keysuffix = key.substring(key.indexOf(".")+1); - String keyprefix = key.substring(0, key.length()-keysuffix.length()-1); - String value = entry.getValue(); - - Map<String,String> submap = result.get(keyprefix); - if (submap == null) { - submap = Maps.newLinkedHashMap(); - result.put(keyprefix, submap); - } - submap.put(keysuffix, value); - } - return result; - } - - /** - * Resolves the download url, given an EntityDriver, with the following rules: - * <ol> - * <li>If url is not null, split and trim it on ";" and use - * <li>If url is null, retrive entity's Attributes.DOWNLOAD_URL and use if non-null - * <li>If fallbackUrl is not null, split and trim it on ";" and use - * <ol> - * - * For each of the resulting Strings, transforms them (using freemarker syntax for - * substitutions). Returns the list. - */ - private static abstract class Rule { - private final String url; - private final String fallbackUrl; - - Rule(String url, String fallbackUrl) { - this.url = url; - this.fallbackUrl = fallbackUrl; - } - - abstract boolean matches(EntityDriver driver, String addon); - - DownloadTargets resolve(DownloadRequirement req) { - EntityDriver driver = req.getEntityDriver(); - - List<String> primaries = Lists.newArrayList(); - List<String> fallbacks = Lists.newArrayList(); - if (Strings.isEmpty(url)) { - String defaulturl = driver.getEntity().getAttribute(Attributes.DOWNLOAD_URL); - if (defaulturl != null) primaries.add(defaulturl); - } else { - String[] parts = url.split(";"); - for (String part : parts) { - if (!part.isEmpty()) primaries.add(part.trim()); - } - } - if (fallbackUrl != null) { - String[] parts = fallbackUrl.split(";"); - for (String part : parts) { - if (!part.isEmpty()) fallbacks.add(part.trim()); - } - } - - BasicDownloadTargets.Builder result = BasicDownloadTargets.builder(); - for (String baseurl : primaries) { - result.addPrimary(DownloadSubstituters.substitute(req, baseurl)); - } - for (String baseurl : fallbacks) { - result.addFallback(DownloadSubstituters.substitute(req, baseurl)); - } - return result.build(); - } - } - - /** - * Rule for generating URLs that applies to all entities, if a more specific rule - * did not exist or failed to find a match. - */ - private static class UniversalRule extends Rule { - UniversalRule(String url, String fallbackUrl) { - super(url, fallbackUrl); - } - - @Override - boolean matches(EntityDriver driver, String addon) { - return true; - } - } - - /** - * Rule for generating URLs that applies to only the entity of the given type. - */ - private static class EntitySpecificRule extends Rule { - private final String entityType; - - EntitySpecificRule(String entityType, String url, String fallbackUrl) { - super(url, fallbackUrl); - this.entityType = checkNotNull(entityType, "entityType"); - } - - @Override - boolean matches(EntityDriver driver, String addon) { - String actualType = driver.getEntity().getEntityType().getName(); - String actualSimpleType = actualType.substring(actualType.lastIndexOf(".")+1); - return addon == null && entityType.equalsIgnoreCase(actualSimpleType); - } - } - - /** - * Rule for generating URLs that applies to only the entity of the given type. - */ - private static class EntityAddonSpecificRule extends Rule { - private final String entityType; - private final String addonName; - - EntityAddonSpecificRule(String entityType, String addonName, String url, String fallbackUrl) { - super(url, fallbackUrl); - this.entityType = checkNotNull(entityType, "entityType"); - this.addonName = checkNotNull(addonName, "addonName"); - } - - @Override - boolean matches(EntityDriver driver, String addon) { - String actualType = driver.getEntity().getEntityType().getName(); - String actualSimpleType = actualType.substring(actualType.lastIndexOf(".")+1); - return addonName.equals(addon) && entityType.equalsIgnoreCase(actualSimpleType); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromUrlAttribute.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromUrlAttribute.java b/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromUrlAttribute.java deleted file mode 100644 index 4e218b9..0000000 --- a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadProducerFromUrlAttribute.java +++ /dev/null @@ -1,63 +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.entity.drivers.downloads; - -import java.util.Map; - -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadRequirement; -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadTargets; -import org.apache.brooklyn.entity.core.Attributes; - -import com.google.common.base.Function; -import com.google.common.collect.Maps; - -/** - * Retrieves the DOWNLOAD_URL or DOWNLOAD_ADDON_URLS attribute of a given entity, and performs the - * template substitutions to generate the download URL. - * - * @author aled - */ -public class DownloadProducerFromUrlAttribute extends DownloadSubstituters.Substituter implements Function<DownloadRequirement, DownloadTargets> { - public DownloadProducerFromUrlAttribute() { - super( - new Function<DownloadRequirement, String>() { - @Override public String apply(DownloadRequirement input) { - if (input.getAddonName() == null) { - return input.getEntityDriver().getEntity().getAttribute(Attributes.DOWNLOAD_URL); - } else { - String addon = input.getAddonName(); - Map<String, String> addonUrls = input.getEntityDriver().getEntity().getAttribute(Attributes.DOWNLOAD_ADDON_URLS); - return (addonUrls != null) ? addonUrls.get(addon) : null; - } - } - }, - new Function<DownloadRequirement, Map<String,?>>() { - @Override public Map<String,?> apply(DownloadRequirement input) { - Map<String,Object> result = Maps.newLinkedHashMap(); - if (input.getAddonName() == null) { - result.putAll(DownloadSubstituters.getBasicEntitySubstitutions(input.getEntityDriver())); - } else { - result.putAll(DownloadSubstituters.getBasicAddonSubstitutions(input.getEntityDriver(), input.getAddonName())); - } - result.putAll(input.getProperties()); - return result; - } - }); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadSubstituters.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadSubstituters.java b/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadSubstituters.java deleted file mode 100644 index f12f343..0000000 --- a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/DownloadSubstituters.java +++ /dev/null @@ -1,172 +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.entity.drivers.downloads; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.Map; - -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.api.entity.drivers.EntityDriver; -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadRequirement; -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadTargets; -import org.apache.brooklyn.entity.core.BrooklynConfigKeys; -import org.apache.brooklyn.util.collections.MutableMap; -import org.apache.brooklyn.util.exceptions.Exceptions; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Function; -import com.google.common.base.Objects; - -import freemarker.cache.StringTemplateLoader; -import freemarker.template.Configuration; -import freemarker.template.Template; -import freemarker.template.TemplateException; - -public class DownloadSubstituters { - - private static final Logger LOG = LoggerFactory.getLogger(DownloadSubstituters.class); - - static { - // TODO in Freemarker 2.4 SLF4J may be auto-selected and we can remove this; - // for now, we need it somewhere, else we get j.u.l logging; - // since this is the main place it is used, let's do it here - try { - LOG.debug("Configuring Freemarker logging for Brooklyn to use SLF4J"); - System.setProperty(freemarker.log.Logger.SYSTEM_PROPERTY_NAME_LOGGER_LIBRARY, freemarker.log.Logger.LIBRARY_NAME_SLF4J); - } catch (Exception e) { - LOG.warn("Error setting Freemarker logging: "+e, e); - } - } - - private DownloadSubstituters() {} - - /** - * Converts the basevalue by substituting things in the form ${key} for values specific - * to a given entity driver. The keys used are: - * <ul> - * <li>driver: the driver instance (e.g. can do freemarker.org stuff like ${driver.osTag} to call {@code driver.getOsTag()}) - * <li>entity: the entity instance - * <li>type: the fully qualified type name of the entity - * <li>simpletype: the unqualified type name of the entity - * <li>addon: the name of the add-on, or null if for the entity's main artifact - * <li>version: the version for this entity (or of the add-on), or not included if null - * </ul> - * - * Additional substitution keys (and values) can be defined using {@link DownloadRequirement#getProperties()}; these - * override the default substitutions listed above. - */ - public static String substitute(DownloadRequirement req, String basevalue) { - return substitute(basevalue, getBasicSubstitutions(req)); - } - - public static Map<String,Object> getBasicSubstitutions(DownloadRequirement req) { - EntityDriver driver = req.getEntityDriver(); - String addon = req.getAddonName(); - Map<String, ?> props = req.getProperties(); - - if (addon == null) { - return MutableMap.<String,Object>builder() - .putAll(getBasicEntitySubstitutions(driver)) - .putAll(props) - .build(); - } else { - return MutableMap.<String,Object>builder() - .putAll(getBasicAddonSubstitutions(driver, addon)) - .putAll(props) - .build(); - } - } - - public static Map<String,Object> getBasicEntitySubstitutions(EntityDriver driver) { - Entity entity = driver.getEntity(); - String type = entity.getEntityType().getName(); - String simpleType = type.substring(type.lastIndexOf(".")+1); - String version = entity.getConfig(BrooklynConfigKeys.SUGGESTED_VERSION); - - return MutableMap.<String,Object>builder() - .put("entity", entity) - .put("driver", driver) - .put("type", type) - .put("simpletype", simpleType) - .putIfNotNull("version", version) - .build(); - } - - public static Map<String,Object> getBasicAddonSubstitutions(EntityDriver driver, String addon) { - return MutableMap.<String,Object>builder() - .putAll(getBasicEntitySubstitutions(driver)) - .put("addon", addon) - .build(); - } - - public static String substitute(String basevalue, Map<String,?> substitutions) { - try { - Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); - StringTemplateLoader templateLoader = new StringTemplateLoader(); - templateLoader.putTemplate("config", basevalue); - cfg.setTemplateLoader(templateLoader); - Template template = cfg.getTemplate("config"); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - Writer out = new OutputStreamWriter(baos); - template.process(substitutions, out); - out.flush(); - - return new String(baos.toByteArray()); - } catch (IOException e) { - LOG.warn("Error processing template '"+basevalue+"'", e); - throw Exceptions.propagate(e); - } catch (TemplateException e) { - throw new IllegalArgumentException("Failed to process driver download '"+basevalue+"'", e); - } - } - - public static Function<DownloadRequirement, DownloadTargets> substituter(Function<? super DownloadRequirement, String> basevalueProducer, Function<? super DownloadRequirement, ? extends Map<String,?>> subsProducer) { - // FIXME Also need default subs (entity, driver, simpletype, etc) - return new Substituter(basevalueProducer, subsProducer); - } - - protected static class Substituter implements Function<DownloadRequirement, DownloadTargets> { - private final Function<? super DownloadRequirement, String> basevalueProducer; - private final Function<? super DownloadRequirement, ? extends Map<String,?>> subsProducer; - - Substituter(Function<? super DownloadRequirement, String> baseValueProducer, Function<? super DownloadRequirement, ? extends Map<String,?>> subsProducer) { - this.basevalueProducer = checkNotNull(baseValueProducer, "basevalueProducer"); - this.subsProducer = checkNotNull(subsProducer, "subsProducer"); - } - - @Override - public DownloadTargets apply(DownloadRequirement input) { - String basevalue = basevalueProducer.apply(input); - Map<String, ?> subs = subsProducer.apply(input); - String result = (basevalue != null) ? substitute(basevalue, subs) : null; - return (result != null) ? BasicDownloadTargets.builder().addPrimary(result).build() : BasicDownloadTargets.empty(); - } - - @Override public String toString() { - return Objects.toStringHelper(this).add("basevalue", basevalueProducer).add("subs", subsProducer).toString(); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/FilenameProducers.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/FilenameProducers.java b/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/FilenameProducers.java deleted file mode 100644 index 11aa537..0000000 --- a/core/src/main/java/org/apache/brooklyn/entity/drivers/downloads/FilenameProducers.java +++ /dev/null @@ -1,64 +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.entity.drivers.downloads; - -import java.util.List; - -import javax.annotation.Nullable; - -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadRequirement; -import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadTargets; -import org.apache.brooklyn.util.text.Strings; - -import com.google.common.base.Function; - -public class FilenameProducers { - - public static String inferFilename(String target) { - String result = target.substring(target.lastIndexOf("/")+1); - result = result.contains("?") ? result.substring(0, result.indexOf("?")) : result; - if (!result.contains(".")) - // require a full stop, else assume it isn't a filename - return null; - return result; - } - - public static Function<DownloadRequirement, String> fromFilenameProperty() { - return new Function<DownloadRequirement, String>() { - @Override public String apply(@Nullable DownloadRequirement req) { - Object filename = req.getProperties().get("filename"); - return (filename != null) ? filename.toString() : null; - } - }; - } - - public static Function<DownloadRequirement, String> firstPrimaryTargetOf(final Function<DownloadRequirement, DownloadTargets> producer) { - return new Function<DownloadRequirement, String>() { - @Override public String apply(@Nullable DownloadRequirement req) { - DownloadTargets targets = producer.apply(req); - List<String> primaryTargets = targets.getPrimaryLocations(); - for (String primaryTarget : primaryTargets) { - String result = inferFilename(primaryTarget); - if (!Strings.isBlank(result)) return result; - } - return null; - } - }; - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c27cf1d0/core/src/main/java/org/apache/brooklyn/entity/factory/AbstractConfigurableEntityFactory.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/factory/AbstractConfigurableEntityFactory.java b/core/src/main/java/org/apache/brooklyn/entity/factory/AbstractConfigurableEntityFactory.java deleted file mode 100644 index a4249ba..0000000 --- a/core/src/main/java/org/apache/brooklyn/entity/factory/AbstractConfigurableEntityFactory.java +++ /dev/null @@ -1,82 +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.entity.factory; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.config.ConfigKey; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public abstract class AbstractConfigurableEntityFactory<T extends Entity> implements ConfigurableEntityFactory<T>, Serializable { - private static final Logger log = LoggerFactory.getLogger(AbstractConfigurableEntityFactory.class); - - protected final Map config = new LinkedHashMap(); - - public AbstractConfigurableEntityFactory(){ - this(new HashMap()); - } - - public AbstractConfigurableEntityFactory(Map flags) { - this.config.putAll(flags); - - } - public AbstractConfigurableEntityFactory<T> configure(Map flags) { - config.putAll(flags); - return this; - } - - public AbstractConfigurableEntityFactory<T> configure(ConfigKey key, Object value) { - config.put(key, value); - return this; - } - - public AbstractConfigurableEntityFactory<T> configure(ConfigKey.HasConfigKey key, Object value) { - return setConfig(key.getConfigKey(), value); - } - - public AbstractConfigurableEntityFactory<T> setConfig(ConfigKey key, Object value) { - return configure(key, value); - } - - public AbstractConfigurableEntityFactory<T> setConfig(ConfigKey.HasConfigKey key, Object value) { - return configure(key.getConfigKey(), value); - } - - public T newEntity(Entity parent){ - return newEntity(new HashMap(),parent); - } - - public T newEntity(Map flags, Entity parent) { - Map flags2 = new HashMap(); - flags2.putAll(config); - flags2.putAll(flags); - T result = newEntity2(flags2, parent); - // we rely increasingly on init, which factory doesn't call; really should remove factories! - log.warn("Deprecated legacy compatibility, using factory (init will not be invoked): "+result); - return result; - } - - public abstract T newEntity2(Map flags, Entity parent); -} -
