Skip to content

Commit

Permalink
parking-forecast: switch to spring boot and upgrade to java 17
Browse files Browse the repository at this point in the history
  • Loading branch information
dulvui committed Nov 20, 2023
1 parent ad93ccf commit ec2ae59
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 106 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci-parking-forecast.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ env:
PROJECT_NAME: odh-mobility-dc-parking-forecast
DOCKER_IMAGE: ghcr.io/${{ github.repository }}/odh-mobility-dc-parking-forecast
DOCKER_TAG: ${{ github.sha }}
JAVA_VERSION: '8'
JAVA_VERSION: '17'

jobs:
test:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Checkout source code
uses: noi-techpark/github-actions/checkout@v2
Expand All @@ -30,7 +30,7 @@ jobs:

# Deploy Test
deploy-test-parking-forecast:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
if: github.ref == 'refs/heads/main'
needs: test
concurrency: deploy-test-parking-forecast
Expand Down Expand Up @@ -98,7 +98,7 @@ jobs:

# Deploy Production
deploy-prod-parking-forecast:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
if: github.ref == 'refs/heads/prod'
needs: test
concurrency: deploy-prod-parking-forecast
Expand Down
27 changes: 27 additions & 0 deletions data-collectors/parking-forecast/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# SPDX-FileCopyrightText: NOI Techpark <digital@noi.bz.it>
#
# SPDX-License-Identifier: CC0-1.0

version: "3.4"

services:
app:
image: maven:3-openjdk-17-slim
environment:
MAVEN_CONFIG: /var/maven/.m2
MAVEN_OPTS: -Dspring-boot.run.jvmArguments="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:9000"
command: >
mvn
-Duser.home=/var/maven
clean
compile
spring-boot:run
ports:
- 9000:9000
- 9001:9001
volumes:
- ~/.m2/:/var/maven/.m2
- ./:/code
working_dir: /code
tty: true
network_mode: host
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
FROM tomcat:8.5-jdk8-openjdk-slim-buster
COPY target/ROOT.war /usr/local/tomcat/webapps/ROOT.war
FROM maven:3-openjdk-17-slim as base
COPY target/ROOT.jar app.jar
CMD [ "java", "-jar", "app.jar" ]
65 changes: 31 additions & 34 deletions data-collectors/parking-forecast/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,74 +10,71 @@ SPDX-License-Identifier: CC0-1.0
<modelVersion>4.0.0</modelVersion>
<groupId>it.bz.noi.sta.parkingforecast</groupId>
<artifactId>dc-parking-forecast</artifactId>
<packaging>war</packaging>
<version>1.0.0</version>
<name>parking-forecast</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<finalName>ROOT</finalName>
<spring.version>5.2.12.RELEASE</spring.version>
<gson-version>2.8.9</gson-version>
</properties>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.8</version>
<relativePath />
<!-- lookup parent from repository -->
</parent>

<repositories>
<repository>
<id>maven-repo.opendatahub.com</id>
<url>https://maven-repo.opendatahub.com/release</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>it.bz.idm.bdp</groupId>
<artifactId>dc-interface</artifactId>
<version>7.4.0</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- embedded tomcat for development, provided: not included in the final
jar/war -->
<dependency>
<groupId>com.github.jsimone</groupId>
<artifactId>webapp-runner-main</artifactId>
<version>8.5.11.3</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.9.0</version>
</dependency>

<!-- This is to fix a "Cannot be cast to javax.servlet.Filter" severe error -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson-version}</version>
</dependency>
</dependencies>
<build>
<finalName>${finalName}</finalName>
</build>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<finalName>${finalName}</finalName>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.ZonedDateTime;
import java.util.*;

@Component
public class MainParkingForecast {
public class JobScheduler {

@Autowired
private ParkingSensorJSONPusher parkingSensorJSONPusher;
Expand All @@ -42,18 +43,20 @@ public class MainParkingForecast {
@Autowired
private ParkingForecastConnector staParkingForecastConnector;

private static Logger LOG = LoggerFactory.getLogger(MainParkingForecast.class);
private static Logger LOG = LoggerFactory.getLogger(JobScheduler.class);

@Scheduled(cron = "${scheduler.job}")
public void execute() {
LOG.info("MainParkingForecast execute");
try {
ParkingForecastResult parkingForecastResult = staParkingForecastConnector.getParkingForecastResult();
LOG.debug("got timeseries about {} stations with publish_timestamp {}, forecast_start_timestamp {}, forecast_period_seconds {}, forecast_duration_hours {}",
parkingForecastResult.getStationTimeseriesMap().size(),
parkingForecastResult.getPublishTimestamp(),
parkingForecastResult.getForecastStartTimestamp(),
parkingForecastResult.getForecastPeriodSeconds(),
parkingForecastResult.getForecastDurationHours());
LOG.debug(
"got timeseries about {} stations with publish_timestamp {}, forecast_start_timestamp {}, forecast_period_seconds {}, forecast_duration_hours {}",
parkingForecastResult.getStationTimeseriesMap().size(),
parkingForecastResult.getPublishTimestamp(),
parkingForecastResult.getForecastStartTimestamp(),
parkingForecastResult.getForecastPeriodSeconds(),
parkingForecastResult.getForecastDurationHours());

for (AbstractParkingForecastJSONPusher jsonPusher : getAllJsonPusher()) {
setupDataType(jsonPusher);
Expand All @@ -77,20 +80,28 @@ private void exportData(AbstractParkingForecastJSONPusher jsonPusher, ParkingFor

for (StationDto stationDto : stationList) {
String stationCode = stationDto.getId();
List<ParkingForecastDataPoint> forecastTimeseries = parkingForecastResult.getStationTimeseriesMap().get(stationCode);
List<ParkingForecastDataPoint> forecastTimeseries = parkingForecastResult.getStationTimeseriesMap()
.get(stationCode);
if (forecastTimeseries != null) {
long timestampMillis = parkingForecastResult.getPublishTimestamp().toEpochSecond() * 1000;
Date dateOfLastRecord = getDateOfLastRecord(jsonPusher,
stationCode,
datatypesConfiguration.getAllDataTypes().stream().filter(datatypeConfiguration -> datatypeConfiguration.getProperty().equals("mean")).sorted((o1, o2) -> o1.getPeriod().compareTo(o2.getPeriod())).findFirst().get());
stationCode,
datatypesConfiguration.getAllDataTypes().stream()
.filter(datatypeConfiguration -> datatypeConfiguration.getProperty().equals("mean"))
.sorted((o1, o2) -> o1.getPeriod().compareTo(o2.getPeriod())).findFirst().get());
if (dateOfLastRecord == null || timestampMillis != dateOfLastRecord.getTime()) {
for (DatatypeConfiguration datatypeConfiguration : datatypesConfiguration.getAllDataTypes()) {
ZonedDateTime forecastDatatypeTimestamp = parkingForecastResult.getForecastStartTimestamp().plusSeconds(datatypeConfiguration.getPeriod());
Optional<ParkingForecastDataPoint> forecastDataPoint = forecastTimeseries.stream().filter(f -> f.getTs().equals(forecastDatatypeTimestamp)).findFirst();
Object propertyValue = forecastDataPoint.isPresent()? forecastDataPoint.get().getProperty(datatypeConfiguration.getProperty()): null;
ZonedDateTime forecastDatatypeTimestamp = parkingForecastResult.getForecastStartTimestamp()
.plusSeconds(datatypeConfiguration.getPeriod());
Optional<ParkingForecastDataPoint> forecastDataPoint = forecastTimeseries.stream()
.filter(f -> f.getTs().equals(forecastDatatypeTimestamp)).findFirst();
Object propertyValue = forecastDataPoint.isPresent()
? forecastDataPoint.get().getProperty(datatypeConfiguration.getProperty())
: null;
if (propertyValue != null) {
dataMap.addRecord(stationCode, datatypeConfiguration.getKey(),
new SimpleRecordDto(forecastDatatypeTimestamp.toEpochSecond() * 1000, propertyValue, datatypeConfiguration.getPeriod()));
new SimpleRecordDto(forecastDatatypeTimestamp.toEpochSecond() * 1000, propertyValue,
datatypeConfiguration.getPeriod()));
pushDataCount++;
} else
skipDataCount++;
Expand All @@ -104,18 +115,19 @@ private void exportData(AbstractParkingForecastJSONPusher jsonPusher, ParkingFor
if (pushDataCount > 0)
jsonPusher.pushData(dataMap);

LOG.debug("{} forecast records pushed, {} records skipped, {} stations with no update, {} stations with no forecast data", pushDataCount, skipDataCount, stationNoUpdateCount, stationNoDataCount);
LOG.debug(
"{} forecast records pushed, {} records skipped, {} stations with no update, {} stations with no forecast data",
pushDataCount, skipDataCount, stationNoUpdateCount, stationNoDataCount);
}

private void setupDataType(AbstractParkingForecastJSONPusher jsonPusher) {
List<DataTypeDto> dataTypeDtoList = new ArrayList<>();
for (DatatypeConfiguration datatypeConfiguration : datatypesConfiguration.getAllDataTypes()) {
dataTypeDtoList.add(
new DataTypeDto(datatypeConfiguration.getKey(),
datatypeConfiguration.getUnit(),
datatypeConfiguration.getDescription(),
datatypeConfiguration.getRtype())
);
new DataTypeDto(datatypeConfiguration.getKey(),
datatypeConfiguration.getUnit(),
datatypeConfiguration.getDescription(),
datatypeConfiguration.getRtype()));
}
jsonPusher.syncDataTypes(dataTypeDtoList);
}
Expand All @@ -124,8 +136,10 @@ private List<AbstractParkingForecastJSONPusher> getAllJsonPusher() {
return Arrays.asList(parkingSensorJSONPusher, parkingStationJSONPusher);
}

private Date getDateOfLastRecord(AbstractParkingForecastJSONPusher jsonPusher, String stationCode, DatatypeConfiguration datatypeConfiguration) {
Object dateOfLastRecord = jsonPusher.getDateOfLastRecord(stationCode, datatypeConfiguration.getKey(), datatypeConfiguration.getPeriod());
private Date getDateOfLastRecord(AbstractParkingForecastJSONPusher jsonPusher, String stationCode,
DatatypeConfiguration datatypeConfiguration) {
Object dateOfLastRecord = jsonPusher.getDateOfLastRecord(stationCode, datatypeConfiguration.getKey(),
datatypeConfiguration.getPeriod());
if (dateOfLastRecord == null)
return null;
return (Date) dateOfLastRecord;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: NOI Techpark <digital@noi.bz.it>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

package it.bz.noi.sta.parkingforecast;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;

@ComponentScan({ "it.bz.noi.sta.parkingforecast", "it.bz.idm.bdp" })
@EnableScheduling
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource("classpath:parkingforecast.properties")
public class ParkingForecstConfiguration {

@Value( "${connector.endpoint}" )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,26 @@
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.PropertySource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;

import javax.annotation.PostConstruct;

@PropertySource("classpath:odh-writer.properties")
public abstract class AbstractParkingForecastJSONPusher extends NonBlockingJSONPusher {

private static final Logger LOG = LoggerFactory.getLogger(AbstractParkingForecastJSONPusher.class);

protected String origin;

@Autowired
protected Environment env;
@Autowired
protected ParkingForecstConfiguration connectorConfiguration;

@Value("${provenance.name}")
private String provenanceName;

@Value("${provenance.version}")
private String provenanceVersion;

public <T> DataMapDto<RecordDtoImpl> mapData(T arg0) {
throw new IllegalStateException("it is used by who?");
}
Expand All @@ -52,6 +55,6 @@ public void init() {

@Override
public ProvenanceDto defineProvenance() {
return new ProvenanceDto(null, env.getProperty("provenance_name"), env.getProperty("provenance_version"), origin);
return new ProvenanceDto(null, provenanceName, provenanceVersion, origin);
}
}

This file was deleted.

Loading

0 comments on commit ec2ae59

Please sign in to comment.