/* * 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.enricher.stock; import java.util.Collection; import java.util.Map; import java.util.Set; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntityLocal; import org.apache.brooklyn.api.sensor.AttributeSensor; 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.core.enricher.AbstractEnricher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; /** * an enricher policy which just listens for the target sensor(s) on a child entity and passes it up. * now superseded by syntax such as: * * <pre>{@code Enrichers.builder().propagating(sensor).from(source).build()}</pre> * * @deprecated since 0.7.0; use {@link Enrichers#builder()} * * @see Propagator if need to sub-class */ public class SensorPropagatingEnricher extends AbstractEnricher implements SensorEventListener<Object> { public static final Logger log = LoggerFactory.getLogger(SensorPropagatingEnricher.class); /** the entity to listen to */ private final Entity source; /** the sensors to listen to */ private final Set<Sensor<?>> sensors; /** the sensors to listen to */ private final Map<Sensor<?>, Sensor<?>> sensorMappings; public static SensorPropagatingEnricher newInstanceListeningToAllSensors(Entity source) { return newInstanceListeningToAllSensorsBut(source); } public static SensorPropagatingEnricher newInstanceListeningToAllSensorsBut(Entity source, Sensor<?>... excludes) { Set<Sensor<?>> excluded = ImmutableSet.copyOf(excludes); Set<Sensor<?>> includes = Sets.newLinkedHashSet(); for (Sensor<?> it : source.getEntityType().getSensors()) { if (!excluded.contains(it)) includes.add(it); } return new SensorPropagatingEnricher(source, includes); } public static SensorPropagatingEnricher newInstanceListeningTo(Entity source, Sensor<?>... includes) { return new SensorPropagatingEnricher(source, includes); } /** * listens to sensors from source, propagates them here renamed according to the map * * Instead, consider calling: * <pre> * {@code * addEnricher(Enrichers.builder() * .propagating(mapOfOldSensorNamesToNewSensorNames) * .from(source) * .build()); * } * </pre> * * @deprecated since 0.7.0; use {@link Enrichers#builder()} */ public static SensorPropagatingEnricher newInstanceRenaming(Entity source, Map<? extends Sensor<?>, ? extends Sensor<?>> sensors) { return new SensorPropagatingEnricher(source, sensors); } /** * @deprecated since 0.7.0; use {@link Enrichers#builder()} */ public SensorPropagatingEnricher(Entity source, Sensor<?>... sensors) { this(source, ImmutableList.copyOf(sensors)); } /** * Instead, consider calling: * <pre> * {@code * addEnricher(Enrichers.builder() * .propagating(sensors) * .from(source) * .build()); * } * </pre> * * @deprecated since 0.7.0; use {@link Enrichers#builder()} */ public SensorPropagatingEnricher(Entity source, Collection<Sensor<?>> sensors) { this.source = source; this.sensors = ImmutableSet.copyOf(sensors); this.sensorMappings = ImmutableMap.of(); } public SensorPropagatingEnricher(Entity source, Map<? extends Sensor<?>, ? extends Sensor<?>> sensors) { this.source = source; this.sensors = ImmutableSet.copyOf(sensors.keySet()); this.sensorMappings = ImmutableMap.copyOf(sensors); } public void setEntity(EntityLocal entity) { super.setEntity(entity); for (Sensor<?> s: sensors) { subscriptions().subscribe(source, s, this); } } @Override @SuppressWarnings({ "unchecked", "rawtypes" }) public void onEvent(SensorEvent<Object> event) { // propagate upwards Sensor<?> sourceSensor = event.getSensor(); Sensor<?> destinationSensor = getDestinationSensor(sourceSensor); if (log.isTraceEnabled()) log.trace("policy {} got {}, propagating via {}{}", new Object[] {this, event, entity, (sourceSensor == destinationSensor ? "" : " (as "+destinationSensor+")")}); if (event.getSensor() instanceof AttributeSensor) { entity.sensors().set((AttributeSensor)destinationSensor, event.getValue()); } else { entity.sensors().emit((Sensor)destinationSensor, event.getValue()); } } /** useful post-addition to emit current values */ public void emitAllAttributes() { emitAllAttributes(false); } @SuppressWarnings({ "rawtypes", "unchecked" }) public void emitAllAttributes(boolean includeNullValues) { for (Sensor s: sensors) { if (s instanceof AttributeSensor) { AttributeSensor destinationSensor = (AttributeSensor<?>) getDestinationSensor(s); Object v = source.getAttribute((AttributeSensor)s); if (v != null || includeNullValues) entity.sensors().set(destinationSensor, v); } } } /** convenience, to be called by the host */ public SensorPropagatingEnricher addToEntityAndEmitAll(Entity host) { host.enrichers().add(this); emitAllAttributes(); return this; } private Sensor<?> getDestinationSensor(Sensor<?> sourceSensor) { return sensorMappings.containsKey(sourceSensor) ? sensorMappings.get(sourceSensor): sourceSensor; } }