From 40780f968fda688e9b914dc38c49d759fda79671 Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 6 Jun 2023 16:12:17 +0800 Subject: [PATCH] Deployment on VPS (#17) Updated config files Extended github actions file with extra jobs --- .github/workflows/main.yml | 16 ++++- .gitignore | 7 +- src/frontend/.env.production | 2 +- src/frontend/vue.config.js | 5 +- .../pocketstats/config/AppConfig.java | 14 ++++ .../pocket/api/PocketItemStatsService.java | 15 ++-- src/main/raporting/raporting/raporting.iml | 7 ++ src/main/resources/application-prod.yaml | 2 +- src/main/resources/application.yaml | 2 +- .../PocketItemStatsServiceIntTest.groovy | 68 ++++++++++--------- 10 files changed, 92 insertions(+), 46 deletions(-) create mode 100644 src/main/java/eu/cybershu/pocketstats/config/AppConfig.java create mode 100644 src/main/raporting/raporting/raporting.iml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b070562..415115e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,6 +2,10 @@ name: PocketStats CI on: [push, pull_request] +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: tests: runs-on: ubuntu-latest @@ -26,8 +30,8 @@ jobs: env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} build: - # needs: - # - tests + needs: + - tests runs-on: ubuntu-latest environment: master steps: @@ -60,7 +64,6 @@ jobs: ssh-keyscan 38.242.142.123 >> ~/.ssh/known_hosts env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} - - name: Deploy app.jar to server run: | scp ./build/libs/app.jar pocketstats@38.242.142.123:/usr/lib/pocketstats/app.jar @@ -74,3 +77,10 @@ jobs: ssh pocketstats@38.242.142.123 'systemctl status pocketstats.service' env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + - name: Health check + run: | + echo "Waiting for 30 seconds before healthcheck" + sleep 30 + echo "Performing healthcheck" + wget --retry-connrefused --waitretry=5 --read-timeout=20 --timeout=15 -t 10 http://38.242.142.123:8080/pocketstats/actuator/health -O /dev/null + shell: bash diff --git a/.gitignore b/.gitignore index 2d949f0..8c1d49c 100644 --- a/.gitignore +++ b/.gitignore @@ -165,4 +165,9 @@ venv ./src/frontend/node_modules # Logs -loga \ No newline at end of file +loga +src/main/java/eu/cybershu/pocketstats/pocket/api/.DS_Store +.DS_Store +src/.DS_Store +src/main/.DS_Store +src/main/raporting/.DS_Store diff --git a/src/frontend/.env.production b/src/frontend/.env.production index eaa1c4e..de5e24d 100644 --- a/src/frontend/.env.production +++ b/src/frontend/.env.production @@ -1 +1 @@ -VUE_APP_BACKEND_URL=http://38.242.142.123:8082 \ No newline at end of file +VUE_APP_BACKEND_URL=https://pocketstats.cybershu.eu \ No newline at end of file diff --git a/src/frontend/vue.config.js b/src/frontend/vue.config.js index 51301e0..ef6073c 100644 --- a/src/frontend/vue.config.js +++ b/src/frontend/vue.config.js @@ -7,5 +7,8 @@ module.exports = defineConfig({ module.exports = { devServer: { port: 8080 - } + }, + publicPath: process.env.NODE_ENV === 'production' + ? '/' + : '/' }; \ No newline at end of file diff --git a/src/main/java/eu/cybershu/pocketstats/config/AppConfig.java b/src/main/java/eu/cybershu/pocketstats/config/AppConfig.java new file mode 100644 index 0000000..16d0285 --- /dev/null +++ b/src/main/java/eu/cybershu/pocketstats/config/AppConfig.java @@ -0,0 +1,14 @@ +package eu.cybershu.pocketstats.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.time.Clock; + +@Configuration +public class AppConfig { + @Bean + Clock clock() { + return Clock.systemUTC(); + } +} diff --git a/src/main/java/eu/cybershu/pocketstats/pocket/api/PocketItemStatsService.java b/src/main/java/eu/cybershu/pocketstats/pocket/api/PocketItemStatsService.java index 24b0931..5f4b1c7 100644 --- a/src/main/java/eu/cybershu/pocketstats/pocket/api/PocketItemStatsService.java +++ b/src/main/java/eu/cybershu/pocketstats/pocket/api/PocketItemStatsService.java @@ -32,12 +32,14 @@ @Service public class PocketItemStatsService { private final MongoTemplate mongoTemplate; + private final Clock clock; public PocketItemStatsService( + Clock clock, MongoTemplate mongoTemplate ) { - this.clock = Clock.systemUTC(); + this.clock = clock; this.mongoTemplate = mongoTemplate; } @@ -223,11 +225,14 @@ public PeriodItemsStats itemsStatsPeriod(TimePeriod timePeriod) { .append("archived", 1L)))); Document docs = result.first(); - Objects.requireNonNull(docs); - return new PeriodItemsStats( - docs.getLong("added"), docs.getLong("archived") - ); + if (docs == null) { + return new PeriodItemsStats(0L, 0L); + } else { + return new PeriodItemsStats( + docs.getLong("added"), docs.getLong("archived") + ); + } } public PeriodItemsStats itemsStatsTotal() { diff --git a/src/main/raporting/raporting/raporting.iml b/src/main/raporting/raporting/raporting.iml new file mode 100644 index 0000000..f4cd67e --- /dev/null +++ b/src/main/raporting/raporting/raporting.iml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/main/resources/application-prod.yaml b/src/main/resources/application-prod.yaml index 695b682..cf28d4c 100644 --- a/src/main/resources/application-prod.yaml +++ b/src/main/resources/application-prod.yaml @@ -6,4 +6,4 @@ spring: server: port: ${PORT:8081} servlet: - context-path: /pocketstats \ No newline at end of file + context-path: / \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index a0b9a55..57c4554 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -12,7 +12,7 @@ auth: access_token: https://getpocket.com/v3/oauth/authorize get: https://getpocket.com/v3/get consumer-key: ${POCKET_CONSUMER_KEY} - redirect_uri: ${BACKEND_URL:http://localhost:8081}/pocket/auth/token + redirect_uri: ${VUE_APP_BACKEND_URL:http://localhost:8081}/pocket/auth/token management: endpoints: diff --git a/src/test/groovy/eu/cybershu/pocketstats/pocket/stats/PocketItemStatsServiceIntTest.groovy b/src/test/groovy/eu/cybershu/pocketstats/pocket/stats/PocketItemStatsServiceIntTest.groovy index 46d7435..429d015 100644 --- a/src/test/groovy/eu/cybershu/pocketstats/pocket/stats/PocketItemStatsServiceIntTest.groovy +++ b/src/test/groovy/eu/cybershu/pocketstats/pocket/stats/PocketItemStatsServiceIntTest.groovy @@ -12,6 +12,9 @@ import eu.cybershu.pocketstats.utils.TimeUtils import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.context.TestConfiguration +import org.springframework.context.annotation.Bean +import org.springframework.test.context.ContextConfiguration import spock.lang.Shared import java.time.* @@ -20,7 +23,16 @@ import java.time.temporal.ChronoUnit import static eu.cybershu.pocketstats.PocketItemBuilder.* import static org.assertj.core.api.Assertions.assertThat +@TestConfiguration +class TestConfig { + @Bean + Clock clock() { + return Clock.fixed(Instant.parse("2023-04-26T10:00:00Z"), ZoneId.of("UTC")) + } +} + @SpringBootTest +@ContextConfiguration(classes = TestConfig.class) @AutoConfigureDataMongo class PocketItemStatsServiceIntTest extends BaseTest { @Autowired @@ -80,8 +92,8 @@ class PocketItemStatsServiceIntTest extends BaseTest { assert repository.saveAll(items).size() == items.size() - def start = LocalDate.now().minusDays(7) - def end = LocalDate.now() + def start = LocalDate.now(clock).minusDays(7) + def end = LocalDate.now(clock) when: def result = statsService.getDayStatsRecords( start, end, DayStatsType.ARCHIVED @@ -92,15 +104,16 @@ class PocketItemStatsServiceIntTest extends BaseTest { assertNumberInDay(result, start, 3) assertNumberInDay(result, end.minusDays(5), 2) assertNumberInDay(result, end.minusDays(2), 1) - assertNumberInDay(result, end, 1) } def "given items in time period expect valid number of valid TODO items"() { given: - def items = [] + def start = LocalDate.now(clock).minusDays(7) + def end = LocalDate.now(clock) + def items = [] //-7 days: 3 added - Instant minus7days = now.minus(7, ChronoUnit.DAYS) + Instant minus7days = TimeUtils.toStartDayInstant(start) items.addAll([ todo(minus7days), todo(minus7days), @@ -129,17 +142,16 @@ class PocketItemStatsServiceIntTest extends BaseTest { ]) //today: 3 added + Instant endInstant = TimeUtils.toStartDayInstant(end) + Instant endMightnightInstant = TimeUtils.toEndOfDay(endInstant) items.addAll([ - todo(TimeUtils.instantTodayEnd()), - todo(now), - todo(TimeUtils.instantTodayEnd()), - archived(now, now), + todo(endMightnightInstant), + todo(endInstant), + todo(endMightnightInstant), + archived(endInstant, now), ]) assert repository.saveAll(items).size() == items.size() - - def start = LocalDate.now().minusDays(7) - def end = LocalDate.now() when: def result = statsService.getDayStatsRecords( start, end, DayStatsType.TODO @@ -250,24 +262,18 @@ class PocketItemStatsServiceIntTest extends BaseTest { assert repository.saveAll(doneItems).size() == doneItems.size() assert repository.saveAll(todoItems).size() == todoItems.size() - when: def result = statsService.itemsStatsAggregated() - then: "last year" - assetPeriodStats(result, "last-year", 1, 2) - and: "last month" - assetPeriodStats(result, "last-month", 1, 2) - and: "last week" - assetPeriodStats(result, "last-week", 1, 2) - - then: "current year" - assetPeriodStats(result, "current-year", 5, 5 + 5) - and: "current month" - assetPeriodStats(result, "current-month", 3, 3 + 3) - and: "current week" - assetPeriodStats(result, "current-week", 2, 2 + 2) - and: "total" - assetPeriodStats(result, "total", 8, 7 + 8) + then: + verifyAll { + assetPeriodStats(result, "last-year", 1, 2) + assetPeriodStats(result, "last-month", 1, 2) //3,6 + assetPeriodStats(result, "last-week", 1, 2) + assetPeriodStats(result, "current-year", 5, 5 + 5) + assetPeriodStats(result, "current-month", 3, 3 + 3) + assetPeriodStats(result, "current-week", 2, 2 + 2) + assetPeriodStats(result, "total", 8, 7 + 8) + } } private assetPeriodStats(ItemsStatsAggregated resul, String name, int expectedRead, int expectedAdded) { @@ -286,10 +292,6 @@ class PocketItemStatsServiceIntTest extends BaseTest { todo(timeAdded, title, url) } - private PocketItem daysDiffArchived(int days) { - daysDiffArchived(days, instantDaysDiffers(-30)) - } - private PocketItem daysDiffArchived(int days, Instant dayAdded) { def timeAdded = instantDaysDiffers(days) String title = "read " + timeAdded @@ -320,7 +322,7 @@ class PocketItemStatsServiceIntTest extends BaseTest { private void assertNumberInDay(DayStatsRecords dayStatsRecords, LocalDate date, Integer expected) { def found = dayStatsRecords.stats().findAll { it -> it.day() == date } - assert found.size() == 1, "Found more than 1 record for day ${date}. It can be only one!" + assert found.size() == 1, "Not found record for day ${date}. Expected one!" assert found.get(0).number() == expected, "Expected ${expected} got ${found.size()} items for day ${date}" } }