refactor: slim vehicle analytics app runtime
This commit is contained in:
@@ -166,9 +166,7 @@ services:
|
||||
<<: *common-env
|
||||
HTTP_PORT: 20300
|
||||
KAFKA_CONSUMER_CLIENT_ID_PREFIX: ${KAFKA_CONSUMER_CLIENT_ID_PREFIX_ANALYTICS:-vehicle-analytics}
|
||||
KAFKA_GROUP_STATE: ${KAFKA_GROUP_STATE:-vehicle-state}
|
||||
KAFKA_GROUP_STAT: ${KAFKA_GROUP_STAT:-vehicle-stat}
|
||||
VEHICLE_STATE_ENABLED: ${VEHICLE_STATE_ENABLED:-false}
|
||||
VEHICLE_STAT_ENABLED: ${VEHICLE_STAT_ENABLED:-true}
|
||||
VEHICLE_STAT_ZONE_ID: ${VEHICLE_STAT_ZONE_ID:-Asia/Shanghai}
|
||||
VEHICLE_STAT_JT808_MILEAGE_ENABLED: ${VEHICLE_STAT_JT808_MILEAGE_ENABLED:-true}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
<artifactId>vehicle-analytics-app</artifactId>
|
||||
<name>vehicle-analytics-app</name>
|
||||
<description>Vehicle state, daily statistics, alarms, and analytics runtime.</description>
|
||||
<description>Vehicle daily statistics and analytics runtime.</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@@ -25,10 +25,6 @@
|
||||
<groupId>com.lingniu.ingest</groupId>
|
||||
<artifactId>sink-mq</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.lingniu.ingest</groupId>
|
||||
<artifactId>vehicle-state-service</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.lingniu.ingest</groupId>
|
||||
<artifactId>vehicle-stat-service</artifactId>
|
||||
|
||||
@@ -22,13 +22,6 @@ spring:
|
||||
username: ${MYSQL_USERNAME:}
|
||||
password: ${MYSQL_PASSWORD:}
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
data:
|
||||
redis:
|
||||
host: ${REDIS_HOST:}
|
||||
port: ${REDIS_PORT:6379}
|
||||
username: ${REDIS_USERNAME:}
|
||||
password: ${REDIS_PASSWORD:}
|
||||
database: ${REDIS_DATABASE:50}
|
||||
|
||||
server:
|
||||
port: ${HTTP_PORT:20300}
|
||||
@@ -58,11 +51,6 @@ lingniu:
|
||||
max-poll-records: ${KAFKA_CONSUMER_MAX_POLL_RECORDS:500}
|
||||
max-poll-interval-millis: ${KAFKA_CONSUMER_MAX_POLL_INTERVAL_MILLIS:900000}
|
||||
bindings:
|
||||
vehicleStateEnvelopeConsumerProcessor:
|
||||
enabled: ${VEHICLE_STATE_ENABLED:false}
|
||||
group-id: ${KAFKA_GROUP_STATE:vehicle-state}
|
||||
topics:
|
||||
- ${KAFKA_TOPIC_JT808_EVENT:vehicle.event.jt808.v1}
|
||||
vehicleStatEnvelopeConsumerProcessor:
|
||||
enabled: ${VEHICLE_STAT_ENABLED:true}
|
||||
group-id: ${KAFKA_GROUP_STAT:vehicle-stat}
|
||||
@@ -72,8 +60,6 @@ lingniu:
|
||||
enabled: false
|
||||
event-history:
|
||||
enabled: false
|
||||
vehicle-state:
|
||||
enabled: ${VEHICLE_STATE_ENABLED:false}
|
||||
vehicle-stat:
|
||||
enabled: ${VEHICLE_STAT_ENABLED:true}
|
||||
zone-id: ${VEHICLE_STAT_ZONE_ID:Asia/Shanghai}
|
||||
@@ -85,9 +71,6 @@ management:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics,prometheus,env
|
||||
health:
|
||||
redis:
|
||||
enabled: ${MANAGEMENT_HEALTH_REDIS_ENABLED:false}
|
||||
metrics:
|
||||
tags:
|
||||
application: vehicle-analytics-app
|
||||
|
||||
@@ -5,8 +5,6 @@ import com.lingniu.ingest.api.consumer.EnvelopeConsumerProcessor;
|
||||
import com.lingniu.ingest.sink.mq.KafkaEnvelopeDeadLetterSink;
|
||||
import com.lingniu.ingest.sink.mq.KafkaEventSink;
|
||||
import com.lingniu.ingest.sink.mq.SinkMqAutoConfiguration;
|
||||
import com.lingniu.ingest.vehiclestate.VehicleStateEnvelopeIngestor;
|
||||
import com.lingniu.ingest.vehiclestate.config.VehicleStateAutoConfiguration;
|
||||
import com.lingniu.ingest.vehiclestat.JdbcVehicleStatMetricRepository;
|
||||
import com.lingniu.ingest.vehiclestat.VehicleStatController;
|
||||
import com.lingniu.ingest.vehiclestat.VehicleStatEnvelopeIngestor;
|
||||
@@ -18,7 +16,6 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -32,19 +29,16 @@ class VehicleAnalyticsAppCompositionTest {
|
||||
new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(
|
||||
SinkMqAutoConfiguration.class,
|
||||
VehicleStateAutoConfiguration.class,
|
||||
VehicleStatAutoConfiguration.class))
|
||||
.withAllowBeanDefinitionOverriding(true)
|
||||
.withBean("kafkaProducer", KafkaProducer.class, VehicleAnalyticsAppCompositionTest::kafkaProducer)
|
||||
.withBean(JdbcTemplate.class, () -> mock(JdbcTemplate.class))
|
||||
.withBean(StringRedisTemplate.class, () -> mock(StringRedisTemplate.class))
|
||||
.withBean(ObjectMapper.class, ObjectMapper::new)
|
||||
.withPropertyValues(
|
||||
"lingniu.ingest.sink.mq.enabled=true",
|
||||
"lingniu.ingest.sink.mq.type=kafka",
|
||||
"lingniu.ingest.sink.mq.bootstrap-servers=localhost:9092",
|
||||
"lingniu.ingest.sink.mq.consumer.enabled=false",
|
||||
"lingniu.ingest.vehicle-state.enabled=false",
|
||||
"lingniu.ingest.vehicle-stat.enabled=true",
|
||||
"lingniu.ingest.vehicle-stat.jt808.enabled=true",
|
||||
"lingniu.ingest.event-history.enabled=false",
|
||||
@@ -61,7 +55,8 @@ class VehicleAnalyticsAppCompositionTest {
|
||||
assertThat(context.getBean("vehicleStatEnvelopeConsumerProcessor"))
|
||||
.isInstanceOf(EnvelopeConsumerProcessor.class);
|
||||
|
||||
assertThat(context).doesNotHaveBean(VehicleStateEnvelopeIngestor.class);
|
||||
assertTypeNotPresent(context, "com.lingniu.ingest.vehiclestate.VehicleStateEnvelopeIngestor");
|
||||
assertTypeNotPresent(context, "com.lingniu.ingest.vehiclestate.config.VehicleStateAutoConfiguration");
|
||||
assertTypeNotPresent(context, "com.lingniu.ingest.protocol.gb32960.inbound.Gb32960NettyServer");
|
||||
assertTypeNotPresent(context, "com.lingniu.ingest.eventfilestore.EventFileStore");
|
||||
});
|
||||
|
||||
@@ -29,24 +29,25 @@ class VehicleAnalyticsAppDefaultsTest {
|
||||
.containsEntry(
|
||||
"lingniu.ingest.vehicle-stat.jt808.enabled",
|
||||
"${VEHICLE_STAT_JT808_MILEAGE_ENABLED:true}")
|
||||
.containsEntry("lingniu.ingest.vehicle-state.enabled", "${VEHICLE_STATE_ENABLED:false}")
|
||||
.containsEntry("lingniu.ingest.sink.mq.consumer.enabled", "${KAFKA_CONSUMER_ENABLED:true}")
|
||||
.containsEntry(
|
||||
"lingniu.ingest.sink.mq.consumer.bindings.vehicleStatEnvelopeConsumerProcessor.enabled",
|
||||
"${VEHICLE_STAT_ENABLED:true}")
|
||||
.containsEntry(
|
||||
"lingniu.ingest.sink.mq.consumer.bindings.vehicleStateEnvelopeConsumerProcessor.enabled",
|
||||
"${VEHICLE_STATE_ENABLED:false}")
|
||||
.containsEntry(
|
||||
"lingniu.ingest.sink.mq.consumer.bindings.vehicleStatEnvelopeConsumerProcessor.group-id",
|
||||
"${KAFKA_GROUP_STAT:vehicle-stat}")
|
||||
.containsEntry(
|
||||
"lingniu.ingest.sink.mq.consumer.bindings.vehicleStateEnvelopeConsumerProcessor.group-id",
|
||||
"${KAFKA_GROUP_STATE:vehicle-state}");
|
||||
"${KAFKA_GROUP_STAT:vehicle-stat}");
|
||||
|
||||
assertThat(properties.stringPropertyNames())
|
||||
.noneMatch(name -> name.startsWith("lingniu.ingest.event-file-store."));
|
||||
assertThat(applicationYaml()).doesNotContain("event-file-store:");
|
||||
.noneMatch(name -> name.startsWith("lingniu.ingest.event-file-store."))
|
||||
.noneMatch(name -> name.startsWith("lingniu.ingest.vehicle-state."))
|
||||
.noneMatch(name -> name.contains("vehicleStateEnvelopeConsumerProcessor"))
|
||||
.noneMatch(name -> name.startsWith("spring.data.redis."))
|
||||
.noneMatch(name -> name.startsWith("management.health.redis."));
|
||||
assertThat(applicationYaml())
|
||||
.doesNotContain("event-file-store:")
|
||||
.doesNotContain("vehicle-state:")
|
||||
.doesNotContain("vehicleStateEnvelopeConsumerProcessor")
|
||||
.doesNotContain("redis:");
|
||||
}
|
||||
|
||||
private static Properties applicationProperties() {
|
||||
|
||||
@@ -48,6 +48,19 @@ class PortainerComposeResourceLimitsTest {
|
||||
.doesNotContain("\n TDENGINE_DATABASE:");
|
||||
}
|
||||
|
||||
@Test
|
||||
void vehicleAnalyticsComposeOnlyExposesStatConsumerEnvironment() throws IOException {
|
||||
String compose = Files.readString(repositoryRoot().resolve("deploy/portainer/docker-compose.yml"));
|
||||
String analyticsService = serviceBlock(compose, "vehicle-analytics-app");
|
||||
|
||||
assertThat(analyticsService)
|
||||
.contains("KAFKA_GROUP_STAT: ${KAFKA_GROUP_STAT:-vehicle-stat}")
|
||||
.contains("VEHICLE_STAT_ENABLED: ${VEHICLE_STAT_ENABLED:-true}")
|
||||
.contains("VEHICLE_STAT_JT808_MILEAGE_ENABLED: ${VEHICLE_STAT_JT808_MILEAGE_ENABLED:-true}")
|
||||
.doesNotContain("KAFKA_GROUP_STATE")
|
||||
.doesNotContain("VEHICLE_STATE_ENABLED");
|
||||
}
|
||||
|
||||
private static void assertServiceMemoryLimit(String compose,
|
||||
String serviceName,
|
||||
String envName,
|
||||
@@ -58,6 +71,29 @@ class PortainerComposeResourceLimitsTest {
|
||||
.contains(" mem_limit: ${" + envName + ":-" + defaultLimit + "}");
|
||||
}
|
||||
|
||||
private static String serviceBlock(String compose, String serviceName) {
|
||||
String marker = "\n " + serviceName + ":\n";
|
||||
int start = compose.indexOf(marker);
|
||||
if (start < 0) {
|
||||
throw new IllegalArgumentException("service not found: " + serviceName);
|
||||
}
|
||||
for (int cursor = start + marker.length(); cursor < compose.length(); ) {
|
||||
int nextLine = compose.indexOf('\n', cursor);
|
||||
if (nextLine < 0) {
|
||||
return compose.substring(start);
|
||||
}
|
||||
int lineStart = nextLine + 1;
|
||||
if (lineStart + 2 < compose.length()
|
||||
&& compose.charAt(lineStart) == ' '
|
||||
&& compose.charAt(lineStart + 1) == ' '
|
||||
&& compose.charAt(lineStart + 2) != ' ') {
|
||||
return compose.substring(start, nextLine);
|
||||
}
|
||||
cursor = lineStart;
|
||||
}
|
||||
return compose.substring(start);
|
||||
}
|
||||
|
||||
private static Path repositoryRoot() {
|
||||
Path current = Path.of(System.getProperty("user.dir")).toAbsolutePath();
|
||||
while (current != null) {
|
||||
|
||||
Reference in New Issue
Block a user