diff --git a/deploy/portainer/docker-compose.yml b/deploy/portainer/docker-compose.yml index c677a74e..3d49cf10 100644 --- a/deploy/portainer/docker-compose.yml +++ b/deploy/portainer/docker-compose.yml @@ -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} diff --git a/modules/apps/vehicle-analytics-app/pom.xml b/modules/apps/vehicle-analytics-app/pom.xml index 4f6e9f71..98de9d4a 100644 --- a/modules/apps/vehicle-analytics-app/pom.xml +++ b/modules/apps/vehicle-analytics-app/pom.xml @@ -10,7 +10,7 @@ vehicle-analytics-app vehicle-analytics-app - Vehicle state, daily statistics, alarms, and analytics runtime. + Vehicle daily statistics and analytics runtime. @@ -25,10 +25,6 @@ com.lingniu.ingest sink-mq - - com.lingniu.ingest - vehicle-state-service - com.lingniu.ingest vehicle-stat-service diff --git a/modules/apps/vehicle-analytics-app/src/main/resources/application.yml b/modules/apps/vehicle-analytics-app/src/main/resources/application.yml index 6a752dcc..0146c252 100644 --- a/modules/apps/vehicle-analytics-app/src/main/resources/application.yml +++ b/modules/apps/vehicle-analytics-app/src/main/resources/application.yml @@ -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 diff --git a/modules/apps/vehicle-analytics-app/src/test/java/com/lingniu/ingest/analyticsapp/VehicleAnalyticsAppCompositionTest.java b/modules/apps/vehicle-analytics-app/src/test/java/com/lingniu/ingest/analyticsapp/VehicleAnalyticsAppCompositionTest.java index 83be9f7b..ad6425a1 100644 --- a/modules/apps/vehicle-analytics-app/src/test/java/com/lingniu/ingest/analyticsapp/VehicleAnalyticsAppCompositionTest.java +++ b/modules/apps/vehicle-analytics-app/src/test/java/com/lingniu/ingest/analyticsapp/VehicleAnalyticsAppCompositionTest.java @@ -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"); }); diff --git a/modules/apps/vehicle-analytics-app/src/test/java/com/lingniu/ingest/analyticsapp/VehicleAnalyticsAppDefaultsTest.java b/modules/apps/vehicle-analytics-app/src/test/java/com/lingniu/ingest/analyticsapp/VehicleAnalyticsAppDefaultsTest.java index a3083e9f..8aec22d8 100644 --- a/modules/apps/vehicle-analytics-app/src/test/java/com/lingniu/ingest/analyticsapp/VehicleAnalyticsAppDefaultsTest.java +++ b/modules/apps/vehicle-analytics-app/src/test/java/com/lingniu/ingest/analyticsapp/VehicleAnalyticsAppDefaultsTest.java @@ -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() { diff --git a/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/PortainerComposeResourceLimitsTest.java b/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/PortainerComposeResourceLimitsTest.java index a0e4388a..2d2ebe2e 100644 --- a/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/PortainerComposeResourceLimitsTest.java +++ b/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/PortainerComposeResourceLimitsTest.java @@ -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) {