@Override public void connectSensors() { super.connectSensors(); connectServiceUpIsRunning(); HostAndPort hostAndPort = BrooklynAccessUtils.getBrooklynAccessibleAddress(this, sensors().get(DOCKER_REGISTRY_PORT)); sensors().set(Attributes.MAIN_URI, URI.create("https://" + hostAndPort + "/v2")); httpFeed = HttpFeed.builder() .entity(this) .period(Duration.seconds(3)) .baseUri(getAttribute(Attributes.MAIN_URI)) .poll( new HttpPollConfig<Boolean>(Attributes.SERVICE_UP) .onSuccess(Functions.constant(true)) .onFailureOrException(Functions.constant(false))) .poll( new HttpPollConfig<List<String>>(DOCKER_REGISTRY_CATALOG) .suburl("/_catalog") .onSuccess( Functionals.chain( HttpValueFunctions.jsonContents(), JsonFunctions.walk("repositories"), JsonFunctions.forEach(JsonFunctions.cast(String.class)))) .onFailureOrException(Functions.constant(Collections.<String>emptyList()))) .build(); }
@Override public Cidr get() { Cidr local = cidr; if (local == null) { synchronized (this) { local = cidr; if (local == null) { String externalIp = LocalhostExternalIpLoader.getLocalhostIpWithin(Duration.seconds(5)); cidr = local = new Cidr(externalIp + "/32"); } } } return local; }
@Override public ComputeService findComputeService(ConfigBag conf, boolean allowReuse) { String provider = checkNotNull(conf.get(CLOUD_PROVIDER), "provider must not be null"); String identity = checkNotNull(conf.get(CloudLocationConfig.ACCESS_IDENTITY), "identity must not be null"); String credential = checkNotNull( conf.get(CloudLocationConfig.ACCESS_CREDENTIAL), "credential must not be null"); Properties properties = new Properties(); properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true)); properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true)); properties.setProperty( "jclouds.ssh.max-retries", conf.getStringKey("jclouds.ssh.max-retries") != null ? conf.getStringKey("jclouds.ssh.max-retries").toString() : "50"); // Enable aws-ec2 lazy image fetching, if given a specific imageId; otherwise customize for // specific owners; or all as a last resort // See https://issues.apache.org/jira/browse/WHIRR-416 if ("aws-ec2".equals(provider)) { // TODO convert AWS-only flags to config keys if (groovyTruth(conf.get(IMAGE_ID))) { properties.setProperty(PROPERTY_EC2_AMI_QUERY, ""); properties.setProperty(PROPERTY_EC2_CC_AMI_QUERY, ""); } else if (groovyTruth(conf.getStringKey("imageOwner"))) { properties.setProperty( PROPERTY_EC2_AMI_QUERY, "owner-id=" + conf.getStringKey("imageOwner") + ";state=available;image-type=machine"); } else if (groovyTruth(conf.getStringKey("anyOwner"))) { // set `anyOwner: true` to override the default query (which is restricted to certain owners // as per below), // allowing the AMI query to bind to any machine // (note however, we sometimes pick defaults in JcloudsLocationFactory); // (and be careful, this can give a LOT of data back, taking several minutes, // and requiring extra memory allocated on the command-line) properties.setProperty(PROPERTY_EC2_AMI_QUERY, "state=available;image-type=machine"); /* * by default the following filters are applied: * Filter.1.Name=owner-id&Filter.1.Value.1=137112412989& * Filter.1.Value.2=063491364108& * Filter.1.Value.3=099720109477& * Filter.1.Value.4=411009282317& * Filter.2.Name=state&Filter.2.Value.1=available& * Filter.3.Name=image-type&Filter.3.Value.1=machine& */ } // occasionally can get com.google.common.util.concurrent.UncheckedExecutionException: // java.lang.RuntimeException: // security group eu-central-1/jclouds#brooklyn-bxza-alex-eu-central-shoul-u2jy-nginx-ielm // is not available after creating // the default timeout was 500ms so let's raise it in case that helps properties.setProperty( EC2Constants.PROPERTY_EC2_TIMEOUT_SECURITYGROUP_PRESENT, "" + Duration.seconds(30).toMilliseconds()); } // FIXME Deprecated mechanism, should have a ConfigKey for overrides Map<String, Object> extra = Maps.filterKeys(conf.getAllConfig(), Predicates.containsPattern("^jclouds\\.")); if (extra.size() > 0) { LOG.warn("Jclouds using deprecated property overrides: " + Sanitizer.sanitize(extra)); } properties.putAll(extra); String endpoint = conf.get(CloudLocationConfig.CLOUD_ENDPOINT); if (!groovyTruth(endpoint)) endpoint = getDeprecatedProperty(conf, Constants.PROPERTY_ENDPOINT); if (groovyTruth(endpoint)) properties.setProperty(Constants.PROPERTY_ENDPOINT, endpoint); Map<?, ?> cacheKey = MutableMap.builder() .putAll(properties) .put("provider", provider) .put("identity", identity) .put("credential", credential) .putIfNotNull("endpoint", endpoint) .build() .asUnmodifiable(); if (allowReuse) { ComputeService result = cachedComputeServices.get(cacheKey); if (result != null) { LOG.trace( "jclouds ComputeService cache hit for compute service, for " + Sanitizer.sanitize(properties)); return result; } LOG.debug( "jclouds ComputeService cache miss for compute service, creating, for " + Sanitizer.sanitize(properties)); } Iterable<Module> modules = getCommonModules(); // Synchronizing to avoid deadlock from sun.reflect.annotation.AnnotationType. // See https://github.com/brooklyncentral/brooklyn/issues/974 ComputeServiceContext computeServiceContext; synchronized (createComputeServicesMutex) { computeServiceContext = ContextBuilder.newBuilder(provider) .modules(modules) .credentials(identity, credential) .overrides(properties) .build(ComputeServiceContext.class); } final ComputeService computeService = computeServiceContext.getComputeService(); if (allowReuse) { synchronized (cachedComputeServices) { ComputeService result = cachedComputeServices.get(cacheKey); if (result != null) { LOG.debug( "jclouds ComputeService cache recovery for compute service, for " + Sanitizer.sanitize(cacheKey)); // keep the old one, discard the new one computeService.getContext().close(); return result; } LOG.debug( "jclouds ComputeService created " + computeService + ", adding to cache, for " + Sanitizer.sanitize(properties)); cachedComputeServices.put(cacheKey, computeService); } } return computeService; }
public class RebindTestUtils { private static final Logger LOG = LoggerFactory.getLogger(RebindTestUtils.class); private static final Duration TIMEOUT = Duration.seconds(20); public static <T> T serializeAndDeserialize(T memento) throws Exception { ObjectReplacer replacer = new ObjectReplacer() { private final Map<Pointer, Object> replaced = Maps.newLinkedHashMap(); @Override public Object replace(Object toserialize) { if (toserialize instanceof Location || toserialize instanceof Entity) { Pointer pointer = new Pointer(((Identifiable) toserialize).getId()); replaced.put(pointer, toserialize); return pointer; } return toserialize; } @Override public Object resolve(Object todeserialize) { if (todeserialize instanceof Pointer) { return checkNotNull(replaced.get(todeserialize), todeserialize); } return todeserialize; } }; try { return Serializers.reconstitute(memento, replacer); } catch (Exception e) { try { Dumpers.logUnserializableChains(memento, replacer); // Dumpers.deepDumpSerializableness(memento); } catch (Throwable t) { LOG.warn( "Error logging unserializable chains for memento " + memento + " (propagating original exception)", t); } throw e; } } public static void deleteMementoDir(String path) { deleteMementoDir(new File(path)); } public static void deleteMementoDir(File f) { FileBasedObjectStore.deleteCompletely(f); } public static void checkMementoSerializable(Application app) throws Exception { BrooklynMemento memento = MementosGenerators.newBrooklynMemento(app.getManagementContext()); checkMementoSerializable(memento); } public static void checkMementoSerializable(BrooklynMemento memento) throws Exception { serializeAndDeserialize(memento); } public static LocalManagementContext newPersistingManagementContext( File mementoDir, ClassLoader classLoader) { return managementContextBuilder(mementoDir, classLoader).buildStarted(); } public static LocalManagementContext newPersistingManagementContext( File mementoDir, ClassLoader classLoader, long persistPeriodMillis) { return managementContextBuilder(mementoDir, classLoader) .persistPeriodMillis(persistPeriodMillis) .buildStarted(); } public static LocalManagementContext newPersistingManagementContextUnstarted( File mementoDir, ClassLoader classLoader) { return managementContextBuilder(mementoDir, classLoader).buildUnstarted(); } public static ManagementContextBuilder managementContextBuilder( File mementoDir, ClassLoader classLoader) { return new ManagementContextBuilder(classLoader, mementoDir); } public static ManagementContextBuilder managementContextBuilder( ClassLoader classLoader, File mementoDir) { return new ManagementContextBuilder(classLoader, mementoDir); } public static ManagementContextBuilder managementContextBuilder( ClassLoader classLoader, PersistenceObjectStore objectStore) { return new ManagementContextBuilder(classLoader, objectStore); } public static class ManagementContextBuilder { final ClassLoader classLoader; BrooklynProperties properties; PersistenceObjectStore objectStore; Duration persistPeriod = Duration.millis(100); HighAvailabilityMode haMode; boolean forLive; boolean enableOsgi = false; boolean emptyCatalog; private boolean enablePersistenceBackups = true; ManagementContextBuilder(File mementoDir, ClassLoader classLoader) { this(classLoader, new FileBasedObjectStore(mementoDir)); } ManagementContextBuilder(ClassLoader classLoader, File mementoDir) { this(classLoader, new FileBasedObjectStore(mementoDir)); } ManagementContextBuilder(ClassLoader classLoader, PersistenceObjectStore objStore) { this.classLoader = checkNotNull(classLoader, "classLoader"); this.objectStore = checkNotNull(objStore, "objStore"); } public ManagementContextBuilder persistPeriodMillis(long persistPeriodMillis) { checkArgument( persistPeriodMillis > 0, "persistPeriodMillis must be greater than 0; was " + persistPeriodMillis); return persistPeriod(Duration.millis(persistPeriodMillis)); } public ManagementContextBuilder persistPeriod(Duration persistPeriod) { checkNotNull(persistPeriod); this.persistPeriod = persistPeriod; return this; } public ManagementContextBuilder properties(BrooklynProperties properties) { this.properties = checkNotNull(properties, "properties"); return this; } public ManagementContextBuilder forLive(boolean val) { this.forLive = val; return this; } public ManagementContextBuilder enablePersistenceBackups(boolean val) { this.enablePersistenceBackups = val; return this; } public ManagementContextBuilder enableOsgi(boolean val) { this.enableOsgi = val; return this; } public ManagementContextBuilder emptyCatalog() { this.emptyCatalog = true; return this; } public ManagementContextBuilder emptyCatalog(boolean val) { this.emptyCatalog = val; return this; } public ManagementContextBuilder haMode(HighAvailabilityMode val) { this.haMode = val; return this; } public LocalManagementContext buildUnstarted() { LocalManagementContext unstarted; BrooklynProperties properties = this.properties != null ? this.properties : BrooklynProperties.Factory.newDefault(); if (this.emptyCatalog) { properties.putIfAbsent( BrooklynServerConfig.BROOKLYN_CATALOG_URL, ManagementContextInternal.EMPTY_CATALOG_URL); } if (!enablePersistenceBackups) { properties.putIfAbsent( BrooklynServerConfig.PERSISTENCE_BACKUPS_REQUIRED_ON_DEMOTION, false); properties.putIfAbsent( BrooklynServerConfig.PERSISTENCE_BACKUPS_REQUIRED_ON_PROMOTION, false); properties.putIfAbsent(BrooklynServerConfig.PERSISTENCE_BACKUPS_REQUIRED, false); } if (forLive) { unstarted = new LocalManagementContext(properties); } else { unstarted = LocalManagementContextForTests.builder(true) .useProperties(properties) .disableOsgi(!enableOsgi) .build(); } objectStore.injectManagementContext(unstarted); objectStore.prepareForSharedUse( PersistMode.AUTO, (haMode == null ? HighAvailabilityMode.DISABLED : haMode)); BrooklynMementoPersisterToObjectStore newPersister = new BrooklynMementoPersisterToObjectStore( objectStore, unstarted.getBrooklynProperties(), classLoader); ((RebindManagerImpl) unstarted.getRebindManager()).setPeriodicPersistPeriod(persistPeriod); unstarted .getRebindManager() .setPersister(newPersister, PersistenceExceptionHandlerImpl.builder().build()); // set the HA persister, in case any children want to use HA unstarted .getHighAvailabilityManager() .setPersister( new ManagementPlaneSyncRecordPersisterToObjectStore( unstarted, objectStore, classLoader)); return unstarted; } public LocalManagementContext buildStarted() { LocalManagementContext unstarted = buildUnstarted(); unstarted.getHighAvailabilityManager().disabled(); unstarted.getRebindManager().startPersistence(); return unstarted; } } /** Convenience for common call; delegates to {@link #rebind(RebindOptions)} */ public static Application rebind(File mementoDir, ClassLoader classLoader) throws Exception { return rebind(RebindOptions.create().mementoDir(mementoDir).classLoader(classLoader)); } /** @deprecated since 0.7.0; use {@link #rebind(RebindOptions)} */ @Deprecated public static Application rebind( File mementoDir, ClassLoader classLoader, RebindExceptionHandler exceptionHandler) throws Exception { return rebind( RebindOptions.create() .mementoDir(mementoDir) .classLoader(classLoader) .exceptionHandler(exceptionHandler)); } /** @deprecated since 0.7.0; use {@link #rebind(RebindOptions)} */ @Deprecated public static Application rebind(ManagementContext newManagementContext, ClassLoader classLoader) throws Exception { return rebind( RebindOptions.create().newManagementContext(newManagementContext).classLoader(classLoader)); } /** @deprecated since 0.7.0; use {@link #rebind(RebindOptions)} */ @Deprecated public static Application rebind( ManagementContext newManagementContext, ClassLoader classLoader, RebindExceptionHandler exceptionHandler) throws Exception { return rebind( RebindOptions.create() .newManagementContext(newManagementContext) .classLoader(classLoader) .exceptionHandler(exceptionHandler)); } /** @deprecated since 0.7.0; use {@link #rebind(RebindOptions)} */ @Deprecated public static Application rebind( ManagementContext newManagementContext, File mementoDir, ClassLoader classLoader) throws Exception { return rebind( RebindOptions.create() .newManagementContext(newManagementContext) .mementoDir(mementoDir) .classLoader(classLoader)); } /** @deprecated since 0.7.0; use {@link #rebind(RebindOptions)} */ @Deprecated public static Application rebind( ManagementContext newManagementContext, File mementoDir, ClassLoader classLoader, RebindExceptionHandler exceptionHandler) throws Exception { return rebind( RebindOptions.create() .newManagementContext(newManagementContext) .mementoDir(mementoDir) .classLoader(classLoader) .exceptionHandler(exceptionHandler)); } /** @deprecated since 0.7.0; use {@link #rebind(RebindOptions)} */ @Deprecated public static Application rebind( ManagementContext newManagementContext, File mementoDir, ClassLoader classLoader, RebindExceptionHandler exceptionHandler, PersistenceObjectStore objectStore) throws Exception { return rebind( RebindOptions.create() .newManagementContext(newManagementContext) .mementoDir(mementoDir) .classLoader(classLoader) .exceptionHandler(exceptionHandler) .objectStore(objectStore)); } public static Application rebind(RebindOptions options) throws Exception { Collection<Application> newApps = rebindAll(options); if (newApps.isEmpty()) throw new IllegalStateException( "Application could not be rebinded; serialization probably failed"); return Iterables.getFirst(newApps, null); } /** @deprecated since 0.7.0; use {@link #rebindAll(RebindOptions)} */ @Deprecated public static Collection<Application> rebindAll(File mementoDir, ClassLoader classLoader) throws Exception { return rebindAll(RebindOptions.create().mementoDir(mementoDir).classLoader(classLoader)); } /** @deprecated since 0.7.0; use {@link #rebind(RebindOptions)} */ @Deprecated public static Collection<Application> rebindAll( File mementoDir, ClassLoader classLoader, RebindExceptionHandler exceptionHandler) throws Exception { return rebindAll( RebindOptions.create() .mementoDir(mementoDir) .classLoader(classLoader) .exceptionHandler(exceptionHandler)); } /** @deprecated since 0.7.0; use {@link #rebind(RebindOptions)} */ @Deprecated public static Collection<Application> rebindAll( LocalManagementContext newManagementContext, ClassLoader classLoader, RebindExceptionHandler exceptionHandler) throws Exception { return rebindAll( RebindOptions.create() .newManagementContext(newManagementContext) .classLoader(classLoader) .exceptionHandler(exceptionHandler)); } /** @deprecated since 0.7.0; use {@link #rebind(RebindOptions)} */ @Deprecated public static Collection<Application> rebindAll( ManagementContext newManagementContext, File mementoDir, ClassLoader classLoader) throws Exception { return rebindAll( RebindOptions.create() .newManagementContext(newManagementContext) .mementoDir(mementoDir) .classLoader(classLoader)); } /** @deprecated since 0.7.0; use {@link #rebind(RebindOptions)} */ @Deprecated public static Collection<Application> rebindAll( ManagementContext newManagementContext, File mementoDir, ClassLoader classLoader, RebindExceptionHandler exceptionHandler, PersistenceObjectStore objectStore) throws Exception { return rebindAll( RebindOptions.create() .newManagementContext(newManagementContext) .mementoDir(mementoDir) .classLoader(classLoader) .exceptionHandler(exceptionHandler) .objectStore(objectStore)); } 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; } public static void waitForPersisted(Application origApp) throws InterruptedException, TimeoutException { waitForPersisted(origApp.getManagementContext()); } public static void waitForPersisted(ManagementContext managementContext) throws InterruptedException, TimeoutException { managementContext.getRebindManager().waitForPendingComplete(TIMEOUT, true); } public static void checkCurrentMementoSerializable(Application app) throws Exception { checkCurrentMementoSerializable(app.getManagementContext()); } public static void checkCurrentMementoSerializable(ManagementContext mgmt) throws Exception { BrooklynMemento memento = MementosGenerators.newBrooklynMemento(mgmt); serializeAndDeserialize(memento); } /** * Dumps out the persisted mementos that are at the given directory. * * <p>Binds to the persisted state (as a "hot standby") to load the raw data (as strings), and to * write out the entity, location, policy, enricher, feed and catalog-item data. * * @param dir The directory containing the persisted state */ public static void dumpMementoDir(File dir) { LocalManagementContextForTests mgmt = new LocalManagementContextForTests(BrooklynProperties.Factory.newEmpty()); FileBasedObjectStore store = null; BrooklynMementoPersisterToObjectStore persister = null; try { store = new FileBasedObjectStore(dir); store.injectManagementContext(mgmt); store.prepareForSharedUse(PersistMode.AUTO, HighAvailabilityMode.HOT_STANDBY); persister = new BrooklynMementoPersisterToObjectStore( store, BrooklynProperties.Factory.newEmpty(), RebindTestUtils.class.getClassLoader()); BrooklynMementoRawData data = persister.loadMementoRawData(RebindExceptionHandlerImpl.builder().build()); List<BrooklynObjectType> types = ImmutableList.of( BrooklynObjectType.ENTITY, BrooklynObjectType.LOCATION, BrooklynObjectType.POLICY, BrooklynObjectType.ENRICHER, BrooklynObjectType.FEED, BrooklynObjectType.CATALOG_ITEM); for (BrooklynObjectType type : types) { LOG.info(type + " (" + data.getObjectsOfType(type).keySet() + "):"); for (Map.Entry<String, String> entry : data.getObjectsOfType(type).entrySet()) { LOG.info("\t" + type + " " + entry.getKey() + ": " + entry.getValue()); } } } finally { if (persister != null) persister.stop(false); if (store != null) store.close(); mgmt.terminate(); } } }