blob: 6ecdca2409824336efcea4ccb6d08a31a1b7a250 [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.policy.failover;
import java.util.Collection;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.EnricherSpec;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.enricher.stock.Propagator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.Beta;
import com.google.common.base.Objects;
/** Makes selected sensors mirrored from the primary to this node. */
@Beta
public class PropagatePrimaryEnricher extends AbstractEnricher implements SensorEventListener<Object> {
private static final Logger log = LoggerFactory.getLogger(PropagatePrimaryEnricher.class);
public static final ConfigKey<String> PRIMARY_SENSOR_NAME = ElectPrimaryConfig.PRIMARY_SENSOR_NAME;
public static final ConfigKey<Entity> CURRENT_PROPAGATED_PRODUCER = ConfigKeys.newConfigKey(Entity.class, "propagate.primary.enricher.current.producer");
// persistence of references to adjuncts not supported, so use the ID
public static final ConfigKey<String> CURRENT_PROPAGATOR_ID = ConfigKeys.newStringConfigKey("propagate.primary.enricher.current.propagatorId");
public static final ConfigKey<Collection<? extends Sensor<?>>> PROPAGATING = Propagator.PROPAGATING;
// the above is the only one currently supported - explicitly named sensors
// NB: old code in history had much of the below working, but not for rebind
// other propagator fields (eg "all but") are not
// public static final ConfigKey<Boolean> PROPAGATING_ALL = Propagator.PROPAGATING_ALL;
// public static final ConfigKey<Collection<? extends Sensor<?>>> PROPAGATING_ALL_BUT = Propagator.PROPAGATING_ALL_BUT;
// public static final ConfigKey<Map<? extends Sensor<?>, ? extends Sensor<?>>> SENSOR_MAPPING = Propagator.SENSOR_MAPPING;
// also no longer support effectors
// public static final ConfigKey<Boolean> PROPAGATE_EFFECTORS = ConfigKeys.newBooleanConfigKey("propagate.effectors",
// "Whether to propagate effectors, default true (effectors already defined here will not be propagated)",
// true);
public void setEntity(@SuppressWarnings("deprecation") org.apache.brooklyn.api.entity.EntityLocal entity) {
super.setEntity(entity);
subscriptions().subscribe(entity, Sensors.newSensor(Entity.class, config().get(PRIMARY_SENSOR_NAME)), this);
onEvent(null);
}
@Override
public synchronized void onEvent(SensorEvent<Object> event) {
Entity primary = entity.getAttribute( Sensors.newSensor(Entity.class, config().get(PRIMARY_SENSOR_NAME)) );
final Entity lastPrimary = config().get(CURRENT_PROPAGATED_PRODUCER);
if (!Objects.equal(primary, lastPrimary)) {
log.debug("Removing propagated items from "+lastPrimary+" at "+entity);
final Propagator propagator = getManagementContext().lookup(config().get(CURRENT_PROPAGATOR_ID), Propagator.class);
// remove propagator
if (propagator!=null) {
entity.enrichers().remove(propagator);
config().set(CURRENT_PROPAGATOR_ID, (String)null);
}
// remove propagated sensors
Collection<? extends Sensor<?>> sensorsToRemove = config().get(PROPAGATING);
if (sensorsToRemove!=null) {
for (Sensor<?> s: sensorsToRemove) {
// TODO - allow strings above also
if (s instanceof AttributeSensor) {
((EntityInternal)entity).sensors().remove((AttributeSensor<?>)s);
}
}
}
if (primary!=null) {
config().set(CURRENT_PROPAGATED_PRODUCER, primary);
// add propagator
addPropagatorEnricher(primary);
}
}
}
@Override
protected <T> void doReconfigureConfig(ConfigKey<T> key, T val) {
if (CURRENT_PROPAGATED_PRODUCER.equals(key)) return;
if (CURRENT_PROPAGATOR_ID.equals(key)) return;
// disallow anything else
super.doReconfigureConfig(key, val);
}
protected void addPropagatorEnricher(Entity primary) {
EnricherSpec<Propagator> spec = EnricherSpec.create(Propagator.class);
spec.configure(Propagator.PRODUCER, primary);
Collection<? extends Sensor<?>> sensorsToPropagate = getConfig(PROPAGATING);
if (sensorsToPropagate==null || sensorsToPropagate.isEmpty()) {
log.warn("Nothing found to propagate from primary "+primary+" at "+entity);
return;
}
spec.configure(Propagator.PROPAGATING, sensorsToPropagate);
// note - history
log.debug("Adding propagator "+spec+" to "+entity+" to track "+primary);
Propagator propagator = entity.enrichers().add(spec);
config().set(CURRENT_PROPAGATOR_ID, propagator.getId());
}
}