Time Series数据库是做数据分析常用的数据库,为了方便地在开发中访问Time Series服务,可以使用官方开发的Rest Client,以提高开发效率。
本篇将介绍如何在java环境下使用内置的Rest Client方便地访问Time Series服务。
在阅读本篇之前,请先保证您已经有一个Predix帐号,并完成以下Time Series使用教程进行了基本的配置:
上传数据到Predix的时序(Time Series)数据服务
注:该功能目前为beta版本,如果有什么疑问可以在Predix官方论坛提问
使用Rest Client访问Time Series服务可以通过以下几步:
首先,使用Rest Client访问Time Series需要在Maven的配置文件中加入相应的依赖。具体如下:
在~/.m2下Maven的配置文件Setting.xml文件中加入如下依赖:
<server>
<id>artifactory.externalid>
<username><predix-user-name>username>
<password><predix-password>password>
server>
其中,predix-user-name和predix-password是你的Predix用户名和密码。除了使用明文以外,此处也可以对用户名密码进行加密,具体可以访问apache加密相关的页面查看。
然后,在工程文件的pom.xml下面加入资源库和依赖
<repositories>
<repository>
<id>artifactory.externalid>
<name>GE external repositoryname>
<url>https://artifactory.predix.io/artifactory/PREDIX-EXTurl>
repository>
repositories>
<dependencies>
<dependency>
<groupId>com.ge.predix.timeseriesgroupId>
<artifactId>timeseries-clientartifactId>
<version>0.0.2-SNAPSHOTversion>
dependency>
dependencies>
Rest Client的正常工作需要提供对应的Time Series的配置信息,可以通过提供配置文件的方式或者编程的方式直接加入到项目中。
1. 通过配置文件加入配置信息
a. 将你的App绑定到你所创建的Time Series的一个instance上,绑定方法见上传数据到Predix的时序(Time Series)数据服务
b. 获取使用Time Series所需要的环境变量:在命令行登录后输入
cf env <application_name>
得到结果如下:
{
"predix-timeseries": [
{
"credentials": {
"ingest": {
"uri": "wss://gateway-predix-data-services.run.aws-jp01-pr.ice.predix.io/v1/stream/messages",
"zone-http-header-name": "Predix-Zone-Id",
"zone-http-header-value": "your-ts-zone-id",
"zone-token-scopes": [
"timeseries.zones.your-ts-zone-id.user",
"timeseries.zones.your-ts-zone-id.ingest"
]
},
"query": {
"uri": "https://time-series-store-predix.run.aws-jp01-pr.ice.predix.io/v1/datapoints",
"zone-http-header-name": "Predix-Zone-Id",
"zone-http-header-value": "your-ts-zone-id",
"zone-token-scopes": [
"timeseries.zones.your-ts-zone-id.user",
"timeseries.zones.your-ts-zone-id.query"
]
}
},
"label": "predix-timeseries",
"name": "your-ts-name",
"plan": "Free",
"provider": null,
"syslog_drain_url": null,
"tags": [
"timeseries",
"time-series",
"time series"
]
},
{
"predix-uaa": [
{
"credentials": {
"dashboardUrl": "https://uaa-dashboard.run.aws-jp01-pr.ice.predix.io/#/login/your-uaa-id",
"issuerId": "https://your-uaa-id.predix-uaa.run.aws-jp01-pr.ice.predix.io/oauth/token",
"subdomain": "your-uaa-id",
"uri": "https://your-uaa-id.predix-uaa.run.aws-jp01-pr.ice.predix.io",
"zone": {
"http-header-name": "X-Identity-Zone-Id",
"http-header-value": "your-uaa-id" }
},
"label": "predix-uaa",
"name": "your-uaa-name",
"plan": "Free",
"provider": null,
"syslog_drain_url": null,
"tags": [],
"volume_mounts": []
}
]
}
]
}
c. 在工程目录中创建一个名为predix-timeseries.properties的文件,并将上一步中得到的参数以及用于访问Time Series的client的信息填到文件中。
# Predix Timeseries configuration. >>>>>
# DO NOT MODIFY WITHOUT CONSULTING PREDIX SUPPORT
predix.timeseries.maxTagsPerQuery=5
predix.timeseries.maxIngestionMessageSize=512000
# Predix Timeseries configuration. <<<<<
#Purchased Plan restrictions. >>>>>
# MODIFY TO SUIT YOUR PLAN. GOING OVER MIGHT RESULT IN ADDED CHARGES
plan.ingestion.concurrent.connections.max=100
plan.query.concurrent.connections.max=100
#Purchased Plan restrictions. <<<<<
#Execution properties. >>>>>
# MODIFY AS APPROPRIATE
#Execution properties. <<<<<
uaa.uri=without the /oauth/token)>
ingestion.uri=from the binding to Predix time-series>
ingestion.zone-http-header-name=Predix-Zone-Id
ingestion.client.id=<the client id that has scope access to 'timeseries.zones.id>.ingest'>
ingestion.client.secret.env.variable=that contains the ingestion client secret>
query.uri=from the binding to Predix time-series>
query.zone-http-header-name=Predix-Zone-Id
query.client.id=id that has scope access to 'timeseries.zones.id>.query'>
query.client.secret.env.variable=that contains the query client secret>
d. 然后把工程文件的目录添加到代码中:
TenantContext tenant = TenantContextFactory.createTenantContextFromPropertiesFile(propertiesPath);
TenantContext tenant = TenantContextFactory.createTenantContextFromProvidedProperties(queryUri, queryAccessToken, ingestionUri, ingestionAccessToken, zoneHeaderName, zoneId)
如果只需要进行注入,则通过以下代码:
TenantContext tenant = TenantContextFactory.createIngestionTenantContextFromProvidedProperties(ingestionUrl, authToken, predixZoneIdHeaderName, predixZoneIdHeaderValue);
如果只需要读取,则通过以下代码:
TenantContext tenant = TenantContextFactory.createQueryTenantContextFromProvidedProperties(queryUrl, authToken, predixZoneIdHeaderName, predixZoneIdHeaderValue);
以下是一个java代码的例子:
Integer sensorValueAsInt = (int) Math.random();
Double sensorValueAsDouble = Math.random();
IngestionRequestBuilder ingestionBuilder = IngestionRequestBuilder.createIngestionRequest()
.withMessageId("" )
.addIngestionTag(IngestionTag.Builder.createIngestionTag()
.withTagName("TagName")
.addDataPoints(
Arrays.asList(
new DataPoint(new Date().getTime(), sensorValueAsInt, Quality.GOOD),
new DataPoint(new Date().getTime(), sensorValueAsDouble, Quality.NOT_APPLICABLE),
new DataPoint(new Date().getTime(), "Bad Value", Quality.BAD),
new DataPoint(new Date().getTime(), null, Quality.UNCERTAIN)
)
)
.addAttribute("AttributeKey", "AttributeValue")
.addAttribute("AttributeKey2", "AttributeValue2")
.build());
String json = ingestionBuilder.build().get(0);
IngestionResponse response = ClientFactory.ingestionClientForTenant(tenant).ingest(json);
String responseStr = response.getMessageId() + response.getStatusCode();
其中,tenant为第二步中所配置的Tenant。
注:Time Series单次上传数据不能超过512KB,目前Time Series还支持压缩格式(GZIP)的Json,但解压后的大小依旧不能超过512KB。
在java中可以用以下代码通过Client读取Time Series数据:
QueryBuilder builder = QueryBuilder.createQuery()
.withStartAbs(1427463525000L)
.withEndAbs(1427483525000L)
.addTags(
QueryTag.Builder.createQueryTag()
.withTagNames(Arrays.asList("ALT_SENSOR", "TEMP_SENSOR"))
.withLimit(1000)
.addAggregation(Aggregation.Builder.averageWithInterval(1, TimeUnit.HOURS))
.addFilters(FilterBuilder.getInstance()
.addAttributeFilter("host", Arrays.asList("" )).build())
.addFilters(FilterBuilder.getInstance()
.addAttributeFilter("type", Arrays.asList("" )).build())
.addFilters(FilterBuilder.getInstance()
.addMeasurementFilter(FilterBuilder.Condition.GREATER_THAN_OR_EQUALS, Arrays.asList("23.1")).build())
.addFilters(FilterBuilder.getInstance()
.withQualitiesFilter(Arrays.asList(Quality.BAD, Quality.GOOD)).build())
.build());
QueryResponse response = ClientFactory.queryClientForTenant(tenant).queryAll(builder.build());
其中,tenant为第二步中所配置的tenant。