All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.influxdb.client.osgi.LineProtocolWriter Maven / Gradle / Ivy

/*
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.influxdb.client.osgi;

import java.math.BigInteger;
import java.util.List;
import java.util.stream.Collectors;

import com.influxdb.client.InfluxDBClient;
import com.influxdb.client.WriteApiBlocking;
import com.influxdb.client.domain.WritePrecision;
import com.influxdb.client.write.internal.NanosecondConverter;

import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventConstants;
import org.osgi.service.event.EventHandler;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;

/**
 * OSGi event handler writing InfluxDB line protocol records.
 *
 * 

Service is used to write RAW (line protocol) event data to InfluxDB. OSGi event topic * {@link LineProtocolWriter#DEFAULT_EVENT_TOPIC} used by default. The following OSGi event properties are * supported:

* *
    *
  • record ({@link String}): value must be a single line protocol record
  • *
  • records ({@link List}): value must be a list of line protocol records
  • *
  • precision ({@link String}, optional): write precision, values: s, ms, us, * ns, default: ns
  • *
  • organization ({@link String}, optional): used to override InfluxDB organization of * {@link LineProtocolWriter} service (by event).
  • *
  • bucket ({@link String}, optional): used to override InfluxDB bucket of * {@link LineProtocolWriter} service (by event).
  • *
* *

One of record or records must be set.

* *

Timestamp is appended to the line protocol record if it is enabled by configuration option (in that case records * must not contain timestamp data!). Value is read from OSGi event (property {@link EventConstants#TIMESTAMP}) or * {@link System#currentTimeMillis()} is set if property not found.

*/ @Component(immediate = true, configurationPolicy = ConfigurationPolicy.REQUIRE, property = { EventConstants.EVENT_TOPIC + "=" + LineProtocolWriter.DEFAULT_EVENT_TOPIC }) public class LineProtocolWriter implements EventHandler { /** * Default OSGi event topic. */ public static final String DEFAULT_EVENT_TOPIC = "influxdb/lineprotocol"; /** * OSGi event property name used to write single line protocol record. */ public static final String RECORD = "record"; /** * OSGi event property name used to write list of line protocol records. */ public static final String RECORDS = "records"; /** * OSGi event property name to set precision. */ public static final String PRECISION = "precision"; /** * OSGi event property name to override InfluxDB organization. */ public static final String ORGANIZATION = "organization"; /** * OSGi event property name to override InfluxDB bucket. */ public static final String BUCKET = "bucket"; /** * Configuration for Line Protocol Writer. */ @ObjectClassDefinition(name = "InfluxDB Line Protocol Writer", description = "Event handler writing line protocol record(s) to InfluxDB") public @interface Config { /** * OSGi event handler topic(s). */ @AttributeDefinition(name = "Topics", description = "OSGi event topics") String[] event_topics() default {DEFAULT_EVENT_TOPIC}; /** * OSGi target filter for InfluxDB connection, i.e. (alias=test). The following properties are * copied from {@link InfluxDBConnector}: organization, bucket, database, * url, alias. */ @AttributeDefinition(required = false, name = "InfluxDB client target", description = "OSGi target filter of InfluxDB client service") String client_target(); /** * Current timestamp is appended to line protocol record(s) is enabled. */ @AttributeDefinition(required = false, name = "Append timestamp", description = "Append timestamp to line protocol record(s)", type = AttributeType.BOOLEAN) boolean timestamp_append() default false; /** * InfluxDB organization to write data (overriding organization of {@link InfluxDBClient}). */ @AttributeDefinition(required = false, name = "Organization", description = "InfluxDB organization to write") String organization(); /** * InfluxDB bucket to write data (overriding bucket of {@link InfluxDBClient}). */ @AttributeDefinition(required = false, name = "Bucket", description = "InfluxDB bucket to write") String bucket(); } @Reference(policyOption = ReferencePolicyOption.GREEDY) InfluxDBClient client; Config config; /** * Start or reconfigure OSGi component. * * @param config configuration */ @Activate @Modified void start(final Config config) { this.config = config; } /** * Write line protocol record from OSGi event. * * @param event OSGI event containing data */ @Override public void handleEvent(final Event event) { String organization = (String) event.getProperty(ORGANIZATION); if (organization == null) { organization = config.organization(); } String bucket = (String) event.getProperty(BUCKET); if (bucket == null) { bucket = config.bucket(); } final WritePrecision writePrecision = getPrecision(event); final WriteApiBlocking writeApi = client.getWriteApiBlocking(); final String record = (String) event.getProperty(RECORD); final List records = (List) event.getProperty(RECORDS); final BigInteger timestamp = calculateTimestamp(event, writePrecision); if (record != null) { final String recordToWrite = timestamp != null ? record + " " + timestamp : record; if (organization != null && bucket != null) { writeApi.writeRecord(bucket, organization, writePrecision, recordToWrite); } else { writeApi.writeRecord(writePrecision, recordToWrite); } } else if (records != null) { final List recordsToWrite = timestamp != null ? records.stream().map(r -> r + " " + timestamp).collect(Collectors.toList()) : records; if (organization != null && bucket != null) { writeApi.writeRecords(bucket, organization, writePrecision, recordsToWrite); } else { writeApi.writeRecords(writePrecision, recordsToWrite); } } else { throw new IllegalArgumentException("Missing line protocol record(s)"); } } private WritePrecision getPrecision(final Event event) { final Object precision = event.getProperty(PRECISION); final WritePrecision writePrecision; if (precision instanceof String) { writePrecision = WritePrecision.fromValue((String) precision); if (writePrecision == null) { throw new IllegalArgumentException("Unsupported precision"); } } else if (precision instanceof WritePrecision) { writePrecision = (WritePrecision) precision; } else { writePrecision = WritePrecision.NS; } return writePrecision; } private BigInteger calculateTimestamp(final Event event, final WritePrecision precision) { if (config.timestamp_append()) { final Long timestamp = (Long) event.getProperty(EventConstants.TIMESTAMP); if (timestamp != null) { return NanosecondConverter.convert(timestamp, precision); } else { return NanosecondConverter.currentTimestamp(precision); } } else { return null; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy