http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/persister/XmlMementoSerializer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/persister/XmlMementoSerializer.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/persister/XmlMementoSerializer.java deleted file mode 100644 index 6133958..0000000 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/persister/XmlMementoSerializer.java +++ /dev/null @@ -1,505 +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.mgmt.rebind.persister; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.io.IOException; -import java.io.Writer; -import java.util.NoSuchElementException; -import java.util.Stack; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicReference; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.apache.brooklyn.api.catalog.CatalogItem; -import org.apache.brooklyn.api.effector.Effector; -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec; -import org.apache.brooklyn.api.location.Location; -import org.apache.brooklyn.api.mgmt.ManagementContext; -import org.apache.brooklyn.api.mgmt.Task; -import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; -import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister.LookupContext; -import org.apache.brooklyn.api.objs.Identifiable; -import org.apache.brooklyn.api.policy.Policy; -import org.apache.brooklyn.api.sensor.Enricher; -import org.apache.brooklyn.api.sensor.Feed; -import org.apache.brooklyn.core.catalog.internal.CatalogBundleDto; -import org.apache.brooklyn.core.catalog.internal.CatalogUtils; -import org.apache.brooklyn.core.config.BasicConfigKey; -import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContextSequential; -import org.apache.brooklyn.core.mgmt.classloading.ClassLoaderFromBrooklynClassLoadingContext; -import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext; -import org.apache.brooklyn.core.mgmt.rebind.dto.BasicCatalogItemMemento; -import org.apache.brooklyn.core.mgmt.rebind.dto.BasicEnricherMemento; -import org.apache.brooklyn.core.mgmt.rebind.dto.BasicEntityMemento; -import org.apache.brooklyn.core.mgmt.rebind.dto.BasicFeedMemento; -import org.apache.brooklyn.core.mgmt.rebind.dto.BasicLocationMemento; -import org.apache.brooklyn.core.mgmt.rebind.dto.BasicPolicyMemento; -import org.apache.brooklyn.core.mgmt.rebind.dto.MutableBrooklynMemento; -import org.apache.brooklyn.effector.core.BasicParameterType; -import org.apache.brooklyn.effector.core.EffectorAndBody; -import org.apache.brooklyn.effector.core.EffectorTasks.EffectorBodyTaskFactory; -import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory; -import org.apache.brooklyn.sensor.core.BasicAttributeSensor; -import org.apache.brooklyn.util.core.xstream.XmlSerializer; -import org.apache.brooklyn.util.exceptions.Exceptions; -import org.apache.brooklyn.util.text.Strings; - -import com.thoughtworks.xstream.converters.Converter; -import com.thoughtworks.xstream.converters.MarshallingContext; -import com.thoughtworks.xstream.converters.SingleValueConverter; -import com.thoughtworks.xstream.converters.UnmarshallingContext; -import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; -import com.thoughtworks.xstream.core.ReferencingMarshallingContext; -import com.thoughtworks.xstream.core.util.HierarchicalStreams; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.io.path.PathTrackingReader; -import com.thoughtworks.xstream.mapper.Mapper; -import com.thoughtworks.xstream.mapper.MapperWrapper; - -/* uses xml, cleaned up a bit - * - * there is an early attempt at doing this with JSON in pull request #344 but - * it is not nicely deserializable, see comments at http://xstream.codehaus.org/json-tutorial.html */ -public class XmlMementoSerializer<T> extends XmlSerializer<T> implements MementoSerializer<T> { - - private static final Logger LOG = LoggerFactory.getLogger(XmlMementoSerializer.class); - - private final ClassLoader classLoader; - private LookupContext lookupContext; - - public XmlMementoSerializer(ClassLoader classLoader) { - this.classLoader = checkNotNull(classLoader, "classLoader"); - xstream.setClassLoader(this.classLoader); - - // old (deprecated in 070? or earlier) single-file persistence uses this keyword; TODO remove soon in 080 ? - xstream.alias("brooklyn", MutableBrooklynMemento.class); - - xstream.alias("entity", BasicEntityMemento.class); - xstream.alias("location", BasicLocationMemento.class); - xstream.alias("policy", BasicPolicyMemento.class); - xstream.alias("feed", BasicFeedMemento.class); - xstream.alias("enricher", BasicEnricherMemento.class); - xstream.alias("configKey", BasicConfigKey.class); - xstream.alias("catalogItem", BasicCatalogItemMemento.class); - xstream.alias("bundle", CatalogBundleDto.class); - xstream.alias("attributeSensor", BasicAttributeSensor.class); - - xstream.alias("effector", Effector.class); - xstream.addDefaultImplementation(EffectorAndBody.class, Effector.class); - xstream.alias("parameter", BasicParameterType.class); - xstream.addDefaultImplementation(EffectorBodyTaskFactory.class, EffectorTaskFactory.class); - - xstream.alias("entityRef", Entity.class); - xstream.alias("locationRef", Location.class); - xstream.alias("policyRef", Policy.class); - xstream.alias("enricherRef", Enricher.class); - - xstream.registerConverter(new LocationConverter()); - xstream.registerConverter(new PolicyConverter()); - xstream.registerConverter(new EnricherConverter()); - xstream.registerConverter(new EntityConverter()); - xstream.registerConverter(new FeedConverter()); - xstream.registerConverter(new CatalogItemConverter()); - xstream.registerConverter(new SpecConverter()); - - xstream.registerConverter(new ManagementContextConverter()); - xstream.registerConverter(new TaskConverter(xstream.getMapper())); - - //For compatibility with existing persistence stores content. - xstream.aliasField("registeredTypeName", BasicCatalogItemMemento.class, "symbolicName"); - xstream.registerLocalConverter(BasicCatalogItemMemento.class, "libraries", new CatalogItemLibrariesConverter()); - } - - // Warning: this is called in the super-class constuctor, so before this constructor! - @Override - protected MapperWrapper wrapMapper(MapperWrapper next) { - MapperWrapper mapper = super.wrapMapper(next); - mapper = new CustomMapper(mapper, Entity.class, "entityProxy"); - mapper = new CustomMapper(mapper, Location.class, "locationProxy"); - return mapper; - } - - @Override - public void serialize(Object object, Writer writer) { - super.serialize(object, writer); - try { - writer.append("\n"); - } catch (IOException e) { - throw Exceptions.propagate(e); - } - } - - @Override - public void setLookupContext(LookupContext lookupContext) { - this.lookupContext = checkNotNull(lookupContext, "lookupContext"); - } - - @Override - public void unsetLookupContext() { - this.lookupContext = null; - } - - /** - * For changing the tag used for anything that implements/extends the given type. - * Necessary for using EntityRef rather than the default "dynamic-proxy" tag. - * - * @author aled - */ - public class CustomMapper extends MapperWrapper { - private final Class<?> clazz; - private final String alias; - - public CustomMapper(Mapper wrapped, Class<?> clazz, String alias) { - super(wrapped); - this.clazz = checkNotNull(clazz, "clazz"); - this.alias = checkNotNull(alias, "alias"); - } - - public String getAlias() { - return alias; - } - - @Override - public String serializedClass(@SuppressWarnings("rawtypes") Class type) { - if (type != null && clazz.isAssignableFrom(type)) { - return alias; - } else { - return super.serializedClass(type); - } - } - - @Override - public Class<?> realClass(String elementName) { - if (elementName.equals(alias)) { - return clazz; - } else { - return super.realClass(elementName); - } - } - } - - public abstract class IdentifiableConverter<IT extends Identifiable> implements SingleValueConverter { - private final Class<IT> clazz; - - IdentifiableConverter(Class<IT> clazz) { - this.clazz = clazz; - } - @Override - public boolean canConvert(@SuppressWarnings("rawtypes") Class type) { - boolean result = clazz.isAssignableFrom(type); - return result; - } - - @Override - public String toString(Object obj) { - return obj == null ? null : ((Identifiable)obj).getId(); - } - @Override - public Object fromString(String str) { - if (lookupContext == null) { - LOG.warn("Cannot unmarshal from persisted xml {} {}; no lookup context supplied!", clazz.getSimpleName(), str); - return null; - } else { - return lookup(str); - } - } - - protected abstract IT lookup(String id); - } - - public class LocationConverter extends IdentifiableConverter<Location> { - LocationConverter() { - super(Location.class); - } - @Override - protected Location lookup(String id) { - return lookupContext.lookupLocation(id); - } - } - - public class PolicyConverter extends IdentifiableConverter<Policy> { - PolicyConverter() { - super(Policy.class); - } - @Override - protected Policy lookup(String id) { - return lookupContext.lookupPolicy(id); - } - } - - public class EnricherConverter extends IdentifiableConverter<Enricher> { - EnricherConverter() { - super(Enricher.class); - } - @Override - protected Enricher lookup(String id) { - return lookupContext.lookupEnricher(id); - } - } - - public class FeedConverter extends IdentifiableConverter<Feed> { - FeedConverter() { - super(Feed.class); - } - @Override - protected Feed lookup(String id) { - return lookupContext.lookupFeed(id); - } - } - - public class EntityConverter extends IdentifiableConverter<Entity> { - EntityConverter() { - super(Entity.class); - } - @Override - protected Entity lookup(String id) { - return lookupContext.lookupEntity(id); - } - } - - @SuppressWarnings("rawtypes") - public class CatalogItemConverter extends IdentifiableConverter<CatalogItem> { - CatalogItemConverter() { - super(CatalogItem.class); - } - @Override - protected CatalogItem<?,?> lookup(String id) { - return lookupContext.lookupCatalogItem(id); - } - } - - - static boolean loggedTaskWarning = false; - public class TaskConverter implements Converter { - private final Mapper mapper; - - TaskConverter(Mapper mapper) { - this.mapper = mapper; - } - @Override - public boolean canConvert(@SuppressWarnings("rawtypes") Class type) { - return Task.class.isAssignableFrom(type); - } - @SuppressWarnings("deprecation") - @Override - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - if (source == null) return; - if (((Task<?>)source).isDone() && !((Task<?>)source).isError()) { - try { - context.convertAnother(((Task<?>)source).get()); - } catch (InterruptedException e) { - throw Exceptions.propagate(e); - } catch (ExecutionException e) { - LOG.warn("Unexpected exception getting done (and non-error) task result for "+source+"; continuing: "+e, e); - } - } else { - // TODO How to log sensibly, without it logging this every second?! - // jun 2014, have added a "log once" which is not ideal but better than the log never behaviour - if (!loggedTaskWarning) { - LOG.warn("Intercepting and skipping request to serialize a Task" - + (context instanceof ReferencingMarshallingContext ? " at "+((ReferencingMarshallingContext)context).currentPath() : "")+ - " (only logging this once): "+source); - loggedTaskWarning = true; - } - - return; - } - } - @Override - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - if (reader.hasMoreChildren()) { - Class<?> type = HierarchicalStreams.readClassType(reader, mapper); - reader.moveDown(); - Object result = context.convertAnother(null, type); - reader.moveUp(); - return result; - } else { - return null; - } - } - } - - public class ManagementContextConverter implements Converter { - @Override - public boolean canConvert(@SuppressWarnings("rawtypes") Class type) { - return ManagementContext.class.isAssignableFrom(type); - } - @Override - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - // write nothing, and always insert the current mgmt context - } - @Override - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - return lookupContext.lookupManagementContext(); - } - } - - /** When reading/writing specs, it checks whether there is a catalog item id set and uses it to load */ - public class SpecConverter extends ReflectionConverter { - SpecConverter() { - super(xstream.getMapper(), xstream.getReflectionProvider()); - } - @Override - public boolean canConvert(@SuppressWarnings("rawtypes") Class type) { - return AbstractBrooklynObjectSpec.class.isAssignableFrom(type); - } - @Override - public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { - if (source == null) return; - AbstractBrooklynObjectSpec<?, ?> spec = (AbstractBrooklynObjectSpec<?, ?>) source; - String catalogItemId = spec.getCatalogItemId(); - if (Strings.isNonBlank(catalogItemId)) { - // write this field first, so we can peek at it when we read - writer.startNode("catalogItemId"); - writer.setValue(catalogItemId); - writer.endNode(); - - // we're going to write the catalogItemId field twice :( but that's okay. - // better solution would be to have mark/reset on reader so we can peek for such a field; - // see comment below - super.marshal(source, writer, context); - } else { - super.marshal(source, writer, context); - } - } - @Override - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - String catalogItemId = null; - instantiateNewInstanceSettingCache(reader, context); - - if (reader instanceof PathTrackingReader) { - // have to assume this is first; there is no mark/reset support on these readers - // (if there were then it would be easier, we could just look for that child anywhere, - // and not need a custom writer!) - if ("catalogItemId".equals( ((PathTrackingReader)reader).peekNextChild() )) { - // cache the instance - - reader.moveDown(); - catalogItemId = reader.getValue(); - reader.moveUp(); - } - } - boolean customLoaderSet = false; - try { - if (Strings.isNonBlank(catalogItemId)) { - if (lookupContext==null) throw new NullPointerException("lookupContext required to load catalog item "+catalogItemId); - CatalogItem<?, ?> cat = CatalogUtils.getCatalogItemOptionalVersion(lookupContext.lookupManagementContext(), catalogItemId); - if (cat==null) throw new NoSuchElementException("catalog item: "+catalogItemId); - BrooklynClassLoadingContext clcNew = CatalogUtils.newClassLoadingContext(lookupContext.lookupManagementContext(), cat); - pushXstreamCustomClassLoader(clcNew); - customLoaderSet = true; - } - - AbstractBrooklynObjectSpec<?, ?> result = (AbstractBrooklynObjectSpec<?, ?>) super.unmarshal(reader, context); - // we wrote it twice so this shouldn't be necessary; but if we fix it so we only write once, we'd need this - result.catalogItemId(catalogItemId); - return result; - } finally { - instance = null; - if (customLoaderSet) { - popXstreamCustomClassLoader(); - } - } - } - - Object instance; - - @Override - protected Object instantiateNewInstance(HierarchicalStreamReader reader, UnmarshallingContext context) { - // the super calls getAttribute which requires that we have not yet done moveDown, - // so we do this earlier and cache it for when we call super.unmarshal - if (instance==null) - throw new IllegalStateException("Instance should be created and cached"); - return instance; - } - protected void instantiateNewInstanceSettingCache(HierarchicalStreamReader reader, UnmarshallingContext context) { - instance = super.instantiateNewInstance(reader, context); - } - } - - Stack<BrooklynClassLoadingContext> contexts = new Stack<BrooklynClassLoadingContext>(); - Stack<ClassLoader> cls = new Stack<ClassLoader>(); - AtomicReference<Thread> xstreamLockOwner = new AtomicReference<Thread>(); - int lockCount; - - /** Must be accompanied by a corresponding {@link #popXstreamCustomClassLoader()} when finished. */ - @SuppressWarnings("deprecation") - protected void pushXstreamCustomClassLoader(BrooklynClassLoadingContext clcNew) { - acquireXstreamLock(); - BrooklynClassLoadingContext oldClc; - if (!contexts.isEmpty()) { - oldClc = contexts.peek(); - } else { - // TODO XmlMementoSerializer should take a BCLC instead of a CL - oldClc = JavaBrooklynClassLoadingContext.create(lookupContext.lookupManagementContext(), xstream.getClassLoader()); - } - BrooklynClassLoadingContextSequential clcMerged = new BrooklynClassLoadingContextSequential(lookupContext.lookupManagementContext(), - oldClc, clcNew); - contexts.push(clcMerged); - cls.push(xstream.getClassLoader()); - ClassLoader newCL = ClassLoaderFromBrooklynClassLoadingContext.of(clcMerged); - xstream.setClassLoader(newCL); - } - - protected void popXstreamCustomClassLoader() { - synchronized (xstreamLockOwner) { - releaseXstreamLock(); - xstream.setClassLoader(cls.pop()); - contexts.pop(); - } - } - - protected void acquireXstreamLock() { - synchronized (xstreamLockOwner) { - while (true) { - if (xstreamLockOwner.compareAndSet(null, Thread.currentThread()) || - Thread.currentThread().equals( xstreamLockOwner.get() )) { - break; - } - try { - xstreamLockOwner.wait(1000); - } catch (InterruptedException e) { - throw Exceptions.propagate(e); - } - } - lockCount++; - } - } - - protected void releaseXstreamLock() { - synchronized (xstreamLockOwner) { - if (lockCount<=0) { - throw new IllegalStateException("xstream not locked"); - } - if (--lockCount == 0) { - if (!xstreamLockOwner.compareAndSet(Thread.currentThread(), null)) { - Thread oldOwner = xstreamLockOwner.getAndSet(null); - throw new IllegalStateException("xstream was locked by "+oldOwner+" but unlock attempt by "+Thread.currentThread()); - } - xstreamLockOwner.notifyAll(); - } - } - } - -}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/plane/dto/BasicManagementNodeSyncRecord.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/plane/dto/BasicManagementNodeSyncRecord.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/plane/dto/BasicManagementNodeSyncRecord.java deleted file mode 100644 index d492260..0000000 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/plane/dto/BasicManagementNodeSyncRecord.java +++ /dev/null @@ -1,194 +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.mgmt.rebind.plane.dto; - -import java.io.Serializable; -import java.net.URI; - -import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState; -import org.apache.brooklyn.api.mgmt.ha.ManagementNodeSyncRecord; -import org.apache.brooklyn.core.BrooklynVersion; -import org.apache.brooklyn.util.time.Time; -import org.codehaus.jackson.annotate.JsonAutoDetect; -import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; - -import com.google.common.base.Objects; - -/** - * Represents the state of a management node within the Brooklyn management plane - * (DTO class). - * - * @author aled - */ -@JsonAutoDetect(fieldVisibility=Visibility.ANY, getterVisibility=Visibility.NONE) -public class BasicManagementNodeSyncRecord implements ManagementNodeSyncRecord, Serializable { - - private static final long serialVersionUID = 4918161834047884244L; - - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - private String brooklynVersion = BrooklynVersion.get(); - protected String nodeId; - protected URI uri; - protected ManagementNodeState status; - protected Long priority; - protected long localTimestamp; - protected Long remoteTimestamp; - - protected Builder self() { - return (Builder) this; - } - public Builder brooklynVersion(String val) { - brooklynVersion = val; return self(); - } - public Builder nodeId(String val) { - nodeId = val; return self(); - } - public Builder uri(URI val) { - uri = val; return self(); - } - public Builder status(ManagementNodeState val) { - status = val; return self(); - } - public Builder priority(Long val) { - priority = val; return self(); - } - public Builder localTimestamp(long val) { - localTimestamp = val; return self(); - } - public Builder remoteTimestamp(Long val) { - remoteTimestamp = val; return self(); - } - public Builder from(ManagementNodeSyncRecord other) { - return from(other, false); - } - public Builder from(ManagementNodeSyncRecord other, boolean ignoreNulls) { - if (ignoreNulls && other==null) return this; - if (other.getBrooklynVersion()!=null) brooklynVersion = other.getBrooklynVersion(); - if (other.getNodeId()!=null) nodeId = other.getNodeId(); - if (other.getUri()!=null) uri = other.getUri(); - if (other.getStatus()!=null) status = other.getStatus(); - if (other.getPriority()!=null) priority = other.getPriority(); - if (other.getLocalTimestamp()>0) localTimestamp = other.getLocalTimestamp(); - if (other.getRemoteTimestamp()!=null) remoteTimestamp = other.getRemoteTimestamp(); - return this; - } - public ManagementNodeSyncRecord build() { - return new BasicManagementNodeSyncRecord(this); - } - } - - private String brooklynVersion; - private String nodeId; - private URI uri; - private ManagementNodeState status; - private Long priority; - private Long localTimestamp; - private Long remoteTimestamp; - - /** @deprecated since 0.7.0, use {@link #localTimestamp} or {@link #remoteTimestamp}, - * but kept (or rather added back in) to support deserializing previous instances */ - @Deprecated - private Long timestampUtc; - - - // for de-serialization - @SuppressWarnings("unused") - private BasicManagementNodeSyncRecord() { - } - - // Trusts the builder to not mess around with mutability concurrently with build(). - protected BasicManagementNodeSyncRecord(Builder builder) { - brooklynVersion = builder.brooklynVersion; - nodeId = builder.nodeId; - uri = builder.uri; - status = builder.status; - priority = builder.priority; - localTimestamp = builder.localTimestamp; - remoteTimestamp = builder.remoteTimestamp; - } - - @Override - public String getBrooklynVersion() { - return brooklynVersion; - } - - @Override - public String getNodeId() { - return nodeId; - } - - @Override - public URI getUri() { - return uri; - } - - @Override - public ManagementNodeState getStatus() { - return status; - } - - @Override - public Long getPriority() { - return priority; - } - - @Override - public long getLocalTimestamp() { - if (localTimestamp!=null) return localTimestamp; - if (timestampUtc!=null) return timestampUtc; - throw new NullPointerException("localTimestamp not known for "+getNodeId()); - } - - @Override - public Long getRemoteTimestamp() { - return remoteTimestamp; - } - - @Override - public String toString() { - return Objects.toStringHelper(this) - .add("nodeId", getNodeId()) - .add("status", getStatus()).toString(); - } - - @Override - public String toVerboseString() { - return Objects.toStringHelper(this) - .omitNullValues() - .add("brooklynVersion", getBrooklynVersion()) - .add("nodeId", getNodeId()) - .add("uri", getUri()) - .add("status", getStatus()) - .add("priority", getPriority()) - .add("localTimestamp", getLocalTimestamp()+"="+Time.makeDateString(getLocalTimestamp())) - .add("remoteTimestamp", getRemoteTimestamp()+(getRemoteTimestamp()==null ? "" : - "="+Time.makeDateString(getRemoteTimestamp()))) - .toString(); - } - - /** used here for store to inject remote timestamp */ - public void setRemoteTimestamp(Long remoteTimestamp) { - this.remoteTimestamp = remoteTimestamp; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/plane/dto/ManagementPlaneSyncRecordImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/plane/dto/ManagementPlaneSyncRecordImpl.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/plane/dto/ManagementPlaneSyncRecordImpl.java deleted file mode 100644 index fc09365..0000000 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/plane/dto/ManagementPlaneSyncRecordImpl.java +++ /dev/null @@ -1,99 +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.mgmt.rebind.plane.dto; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import java.io.Serializable; -import java.util.Map; - -import org.apache.brooklyn.api.mgmt.ha.ManagementNodeSyncRecord; -import org.apache.brooklyn.api.mgmt.ha.ManagementPlaneSyncRecord; -import org.apache.brooklyn.util.collections.MutableMap; - -import com.google.common.base.Objects; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; - -public class ManagementPlaneSyncRecordImpl implements ManagementPlaneSyncRecord, Serializable { - - private static final long serialVersionUID = -4207907303446336973L; - - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - protected String masterNodeId; - protected final Map<String,ManagementNodeSyncRecord> nodes = MutableMap.of(); - - public Builder masterNodeId(String val) { - masterNodeId = val; return this; - } - public Builder nodes(Iterable<ManagementNodeSyncRecord> vals) { - checkState(!Iterables.contains(checkNotNull(vals, "nodes must not be null"), null), "nodes must not contain null: %s", vals); - for (ManagementNodeSyncRecord val: vals) nodes.put(val.getNodeId(), val); - return this; - } - public Builder node(ManagementNodeSyncRecord val) { - checkNotNull(val, "node must not be null"); - nodes.put(val.getNodeId(), val); - return this; - } - public ManagementPlaneSyncRecord build() { - return new ManagementPlaneSyncRecordImpl(this); - } - } - - private String masterNodeId; - private Map<String, ManagementNodeSyncRecord> managementNodes; - - private ManagementPlaneSyncRecordImpl(Builder builder) { - masterNodeId = builder.masterNodeId; - managementNodes = Maps.newLinkedHashMap(); - for (ManagementNodeSyncRecord node : builder.nodes.values()) { - checkState(!managementNodes.containsKey(node.getNodeId()), "duplicate nodeId %s", node.getNodeId()); - managementNodes.put(node.getNodeId(), node); - } - } - - @Override - public String getMasterNodeId() { - return masterNodeId; - } - - @Override - public Map<String, ManagementNodeSyncRecord> getManagementNodes() { - return managementNodes; - } - - @Override - public String toString() { - return Objects.toStringHelper(this) - .add("masterNodeId", masterNodeId) - .add("nodes", managementNodes.keySet()) - .toString(); - } - - @Override - public String toVerboseString() { - return toString(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformer.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformer.java index 1e547ee..74b1375 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformer.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformer.java @@ -26,7 +26,7 @@ import java.util.Map; import org.apache.brooklyn.api.mgmt.rebind.RebindExceptionHandler; import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoRawData; import org.apache.brooklyn.api.objs.BrooklynObjectType; -import org.apache.brooklyn.core.mgmt.rebind.persister.BrooklynMementoPersisterToObjectStore; +import org.apache.brooklyn.core.mgmt.persist.BrooklynMementoPersisterToObjectStore; import org.apache.brooklyn.core.mgmt.rebind.transformer.impl.XsltTransformer; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.core.ResourceUtils; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalLocationFactory.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalLocationFactory.java b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalLocationFactory.java index 02d058e..e66c8b3 100644 --- a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalLocationFactory.java +++ b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalLocationFactory.java @@ -28,8 +28,8 @@ import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.core.mgmt.internal.LocalLocationManager; import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; -import org.apache.brooklyn.location.basic.AbstractLocation; -import org.apache.brooklyn.location.basic.LocationInternal; +import org.apache.brooklyn.location.core.AbstractLocation; +import org.apache.brooklyn.location.core.internal.LocationInternal; import org.apache.brooklyn.util.core.config.ConfigBag; import org.apache.brooklyn.util.core.flags.FlagUtils; import org.apache.brooklyn.util.exceptions.Exceptions; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/effector/core/EffectorTasks.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/EffectorTasks.java b/core/src/main/java/org/apache/brooklyn/effector/core/EffectorTasks.java index 7a0881d..4f1b8d5 100644 --- a/core/src/main/java/org/apache/brooklyn/effector/core/EffectorTasks.java +++ b/core/src/main/java/org/apache/brooklyn/effector/core/EffectorTasks.java @@ -33,9 +33,9 @@ import org.apache.brooklyn.core.mgmt.BrooklynTaskTags; import org.apache.brooklyn.core.mgmt.internal.EffectorUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.brooklyn.location.basic.Machines; -import org.apache.brooklyn.location.basic.SshMachineLocation; -import org.apache.brooklyn.location.basic.WinRmMachineLocation; +import org.apache.brooklyn.location.core.Machines; +import org.apache.brooklyn.location.ssh.SshMachineLocation; +import org.apache.brooklyn.location.winrm.WinRmMachineLocation; import org.apache.brooklyn.util.core.config.ConfigBag; import org.apache.brooklyn.util.core.task.DynamicSequentialTask; import org.apache.brooklyn.util.core.task.DynamicTasks; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/entity/core/AbstractEntity.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/core/AbstractEntity.java b/core/src/main/java/org/apache/brooklyn/entity/core/AbstractEntity.java index a4447af..2814f32 100644 --- a/core/src/main/java/org/apache/brooklyn/entity/core/AbstractEntity.java +++ b/core/src/main/java/org/apache/brooklyn/entity/core/AbstractEntity.java @@ -75,7 +75,7 @@ import org.apache.brooklyn.entity.core.internal.EntityConfigMap; import org.apache.brooklyn.entity.lifecycle.PolicyDescriptor; import org.apache.brooklyn.entity.lifecycle.ServiceStateLogic; import org.apache.brooklyn.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic; -import org.apache.brooklyn.location.basic.Locations; +import org.apache.brooklyn.location.core.Locations; import org.apache.brooklyn.policy.core.AbstractPolicy; import org.apache.brooklyn.sensor.core.AttributeMap; import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/entity/core/Entities.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/core/Entities.java b/core/src/main/java/org/apache/brooklyn/entity/core/Entities.java index b9ea275..4e479f5 100644 --- a/core/src/main/java/org/apache/brooklyn/entity/core/Entities.java +++ b/core/src/main/java/org/apache/brooklyn/entity/core/Entities.java @@ -75,8 +75,8 @@ import org.apache.brooklyn.core.objs.proxy.EntityProxyImpl; import org.apache.brooklyn.effector.core.Effectors; import org.apache.brooklyn.entity.trait.Startable; import org.apache.brooklyn.entity.trait.StartableMethods; -import org.apache.brooklyn.location.basic.LocationInternal; -import org.apache.brooklyn.location.basic.Locations; +import org.apache.brooklyn.location.core.Locations; +import org.apache.brooklyn.location.core.internal.LocationInternal; import org.apache.brooklyn.sensor.core.DependentConfiguration; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.core.ResourceUtils; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/entity/core/EntitySuppliers.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/core/EntitySuppliers.java b/core/src/main/java/org/apache/brooklyn/entity/core/EntitySuppliers.java index 3c6ebea..7d5640c 100644 --- a/core/src/main/java/org/apache/brooklyn/entity/core/EntitySuppliers.java +++ b/core/src/main/java/org/apache/brooklyn/entity/core/EntitySuppliers.java @@ -19,8 +19,8 @@ package org.apache.brooklyn.entity.core; import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.location.basic.Machines; -import org.apache.brooklyn.location.basic.SshMachineLocation; +import org.apache.brooklyn.location.core.Machines; +import org.apache.brooklyn.location.ssh.SshMachineLocation; import com.google.common.base.Supplier; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/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 index b0791b2..0e54806 100644 --- a/core/src/main/java/org/apache/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java +++ b/core/src/main/java/org/apache/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java @@ -28,9 +28,9 @@ 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.basic.SshMachineLocation; import org.apache.brooklyn.location.paas.PaasLocation; -import org.apache.brooklyn.location.basic.WinRmMachineLocation; +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; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java index 69f3744..a348489 100644 --- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java +++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java @@ -52,8 +52,8 @@ import org.apache.brooklyn.entity.trait.Startable; import org.apache.brooklyn.entity.trait.StartableMethods; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.brooklyn.location.basic.Locations; import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension; +import org.apache.brooklyn.location.core.Locations; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.core.flags.TypeCoercions; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/entity/stock/BasicStartable.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/stock/BasicStartable.java b/core/src/main/java/org/apache/brooklyn/entity/stock/BasicStartable.java index 0d6c62e..432e045 100644 --- a/core/src/main/java/org/apache/brooklyn/entity/stock/BasicStartable.java +++ b/core/src/main/java/org/apache/brooklyn/entity/stock/BasicStartable.java @@ -26,7 +26,7 @@ import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.core.config.ConfigKeys; import org.apache.brooklyn.entity.trait.Startable; -import org.apache.brooklyn.location.basic.Locations; +import org.apache.brooklyn.location.core.Locations; import com.google.common.collect.ImmutableList; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/entity/stock/BasicStartableImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/entity/stock/BasicStartableImpl.java b/core/src/main/java/org/apache/brooklyn/entity/stock/BasicStartableImpl.java index 3ff4b21..1818262 100644 --- a/core/src/main/java/org/apache/brooklyn/entity/stock/BasicStartableImpl.java +++ b/core/src/main/java/org/apache/brooklyn/entity/stock/BasicStartableImpl.java @@ -33,7 +33,7 @@ import org.apache.brooklyn.entity.lifecycle.Lifecycle; import org.apache.brooklyn.entity.lifecycle.ServiceStateLogic; import org.apache.brooklyn.entity.trait.Startable; import org.apache.brooklyn.entity.trait.StartableMethods; -import org.apache.brooklyn.location.basic.Locations; +import org.apache.brooklyn.location.core.Locations; import org.apache.brooklyn.util.exceptions.Exceptions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java b/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java index 38e9fdd..941f557 100644 --- a/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java +++ b/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java @@ -28,9 +28,9 @@ import org.apache.brooklyn.core.config.BasicConfigKey; import org.apache.brooklyn.entity.core.Attributes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.brooklyn.location.basic.Machines; -import org.apache.brooklyn.location.basic.SshMachineLocation; -import org.apache.brooklyn.location.basic.SupportsPortForwarding; +import org.apache.brooklyn.location.core.Machines; +import org.apache.brooklyn.location.core.SupportsPortForwarding; +import org.apache.brooklyn.location.ssh.SshMachineLocation; import org.apache.brooklyn.util.core.task.DynamicTasks; import org.apache.brooklyn.util.core.task.Tasks; import org.apache.brooklyn.util.core.task.ssh.SshTasks; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java index 62b5c29..83be7f0 100644 --- a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java +++ b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java @@ -34,7 +34,7 @@ import org.apache.brooklyn.api.mgmt.rebind.RebindContext; import org.apache.brooklyn.api.mgmt.rebind.RebindSupport; import org.apache.brooklyn.api.mgmt.rebind.mementos.LocationMemento; import org.apache.brooklyn.core.mgmt.rebind.BasicLocationRebindSupport; -import org.apache.brooklyn.location.basic.AbstractLocation; +import org.apache.brooklyn.location.core.AbstractLocation; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.exceptions.Exceptions; import org.slf4j.Logger; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java index 1cc5318..525631c 100644 --- a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java +++ b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java @@ -23,12 +23,12 @@ import java.util.Map; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.api.location.LocationRegistry; import org.apache.brooklyn.api.location.LocationSpec; -import org.apache.brooklyn.location.basic.LocationConfigUtils; -import org.apache.brooklyn.location.basic.LocationInternal; -import org.apache.brooklyn.location.basic.LocationPredicates; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.brooklyn.location.basic.AbstractLocationResolver; +import org.apache.brooklyn.location.core.AbstractLocationResolver; +import org.apache.brooklyn.location.core.LocationConfigUtils; +import org.apache.brooklyn.location.core.LocationPredicates; +import org.apache.brooklyn.location.core.internal.LocationInternal; import org.apache.brooklyn.util.core.config.ConfigBag; import com.google.common.base.Optional; http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java deleted file mode 100644 index bab336a..0000000 --- a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java +++ /dev/null @@ -1,707 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.brooklyn.location.basic; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static org.apache.brooklyn.util.GroovyJavaMethods.elvis; -import static org.apache.brooklyn.util.JavaGroovyEquivalents.groovyTruth; - -import java.io.Closeable; -import java.util.Collection; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.brooklyn.api.location.Location; -import org.apache.brooklyn.api.location.LocationSpec; -import org.apache.brooklyn.api.mgmt.Task; -import org.apache.brooklyn.api.mgmt.rebind.RebindSupport; -import org.apache.brooklyn.api.mgmt.rebind.mementos.LocationMemento; -import org.apache.brooklyn.api.objs.Configurable; -import org.apache.brooklyn.config.ConfigInheritance; -import org.apache.brooklyn.config.ConfigKey; -import org.apache.brooklyn.config.ConfigKey.HasConfigKey; -import org.apache.brooklyn.core.config.BasicConfigKey; -import org.apache.brooklyn.core.config.ConfigKeys; -import org.apache.brooklyn.core.internal.BrooklynFeatureEnablement; -import org.apache.brooklyn.core.internal.storage.BrooklynStorage; -import org.apache.brooklyn.core.internal.storage.Reference; -import org.apache.brooklyn.core.internal.storage.impl.BasicReference; -import org.apache.brooklyn.core.mgmt.internal.LocalLocationManager; -import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; -import org.apache.brooklyn.core.mgmt.rebind.BasicLocationRebindSupport; -import org.apache.brooklyn.core.objs.AbstractBrooklynObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.apache.brooklyn.location.geo.HasHostGeoInfo; -import org.apache.brooklyn.location.geo.HostGeoInfo; -import org.apache.brooklyn.util.collections.SetFromLiveMap; -import org.apache.brooklyn.util.core.config.ConfigBag; -import org.apache.brooklyn.util.core.flags.FlagUtils; -import org.apache.brooklyn.util.core.flags.TypeCoercions; -import org.apache.brooklyn.util.guava.Maybe; -import org.apache.brooklyn.util.stream.Streams; - -import com.google.common.base.Objects; -import com.google.common.base.Objects.ToStringHelper; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.common.reflect.TypeToken; - -/** - * A basic implementation of the {@link Location} interface. - * - * This provides an implementation which works according to the requirements of - * the interface documentation, and is ready to be extended to make more specialized locations. - * - * Override {@link #configure(Map)} to add special initialization logic. - */ -public abstract class AbstractLocation extends AbstractBrooklynObject implements LocationInternal, HasHostGeoInfo, Configurable { - - private static final long serialVersionUID = -7495805474138619830L; - - /** @deprecated since 0.7.0 shouldn't be public */ - @Deprecated - public static final Logger LOG = LoggerFactory.getLogger(AbstractLocation.class); - - public static final ConfigKey<Location> PARENT_LOCATION = new BasicConfigKey<Location>(Location.class, "parentLocation"); - - public static final ConfigKey<Boolean> TEMPORARY_LOCATION = ConfigKeys.newBooleanConfigKey("temporaryLocation", - "Indicates that the location is a temporary location that has been created to test connectivity, and that" + - "the location's events should not be recorded by usage listeners", false); - - private final AtomicBoolean configured = new AtomicBoolean(); - - private Reference<Long> creationTimeUtc = new BasicReference<Long>(System.currentTimeMillis()); - - // _not_ set from flag; configured explicitly in configure, because we also need to update the parent's list of children - private Reference<Location> parent = new BasicReference<Location>(); - - // NB: all accesses should be synchronized - private Set<Location> children = Sets.newLinkedHashSet(); - - private Reference<String> name = new BasicReference<String>(); - private boolean displayNameAutoGenerated = true; - - private Reference<HostGeoInfo> hostGeoInfo = new BasicReference<HostGeoInfo>(); - - private BasicConfigurationSupport config = new BasicConfigurationSupport(); - - private ConfigBag configBag = new ConfigBag(); - - private volatile boolean managed; - - private boolean inConstruction; - - private Reference<Map<Class<?>, Object>> extensions = new BasicReference<Map<Class<?>, Object>>(Maps.<Class<?>, Object>newConcurrentMap()); - - private final LocationDynamicType locationType; - - /** - * Construct a new instance of an AbstractLocation. - */ - public AbstractLocation() { - this(Maps.newLinkedHashMap()); - } - - /** - * Construct a new instance of an AbstractLocation. - * - * The properties map recognizes the following keys: - * <ul> - * <li>name - a name for the location - * <li>parentLocation - the parent {@link Location} - * </ul> - * - * Other common properties (retrieved via get/findLocationProperty) include: - * <ul> - * <li>latitude - * <li>longitude - * <li>displayName - * <li>iso3166 - list of iso3166-2 code strings - * <li>timeZone - * <li>abbreviatedName - * </ul> - */ - public AbstractLocation(Map<?,?> properties) { - super(properties); - inConstruction = true; - - // When one calls getConfig(key), we want to use the default value specified on *this* location - // if it overrides the default config, by using the type object - locationType = new LocationDynamicType(this); - - if (isLegacyConstruction()) { - AbstractBrooklynObject checkWeGetThis = configure(properties); - assert this.equals(checkWeGetThis) : this+" configure method does not return itself; returns "+checkWeGetThis+" instead of "+this; - - boolean deferConstructionChecks = (properties.containsKey("deferConstructionChecks") && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class)); - if (!deferConstructionChecks) { - FlagUtils.checkRequiredFields(this); - } - } - - inConstruction = false; - } - - protected void assertNotYetManaged() { - if (!inConstruction && Locations.isManaged(this)) { - LOG.warn("Configuration being made to {} after deployment; may not be supported in future versions", this); - } - //throw new IllegalStateException("Cannot set configuration "+key+" on active location "+this) - } - - public void setManagementContext(ManagementContextInternal managementContext) { - super.setManagementContext(managementContext); - if (displayNameAutoGenerated && getId() != null) name.set(getClass().getSimpleName()+":"+getId().substring(0, Math.min(getId().length(),4))); - - if (BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_USE_BROOKLYN_LIVE_OBJECTS_DATAGRID_STORAGE)) { - Location oldParent = parent.get(); - Set<Location> oldChildren = children; - Map<String, Object> oldConfig = configBag.getAllConfig(); - Long oldCreationTimeUtc = creationTimeUtc.get(); - String oldDisplayName = name.get(); - HostGeoInfo oldHostGeoInfo = hostGeoInfo.get(); - - parent = managementContext.getStorage().getReference(getId()+"-parent"); - children = SetFromLiveMap.create(managementContext.getStorage().<Location,Boolean>getMap(getId()+"-children")); - creationTimeUtc = managementContext.getStorage().getReference(getId()+"-creationTime"); - hostGeoInfo = managementContext.getStorage().getReference(getId()+"-hostGeoInfo"); - name = managementContext.getStorage().getReference(getId()+"-displayName"); - - // Only override stored defaults if we have actual values. We might be in setManagementContext - // because we are reconstituting an existing entity in a new brooklyn management-node (in which - // case believe what is already in the storage), or we might be in the middle of creating a new - // entity. Normally for a new entity (using EntitySpec creation approach), this will get called - // before setting the parent etc. However, for backwards compatibility we still support some - // things calling the entity's constructor directly. - if (oldParent != null) parent.set(oldParent); - if (oldChildren.size() > 0) children.addAll(oldChildren); - if (creationTimeUtc.isNull()) creationTimeUtc.set(oldCreationTimeUtc); - if (hostGeoInfo.isNull()) hostGeoInfo.set(oldHostGeoInfo); - if (name.isNull()) { - name.set(oldDisplayName); - } else { - displayNameAutoGenerated = false; - } - - configBag = ConfigBag.newLiveInstance(managementContext.getStorage().<String,Object>getMap(getId()+"-config")); - if (oldConfig.size() > 0) { - configBag.putAll(oldConfig); - } - } - } - - /** - * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly; - * see overridden method for more info - */ - @SuppressWarnings("serial") - @Override - @Deprecated - public AbstractLocation configure(Map<?,?> properties) { - assertNotYetManaged(); - - boolean firstTime = !configured.getAndSet(true); - - configBag.putAll(properties); - - if (properties.containsKey(PARENT_LOCATION.getName())) { - // need to ensure parent's list of children is also updated - setParent(configBag.get(PARENT_LOCATION)); - - // don't include parentLocation in configBag, as breaks rebind - configBag.remove(PARENT_LOCATION); - } - - // NB: flag-setting done here must also be done in BasicLocationRebindSupport - FlagUtils.setFieldsFromFlagsWithBag(this, properties, configBag, firstTime); - FlagUtils.setAllConfigKeys(this, configBag, false); - - if (properties.containsKey("displayName")) { - name.set((String) removeIfPossible(properties, "displayName")); - displayNameAutoGenerated = false; - } else if (properties.containsKey("name")) { - name.set((String) removeIfPossible(properties, "name")); - displayNameAutoGenerated = false; - } else if (isLegacyConstruction()) { - name.set(getClass().getSimpleName()+":"+getId().substring(0, Math.min(getId().length(),4))); - displayNameAutoGenerated = true; - } - - // TODO Explicitly dealing with iso3166 here because want custom splitter rule comma-separated string. - // Is there a better way to do it (e.g. more similar to latitude, where configKey+TypeCoercion is enough)? - if (groovyTruth(properties.get("iso3166"))) { - Object rawCodes = removeIfPossible(properties, "iso3166"); - Set<String> codes; - if (rawCodes instanceof CharSequence) { - codes = ImmutableSet.copyOf(Splitter.on(",").trimResults().split((CharSequence)rawCodes)); - } else { - codes = TypeCoercions.coerce(rawCodes, new TypeToken<Set<String>>() {}); - } - configBag.put(LocationConfigKeys.ISO_3166, codes); - } - - return this; - } - - // TODO ensure no callers rely on 'remove' semantics, and don't remove; - // or perhaps better use a config bag so we know what is used v unused - private static Object removeIfPossible(Map<?,?> map, Object key) { - try { - return map.remove(key); - } catch (Exception e) { - return map.get(key); - } - } - - public boolean isManaged() { - return getManagementContext() != null && managed; - } - - public void onManagementStarted() { - if (displayNameAutoGenerated) name.set(getClass().getSimpleName()+":"+getId().substring(0, Math.min(getId().length(),4))); - this.managed = true; - } - - public void onManagementStopped() { - this.managed = false; - if (getManagementContext().isRunning()) { - BrooklynStorage storage = ((ManagementContextInternal)getManagementContext()).getStorage(); - storage.remove(getId()+"-parent"); - storage.remove(getId()+"-children"); - storage.remove(getId()+"-creationTime"); - storage.remove(getId()+"-hostGeoInfo"); - storage.remove(getId()+"-displayName"); - storage.remove(getId()+"-config"); - } - } - - @Override - public String getDisplayName() { - return name.get(); - } - - protected boolean isDisplayNameAutoGenerated() { - return displayNameAutoGenerated; - } - - @Override - public Location getParent() { - return parent.get(); - } - - @Override - public Collection<Location> getChildren() { - synchronized (children) { - return ImmutableList.copyOf(children); - } - } - - @Override - public void setParent(Location newParent) { - setParent(newParent, true); - } - - public void setParent(Location newParent, boolean updateChildListParents) { - if (newParent == this) { - throw new IllegalArgumentException("Location cannot be its own parent: "+this); - } - if (newParent == parent.get()) { - return; // no-op; already have desired parent - } - - if (parent.get() != null) { - Location oldParent = parent.get(); - parent.set(null); - if (updateChildListParents) - ((AbstractLocation)oldParent).removeChild(this); - } - // TODO Should we support a location changing parent? The resulting unmanage/manage might cause problems. - // The code above suggests we do, but maybe we should warn or throw error, or at least test it! - - parent.set(newParent); - if (newParent != null) { - if (updateChildListParents) - ((AbstractLocation)newParent).addChild(this); - } - - onChanged(); - } - - @Override - public ConfigurationSupportInternal config() { - return config ; - } - - private class BasicConfigurationSupport implements ConfigurationSupportInternal { - - @Override - public <T> T get(ConfigKey<T> key) { - if (hasConfig(key, false)) return getLocalBag().get(key); - if (getParent() != null && isInherited(key)) { - return getParent().getConfig(key); - } - - // In case this entity class has overridden the given key (e.g. to set default), then retrieve this entity's key - // TODO when locations become entities, the duplication of this compared to EntityConfigMap.getConfig will disappear. - @SuppressWarnings("unchecked") - ConfigKey<T> ownKey = (ConfigKey<T>) elvis(locationType.getConfigKey(key.getName()), key); - - return ownKey.getDefaultValue(); - } - - @Override - public <T> T get(HasConfigKey<T> key) { - return get(key.getConfigKey()); - } - - @Override - public <T> T set(ConfigKey<T> key, T val) { - T result = configBag.put(key, val); - onChanged(); - return result; - } - - @Override - public <T> T set(HasConfigKey<T> key, T val) { - return set(key.getConfigKey(), val); - } - - @Override - public <T> T set(ConfigKey<T> key, Task<T> val) { - // TODO Support for locations - throw new UnsupportedOperationException(); - } - - @Override - public <T> T set(HasConfigKey<T> key, Task<T> val) { - // TODO Support for locations - throw new UnsupportedOperationException(); - } - - @Override - public ConfigBag getBag() { - ConfigBag result = ConfigBag.newInstanceExtending(configBag, ImmutableMap.of()); - Location p = getParent(); - if (p!=null) result.putIfAbsent(((LocationInternal)p).config().getBag()); - return result; - } - - @Override - public ConfigBag getLocalBag() { - return configBag; - } - - @Override - public Maybe<Object> getRaw(ConfigKey<?> key) { - if (hasConfig(key, false)) return Maybe.of(getLocalBag().getStringKey(key.getName())); - if (getParent() != null && isInherited(key)) return ((LocationInternal)getParent()).config().getRaw(key); - return Maybe.absent(); - } - - @Override - public Maybe<Object> getRaw(HasConfigKey<?> key) { - return getRaw(key.getConfigKey()); - } - - @Override - public Maybe<Object> getLocalRaw(ConfigKey<?> key) { - if (hasConfig(key, false)) return Maybe.of(getLocalBag().getStringKey(key.getName())); - return Maybe.absent(); - } - - @Override - public Maybe<Object> getLocalRaw(HasConfigKey<?> key) { - return getLocalRaw(key.getConfigKey()); - } - - @Override - public void addToLocalBag(Map<String, ?> vals) { - configBag.putAll(vals); - } - - @Override - public void removeFromLocalBag(String key) { - configBag.remove(key); - } - - @Override - public void refreshInheritedConfig() { - // no-op for location - } - - @Override - public void refreshInheritedConfigOfChildren() { - // no-op for location - } - - private boolean hasConfig(ConfigKey<?> key, boolean includeInherited) { - if (includeInherited && isInherited(key)) { - return getBag().containsKey(key); - } else { - return getLocalBag().containsKey(key); - } - } - - private boolean isInherited(ConfigKey<?> key) { - ConfigInheritance inheritance = key.getInheritance(); - if (inheritance==null) inheritance = getDefaultInheritance(); - return inheritance.isInherited(key, getParent(), AbstractLocation.this); - } - - private ConfigInheritance getDefaultInheritance() { - return ConfigInheritance.ALWAYS; - } - } - - @Override - public <T> T getConfig(HasConfigKey<T> key) { - return config().get(key); - } - - @Override - public <T> T getConfig(ConfigKey<T> key) { - return config().get(key); - } - - @Override - @Deprecated - public boolean hasConfig(ConfigKey<?> key, boolean includeInherited) { - return config.hasConfig(key, includeInherited); - } - - @Override - @Deprecated - public Map<String,Object> getAllConfig(boolean includeInherited) { - // TODO Have no information about what to include/exclude inheritance wise. - // however few things use getAllConfigBag() - ConfigBag bag = (includeInherited ? config().getBag() : config().getLocalBag()); - return bag.getAllConfig(); - } - - @Override - @Deprecated - public ConfigBag getAllConfigBag() { - // TODO see comments in EntityConfigMap and on interface methods. - // here ConfigBag is used exclusively so - // we have no information about what to include/exclude inheritance wise. - // however few things use getAllConfigBag() - return config().getBag(); - } - - @Override - public ConfigBag getLocalConfigBag() { - return config().getLocalBag(); - } - - /** - * @deprecated since 0.7; use {@link #getLocalConfigBag()} - * @since 0.6 - */ - @Deprecated - public ConfigBag getRawLocalConfigBag() { - return config().getLocalBag(); - } - - @Override - @Deprecated - public <T> T setConfig(ConfigKey<T> key, T value) { - return config().set(key, value); - } - - /** - * @since 0.6.0 (?) - use getDisplayName - * @deprecated since 0.7.0; use {@link #getDisplayName()} - */ - @Deprecated - public void setName(String newName) { - setDisplayName(newName); - } - - public void setDisplayName(String newName) { - name.set(newName); - displayNameAutoGenerated = false; - onChanged(); - } - - @Override - public boolean equals(Object o) { - if (! (o instanceof Location)) { - return false; - } - - Location l = (Location) o; - return getId().equals(l.getId()); - } - - @Override - public int hashCode() { - return getId().hashCode(); - } - - @Override - public boolean containsLocation(Location potentialDescendent) { - Location loc = potentialDescendent; - while (loc != null) { - if (this == loc) return true; - loc = loc.getParent(); - } - return false; - } - - protected <T extends Location> T addChild(LocationSpec<T> spec) { - T child = getManagementContext().getLocationManager().createLocation(spec); - addChild(child); - return child; - } - - @SuppressWarnings("deprecation") - public void addChild(Location child) { - // Previously, setParent delegated to addChildLocation and we sometimes ended up with - // duplicate entries here. Instead this now uses a similar scheme to - // AbstractLocation.setParent/addChild (with any weaknesses for distribution that such a - // scheme might have...). - // - // We continue to use a list to allow identical-looking locations, but they must be different - // instances. - - synchronized (children) { - for (Location contender : children) { - if (contender == child) { - // don't re-add; no-op - return; - } - } - - children.add(child); - } - - if (isManaged()) { - if (!getManagementContext().getLocationManager().isManaged(child)) { - Locations.manage(child, getManagementContext()); - } - } else if (getManagementContext() != null) { - if (((LocalLocationManager)getManagementContext().getLocationManager()).getLocationEvenIfPreManaged(child.getId()) == null) { - ((ManagementContextInternal)getManagementContext()).prePreManage(child); - } - } - - children.add(child); - child.setParent(this); - - onChanged(); - } - - public boolean removeChild(Location child) { - boolean removed; - synchronized (children) { - removed = children.remove(child); - } - if (removed) { - if (child instanceof Closeable) { - Streams.closeQuietly((Closeable)child); - } - child.setParent(null); - - if (isManaged()) { - getManagementContext().getLocationManager().unmanage(child); - } - } - onChanged(); - return removed; - } - - protected void onChanged() { - // currently changes simply trigger re-persistence; there is no intermediate listener as we do for EntityChangeListener - if (isManaged()) { - getManagementContext().getRebindManager().getChangeListener().onChanged(this); - } - } - - /** Default String representation is simplified name of class, together with selected fields. */ - @Override - public String toString() { - return string().toString(); - } - - @Override - public String toVerboseString() { - return toString(); - } - - /** override this, adding to the returned value, to supply additional fields to include in the toString */ - protected ToStringHelper string() { - return Objects.toStringHelper(getClass()).add("id", getId()).add("name", name); - } - - @Override - public HostGeoInfo getHostGeoInfo() { return hostGeoInfo.get(); } - - public void setHostGeoInfo(HostGeoInfo hostGeoInfo) { - if (hostGeoInfo!=null) { - this.hostGeoInfo.set(hostGeoInfo); - setConfig(LocationConfigKeys.LATITUDE, hostGeoInfo.latitude); - setConfig(LocationConfigKeys.LONGITUDE, hostGeoInfo.longitude); - } - } - - @Override - public RebindSupport<LocationMemento> getRebindSupport() { - return new BasicLocationRebindSupport(this); - } - - @Override - public boolean hasExtension(Class<?> extensionType) { - return extensions.get().containsKey(checkNotNull(extensionType, "extensionType")); - } - - @Override - @SuppressWarnings("unchecked") - public <T> T getExtension(Class<T> extensionType) { - Object extension = extensions.get().get(checkNotNull(extensionType, "extensionType")); - if (extension == null) { - throw new IllegalArgumentException("No extension of type "+extensionType+" registered for location "+this); - } - return (T) extension; - } - - @Override - public <T> void addExtension(Class<T> extensionType, T extension) { - checkNotNull(extensionType, "extensionType"); - checkNotNull(extension, "extension"); - checkArgument(extensionType.isInstance(extension), "extension %s does not implement %s", extension, extensionType); - extensions.get().put(extensionType, extension); - } - - @Override - public Map<String, String> toMetadataRecord() { - ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); - if (getDisplayName() != null) builder.put("displayName", getDisplayName()); - if (getParent() != null && getParent().getDisplayName() != null) { - builder.put("parentDisplayName", getParent().getDisplayName()); - } - return builder.build(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a1ad34d7/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocationResolver.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocationResolver.java deleted file mode 100644 index 90a1861..0000000 --- a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocationResolver.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.brooklyn.location.basic; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.brooklyn.api.location.Location; -import org.apache.brooklyn.api.location.LocationRegistry; -import org.apache.brooklyn.api.location.LocationResolver; -import org.apache.brooklyn.api.location.LocationSpec; -import org.apache.brooklyn.api.mgmt.ManagementContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.apache.brooklyn.location.basic.AbstractLocationResolver.SpecParser.ParsedSpec; -import org.apache.brooklyn.util.collections.MutableMap; -import org.apache.brooklyn.util.core.config.ConfigBag; -import org.apache.brooklyn.util.text.KeyValueParser; - -import com.google.common.collect.ImmutableList; - -/** - * Examples of valid specs: - * <ul> - * <li>byon(hosts=myhost) - * <li>byon(hosts=myhost,myhost2) - * <li>byon(hosts="myhost, myhost2") - * <li>byon(hosts=myhost,myhost2, name=abc) - * <li>byon(hosts="myhost, myhost2", name="my location name") - * </ul> - * - * @author aled - */ -@SuppressWarnings({"unchecked","rawtypes"}) -public abstract class AbstractLocationResolver implements LocationResolver { - - public static final Logger log = LoggerFactory.getLogger(AbstractLocationResolver.class); - - protected volatile ManagementContext managementContext; - - protected volatile SpecParser specParser; - - protected abstract Class<? extends Location> getLocationType(); - - protected abstract SpecParser getSpecParser(); - - @Override - public void init(ManagementContext managementContext) { - this.managementContext = checkNotNull(managementContext, "managementContext"); - this.specParser = getSpecParser(); - } - - @Override - public boolean accepts(String spec, LocationRegistry registry) { - return BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true); - } - - @Override - public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) { - ConfigBag config = extractConfig(locationFlags, spec, registry); - Map globalProperties = registry.getProperties(); - String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName()); - - if (registry != null) { - LocationPropertiesFromBrooklynProperties.setLocalTempDir(globalProperties, config); - } - - return managementContext.getLocationManager().createLocation(LocationSpec.create(getLocationType()) - .configure(config.getAllConfig()) - .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation))); - } - - protected ConfigBag extractConfig(Map<?,?> locationFlags, String spec, LocationRegistry registry) { - Map globalProperties = registry.getProperties(); - ParsedSpec parsedSpec = specParser.parse(spec); - String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName()); - - // prefer args map over location flags - Map<String, Object> filteredProperties = getFilteredLocationProperties(getPrefix(), namedLocation, globalProperties); - ConfigBag flags = ConfigBag.newInstance(parsedSpec.argsMap).putIfAbsent(locationFlags).putIfAbsent(filteredProperties); - - return flags; - } - - protected Map<String, Object> getFilteredLocationProperties(String provider, String namedLocation, Map<String, ?> globalProperties) { - return new LocationPropertiesFromBrooklynProperties().getLocationProperties(getPrefix(), namedLocation, globalProperties); - } - - /** - * Parses a spec, by default of the general form "prefix:parts1:part2(arg1=val1,arg2=val2)" - */ - protected static class SpecParser { - - protected static class ParsedSpec { - public final String spec; - public final List<String> partsList; - public final Map<String,String> argsMap; - - ParsedSpec(String spec, List<String> partsList, Map<String,String> argsMap) { - this.spec = spec; - this.partsList = ImmutableList.copyOf(partsList); - this.argsMap = Collections.unmodifiableMap(MutableMap.copyOf(argsMap)); - } - } - - protected final String prefix; - protected final Pattern pattern; - private String exampleUsage; - - public SpecParser(String prefix) { - this.prefix = prefix; - pattern = Pattern.compile("("+prefix+"|"+prefix.toLowerCase()+"|"+prefix.toUpperCase()+")" + "(:)?" + "(\\((.*)\\))?$"); - } - - public SpecParser(String prefix, Pattern pattern) { - this.prefix = prefix; - this.pattern = pattern; - } - - public SpecParser setExampleUsage(String exampleUsage) { - this.exampleUsage = exampleUsage; - return this; - } - - protected String getUsage(String spec) { - if (exampleUsage == null) { - return "Spec should be in the form "+pattern; - } else { - return "for example, "+exampleUsage; - } - } - - protected void checkParsedSpec(ParsedSpec parsedSpec) { - // If someone tries "byon:(),byon:()" as a single spec, we get weird key-values! - for (String key : parsedSpec.argsMap.keySet()) { - if (key.contains(":") || key.contains("{") || key.contains("}") || key.contains("(") || key.contains(")")) { - throw new IllegalArgumentException("Invalid byon spec: "+parsedSpec.spec+" (key="+key+")"); - } - } - String name = parsedSpec.argsMap.get("name"); - if (parsedSpec.argsMap.containsKey("name") && (name == null || name.isEmpty())) { - throw new IllegalArgumentException("Invalid location '"+parsedSpec.spec+"'; if name supplied then value must be non-empty"); - } - String displayName = parsedSpec.argsMap.get("displayName"); - if (parsedSpec.argsMap.containsKey("displayName") && (displayName == null || displayName.isEmpty())) { - throw new IllegalArgumentException("Invalid location '"+parsedSpec.spec+"'; if displayName supplied then value must be non-empty"); - } - } - - public ParsedSpec parse(String spec) { - Matcher matcher = pattern.matcher(spec); - if (!matcher.matches()) { - throw new IllegalArgumentException("Invalid location '"+spec+"'; "+getUsage(spec)); - } - - String argsPart = matcher.group(3); - if (argsPart != null && argsPart.startsWith("(") && argsPart.endsWith(")")) { - // TODO Hacky; hosts("1.1.1.1") returns argsPart=("1.1.1.1") - argsPart = argsPart.substring(1, argsPart.length()-1); - } - Map<String, String> argsMap = KeyValueParser.parseMap(argsPart); - ParsedSpec result = new ParsedSpec(spec, ImmutableList.<String>of(), argsMap); - checkParsedSpec(result); - return result; - } - } -}
