SampleType
- type that is implemented by all samples that are generated by this
control-system support.public interface ControlSystemSupport<SampleType extends Sample>
Interface to a control-system support module. Each control-system support has
to implement this interface so that the archive server can use it. The module
also has to register a ControlSystemSupportFactory
which is
responsible for creating the ControlSystemSupport
instance when
requested by the server.
Classes implementing this interface must be thread-safe. All methods might be called in parallel by different threads.
Modifier and Type | Field and Description |
---|---|
static int |
SAMPLES_LIMIT_UNBOUNDED
Number to be specified when samples should be retrieved without limiting
their number.
|
Modifier and Type | Method and Description |
---|---|
com.google.common.util.concurrent.ListenableFuture<? extends ControlSystemChannel> |
createChannel(String channelName,
Map<String,String> options,
SampleBucketId currentBucketId,
SampleListener<SampleType> sampleListener)
Creates the control-system-specific support for an archived channel.
|
SampleDecimator<SampleType> |
createSampleDecimator(String channelName,
Map<String,String> options,
long intervalStartTime,
long intervalLength)
Creates a sample decimator.
|
com.google.common.util.concurrent.ListenableFuture<Void> |
deleteSamples(SampleBucketId bucketId)
Deletes all samples associated with the specified sample bucket.
|
void |
destroy()
Destroys this control-system support.
|
com.google.common.util.concurrent.ListenableFuture<SampleWithSizeEstimate<SampleType>> |
generateChannelDisabledSample(String channelName,
Map<String,String> options,
SampleBucketId currentBucketId)
Generates a sample that indicates that the specified channel is disabled.
|
String |
getId()
Returns the identifier that uniquely identifies the control-system
support module.
|
String |
getName()
Returns a short, descriptive name for this control-system support,
suitable for display.
|
com.google.common.util.concurrent.ListenableFuture<SampleBucketState> |
getSampleBucketState(SampleBucketId bucketId)
Returns the state of the specified sample bucket.
|
com.google.common.util.concurrent.ListenableFuture<ObjectResultSet<SampleType>> |
getSamples(SampleBucketId bucketId,
long timeStampGreaterThanOrEqualTo,
long timeStampLessThanOrEqualTo,
int limit)
Retrieves samples from the specified sample bucket.
|
com.google.common.util.concurrent.ListenableFuture<ObjectResultSet<SampleType>> |
getSamplesInReverseOrder(SampleBucketId bucketId,
long timeStampGreaterThanOrEqualTo,
long timeStampLessThanOrEqualTo,
int limit)
Retrieves samples from the specified sample bucket in reverse order
(newer samples first).
|
void |
serializeSampleToJsonV1(SampleType sample,
JsonGenerator jsonGenerator)
Serializes a sample in the JSON format version 1.
|
com.google.common.util.concurrent.ListenableFuture<Void> |
writeSample(SampleType sample,
SampleBucketId bucketId,
int newBucketSize)
Writes a sample to the database.
|
static final int SAMPLES_LIMIT_UNBOUNDED
com.google.common.util.concurrent.ListenableFuture<? extends ControlSystemChannel> createChannel(String channelName, Map<String,String> options, SampleBucketId currentBucketId, SampleListener<SampleType> sampleListener)
Creates the control-system-specific support for an archived channel. The channel should be created in an asynchronous way. Any blocking or long running operation should be performed in a separate thread that completes the returned future once it has finished.
Separate calls to this method providing the same channel name should result in separate channel instances being returned. In particular, destroying a channel instance should never destroy other channel instances with the same channel name.
The control-system support is supposed to notify the
sampleListener
whenever it detects that the value of the
channel has changed in the control-system and the new value should be
archived. It is important that the sampleListener
gets the
correct instance of the control-system channel passed to it. This must
exactly be the instance provided by the future returned by this method
because the archiving code will test for object identity when checking
that a sample comes from the most recent instance of a control-system
channel (and not from an instance that has been destroyed).
A control-system support should not throw an exception when creating a channel unless it detects a permanent problem. The archiving code will not retry creating a channel if an exception has been thrown unless the configuration for this channel is changed or the whole server goes offline and back online. Therefore, transient problems (e.g. connection problems) should be handled internally, transparently establishing the connection when the problems have been resolved.
This method is only called when archiving for a channel has been enabled
in the channel's configuration. When archiving has been disabled, the
generateChannelDisabledSample(String, Map, SampleBucketId)
method is called instead.
channelName
- name identifying the channel.options
- control-system-specific options associated with the channel.
The interpretation of this options is up to the implementation
of the control-system support.currentBucketId
- ID of the sample bucket to which raw samples for the channel
are currently being written. This may be null
if
no samples have been written yet. The control-system support
may use this information if it needs information about the
sample last written before it can start operation.sampleListener
- listener that shall be notified whenever the control-system
support detects that the channel's value has changed in the
control-system and the new value should be archived.SampleDecimator<SampleType> createSampleDecimator(String channelName, Map<String,String> options, long intervalStartTime, long intervalLength)
Creates a sample decimator. A sample decimator is responsible for creating a decimated sample for a certain period of time. This period is specified by the interval start-time and length parameters.
The actual strategy for generating a decimated sample depends on the control-system support and possibly even on the internal type of the sample. For example, a simple implementation might always choose the sample right at the beginning of the period, thus simply decimating the samples. A more complex implementation might calculate the average of the samples in the period and create a decimated sample that represents this average, possibly carrying additional information like minimum and maximum values or the standard deviation.
The sample decimator returned by this method does not have to be thread-safe. Its method may only be called by a single thread. This method however has to be thread-safe, because many sample decimators might be created and active at the same time.
This method must not block or perform any long-running actions as it might be called from time-sensitive threads.
Please refer to the description of the SampleDecimator
interface
for details about the contract that applies to sample decimators.
channelName
- name identifying the channel for which samples are supposed to
be decimated.options
- control-system-specific options associated with the channel.
The interpretation of this options is up to the implementation
of the control-system support.intervalStartTime
- start time or the period for which the created sample
decimator is supposed to generate a decimated sample. The
first sample passed to the sample decimator is guaranteed to
have a time stamp less than or equal to this time. The start
time is specified as the number of nanoseconds since epoch
(January 1st, 1970, 00:00:00 UTC).intervalLength
- the length of the period for which the created sample
decimator is supposed to generate a decimated sample. Together
with the intervalStartTime
, the
intervalLength
specifies the whole interval that
shall be covered by the created sample decimator. This
interval is [intervalStartTime
,
intervalStartTime
+ intervalLength
).
The length is specified in nanoseconds.com.google.common.util.concurrent.ListenableFuture<Void> deleteSamples(SampleBucketId bucketId)
bucketId
- unique identifier of the sample bucket that shall be deleted.void destroy()
com.google.common.util.concurrent.ListenableFuture<SampleWithSizeEstimate<SampleType>> generateChannelDisabledSample(String channelName, Map<String,String> options, SampleBucketId currentBucketId)
Generates a sample that indicates that the specified channel is disabled.
If the sample cannot be generated immediately, it should be generated in
an asynchronous way. This method must never block. When no marker sample
shall be written, the future returned by this method returns
null
, this method itself, however, never returns
null
.
This method is only called when archiving for a channel has been disabled
in the channel's configuration. When archiving has been enabled, the
createChannel(String, Map, SampleBucketId, SampleListener)
method is called instead. This method is called every time that the
channel is is initialized by the archiving service. Typically, this
happens every time when the server switches from the offline to the
online state.
A control-system support may choose to generate a marker sample that
indicates that a channel has been disabled. Such a marker sample might
help in determining why there is no valid data for a certain period of
time. However, a control-system support may also choose not to write such
a sample (possibly based on a configuration option). In this case, the
future returned by this method returns null
and the
archiving service does not write a sample..
channelName
- name identifying the channel.options
- control-system-specific options associated with the channel.
The interpretation of this options is up to the implementation
of the control-system support.currentBucketId
- ID of the sample bucket to which raw samples for the channel
are currently being written. This may be null
if
no samples have been written yet. The control-system support
may use this information if it needs information about the
sample last written for generating the marker sample.null
if no
such sample shall be written. The future throws an exception if
there is an error while processing the request, typically because
the specified options
are invalid.String getId()
String getName()
com.google.common.util.concurrent.ListenableFuture<SampleBucketState> getSampleBucketState(SampleBucketId bucketId)
bucketId
- unique identifier of the bucket for which the meta data shall
be received.null
value to be returned. Instead, the returned
bucket state should specify a bucket size of zero and a time
stamp of zero for the latest sample.com.google.common.util.concurrent.ListenableFuture<ObjectResultSet<SampleType>> getSamples(SampleBucketId bucketId, long timeStampGreaterThanOrEqualTo, long timeStampLessThanOrEqualTo, int limit)
Retrieves samples from the specified sample bucket. The result set containing the samples matching the query is returned through a future. If the query fails, the future throws an exception.
The process for retrieving samples may (and typically will) be iterative, meaning that samples are not retrieved all at once but gradually as they are read from the result set. For this reason, retrieving samples from the result set can fail with an exception, even if the future completed successfully.
The samples in the bucket that have a time-stamp between
timeStampGreaterThanOrEqualTo
and
timeStampLessThanOrEqualTo
(both inclusive) are returned.
The returned samples are ordered by the natural order of their
time-stamps (ascending, older samples first). If there are more samples
in the specified interval than the specified limit
, only the
first limit
samples are returned. If limit
is
negative, the number of samples returned is unbounded.
Calls to this method should not block. Instead, this method should quickly return a future that completes when a longer running operation has completed in the background.
bucketId
- identifier of the sample bucket from which the samples shall
be retrieved.timeStampGreaterThanOrEqualTo
- lower limit of the time interval (inclusive) for which samples
shall be retrieved.timeStampLessThanOrEqualTo
- upper limit of the time interval (inclusive) for which samples
shall be retrieved.limit
- maximum number of samples that shall be retrieved. If the
number of samples shall not be bounded,
SAMPLES_LIMIT_UNBOUNDED
should be specified.getSamplesInReverseOrder(SampleBucketId, long, long, int)
com.google.common.util.concurrent.ListenableFuture<ObjectResultSet<SampleType>> getSamplesInReverseOrder(SampleBucketId bucketId, long timeStampGreaterThanOrEqualTo, long timeStampLessThanOrEqualTo, int limit)
Retrieves samples from the specified sample bucket in reverse order (newer samples first). The result set containing the samples matching the query is returned through a future. If the query fails, the future throws an exception.
The process for retrieving samples may (and typically will) be iterative, meaning that samples are not retrieved all at once but gradually as they are read from the result set. For this reason, retrieving samples from the result set can fail with an exception, even if the future completed successfully.
The samples in the bucket that have a time-stamp between
timeStampGreaterThanOrEqualTo
and
timeStampLessThanOrEqualTo
(both inclusive) are returned.
The returned samples are ordered by the inverse natural order of their
time-stamps (descending, newer samples first). If there are more samples
in the specified interval than the specified limit
, only the
first limit
samples are returned. If limit
is
negative, the number of samples returned is unbounded.
Calls to this method should not block. Instead, this method should quickly return a future that completes when a longer running operation has completed in the background.
bucketId
- identifier of the sample bucket from which the samples shall
be retrieved.timeStampGreaterThanOrEqualTo
- lower limit of the time interval (inclusive) for which samples
shall be retrieved.timeStampLessThanOrEqualTo
- upper limit of the time interval (inclusive) for which samples
shall be retrieved.limit
- maximum number of samples that shall be retrieved. If the
number of samples shall not be bounded,
SAMPLES_LIMIT_UNBOUNDED
should be specified.getSamples(SampleBucketId, long, long, int)
void serializeSampleToJsonV1(SampleType sample, JsonGenerator jsonGenerator) throws IOException
JsonV1SampleSerializer
. This will help to
ensure that the serialization format matches the specification expected
by a client.sample
- sample to be serialized. This sample has been provided by this
control-system support, so it is guaranteed to be of the
correct type.jsonGenerator
- JSON generator to which the serialized form of the sample
shall be written.IOException
- if such an exception is thrown by the
jsonGenerator
.com.google.common.util.concurrent.ListenableFuture<Void> writeSample(SampleType sample, SampleBucketId bucketId, int newBucketSize)
sample
- sample that shall be written. This sample has been provided by
this control-system support, so it is guaranteed to be of the
correct type.bucketId
- unique identifier of the bucket to which the
sample
shall be appended.newBucketSize
- new size of the sample bucket. The calling code takes care of
calculating the updated bucket size, so the control-system
support can simply save the supplied number.Copyright © 2011–2019 aquenos GmbH. All rights reserved.