@Override public void stopReadOnly() { readOnlyRunning = false; if (readOnlyTask != null) { LOG.debug( "Stopping read-only rebinding (" + this + "), mgmt " + managementContext.getManagementNodeId()); readOnlyTask.cancel(true); readOnlyTask.blockUntilEnded(); boolean reallyEnded = Tasks.blockUntilInternalTasksEnded(readOnlyTask, Duration.TEN_SECONDS); if (!reallyEnded) { LOG.warn( "Rebind (read-only) tasks took too long to die after interrupt (ignoring): " + readOnlyTask); } readOnlyTask = null; LOG.debug( "Stopped read-only rebinding (" + this + "), mgmt " + managementContext.getManagementNodeId()); } }
public BrooklynCampPlatform setConfigKeyAtManagmentContext() { ((ManagementContextInternal) bmc) .getBrooklynProperties() .put(BrooklynCampConstants.CAMP_PLATFORM, this); ((ManagementContextInternal) bmc) .getBrooklynProperties() .put(CampYamlParser.YAML_PARSER_KEY, new YamlParserImpl(this)); return this; }
@Override public void stopPersistence() { LOG.debug( "Stopping persistence (" + this + "), mgmt " + managementContext.getManagementNodeId()); persistenceRunning = false; if (persistenceRealChangeListener != null) persistenceRealChangeListener.stop(); if (persistenceStoreAccess != null) persistenceStoreAccess.disableWriteAccess(true); LOG.debug("Stopped rebind (persistence), mgmt " + managementContext.getManagementNodeId()); }
protected ManagementNodeState getRebindMode() { if (managementContext == null) throw new IllegalStateException("Invalid " + this + ": no management context"); if (!(managementContext.getHighAvailabilityManager() instanceof HighAvailabilityManagerImpl)) throw new IllegalStateException( "Invalid " + this + ": unknown HA manager type " + managementContext.getHighAvailabilityManager()); ManagementNodeState target = ((HighAvailabilityManagerImpl) managementContext.getHighAvailabilityManager()) .getTransitionTargetNodeState(); return target; }
@Override public void setPersister( BrooklynMementoPersister val, PersistenceExceptionHandler exceptionHandler) { 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); this.persistencePublicChangeListener = new SafeChangeListener(persistenceRealChangeListener); if (persistenceRunning) { persistenceRealChangeListener.start(); } }
@Override public List<Application> rebind( ClassLoader classLoaderO, RebindExceptionHandler exceptionHandlerO, ManagementNodeState modeO) { final ClassLoader classLoader = classLoaderO != null ? classLoaderO : managementContext.getCatalogClassLoader(); final RebindExceptionHandler exceptionHandler = exceptionHandlerO != null ? exceptionHandlerO : RebindExceptionHandlerImpl.builder() .danglingRefFailureMode(danglingRefFailureMode) .danglingRefQuorumRequiredHealthy(danglingRefsQuorumRequiredHealthy) .rebindFailureMode(rebindFailureMode) .addConfigFailureMode(addConfigFailureMode) .addPolicyFailureMode(addPolicyFailureMode) .loadPolicyFailureMode(loadPolicyFailureMode) .build(); final ManagementNodeState mode = modeO != null ? modeO : getRebindMode(); if (mode != ManagementNodeState.MASTER && mode != ManagementNodeState.HOT_STANDBY && mode != ManagementNodeState.HOT_BACKUP) throw new IllegalStateException( "Must be either master or hot standby/backup to rebind (mode " + mode + ")"); ExecutionContext ec = BasicExecutionContext.getCurrentExecutionContext(); if (ec == null) { ec = managementContext.getServerExecutionContext(); Task<List<Application>> task = ec.submit( new Callable<List<Application>>() { @Override public List<Application> call() throws Exception { return rebindImpl(classLoader, exceptionHandler, mode); } }); try { return task.get(); } catch (Exception e) { throw Exceptions.propagate(e); } } else { return rebindImpl(classLoader, exceptionHandler, mode); } }
public void rebindPartialActive(CompoundTransformer transformer, String... objectsToRebindIds) { List<BrooklynObject> objectsToRebind = MutableList.of(); for (String objectId : objectsToRebindIds) { BrooklynObject obj = managementContext.lookup(objectId); objectsToRebind.add(obj); } rebindPartialActive(transformer, objectsToRebind.iterator()); }
@Override public void startPersistence() { if (readOnlyRunning) { throw new IllegalStateException( "Cannot start read-only when already running with persistence"); } LOG.debug( "Starting persistence (" + this + "), mgmt " + managementContext.getManagementNodeId()); if (!persistenceRunning) { if (managementContext .getBrooklynProperties() .getConfig(BrooklynServerConfig.PERSISTENCE_BACKUPS_REQUIRED_ON_PROMOTION)) { BrooklynPersistenceUtils.createBackup( managementContext, CreateBackupMode.PROMOTION, MementoCopyMode.REMOTE); } } persistenceRunning = true; readOnlyRebindCount.set(Integer.MIN_VALUE); persistenceStoreAccess.enableWriteAccess(); if (persistenceRealChangeListener != null) persistenceRealChangeListener.start(); }
public RebindManagerImpl(ManagementContextInternal managementContext) { this.managementContext = managementContext; this.persistencePublicChangeListener = ChangeListener.NOOP; this.persistPoliciesEnabled = BrooklynFeatureEnablement.isEnabled( BrooklynFeatureEnablement.FEATURE_POLICY_PERSISTENCE_PROPERTY); this.persistEnrichersEnabled = BrooklynFeatureEnablement.isEnabled( BrooklynFeatureEnablement.FEATURE_ENRICHER_PERSISTENCE_PROPERTY); this.persistFeedsEnabled = BrooklynFeatureEnablement.isEnabled( BrooklynFeatureEnablement.FEATURE_FEED_PERSISTENCE_PROPERTY); this.persistCatalogItemsEnabled = BrooklynFeatureEnablement.isEnabled( BrooklynFeatureEnablement.FEATURE_CATALOG_PERSISTENCE_PROPERTY); danglingRefFailureMode = managementContext.getConfig().getConfig(DANGLING_REFERENCE_FAILURE_MODE); rebindFailureMode = managementContext.getConfig().getConfig(REBIND_FAILURE_MODE); addConfigFailureMode = managementContext.getConfig().getConfig(ADD_CONFIG_FAILURE_MODE); addPolicyFailureMode = managementContext.getConfig().getConfig(ADD_POLICY_FAILURE_MODE); loadPolicyFailureMode = managementContext.getConfig().getConfig(LOAD_POLICY_FAILURE_MODE); danglingRefsQuorumRequiredHealthy = managementContext.getConfig().getConfig(DANGLING_REFERENCES_MIN_REQUIRED_HEALTHY); LOG.debug( "{} initialized, settings: policies={}, enrichers={}, feeds={}, catalog={}", new Object[] { this, persistPoliciesEnabled, persistEnrichersEnabled, persistFeedsEnabled, persistCatalogItemsEnabled }); }
public void rebindPartialActive( CompoundTransformer transformer, Iterator<BrooklynObject> objectsToRebind) { final ClassLoader classLoader = managementContext.getCatalogClassLoader(); // TODO we might want different exception handling for partials; // failure at various points should leave proxies in a sensible state, // either pointing at old or at new, though this is relatively untested, // and some things e.g. policies might not be properly started final RebindExceptionHandler exceptionHandler = RebindExceptionHandlerImpl.builder() .danglingRefFailureMode(danglingRefFailureMode) .danglingRefQuorumRequiredHealthy(danglingRefsQuorumRequiredHealthy) .rebindFailureMode(rebindFailureMode) .addConfigFailureMode(addConfigFailureMode) .addPolicyFailureMode(addPolicyFailureMode) .loadPolicyFailureMode(loadPolicyFailureMode) .build(); final ManagementNodeState mode = getRebindMode(); ActivePartialRebindIteration iteration = new ActivePartialRebindIteration( this, mode, classLoader, exceptionHandler, rebindActive, readOnlyRebindCount, rebindMetrics, persistenceStoreAccess); iteration.setObjectIterator( Iterators.transform( objectsToRebind, new Function<BrooklynObject, BrooklynObject>() { @Override public BrooklynObject apply(BrooklynObject obj) { // entities must be deproxied if (obj instanceof Entity) obj = Entities.deproxy((Entity) obj); return obj; } })); if (transformer != null) iteration.applyTransformer(transformer); iteration.run(); }
public static Collection<Application> rebindAll(RebindOptions options) throws Exception { File mementoDir = options.mementoDir; File mementoDirBackup = options.mementoDirBackup; ClassLoader classLoader = checkNotNull(options.classLoader, "classLoader"); ManagementContextInternal origManagementContext = (ManagementContextInternal) options.origManagementContext; ManagementContextInternal newManagementContext = (ManagementContextInternal) options.newManagementContext; PersistenceObjectStore objectStore = options.objectStore; HighAvailabilityMode haMode = (options.haMode == null ? HighAvailabilityMode.DISABLED : options.haMode); RebindExceptionHandler exceptionHandler = options.exceptionHandler; boolean hasPersister = newManagementContext != null && newManagementContext.getRebindManager().getPersister() != null; boolean checkSerializable = options.checkSerializable; boolean terminateOrigManagementContext = options.terminateOrigManagementContext; Function<BrooklynMementoPersister, Void> stateTransformer = options.stateTransformer; LOG.info("Rebinding app, using mementoDir " + mementoDir + "; object store " + objectStore); if (newManagementContext == null) { // TODO Could use empty properties, to save reading brooklyn.properties file. // Would that affect any tests? newManagementContext = new LocalManagementContextForTests(BrooklynProperties.Factory.newDefault()); } if (!hasPersister) { if (objectStore == null) { objectStore = new FileBasedObjectStore( checkNotNull(mementoDir, "mementoDir and objectStore must not both be null")); } objectStore.injectManagementContext(newManagementContext); objectStore.prepareForSharedUse(PersistMode.AUTO, haMode); BrooklynMementoPersisterToObjectStore newPersister = new BrooklynMementoPersisterToObjectStore( objectStore, newManagementContext.getBrooklynProperties(), classLoader); newManagementContext .getRebindManager() .setPersister(newPersister, PersistenceExceptionHandlerImpl.builder().build()); } else { if (objectStore != null) throw new IllegalStateException( "Must not supply ManagementContext with persister and an object store"); } if (checkSerializable) { checkNotNull( origManagementContext, "must supply origManagementContext with checkSerializable"); RebindTestUtils.checkCurrentMementoSerializable(origManagementContext); } if (terminateOrigManagementContext) { checkNotNull( origManagementContext, "must supply origManagementContext with terminateOrigManagementContext"); origManagementContext.terminate(); } if (mementoDirBackup != null) { FileUtil.copyDir(mementoDir, mementoDirBackup); FileUtil.setFilePermissionsTo700(mementoDirBackup); } if (stateTransformer != null) { BrooklynMementoPersister persister = newManagementContext.getRebindManager().getPersister(); stateTransformer.apply(persister); } List<Application> newApps = newManagementContext .getRebindManager() .rebind( classLoader, exceptionHandler, (haMode == HighAvailabilityMode.DISABLED) ? ManagementNodeState.MASTER : ManagementNodeState.of(haMode).get()); newManagementContext.getRebindManager().startPersistence(); return newApps; }
@Override public String toString() { return super.toString() + "[mgmt=" + managementContext.getManagementNodeId() + "]"; }
@SuppressWarnings("unchecked") @Override public void startReadOnly(final ManagementNodeState mode) { if (!ManagementNodeState.isHotProxy(mode)) { throw new IllegalStateException( "Read-only rebind thread only permitted for hot proxy modes; not " + mode); } if (persistenceRunning) { throw new IllegalStateException( "Cannot start read-only when already running with persistence"); } if (readOnlyRunning || readOnlyTask != null) { LOG.warn( "Cannot request read-only mode for " + this + " when already running - " + readOnlyTask + "; ignoring"); return; } LOG.debug( "Starting read-only rebinding (" + this + "), mgmt " + managementContext.getManagementNodeId()); if (persistenceRealChangeListener != null) persistenceRealChangeListener.stop(); if (persistenceStoreAccess != null) persistenceStoreAccess.disableWriteAccess(true); readOnlyRunning = true; readOnlyRebindCount.set(0); try { rebind(null, null, mode); } catch (Exception e) { throw Exceptions.propagate(e); } Callable<Task<?>> taskFactory = new Callable<Task<?>>() { @Override public Task<Void> call() { return Tasks.<Void>builder() .dynamic(false) .displayName("rebind (periodic run") .body( new Callable<Void>() { public Void call() { try { rebind(null, null, mode); return null; } catch (RuntimeInterruptedException e) { LOG.debug("Interrupted rebinding (re-interrupting): " + e); if (LOG.isTraceEnabled()) LOG.trace("Interrupted rebinding (re-interrupting), details: " + e, e); Thread.currentThread().interrupt(); return null; } catch (Exception e) { // Don't rethrow: the behaviour of executionManager is different from a // scheduledExecutorService, // if we throw an exception, then our task will never get executed again if (!readOnlyRunning) { LOG.debug( "Problem rebinding (read-only running has probably just been turned off): " + e); if (LOG.isTraceEnabled()) { LOG.trace( "Problem rebinding (read-only running has probably just been turned off), details: " + e, e); } } else { LOG.error("Problem rebinding: " + Exceptions.collapseText(e), e); } return null; } catch (Throwable t) { LOG.warn("Problem rebinding (rethrowing)", t); throw Exceptions.propagate(t); } } }) .build(); } }; readOnlyTask = (ScheduledTask) managementContext .getServerExecutionContext() .submit( new ScheduledTask( MutableMap.of("displayName", "Periodic read-only rebind"), taskFactory) .period(periodicPersistPeriod)); }