blob: 04a9cbdd7dafd2e0f5674bee10d901aa6455a472 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.brooklyn.api.mgmt;
import java.io.Serializable;
import java.net.URI;
import java.util.Collection;
import org.apache.brooklyn.api.catalog.BrooklynCatalog;
import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
import org.apache.brooklyn.api.entity.drivers.EntityDriverManager;
import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.location.LocationRegistry;
import org.apache.brooklyn.api.mgmt.entitlement.EntitlementManager;
import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityManager;
import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
import org.apache.brooklyn.api.mgmt.rebind.RebindManager;
import org.apache.brooklyn.api.objs.BrooklynObject;
import org.apache.brooklyn.api.objs.EntityAdjunct;
import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry;
import org.apache.brooklyn.config.StringConfigMap;
import org.apache.brooklyn.util.guava.Maybe;
import com.google.common.annotations.Beta;
import com.google.common.base.Predicate;
/**
* This is the entry point for accessing and interacting with a realm of applications and their entities in Brooklyn.
*
* For example, policies and the management console(s) (web-app, etc) can use this to interact with entities;
* policies, web-app, and entities share the realm for subscribing to events, executing tasks, and generally co-existing.
* <p>
* It may refer to several applications, and it refers to all the entities descended from those applications.
*/
public interface ManagementContext {
// TODO Consider separating out into a ConfigManager for methods like:
// - getConfig()
// - reloadBrooklynProperties();
// - addPropertiesReloadListener
// - removePropertiesReloadListener
// - interface PropertiesReloadListener
/**
* As {@link #getManagementPlaneIdMaybe()}, but throws if not available, to prevent callers accessing prematurely.
*
* @deprecated since 0.11.0, use {@link #getManagementPlaneIdMaybe()} instead.
*/
@Deprecated
String getManagementPlaneId();
/**
* UID for the Brooklyn management plane which this {@link ManagementContext} node is a part of.
* <p>
* Each Brooklyn entity is actively managed by a unique management plane
* whose ID which should not normally change for the duration of that entity,
* even though the nodes in that plane might, and the plane may go down and come back up.
* In other words the value of {@link Application#getManagementContext()#getManagementPlaneId()}
* will generally be constant (in contrast to {@link #getManagementNodeId()}).
* <p>
* Returns absent while the management context is still initialising. The value is set:
* <ul>
* <li>no persistence - during launch
* <li>persistence enabled, HA disabled - on rebind (during launch)
* <li>persistence enabled, HA enabled - on the first HA state check (async to launch)
* </ul>
*/
Maybe<String> getManagementPlaneIdMaybe();
/**
* UID for this {@link ManagementContext} node (as part of a single management plane).
* <p>
* No two instances of {@link ManagementContext} should ever have the same node UID.
* The value of {@link Application#getManagementContext()#getManagementNodeId()} may
* change if it is rebinded to a different node,
* in contrast to {@link #getManagementPlaneIdMaybe()} which is the same for all nodes in a Brooklyn plane.
* <p>
* This value should not be null unless the management context is a non-functional
* (non-deployment) instance. */
String getManagementNodeId();
/**
* The URI that this management node's REST API is available at, or absent if the node's
* API is unavailable.
*/
Maybe<URI> getManagementNodeUri();
/**
* All applications under control of this management plane
*/
Collection<Application> getApplications();
/**
* Returns the {@link EntityManager} instance for managing/querying entities.
*/
EntityManager getEntityManager();
/**
* Returns the {@link ExecutionManager} instance for entities and users in this management realm
* to submit tasks and to observe what tasks are occurring
*/
ExecutionManager getExecutionManager();
/**
* Returns an {@link ExecutionContext} within the {@link ExecutionManager} for tasks
* associated to the Brooklyn node's operation (not any entities).
**/
ExecutionContext getServerExecutionContext();
/**
* Returns the {@link EntityDriverManager} entities can use to create drivers. This
* manager can also be used to programmatically customize which driver type to use
* for entities in different locations.
*
* The default strategy for choosing a driver is to use a naming convention:
* {@link DriverDependentEntity#getDriverInterface()} returns the interface that the
* driver must implement; its name should end in "Driver". For example, this suffix is
* replaced with "SshDriver" for SshMachineLocation, for example.
*/
EntityDriverManager getEntityDriverManager();
/**
* Returns the {@link DownloadResolverManager} for resolving things like which URL to download an installer from.
*
* The default {@link DownloadResolverManager} will retrieve {@code entity.getAttribute(Attributes.DOWNLOAD_URL)},
* and substitute things like "${version}" etc.
*
* However, additional resolvers can be registered to customize this behaviour (e.g. to always go to an
* enterprise's repository).
*/
DownloadResolverManager getEntityDownloadsManager();
/**
* Returns the {@link SubscriptionManager} instance for entities and users of this management realm
* to subscribe to sensor events (and, in the case of entities, to emit sensor events)
*/
SubscriptionManager getSubscriptionManager();
//TODO (Alex) I'm not sure the following two getXxxContext methods are needed on the interface;
//I expect they will only be called once, in AbstractEntity, and fully capable
//there of generating the respective contexts from the managers
//(Litmus test will be whether there is anything in FederatedManagementContext
//which requires a custom FederatedExecutionContext -- or whether BasicEC
//works with FederatedExecutionManager)
/**
* Returns an {@link ExecutionContext} instance representing tasks
* (from the {@link ExecutionManager}) associated with this entity, and capable
* of conveniently running such tasks which will be associated with that entity
*/
ExecutionContext getExecutionContext(Entity entity);
/** As {@link #getExecutionContext(Entity)} where there is also an adjunct */
ExecutionContext getExecutionContext(Entity e, EntityAdjunct a);
/**
* Returns a {@link SubscriptionContext} instance representing subscriptions
* (from the {@link SubscriptionManager}) associated with this entity, and capable
* of conveniently subscribing on behalf of that entity.
*
* For subscriptions made using this {@link SubscriptionContext}, the calls to
* {@link org.apache.brooklyn.api.sensor.SensorEventListener#onEvent(org.apache.brooklyn.api.sensor.SensorEvent)}
* will be made in a task that has the {@code CONTEXT_ENTITY} tag set to this entity (see BrooklynTaskTag).
*/
SubscriptionContext getSubscriptionContext(Entity entity);
/** As {@link #getSubscriptionContext(Entity)} where there is also an adjunct */
SubscriptionContext getSubscriptionContext(Entity e, EntityAdjunct a);
/**
* Returns a {@link SubscriptionContext} instance representing subscriptions
* (from the {@link SubscriptionManager}) associated with this location, and capable
* of conveniently subscribing on behalf of that location
*/
@Beta
SubscriptionContext getSubscriptionContext(Location location);
@Beta // method may move to an internal interface; brooklyn users should not need to call this directly
RebindManager getRebindManager();
/**
* @since 0.7.0
*/
@Beta // method may move to an internal interface; brooklyn users should not need to call this directly
HighAvailabilityManager getHighAvailabilityManager();
/**
* Returns the ConfigMap (e.g. BrooklynProperties) applicable to this management context.
* Defaults to reading ~/.brooklyn/brooklyn.properties but configurable in the management context.
*/
StringConfigMap getConfig();
/**
* <p>
* Provides a scratchpad area for this ManagementContext. It can be used for storing any data useful to Brooklyn core
* or custom entities. Usually it's used for singleton-like objects per ManagementContext. The lifetime of he
* scratch area is for the duration of the ManagementContext. It's not persisted or shared between HA nodes,
* doesn't survive restarts.
* <p>
* Code using {@link #getConfig()} for the same purpose should migrate to using this method as {@link #getConfig()}
* will become read-only in future releases. Note that the scratchpad is not reset on reloading {@code brooklyn.properties}
* unlike {@link #getConfig()}.
* <p>
* The returned map is thread safe, no locking is required to use it from parallel threads.
*/
Scratchpad getScratchpad();
/**
* Whether the management context has been initialized and not yet terminated.
* This does not mean startup is entirely completed. See also {@link #isStartupComplete()}.
*/
// TODO should we replace this with isNotYetTerminated() ??
// and perhaps introduce isFullyRunning() which does (isStartupComplete() && isRunning()),
// and/or move to a MgmtContextStatus subclass where errors can also be stored?
public boolean isRunning();
/**
* Whether all startup tasks have completed. Previous to this point the management context is still usable
* (and hence {@link #isRunning()} returns true immediately after construction)
* but some subsystems (e.g. persistence, OSGi, webapps, entities started at startup)
* may not be available until this returns true.
* <p>
* Also returns false if HA state is transitioning. See {@link #getNodeState()} to atomically check node state,
* as the preferred way to tell if a node is master.
*/
@Beta // see comment on isRunning() as items might move to a status handler
public boolean isStartupComplete();
/** Returns node state, always reporting {@link ManagementNodeState#INITIALIZING} if there is any transition
* and {@link ManagementNodeState#FAILED} if there are any server errors.
* If this returns {@link ManagementNodeState#MASTER} we can guarantee the node to be in master state,
* unlike {@link HighAvailabilityManager#getNodeState()} which may return {@link ManagementNodeState#MASTER} slightly early.
*/
public ManagementNodeState getNodeState();
/** Record of configured locations and location resolvers */
LocationRegistry getLocationRegistry();
/** Record of configured Brooklyn entities (and templates and policies) which can be loaded */
BrooklynCatalog getCatalog();
/** Record of configured classes which can be loaded */
BrooklynTypeRegistry getTypeRegistry();
/** Returns the class loader to be used to load items.
* Temporary routine while catalog supports classloader-based and OSGi-based classloading. */
@Beta
ClassLoader getCatalogClassLoader();
LocationManager getLocationManager();
/**
* For controlling access to operations - can be queried to find if an operation is allowed.
* Callers should *not* cache the result of this method, but should instead always call
* again to get the {@link AccessController}.
*/
AccessController getAccessController();
/**
* Reloads locations from {@code brooklyn.properties}. Any changes will apply only to newly created applications
*/
void reloadBrooklynProperties();
/**
* Listener for {@code brooklyn.properties} reload events.
*
* @see {@link #raddPropertiesReloadListenerPropertiesReloadListener)}
* @see {@link #removePropertiesReloadListener(PropertiesReloadListener)}
*/
interface PropertiesReloadListener extends Serializable {
/** Called when {@code brooklyn.properties} is reloaded. */
void reloaded();
}
/**
* Registers a listener to be notified when brooklyn.properties is reloaded
*/
void addPropertiesReloadListener(PropertiesReloadListener listener);
/**
* Deregisters a listener from brooklyn.properties reload notifications
*/
void removePropertiesReloadListener(PropertiesReloadListener listener);
/**
* Active entitlements checker instance.
*/
EntitlementManager getEntitlementManager();
/** As {@link #lookup(String, Class)} but not constraining the return type */
public BrooklynObject lookup(String id);
/** As {@link #lookup(Predicate)} comparing the ID of the object with the given string */
@Beta
public <T extends BrooklynObject> T lookup(String id, Class<T> type);
/** Finds a {@link BrooklynObject} known in this management context
* satisfying the given predicate, or null */
@Beta
public <T extends BrooklynObject> T lookup(Predicate<? super T> filter);
/** As {@link #lookup(Predicate)} but returning all such instances */
@Beta
public <T extends BrooklynObject> Collection<T> lookupAll(Predicate<? super T> filter);
}