| /* |
| * 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()); |
| } |
| |
| } |