75. Datum Data Source Poll JobΒΆ
The DatumDataSourcePollManagedJob
class is a Job
Service implementation that can be used to let users schedule the
generation of datum from a Datum Data Source. Typically this is configured
as a Managed Service Factory so users
can configure any number of job instances, each with their own settings.
Here is a typical example of a DatumDataSourcePollManagedJob
, in a fictional MyDatumDataSource
:
package com.example;
import java.time.Instant;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import net.solarnetwork.domain.datum.DatumSamples;
import net.solarnetwork.node.domain.datum.EnergyDatum;
import net.solarnetwork.node.domain.datum.NodeDatum;
import net.solarnetwork.node.domain.datum.SimpleEnergyDatum;
import net.solarnetwork.node.service.DatumDataSource;
import net.solarnetwork.node.service.support.DatumDataSourceSupport;
import net.solarnetwork.settings.SettingSpecifier;
import net.solarnetwork.settings.SettingSpecifierProvider;
import net.solarnetwork.settings.SettingsChangeObserver;
import net.solarnetwork.settings.support.BasicTextFieldSettingSpecifier;
/**
* Super-duper datum data source.
*
* @author matt
* @version 1.0
*/
public class MyDatumDataSource extends DatumDataSourceSupport
implements DatumDataSource, SettingSpecifierProvider, SettingsChangeObserver {
private String sourceId;
private int level;
@Override
public Class<? extends NodeDatum> getDatumType() {
return EnergyDatum.class;
}
@Override
public EnergyDatum readCurrentDatum() {
final String sourceId = resolvePlaceholders(this.sourceId);
if ( sourceId == null || sourceId.isEmpty() ) {
return null;
}
SimpleEnergyDatum d = new SimpleEnergyDatum(sourceId, Instant.now(), new DatumSamples());
d.setWatts(level);
return d;
}
@Override
public void configurationChanged(Map<String, Object> properties) {
// the settings have changed; do something
}
@Override
public String getSettingUid() {
return "com.example.MyDatumDataSource";
}
@Override
public List<SettingSpecifier> getSettingSpecifiers() {
return Arrays.asList(new BasicTextFieldSettingSpecifier("sourceId", null),
new BasicTextFieldSettingSpecifier("level", String.valueOf(0)));
}
public String getSourceId() {
return sourceId;
}
public void setSourceId(String sourceId) {
this.sourceId = sourceId;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
}
title = Super-duper Datum Data Source
desc = This managed datum data source does it all.
schedule.key = Schedule
schedule.desc = The schedule to execute the job at. \
Can be either a number representing a frequency in <b>milliseconds</b> \
or a <a href="{0}">cron expression</a>, for example <code>0 * * * * *</code>.
sourceId.key = Source ID
sourceId.desc = The source ID to use.
level.key = Level
level.desc = This one goes to 11.
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgix="http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium
http://www.eclipse.org/gemini/blueprint/schema/blueprint-compendium/gemini-blueprint-compendium.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Service References -->
<bean id="datumMetadataService" class="net.solarnetwork.common.osgi.service.DynamicServiceTracker">
<argument ref="bundleContext"/>
<property name="serviceClassName" value="net.solarnetwork.node.service.DatumMetadataService"/>
<property name="sticky" value="true"/>
</bean>
<bean id="datumQueue" class="net.solarnetwork.common.osgi.service.DynamicServiceTracker">
<argument ref="bundleContext"/>
<property name="serviceClassName" value="net.solarnetwork.node.service.DatumQueue"/>
<property name="sticky" value="true"/>
</bean>
<bean id="placeholderService" class="net.solarnetwork.common.osgi.service.DynamicServiceTracker">
<argument ref="bundleContext"/>
<property name="serviceClassName" value="net.solarnetwork.node.service.PlaceholderService"/>
<property name="sticky" value="true"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="com.example.MyDatumDataSource"/>
</bean>
<bean id="jobMessageSource" class="net.solarnetwork.support.PrefixedMessageSource">
<property name="prefix" value="datumDataSource."/>
<property name="delegate" ref="messageSource"/>
</bean>
<!-- Managed Service Factory for Datum Data Source -->
<service interface="net.solarnetwork.settings.SettingSpecifierProviderFactory">
<bean class="net.solarnetwork.settings.support.BasicSettingSpecifierProviderFactory">
<property name="displayName" value="Super-duper Datum Data Source"/>
<property name="factoryUid" value="com.example.MyDatumDataSource"/><!-- (1)! -->
<property name="messageSource" ref="messageSource"/>
</bean>
</service>
<osgix:managed-service-factory factory-pid="com.example.MyDatumDataSource"
autowire-on-update="true" update-method="configurationChanged">
<osgix:interfaces>
<beans:value>net.solarnetwork.node.job.ManagedJob</beans:value>
</osgix:interfaces>
<bean class="net.solarnetwork.node.job.SimpleManagedJob"
init-method="serviceDidStartup" destroy-method="serviceDidShutdown">
<argument>
<bean class="net.solarnetwork.node.job.DatumDataSourcePollManagedJob">
<property name="datumMetadataService" ref="datumMetadataService"/>
<property name="datumQueue" ref="datumQueue"/>
<property name="datumDataSource">
<bean class="com.example.MyDatumDataSource"><!-- (2)! -->
<property name="datumMetadataService" ref="datumMetadataService"/>
<property name="messageSource" ref="jobMessageSource"/>
<property name="placeholderService" ref="placeholderService"/>
</bean>
</property>
</bean>
</argument>
<argument value="0 * * * * ?"/>
<property name="serviceProviderConfigurations"><!-- (3)! -->
<map>
<entry key="datumDataSource">
<bean class="net.solarnetwork.node.job.SimpleServiceProviderConfiguration">
<property name="interfaces">
<list>
<value>net.solarnetwork.node.service.DatumDataSource</value>
</list>
</property>
<property name="properties">
<map>
<entry key="datumClassName" value="net.solarnetwork.node.domain.datum.EnergyDatum"/>
</map>
</property>
</bean>
</entry>
</map>
</property>
</bean>
</osgix:managed-service-factory>
</blueprint>
- The
factoryUid
is the same value as thegetSettingsUid()
value inMyDatumDataSource.java
- Hiding down here is our actual data source!
- Adding a service provider configuration is optional, but registers our data source as an
OSGi service, in addition to the
ManagedJob
that the Managed Service Factory registers.
When this plugin is deployed in SolarNode, the managed component will appear on the main Settings page and then the component settings UI will look like this: