You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by an...@apache.org on 2015/02/03 12:41:35 UTC
[04/17] incubator-brooklyn git commit: refactor RebindManager to have
a RebindIteration
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/55b5f65e/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java b/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
index 8556e61..b1a02c1 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindManagerImpl.java
@@ -20,105 +20,53 @@ package brooklyn.entity.rebind;
import static com.google.common.base.Preconditions.checkNotNull;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import brooklyn.basic.AbstractBrooklynObject;
import brooklyn.basic.BrooklynObject;
-import brooklyn.basic.BrooklynObjectInternal;
-import brooklyn.catalog.BrooklynCatalog;
-import brooklyn.catalog.CatalogItem;
-import brooklyn.catalog.CatalogLoadMode;
-import brooklyn.catalog.internal.BasicBrooklynCatalog;
-import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.config.BrooklynLogging;
-import brooklyn.config.BrooklynLogging.LoggingLevel;
import brooklyn.config.BrooklynServerConfig;
import brooklyn.config.ConfigKey;
import brooklyn.enricher.basic.AbstractEnricher;
import brooklyn.entity.Application;
-import brooklyn.entity.Entity;
-import brooklyn.entity.Feed;
-import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.entity.basic.AbstractEntity;
import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.entity.proxying.InternalEntityFactory;
-import brooklyn.entity.proxying.InternalFactory;
-import brooklyn.entity.proxying.InternalLocationFactory;
-import brooklyn.entity.proxying.InternalPolicyFactory;
import brooklyn.entity.rebind.persister.BrooklynMementoPersisterToObjectStore;
import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils;
import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils.CreateBackupMode;
import brooklyn.entity.rebind.persister.PersistenceActivityMetrics;
-import brooklyn.event.feed.AbstractFeed;
import brooklyn.internal.BrooklynFeatureEnablement;
-import brooklyn.location.Location;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.basic.LocationInternal;
import brooklyn.management.ExecutionContext;
import brooklyn.management.ManagementContext;
import brooklyn.management.Task;
-import brooklyn.management.classloading.BrooklynClassLoadingContext;
import brooklyn.management.ha.HighAvailabilityManagerImpl;
import brooklyn.management.ha.ManagementNodeState;
import brooklyn.management.ha.MementoCopyMode;
-import brooklyn.management.internal.EntityManagerInternal;
-import brooklyn.management.internal.LocationManagerInternal;
import brooklyn.management.internal.ManagementContextInternal;
import brooklyn.management.internal.ManagementTransitionInfo.ManagementTransitionMode;
-import brooklyn.mementos.BrooklynMemento;
-import brooklyn.mementos.BrooklynMementoManifest;
-import brooklyn.mementos.BrooklynMementoManifest.EntityMementoManifest;
import brooklyn.mementos.BrooklynMementoPersister;
-import brooklyn.mementos.BrooklynMementoPersister.LookupContext;
import brooklyn.mementos.BrooklynMementoRawData;
-import brooklyn.mementos.CatalogItemMemento;
-import brooklyn.mementos.EnricherMemento;
-import brooklyn.mementos.EntityMemento;
-import brooklyn.mementos.FeedMemento;
-import brooklyn.mementos.LocationMemento;
-import brooklyn.mementos.Memento;
-import brooklyn.mementos.PolicyMemento;
import brooklyn.mementos.TreeNode;
-import brooklyn.policy.Enricher;
-import brooklyn.policy.Policy;
-import brooklyn.policy.basic.AbstractPolicy;
-import brooklyn.util.collections.MutableList;
import brooklyn.util.collections.MutableMap;
import brooklyn.util.collections.QuorumCheck;
import brooklyn.util.collections.QuorumCheck.QuorumChecks;
import brooklyn.util.exceptions.Exceptions;
import brooklyn.util.exceptions.RuntimeInterruptedException;
-import brooklyn.util.flags.FlagUtils;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.javalang.Reflections;
import brooklyn.util.task.BasicExecutionContext;
import brooklyn.util.task.ScheduledTask;
import brooklyn.util.task.Tasks;
-import brooklyn.util.text.Strings;
import brooklyn.util.time.Duration;
-import brooklyn.util.time.Time;
-import com.google.common.base.Preconditions;
import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
/** Manages the persistence/rebind process.
* <p>
@@ -129,7 +77,6 @@ import com.google.common.collect.Sets;
public class RebindManagerImpl implements RebindManager {
// TODO Use ImmediateDeltaChangeListener if the period is set to 0?
- // But for MultiFile persister, that is still async
public static final ConfigKey<RebindFailureMode> DANGLING_REFERENCE_FAILURE_MODE =
ConfigKeys.newConfigKey(RebindFailureMode.class, "rebind.failureMode.danglingRef",
@@ -165,14 +112,14 @@ public class RebindManagerImpl implements RebindManager {
private volatile boolean readOnlyRunning = false;
private volatile ScheduledTask readOnlyTask = null;
private transient Semaphore rebindActive = new Semaphore(1);
- private transient int readOnlyRebindCount = Integer.MIN_VALUE;
+ private transient AtomicInteger readOnlyRebindCount = new AtomicInteger(Integer.MIN_VALUE);
private volatile BrooklynMementoPersister persistenceStoreAccess;
- private final boolean persistPoliciesEnabled;
- private final boolean persistEnrichersEnabled;
- private final boolean persistFeedsEnabled;
- private final boolean persistCatalogItemsEnabled;
+ final boolean persistPoliciesEnabled;
+ final boolean persistEnrichersEnabled;
+ final boolean persistFeedsEnabled;
+ final boolean persistCatalogItemsEnabled;
private RebindFailureMode danglingRefFailureMode;
private RebindFailureMode rebindFailureMode;
@@ -229,6 +176,10 @@ public class RebindManagerImpl implements RebindManager {
new Object[]{this, persistPoliciesEnabled, persistEnrichersEnabled, persistFeedsEnabled, persistCatalogItemsEnabled});
}
+ public ManagementContextInternal getManagementContext() {
+ return managementContext;
+ }
+
/**
* Must be called before setPerister()
*/
@@ -264,6 +215,11 @@ public class RebindManagerImpl implements RebindManager {
if (persistenceStoreAccess != null && persistenceStoreAccess != val) {
throw new IllegalStateException("Dynamically changing persister is not supported: old="+persistenceStoreAccess+"; new="+val);
}
+ if (persistenceRealChangeListener!=null) {
+ // TODO should probably throw here, but previously we have not -- so let's log for now to be sure it's not happening
+ LOG.warn("Persister reset after listeners have been set", new Throwable("Source of persister reset"));
+ }
+
this.persistenceStoreAccess = checkNotNull(val, "persister");
this.persistenceRealChangeListener = new PeriodicDeltaChangeListener(managementContext.getServerExecutionContext(), persistenceStoreAccess, exceptionHandler, persistMetrics, periodicPersistPeriod);
@@ -292,7 +248,7 @@ public class RebindManagerImpl implements RebindManager {
}
}
persistenceRunning = true;
- readOnlyRebindCount = Integer.MIN_VALUE;
+ readOnlyRebindCount.set(Integer.MIN_VALUE);
persistenceStoreAccess.enableWriteAccess();
if (persistenceRealChangeListener != null) persistenceRealChangeListener.start();
}
@@ -326,7 +282,7 @@ public class RebindManagerImpl implements RebindManager {
if (persistenceStoreAccess != null) persistenceStoreAccess.disableWriteAccess(true);
readOnlyRunning = true;
- readOnlyRebindCount = 0;
+ readOnlyRebindCount.set(0);
try {
rebind(null, null, mode);
@@ -533,596 +489,18 @@ public class RebindManagerImpl implements RebindManager {
}
protected List<Application> rebindImpl(final ClassLoader classLoader, final RebindExceptionHandler exceptionHandler, ManagementNodeState mode) {
- checkNotNull(classLoader, "classLoader");
-
- try {
- rebindActive.acquire();
- } catch (InterruptedException e1) { Exceptions.propagate(e1); }
- RebindTracker.setRebinding();
- if (ManagementNodeState.isHotProxy(mode))
- readOnlyRebindCount++;
-
- Stopwatch timer = Stopwatch.createStarted();
- try {
- Reflections reflections = new Reflections(classLoader);
- RebindContextImpl rebindContext = new RebindContextImpl(exceptionHandler, classLoader);
-
- exceptionHandler.onStart(rebindContext);
-
- if (mode==ManagementNodeState.HOT_STANDBY || mode==ManagementNodeState.HOT_BACKUP) {
- rebindContext.setAllReadOnly();
- } else {
- Preconditions.checkState(mode==ManagementNodeState.MASTER, "Must be either master or read only to rebind (mode "+mode+")");
- }
-
- LookupContext realLookupContext = new RebindContextLookupContext(managementContext, rebindContext, exceptionHandler);
- rebindContext.setLookupContext(realLookupContext);
-
- // Mutli-phase deserialization.
- //
- // 1. deserialize just the "manifest" to find all instances (and their types).
- // 2. instantiate and reconstruct catalog items
- // 3. instantiate entities+locations so that inter-entity references can subsequently be set during deserialize (and entity config/state is set).
- // 4. deserialize the memento
- // 5. instantiate policies+enricherss+feeds (could perhaps merge this with (3), depending how they are implemented)
- // 6. reconstruct the entities etc (i.e. calling rebind() on the already-instantiated instances)
- // 7. add policies+enrichers+feeds to all the entities.
- // 8. manage the entities
-
- // TODO if underlying data-store is changed between first and second manifest read (e.g. to add an
- // entity), then second phase might try to reconstitute an entity that has not been put in
- // the rebindContext. This should not affect normal production usage, because rebind is run
- // against a data-store that is not being written to by other brooklyn instance(s).
-
- // TODO Rebinding to code in OSGi bundles:
- // Inferring the catalog item id context:
- // * most of the time the creator will be passing "my catalog item id"
- // (or API could also take "BrooklynObject me" as a creation context and the
- // receiver query the creator's catalog item id)
- // * look at the context entity of Tasks.current() (if set)
- // * propagate the catalog item id when doing setEntity, addChild
- // * when none of the above work (or they are wrong) let the user specify the catalog item
- //
- // Precedence of setting the catalog item ID:
- // 1. User-supplied catalog item ID.
- // 2. Creating from a catalog item - all items resolved during the creation of a spec
- // from a catalog item receive the catalog item's ID as context.
- // 3. When using the Java API for creating specs get the catalog item ID from the
- // context entity of the Tasks.current() task.
- // 4. Propagate the context catalog item ID to children, adjuncts if they don't have one already.
-
- //
- // PHASE ONE
- //
-
- //The manifest contains full catalog items mementos. Reading them at this stage means that
- //we don't support references to entities/locations withing tags.
-
- LOG.debug("Rebinding ("+mode+
- (readOnlyRebindCount>Integer.MIN_VALUE ? ", iteration "+readOnlyRebindCount : "")+
- ") from "+getPersister().getBackingStoreDescription()+"...");
-
- BrooklynMementoRawData mementoRawData = persistenceStoreAccess.loadMementoRawData(exceptionHandler);
- BrooklynMementoManifest mementoManifest = persistenceStoreAccess.loadMementoManifest(mementoRawData, exceptionHandler);
-
- boolean overwritingMaster = false;
- boolean isEmpty = mementoManifest.isEmpty();
- if (mode!=ManagementNodeState.HOT_STANDBY && mode!=ManagementNodeState.HOT_BACKUP) {
- if (!isEmpty) {
- LOG.info("Rebinding from "+getPersister().getBackingStoreDescription()+" for "+Strings.toLowerCase(Strings.toString(mode))+" "+managementContext.getManagementNodeId()+"...");
- } else {
- LOG.info("Rebind check: no existing state; will persist new items to "+getPersister().getBackingStoreDescription());
- }
-
- if (!managementContext.getEntityManager().getEntities().isEmpty() || !managementContext.getLocationManager().getLocations().isEmpty()) {
- // this is discouraged if we were already master
- Entity anEntity = Iterables.getFirst(managementContext.getEntityManager().getEntities(), null);
- if (anEntity!=null && !((EntityInternal)anEntity).getManagementSupport().isReadOnly()) {
- overwritingMaster = true;
- LOG.warn("Rebind requested for "+mode+" node "+managementContext.getManagementNodeId()+" "
- + "when it already has active state; discouraged, "
- + "will likely overwrite: "+managementContext.getEntityManager().getEntities()+" and "+managementContext.getLocationManager().getLocations()+" and more");
- }
- }
- }
-
- //
- // PHASE TWO - build catalog so we can load other things
- //
-
- BrooklynObjectInstantiator instantiator = new BrooklynObjectInstantiator(classLoader, rebindContext, reflections);
-
- // Instantiate catalog items
- if (persistCatalogItemsEnabled) {
- logRebindingDebug("RebindManager instantiating catalog items: {}", mementoManifest.getCatalogItemIds());
- for (CatalogItemMemento catalogItemMemento : mementoManifest.getCatalogItemMementos().values()) {
- if (LOG.isDebugEnabled()) LOG.debug("RebindManager instantiating catalog item {}", catalogItemMemento);
- try {
- CatalogItem<?, ?> catalogItem = instantiator.newCatalogItem(catalogItemMemento);
- rebindContext.registerCatalogItem(catalogItemMemento.getId(), catalogItem);
- } catch (Exception e) {
- exceptionHandler.onCreateFailed(BrooklynObjectType.CATALOG_ITEM, catalogItemMemento.getId(), catalogItemMemento.getType(), e);
- }
- }
- } else {
- logRebindingDebug("Not rebinding catalog; feature disabled: {}", mementoManifest.getCatalogItemIds());
- }
-
- // Reconstruct catalog entries
- if (persistCatalogItemsEnabled) {
- logRebindingDebug("RebindManager reconstructing catalog items");
- for (CatalogItemMemento catalogItemMemento : mementoManifest.getCatalogItemMementos().values()) {
- CatalogItem<?, ?> item = rebindContext.getCatalogItem(catalogItemMemento.getId());
- logRebindingDebug("RebindManager reconstructing catalog item {}", catalogItemMemento);
- if (item == null) {
- exceptionHandler.onNotFound(BrooklynObjectType.CATALOG_ITEM, catalogItemMemento.getId());
- } else {
- try {
- item.getRebindSupport().reconstruct(rebindContext, catalogItemMemento);
- if (item instanceof AbstractBrooklynObject) {
- AbstractBrooklynObject.class.cast(item).setManagementContext(managementContext);
- }
- } catch (Exception e) {
- exceptionHandler.onRebindFailed(BrooklynObjectType.CATALOG_ITEM, item, e);
- }
- }
- }
- }
-
- // Register catalogue items with the management context. Loads the bundles in the OSGi framework.
- CatalogLoadMode catalogLoadMode = managementContext.getConfig().getConfig(BrooklynServerConfig.CATALOG_LOAD_MODE);
- if (persistCatalogItemsEnabled) {
- boolean shouldResetCatalog = catalogLoadMode == CatalogLoadMode.LOAD_PERSISTED_STATE
- || (!isEmpty && catalogLoadMode == CatalogLoadMode.LOAD_BROOKLYN_CATALOG_URL_IF_NO_PERSISTED_STATE);
- boolean shouldLoadDefaultCatalog = catalogLoadMode == CatalogLoadMode.LOAD_BROOKLYN_CATALOG_URL
- || (isEmpty && catalogLoadMode == CatalogLoadMode.LOAD_BROOKLYN_CATALOG_URL_IF_NO_PERSISTED_STATE);
- if (shouldResetCatalog) {
- // Reset catalog with previously persisted state
- logRebindingDebug("RebindManager resetting management context catalog to previously persisted state");
- managementContext.getCatalog().reset(rebindContext.getCatalogItems());
- } else if (shouldLoadDefaultCatalog) {
- // Load catalogue as normal
- // TODO in read-only mode, should do this less frequently than entities etc
- logRebindingDebug("RebindManager loading default catalog");
- ((BasicBrooklynCatalog) managementContext.getCatalog()).resetCatalogToContentsAtConfiguredUrl();
- } else {
- // Management context should have taken care of loading the catalogue
- Collection<CatalogItem<?, ?>> catalogItems = rebindContext.getCatalogItems();
- String message = "RebindManager not resetting catalog to persisted state. Catalog load mode is {}.";
- if (!catalogItems.isEmpty() && shouldLogRebinding()) {
- LOG.info(message + " There {} {} item{} persisted.", new Object[]{
- catalogLoadMode, catalogItems.size() == 1 ? "was" : "were", catalogItems.size(), Strings.s(catalogItems)});
- } else if (LOG.isDebugEnabled()) {
- logRebindingDebug(message, catalogLoadMode);
- }
- }
- // TODO destroy old (as above)
- } else {
- logRebindingDebug("RebindManager not resetting catalog because catalog persistence is disabled");
- }
-
-
- //
- // PHASE THREE
- //
-
- // Instantiate locations
- logRebindingDebug("RebindManager instantiating locations: {}", mementoManifest.getLocationIdToType().keySet());
- for (Map.Entry<String, String> entry : mementoManifest.getLocationIdToType().entrySet()) {
- String locId = entry.getKey();
- String locType = entry.getValue();
- if (LOG.isTraceEnabled()) LOG.trace("RebindManager instantiating location {}", locId);
-
- try {
- Location location = instantiator.newLocation(locId, locType);
- rebindContext.registerLocation(locId, location);
- } catch (Exception e) {
- exceptionHandler.onCreateFailed(BrooklynObjectType.LOCATION, locId, locType, e);
- }
- }
-
- // Instantiate entities
- logRebindingDebug("RebindManager instantiating entities: {}", mementoManifest.getEntityIdToManifest().keySet());
- for (Map.Entry<String, EntityMementoManifest> entry : mementoManifest.getEntityIdToManifest().entrySet()) {
- String entityId = entry.getKey();
- EntityMementoManifest entityManifest = entry.getValue();
- String catalogItemId = findCatalogItemId(classLoader, mementoManifest.getEntityIdToManifest(), entityManifest);
-
- if (LOG.isTraceEnabled()) LOG.trace("RebindManager instantiating entity {}", entityId);
-
- try {
- Entity entity = (Entity) instantiator.newEntity(entityId, entityManifest.getType(), catalogItemId);
- ((EntityInternal)entity).getManagementSupport().setReadOnly( rebindContext.isReadOnly(entity) );
- rebindContext.registerEntity(entityId, entity);
-
- } catch (Exception e) {
- exceptionHandler.onCreateFailed(BrooklynObjectType.ENTITY, entityId, entityManifest.getType(), e);
- }
- }
-
-
- //
- // PHASE FOUR
- //
-
- BrooklynMemento memento = persistenceStoreAccess.loadMemento(mementoRawData, realLookupContext, exceptionHandler);
-
-
- //
- // PHASE FIVE
- //
-
- // Instantiate policies
- if (persistPoliciesEnabled) {
- logRebindingDebug("RebindManager instantiating policies: {}", memento.getPolicyIds());
- for (PolicyMemento policyMemento : memento.getPolicyMementos().values()) {
- logRebindingDebug("RebindManager instantiating policy {}", policyMemento);
-
- try {
- Policy policy = instantiator.newPolicy(policyMemento);
- rebindContext.registerPolicy(policyMemento.getId(), policy);
- } catch (Exception e) {
- exceptionHandler.onCreateFailed(BrooklynObjectType.POLICY, policyMemento.getId(), policyMemento.getType(), e);
- }
- }
- } else {
- logRebindingDebug("Not rebinding policies; feature disabled: {}", memento.getPolicyIds());
- }
-
- // Instantiate enrichers
- if (persistEnrichersEnabled) {
- logRebindingDebug("RebindManager instantiating enrichers: {}", memento.getEnricherIds());
- for (EnricherMemento enricherMemento : memento.getEnricherMementos().values()) {
- logRebindingDebug("RebindManager instantiating enricher {}", enricherMemento);
-
- try {
- Enricher enricher = instantiator.newEnricher(enricherMemento);
- rebindContext.registerEnricher(enricherMemento.getId(), enricher);
- } catch (Exception e) {
- exceptionHandler.onCreateFailed(BrooklynObjectType.ENRICHER, enricherMemento.getId(), enricherMemento.getType(), e);
- }
- }
- } else {
- logRebindingDebug("Not rebinding enrichers; feature disabled: {}", memento.getEnricherIds());
- }
-
- // Instantiate feeds
- if (persistFeedsEnabled) {
- logRebindingDebug("RebindManager instantiating feeds: {}", memento.getFeedIds());
- for (FeedMemento feedMemento : memento.getFeedMementos().values()) {
- if (LOG.isDebugEnabled()) LOG.debug("RebindManager instantiating feed {}", feedMemento);
-
- try {
- Feed feed = instantiator.newFeed(feedMemento);
- rebindContext.registerFeed(feedMemento.getId(), feed);
- } catch (Exception e) {
- exceptionHandler.onCreateFailed(BrooklynObjectType.FEED, feedMemento.getId(), feedMemento.getType(), e);
- }
- }
- } else {
- logRebindingDebug("Not rebinding feeds; feature disabled: {}", memento.getFeedIds());
- }
-
- //
- // PHASE SIX
- //
-
- // Reconstruct locations
- logRebindingDebug("RebindManager reconstructing locations");
- for (LocationMemento locMemento : sortParentFirst(memento.getLocationMementos()).values()) {
- Location location = rebindContext.getLocation(locMemento.getId());
- logRebindingDebug("RebindManager reconstructing location {}", locMemento);
- if (location == null) {
- // usually because of creation-failure, when not using fail-fast
- exceptionHandler.onNotFound(BrooklynObjectType.LOCATION, locMemento.getId());
- } else {
- try {
- ((LocationInternal)location).getRebindSupport().reconstruct(rebindContext, locMemento);
- } catch (Exception e) {
- exceptionHandler.onRebindFailed(BrooklynObjectType.LOCATION, location, e);
- }
- }
- }
-
- // Reconstruct policies
- if (persistPoliciesEnabled) {
- logRebindingDebug("RebindManager reconstructing policies");
- for (PolicyMemento policyMemento : memento.getPolicyMementos().values()) {
- Policy policy = rebindContext.getPolicy(policyMemento.getId());
- logRebindingDebug("RebindManager reconstructing policy {}", policyMemento);
-
- if (policy == null) {
- // usually because of creation-failure, when not using fail-fast
- exceptionHandler.onNotFound(BrooklynObjectType.POLICY, policyMemento.getId());
- } else {
- try {
- policy.getRebindSupport().reconstruct(rebindContext, policyMemento);
- } catch (Exception e) {
- exceptionHandler.onRebindFailed(BrooklynObjectType.POLICY, policy, e);
- rebindContext.unregisterPolicy(policy);
- }
- }
- }
- }
-
- // Reconstruct enrichers
- if (persistEnrichersEnabled) {
- logRebindingDebug("RebindManager reconstructing enrichers");
- for (EnricherMemento enricherMemento : memento.getEnricherMementos().values()) {
- Enricher enricher = rebindContext.getEnricher(enricherMemento.getId());
- logRebindingDebug("RebindManager reconstructing enricher {}", enricherMemento);
+ RebindIteration iteration = new RebindIteration(this, mode, classLoader, exceptionHandler,
+ rebindActive, readOnlyRebindCount, rebindMetrics, persistenceStoreAccess);
- if (enricher == null) {
- // usually because of creation-failure, when not using fail-fast
- exceptionHandler.onNotFound(BrooklynObjectType.ENRICHER, enricherMemento.getId());
- } else {
- try {
- enricher.getRebindSupport().reconstruct(rebindContext, enricherMemento);
- } catch (Exception e) {
- exceptionHandler.onRebindFailed(BrooklynObjectType.ENRICHER, enricher, e);
- rebindContext.unregisterEnricher(enricher);
- }
- }
- }
- }
-
- // Reconstruct feeds
- if (persistFeedsEnabled) {
- logRebindingDebug("RebindManager reconstructing feeds");
- for (FeedMemento feedMemento : memento.getFeedMementos().values()) {
- Feed feed = rebindContext.getFeed(feedMemento.getId());
- logRebindingDebug("RebindManager reconstructing feed {}", feedMemento);
+ iteration.runFullRebind();
- if (feed == null) {
- // usually because of creation-failure, when not using fail-fast
- exceptionHandler.onNotFound(BrooklynObjectType.FEED, feedMemento.getId());
- } else {
- try {
- feed.getRebindSupport().reconstruct(rebindContext, feedMemento);
- } catch (Exception e) {
- exceptionHandler.onRebindFailed(BrooklynObjectType.FEED, feed, e);
- rebindContext.unregisterFeed(feed);
- }
- }
-
- }
- }
-
- // Reconstruct entities
- logRebindingDebug("RebindManager reconstructing entities");
- for (EntityMemento entityMemento : sortParentFirst(memento.getEntityMementos()).values()) {
- Entity entity = rebindContext.lookup().lookupEntity(entityMemento.getId());
- logRebindingDebug("RebindManager reconstructing entity {}", entityMemento);
-
- if (entity == null) {
- // usually because of creation-failure, when not using fail-fast
- exceptionHandler.onNotFound(BrooklynObjectType.ENTITY, entityMemento.getId());
- } else {
- try {
- entityMemento.injectTypeClass(entity.getClass());
- ((EntityInternal)entity).getRebindSupport().reconstruct(rebindContext, entityMemento);
- } catch (Exception e) {
- exceptionHandler.onRebindFailed(BrooklynObjectType.ENTITY, entity, e);
- }
- }
- }
-
- //
- // PHASE SEVEN
- //
-
- // Associate policies+enrichers+feeds with entities
- logRebindingDebug("RebindManager reconstructing entities");
- for (EntityMemento entityMemento : sortParentFirst(memento.getEntityMementos()).values()) {
- Entity entity = rebindContext.getEntity(entityMemento.getId());
- logRebindingDebug("RebindManager reconstructing entity {}", entityMemento);
-
- if (entity == null) {
- // usually because of creation-failure, when not using fail-fast
- exceptionHandler.onNotFound(BrooklynObjectType.ENTITY, entityMemento.getId());
- } else {
- try {
- entityMemento.injectTypeClass(entity.getClass());
- // TODO these call to the entity which in turn sets the entity on the underlying feeds and enrichers;
- // that is taken as the cue to start, but it should not be. start should be a separate call.
- ((EntityInternal)entity).getRebindSupport().addPolicies(rebindContext, entityMemento);
- ((EntityInternal)entity).getRebindSupport().addEnrichers(rebindContext, entityMemento);
- ((EntityInternal)entity).getRebindSupport().addFeeds(rebindContext, entityMemento);
- } catch (Exception e) {
- exceptionHandler.onRebindFailed(BrooklynObjectType.ENTITY, entity, e);
- }
- }
- }
-
-
- //
- // PHASE EIGHT
- //
-
- logRebindingDebug("RebindManager managing locations");
- LocationManagerInternal locationManager = (LocationManagerInternal)managementContext.getLocationManager();
- Set<String> oldLocations = Sets.newLinkedHashSet(locationManager.getLocationIds());
- for (Location location: rebindContext.getLocations()) {
- ManagementTransitionMode oldMode = locationManager.getLastManagementTransitionMode(location.getId());
- locationManager.setManagementTransitionMode(location, computeMode(managementContext, location, oldMode, rebindContext.isReadOnly(location)) );
- if (oldMode!=null)
- oldLocations.remove(location.getId());
- }
- for (Location location: rebindContext.getLocations()) {
- if (location.getParent()==null) {
- // manage all root locations
- try {
- ((LocationManagerInternal)managementContext.getLocationManager()).manageRebindedRoot(location);
- } catch (Exception e) {
- exceptionHandler.onManageFailed(BrooklynObjectType.LOCATION, location, e);
- }
- }
- }
- // destroy old
- if (!oldLocations.isEmpty()) BrooklynLogging.log(LOG, overwritingMaster ? BrooklynLogging.LoggingLevel.WARN : BrooklynLogging.LoggingLevel.DEBUG,
- "Destroying unused locations on rebind: "+oldLocations);
- for (String oldLocationId: oldLocations) {
- locationManager.unmanage(locationManager.getLocation(oldLocationId), ManagementTransitionMode.REBINDING_DESTROYED);
- }
-
- // Manage the top-level apps (causing everything under them to become managed)
- logRebindingDebug("RebindManager managing entities");
- EntityManagerInternal entityManager = (EntityManagerInternal)managementContext.getEntityManager();
- Set<String> oldEntities = Sets.newLinkedHashSet(entityManager.getEntityIds());
- for (Entity entity: rebindContext.getEntities()) {
- ManagementTransitionMode oldMode = entityManager.getLastManagementTransitionMode(entity.getId());
- entityManager.setManagementTransitionMode(entity, computeMode(managementContext,entity, oldMode, rebindContext.isReadOnly(entity)) );
- if (oldMode!=null)
- oldEntities.remove(entity.getId());
- }
- List<Application> apps = Lists.newArrayList();
- for (String appId : memento.getApplicationIds()) {
- Entity entity = rebindContext.getEntity(appId);
- if (entity == null) {
- // usually because of creation-failure, when not using fail-fast
- exceptionHandler.onNotFound(BrooklynObjectType.ENTITY, appId);
- } else {
- try {
- entityManager.manageRebindedRoot(entity);
- } catch (Exception e) {
- exceptionHandler.onManageFailed(BrooklynObjectType.ENTITY, entity, e);
- }
- apps.add((Application)entity);
- }
- }
- // destroy old
- if (!oldLocations.isEmpty()) BrooklynLogging.log(LOG, overwritingMaster ? BrooklynLogging.LoggingLevel.WARN : BrooklynLogging.LoggingLevel.DEBUG,
- "Destroying unused entities on rebind: "+oldEntities);
- for (String oldEntityId: oldEntities) {
- entityManager.unmanage(entityManager.getEntity(oldEntityId), ManagementTransitionMode.REBINDING_DESTROYED);
- }
-
- exceptionHandler.onDone();
-
- rebindMetrics.noteSuccess(Duration.of(timer));
- noteErrors(exceptionHandler, null);
- if (firstRebindAppCount==null) {
- firstRebindAppCount = apps.size();
- firstRebindEntityCount = rebindContext.getEntities().size();
- firstRebindItemCount = rebindContext.getAllBrooklynObjects().size();
- }
-
- if (!isEmpty) {
- BrooklynLogging.log(LOG, shouldLogRebinding() ? LoggingLevel.INFO : LoggingLevel.DEBUG,
- "Rebind complete " + "("+mode+(readOnlyRebindCount>=0 ? ", iteration "+readOnlyRebindCount : "")+")" +
- " in {}: {} app{}, {} entit{}, {} location{}, {} polic{}, {} enricher{}, {} feed{}, {} catalog item{}", new Object[]{
- Time.makeTimeStringRounded(timer), apps.size(), Strings.s(apps),
- rebindContext.getEntities().size(), Strings.ies(rebindContext.getEntities()),
- rebindContext.getLocations().size(), Strings.s(rebindContext.getLocations()),
- rebindContext.getPolicies().size(), Strings.ies(rebindContext.getPolicies()),
- rebindContext.getEnrichers().size(), Strings.s(rebindContext.getEnrichers()),
- rebindContext.getFeeds().size(), Strings.s(rebindContext.getFeeds()),
- rebindContext.getCatalogItems().size(), Strings.s(rebindContext.getCatalogItems())
- });
- }
-
- // Return the top-level applications
- logRebindingDebug("RebindManager complete; apps: {}", memento.getApplicationIds());
- return apps;
-
- } catch (Exception e) {
- rebindMetrics.noteFailure(Duration.of(timer));
-
- Exceptions.propagateIfFatal(e);
- noteErrors(exceptionHandler, e);
- throw exceptionHandler.onFailed(e);
-
- } finally {
- rebindActive.release();
- RebindTracker.reset();
- }
- }
-
- private void noteErrors(final RebindExceptionHandler exceptionHandler, Exception primaryException) {
- List<Exception> exceptions = exceptionHandler.getExceptions();
- List<String> warnings = exceptionHandler.getWarnings();
- if (primaryException!=null || !exceptions.isEmpty() || !warnings.isEmpty()) {
- List<String> messages = MutableList.<String>of();
- if (primaryException!=null) messages.add(primaryException.toString());
- for (Exception e: exceptions) messages.add(e.toString());
- for (String w: warnings) messages.add(w);
- rebindMetrics.noteError(messages);
- }
- }
-
- private String findCatalogItemId(ClassLoader cl, Map<String, EntityMementoManifest> entityIdToManifest, EntityMementoManifest entityManifest) {
- if (entityManifest.getCatalogItemId() != null) {
- return entityManifest.getCatalogItemId();
- }
-
- if (BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_INFER_CATALOG_ITEM_ON_REBIND)) {
- //First check if any of the parent entities has a catalogItemId set.
- EntityMementoManifest ptr = entityManifest;
- while (ptr != null) {
- if (ptr.getCatalogItemId() != null) {
- CatalogItem<?, ?> catalogItem = CatalogUtils.getCatalogItemOptionalVersion(managementContext, ptr.getCatalogItemId());
- if (catalogItem != null) {
- return catalogItem.getId();
- } else {
- //Couldn't find a catalog item with this id, but return it anyway and
- //let the caller deal with the error.
- return ptr.getCatalogItemId();
- }
- }
- if (ptr.getParent() != null) {
- ptr = entityIdToManifest.get(ptr.getParent());
- } else {
- ptr = null;
- }
- }
-
- //If no parent entity has the catalogItemId set try to match them by the type we are trying to load.
- //The current convention is to set catalog item IDs to the java type (for both plain java or CAMP plan) they represent.
- //This will be applicable only the first time the store is rebinded, while the catalog items don't have the default
- //version appended to their IDs, but then we will have catalogItemId set on entities so not neede further anyways.
- BrooklynCatalog catalog = managementContext.getCatalog();
- ptr = entityManifest;
- while (ptr != null) {
- CatalogItem<?, ?> catalogItem = catalog.getCatalogItem(ptr.getType(), BrooklynCatalog.DEFAULT_VERSION);
- if (catalogItem != null) {
- LOG.debug("Inferred catalog item ID "+catalogItem.getId()+" for "+entityManifest+" from ancestor "+ptr);
- return catalogItem.getId();
- }
- if (ptr.getParent() != null) {
- ptr = entityIdToManifest.get(ptr.getParent());
- } else {
- ptr = null;
- }
- }
-
- //As a last resort go through all catalog items trying to load the type and use the first that succeeds.
- //But first check if can be loaded from the default classpath
- try {
- cl.loadClass(entityManifest.getType());
- return null;
- } catch (ClassNotFoundException e) {
- }
-
- for (CatalogItem<?, ?> item : catalog.getCatalogItems()) {
- BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(managementContext, item);
- boolean canLoadClass = loader.tryLoadClass(entityManifest.getType()).isPresent();
- if (canLoadClass) {
- LOG.warn("Missing catalog item for "+entityManifest.getId()+", inferring as "+item.getId()+" because that is able to load the item");
- return item.getId();
- }
- }
+ if (firstRebindAppCount==null) {
+ firstRebindAppCount = iteration.getApplications().size();
+ firstRebindEntityCount = iteration.getRebindContext().getEntities().size();
+ firstRebindItemCount = iteration.getRebindContext().getAllBrooklynObjects().size();
}
- return null;
- }
- private BrooklynClassLoadingContext getLoadingContextFromCatalogItemId(String catalogItemId, ClassLoader classLoader, RebindContext rebindContext) {
- Preconditions.checkNotNull(catalogItemId, "catalogItemId required (should not be null)");
- CatalogItem<?, ?> catalogItem = rebindContext.lookup().lookupCatalogItem(catalogItemId);
- if (catalogItem != null) {
- return CatalogUtils.newClassLoadingContext(managementContext, catalogItem);
- } else {
- throw new IllegalStateException("Failed to load catalog item " + catalogItemId + " required for rebinding.");
- }
+ return iteration.getApplications();
}
static ManagementTransitionMode computeMode(ManagementContext mgmt, BrooklynObject item, ManagementTransitionMode oldMode, boolean isNowReadOnly) {
@@ -1159,7 +537,7 @@ public class RebindManagerImpl implements RebindManager {
* TODO Inefficient implementation!
*/
@VisibleForTesting
- <T extends TreeNode> Map<String, T> sortParentFirst(Map<String, T> nodes) {
+ static <T extends TreeNode> Map<String, T> sortParentFirst(Map<String, T> nodes) {
Map<String, T> result = Maps.newLinkedHashMap();
for (T node : nodes.values()) {
List<T> tempchain = Lists.newLinkedList();
@@ -1176,245 +554,6 @@ public class RebindManagerImpl implements RebindManager {
return result;
}
- private class BrooklynObjectInstantiator {
-
- private final ClassLoader classLoader;
- private final RebindContextImpl rebindContext;
- private final Reflections reflections;
-
- private BrooklynObjectInstantiator(ClassLoader classLoader, RebindContextImpl rebindContext, Reflections reflections) {
- this.classLoader = classLoader;
- this.rebindContext = rebindContext;
- this.reflections = reflections;
- }
-
- private Entity newEntity(String entityId, String entityType, String catalogItemId) {
- Class<? extends Entity> entityClazz = load(Entity.class, entityType, catalogItemId, entityId);
-
- Entity entity;
-
- if (InternalFactory.isNewStyle(entityClazz)) {
- // Not using entityManager.createEntity(EntitySpec) because don't want init() to be called.
- // Creates an uninitialized entity, but that has correct id + proxy.
- InternalEntityFactory entityFactory = managementContext.getEntityFactory();
- entity = entityFactory.constructEntity(entityClazz, Reflections.getAllInterfaces(entityClazz), entityId);
-
- } else {
- LOG.warn("Deprecated rebind of entity without no-arg constructor; this may not be supported in future versions: id="+entityId+"; type="+entityType);
-
- // There are several possibilities for the constructor; find one that works.
- // Prefer passing in the flags because required for Application to set the management context
- // TODO Feels very hacky!
-
- Map<Object,Object> flags = Maps.newLinkedHashMap();
- flags.put("id", entityId);
- if (AbstractApplication.class.isAssignableFrom(entityClazz)) flags.put("mgmt", managementContext);
-
- // TODO document the multiple sources of flags, and the reason for setting the mgmt context *and* supplying it as the flag
- // (NB: merge reported conflict as the two things were added separately)
- entity = (Entity) invokeConstructor(null, entityClazz, new Object[] {flags}, new Object[] {flags, null}, new Object[] {null}, new Object[0]);
-
- // In case the constructor didn't take the Map arg, then also set it here.
- // e.g. for top-level app instances such as WebClusterDatabaseExampleApp will (often?) not have
- // interface + constructor.
- // TODO On serializing the memento, we should capture which interfaces so can recreate
- // the proxy+spec (including for apps where there's not an obvious interface).
- FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", entityId), entity);
- if (entity instanceof AbstractApplication) {
- FlagUtils.setFieldsFromFlags(ImmutableMap.of("mgmt", managementContext), entity);
- }
- ((AbstractEntity)entity).setManagementContext(managementContext);
- managementContext.prePreManage(entity);
- }
-
- setCatalogItemId(entity, catalogItemId);
- return entity;
- }
-
- private void setCatalogItemId(BrooklynObject item, String catalogItemId) {
- if (catalogItemId!=null) {
- ((BrooklynObjectInternal)item).setCatalogItemId(catalogItemId);
- }
- }
-
- private <T extends BrooklynObject> Class<? extends T> load(Class<T> bType, Memento memento) {
- return load(bType, memento.getType(), memento.getCatalogItemId(), memento.getId());
- }
- @SuppressWarnings("unchecked")
- private <T extends BrooklynObject> Class<? extends T> load(Class<T> bType, String jType, String catalogItemId, String contextSuchAsId) {
- checkNotNull(jType, "Type of %s (%s) must not be null", contextSuchAsId, bType.getSimpleName());
- if (catalogItemId != null) {
- BrooklynClassLoadingContext loader = getLoadingContextFromCatalogItemId(catalogItemId, classLoader, rebindContext);
- return loader.loadClass(jType, bType);
- } else {
- // we have previously used reflections; not sure if that's needed?
- try {
- return (Class<T>)reflections.loadClass(jType);
- } catch (Exception e) {
- LOG.warn("Unable to load "+jType+" using reflections; will try standard context");
- }
-
- if (BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_INFER_CATALOG_ITEM_ON_REBIND)) {
- //Try loading from whichever catalog bundle succeeds.
- BrooklynCatalog catalog = managementContext.getCatalog();
- for (CatalogItem<?, ?> item : catalog.getCatalogItems()) {
- BrooklynClassLoadingContext catalogLoader = CatalogUtils.newClassLoadingContext(managementContext, item);
- Maybe<Class<?>> catalogClass = catalogLoader.tryLoadClass(jType);
- if (catalogClass.isPresent()) {
- return (Class<? extends T>) catalogClass.get();
- }
- }
- throw new IllegalStateException("No catalogItemId specified and can't load class from either classpath of catalog items");
- } else {
- throw new IllegalStateException("No catalogItemId specified and can't load class from classpath");
- }
-
- }
- }
-
- /**
- * Constructs a new location, passing to its constructor the location id and all of memento.getFlags().
- */
- private Location newLocation(String locationId, String locationType) {
- Class<? extends Location> locationClazz = reflections.loadClass(locationType, Location.class);
-
- if (InternalFactory.isNewStyle(locationClazz)) {
- // Not using loationManager.createLocation(LocationSpec) because don't want init() to be called
- // TODO Need to rationalise this to move code into methods of InternalLocationFactory.
- // But note that we'll change all locations to be entities at some point!
- // See same code approach used in #newEntity(EntityMemento, Reflections)
- InternalLocationFactory locationFactory = managementContext.getLocationFactory();
- Location location = locationFactory.constructLocation(locationClazz);
- FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", locationId), location);
- managementContext.prePreManage(location);
- ((AbstractLocation)location).setManagementContext(managementContext);
-
- return location;
- } else {
- LOG.warn("Deprecated rebind of location without no-arg constructor; this may not be supported in future versions: id="+locationId+"; type="+locationType);
-
- // There are several possibilities for the constructor; find one that works.
- // Prefer passing in the flags because required for Application to set the management context
- // TODO Feels very hacky!
- Map<String,?> flags = MutableMap.of("id", locationId, "deferConstructionChecks", true);
-
- return (Location) invokeConstructor(reflections, locationClazz, new Object[] {flags});
- }
- // note 'used' config keys get marked in BasicLocationRebindSupport
- }
-
- /**
- * Constructs a new policy, passing to its constructor the policy id and all of memento.getConfig().
- */
- private Policy newPolicy(PolicyMemento memento) {
- String id = memento.getId();
- Class<? extends Policy> policyClazz = load(Policy.class, memento.getType(), memento.getCatalogItemId(), id);
-
- Policy policy;
- if (InternalFactory.isNewStyle(policyClazz)) {
- InternalPolicyFactory policyFactory = managementContext.getPolicyFactory();
- policy = policyFactory.constructPolicy(policyClazz);
- FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", id), policy);
- ((AbstractPolicy)policy).setManagementContext(managementContext);
-
- } else {
- LOG.warn("Deprecated rebind of policy without no-arg constructor; this may not be supported in future versions: id="+id+"; type="+policyClazz);
-
- // There are several possibilities for the constructor; find one that works.
- // Prefer passing in the flags because required for Application to set the management context
- // TODO Feels very hacky!
- Map<String, Object> flags = MutableMap.<String, Object>of(
- "id", id,
- "deferConstructionChecks", true,
- "noConstructionInit", true);
- flags.putAll(memento.getConfig());
-
- policy = invokeConstructor(null, policyClazz, new Object[] {flags});
- }
-
- setCatalogItemId(policy, memento.getCatalogItemId());
- return policy;
- }
-
- /**
- * Constructs a new enricher, passing to its constructor the enricher id and all of memento.getConfig().
- */
- private Enricher newEnricher(EnricherMemento memento) {
- Class<? extends Enricher> enricherClazz = load(Enricher.class, memento);
- String id = memento.getId();
-
- Enricher enricher;
- if (InternalFactory.isNewStyle(enricherClazz)) {
- InternalPolicyFactory policyFactory = managementContext.getPolicyFactory();
- enricher = policyFactory.constructEnricher(enricherClazz);
- FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", id), enricher);
- ((AbstractEnricher)enricher).setManagementContext(managementContext);
-
- } else {
- LOG.warn("Deprecated rebind of enricher without no-arg constructor; this may not be supported in future versions: id="+id+"; type="+enricherClazz);
-
- // There are several possibilities for the constructor; find one that works.
- // Prefer passing in the flags because required for Application to set the management context
- // TODO Feels very hacky!
- Map<String, Object> flags = MutableMap.<String, Object>of(
- "id", id,
- "deferConstructionChecks", true,
- "noConstructionInit", true);
- flags.putAll(memento.getConfig());
-
- enricher = invokeConstructor(reflections, enricherClazz, new Object[] {flags});
- }
-
- setCatalogItemId(enricher, memento.getCatalogItemId());
- return enricher;
- }
-
- /**
- * Constructs a new enricher, passing to its constructor the enricher id and all of memento.getConfig().
- */
- private Feed newFeed(FeedMemento memento) {
- Class<? extends Feed> feedClazz = load(Feed.class, memento);
- String id = memento.getId();
-
- Feed feed;
- if (InternalFactory.isNewStyle(feedClazz)) {
- InternalPolicyFactory policyFactory = managementContext.getPolicyFactory();
- feed = policyFactory.constructFeed(feedClazz);
- FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", id), feed);
- ((AbstractFeed)feed).setManagementContext(managementContext);
-
- } else {
- throw new IllegalStateException("rebind of feed without no-arg constructor unsupported: id="+id+"; type="+feedClazz);
- }
-
- setCatalogItemId(feed, memento.getCatalogItemId());
- return feed;
- }
-
- @SuppressWarnings({ "rawtypes" })
- private CatalogItem<?, ?> newCatalogItem(CatalogItemMemento memento) {
- String id = memento.getId();
- // catalog item subtypes are internal to brooklyn, not in osgi
- String itemType = checkNotNull(memento.getType(), "catalog item type of %s must not be null in memento", id);
- Class<? extends CatalogItem> clazz = reflections.loadClass(itemType, CatalogItem.class);
- return invokeConstructor(reflections, clazz, new Object[]{});
- }
-
- private <T> T invokeConstructor(Reflections reflections, Class<T> clazz, Object[]... possibleArgs) {
- for (Object[] args : possibleArgs) {
- try {
- Optional<T> v = Reflections.invokeConstructorWithArgs(clazz, args, true);
- if (v.isPresent()) {
- return v.get();
- }
- } catch (Exception e) {
- throw Exceptions.propagate(e);
- }
- }
- throw new IllegalStateException("Cannot instantiate instance of type "+clazz+"; expected constructor signature not found");
- }
- }
-
/**
* Wraps a ChangeListener, to log and never propagate any exceptions that it throws.
*
@@ -1460,21 +599,8 @@ public class RebindManagerImpl implements RebindManager {
}
}
- /** logs at debug, except during subsequent read-only rebinds, in which it logs trace */
- private void logRebindingDebug(String message, Object... args) {
- if (shouldLogRebinding()) {
- LOG.debug(message, args);
- } else {
- LOG.trace(message, args);
- }
- }
-
- protected boolean shouldLogRebinding() {
- return (readOnlyRebindCount < 5) || (readOnlyRebindCount%1000==0);
- }
-
public int getReadOnlyRebindCount() {
- return readOnlyRebindCount;
+ return readOnlyRebindCount.get();
}
@Override
@@ -1484,7 +610,7 @@ public class RebindManagerImpl implements RebindManager {
result.put("rebind", rebindMetrics.asMap());
result.put("persist", persistMetrics.asMap());
- if (readOnlyRebindCount>=0)
+ if (readOnlyRebindCount.get()>=0)
result.put("rebindReadOnlyCount", readOnlyRebindCount);
// include first rebind counts, so we know whether we rebinded or not
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/55b5f65e/core/src/main/java/brooklyn/entity/rebind/persister/PersistenceActivityMetrics.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/PersistenceActivityMetrics.java b/core/src/main/java/brooklyn/entity/rebind/persister/PersistenceActivityMetrics.java
index 8315156..1167ce6 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/PersistenceActivityMetrics.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/PersistenceActivityMetrics.java
@@ -43,7 +43,7 @@ public class PersistenceActivityMetrics {
count++;
failureCount++;
lastFailureTime = System.currentTimeMillis();
- lastDuration = duration.toMilliseconds();
+ lastDuration = duration!=null ? duration.toMilliseconds() : -1;
}
public void noteError(String error) {