http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/FeedConfig.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/FeedConfig.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/FeedConfig.java deleted file mode 100644 index b9662ef..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/FeedConfig.java +++ /dev/null @@ -1,307 +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.feed; - -import static com.google.common.base.Preconditions.checkNotNull; - -import org.apache.brooklyn.api.sensor.AttributeSensor; -import org.apache.brooklyn.core.entity.Entities; -import org.apache.brooklyn.core.sensor.Sensors; -import org.apache.brooklyn.feed.http.HttpPollConfig; -import org.apache.brooklyn.util.collections.MutableList; -import org.apache.brooklyn.util.guava.Functionals; -import org.apache.brooklyn.util.javalang.JavaClassNames; -import org.apache.brooklyn.util.text.Strings; - -import com.google.common.base.Function; -import com.google.common.base.Functions; -import com.google.common.base.Objects; -import com.google.common.base.Predicate; - -/** - * Configuration for a poll, or a subscription etc, that is being added to a feed. - * - * @author aled - */ -public class FeedConfig<V, T, F extends FeedConfig<V, T, F>> { - - /** The onSuccess or onError functions can return this value to indicate that the sensor should not change. - * @deprecated since 0.7.0 use UNCHANGED */ - public static final Object UNSET = Entities.UNCHANGED; - /** The onSuccess or onError functions can return this value to indicate that the sensor should not change. */ - public static final Object UNCHANGED = Entities.UNCHANGED; - /** The onSuccess or onError functions can return this value to indicate that the sensor value should be removed - * (cf 'null', but useful in dynamic situations) */ - public static final Object REMOVE = Entities.REMOVE; - - /** Indicates that no sensor is being used here. This sensor is suppressed, - * but is useful where you want to use the feeds with custom success/exception/failure functions - * which directly set multiple sensors, e.g. dynamically based on the poll response. - * <p> - * See {@link HttpPollConfig#forMultiple()} and its usages. - * (It can work for any poll config, but conveniences have not been supplied for others.) */ - public static final AttributeSensor<Void> NO_SENSOR = Sensors.newSensor(Void.class, "brooklyn.no.sensor"); - - private final AttributeSensor<T> sensor; - private Function<? super V, T> onsuccess; - private Function<? super V, T> onfailure; - private Function<? super Exception, T> onexception; - private Predicate<? super V> checkSuccess; - private boolean suppressDuplicates; - private boolean enabled = true; - - public FeedConfig(AttributeSensor<T> sensor) { - this.sensor = checkNotNull(sensor, "sensor"); - } - - public FeedConfig(FeedConfig<V, T, F> other) { - this.sensor = other.sensor; - this.onsuccess = other.onsuccess; - this.onfailure = other.onfailure; - this.onexception = other.onexception; - this.checkSuccess = other.checkSuccess; - this.suppressDuplicates = other.suppressDuplicates; - this.enabled = other.enabled; - } - - @SuppressWarnings("unchecked") - protected F self() { - return (F) this; - } - - public AttributeSensor<T> getSensor() { - return sensor; - } - - public Predicate<? super V> getCheckSuccess() { - return checkSuccess; - } - - public Function<? super V, T> getOnSuccess() { - return onsuccess; - } - - public Function<? super V, T> getOnFailure() { - return onfailure; - } - - public Function<? super Exception, T> getOnException() { - return onexception; - } - - public boolean getSupressDuplicates() { - return suppressDuplicates; - } - - public boolean isEnabled() { - return enabled; - } - - /** sets the predicate used to check whether a feed run is successful */ - public F checkSuccess(Predicate<? super V> val) { - this.checkSuccess = checkNotNull(val, "checkSuccess"); - return self(); - } - /** as {@link #checkSuccess(Predicate)} */ - public F checkSuccess(final Function<? super V,Boolean> val) { - return checkSuccess(Functionals.predicate(val)); - } - - @SuppressWarnings("unused") - /** @deprecated since 0.7.0, kept for rebind */ @Deprecated - private F checkSuccessLegacy(final Function<? super V,Boolean> val) { - return checkSuccess(new Predicate<V>() { - @Override - public boolean apply(V input) { - return val.apply(input); - } - }); - } - - public F onSuccess(Function<? super V,T> val) { - this.onsuccess = checkNotNull(val, "onSuccess"); - return self(); - } - - public F setOnSuccess(T val) { - return onSuccess(Functions.constant(val)); - } - - /** - * A failure is when the connection is fine (no exception) but the other end returns a result object V - * which the feed can tell indicates a failure (e.g. HTTP code 404) - */ - public F onFailure(Function<? super V,T> val) { - this.onfailure = checkNotNull(val, "onFailure"); - return self(); - } - - /** @see #onFailure(Function) */ - public F setOnFailure(T val) { - return onFailure(Functions.constant(val)); - } - - /** - * Registers a callback to be used by {@link #onSuccess(Function)} and {@link #onFailure(Function)}, - * i.e. whenever a result comes back, but not in case of exceptions being thrown (ie problems communicating) - */ - public F onResult(Function<? super V, T> val) { - onSuccess(val); - return onFailure(val); - } - - /** @see #onResult(Function) */ - public F setOnResult(T val) { - return onResult(Functions.constant(val)); - } - - /** - * An exception is when there is an error in the communication - */ - public F onException(Function<? super Exception,T> val) { - this.onexception = checkNotNull(val, "onException"); - return self(); - } - - /** @see #onException(Function) */ - public F setOnException(T val) { - return onException(Functions.constant(val)); - } - - /** - * A convenience for indicating a behaviour to occur for both {@link #onException(Function)} - * (error connecting) and {@link #onFailure(Function)} (successful communication but failure - * report from remote end) - */ - public F onFailureOrException(Function<Object,T> val) { - onFailure(val); - return onException(val); - } - - /** @see #onFailureOrException(Function) */ - public F setOnFailureOrException(T val) { - return onFailureOrException(Functions.constant(val)); - } - - public F suppressDuplicates(boolean val) { - suppressDuplicates = val; - return self(); - } - - /** - * Whether this feed is enabled (defaulting to true). - */ - public F enabled(boolean val) { - enabled = val; - return self(); - } - - public boolean hasSuccessHandler() { - return this.onsuccess != null; - } - - public boolean hasFailureHandler() { - return this.onfailure != null; - } - - public boolean hasExceptionHandler() { - return this.onexception != null; - } - - public boolean hasCheckSuccessHandler() { - return this.checkSuccess != null; - } - - @Override - public String toString() { - StringBuilder result = new StringBuilder(); - result.append(toStringBaseName()); - result.append("["); - boolean contents = false; - Object source = toStringPollSource(); - AttributeSensor<T> s = getSensor(); - if (Strings.isNonBlank(Strings.toString(source))) { - result.append(Strings.toUniqueString(source, 40)); - if (s!=null) { - result.append("->"); - result.append(s.getName()); - } - contents = true; - } else if (s!=null) { - result.append(s.getName()); - contents = true; - } - MutableList<Object> fields = toStringOtherFields(); - if (fields!=null) { - for (Object field: fields) { - if (Strings.isNonBlank(Strings.toString(field))) { - if (contents) result.append(";"); - contents = true; - result.append(field); - } - } - } - result.append("]"); - return result.toString(); - } - - /** can be overridden to supply a simpler base name than the class name */ - protected String toStringBaseName() { - return JavaClassNames.simpleClassName(this); - } - /** can be overridden to supply add'l info for the {@link #toString()}; subclasses can add to the returned value */ - protected MutableList<Object> toStringOtherFields() { - return MutableList.<Object>of(); - } - /** can be overridden to supply add'l info for the {@link #toString()}, placed before the sensor with -> */ - protected Object toStringPollSource() { - return null; - } - /** all configs should supply a unique tag element, inserted into the feed */ - protected String getUniqueTag() { - return toString(); - } - - /** returns fields which should be used for equality, including by default {@link #toStringOtherFields()} and {@link #toStringPollSource()}; - * subclasses can add to the returned value */ - protected MutableList<Object> equalsFields() { - MutableList<Object> result = MutableList.of().appendIfNotNull(getSensor()).appendIfNotNull(toStringPollSource()); - for (Object field: toStringOtherFields()) result.appendIfNotNull(field); - return result; - } - - @Override - public int hashCode() { - int hc = super.hashCode(); - for (Object f: equalsFields()) - hc = Objects.hashCode(hc, f); - return hc; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!super.equals(obj)) return false; - PollConfig<?,?,?> other = (PollConfig<?,?,?>) obj; - if (!Objects.equal(getUniqueTag(), other.getUniqueTag())) return false; - if (!Objects.equal(equalsFields(), other.equalsFields())) return false; - return true; - } - -}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/PollConfig.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/PollConfig.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/PollConfig.java deleted file mode 100644 index 133431b..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/PollConfig.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.core.feed; - -import static com.google.common.base.Preconditions.checkArgument; - -import java.util.concurrent.TimeUnit; - -import org.apache.brooklyn.api.sensor.AttributeSensor; -import org.apache.brooklyn.util.collections.MutableList; -import org.apache.brooklyn.util.time.Duration; - -/** - * Configuration for polling, which is being added to a feed (e.g. to poll a given URL over http). - * - * @author aled - */ -public class PollConfig<V, T, F extends PollConfig<V, T, F>> extends FeedConfig<V, T, F> { - - private long period = -1; - private String description; - - public PollConfig(AttributeSensor<T> sensor) { - super(sensor); - } - - public PollConfig(PollConfig<V,T,F> other) { - super(other); - this.period = other.period; - } - - public long getPeriod() { - return period; - } - - public F period(Duration val) { - checkArgument(val.toMilliseconds() >= 0, "period must be greater than or equal to zero"); - this.period = val.toMilliseconds(); - return self(); - } - - public F period(long val) { - checkArgument(val >= 0, "period must be greater than or equal to zero"); - this.period = val; return self(); - } - - public F period(long val, TimeUnit units) { - checkArgument(val >= 0, "period must be greater than or equal to zero"); - return period(units.toMillis(val)); - } - - public F description(String description) { - this.description = description; - return self(); - } - - public String getDescription() { - return description; - } - - @Override protected MutableList<Object> toStringOtherFields() { - return super.toStringOtherFields().appendIfNotNull(description); - } - - @Override - protected MutableList<Object> equalsFields() { - return super.equalsFields().appendIfNotNull(period); - } -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/PollHandler.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/PollHandler.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/PollHandler.java deleted file mode 100644 index a63ebde..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/PollHandler.java +++ /dev/null @@ -1,38 +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.feed; - -/** - * Notified by the Poller of the result for each job, on each poll. - * - * @author aled - */ -public interface PollHandler<V> { - - public boolean checkSuccess(V val); - - public void onSuccess(V val); - - public void onFailure(V val); - - public void onException(Exception exception); - - public String getDescription(); - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/Poller.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/Poller.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/Poller.java deleted file mode 100644 index a9a34d9..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/feed/Poller.java +++ /dev/null @@ -1,210 +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.feed; - -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Callable; - -import org.apache.brooklyn.api.entity.EntityLocal; -import org.apache.brooklyn.api.mgmt.Task; -import org.apache.brooklyn.core.entity.Attributes; -import org.apache.brooklyn.core.entity.Entities; -import org.apache.brooklyn.core.entity.EntityInternal; -import org.apache.brooklyn.core.mgmt.BrooklynTaskTags; -import org.apache.brooklyn.util.collections.MutableMap; -import org.apache.brooklyn.util.core.task.DynamicSequentialTask; -import org.apache.brooklyn.util.core.task.ScheduledTask; -import org.apache.brooklyn.util.core.task.TaskTags; -import org.apache.brooklyn.util.core.task.Tasks; -import org.apache.brooklyn.util.time.Duration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Objects; - - -/** - * For executing periodic polls. - * Jobs are added to the schedule, and then the poller is started. - * The jobs will then be executed periodically, and the handler called for the result/failure. - * - * Assumes the schedule+start will be done single threaded, and that stop will not be done concurrently. - */ -public class Poller<V> { - public static final Logger log = LoggerFactory.getLogger(Poller.class); - - private final EntityLocal entity; - private final boolean onlyIfServiceUp; - private final Set<Callable<?>> oneOffJobs = new LinkedHashSet<Callable<?>>(); - private final Set<PollJob<V>> pollJobs = new LinkedHashSet<PollJob<V>>(); - private final Set<Task<?>> oneOffTasks = new LinkedHashSet<Task<?>>(); - private final Set<ScheduledTask> tasks = new LinkedHashSet<ScheduledTask>(); - private volatile boolean started = false; - - private static class PollJob<V> { - final PollHandler<? super V> handler; - final Duration pollPeriod; - final Runnable wrappedJob; - private boolean loggedPreviousException = false; - - PollJob(final Callable<V> job, final PollHandler<? super V> handler, Duration period) { - this.handler = handler; - this.pollPeriod = period; - - wrappedJob = new Runnable() { - public void run() { - try { - V val = job.call(); - loggedPreviousException = false; - if (handler.checkSuccess(val)) { - handler.onSuccess(val); - } else { - handler.onFailure(val); - } - } catch (Exception e) { - if (loggedPreviousException) { - if (log.isTraceEnabled()) log.trace("PollJob for {}, repeated consecutive failures, handling {} using {}", new Object[] {job, e, handler}); - } else { - if (log.isDebugEnabled()) log.debug("PollJob for {} handling {} using {}", new Object[] {job, e, handler}); - loggedPreviousException = true; - } - handler.onException(e); - } - } - }; - } - } - - /** @deprecated since 0.7.0, pass in whether should run onlyIfServiceUp */ - @Deprecated - public Poller(EntityLocal entity) { - this(entity, false); - } - public Poller(EntityLocal entity, boolean onlyIfServiceUp) { - this.entity = entity; - this.onlyIfServiceUp = onlyIfServiceUp; - } - - /** Submits a one-off poll job; recommended that callers supply to-String so that task has a decent description */ - public void submit(Callable<?> job) { - if (started) { - throw new IllegalStateException("Cannot submit additional tasks after poller has started"); - } - oneOffJobs.add(job); - } - - public void scheduleAtFixedRate(Callable<V> job, PollHandler<? super V> handler, long period) { - scheduleAtFixedRate(job, handler, Duration.millis(period)); - } - public void scheduleAtFixedRate(Callable<V> job, PollHandler<? super V> handler, Duration period) { - if (started) { - throw new IllegalStateException("Cannot schedule additional tasks after poller has started"); - } - PollJob<V> foo = new PollJob<V>(job, handler, period); - pollJobs.add(foo); - } - - @SuppressWarnings({ "unchecked" }) - public void start() { - // TODO Previous incarnation of this logged this logged polledSensors.keySet(), but we don't know that anymore - // Is that ok, are can we do better? - - if (log.isDebugEnabled()) log.debug("Starting poll for {} (using {})", new Object[] {entity, this}); - if (started) { - throw new IllegalStateException(String.format("Attempt to start poller %s of entity %s when already running", - this, entity)); - } - - started = true; - - for (final Callable<?> oneOffJob : oneOffJobs) { - Task<?> task = Tasks.builder().dynamic(false).body((Callable<Object>) oneOffJob).displayName("Poll").description("One-time poll job "+oneOffJob).build(); - oneOffTasks.add(((EntityInternal)entity).getExecutionContext().submit(task)); - } - - for (final PollJob<V> pollJob : pollJobs) { - final String scheduleName = pollJob.handler.getDescription(); - if (pollJob.pollPeriod.compareTo(Duration.ZERO) > 0) { - Callable<Task<?>> pollingTaskFactory = new Callable<Task<?>>() { - public Task<?> call() { - DynamicSequentialTask<Void> task = new DynamicSequentialTask<Void>(MutableMap.of("displayName", scheduleName, "entity", entity), - new Callable<Void>() { public Void call() { - if (onlyIfServiceUp && !Boolean.TRUE.equals(entity.getAttribute(Attributes.SERVICE_UP))) { - return null; - } - pollJob.wrappedJob.run(); - return null; - } } ); - BrooklynTaskTags.setTransient(task); - return task; - } - }; - Map<String, ?> taskFlags = MutableMap.of("displayName", "scheduled:" + scheduleName); - ScheduledTask task = new ScheduledTask(taskFlags, pollingTaskFactory) - .period(pollJob.pollPeriod) - .cancelOnException(false); - tasks.add(Entities.submit(entity, task)); - } else { - if (log.isDebugEnabled()) log.debug("Activating poll (but leaving off, as period {}) for {} (using {})", new Object[] {pollJob.pollPeriod, entity, this}); - } - } - } - - public void stop() { - if (log.isDebugEnabled()) log.debug("Stopping poll for {} (using {})", new Object[] {entity, this}); - if (!started) { - throw new IllegalStateException(String.format("Attempt to stop poller %s of entity %s when not running", - this, entity)); - } - - started = false; - for (Task<?> task : oneOffTasks) { - if (task != null) task.cancel(true); - } - for (ScheduledTask task : tasks) { - if (task != null) task.cancel(); - } - oneOffTasks.clear(); - tasks.clear(); - } - - public boolean isRunning() { - boolean hasActiveTasks = false; - for (Task<?> task: tasks) { - if (task.isBegun() && !task.isDone()) { - hasActiveTasks = true; - break; - } - } - if (!started && hasActiveTasks) { - log.warn("Poller should not be running, but has active tasks, tasks: "+tasks); - } - return started && hasActiveTasks; - } - - protected boolean isEmpty() { - return pollJobs.isEmpty(); - } - - public String toString() { - return Objects.toStringHelper(this).add("entity", entity).toString(); - } -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/ApiObjectsFactoryImpl.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/ApiObjectsFactoryImpl.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/ApiObjectsFactoryImpl.java deleted file mode 100644 index 6957ebe..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/ApiObjectsFactoryImpl.java +++ /dev/null @@ -1,41 +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.internal; - -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.api.internal.ApiObjectsFactoryInterface; -import org.apache.brooklyn.api.mgmt.Task; -import org.apache.brooklyn.core.mgmt.BrooklynTaskTags; -import org.apache.brooklyn.util.core.task.Tasks; - -public class ApiObjectsFactoryImpl implements ApiObjectsFactoryInterface { - - @Override - public String getCatalogItemIdFromContext() { - Task<?> currentTask = Tasks.current(); - if (currentTask != null) { - Entity contextEntity = BrooklynTaskTags.getContextEntity(currentTask); - if (contextEntity != null) { - return contextEntity.getCatalogItemId(); - } - } - return null; - } - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynInitialization.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynInitialization.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynInitialization.java deleted file mode 100644 index 6dc825d..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynInitialization.java +++ /dev/null @@ -1,81 +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.internal; - -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.brooklyn.core.location.PortRanges; -import org.apache.brooklyn.util.core.crypto.SecureKeys; -import org.apache.brooklyn.util.core.flags.TypeCoercions; -import org.apache.brooklyn.util.net.Networking; - -import com.google.common.annotations.Beta; - -/** Various static initialization tasks are routed through this class, - * to give us better traceability of their invocation. */ -@Beta -public class BrooklynInitialization { - - private static AtomicBoolean done = new AtomicBoolean(false); - - public static void initTypeCoercionStandardAdapters() { - TypeCoercions.initStandardAdapters(); - } - - public static void initSecureKeysBouncyCastleProvider() { - SecureKeys.initBouncyCastleProvider(); - } - - public static void initNetworking() { - Networking.init(); - } - - public static void initPortRanges() { - PortRanges.init(); - } - - @SuppressWarnings("deprecation") - public static void initLegacyLanguageExtensions() { - org.apache.brooklyn.util.core.BrooklynLanguageExtensions.init(); - } - - /* other things: - * - * RendererHints - done by the entity classes which need them, including Sensors - * - */ - - public synchronized static void initAll() { - if (done.get()) return; - initTypeCoercionStandardAdapters(); - initSecureKeysBouncyCastleProvider(); - initNetworking(); - initPortRanges(); - initLegacyLanguageExtensions(); - done.set(true); - } - - @SuppressWarnings("deprecation") - public synchronized static void reinitAll() { - done.set(false); - org.apache.brooklyn.util.core.BrooklynLanguageExtensions.reinit(); - initAll(); - } - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynProperties.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynProperties.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynProperties.java deleted file mode 100644 index 75b7b34..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynProperties.java +++ /dev/null @@ -1,305 +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.internal; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.io.File; -import java.io.InputStream; -import java.net.URL; -import java.util.Map; - -import org.apache.brooklyn.config.ConfigKey; -import org.apache.brooklyn.config.ConfigKey.HasConfigKey; -import org.apache.brooklyn.config.StringConfigMap; -import org.apache.brooklyn.util.core.ResourceUtils; -import org.apache.brooklyn.util.core.config.ConfigBag; -import org.apache.brooklyn.util.guava.Maybe; -import org.apache.brooklyn.util.os.Os; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.annotations.Beta; -import com.google.common.base.Objects; -import com.google.common.base.Predicate; - -/** - * Utils for accessing command-line and system-env properties; - * doesn't resolve anything (unless an execution context is supplied) - * and treats ConfigKeys as of type object when in doubt, - * or string when that is likely wanted (e.g. {@link #getFirst(Map, String...)} - * <p> - * Intention for normal use is that they are set during startup and not modified - * thereafter. - */ -@SuppressWarnings("rawtypes") -public interface BrooklynProperties extends Map, StringConfigMap { - - public static class Factory { - private static final Logger LOG = LoggerFactory.getLogger(BrooklynProperties.Factory.class); - - /** creates a new empty {@link BrooklynProperties} */ - public static BrooklynProperties newEmpty() { - return new BrooklynPropertiesImpl(); - } - - /** creates a new {@link BrooklynProperties} with contents loaded - * from the usual places, including *.properties files and environment variables */ - public static BrooklynProperties newDefault() { - return new Builder(true).build(); - } - - public static Builder builderDefault() { - return new Builder(true); - } - - public static Builder builderEmpty() { - return new Builder(false); - } - - public static class Builder { - private String defaultLocationMetadataUrl; - private String globalLocationMetadataFile = null; - private String globalPropertiesFile = null; - private String localPropertiesFile = null; - private BrooklynProperties originalProperties = null; - - /** @deprecated since 0.7.0 use static methods in {@link Factory} to create */ - public Builder() { - this(true); - } - - private Builder(boolean setGlobalFileDefaults) { - resetDefaultLocationMetadataUrl(); - if (setGlobalFileDefaults) { - resetGlobalFiles(); - } - } - - public Builder resetDefaultLocationMetadataUrl() { - defaultLocationMetadataUrl = "classpath://brooklyn/location-metadata.properties"; - return this; - } - public Builder resetGlobalFiles() { - defaultLocationMetadataUrl = "classpath://brooklyn/location-metadata.properties"; - globalLocationMetadataFile = Os.mergePaths(Os.home(), ".brooklyn", "location-metadata.properties"); - globalPropertiesFile = Os.mergePaths(Os.home(), ".brooklyn", "brooklyn.properties"); - return this; - } - - /** - * Creates a Builder that when built, will return the BrooklynProperties passed to this constructor - */ - private Builder(BrooklynProperties originalProperties) { - this.originalProperties = new BrooklynPropertiesImpl().addFromMap(originalProperties); - } - - /** - * The URL of a default location-metadata.properties (for meta-data about different locations, such as iso3166 and global lat/lon). - * Defaults to classpath://brooklyn/location-metadata.properties - */ - public Builder defaultLocationMetadataUrl(String val) { - defaultLocationMetadataUrl = checkNotNull(val, "file"); - return this; - } - - /** - * The URL of a location-metadata.properties file that appends to and overwrites values in the locationMetadataUrl. - * Defaults to ~/.brooklyn/location-metadata.properties - */ - public Builder globalLocationMetadataFile(String val) { - globalLocationMetadataFile = checkNotNull(val, "file"); - return this; - } - - /** - * The URL of a shared brooklyn.properties file. Defaults to ~/.brooklyn/brooklyn.properties. - * Can be null to disable. - */ - public Builder globalPropertiesFile(String val) { - globalPropertiesFile = val; - return this; - } - - @Beta - public boolean hasDelegateOriginalProperties() { - return this.originalProperties==null; - } - - /** - * The URL of a brooklyn.properties file specific to this launch. Appends to and overwrites values in globalPropertiesFile. - */ - public Builder localPropertiesFile(String val) { - localPropertiesFile = val; - return this; - } - - public BrooklynProperties build() { - if (originalProperties != null) - return new BrooklynPropertiesImpl().addFromMap(originalProperties); - - BrooklynProperties properties = new BrooklynPropertiesImpl(); - - // TODO Could also read from http://brooklyn.io, for up-to-date values? - // But might that make unit tests run very badly when developer is offline? - addPropertiesFromUrl(properties, defaultLocationMetadataUrl, false); - - addPropertiesFromFile(properties, globalLocationMetadataFile); - addPropertiesFromFile(properties, globalPropertiesFile); - addPropertiesFromFile(properties, localPropertiesFile); - - properties.addEnvironmentVars(); - properties.addSystemProperties(); - - return properties; - } - - public static Builder fromProperties(BrooklynProperties brooklynProperties) { - return new Builder(brooklynProperties); - } - - @Override - public String toString() { - return Objects.toStringHelper(this) - .omitNullValues() - .add("originalProperties", originalProperties) - .add("defaultLocationMetadataUrl", defaultLocationMetadataUrl) - .add("globalLocationMetadataUrl", globalLocationMetadataFile) - .add("globalPropertiesFile", globalPropertiesFile) - .add("localPropertiesFile", localPropertiesFile) - .toString(); - } - } - - private static void addPropertiesFromUrl(BrooklynProperties p, String url, boolean warnIfNotFound) { - if (url==null) return; - - try { - p.addFrom(ResourceUtils.create(BrooklynProperties.class).getResourceFromUrl(url)); - } catch (Exception e) { - if (warnIfNotFound) - LOG.warn("Could not load {}; continuing", url); - if (LOG.isTraceEnabled()) LOG.trace("Could not load "+url+"; continuing", e); - } - } - - private static void addPropertiesFromFile(BrooklynProperties p, String file) { - if (file==null) return; - - String fileTidied = Os.tidyPath(file); - File f = new File(fileTidied); - - if (f.exists()) { - p.addFrom(f); - } - } - } - - public BrooklynProperties addEnvironmentVars(); - - public BrooklynProperties addSystemProperties(); - - public BrooklynProperties addFrom(ConfigBag cfg); - - public BrooklynProperties addFrom(Map map); - - public BrooklynProperties addFrom(InputStream i); - - public BrooklynProperties addFrom(File f); - - public BrooklynProperties addFrom(URL u); - - /** - * @see ResourceUtils#getResourceFromUrl(String) - * - * of the form form file:///home/... or http:// or classpath://xx ; - * for convenience if not starting with xxx: it is treated as a classpath reference or a file; - * throws if not found (but does nothing if argument is null) - */ - public BrooklynProperties addFromUrl(String url); - - /** expects a property already set in scope, whose value is acceptable to {@link #addFromUrl(String)}; - * if property not set, does nothing */ - public BrooklynProperties addFromUrlProperty(String urlProperty); - - /** - * adds the indicated properties - */ - public BrooklynProperties addFromMap(Map properties); - - /** inserts the value under the given key, if it was not present */ - public boolean putIfAbsent(String key, Object value); - - /** @deprecated attempts to call get with this syntax are probably mistakes; get(key, defaultValue) is fine but - * Map is unlikely the key, much more likely they meant getFirst(flags, key). - */ - @Deprecated - public String get(Map flags, String key); - - /** returns the value of the first key which is defined - * <p> - * takes the following flags: - * 'warnIfNone', 'failIfNone' (both taking a boolean (to use default message) or a string (which is the message)); - * and 'defaultIfNone' (a default value to return if there is no such property); defaults to no warning and null response */ - @Override - public String getFirst(String ...keys); - - @Override - public String getFirst(Map flags, String ...keys); - - /** like normal map.put, except config keys are dereferenced on the way in */ - public Object put(Object key, Object value); - - /** like normal map.putAll, except config keys are dereferenced on the way in */ - @Override - public void putAll(Map vals); - - public <T> Object put(HasConfigKey<T> key, T value); - - public <T> Object put(ConfigKey<T> key, T value); - - public <T> boolean putIfAbsent(ConfigKey<T> key, T value); - - @Override - public <T> T getConfig(ConfigKey<T> key); - - @Override - public <T> T getConfig(HasConfigKey<T> key); - - @Override - public <T> T getConfig(HasConfigKey<T> key, T defaultValue); - - @Override - public <T> T getConfig(ConfigKey<T> key, T defaultValue); - - @Override - public Object getRawConfig(ConfigKey<?> key); - - @Override - public Maybe<Object> getConfigRaw(ConfigKey<?> key, boolean includeInherited); - - @Override - public Map<ConfigKey<?>, Object> getAllConfig(); - - @Override - public BrooklynProperties submap(Predicate<ConfigKey<?>> filter); - - @Override - public Map<String, Object> asMapWithStringKeys(); -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynPropertiesImpl.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynPropertiesImpl.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynPropertiesImpl.java deleted file mode 100644 index 023b3e3..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynPropertiesImpl.java +++ /dev/null @@ -1,477 +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.internal; - -import static com.google.common.base.Preconditions.checkNotNull; -import groovy.lang.Closure; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Properties; - -import org.apache.brooklyn.config.ConfigKey; -import org.apache.brooklyn.config.ConfigKey.HasConfigKey; -import org.apache.brooklyn.core.config.BasicConfigKey; -import org.apache.brooklyn.util.collections.MutableMap; -import org.apache.brooklyn.util.core.ResourceUtils; -import org.apache.brooklyn.util.core.config.ConfigBag; -import org.apache.brooklyn.util.core.flags.TypeCoercions; -import org.apache.brooklyn.util.guava.Maybe; -import org.apache.brooklyn.util.os.Os; -import org.apache.brooklyn.util.text.StringFunctions; -import org.apache.brooklyn.util.text.Strings; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.annotations.Beta; -import com.google.common.base.CharMatcher; -import com.google.common.base.Objects; -import com.google.common.base.Predicate; -import com.google.common.base.Throwables; -import com.google.common.collect.Maps; - -/** - * TODO methods in this class are not thread safe. - * intention is that they are set during startup and not modified thereafter. - */ -@SuppressWarnings("rawtypes") -public class BrooklynPropertiesImpl extends LinkedHashMap implements BrooklynProperties { - - private static final long serialVersionUID = -945875483083108978L; - private static final Logger LOG = LoggerFactory.getLogger(BrooklynPropertiesImpl.class); - - public static class Factory { - /** creates a new empty {@link BrooklynPropertiesImpl} */ - public static BrooklynPropertiesImpl newEmpty() { - return new BrooklynPropertiesImpl(); - } - - /** creates a new {@link BrooklynPropertiesImpl} with contents loaded - * from the usual places, including *.properties files and environment variables */ - public static BrooklynPropertiesImpl newDefault() { - return new Builder(true).build(); - } - - public static Builder builderDefault() { - return new Builder(true); - } - - public static Builder builderEmpty() { - return new Builder(false); - } - - public static class Builder { - private String defaultLocationMetadataUrl; - private String globalLocationMetadataFile = null; - private String globalPropertiesFile = null; - private String localPropertiesFile = null; - private BrooklynPropertiesImpl originalProperties = null; - - /** @deprecated since 0.7.0 use static methods in {@link Factory} to create */ - public Builder() { - this(true); - } - - private Builder(boolean setGlobalFileDefaults) { - resetDefaultLocationMetadataUrl(); - if (setGlobalFileDefaults) { - resetGlobalFiles(); - } - } - - public Builder resetDefaultLocationMetadataUrl() { - defaultLocationMetadataUrl = "classpath://brooklyn/location-metadata.properties"; - return this; - } - public Builder resetGlobalFiles() { - defaultLocationMetadataUrl = "classpath://brooklyn/location-metadata.properties"; - globalLocationMetadataFile = Os.mergePaths(Os.home(), ".brooklyn", "location-metadata.properties"); - globalPropertiesFile = Os.mergePaths(Os.home(), ".brooklyn", "brooklyn.properties"); - return this; - } - - /** - * Creates a Builder that when built, will return the BrooklynProperties passed to this constructor - */ - private Builder(BrooklynPropertiesImpl originalProperties) { - this.originalProperties = new BrooklynPropertiesImpl().addFromMap(originalProperties); - } - - /** - * The URL of a default location-metadata.properties (for meta-data about different locations, such as iso3166 and global lat/lon). - * Defaults to classpath://brooklyn/location-metadata.properties - */ - public Builder defaultLocationMetadataUrl(String val) { - defaultLocationMetadataUrl = checkNotNull(val, "file"); - return this; - } - - /** - * The URL of a location-metadata.properties file that appends to and overwrites values in the locationMetadataUrl. - * Defaults to ~/.brooklyn/location-metadata.properties - */ - public Builder globalLocationMetadataFile(String val) { - globalLocationMetadataFile = checkNotNull(val, "file"); - return this; - } - - /** - * The URL of a shared brooklyn.properties file. Defaults to ~/.brooklyn/brooklyn.properties. - * Can be null to disable. - */ - public Builder globalPropertiesFile(String val) { - globalPropertiesFile = val; - return this; - } - - @Beta - public boolean hasDelegateOriginalProperties() { - return this.originalProperties==null; - } - - /** - * The URL of a brooklyn.properties file specific to this launch. Appends to and overwrites values in globalPropertiesFile. - */ - public Builder localPropertiesFile(String val) { - localPropertiesFile = val; - return this; - } - - public BrooklynPropertiesImpl build() { - if (originalProperties != null) - return new BrooklynPropertiesImpl().addFromMap(originalProperties); - - BrooklynPropertiesImpl properties = new BrooklynPropertiesImpl(); - - // TODO Could also read from http://brooklyn.io, for up-to-date values? - // But might that make unit tests run very badly when developer is offline? - addPropertiesFromUrl(properties, defaultLocationMetadataUrl, false); - - addPropertiesFromFile(properties, globalLocationMetadataFile); - addPropertiesFromFile(properties, globalPropertiesFile); - addPropertiesFromFile(properties, localPropertiesFile); - - properties.addEnvironmentVars(); - properties.addSystemProperties(); - - return properties; - } - - public static Builder fromProperties(BrooklynPropertiesImpl brooklynProperties) { - return new Builder(brooklynProperties); - } - - @Override - public String toString() { - return Objects.toStringHelper(this) - .omitNullValues() - .add("originalProperties", originalProperties) - .add("defaultLocationMetadataUrl", defaultLocationMetadataUrl) - .add("globalLocationMetadataUrl", globalLocationMetadataFile) - .add("globalPropertiesFile", globalPropertiesFile) - .add("localPropertiesFile", localPropertiesFile) - .toString(); - } - } - - private static void addPropertiesFromUrl(BrooklynPropertiesImpl p, String url, boolean warnIfNotFound) { - if (url==null) return; - - try { - p.addFrom(ResourceUtils.create(BrooklynPropertiesImpl.class).getResourceFromUrl(url)); - } catch (Exception e) { - if (warnIfNotFound) - LOG.warn("Could not load {}; continuing", url); - if (LOG.isTraceEnabled()) LOG.trace("Could not load "+url+"; continuing", e); - } - } - - private static void addPropertiesFromFile(BrooklynPropertiesImpl p, String file) { - if (file==null) return; - - String fileTidied = Os.tidyPath(file); - File f = new File(fileTidied); - - if (f.exists()) { - p.addFrom(f); - } - } - } - - protected BrooklynPropertiesImpl() { - } - - public BrooklynPropertiesImpl addEnvironmentVars() { - addFrom(System.getenv()); - return this; - } - - public BrooklynPropertiesImpl addSystemProperties() { - addFrom(System.getProperties()); - return this; - } - - public BrooklynPropertiesImpl addFrom(ConfigBag cfg) { - addFrom(cfg.getAllConfig()); - return this; - } - - @SuppressWarnings("unchecked") - public BrooklynPropertiesImpl addFrom(Map map) { - putAll(Maps.transformValues(map, StringFunctions.trim())); - return this; - } - - public BrooklynPropertiesImpl addFrom(InputStream i) { - // Ugly way to load them in order, but Properties is a Hashtable so loses order otherwise. - @SuppressWarnings({ "serial" }) - Properties p = new Properties() { - @Override - public synchronized Object put(Object key, Object value) { - // Trim the string values to remove leading and trailing spaces - String s = (String) value; - if (Strings.isBlank(s)) { - s = Strings.EMPTY; - } else { - s = CharMatcher.BREAKING_WHITESPACE.trimFrom(s); - } - return BrooklynPropertiesImpl.this.put(key, s); - } - }; - try { - p.load(i); - } catch (IOException e) { - throw Throwables.propagate(e); - } - return this; - } - - public BrooklynPropertiesImpl addFrom(File f) { - if (!f.exists()) { - LOG.warn("Unable to find file '"+f.getAbsolutePath()+"' when loading properties; ignoring"); - return this; - } else { - try { - return addFrom(new FileInputStream(f)); - } catch (FileNotFoundException e) { - throw Throwables.propagate(e); - } - } - } - public BrooklynPropertiesImpl addFrom(URL u) { - try { - return addFrom(u.openStream()); - } catch (IOException e) { - throw new RuntimeException("Error reading properties from "+u+": "+e, e); - } - } - /** - * @see ResourceUtils#getResourceFromUrl(String) - * - * of the form form file:///home/... or http:// or classpath://xx ; - * for convenience if not starting with xxx: it is treated as a classpath reference or a file; - * throws if not found (but does nothing if argument is null) - */ - public BrooklynPropertiesImpl addFromUrl(String url) { - try { - if (url==null) return this; - return addFrom(ResourceUtils.create(this).getResourceFromUrl(url)); - } catch (Exception e) { - throw new RuntimeException("Error reading properties from "+url+": "+e, e); - } - } - - /** expects a property already set in scope, whose value is acceptable to {@link #addFromUrl(String)}; - * if property not set, does nothing */ - public BrooklynPropertiesImpl addFromUrlProperty(String urlProperty) { - String url = (String) get(urlProperty); - if (url==null) addFromUrl(url); - return this; - } - - /** - * adds the indicated properties - */ - public BrooklynPropertiesImpl addFromMap(Map properties) { - putAll(properties); - return this; - } - - /** inserts the value under the given key, if it was not present */ - public boolean putIfAbsent(String key, Object value) { - if (containsKey(key)) return false; - put(key, value); - return true; - } - - /** @deprecated attempts to call get with this syntax are probably mistakes; get(key, defaultValue) is fine but - * Map is unlikely the key, much more likely they meant getFirst(flags, key). - */ - @Deprecated - public String get(Map flags, String key) { - LOG.warn("Discouraged use of 'BrooklynProperties.get(Map,String)' (ambiguous); use getFirst(Map,String) or get(String) -- assuming the former"); - LOG.debug("Trace for discouraged use of 'BrooklynProperties.get(Map,String)'", - new Throwable("Arguments: "+flags+" "+key)); - return getFirst(flags, key); - } - - /** returns the value of the first key which is defined - * <p> - * takes the following flags: - * 'warnIfNone', 'failIfNone' (both taking a boolean (to use default message) or a string (which is the message)); - * and 'defaultIfNone' (a default value to return if there is no such property); defaults to no warning and null response */ - @Override - public String getFirst(String ...keys) { - return getFirst(MutableMap.of(), keys); - } - @Override - public String getFirst(Map flags, String ...keys) { - for (String k: keys) { - if (k!=null && containsKey(k)) return (String) get(k); - } - if (flags.get("warnIfNone")!=null && !Boolean.FALSE.equals(flags.get("warnIfNone"))) { - if (Boolean.TRUE.equals(flags.get("warnIfNone"))) - LOG.warn("Unable to find Brooklyn property "+keys); - else - LOG.warn(""+flags.get("warnIfNone")); - } - if (flags.get("failIfNone")!=null && !Boolean.FALSE.equals(flags.get("failIfNone"))) { - Object f = flags.get("failIfNone"); - if (f instanceof Closure) - ((Closure)f).call((Object[])keys); - if (Boolean.TRUE.equals(f)) - throw new NoSuchElementException("Brooklyn unable to find mandatory property "+keys[0]+ - (keys.length>1 ? " (or "+(keys.length-1)+" other possible names, full list is "+Arrays.asList(keys)+")" : "") ); - else - throw new NoSuchElementException(""+f); - } - if (flags.get("defaultIfNone")!=null) { - return (String) flags.get("defaultIfNone"); - } - return null; - } - - @Override - public String toString() { - return "BrooklynProperties["+size()+"]"; - } - - /** like normal map.put, except config keys are dereferenced on the way in */ - @SuppressWarnings("unchecked") - public Object put(Object key, Object value) { - if (key instanceof HasConfigKey) key = ((HasConfigKey)key).getConfigKey().getName(); - if (key instanceof ConfigKey) key = ((ConfigKey)key).getName(); - return super.put(key, value); - } - - /** like normal map.putAll, except config keys are dereferenced on the way in */ - @Override - public void putAll(Map vals) { - for (Map.Entry<?,?> entry : ((Map<?,?>)vals).entrySet()) { - put(entry.getKey(), entry.getValue()); - } - } - - @SuppressWarnings("unchecked") - public <T> Object put(HasConfigKey<T> key, T value) { - return super.put(key.getConfigKey().getName(), value); - } - - @SuppressWarnings("unchecked") - public <T> Object put(ConfigKey<T> key, T value) { - return super.put(key.getName(), value); - } - - public <T> boolean putIfAbsent(ConfigKey<T> key, T value) { - return putIfAbsent(key.getName(), value); - } - - @Override - public <T> T getConfig(ConfigKey<T> key) { - return getConfig(key, null); - } - - @Override - public <T> T getConfig(HasConfigKey<T> key) { - return getConfig(key.getConfigKey(), null); - } - - @Override - public <T> T getConfig(HasConfigKey<T> key, T defaultValue) { - return getConfig(key.getConfigKey(), defaultValue); - } - - @Override - public <T> T getConfig(ConfigKey<T> key, T defaultValue) { - // TODO does not support MapConfigKey etc where entries use subkey notation; for now, access using submap - if (!containsKey(key.getName())) { - if (defaultValue!=null) return defaultValue; - return key.getDefaultValue(); - } - Object value = get(key.getName()); - if (value==null) return null; - // no evaluation / key extraction here - return TypeCoercions.coerce(value, key.getTypeToken()); - } - - @Override - public Object getRawConfig(ConfigKey<?> key) { - return get(key.getName()); - } - - @Override - public Maybe<Object> getConfigRaw(ConfigKey<?> key, boolean includeInherited) { - if (containsKey(key.getName())) return Maybe.of(get(key.getName())); - return Maybe.absent(); - } - - @Override - public Map<ConfigKey<?>, Object> getAllConfig() { - Map<ConfigKey<?>, Object> result = new LinkedHashMap<ConfigKey<?>, Object>(); - for (Object entry: entrySet()) - result.put(new BasicConfigKey<Object>(Object.class, ""+((Map.Entry)entry).getKey()), ((Map.Entry)entry).getValue()); - return result; - } - - @Override - public BrooklynPropertiesImpl submap(Predicate<ConfigKey<?>> filter) { - BrooklynPropertiesImpl result = Factory.newEmpty(); - for (Object entry: entrySet()) { - ConfigKey<?> k = new BasicConfigKey<Object>(Object.class, ""+((Map.Entry)entry).getKey()); - if (filter.apply(k)) - result.put(((Map.Entry)entry).getKey(), ((Map.Entry)entry).getValue()); - } - return result; - } - - @SuppressWarnings("unchecked") - @Override - public Map<String, Object> asMapWithStringKeys() { - return this; - } - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/BrooklynStorage.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/BrooklynStorage.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/BrooklynStorage.java deleted file mode 100644 index b1f9cdf..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/BrooklynStorage.java +++ /dev/null @@ -1,114 +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.internal.storage; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentMap; - -import com.google.common.annotations.Beta; -import com.google.common.annotations.VisibleForTesting; - -public interface BrooklynStorage { - - /** - * Creates a reference to a value, backed by the storage-medium. If a reference with this - * name has already been created, then that existing reference will be returned. - * - * The returned reference is a live view: changes made to the reference will be persisted, - * and changes that others make will be reflected in the reference. - * - * The reference is thread-safe. No additional synchronization is required when getting/setting - * the reference. - * - * @param id - */ - <T> Reference<T> getReference(String id); - - /** - * Creates a list backed by the storage-medium. If a list with this name has already been - * created, then that existing list will be returned. - * - * The returned list is not a live view. Changes are made by calling reference.set(), and - * the view is refreshed by calling reference.get(). Changes are thread-safe, but callers - * must be careful not to overwrite other's changes. For example, the code below could overwrite - * another threads changes that are made to the map between the call to get() and the subsequent - * call to set(). - * - * <pre> - * {@code - * Reference<List<String>> ref = storage.<String>createNonConcurrentList("myid"); - * List<String> newval = ImmutableList.<String>builder().addAll(ref.get()).add("another").builder(); - * ref.set(newval); - * } - * </pre> - * - * TODO Aled says: Is getNonConcurrentList necessary? - * The purpose of this method, rather than just using - * {@code Reference ref = getReference(id); ref.set(ImmutableList.of())} - * is to allow control of the serialization of the things inside the list - * (e.g. switching the Location object to serialize a proxy object of some sort). - * I don't want us to have to do deep inspection of every object being added to any map/ref. - * Feels like we can use normal serialization unless the top-level object matches an - * instanceof for special things like Entity, Location, etc. - * - * Peter responds: - * What I'm a bit scared of is that we need to write some kind of meta serialization mechanism - * on top of the mechanisms provided by e.g. Hazelcast or Infinispan. Hazelcast has a very - * extensive serialization library where you can plug in all kinds of serialization mechanisms. - * - * @param id - */ - @Beta - <T> Reference<List<T>> getNonConcurrentList(String id); - - /** - * Creates a map backed by the storage-medium. If a map with this name has already been - * created, then that existing map will be returned. - * - * The returned map is a live view: changes made to the map will be persisted, and changes - * that others make will be reflected in the map. - * - * The map is thread-safe: {@link Map#keySet()} etc will iterate over a snapshot view of the - * contents. - * - * @param id - */ - <K,V> ConcurrentMap<K,V> getMap(String id); - - /** - * Removes the data stored against this id, whether it is a map, ref or whatever. - */ - void remove(String id); - - /** - * Terminates the BrooklynStorage. - */ - void terminate(); - - /** asserts that some of the storage containers which should be empty are empty; - * this could do more thorough checks, but as it is it is useful to catch many leaks, - * and the things which aren't empty it's much harder to check whether they should be empty! - * <p> - * not meant for use outwith tests */ - @VisibleForTesting - public boolean isMostlyEmpty(); - - Map<String, Object> getStorageMetrics(); -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGrid.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGrid.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGrid.java deleted file mode 100644 index 09f50fb..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGrid.java +++ /dev/null @@ -1,52 +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.internal.storage; - -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentMap; - -import com.google.common.annotations.VisibleForTesting; - -public interface DataGrid { - - /** - * If a map already exists with this id, returns it; otherwise creates a new map stored - * in the datagrid. - */ - <K,V> ConcurrentMap<K,V> getMap(String id); - - /** - * Deletes the map for this id, if it exists; otherwise a no-op. - */ - void remove(String id); - - /** - * Terminates the DataGrid. If there is a real datagrid with multiple machines running, it doesn't mean that the - * datagrid is going to be terminated; it only means that all local resources of the datagrid are released. - */ - void terminate(); - - Map<String, Object> getDatagridMetrics(); - - /** Returns snapshot of known keys at this datagrid */ - @VisibleForTesting - Set<String> getKeys(); - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGridFactory.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGridFactory.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGridFactory.java deleted file mode 100644 index 45c696b..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/DataGridFactory.java +++ /dev/null @@ -1,38 +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.internal.storage; - -import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; - -/** - * A factory for creating a {@link DataGrid}. - * - * Implementations of this interface should have a public no arg constructor; this constructor will be - * called through reflection in the {@link org.apache.brooklyn.core.mgmt.internal.LocalManagementContext}. - */ -public interface DataGridFactory { - - /** - * Creates a {@link BrooklynStorage} instance. - * - * @param managementContext the ManagementContextInternal - * @return the created BrooklynStorage. - */ - DataGrid newDataGrid(ManagementContextInternal managementContext); -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/Reference.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/Reference.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/Reference.java deleted file mode 100644 index 3f2d846..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/Reference.java +++ /dev/null @@ -1,50 +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.internal.storage; - -/** - * A reference to a value, backed by the storage-medium. - * - * @see BrooklynStorage#getReference(String) - * - * @author aled - */ -public interface Reference<T> { - - // TODO We can add compareAndSet(T,T) as and when required - - T get(); - - T set(T val); - - /** - * @return true if the value is null; false otherwise. - */ - boolean isNull(); - - /** - * Sets the value back to null. Similar to {@code set(null)}. - */ - void clear(); - - /** - * @return true if the value equals the given parameter; false otherwise - */ - boolean contains(Object other); -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BackedReference.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BackedReference.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BackedReference.java deleted file mode 100644 index e51e782..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BackedReference.java +++ /dev/null @@ -1,73 +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.internal.storage.impl; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Map; - -import org.apache.brooklyn.core.internal.storage.Reference; - -import com.google.common.base.Objects; - -class BackedReference<T> implements Reference<T> { - private final Map<String,? super T> backingMap; - private final String key; - - BackedReference(Map<String,? super T> backingMap, String key) { - this.backingMap = checkNotNull(backingMap, "backingMap"); - this.key = key; - } - - @Override - public T get() { - // For happens-before (for different threads calling get and set), relies on - // underlying map (e.g. from datagrid) having some synchronization - return (T) backingMap.get(key); - } - - @Override - public T set(T val) { - if (val == null) { - return (T) backingMap.remove(key); - } else { - return (T) backingMap.put(key, val); - } - } - - @Override - public String toString() { - return ""+get(); - } - - @Override - public boolean isNull() { - return get() == null; - } - - @Override - public void clear() { - set(null); - } - - @Override - public boolean contains(Object other) { - return Objects.equal(get(), other); - } -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BasicReference.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BasicReference.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BasicReference.java deleted file mode 100644 index a01d61c..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BasicReference.java +++ /dev/null @@ -1,67 +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.internal.storage.impl; - -import java.util.concurrent.atomic.AtomicReference; - -import org.apache.brooklyn.core.internal.storage.Reference; - -import com.google.common.base.Objects; - -public class BasicReference<T> implements Reference<T >{ - - private final AtomicReference<T> ref = new AtomicReference<T>(); - - public BasicReference() { - } - - public BasicReference(T val) { - set(val); - } - - @Override - public T get() { - return ref.get(); - } - - @Override - public T set(T val) { - return ref.getAndSet(val); - } - - @Override - public boolean isNull() { - return get() == null; - } - - @Override - public void clear() { - set(null); - } - - @Override - public boolean contains(Object other) { - return Objects.equal(get(), other); - } - - @Override - public String toString() { - return ""+get(); - } -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImpl.java ---------------------------------------------------------------------- diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImpl.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImpl.java deleted file mode 100644 index 188955a..0000000 --- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/internal/storage/impl/BrooklynStorageImpl.java +++ /dev/null @@ -1,139 +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.internal.storage.impl; - -import java.lang.ref.WeakReference; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentMap; - -import org.apache.brooklyn.core.internal.storage.BrooklynStorage; -import org.apache.brooklyn.core.internal.storage.DataGrid; -import org.apache.brooklyn.core.internal.storage.Reference; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; - -public class BrooklynStorageImpl implements BrooklynStorage { - - private final DataGrid datagrid; - private final ConcurrentMap<String, Object> refsMap; - private final ConcurrentMap<String, Object> listsMap; - private final ConcurrentMap<String, WeakReference<Reference<?>>> refsCache; - private final ConcurrentMap<String, WeakReference<Reference<?>>> listRefsCache; - - public BrooklynStorageImpl(DataGrid datagrid) { - this.datagrid = datagrid; - this.refsMap = datagrid.getMap("refs"); - this.listsMap = datagrid.getMap("lists"); - this.refsCache = Maps.newConcurrentMap(); - this.listRefsCache = Maps.newConcurrentMap(); - } - - /** - * Returns the DataGrid used by this BrooklynStorageImpl - * - * @return the DataGrid. - */ - @VisibleForTesting - public DataGrid getDataGrid() { - return datagrid; - } - - @Override - public <T> Reference<T> getReference(final String id) { - // Can use different ref instances; no need to always return same one. Caching is an - // optimisation to just avoid extra object creation. - WeakReference<Reference<?>> weakRef = refsCache.get(id); - Reference<?> ref = (weakRef != null) ? weakRef.get() : null; - if (ref == null) { - ref = new BackedReference<T>(refsMap, id) { - @Override protected void finalize() { - // TODO Don't like using finalize due to performance overhead, but not - // optimising yet. Could use PhantomReference instead; see - // http://java.dzone.com/articles/finalization-and-phantom - refsCache.remove(id); - } - }; - refsCache.putIfAbsent(id, new WeakReference<Reference<?>>(ref)); - } - return (Reference<T>) ref; - } - - @Override - public <T> Reference<List<T>> getNonConcurrentList(final String id) { - WeakReference<Reference<?>> weakRef = listRefsCache.get(id); - Reference<?> ref = (weakRef != null) ? weakRef.get() : null; - if (ref == null) { - ref = new BackedReference<List<T>>(listsMap, id) { - @Override public List<T> get() { - List<T> result = super.get(); - return (result == null ? ImmutableList.<T>of() : Collections.unmodifiableList(result)); - } - @Override protected void finalize() { - listRefsCache.remove(id); - } - }; - listRefsCache.putIfAbsent(id, new WeakReference<Reference<?>>(ref)); - } - return (Reference<List<T>>) ref; - } - - @Override - public <K, V> ConcurrentMap<K, V> getMap(final String id) { - return datagrid.<K,V>getMap(id); - } - - @Override - public void remove(String id) { - datagrid.remove(id); - refsMap.remove(id); - listsMap.remove(id); - refsCache.remove(id); - listRefsCache.remove(id); - } - - @Override - public void terminate() { - datagrid.terminate(); - } - - public boolean isMostlyEmpty() { - if (!refsMap.isEmpty() || !listsMap.isEmpty()) - return false; - // the datagrid may have some standard bookkeeping entries - return true; - } - - @Override - public Map<String, Object> getStorageMetrics() { - return ImmutableMap.of( - "datagrid", datagrid.getDatagridMetrics(), - "refsMapSize", ""+refsMap.size(), - "listsMapSize", ""+listsMap.size()); - } - - @Override - public String toString() { - return super.toString() + getStorageMetrics(); - } -}
