This is an automated email from the ASF dual-hosted git repository. heneveld pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
commit 0925e5d440e146bab504d2115b75361740229396 Author: Alex Heneveld <[email protected]> AuthorDate: Mon Sep 13 14:54:37 2021 +0100 more logging and error edge cases catches --- .../catalog/internal/CatalogInitialization.java | 15 +- .../core/catalog/internal/CatalogUtils.java | 8 +- .../core/mgmt/ha/HighAvailabilityManagerImpl.java | 22 +- .../mgmt/internal/LocalSubscriptionManager.java | 13 +- .../brooklyn/core/mgmt/rebind/RebindIteration.java | 563 +++++++++++---------- .../core/mgmt/rebind/RebindManagerImpl.java | 3 + 6 files changed, 339 insertions(+), 285 deletions(-) diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java index 669ab17..4928e8f 100644 --- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java +++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java @@ -241,19 +241,14 @@ public class CatalogInitialization implements ManagementContextInjectable { } synchronized (populatingCatalogMutex) { if (hasRunFinalInitialization()) { - log.warn("Catalog initialization called to add persisted catalog, even though it has already run the final 'master' initialization; mode="+mode+" (perhaps previously demoted from master?)"); + log.warn("Catalog initialization called to add persisted catalog, even though it has already run the final 'master' initialization; mode="+mode, new Throwable("Source of duplicate catalog initialization")); hasRunFinalInitialization = false; } if (hasRunPersistenceInitialization()) { // Multiple calls; will need to reset (only way to clear out the previous persisted state's catalog) if (log.isDebugEnabled()) { String message = "Catalog initialization repeated call to add persisted catalog, resetting catalog (including initial) to start from clean slate; mode="+mode; - if (!ManagementNodeState.isHotProxy(mode)) { - log.debug(message); - } else { - // in hot modes, make this message trace so we don't get too much output then - log.trace(message); - } + log.debug(message); } } else if (hasRunInitialCatalogInitialization()) { throw new IllegalStateException("Catalog initialization already run for initial catalog by mechanism other than populating persisted state; mode="+mode); @@ -433,6 +428,12 @@ public class CatalogInitialization implements ManagementContextInjectable { confirmCatalog(); } + public void clearForSubsequentCatalogInit() { + hasRunInitialCatalogInitialization = false; + hasRunPersistenceInitialization = false; + hasRunFinalInitialization = false; + } + private void populateViaInitialBomImpl(BasicBrooklynCatalog catalog) { // B1) look for --catalog-initial, if so read it, then go to C1 // B2) look for BrooklynServerConfig.BROOKLYN_CATALOG_URL, if so, read it, supporting YAML, then go to C1 diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java index 80c3f29..026c3c0 100644 --- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java +++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java @@ -244,13 +244,13 @@ public class CatalogUtils { if (itemBeingAdded.getCatalogItemId()==null) { if (log.isDebugEnabled()) BrooklynLogging.log(log, BrooklynLogging.levelDebugOrTraceIfReadOnly(entity), - "Catalog item addition: "+entity+" from "+entity.getCatalogItemId()+" applying its catalog item ID to "+itemBeingAdded); + "Entity "+entity+" from "+entity.getCatalogItemId()+" applying its catalog item ID to "+itemBeingAdded); final BrooklynObjectInternal addInternal = (BrooklynObjectInternal) itemBeingAdded; addInternal.setCatalogItemIdAndSearchPath(entity.getCatalogItemId(), entity.getCatalogItemIdSearchPath()); } else { if (!itemBeingAdded.getCatalogItemId().equals(entity.getCatalogItemId())) { - // not a problem, but something to watch out for - log.debug("Cross-catalog item detected: "+entity+" from "+entity.getCatalogItemId()+" has "+itemBeingAdded+" from "+itemBeingAdded.getCatalogItemId()); + // not a problem, but something worth noting + log.debug("Blueprint for "+entity+" from "+entity.getCatalogItemId()+" includes "+itemBeingAdded+" from other catalog "+itemBeingAdded.getCatalogItemId()); } } } else if (itemBeingAdded.getCatalogItemId()!=null) { @@ -270,7 +270,7 @@ public class CatalogUtils { /** @deprecated since 0.12.0 - the "version starts with number" test this does is hokey; use * either {@link RegisteredTypeNaming#isUsableTypeColonVersion(String)} for weak enforcement - * or {@link RegisteredTypeNaming#isGoodTypeColonVersion(String)} for OSGi enforcement. */ + * or {@link RegisteredTypeNaming#isUsableTypeColonVersion(String)} for OSGi enforcement. */ // several references, but all deprecated, most safe to remove after a cycle or two and bad verisons have been warned @Deprecated public static boolean looksLikeVersionedId(String versionedId) { diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java index 2779f4f..2bd080d 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java @@ -288,6 +288,8 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { @VisibleForTesting @Beta public void changeMode(HighAvailabilityMode startMode, boolean preventElectionOnExplicitStandbyMode, boolean failOnExplicitModesIfUnusual) { + LOG.debug("Changing HA mode to "+startMode+", election prevention "+preventElectionOnExplicitStandbyMode+", fail on unusual "+failOnExplicitModesIfUnusual); + if (!running) { // if was not running then start as disabled mode, then proceed as normal LOG.info("HA changing mode to "+startMode+" from "+getInternalNodeState()+" when not running, forcing an intermediate start as DISABLED then will convert to "+startMode); @@ -471,7 +473,9 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { throw Exceptions.propagate(e); } } else { + LOG.debug("Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" restarting read only on transition to "+startMode+" (from "+oldState+" / "+getNodeState()+")"); // transitioning among hot proxy states - tell the rebind manager + // TODO i think we might have previously started _in_ this method, if so we should set a flag and suppress the stop-then-restart managementContext.getRebindManager().stopReadOnly(); managementContext.getRebindManager().startReadOnly(ManagementNodeState.of(startMode).get()); setNodeStateTransitionComplete(true); @@ -534,6 +538,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { } protected void setInternalNodeState(ManagementNodeState newState) { + LOG.debug("HA state internal "+nodeState+" -> "+newState); ManagementNodeState oldState = getInternalNodeState(); synchronized (nodeStateHistory) { if (this.nodeState != newState) { @@ -554,6 +559,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { if (ManagementNodeState.isHotProxy(oldState) && !ManagementNodeState.isHotProxy(newState)) { // could perhaps promote standby items on some transitions; but for now we stop the old read-only and re-load them // TODO ideally there'd be an incremental rebind as well as an incremental persist + LOG.debug("Resetting rebind on hot->cold transition, from "+oldState+" to "+newState); managementContext.getRebindManager().stopReadOnly(); clearManagedItems(ManagementTransitionMode.transitioning(BrooklynObjectManagementMode.LOADED_READ_ONLY, BrooklynObjectManagementMode.UNMANAGED_PERSISTED)); managementContext.getRebindManager().reset(); @@ -564,7 +570,8 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { private void setNodeStateTransitionComplete(boolean val) { nodeStateTransitionComplete = val; - + LOG.debug("HA state transition complete now "+val+" ("+nodeState+" / "+getNodeState()+")"); + // Can cause getNodeState() value to change, so notify listener stateListener.onStateChange(getNodeState()); } @@ -873,6 +880,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { } protected void promoteToMaster() { + LOG.debug("Promoting to master: "+this); if (!running) { LOG.warn("Ignoring promote-to-master request, as HighAvailabilityManager is not running"); return; @@ -907,12 +915,20 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { } protected void demoteTo(ManagementNodeState toState) { + LOG.debug("Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" demoting to "+toState+" (from "+nodeState+" / "+getNodeState()+")"); if (toState!=ManagementNodeState.FAILED && !running) { LOG.warn("Ignoring demote-from-master request, as HighAvailabilityManager is no longer running"); return; } boolean wasMaster = (getInternalNodeState() == ManagementNodeState.MASTER); - if (wasMaster) backupOnDemotionIfNeeded(); + if (wasMaster) { + try { + backupOnDemotionIfNeeded(); + } catch (Exception e) { + Exceptions.propagateIfFatal(e); + LOG.error("Unable to create backup on demotion (ignoring): "+e, e); + } + } // TODO target may be RO ? ManagementTransitionMode mode = ManagementTransitionMode.transitioning( wasMaster ? BrooklynObjectManagementMode.MANAGED_PRIMARY : BrooklynObjectManagementMode.LOADED_READ_ONLY, @@ -947,6 +963,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { protected void onDemotionStopItems(ManagementTransitionMode mode) { // stop persistence and remove all apps etc + LOG.debug("Stopping rebind on demotion to "+mode+" (in state "+nodeState+")"); managementContext.getRebindManager().stopPersistence(); managementContext.getRebindManager().stopReadOnly(); clearManagedItems(mode); @@ -1002,6 +1019,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { * (if not, errors should be stored elsewhere), callers may want to rethrow */ protected ReferenceWithError<Boolean> activateHotProxy(ManagementNodeState toState) { try { + LOG.debug("Activating hot proxy for state "+toState); Preconditions.checkState(nodeStateTransitionComplete==false, "Must be in transitioning state to go into "+toState); setInternalNodeState(toState); managementContext.getRebindManager().startReadOnly(toState); diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalSubscriptionManager.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalSubscriptionManager.java index 9b2cd79..ca39bf8 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalSubscriptionManager.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalSubscriptionManager.java @@ -331,7 +331,14 @@ public class LocalSubscriptionManager extends AbstractSubscriptionManager { } @Override public void run() { - BasicExecutionContext oldEC = ec instanceof BasicExecutionContext ? BasicExecutionContext.setPerThreadExecutionContext((BasicExecutionContext)ec) : null; + BasicExecutionContext oldEC = null; + boolean setEC; + if (ec instanceof BasicExecutionContext) { + oldEC = BasicExecutionContext.setPerThreadExecutionContext((BasicExecutionContext) ec); + setEC = true; + } else { + setEC = false; + } try { if (isEntityStarting) { @@ -362,7 +369,9 @@ public class LocalSubscriptionManager extends AbstractSubscriptionManager { LOG.warn("Error processing subscriptions to "+this+": "+t, t); } } finally { - BasicExecutionContext.setPerThreadExecutionContext(oldEC); + if (setEC) { + BasicExecutionContext.setPerThreadExecutionContext(oldEC); + } } }}; if (!isInitialPublicationOfOldValueInCorrectScheduledThread) { diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java index 38f4af7..c3a7ab7 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java @@ -137,156 +137,158 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; /** -Multi-phase deserialization: - -<ul> -<li> 1. load the manifest files and populate the summaries (ID+type) in {@link BrooklynMementoManifest} -<li> 2. install bundles, instantiate and reconstruct catalog items -<li> 3. instantiate entities+locations -- so that inter-entity references can subsequently - be set during deserialize (and entity config/state is set). -<li> 4. deserialize the manifests to instantiate the mementos -<li> 5. instantiate policies+enrichers+feeds - (could probably merge this with (3), depending how they are implemented) -<li> 6. reconstruct the locations, policies, etc, then finally entities -- setting all fields and then calling - {@link RebindSupport#reconstruct(RebindContext, Memento)} -<li> 7. associate policies+enrichers+feeds to all the entities -<li> 8. manage the entities -</ul> - - 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). - But clearly it would be desirable to have better locking possible against the backing store. - -<p> - When rebinding to code in OSGi bundles, thecatalog item id context is inferred as follows: - * 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 -<p> - 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. -*/ + * Multi-phase deserialization: + * + * <ul> + * <li> 1. load the manifest files and populate the summaries (ID+type) in {@link BrooklynMementoManifest} + * <li> 2. install bundles, instantiate and reconstruct catalog items + * <li> 3. instantiate entities+locations -- so that inter-entity references can subsequently + * be set during deserialize (and entity config/state is set). + * <li> 4. deserialize the manifests to instantiate the mementos + * <li> 5. instantiate policies+enrichers+feeds + * (could probably merge this with (3), depending how they are implemented) + * <li> 6. reconstruct the locations, policies, etc, then finally entities -- setting all fields and then calling + * {@link RebindSupport#reconstruct(RebindContext, Memento)} + * <li> 7. associate policies+enrichers+feeds to all the entities + * <li> 8. manage the entities + * </ul> + * <p> + * 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). + * But clearly it would be desirable to have better locking possible against the backing store. + * + * <p> + * When rebinding to code in OSGi bundles, thecatalog item id context is inferred as follows: + * 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 + * <p> + * 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. + */ public abstract class RebindIteration { private static final Logger LOG = LoggerFactory.getLogger(RebindIteration.class); - + protected final RebindManagerImpl rebindManager; - + protected final ClassLoader classLoader; protected final RebindExceptionHandler exceptionHandler; protected final ManagementNodeState mode; protected final ManagementContextInternal managementContext; - protected final Semaphore rebindActive; + protected final Semaphore rebindActive; protected final AtomicInteger readOnlyRebindCount; protected final PersistenceActivityMetrics rebindMetrics; protected final BrooklynMementoPersister persistenceStoreAccess; - + protected final AtomicBoolean iterationStarted = new AtomicBoolean(); protected final RebindContextImpl rebindContext; protected final Reflections reflections; protected final BrooklynObjectInstantiator instantiator; - + // populated in the course of a run - + // set on run start - + protected Stopwatch timer; - /** phase is used to ensure our steps are run as we've expected, and documented (in javadoc at top). - * it's worth the extra effort due to the complication and the subtleties. */ + /** + * phase is used to ensure our steps are run as we've expected, and documented (in javadoc at top). + * it's worth the extra effort due to the complication and the subtleties. + */ protected int phase = 0; // set in first phase - + protected BrooklynMementoRawData mementoRawData; protected BrooklynMementoManifest mementoManifest; protected Boolean overwritingMaster; protected Boolean isEmpty; // set later on - + protected BrooklynMemento memento; // set near the end - + protected List<Application> applications; - public RebindIteration(RebindManagerImpl rebindManager, - ManagementNodeState mode, - ClassLoader classLoader, RebindExceptionHandler exceptionHandler, - Semaphore rebindActive, AtomicInteger readOnlyRebindCount, PersistenceActivityMetrics rebindMetrics, BrooklynMementoPersister persistenceStoreAccess - ) { + public RebindIteration(RebindManagerImpl rebindManager, + ManagementNodeState mode, + ClassLoader classLoader, RebindExceptionHandler exceptionHandler, + Semaphore rebindActive, AtomicInteger readOnlyRebindCount, PersistenceActivityMetrics rebindMetrics, BrooklynMementoPersister persistenceStoreAccess + ) { // NB: there is no particularly deep meaning in what is passed in vs what is looked up from the RebindManager which calls us // (this is simply a refactoring of previous code to a new class) - + this.rebindManager = rebindManager; - + this.mode = mode; this.classLoader = checkNotNull(classLoader, "classLoader"); this.exceptionHandler = checkNotNull(exceptionHandler, "exceptionHandler"); - - this.rebindActive = rebindActive; + + this.rebindActive = rebindActive; this.readOnlyRebindCount = readOnlyRebindCount; this.rebindMetrics = rebindMetrics; this.persistenceStoreAccess = persistenceStoreAccess; - + managementContext = rebindManager.getManagementContext(); rebindContext = new RebindContextImpl(managementContext, exceptionHandler, classLoader); reflections = new Reflections(classLoader).applyClassRenames(DeserializingClassRenamesProvider.INSTANCE.loadDeserializingMapping()); instantiator = new BrooklynObjectInstantiator(classLoader, rebindContext, reflections); - - if (mode==ManagementNodeState.HOT_STANDBY || mode==ManagementNodeState.HOT_BACKUP) { + + 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+")"); + Preconditions.checkState(mode == ManagementNodeState.MASTER, "Must be either master or read only to rebind (mode " + mode + ")"); } } public List<Application> getApplications() { return applications; } - + RebindContextImpl getRebindContext() { return rebindContext; } - + protected void doRun() throws Exception { - if (readOnlyRebindCount.get()>1) { + if (readOnlyRebindCount.get() > 1) { // wait for tasks Collection<Task<?>> entityTasks = ((BasicExecutionManager) managementContext.getExecutionManager()).allTasksLive() - .stream().filter(t -> BrooklynTaskTags.getContextEntity(t)!=null).collect(Collectors.toList()); + .stream().filter(t -> BrooklynTaskTags.getContextEntity(t) != null).collect(Collectors.toList()); List<Task<?>> openTasks; CountdownTimer time = CountdownTimer.newInstanceStarted(Duration.seconds(15)); do { openTasks = entityTasks.stream().filter(t -> !t.isDone()).collect(Collectors.toList()); if (openTasks.isEmpty()) break; if (time.isExpired()) { - LOG.warn("Aborting "+openTasks.size()+" incomplete task(s) before rebinding again: "+openTasks); + LOG.warn("Aborting " + openTasks.size() + " incomplete task(s) before rebinding again: " + openTasks); openTasks.forEach(t -> t.cancel(true)); } if (time.getDurationElapsed().isShorterThan(Duration.millis(200))) { LOG.info("Waiting on " + openTasks.size() + " task(s) before rebinding again: " + openTasks); - } else { - LOG.debug("Waiting on " + openTasks.size() + " task(s) before rebinding again: " + openTasks); } + LOG.debug("Waiting on " + openTasks.size() + " task(s) before rebinding again, details: " + + openTasks.stream().map(t -> ""+t+"("+BrooklynTaskTags.getContextEntity(t)+")").collect(Collectors.toList())); Time.sleep(Duration.millis(200)); } while (true); - entityTasks.forEach( ((BasicExecutionManager) managementContext.getExecutionManager())::deleteTask ); + entityTasks.forEach(((BasicExecutionManager) managementContext.getExecutionManager())::deleteTask); List<Task<?>> otherDoneTasks = ((BasicExecutionManager) managementContext.getExecutionManager()).allTasksLive() .stream().filter(Task::isDone).collect(Collectors.toList()); - otherDoneTasks.forEach( ((BasicExecutionManager) managementContext.getExecutionManager())::deleteTask ); + otherDoneTasks.forEach(((BasicExecutionManager) managementContext.getExecutionManager())::deleteTask); } loadManifestFiles(); @@ -302,63 +304,67 @@ public abstract class RebindIteration { manageTheObjects(); finishingUp(); } - + protected abstract void loadManifestFiles() throws Exception; - + public void run() { if (iterationStarted.getAndSet(true)) { - throw new IllegalStateException("Iteration "+this+" has already run; create a new instance for another rebind pass."); + throw new IllegalStateException("Iteration " + this + " has already run; create a new instance for another rebind pass."); } try { rebindActive.acquire(); - } catch (InterruptedException e) { Exceptions.propagate(e); } + } catch (InterruptedException e) { + Exceptions.propagate(e); + } try { RebindTracker.setRebinding(); - if (ManagementNodeState.isHotProxy(mode)) + if (ManagementNodeState.isHotProxy(mode)) { readOnlyRebindCount.incrementAndGet(); + } timer = Stopwatch.createStarted(); exceptionHandler.onStart(rebindContext); doRun(); - + exceptionHandler.onDone(); - + rebindMetrics.noteSuccess(Duration.of(timer)); noteErrors(exceptionHandler, null); - + } catch (Exception e) { rebindMetrics.noteFailure(Duration.of(timer)); - + Exceptions.propagateIfFatal(e); noteErrors(exceptionHandler, e); throw exceptionHandler.onFailed(e); - + } finally { rebindActive.release(); RebindTracker.reset(); } } - + protected void checkEnteringPhase(int targetPhase) { phase++; checkContinuingPhase(targetPhase); } + protected void checkContinuingPhase(int targetPhase) { - if (targetPhase!=phase) - throw new IllegalStateException("Phase mismatch: should be phase "+targetPhase+" but is currently "+phase); + if (targetPhase != phase) + throw new IllegalStateException("Phase mismatch: should be phase " + targetPhase + " but is currently " + phase); } - + protected void preprocessManifestFiles() throws Exception { checkContinuingPhase(1); - Preconditions.checkState(mementoRawData!=null, "Memento raw data should be set when calling this"); - Preconditions.checkState(mementoManifest==null, "Memento data should not yet be set when calling this"); - + Preconditions.checkState(mementoRawData != null, "Memento raw data should be set when calling this"); + Preconditions.checkState(mementoManifest == null, "Memento data should not yet be set when calling this"); + // TODO building the manifests should be part of this class (or parent) // it does not have anything to do with the persistence store! mementoManifest = persistenceStoreAccess.loadMementoManifest(mementoRawData, exceptionHandler); - + overwritingMaster = false; isEmpty = mementoManifest.isEmpty(); } @@ -367,12 +373,13 @@ public abstract class RebindIteration { // Build catalog early so we can load other things. // Reads the persisted catalog contents, and passes it all to CatalogInitialization, which decides what to do with it. checkEnteringPhase(2); - + CatalogInitialization.RebindLogger rebindLogger = new CatalogInitialization.RebindLogger() { @Override public void debug(String message, Object... args) { logRebindingDebug(message, args); } + @Override public void info(String message, Object... args) { logRebindingInfo(message, args); @@ -382,18 +389,20 @@ public abstract class RebindIteration { class InstallableManagedBundleImpl implements CatalogInitialization.InstallableManagedBundle { private final ManagedBundleMemento memento; private final ManagedBundle managedBundle; - + InstallableManagedBundleImpl(ManagedBundleMemento memento, ManagedBundle managedBundle) { this.memento = memento; this.managedBundle = managedBundle; } - @Override public ManagedBundle getManagedBundle() { + @Override + public ManagedBundle getManagedBundle() { return managedBundle; } - @Override public Supplier<InputStream> getInputStreamSource() throws IOException { - return InputStreamSource.ofRenewableSupplier("JAR for "+memento, () -> { + @Override + public Supplier<InputStream> getInputStreamSource() throws IOException { + return InputStreamSource.ofRenewableSupplier("JAR for " + memento, () -> { try { return memento.getJarContent().openStream(); } catch (IOException e) { @@ -402,10 +411,10 @@ public abstract class RebindIteration { }); } } - + Map<VersionedName, InstallableManagedBundle> bundles = new LinkedHashMap<>(); - Collection<CatalogItem<?,?>> legacyCatalogItems = new ArrayList<>(); - + Collection<CatalogItem<?, ?>> legacyCatalogItems = new ArrayList<>(); + // Find the bundles if (rebindManager.persistBundlesEnabled) { for (ManagedBundleMemento bundleMemento : mementoManifest.getBundles().values()) { @@ -416,10 +425,10 @@ public abstract class RebindIteration { } else { logRebindingDebug("Not rebinding bundles; feature disabled: {}", mementoManifest.getBundleIds()); } - + // Construct the legacy catalog items; don't add them to the catalog here, // but instead pass them to catalogInitialization.populateCatalog. - + if (rebindManager.persistCatalogItemsEnabled) { // Instantiate catalog items logRebindingDebug("RebindManager instantiating catalog items: {}", mementoManifest.getCatalogItemIds()); @@ -433,7 +442,7 @@ public abstract class RebindIteration { exceptionHandler.onCreateFailed(BrooklynObjectType.CATALOG_ITEM, catalogItemMemento.getId(), catalogItemMemento.getType(), e); } } - + // Reconstruct catalog entries logRebindingDebug("RebindManager reconstructing catalog items"); for (CatalogItemMemento catalogItemMemento : mementoManifest.getCatalogItemMementos().values()) { @@ -460,22 +469,23 @@ public abstract class RebindIteration { // Delegates to CatalogInitialization; see notes there. CatalogInitialization.PersistedCatalogState persistedCatalogState = new CatalogInitialization.PersistedCatalogState(bundles, legacyCatalogItems); - + CatalogInitialization catInit = managementContext.getCatalogInitialization(); + catInit.clearForSubsequentCatalogInit(); catInit.populateInitialAndPersistedCatalog(mode, persistedCatalogState, exceptionHandler, rebindLogger); } protected void instantiateLocationsAndEntities() { checkEnteringPhase(3); - + // 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); @@ -483,18 +493,18 @@ public abstract class RebindIteration { 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(); - + if (LOG.isTraceEnabled()) LOG.trace("RebindManager instantiating entity {}", entityId); - + try { Entity entity = instantiator.newEntity(entityManifest); - ((EntityInternal)entity).getManagementSupport().setReadOnly( rebindContext.isReadOnly(entity) ); + ((EntityInternal) entity).getManagementSupport().setReadOnly(rebindContext.isReadOnly(entity)); rebindContext.registerEntity(entityId, entity); } catch (Exception e) { @@ -504,9 +514,9 @@ public abstract class RebindIteration { } protected void instantiateMementos() throws IOException { - + checkEnteringPhase(4); - + memento = persistenceStoreAccess.loadMemento(mementoRawData, rebindContext.lookup(), exceptionHandler); } @@ -518,23 +528,23 @@ public abstract class RebindIteration { "Expected if this is the first rebind after upgrading to Brooklyn 0.12.0+"); } if (managementContext.getManagementPlaneIdMaybe().isAbsent()) { - ((LocalManagementContext)managementContext).generateManagementPlaneId(); + ((LocalManagementContext) managementContext).generateManagementPlaneId(); } } else { - ((LocalManagementContext)managementContext).setManagementPlaneId(persistedPlaneId); + ((LocalManagementContext) managementContext).setManagementPlaneId(persistedPlaneId); } } protected void instantiateAdjuncts(BrooklynObjectInstantiator instantiator) { - + checkEnteringPhase(5); - + // Instantiate policies if (rebindManager.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); @@ -545,7 +555,7 @@ public abstract class RebindIteration { } else { logRebindingDebug("Not rebinding policies; feature disabled: {}", memento.getPolicyIds()); } - + // Instantiate enrichers if (rebindManager.persistEnrichersEnabled) { logRebindingDebug("RebindManager instantiating enrichers: {}", memento.getEnricherIds()); @@ -561,8 +571,8 @@ public abstract class RebindIteration { } } else { logRebindingDebug("Not rebinding enrichers; feature disabled: {}", memento.getEnricherIds()); - } - + } + // Instantiate feeds if (rebindManager.persistFeedsEnabled) { logRebindingDebug("RebindManager instantiating feeds: {}", memento.getFeedIds()); @@ -582,9 +592,9 @@ public abstract class RebindIteration { } protected void reconstructEverything() { - + checkEnteringPhase(6); - + // Reconstruct locations logRebindingDebug("RebindManager reconstructing locations"); for (LocationMemento locMemento : sortParentFirst(memento.getLocationMementos()).values()) { @@ -595,7 +605,7 @@ public abstract class RebindIteration { exceptionHandler.onNotFound(BrooklynObjectType.LOCATION, locMemento.getId()); } else { try { - ((LocationInternal)location).getRebindSupport().reconstruct(rebindContext, locMemento); + ((LocationInternal) location).getRebindSupport().reconstruct(rebindContext, locMemento); } catch (Exception e) { exceptionHandler.onRebindFailed(BrooklynObjectType.LOCATION, location, e); } @@ -608,7 +618,7 @@ public abstract class RebindIteration { 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()); @@ -629,7 +639,7 @@ public abstract class RebindIteration { for (EnricherMemento enricherMemento : memento.getEnricherMementos().values()) { Enricher enricher = rebindContext.getEnricher(enricherMemento.getId()); logRebindingDebug("RebindManager reconstructing enricher {}", enricherMemento); - + if (enricher == null) { // usually because of creation-failure, when not using fail-fast exceptionHandler.onNotFound(BrooklynObjectType.ENRICHER, enricherMemento.getId()); @@ -643,14 +653,14 @@ public abstract class RebindIteration { } } } - + // Reconstruct feeds if (rebindManager.persistFeedsEnabled) { logRebindingDebug("RebindManager reconstructing feeds"); for (FeedMemento feedMemento : memento.getFeedMementos().values()) { Feed feed = rebindContext.getFeed(feedMemento.getId()); logRebindingDebug("RebindManager reconstructing feed {}", feedMemento); - + if (feed == null) { // usually because of creation-failure, when not using fail-fast exceptionHandler.onNotFound(BrooklynObjectType.FEED, feedMemento.getId()); @@ -665,20 +675,20 @@ public abstract class RebindIteration { } } - + // 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); + ((EntityInternal) entity).getRebindSupport().reconstruct(rebindContext, entityMemento); } catch (Exception e) { exceptionHandler.onRebindFailed(BrooklynObjectType.ENTITY, entity, e); } @@ -693,7 +703,7 @@ public abstract class RebindIteration { for (EntityMemento entityMemento : sortParentFirst(memento.getEntityMementos()).values()) { Entity entity = rebindContext.getEntity(entityMemento.getId()); logRebindingDebug("RebindManager associating adjuncts to entity {}", entityMemento); - + if (entity == null) { // usually because of creation-failure, when not using fail-fast exceptionHandler.onNotFound(BrooklynObjectType.ENTITY, entityMemento.getId()); @@ -705,16 +715,16 @@ public abstract class RebindIteration { 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); + ((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); } } }; - ((EntityInternal)entity).getExecutionContext().get(Tasks.<Void>builder() - .displayName("rebind-adjuncts-"+entity.getId()) + ((EntityInternal) entity).getExecutionContext().get(Tasks.<Void>builder() + .displayName("rebind-adjuncts-" + entity.getId()) .dynamic(false) .body(new RebindAdjuncts(entityMemento, entity, rebindContext, exceptionHandler)) .build()); @@ -741,9 +751,9 @@ public abstract class RebindIteration { 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); + ((EntityInternal) entity).getRebindSupport().addPolicies(rebindContext, entityMemento); + ((EntityInternal) entity).getRebindSupport().addEnrichers(rebindContext, entityMemento); + ((EntityInternal) entity).getRebindSupport().addFeeds(rebindContext, entityMemento); entityMemento = null; entity = null; @@ -756,20 +766,20 @@ public abstract class RebindIteration { protected void manageTheObjects() { checkEnteringPhase(8); - + logRebindingDebug("RebindManager managing locations"); - LocationManagerInternal locationManager = (LocationManagerInternal)managementContext.getLocationManager(); + LocationManagerInternal locationManager = (LocationManagerInternal) managementContext.getLocationManager(); Set<String> oldLocations = Sets.newLinkedHashSet(locationManager.getLocationIds()); - for (Location location: rebindContext.getLocations()) { + for (Location location : rebindContext.getLocations()) { ManagementTransitionMode oldMode = updateTransitionMode(locationManager, location); - if (oldMode!=null) + if (oldMode != null) oldLocations.remove(location.getId()); } - for (Location location: rebindContext.getLocations()) { - if (location.getParent()==null) { + for (Location location : rebindContext.getLocations()) { + if (location.getParent() == null) { // manage all root locations try { - ((LocationManagerInternal)managementContext.getLocationManager()).manageRebindedRoot(location); + ((LocationManagerInternal) managementContext.getLocationManager()).manageRebindedRoot(location); } catch (Exception e) { exceptionHandler.onManageFailed(BrooklynObjectType.LOCATION, location, e); } @@ -777,14 +787,14 @@ public abstract class RebindIteration { } // TODO could also see about purging unreferenced locations cleanupOldLocations(oldLocations); - + // Manage the top-level apps (causing everything under them to become managed) logRebindingDebug("RebindManager managing entities"); - EntityManagerInternal entityManager = (EntityManagerInternal)managementContext.getEntityManager(); + EntityManagerInternal entityManager = (EntityManagerInternal) managementContext.getEntityManager(); Set<String> oldEntities = Sets.newLinkedHashSet(entityManager.getEntityIds()); - for (Entity entity: rebindContext.getEntities()) { + for (Entity entity : rebindContext.getEntities()) { ManagementTransitionMode oldMode = updateTransitionMode(entityManager, entity); - if (oldMode!=null) + if (oldMode != null) oldEntities.remove(entity.getId()); } List<Application> apps = Lists.newArrayList(); @@ -800,7 +810,7 @@ public abstract class RebindIteration { exceptionHandler.onManageFailed(BrooklynObjectType.ENTITY, entity, e); } if (entity instanceof Application) - apps.add((Application)entity); + apps.add((Application) entity); } } cleanupOldEntities(oldEntities); @@ -810,10 +820,10 @@ public abstract class RebindIteration { private <T extends BrooklynObject> ManagementTransitionMode updateTransitionMode(BrooklynObjectManagerInternal<T> boManager, T bo) { ManagementTransitionMode oldTransitionMode = boManager.getLastManagementTransitionMode(bo.getId()); - + Boolean isNowReadOnly = rebindContext.isReadOnly(bo); - BrooklynObjectManagementMode modeBefore, modeAfter; - if (oldTransitionMode==null) { + BrooklynObjectManagementMode modeBefore, modeAfter; + if (oldTransitionMode == null) { modeBefore = BrooklynObjectManagementMode.UNMANAGED_PERSISTED; } else { modeBefore = oldTransitionMode.getModeAfter(); @@ -821,14 +831,14 @@ public abstract class RebindIteration { if (isRebindingActiveAgain()) { Preconditions.checkState(!Boolean.TRUE.equals(isNowReadOnly)); - Preconditions.checkState(modeBefore==BrooklynObjectManagementMode.MANAGED_PRIMARY); + Preconditions.checkState(modeBefore == BrooklynObjectManagementMode.MANAGED_PRIMARY); modeAfter = BrooklynObjectManagementMode.MANAGED_PRIMARY; } else if (isNowReadOnly) { modeAfter = BrooklynObjectManagementMode.LOADED_READ_ONLY; } else { modeAfter = BrooklynObjectManagementMode.MANAGED_PRIMARY; } - + ManagementTransitionMode newTransitionMode = ManagementTransitionMode.transitioning(modeBefore, modeAfter); boManager.setManagementTransitionMode(bo, newTransitionMode); return oldTransitionMode; @@ -841,24 +851,25 @@ public abstract class RebindIteration { } protected abstract void cleanupOldLocations(Set<String> oldLocations); + protected abstract void cleanupOldEntities(Set<String> oldEntities); protected void finishingUp() { - + checkContinuingPhase(8); - + if (!isEmpty) { - BrooklynLogging.log(LOG, shouldLogRebinding() ? LoggingLevel.INFO : LoggingLevel.DEBUG, - "Rebind complete " + "("+mode+(readOnlyRebindCount.get()>=0 ? ", iteration "+readOnlyRebindCount : "")+")" + - " in {}: {} app{}, {} entit{}, {} location{}, {} polic{}, {} enricher{}, {} feed{}, {} catalog item{}, {} catalog bundle{}", - Time.makeTimeStringRounded(timer), applications.size(), Strings.s(applications), - 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()), - rebindContext.getBundles().size(), Strings.s(rebindContext.getBundles()) + BrooklynLogging.log(LOG, shouldLogRebinding() ? LoggingLevel.INFO : LoggingLevel.DEBUG, + "Rebind complete " + "(" + mode + (readOnlyRebindCount.get() >= 0 ? ", iteration " + readOnlyRebindCount : "") + ")" + + " in {}: {} app{}, {} entit{}, {} location{}, {} polic{}, {} enricher{}, {} feed{}, {} catalog item{}, {} catalog bundle{}", + Time.makeTimeStringRounded(timer), applications.size(), Strings.s(applications), + 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()), + rebindContext.getBundles().size(), Strings.s(rebindContext.getBundles()) ); } @@ -869,11 +880,11 @@ public abstract class RebindIteration { protected void noteErrors(final RebindExceptionHandler exceptionHandler, Exception primaryException) { List<Exception> exceptions = exceptionHandler.getExceptions(); List<String> warnings = exceptionHandler.getWarnings(); - if (primaryException!=null || !exceptions.isEmpty() || !warnings.isEmpty()) { + 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); + 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); } } @@ -886,16 +897,22 @@ public abstract class RebindIteration { this.catalogItemId = catalogItemId; this.searchPath = searchPath; } - public String getCatalogItemId() { return catalogItemId; } - public List<String> getSearchPath() { return searchPath; } + + public String getCatalogItemId() { + return catalogItemId; + } + + public List<String> getSearchPath() { + return searchPath; + } } protected CatalogItemIdAndSearchPath findCatalogItemIds(ClassLoader cl, Map<String, - EntityMementoManifest> entityIdToManifest, EntityMementoManifest entityManifest) { + EntityMementoManifest> entityIdToManifest, EntityMementoManifest entityManifest) { if (entityManifest.getCatalogItemId() != null) { return new CatalogItemIdAndSearchPath(entityManifest.getCatalogItemId(), - entityManifest.getCatalogItemIdSearchPath()); + entityManifest.getCatalogItemIdSearchPath()); } if (BrooklynFeatureEnablement.isEnabled(FEATURE_BACKWARDS_COMPATIBILITY_INFER_CATALOG_ITEM_ON_REBIND)) { @@ -939,7 +956,7 @@ public abstract class RebindIteration { while (ptr != null) { RegisteredType t = types.get(ptr.getType(), BrooklynCatalog.DEFAULT_VERSION); if (t != null) { - LOG.debug("Inferred catalog item ID "+t.getId()+" for "+entityManifest+" from ancestor "+ptr); + LOG.debug("Inferred catalog item ID " + t.getId() + " for " + entityManifest + " from ancestor " + ptr); return new CatalogItemIdAndSearchPath(t.getId(), ImmutableList.<String>of()); } if (ptr.getParent() != null) { @@ -961,7 +978,7 @@ public abstract class RebindIteration { boolean canLoadClass = loader.tryLoadClass(entityManifest.getType()).isPresent(); if (canLoadClass) { LOG.warn("Missing catalog item for " + entityManifest.getId() + " (" + entityManifest.getType() - + "), inferring as " + item.getId() + " because that is able to load the item"); + + "), inferring as " + item.getId() + " because that is able to load the item"); return new CatalogItemIdAndSearchPath(item.getId(), ImmutableList.<String>of()); } } @@ -986,7 +1003,7 @@ public abstract class RebindIteration { protected final ClassLoader classLoader; protected final RebindContextImpl rebindContext; protected final Reflections reflections; - + protected BrooklynObjectInstantiator(ClassLoader classLoader, RebindContextImpl rebindContext, Reflections reflections) { this.classLoader = classLoader; this.rebindContext = rebindContext; @@ -996,15 +1013,15 @@ public abstract class RebindIteration { protected Entity newEntity(EntityMementoManifest entityManifest) { String entityId = entityManifest.getId(); CatalogItemIdAndSearchPath idPath = - findCatalogItemIds(classLoader, mementoManifest.getEntityIdToManifest(), entityManifest); + findCatalogItemIds(classLoader, mementoManifest.getEntityIdToManifest(), entityManifest); String entityType = entityManifest.getType(); LoadedClass<? extends Entity> loaded = - load(Entity.class, entityType, idPath.getCatalogItemId(), idPath.getSearchPath(), entityId); + load(Entity.class, entityType, idPath.getCatalogItemId(), idPath.getSearchPath(), entityId); Class<? extends Entity> entityClazz = loaded.clazz; 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. @@ -1013,13 +1030,13 @@ public abstract class RebindIteration { } else { LOG.warn("Deprecated rebind of entity without no-arg constructor; " + - "this may not be supported in future versions: id=" + entityId+"; type=" + entityType); + "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(); + Map<Object, Object> flags = Maps.newLinkedHashMap(); flags.put("id", entityId); if (AbstractApplication.class.isAssignableFrom(entityClazz)) flags.put("mgmt", managementContext); @@ -1027,7 +1044,7 @@ public abstract class RebindIteration { // supplying it as the flag // (NB: merge reported conflict as the two things were added separately) entity = invokeConstructor(null, entityClazz, - new Object[] {flags}, new Object[] {flags, null}, new Object[] {null}, new Object[0]); + 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 @@ -1038,7 +1055,7 @@ public abstract class RebindIteration { if (entity instanceof AbstractApplication) { FlagUtils.setFieldsFromFlags(ImmutableMap.of("mgmt", managementContext), entity); } - ((AbstractEntity)entity).setManagementContext(managementContext); + ((AbstractEntity) entity).setManagementContext(managementContext); managementContext.prePreManage(entity); } @@ -1055,29 +1072,29 @@ public abstract class RebindIteration { protected <T extends BrooklynObject> LoadedClass<? extends T> load(Class<T> bType, Memento memento) { return load(bType, memento.getType(), memento.getCatalogItemId(), memento.getCatalogItemIdSearchPath(), - memento.getId()); + memento.getId()); } - + @SuppressWarnings("unchecked") // TODO should prefer a registered type as the type to load (in lieu of jType), // but note some callers (enrichers etc) use catalogItemId to be the first entry in search path rather than their actual type, // so until callers are all updated all we can do here is load the java type with no guarantee the catalogItemId should be the same. // (yoml should help a lot with this.) protected <T extends BrooklynObject> LoadedClass<? extends T> load(Class<T> bType, String jType, - String catalogItemId, List<String> searchPath, String contextSuchAsId) { + String catalogItemId, List<String> searchPath, String contextSuchAsId) { checkNotNull(jType, "Type of %s (%s) must not be null", contextSuchAsId, bType.getSimpleName()); CatalogUpgrades.markerForCodeThatLoadsJavaTypesButShouldLoadRegisteredType(); - + List<String> warnings = MutableList.of(); List<String> reboundSearchPath = MutableList.of(); if (searchPath != null && !searchPath.isEmpty()) { for (String searchItemId : searchPath) { String fixedSearchItemId = null; OsgiManager osgi = managementContext.getOsgiManager().orNull(); - if (osgi!=null) { + if (osgi != null) { ManagedBundle bundle = osgi.getManagedBundle(VersionedName.fromString(searchItemId)); - if (bundle!=null) { + if (bundle != null) { // found as bundle reboundSearchPath.add(searchItemId); continue; @@ -1086,56 +1103,56 @@ public abstract class RebindIteration { // look for as a type now RegisteredType t1 = managementContext.getTypeRegistry().get(searchItemId); - if (t1==null) { + if (t1 == null) { String newSearchItemId = CatalogUpgrades.getTypeUpgradedIfNecessary(managementContext, searchItemId); if (!newSearchItemId.equals(searchItemId)) { - logRebindingDebug("Upgrading search path entry of "+bType.getSimpleName().toLowerCase()+" "+contextSuchAsId+" from "+searchItemId+" to "+newSearchItemId); + logRebindingDebug("Upgrading search path entry of " + bType.getSimpleName().toLowerCase() + " " + contextSuchAsId + " from " + searchItemId + " to " + newSearchItemId); searchItemId = newSearchItemId; t1 = managementContext.getTypeRegistry().get(newSearchItemId); } } - if (t1!=null) fixedSearchItemId = t1.getId(); - if (fixedSearchItemId==null) { + if (t1 != null) fixedSearchItemId = t1.getId(); + if (fixedSearchItemId == null) { CatalogItem<?, ?> ci = findCatalogItemInReboundCatalog(bType, searchItemId, contextSuchAsId); - if (ci!=null) { + if (ci != null) { fixedSearchItemId = ci.getCatalogItemId(); - logRebindingWarn("Needed rebind catalog to resolve search path entry "+searchItemId+" (now "+fixedSearchItemId+") for "+bType.getSimpleName().toLowerCase()+" "+contextSuchAsId+ - ", persistence should remove this in future but future versions will not support this and definitions should be fixed"); + logRebindingWarn("Needed rebind catalog to resolve search path entry " + searchItemId + " (now " + fixedSearchItemId + ") for " + bType.getSimpleName().toLowerCase() + " " + contextSuchAsId + + ", persistence should remove this in future but future versions will not support this and definitions should be fixed"); } else { - logRebindingWarn("Could not find search path entry "+searchItemId+" for "+bType.getSimpleName().toLowerCase()+" "+contextSuchAsId+", ignoring"); + logRebindingWarn("Could not find search path entry " + searchItemId + " for " + bType.getSimpleName().toLowerCase() + " " + contextSuchAsId + ", ignoring"); } } if (fixedSearchItemId != null) { reboundSearchPath.add(fixedSearchItemId); } else { - warnings.add("unable to resolve search path entry "+ searchItemId); + warnings.add("unable to resolve search path entry " + searchItemId); } } } if (catalogItemId != null) { String transformedCatalogItemId = null; - + Maybe<RegisteredType> contextRegisteredType = managementContext.getTypeRegistry().getMaybe(catalogItemId, - // this is context RT, not item we are loading, so bType does not apply here - // if we were instantiating from an RT instead of a JT (ideal) then we would use bType to filter - null ); + // this is context RT, not item we are loading, so bType does not apply here + // if we were instantiating from an RT instead of a JT (ideal) then we would use bType to filter + null); if (contextRegisteredType.isAbsent()) { transformedCatalogItemId = CatalogUpgrades.getTypeUpgradedIfNecessary(managementContext, catalogItemId); if (!transformedCatalogItemId.equals(catalogItemId)) { // catalog item id is sometimes the type of the item, but sometimes just the first part of the search path - logRebindingInfo("Upgrading "+bType.getSimpleName().toLowerCase()+" "+contextSuchAsId+ - " stored catalog item context on rebind"+ - " from "+catalogItemId+" to "+transformedCatalogItemId); - + logRebindingInfo("Upgrading " + bType.getSimpleName().toLowerCase() + " " + contextSuchAsId + + " stored catalog item context on rebind" + + " from " + catalogItemId + " to " + transformedCatalogItemId); + // again ignore bType contextRegisteredType = managementContext.getTypeRegistry().getMaybe(transformedCatalogItemId, null); - + } else { transformedCatalogItemId = null; } } - + if (contextRegisteredType.isPresent()) { transformedCatalogItemId = contextRegisteredType.get().getId(); } else { @@ -1144,20 +1161,20 @@ public abstract class RebindIteration { transformedCatalogItemId = catalogItem.getCatalogItemId(); } } - if (transformedCatalogItemId!=null) { + if (transformedCatalogItemId != null) { try { BrooklynClassLoadingContextSequential loader = - new BrooklynClassLoadingContextSequential(managementContext); + new BrooklynClassLoadingContextSequential(managementContext); loader.add(newClassLoadingContextForCatalogItems(managementContext, transformedCatalogItemId, - reboundSearchPath)); + reboundSearchPath)); return new LoadedClass<T>(loader.loadClass(jType, bType), transformedCatalogItemId, reboundSearchPath); } catch (Exception e) { Exceptions.propagateIfFatal(e); - warnings.add("unable to load class "+jType+" for resovled context type "+transformedCatalogItemId); + warnings.add("unable to load class " + jType + " for resovled context type " + transformedCatalogItemId); } } else { // TODO fail, rather than fallback to java? - warnings.add("unable to resolve context type "+catalogItemId); + warnings.add("unable to resolve context type " + catalogItemId); } } else { // can happen for enrichers etc added by java, and for BasicApplication when things are deployed; @@ -1165,9 +1182,9 @@ public abstract class RebindIteration { } try { - Class<T> jTypeC = (Class<T>)loadClass(jType); + Class<T> jTypeC = (Class<T>) loadClass(jType); if (!warnings.isEmpty()) { - LOG.warn("Loaded java type "+jType+" for "+bType.getSimpleName().toLowerCase()+" "+contextSuchAsId+" but had errors: "+Strings.join(warnings, ";")); + LOG.warn("Loaded java type " + jType + " for " + bType.getSimpleName().toLowerCase() + " " + contextSuchAsId + " but had errors: " + Strings.join(warnings, ";")); } return new LoadedClass<T>(jTypeC, catalogItemId, reboundSearchPath); } catch (Exception e) { @@ -1175,10 +1192,10 @@ public abstract class RebindIteration { } if (catalogItemId != null) { - String msg = "Class "+jType+" not found for "+bType.getSimpleName().toLowerCase()+" "+contextSuchAsId+" ("+catalogItemId+"): "+Strings.join(warnings, ";"); - LOG.warn(msg+" (rethrowing)"); + String msg = "Class " + jType + " not found for " + bType.getSimpleName().toLowerCase() + " " + contextSuchAsId + " (" + catalogItemId + "): " + Strings.join(warnings, ";"); + LOG.warn(msg + " (rethrowing)"); throw new IllegalStateException(msg); - + } else if (BrooklynFeatureEnablement.isEnabled(FEATURE_BACKWARDS_COMPATIBILITY_INFER_CATALOG_ITEM_ON_REBIND)) { //Try loading from whichever catalog bundle succeeds (legacy CI items only; also disabling this, as no longer needed 2017-09) BrooklynCatalog catalog = managementContext.getCatalog(); @@ -1186,26 +1203,26 @@ public abstract class RebindIteration { BrooklynClassLoadingContext catalogLoader = CatalogUtils.newClassLoadingContext(managementContext, item); Maybe<Class<?>> catalogClass = catalogLoader.tryLoadClass(jType); if (catalogClass.isPresent()) { - LOG.warn("Falling back to java type "+jType+" for "+bType.getSimpleName().toLowerCase()+" "+contextSuchAsId+" using catalog search paths, found on "+item+ - (warnings.isEmpty() ? "" : ", after errors: "+Strings.join(warnings, ";"))); + LOG.warn("Falling back to java type " + jType + " for " + bType.getSimpleName().toLowerCase() + " " + contextSuchAsId + " using catalog search paths, found on " + item + + (warnings.isEmpty() ? "" : ", after errors: " + Strings.join(warnings, ";"))); return new LoadedClass<T>((Class<? extends T>) catalogClass.get(), catalogItemId, reboundSearchPath); } } - String msg = "Class "+jType+" not found for "+bType.getSimpleName().toLowerCase()+" "+contextSuchAsId+", even after legacy global classpath search"+ - (warnings.isEmpty() ? "" : ": "+Strings.join(warnings, ";")); - LOG.warn(msg+" (rethrowing)"); + String msg = "Class " + jType + " not found for " + bType.getSimpleName().toLowerCase() + " " + contextSuchAsId + ", even after legacy global classpath search" + + (warnings.isEmpty() ? "" : ": " + Strings.join(warnings, ";")); + LOG.warn(msg + " (rethrowing)"); throw new IllegalStateException(msg); } else { - String msg = "Class "+jType+" not found for "+bType.getSimpleName().toLowerCase()+" "+contextSuchAsId+ - (warnings.isEmpty() ? "" : ": "+Strings.join(warnings, ";")); - LOG.warn(msg+" (rethrowing)"); + String msg = "Class " + jType + " not found for " + bType.getSimpleName().toLowerCase() + " " + contextSuchAsId + + (warnings.isEmpty() ? "" : ": " + Strings.join(warnings, ";")); + LOG.warn(msg + " (rethrowing)"); throw new IllegalStateException(msg); } } private <T extends BrooklynObject> CatalogItem<?, ?> findCatalogItemInReboundCatalog(Class<T> bType, - String catalogItemId, String contextSuchAsId) { + String catalogItemId, String contextSuchAsId) { CatalogItem<?, ?> catalogItem = rebindContext.lookup().lookupCatalogItem(catalogItemId); if (catalogItem == null) { if (BrooklynFeatureEnablement.isEnabled(FEATURE_AUTO_FIX_CATALOG_REF_ON_REBIND)) { @@ -1220,8 +1237,8 @@ public abstract class RebindIteration { if (catalogItem != null) { LOG.warn("Unable to load catalog item " + catalogItemId + " for " + contextSuchAsId - + " (" + bType.getSimpleName() + "); will auto-upgrade to " - + catalogItem.getCatalogItemId() + ":" + catalogItem.getVersion()); + + " (" + bType.getSimpleName() + "); will auto-upgrade to " + + catalogItem.getCatalogItemId() + ":" + catalogItem.getVersion()); } } } @@ -1231,7 +1248,7 @@ public abstract class RebindIteration { protected Class<?> loadClass(String jType) throws ClassNotFoundException { try { - return reflections.loadClass(jType); + return reflections.loadClass(jType); } catch (Exception e) { Exceptions.propagateIfFatal(e); } @@ -1262,19 +1279,19 @@ public abstract class RebindIteration { Location location = locationFactory.constructLocation(locationClazz); FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", locationId), location); managementContext.prePreManage(location); - ((AbstractLocation)location).setManagementContext(managementContext); + ((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); + "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); + Map<String, ?> flags = MutableMap.of("id", locationId, "deferConstructionChecks", true); - return invokeConstructor(reflections, locationClazz, new Object[] {flags}); + return invokeConstructor(reflections, locationClazz, new Object[]{flags}); } // note 'used' config keys get marked in BasicLocationRebindSupport } @@ -1292,25 +1309,25 @@ public abstract class RebindIteration { InternalPolicyFactory policyFactory = managementContext.getPolicyFactory(); policy = policyFactory.constructPolicy(policyClazz); FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", id), policy); - ((AbstractPolicy)policy).setManagementContext(managementContext); - ((AbstractPolicy)policy).setHighlights(memento.getHighlights()); + ((AbstractPolicy) policy).setManagementContext(managementContext); + ((AbstractPolicy) policy).setHighlights(memento.getHighlights()); } else { LOG.warn("Deprecated rebind of policy without no-arg constructor; " + - "this may not be supported in future versions: id=" + id + "; type="+policyClazz); + "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); + "id", id, + "deferConstructionChecks", true, + "noConstructionInit", true); flags.putAll(memento.getConfig()); - policy = invokeConstructor(null, policyClazz, new Object[] {flags}); + policy = invokeConstructor(null, policyClazz, new Object[]{flags}); } - + setCatalogItemIds(policy, loaded.catalogItemId, loaded.searchPath); return policy; } @@ -1328,24 +1345,24 @@ public abstract class RebindIteration { InternalPolicyFactory policyFactory = managementContext.getPolicyFactory(); enricher = policyFactory.constructEnricher(enricherClazz); FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", id), enricher); - ((AbstractEnricher)enricher).setManagementContext(managementContext); + ((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); + "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); + "id", id, + "deferConstructionChecks", true, + "noConstructionInit", true); flags.putAll(memento.getConfig()); - enricher = invokeConstructor(reflections, enricherClazz, new Object[] {flags}); + enricher = invokeConstructor(reflections, enricherClazz, new Object[]{flags}); } - + setCatalogItemIds(enricher, loaded.catalogItemId, loaded.searchPath); return enricher; } @@ -1363,18 +1380,18 @@ public abstract class RebindIteration { InternalPolicyFactory policyFactory = managementContext.getPolicyFactory(); feed = policyFactory.constructFeed(feedClazz); FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", id), feed); - ((AbstractFeed)feed).setManagementContext(managementContext); + ((AbstractFeed) feed).setManagementContext(managementContext); } else { throw new IllegalStateException("rebind of feed without no-arg constructor unsupported: id=" + id + - "; type="+feedClazz); + "; type=" + feedClazz); } - + setCatalogItemIds(feed, loaded.catalogItemId, loaded.searchPath); return feed; } - @SuppressWarnings({ "rawtypes" }) + @SuppressWarnings({"rawtypes"}) protected CatalogItem<?, ?> newCatalogItem(CatalogItemMemento memento) { String id = memento.getId(); // catalog item subtypes are internal to brooklyn, not in osgi @@ -1389,7 +1406,7 @@ public abstract class RebindIteration { FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", memento.getId()), result); return result; } - + protected <T> T invokeConstructor(Reflections reflections, Class<T> clazz, Object[]... possibleArgs) { for (Object[] args : possibleArgs) { try { @@ -1402,29 +1419,31 @@ public abstract class RebindIteration { } } StringBuilder args = new StringBuilder(); - if (possibleArgs.length<1) args.append("no possible argument sets supplied; error"); - else if (possibleArgs.length<2) args.append("args are "+Arrays.asList(possibleArgs[0])); + if (possibleArgs.length < 1) args.append("no possible argument sets supplied; error"); + else if (possibleArgs.length < 2) args.append("args are " + Arrays.asList(possibleArgs[0])); else { - args.append("args are "+Arrays.asList(possibleArgs[0])); - for (int i=1; i<possibleArgs.length; i++) { + args.append("args are " + Arrays.asList(possibleArgs[0])); + for (int i = 1; i < possibleArgs.length; i++) { args.append(" or "); args.append(Arrays.asList(possibleArgs[i])); } } throw new IllegalStateException("Cannot instantiate instance of type " + clazz + - "; expected constructor signature not found ("+args+")"); + "; expected constructor signature not found (" + args + ")"); } } protected BrooklynMementoPersister getPersister() { return rebindManager.getPersister(); } - + protected <T extends TreeNode> Map<String, T> sortParentFirst(Map<String, T> nodes) { return RebindManagerImpl.sortParentFirst(nodes); } - /** logs at debug, except during subsequent read-only rebinds, in which it logs trace */ + /** + * logs at debug, except during subsequent read-only rebinds, in which it logs trace + */ protected void logRebindingDebug(String message, Object... args) { if (shouldLogRebinding()) { LOG.debug(message, args); @@ -1432,8 +1451,10 @@ public abstract class RebindIteration { LOG.trace(message, args); } } - - /** logs at info, except during subsequent read-only rebinds, in which it logs trace */ + + /** + * logs at info, except during subsequent read-only rebinds, in which it logs trace + */ protected void logRebindingInfo(String message, Object... args) { if (shouldLogRebinding()) { LOG.info(message, args); @@ -1441,8 +1462,10 @@ public abstract class RebindIteration { LOG.trace(message, args); } } - - /** logs at warn, except during subsequent read-only rebinds, in which it logs trace */ + + /** + * logs at warn, except during subsequent read-only rebinds, in which it logs trace + */ protected void logRebindingWarn(String message, Object... args) { if (shouldLogRebinding()) { LOG.warn(message, args); @@ -1450,9 +1473,9 @@ public abstract class RebindIteration { LOG.trace(message, args); } } - + protected boolean shouldLogRebinding() { - return (readOnlyRebindCount.get() < 5) || (readOnlyRebindCount.get()%1000==0); + return (readOnlyRebindCount.get() < 5) || (readOnlyRebindCount.get() % 1000 == 0); } } diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java index 3a597ab..8f6d6af 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java @@ -312,6 +312,7 @@ public class RebindManagerImpl implements RebindManager { @Override public void startReadOnly(final ManagementNodeState mode) { + LOG.debug("Starting RO rebind for "+mode+": "+this); if (!ManagementNodeState.isHotProxy(mode)) { throw new IllegalStateException("Read-only rebind thread only permitted for hot proxy modes; not "+mode); } @@ -370,6 +371,7 @@ public class RebindManagerImpl implements RebindManager { }}).build(); } }; + LOG.debug("Submitted scheduled RO rebind task for "+mode+": "+this); readOnlyTask = (ScheduledTask) managementContext.getServerExecutionContext().submit( ScheduledTask.builder(taskFactory).displayName("scheduled:[periodic-read-only-rebind]").period(periodicPersistPeriod).build() ); } @@ -409,6 +411,7 @@ public class RebindManagerImpl implements RebindManager { @Override public void stop() { + LOG.debug("Stopping rebind manager "+this); stopReadOnly(); stopPersistence(); if (persistenceStoreAccess != null) persistenceStoreAccess.stop(true);
