Files
Henry ZhangandClaude Fable 5 7c643a8e80 fix(api): dc3-api contract overhaul (auth JWT, history, presence, decision enum) (#193)
* fix(api): correct inverted enable_flag comment and document time unit

- tenant.proto enable_flag comment said "1 enabled, 0 disabled" but the
  actual EnableFlagEnum is ENABLE=0, DISABLE=1 — callers reading the
  comment would invert the flag. Correct it.
- base.proto create_time/operate_time are epoch milliseconds
  (LocalDateTimeUtil/Instant.toEpochMilli); document the unit so callers
  don't guess seconds vs millis.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(api): carry timestamp in point-value history; explicit bool presence

#5 Point-value history: the whole chain (proto -> gRPC server ->
PointValueService -> repository -> facades -> controller -> agentic tool)
returned List<String> and dropped create_time even though the DB row
already carried it. Switch to PointValueBO / FacadePointValueBO end to
end so callers receive each value with its timestamp.

#6 Field presence: GrpcR.ok and McpIntrospectDTO.active are now optional
bool, so "unset" is distinguishable from false on the wire.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(auth): unify JWT signing key, drop salt/password from token contract

The JWT signing key was per-principal — securityKey + ":" + salt, where
salt was the credential salt also carried through the gateway and the
token RPC. That makes the JWT key weak and widens salt exposure to every
gateway hop. Sign with the single configured securityKey (HS256) instead
and remove salt from the JWT path entirely:

- KeyUtil.generateToken/parserToken drop the salt parameter; the HMAC
  key is now just securityKey (must be >= 32 bytes for HS256).
- TokenService.generateToken/checkValid drop the salt parameter.
- token.proto GrpcLoginQuery drops salt and password — CheckValid only
  ever needed tenant, name and token.
- gateway FilterService, TokenGrpcFacade, TokenController adapted; the
  request header no longer feeds salt into validation.

The login-handshake salt (POST /token/salt, used to salt the password
client-side before verifyPassword) is unchanged — only the JWT signing
salt is removed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(api): type MCP authorize decision as proto enum

The authorize-tool-call decision was a free-form string, so callers
could only compare it against literals with no compile-time check.
Introduce GrpcMcpDecision (MCP_DECISION_UNSPECIFIED / AUTHORIZED /
CONFIRM_REQUIRED / REJECTED) and type GrpcMcpToolAuthorizeDTO.decision
with it. Enum names match the existing auth-side literals, so the
mapping is a direct valueOf / name().

- McpRuntimeServer builds the enum via toGrpcDecision (unknown -> UNSPECIFIED).
- McpRuntimeGrpcFacade maps enum -> BO string via name().
- gateway unchanged: it receives the BO (string decision) through the facade.

The other string MCP fields (risk_level, status, grant_type,
principal_type) stay strings for now — their value sets are wider and
partly lowercase (OAuth grant_type), so they are a follow-up.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(facade): align TokenLocalFacade with 3-arg checkValid (CI compile fix)

TokenLocalFacade (local impl) was missed when TokenFacade.checkValid
dropped salt; CI compiles facade-local-auth independently and caught
it. Align it + its test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 16:36:35 +08:00
..

DC3 API Data

Overview

dc3-api-data provides gRPC service definitions for device data collection and management in the IoT DC3 platform. It defines interfaces for querying real-time device point values and historical data retrieval.

Module Information

  • Group ID: io.github.pnoker
  • Artifact ID: dc3-api-data
  • Version: 2026.5.22
  • Package: io.github.pnoker.api.center.data

Proto Definitions

point_value.proto

Defines point value query RPC calls and data structures for device data collection.

Service: PointValueApi

  • GetLastValue - Query the latest collected value of a device point
  • ListHistoryValues - Query historical values of a device point
  • ReadCommand - Trigger a read command for a device point
  • WriteCommand - Trigger a write command for a device point

Key Messages:

  • GrpcPointValueQuery - Request wrapper for point value queries (device_id, point_id, tenant_id)
  • GrpcRPointValueDTO - Response wrapper containing point value information
  • GrpcPointValueDTO - Point value data structure

event_history.proto

Defines device event history RPC calls.

Service: EventHistoryApi

  • ReportEvent - Report a device event
  • GetByRecordId - Query an event history record by record ID
  • ListByPage - Query event history with pagination support

command_history.proto

Defines device command history RPC calls.

Service: CommandHistoryApi

  • CallCommand - Issue a command to a device
  • GetByRecordId - Query a command history record by record ID
  • ListByPage - Query command history with pagination support

status_health.proto

Defines device/driver status and system health RPC calls.

Service: StatusHealthApi

  • DeviceStatusesByIds - Query device statuses by device IDs
  • DeviceStatusesByProfileId - Query device statuses by profile ID
  • DriverStatusesByIds - Query driver statuses by driver IDs
  • DriverDeviceStatusSummary - Summarize device statuses under a driver
  • SystemHealth - Query overall system health

Data Models

Point Value Model

The GrpcPointValueDTO represents collected data from device points:

message GrpcPointValueDTO {
  int64 id = 1;           // Point value record ID
  int64 device_id = 2;    // Source device identifier
  int64 point_id = 3;     // Point identifier
  string value = 4;       // Processed/converted value
  string raw_value = 5;   // Raw value from device
  int64 create_time = 6;  // Storage timestamp
}

Field Descriptions

Field Type Description
id int64 Unique identifier for the point value record
device_id int64 ID of the device that generated the data
point_id int64 ID of the point (tag) within the device
value string Processed value after data conversion and formatting
raw_value string Original raw value collected from the device
create_time int64 Unix timestamp when data was stored (milliseconds)

Dependencies

This module depends on common proto definitions:

  • api/common/r.proto - Common response wrapper (GrpcR)

Usage

1. Add Dependency


<dependency>
    <groupId>io.github.pnoker</groupId>
    <artifactId>dc3-api-data</artifactId>
    <version>2026.5.22</version>
</dependency>

2. Import Proto Files

import "api/center/data/point_value.proto";

3. Implement Service

public class PointValueServiceImpl extends PointValueApiGrpc.PointValueApiImplBase {
    @Override
    public void getLastValue(GrpcPointValueQuery request,
                             StreamObserver<GrpcRPointValueDTO> responseObserver) {
        // Query latest point value from database
        // Return GrpcRPointValueDTO with point value data
    }
}

4. Query Example

// Build query request
GrpcPointValueQuery query = GrpcPointValueQuery.newBuilder()
                .setDeviceId(12345L)
                .setPointId(67890L)
                .setTenantId(1L)
                .build();

// Call service
GrpcRPointValueDTO response = pointValueApi.getLastValue(query);

// Extract data
if(response.

getResult().

getOk()){
GrpcPointValueDTO pointValue = response.getData();
String value = pointValue.getValue();
String rawValue = pointValue.getRawValue();
long timestamp = pointValue.getCreateTime();
}

API Features

Real-Time Data Access

  • Query latest point values by device and point IDs
  • Support for both raw and processed values
  • Tenant-scoped data access

Data Processing

  • Raw Value: Original data read from the device without processing
  • Processed Value: Converted and formatted value after applying:
    • Unit conversion
    • Scale factors
    • Precision formatting
    • Data type conversion

Data Flow

Device → Driver → Data Collection → Time Series DB → PointValueApi

Use Cases

1. Real-Time Monitoring

// Monitor device point value in real-time
GrpcPointValueDTO latestValue = getLastValue(deviceId, pointId);

displayValue(latestValue.getValue());

2. Data Analysis

// Compare raw vs processed values
String raw = pointValue.getRawValue();
String processed = pointValue.getValue();

analyzeConversion(raw, processed);

3. Time Series Operations

// Use timestamp for time-based queries
long timestamp = pointValue.getCreateTime();
Date collectionTime = new Date(timestamp);

Performance Considerations

  • Query Optimization: Always include tenant_id for proper data isolation
  • Caching: Consider caching recent point values for high-frequency queries
  • Time Series Store: This API queries the time-series store through dc3-common-repository (PostgreSQL with the TimescaleDB extension)
  • Data Volume: Point value queries can generate high traffic in large-scale deployments

Integration Points

Driver Services

Drivers write point values to the data layer:

Driver Service → Device SDK → Point Collection → Data Store

Manager Service

Manager service provides device/point metadata:

PointValueApi → ManagerApi (get point info) → Return value with metadata

Application Layer

Upper applications consume point value data for:

  • Real-time dashboards
  • Data analytics
  • Alarm monitoring
  • Historical data queries

Data Retention

Point values are typically stored in time-series databases with:

  • High-frequency data: Raw values for immediate processing
  • Aggregated data: Processed values for long-term storage
  • Retention policies: Configurable by tenant or device type

Build Instructions

# Build the module
mvn -s ../../.mvn/settings.xml clean package

# Install to local repository
mvn -s ../../.mvn/settings.xml clean install
  • dc3-api-driver - Driver interface for point data collection
  • dc3-api-manager - Device and point metadata management
  • dc3-common-data - Data models and DTOs

License

Copyright 2016-present the IoT DC3 original author or authors.

Licensed under the GNU Affero General Public License v3.0 (AGPL 3.0)