package rocks.inspectit.server.processor.impl; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.persistence.EntityManager; import org.influxdb.dto.Point.Builder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; import rocks.inspectit.server.influx.builder.DefaultDataPointBuilder; import rocks.inspectit.server.influx.dao.InfluxDBDao; import rocks.inspectit.server.processor.AbstractCmrDataProcessor; import rocks.inspectit.shared.all.communication.DefaultData; import rocks.inspectit.shared.all.communication.data.InvocationSequenceData; import rocks.inspectit.shared.all.communication.data.JmxSensorValueData; import rocks.inspectit.shared.all.communication.data.TimerData; /** * The simple influx processor. Processor knows all available influx point builders. When the * default data comes the processor with check if influx is online and if point builder exists for * the given data type. If so an influx point will be created and inserted to {@link #influxDbDao}. * * @author Ivan Senic * */ public class InfluxProcessor extends AbstractCmrDataProcessor { /** * {@link InfluxDBDao} to write to. */ private InfluxDBDao influxDbDao; /** * Map of all builders. */ private Map<Class<? extends DefaultData>, DefaultDataPointBuilder<DefaultData>> builderMap; /** * Default constructor. * * @param influxDbDao * {@link IInfluxDBDao} * @param builders * All available influx point builders. */ @Autowired public InfluxProcessor(InfluxDBDao influxDbDao, List<DefaultDataPointBuilder<DefaultData>> builders) { this.influxDbDao = influxDbDao; if (CollectionUtils.isEmpty(builders)) { builderMap = Collections.emptyMap(); } else { builderMap = new HashMap<>(); for (DefaultDataPointBuilder<DefaultData> builder : builders) { builderMap.put(builder.getDataClass(), builder); } } } /** * {@inheritDoc} */ @Override protected void processData(DefaultData defaultData, EntityManager entityManager) { DefaultDataPointBuilder<DefaultData> defaultDataPointBuilder = builderMap.get(defaultData.getClass()); Builder builder = defaultDataPointBuilder.createBuilder(defaultData); influxDbDao.insert(builder.build()); } /** * {@inheritDoc} */ @Override public boolean canBeProcessed(DefaultData defaultData) { return influxDbDao.isConnected() && builderMap.containsKey(defaultData.getClass()) && isValidData(defaultData); } /** * Check if the data if valid. We currently have following constraints: * * <ul> * <li>If {@link TimerData} instance then charting must be set * <li>If {@link JmxSensorValueData} instance then it must be boolean or numeric * </ul> * * @param defaultData * Data to check. * @return True if data should be used with the pointer and sent to influx. */ private boolean isValidData(DefaultData defaultData) { if ((defaultData instanceof TimerData) && !((TimerData) defaultData).isCharting()) { return false; } if ((defaultData instanceof JmxSensorValueData) && !((JmxSensorValueData) defaultData).isBooleanOrNumeric()) { return false; } if ((defaultData instanceof InvocationSequenceData) && (((InvocationSequenceData) defaultData).getParentSequence() != null)) { return false; } return true; } }