├── version.txt
├── database.env.example
├── src
├── main
│ ├── resources
│ │ ├── db
│ │ │ └── migration
│ │ │ │ ├── V1_3_0__add_domain_headers_column.sql
│ │ │ │ ├── V1_2_0__add_domain_endpoint_column.sql
│ │ │ │ ├── V1_3_1__add_domain_timeout_column.sql
│ │ │ │ ├── V1_3_2__update_new_fields_to_defaults.sql
│ │ │ │ ├── V1_5_0__spring_batch_5_migration.sql
│ │ │ │ ├── V1_4_0__add_server_tables.sql
│ │ │ │ ├── V1_1_0__init_spring_batch.sql
│ │ │ │ └── V1_0_0__init_schema.sql
│ │ ├── banner.txt
│ │ ├── application.yaml
│ │ └── META-INF
│ │ │ └── additional-spring-configuration-metadata.json
│ └── java
│ │ └── com
│ │ └── bompotis
│ │ └── netcheck
│ │ ├── api
│ │ ├── model
│ │ │ ├── PatchOperation.java
│ │ │ ├── ServerMetricModel.java
│ │ │ ├── RegisterServerRequest.java
│ │ │ ├── ServerMetricRequest.java
│ │ │ ├── assembler
│ │ │ │ ├── PaginatedRepresentationModelAssemblerSupport.java
│ │ │ │ ├── ServerDefinitionAssembler.java
│ │ │ │ ├── CertificateModelAssembler.java
│ │ │ │ ├── ServerUpdateDtoAssembler.java
│ │ │ │ ├── DomainUpdateDtoAssembler.java
│ │ │ │ ├── AbstractUpdateDtoAssembler.java
│ │ │ │ ├── MetricModelAssembler.java
│ │ │ │ ├── StateModelAssembler.java
│ │ │ │ └── HttpCheckModelAssembler.java
│ │ │ ├── DomainRequest.java
│ │ │ ├── DomainCheckModel.java
│ │ │ ├── ServerModel.java
│ │ │ ├── ServerDefinitionModel.java
│ │ │ ├── CertificateModel.java
│ │ │ ├── DomainResponse.java
│ │ │ ├── MetricModel.java
│ │ │ ├── StateModel.java
│ │ │ └── HttpCheckModel.java
│ │ ├── exception
│ │ │ ├── InvalidAuthHeaders.java
│ │ │ ├── UnauthorizedStatusException.java
│ │ │ ├── EntityNotFoundException.java
│ │ │ └── ControllerAdvisor.java
│ │ ├── security
│ │ │ └── WebSecurityConfig.java
│ │ └── controller
│ │ │ ├── StreamController.java
│ │ │ ├── AbstractStreamController.java
│ │ │ └── NotificationTestController.java
│ │ ├── scheduler
│ │ └── batch
│ │ │ ├── notification
│ │ │ ├── client
│ │ │ │ ├── MessagePriority.java
│ │ │ │ ├── PushoverRestClient.java
│ │ │ │ └── PushoverMessage.java
│ │ │ ├── NotificationService.java
│ │ │ ├── EventDto.java
│ │ │ ├── NotificationEventDto.java
│ │ │ ├── ServerMetricEventDto.java
│ │ │ ├── NotificationEventService.java
│ │ │ ├── CheckEventDto.java
│ │ │ ├── config
│ │ │ │ ├── WebhookConfig.java
│ │ │ │ └── PushoverConfig.java
│ │ │ ├── PushoverService.java
│ │ │ └── WebhookService.java
│ │ │ ├── JobCompletionNotificationListener.java
│ │ │ ├── processor
│ │ │ ├── DomainMetricProcessor.java
│ │ │ └── DomainCheckProcessor.java
│ │ │ ├── writer
│ │ │ ├── CheckEventItemWriter.java
│ │ │ ├── DomainMetricListWriter.java
│ │ │ └── NotificationItemWriter.java
│ │ │ └── reader
│ │ │ └── OldDomainCheckItemReader.java
│ │ ├── service
│ │ ├── dto
│ │ │ ├── DtoBuilder.java
│ │ │ ├── PatchDtoBuilder.java
│ │ │ ├── Operation.java
│ │ │ ├── PaginatedDto.java
│ │ │ ├── AbstractPaginatedDto.java
│ │ │ ├── DomainUpdateDto.java
│ │ │ ├── ServerUpdateDto.java
│ │ │ ├── DomainCheckConfigDto.java
│ │ │ ├── HttpsCheckDto.java
│ │ │ ├── RequestOptionsDto.java
│ │ │ ├── DomainCheckDto.java
│ │ │ ├── ServerDto.java
│ │ │ ├── DomainsOptionsDto.java
│ │ │ ├── MetricDto.java
│ │ │ └── ServerDefinitionDto.java
│ │ └── AbstractService.java
│ │ ├── data
│ │ ├── entity
│ │ │ ├── EntityBuilder.java
│ │ │ ├── OperationUpdater.java
│ │ │ ├── AbstractTimestampable.java
│ │ │ ├── AbstractTimestampablePersistable.java
│ │ │ └── ServerMetricEntity.java
│ │ └── repository
│ │ │ ├── ServerMetricRepository.java
│ │ │ ├── ServerMetricDefinitionRepository.java
│ │ │ ├── DomainRepository.java
│ │ │ ├── ServerRepository.java
│ │ │ └── DomainMetricRepository.java
│ │ └── NetcheckApplication.java
└── test
│ ├── resources
│ └── application.yaml
│ └── java
│ └── com
│ └── bompotis
│ └── netcheck
│ └── NetcheckApplicationStartupTests.java
├── .env.example
├── test-depedancies.docker-compose.yml
├── .gitignore
├── Dockerfile
├── amd64.openj9.Dockerfile
├── docker-compose.dockerhub.yml
├── docker-compose.yml
├── .github
└── dependabot.yml
└── traefik.docker-compose.yml
/version.txt:
--------------------------------------------------------------------------------
1 | 0.11.4
--------------------------------------------------------------------------------
/database.env.example:
--------------------------------------------------------------------------------
1 | POSTGRES_USER=netcheck
2 | POSTGRES_PASSWORD=netcheck
3 | POSTGRES_DB=netcheck
--------------------------------------------------------------------------------
/src/main/resources/db/migration/V1_3_0__add_domain_headers_column.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE public."domain" ADD COLUMN headers jsonb;
--------------------------------------------------------------------------------
/src/main/resources/db/migration/V1_2_0__add_domain_endpoint_column.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE public."domain" ADD COLUMN endpoint VARCHAR;
--------------------------------------------------------------------------------
/src/main/resources/db/migration/V1_3_1__add_domain_timeout_column.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE public."domain" ADD COLUMN timeout_ms int4;
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | POSTGRES_HOST=db
2 | POSTGRES_PORT=5432
3 | SETTINGS_NOTIFICATIONS_PUSHOVER_ENABLED=false
4 | SETTINGS_NOTIFICATIONS_PUSHOVER_APITOKEN=
5 | SETTINGS_NOTIFICATIONS_PUSHOVER_USERIDTOKEN=
--------------------------------------------------------------------------------
/src/main/resources/db/migration/V1_3_2__update_new_fields_to_defaults.sql:
--------------------------------------------------------------------------------
1 | UPDATE public."domain" SET endpoint='' WHERE endpoint IS NULL;
2 | UPDATE public."domain" SET timeout_ms=30000 WHERE timeout_ms IS NULL;
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/PatchOperation.java:
--------------------------------------------------------------------------------
1 | package com.bompotis.netcheck.api.model;
2 |
3 | /**
4 | * Created by Kyriakos Bompotis on 2/9/20.
5 | */
6 | public record PatchOperation(String op, String field, String value, String path) {
7 | }
8 |
--------------------------------------------------------------------------------
/test-depedancies.docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.6'
2 |
3 | services:
4 | test-db:
5 | image: postgres
6 | environment:
7 | POSTGRES_USER: postgresql
8 | POSTGRES_PASSWORD: letmein
9 | POSTGRES_DB: test_db
10 | volumes:
11 | - db-test-data:/var/lib/postgresql/data
12 | ports:
13 | - "5432:5432"
14 |
15 | volumes:
16 | db-test-data:
17 | driver: local
--------------------------------------------------------------------------------
/src/main/resources/banner.txt:
--------------------------------------------------------------------------------
1 | _____ __ _____ _______________ ______
2 | ___ | / /_____ __ /___ ____/___ /_ _____ __________ /__
3 | __ |/ / _ _ \_ __/_ / __ __ \_ _ \_ ___/__ //_/
4 | _ /| / / __// /_ / /___ _ / / // __// /__ _ ,<
5 | /_/ |_/ \___/ \__/ \____/ /_/ /_/ \___/ \___/ /_/|_|
6 | Application Version: ${application.version}
7 | Spring Boot Version: ${spring-boot.version}
--------------------------------------------------------------------------------
/src/test/resources/application.yaml:
--------------------------------------------------------------------------------
1 | spring:
2 | datasource:
3 | url: jdbc:postgresql://${postgres.host:localhost}:${postgres.port:5432}/${postgres.db:test_db}
4 | username: ${postgres.user:postgresql}
5 | password: ${postgres.password:letmein}
6 | batch:
7 | jdbc:
8 | initialize-schema: always
9 | job:
10 | enabled: false
11 | jpa:
12 | hibernate:
13 | ddl-auto: create-drop
14 | settings:
15 | cors:
16 | origin: "*"
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | database.env
3 | .env
4 | target/
5 | !.mvn/wrapper/maven-wrapper.jar
6 | !**/src/main/**
7 | !**/src/test/**
8 |
9 | ### STS ###
10 | .apt_generated
11 | .classpath
12 | .factorypath
13 | .project
14 | .settings
15 | .springBeans
16 | .sts4-cache
17 |
18 | ### IntelliJ IDEA ###
19 | .idea
20 | *.iws
21 | *.iml
22 | *.ipr
23 |
24 | ### NetBeans ###
25 | /nbproject/private/
26 | /nbbuild/
27 | /dist/
28 | /nbdist/
29 | /.nb-gradle/
30 | build/
31 |
32 | ### VS Code ###
33 | .vscode/
34 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ${ARCH}eclipse-temurin:17
2 | WORKDIR /var/app/netcheck/
3 | COPY ./target/netcheck.jar ./netcheck.jar
4 | RUN addgroup --system netcheck && adduser --no-create-home --gecos '' --ingroup netcheck --disabled-password netcheck
5 | USER netcheck
6 | VOLUME /tmp
7 | EXPOSE 8080 8081
8 | ENTRYPOINT ["java", "-Dhibernate.types.print.banner=false", "-noverify", "-jar", "/var/app/netcheck/netcheck.jar"]
9 | HEALTHCHECK --interval=60s --timeout=10s --retries=3 CMD curl -sSL "http://localhost:8080/api/v1/actuator/health" || exit 1
--------------------------------------------------------------------------------
/amd64.openj9.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ibm-semeru-runtimes:open-17-jre
2 | WORKDIR /var/app/netcheck/
3 | COPY ./target/netcheck.jar ./netcheck.jar
4 | RUN addgroup --system netcheck && adduser --no-create-home --gecos '' --ingroup netcheck --disabled-password netcheck
5 | USER netcheck
6 | VOLUME /tmp
7 | EXPOSE 8080 8081
8 | ENTRYPOINT ["java", "-Dhibernate.types.print.banner=false", "-noverify", "-jar", "/var/app/netcheck/netcheck.jar"]
9 | HEALTHCHECK --interval=60s --timeout=10s --retries=3 CMD curl -sSL "http://localhost:8080/api/v1/actuator/health" || exit 1
--------------------------------------------------------------------------------
/docker-compose.dockerhub.yml:
--------------------------------------------------------------------------------
1 | version: '3.6'
2 |
3 | services:
4 |
5 | netcheck-backend:
6 | container_name: netcheck-backend
7 | env_file:
8 | - database.env
9 | - .env
10 | depends_on:
11 | - db
12 | image: memphisx/netcheck-api:latest
13 | ports:
14 | - "8080:8080"
15 | - "8081:8081"
16 |
17 | db:
18 | image: postgres
19 | env_file:
20 | - database.env
21 | volumes:
22 | - db-data:/var/lib/postgresql/data
23 | ports:
24 | - "4000:5432"
25 |
26 | volumes:
27 | db-data:
28 | driver: local
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/notification/client/MessagePriority.java:
--------------------------------------------------------------------------------
1 | package com.bompotis.netcheck.scheduler.batch.notification.client;
2 |
3 | public enum MessagePriority {
4 | LOWEST(-2), LOW(-1), QUIET(-1), NORMAL(0), HIGH(1), EMERGENCY(2);
5 | private final int priority;
6 |
7 | MessagePriority(int priority) {
8 | this.priority = priority;
9 | }
10 |
11 | public int getPriority() {
12 | return priority;
13 | }
14 |
15 | @Override
16 | public String toString() {
17 | return String.valueOf(this.priority);
18 | }
19 | }
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.6'
2 |
3 | services:
4 |
5 | netcheck-backend:
6 | container_name: netcheck-backend
7 | env_file:
8 | - database.env
9 | - .env
10 | depends_on:
11 | - db
12 | build:
13 | context: ./
14 | dockerfile: ./amd64.openj9.Dockerfile
15 | ports:
16 | - "8080:8080"
17 | - "8081:8081"
18 |
19 | db:
20 | image: postgres
21 | env_file:
22 | - database.env
23 | volumes:
24 | - db-data:/var/lib/postgresql/data
25 | ports:
26 | - "4000:5432"
27 |
28 | volumes:
29 | db-data:
30 | driver: local
--------------------------------------------------------------------------------
/src/test/java/com/bompotis/netcheck/NetcheckApplicationStartupTests.java:
--------------------------------------------------------------------------------
1 | package com.bompotis.netcheck;
2 |
3 | import com.bompotis.netcheck.scheduler.batch.notification.config.PushoverConfig;
4 | import com.bompotis.netcheck.scheduler.batch.notification.config.WebhookConfig;
5 | import org.junit.jupiter.api.Test;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.boot.test.context.SpringBootTest;
8 |
9 | import static org.assertj.core.api.Assertions.assertThat;
10 |
11 | @SpringBootTest
12 | class NetcheckApplicationStartupTests {
13 |
14 | @Autowired
15 | private WebhookConfig webhookConfig;
16 |
17 | @Autowired
18 | private PushoverConfig pushoverConfig;
19 |
20 | @Test
21 | void contextLoads() {
22 | assertThat(webhookConfig.getEnabled()).isFalse();
23 | assertThat(pushoverConfig.getEnabled()).isFalse();
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/resources/db/migration/V1_5_0__spring_batch_5_migration.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE BATCH_STEP_EXECUTION ADD CREATE_TIME TIMESTAMP NOT NULL DEFAULT '1970-01-01 00:00:00';
2 |
3 | ALTER TABLE BATCH_STEP_EXECUTION ALTER COLUMN START_TIME DROP NOT NULL;
4 |
5 | ALTER TABLE BATCH_JOB_EXECUTION_PARAMS DROP COLUMN DATE_VAL;
6 |
7 | ALTER TABLE BATCH_JOB_EXECUTION_PARAMS DROP COLUMN LONG_VAL;
8 |
9 | ALTER TABLE BATCH_JOB_EXECUTION_PARAMS DROP COLUMN DOUBLE_VAL;
10 |
11 | ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN TYPE_CD TYPE VARCHAR(100);
12 |
13 | ALTER TABLE BATCH_JOB_EXECUTION_PARAMS RENAME TYPE_CD TO PARAMETER_TYPE;
14 |
15 | ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN KEY_NAME TYPE VARCHAR(100);
16 |
17 | ALTER TABLE BATCH_JOB_EXECUTION_PARAMS RENAME KEY_NAME TO PARAMETER_NAME;
18 |
19 | ALTER TABLE BATCH_JOB_EXECUTION_PARAMS ALTER COLUMN STRING_VAL TYPE VARCHAR(2500);
20 |
21 | ALTER TABLE BATCH_JOB_EXECUTION_PARAMS RENAME STRING_VAL TO PARAMETER_VALUE;
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: maven
4 | directory: "/"
5 | schedule:
6 | interval: daily
7 | time: "11:00"
8 | open-pull-requests-limit: 10
9 | ignore:
10 | - dependency-name: org.flywaydb:flyway-core
11 | versions:
12 | - 7.5.2
13 | - 7.5.3
14 | - 7.5.4
15 | - 7.7.0
16 | - 7.7.1
17 | - 7.7.2
18 | - 7.7.3
19 | - 7.8.0
20 | - 7.8.1
21 | - dependency-name: org.springdoc:springdoc-openapi-hateoas
22 | versions:
23 | - 1.5.3
24 | - 1.5.4
25 | - 1.5.6
26 | - 1.5.7
27 | - dependency-name: org.springdoc:springdoc-openapi-data-rest
28 | versions:
29 | - 1.5.3
30 | - 1.5.4
31 | - 1.5.6
32 | - 1.5.7
33 | - dependency-name: org.springdoc:springdoc-openapi-ui
34 | versions:
35 | - 1.5.3
36 | - 1.5.4
37 | - 1.5.6
38 | - 1.5.7
39 | - dependency-name: org.springframework.boot:spring-boot-starter-parent
40 | versions:
41 | - 2.4.4
42 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/dto/DtoBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.service.dto;
19 |
20 | /**
21 | * Created by Kyriakos Bompotis on 7/9/20.
22 | */
23 | public interface DtoBuilder {
24 | T build();
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/data/entity/EntityBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.data.entity;
19 |
20 | /**
21 | * Created by Kyriakos Bompotis on 8/9/20.
22 | */
23 | public interface EntityBuilder {
24 | T build();
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/exception/InvalidAuthHeaders.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.exception;
19 |
20 | /**
21 | * Created by Kyriakos Bompotis on 6/9/20.
22 | */
23 | public class InvalidAuthHeaders extends Exception{
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/exception/UnauthorizedStatusException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.exception;
19 |
20 | /**
21 | * Created by Kyriakos Bompotis on 6/9/20.
22 | */
23 | public class UnauthorizedStatusException extends Exception{
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/exception/EntityNotFoundException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.exception;
19 |
20 | /**
21 | * Created by Kyriakos Bompotis on 5/9/20.
22 | */
23 | public class EntityNotFoundException extends Exception {
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/dto/PatchDtoBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.service.dto;
19 |
20 | /**
21 | * Created by Kyriakos Bompotis on 7/9/20.
22 | */
23 | public interface PatchDtoBuilder extends DtoBuilder {
24 | DtoBuilder addOperation(Operation operation);
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/dto/Operation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.service.dto;
19 |
20 | /**
21 | * Created by Kyriakos Bompotis on 2/9/20.
22 | */
23 |
24 | public record Operation(String field, Action action, String value, String path) {
25 | public enum Action {
26 | REMOVE,
27 | UPDATE,
28 | ADD
29 | }
30 | }
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/notification/NotificationService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.notification;
19 |
20 | /**
21 | * Created by Kyriakos Bompotis on 1/7/20.
22 | */
23 | public interface NotificationService {
24 | boolean isEnabled();
25 | String name();
26 | void notify(NotificationDto notification);
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/notification/EventDto.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.notification;
19 |
20 | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
21 |
22 | /**
23 | * Created by Kyriakos Bompotis on 26/8/20.
24 | */
25 | public interface EventDto {
26 | SseEmitter.SseEventBuilder getEvent();
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/data/repository/ServerMetricRepository.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.data.repository;
19 |
20 | import com.bompotis.netcheck.data.entity.ServerMetricEntity;
21 | import org.springframework.data.jpa.repository.JpaRepository;
22 |
23 | /**
24 | * Server Metric specific extension of {@link org.springframework.data.jpa.repository.JpaRepository}.
25 | *
26 | * @author Kyriakos Bompotis
27 | */
28 | public interface ServerMetricRepository extends JpaRepository {
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/ServerMetricModel.java:
--------------------------------------------------------------------------------
1 | package com.bompotis.netcheck.api.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import org.springframework.hateoas.RepresentationModel;
5 | import org.springframework.hateoas.server.core.Relation;
6 |
7 | import jakarta.validation.constraints.NotNull;
8 | import java.util.Date;
9 | import java.util.Map;
10 |
11 | /**
12 | * Created by Kyriakos Bompotis on 6/9/20.
13 | */
14 | @Relation(collectionRelation = "metrics", itemRelation = "metric")
15 | public class ServerMetricModel extends RepresentationModel {
16 |
17 | private final String id;
18 |
19 | @NotNull(message = "metrics are mandatory")
20 | private final Map metrics;
21 |
22 | @NotNull(message = "collectedAt Date is mandatory")
23 | private final Date collectedAt;
24 |
25 | public ServerMetricModel(
26 | @JsonProperty("id") String id,
27 | @JsonProperty("metrics") Map metrics,
28 | @JsonProperty("collectedAt") Date collectedAt) {
29 | this.metrics = metrics;
30 | this.collectedAt = collectedAt;
31 | this.id = id;
32 | }
33 |
34 | public Map getMetrics() {
35 | return metrics;
36 | }
37 |
38 | public Date getCollectedAt() {
39 | return collectedAt;
40 | }
41 |
42 | public String getId() {
43 | return id;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/data/repository/ServerMetricDefinitionRepository.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.data.repository;
19 |
20 | import com.bompotis.netcheck.data.entity.ServerMetricDefinitionEntity;
21 | import org.springframework.data.jpa.repository.JpaRepository;
22 | import org.springframework.stereotype.Repository;
23 |
24 | /**
25 | * Server Metric Definition specific extension of {@link org.springframework.data.jpa.repository.JpaRepository}.
26 | *
27 | * @author Kyriakos Bompotis
28 | */
29 | @Repository
30 | public interface ServerMetricDefinitionRepository extends JpaRepository {
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/AbstractService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.service;
19 |
20 | import org.springframework.data.domain.PageRequest;
21 | import org.springframework.data.domain.Sort;
22 |
23 | import java.util.Optional;
24 |
25 | /**
26 | * Created by Kyriakos Bompotis on 13/7/20.
27 | */
28 | public abstract class AbstractService {
29 |
30 | protected PageRequest getDefaultPageRequest(Integer page, Integer size) {
31 | return PageRequest.of(
32 | Optional.ofNullable(page).orElse(0),
33 | Optional.ofNullable(size).orElse(10),
34 | Sort.by("createdAt").descending()
35 | );
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/dto/PaginatedDto.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.service.dto;
19 |
20 | import java.util.List;
21 |
22 | /**
23 | * Created by Kyriakos Bompotis on 22/6/20.
24 | */
25 | public class PaginatedDto extends AbstractPaginatedDto {
26 | private final List dtoList;
27 |
28 | public PaginatedDto(List dtoList,
29 | long totalElements,
30 | int totalPages,
31 | int number,
32 | int size) {
33 | super(totalElements, totalPages, number, size);
34 | this.dtoList = dtoList;
35 | }
36 |
37 | public List getDtoList() {
38 | return dtoList;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/RegisterServerRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model;
19 |
20 | import jakarta.validation.constraints.NotBlank;
21 |
22 | /**
23 | * Created by Kyriakos Bompotis on 4/9/20.
24 | */
25 | public class RegisterServerRequest {
26 | @NotBlank(message = "serverName is mandatory")
27 | private String serverName;
28 |
29 | private String description;
30 |
31 | public RegisterServerRequest() {}
32 |
33 | public RegisterServerRequest(String serverName, String description) {
34 | this.serverName = serverName;
35 | this.description = description;
36 | }
37 |
38 | public String getServerName() {
39 | return serverName;
40 | }
41 |
42 | public String getDescription() {
43 | return description;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/data/entity/OperationUpdater.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.data.entity;
19 |
20 | import com.bompotis.netcheck.service.dto.Operation;
21 |
22 | /**
23 | * Created by Kyriakos Bompotis on 8/9/20.
24 | */
25 | public interface OperationUpdater extends EntityBuilder {
26 | void removeField(String field, String path);
27 |
28 | void updateField(String field, String path, String value);
29 |
30 | default void processOperation(Operation operation) {
31 | switch (operation.action()) {
32 | case REMOVE -> removeField(operation.field(), operation.path());
33 | case ADD, UPDATE -> updateField(operation.field(), operation.path(), operation.value());
34 | default -> throw new IllegalArgumentException("Invalid operation");
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/data/repository/DomainRepository.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.data.repository;
19 |
20 | import com.bompotis.netcheck.data.entity.DomainEntity;
21 | import org.springframework.data.domain.Page;
22 | import org.springframework.data.domain.Pageable;
23 | import org.springframework.data.jpa.repository.JpaRepository;
24 | import org.springframework.data.jpa.repository.Query;
25 | import org.springframework.stereotype.Repository;
26 |
27 | /**
28 | * Domain specific extension of {@link org.springframework.data.jpa.repository.JpaRepository}.
29 | *
30 | * @author Kyriakos Bompotis
31 | */
32 | @Repository
33 | public interface DomainRepository extends JpaRepository {
34 | @Query("select d from DomainEntity d where d.domain like %?1%")
35 | Page findAllFiltered(String filter, Pageable pageable);
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/data/repository/ServerRepository.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.data.repository;
19 |
20 | import com.bompotis.netcheck.data.entity.ServerEntity;
21 | import org.springframework.data.domain.Page;
22 | import org.springframework.data.domain.Pageable;
23 | import org.springframework.data.jpa.repository.JpaRepository;
24 | import org.springframework.data.jpa.repository.Query;
25 | import org.springframework.stereotype.Repository;
26 |
27 | /**
28 | * Server specific extension of {@link org.springframework.data.jpa.repository.JpaRepository}.
29 | *
30 | * @author Kyriakos Bompotis
31 | */
32 | @Repository
33 | public interface ServerRepository extends JpaRepository {
34 | @Query("select s from ServerEntity s where s.serverName like %?1%")
35 | Page findAllFiltered(String filter, Pageable pageable);
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/ServerMetricRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model;
19 |
20 | import jakarta.validation.constraints.NotNull;
21 | import java.util.Date;
22 | import java.util.Map;
23 |
24 | /**
25 | * Created by Kyriakos Bompotis on 6/9/20.
26 | */
27 | public class ServerMetricRequest {
28 | @NotNull(message = "metrics are mandatory")
29 | private Map metrics;
30 |
31 | @NotNull(message = "collectedAt Date is mandatory")
32 | private Date collectedAt;
33 |
34 | public ServerMetricRequest() {}
35 |
36 | public ServerMetricRequest(Map metrics, Date collectedAt) {
37 | this.metrics = metrics;
38 | this.collectedAt = collectedAt;
39 | }
40 |
41 | public Map getMetrics() {
42 | return metrics;
43 | }
44 |
45 | public Date getCollectedAt() {
46 | return collectedAt;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/JobCompletionNotificationListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch;
19 |
20 | import org.slf4j.Logger;
21 | import org.slf4j.LoggerFactory;
22 | import org.springframework.batch.core.BatchStatus;
23 | import org.springframework.batch.core.JobExecution;
24 | import org.springframework.batch.core.listener.JobExecutionListenerSupport;
25 | import org.springframework.stereotype.Component;
26 |
27 | /**
28 | * Created by Kyriakos Bompotis on 10/6/20.
29 | */
30 | @Component
31 | public class JobCompletionNotificationListener extends JobExecutionListenerSupport {
32 |
33 | private static final Logger log = LoggerFactory.getLogger(JobCompletionNotificationListener.class);
34 |
35 | @Override
36 | public void afterJob(JobExecution jobExecution) {
37 | if(jobExecution.getStatus() == BatchStatus.COMPLETED) {
38 | log.info("!!! JOB FINISHED!");
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/notification/NotificationEventDto.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.notification;
19 |
20 | import com.google.gson.Gson;
21 | import org.springframework.context.ApplicationEvent;
22 | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
23 |
24 | import static org.springframework.http.MediaType.APPLICATION_JSON;
25 |
26 | /**
27 | * Created by Kyriakos Bompotis on 25/8/20.
28 | */
29 | public class NotificationEventDto extends ApplicationEvent implements EventDto {
30 |
31 | private final SseEmitter.SseEventBuilder event;
32 |
33 | public NotificationEventDto(Object source, NotificationDto notificationDto) {
34 | super(source);
35 | event = SseEmitter.event()
36 | .data(new Gson().toJson(notificationDto), APPLICATION_JSON)
37 | .reconnectTime(1000L)
38 | .name("Notification");
39 | }
40 |
41 | public SseEmitter.SseEventBuilder getEvent() {
42 | return event;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/assembler/PaginatedRepresentationModelAssemblerSupport.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model.assembler;
19 |
20 | import org.springframework.hateoas.RepresentationModel;
21 | import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
22 |
23 | /**
24 | * Created by Kyriakos Bompotis on 17/6/20.
25 | */
26 | public abstract class PaginatedRepresentationModelAssemblerSupport> extends RepresentationModelAssemblerSupport {
27 | public PaginatedRepresentationModelAssemblerSupport(Class controllerClass, Class resourceType) {
28 | super(controllerClass, resourceType);
29 | }
30 |
31 | protected boolean isValidPage(int pageNumber, int totalPages) {
32 | return pageNumber+1 <= totalPages;
33 | }
34 |
35 | protected boolean isNotFirstPage(int pageNumber) {
36 | return pageNumber != 0;
37 | }
38 |
39 | protected boolean isNotLastPage(int pageNumber, int totalPages) {
40 | return (pageNumber + 1 != totalPages);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/dto/AbstractPaginatedDto.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.service.dto;
19 |
20 | /**
21 | * Created by Kyriakos Bompotis on 12/6/20.
22 | */
23 | public abstract class AbstractPaginatedDto {
24 |
25 | private final long totalElements;
26 | private final int totalPages;
27 | private final int number;
28 | private final int size;
29 |
30 | public AbstractPaginatedDto(long totalElements,
31 | int totalPages,
32 | int number,
33 | int size) {
34 | this.totalElements = totalElements;
35 | this.totalPages = totalPages;
36 | this.number = number;
37 | this.size = size;
38 | }
39 |
40 | public long getTotalElements() {
41 | return totalElements;
42 | }
43 |
44 | public int getTotalPages() {
45 | return totalPages;
46 | }
47 |
48 | public int getNumber() {
49 | return number;
50 | }
51 |
52 | public int getSize() {
53 | return size;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/notification/ServerMetricEventDto.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.notification;
19 |
20 | import com.bompotis.netcheck.service.dto.ServerMetricDto;
21 | import com.google.gson.Gson;
22 | import org.springframework.context.ApplicationEvent;
23 | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
24 |
25 | import static org.springframework.http.MediaType.APPLICATION_JSON;
26 |
27 |
28 | public class ServerMetricEventDto extends ApplicationEvent implements EventDto {
29 |
30 | private final SseEmitter.SseEventBuilder event;
31 |
32 | public ServerMetricEventDto(Object source, ServerMetricDto.ServerMetricEvent serverMetricEvent) {
33 | super(source);
34 | event = SseEmitter.event()
35 | .data(new Gson().toJson(serverMetricEvent), APPLICATION_JSON)
36 | .reconnectTime(1000L)
37 | .name("ServerMetrics_" + serverMetricEvent.getServerId());
38 | }
39 |
40 | public SseEmitter.SseEventBuilder getEvent() {
41 | return event;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/notification/NotificationEventService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.notification;
19 |
20 | import org.springframework.beans.factory.annotation.Autowired;
21 | import org.springframework.context.ApplicationEventPublisher;
22 | import org.springframework.stereotype.Service;
23 |
24 | /**
25 | * Created by Kyriakos Bompotis on 25/8/20.
26 | */
27 | @Service
28 | public class NotificationEventService implements NotificationService {
29 |
30 | private final ApplicationEventPublisher eventPublisher;
31 |
32 | @Autowired
33 | public NotificationEventService(ApplicationEventPublisher eventPublisher) {
34 | this.eventPublisher = eventPublisher;
35 | }
36 |
37 | @Override
38 | public boolean isEnabled() {
39 | return true;
40 | }
41 |
42 | @Override
43 | public String name() {
44 | return "NotificationEvent";
45 | }
46 |
47 | @Override
48 | public void notify(NotificationDto notification) {
49 | eventPublisher.publishEvent(new NotificationEventDto(this, notification));
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/resources/application.yaml:
--------------------------------------------------------------------------------
1 | info:
2 | app:
3 | name: NetCheck API
4 | description: Website performance and availability monitoring app
5 | java:
6 | vendor: ${java.specification.vendor}
7 | version: ${java.version}
8 | vm-name: ${java.vm.name}
9 | vm-version: ${java.vm.version}
10 | version-date: ${java.version.date}
11 | os:
12 | name: ${os.name}
13 | springdoc:
14 | api-docs:
15 | path: "/docs/v1/OpenAPIv3"
16 | show-actuator: true
17 | swagger-ui:
18 | operationsSorter: method
19 | path: "/docs/v1/"
20 | spring:
21 | autoconfigure:
22 | exclude: org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
23 | jmx:
24 | enabled: false
25 | datasource:
26 | hikari:
27 | connectionTimeout: 20000
28 | maximumPoolSize: 20
29 | url: jdbc:postgresql://${postgres.host}:${postgres.port}/${postgres.db}
30 | username: ${postgres.user}
31 | password: ${postgres.password}
32 | batch:
33 | job:
34 | enabled: false
35 | jdbc:
36 | initialize-schema: never
37 | jpa:
38 | open-in-view: true
39 | hibernate:
40 | ddl-auto: validate
41 | settings:
42 | cors:
43 | origin: "*"
44 | schedulers:
45 | cleanup:
46 | enabled: false
47 | deleteOlderThan: 3
48 | management:
49 | info:
50 | env:
51 | enabled: true
52 | endpoints:
53 | enabled-by-default: false
54 | web:
55 | base-path: "/api/v1/actuator"
56 | exposure:
57 | include: "*"
58 | cors:
59 | allowed-origins: ${settings.cors.origin}
60 | allowed-methods: "GET"
61 | endpoint:
62 | info:
63 | enabled: true
64 | metrics:
65 | enabled: true
66 | health:
67 | enabled: true
68 | show-details: always
69 | show-components: always
70 | server:
71 | forward-headers-strategy: native
72 | compression:
73 | enabled: true
74 | port: 8080
75 | http2:
76 | enabled: true
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/assembler/ServerDefinitionAssembler.java:
--------------------------------------------------------------------------------
1 | package com.bompotis.netcheck.api.model.assembler;
2 |
3 | import com.bompotis.netcheck.api.controller.ServerController;
4 | import com.bompotis.netcheck.api.model.ServerDefinitionModel;
5 | import com.bompotis.netcheck.service.dto.ServerDefinitionDto;
6 | import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
7 | import org.springframework.lang.NonNull;
8 |
9 | /**
10 | * Created by Kyriakos Bompotis on 9/9/20.
11 | */
12 | public class ServerDefinitionAssembler extends RepresentationModelAssemblerSupport {
13 |
14 | public ServerDefinitionAssembler() {
15 | super(ServerController.class, ServerDefinitionModel.class);
16 | }
17 |
18 | @NonNull
19 | @Override
20 | public ServerDefinitionModel toModel(ServerDefinitionDto entity) {
21 | return new ServerDefinitionModel(
22 | entity.getLabel(),
23 | entity.getFieldName(),
24 | entity.getSuffix(),
25 | entity.getValueType(),
26 | entity.getMetricKind(),
27 | entity.getExtendedType(),
28 | entity.getMinThreshold(),
29 | entity.getMaxThreshold(),
30 | entity.getNotify()
31 | );
32 | }
33 |
34 | public ServerDefinitionDto toDto(ServerDefinitionModel model) {
35 | return new ServerDefinitionDto.Builder()
36 | .label(model.getLabel())
37 | .fieldName(model.getFieldName())
38 | .suffix(model.getSuffix())
39 | .valueType(model.getValueType())
40 | .metricKind(model.getMetricKind())
41 | .extendedType(model.getExtendedType())
42 | .maxThreshold(model.getMaxThreshold())
43 | .minThreshold(model.getMinThreshold())
44 | .notify(model.getNotify())
45 | .build();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/resources/META-INF/additional-spring-configuration-metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "properties": [
3 | {
4 | "name": "settings.cors.origin",
5 | "type": "java.lang.String",
6 | "description": "CORS Permitted Domains."
7 | },
8 | {
9 | "name": "settings.notifications.pushover.enabled",
10 | "type": "java.lang.String",
11 | "description": "Enable or disable Pushover notifications."
12 | },
13 | {
14 | "name": "settings.notifications.pushover.apiToken",
15 | "type": "java.lang.String",
16 | "description": "Pushover API Token."
17 | },
18 | {
19 | "name": "settings.notifications.pushover.userIdToken",
20 | "type": "java.lang.String",
21 | "description": "Pushover User ID token."
22 | },
23 | {
24 | "name": "settings.notifications.pushover.notifyOnlyFor",
25 | "type": "java.util.List",
26 | "description": "Filter for only sending specific type of notifications."
27 | },
28 | {
29 | "name": "settings.schedulers.cleanup.enabled",
30 | "type": "java.lang.String",
31 | "description": "Enable or disable deletion of older checks every month."
32 | },
33 | {
34 | "name": "settings.schedulers.cleanup.deleteOlderThan",
35 | "type": "java.lang.String",
36 | "description": "Minimum amount of months a check should be consider old enough to be deleted."
37 | },
38 | {
39 | "name": "settings.notifications.webhook.enabled",
40 | "type": "java.lang.String",
41 | "description": "Enable or disable notifications through a Webhook."
42 | },
43 | {
44 | "name": "settings.notifications.webhook.url",
45 | "type": "java.lang.String",
46 | "description": "Url of the webhook."
47 | },
48 | {
49 | "name": "settings.notifications.webhook.notifyOnlyFor",
50 | "type": "java.util.List",
51 | "description": "Filter for only sending specific type of notifications."
52 | }
53 | ]
54 | }
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/processor/DomainMetricProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.processor;
19 |
20 | import com.bompotis.netcheck.data.entity.DomainEntity;
21 | import com.bompotis.netcheck.data.entity.DomainMetricEntity;
22 | import com.bompotis.netcheck.service.MetricService;
23 | import org.springframework.batch.item.ItemProcessor;
24 | import org.springframework.lang.NonNull;
25 |
26 | import java.util.List;
27 |
28 | /**
29 | * Created by Kyriakos Bompotis on 29/6/20.
30 | */
31 | public class DomainMetricProcessor implements ItemProcessor> {
32 |
33 | private final MetricService metricService;
34 |
35 | private final MetricService.ScheduledPeriod period;
36 |
37 | public DomainMetricProcessor(MetricService.ScheduledPeriod period,
38 | MetricService metricService) {
39 | this.period = period;
40 | this.metricService = metricService;
41 | }
42 |
43 | @Override
44 | public List process(@NonNull DomainEntity domainEntity) {
45 | return metricService.generateMetric(domainEntity,new MetricService.TimeFrame(this.period));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/dto/DomainUpdateDto.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.service.dto;
19 |
20 | import java.util.*;
21 |
22 | /**
23 | * Created by Kyriakos Bompotis on 2/9/20.
24 | */
25 | public class DomainUpdateDto {
26 | private final String domain;
27 | private final List operations;
28 |
29 | public String getDomain() {
30 | return domain;
31 | }
32 |
33 | public List getOperations() {
34 | return operations;
35 | }
36 |
37 | public static class Builder implements PatchDtoBuilder {
38 | private final String domain;
39 | private final List operations = new ArrayList<>();
40 |
41 | public Builder(String domain) {
42 | this.domain = domain;
43 | }
44 |
45 | public Builder addOperation(Operation operation) {
46 | this.operations.add(operation);
47 | return this;
48 | }
49 |
50 | public DomainUpdateDto build() {
51 | return new DomainUpdateDto(this);
52 | }
53 | }
54 |
55 | private DomainUpdateDto(Builder b) {
56 | this.domain = b.domain;
57 | this.operations = b.operations;
58 | }
59 | }
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/data/repository/DomainMetricRepository.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.data.repository;
19 |
20 | import com.bompotis.netcheck.data.entity.DomainMetricEntity;
21 | import org.springframework.data.domain.Page;
22 | import org.springframework.data.domain.Pageable;
23 | import org.springframework.data.jpa.repository.JpaRepository;
24 | import org.springframework.data.jpa.repository.Query;
25 | import org.springframework.stereotype.Repository;
26 |
27 | import java.util.Date;
28 | import java.util.Set;
29 |
30 | /**
31 | * Domain Metric specific extension of {@link org.springframework.data.jpa.repository.JpaRepository}.
32 | *
33 | * @author Kyriakos Bompotis
34 | */
35 | @Repository
36 | public interface DomainMetricRepository extends JpaRepository {
37 | @Query("select d from DomainMetricEntity d where d.domain = ?1 " +
38 | "and d.periodType = ?2 and d.createdAt >= ?3 and d.createdAt < ?4")
39 | Set findAllBetweenDates(String domain, String period, Date startDate, Date endDate);
40 |
41 | Page findAllByDomainAndProtocolAndPeriodType(String domain, DomainMetricEntity.Protocol protocol, DomainMetricEntity.Period periodType, Pageable pageable);
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/dto/ServerUpdateDto.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.service.dto;
19 |
20 | import java.util.ArrayList;
21 | import java.util.List;
22 |
23 | /**
24 | * Created by Kyriakos Bompotis on 2/9/20.
25 | */
26 | public class ServerUpdateDto {
27 | private final String serverId;
28 | private final List operations;
29 |
30 | public String getServerId() {
31 | return serverId;
32 | }
33 |
34 | public List getOperations() {
35 | return operations;
36 | }
37 |
38 | public static class Builder implements PatchDtoBuilder{
39 | private final String serverId;
40 | private final List operations = new ArrayList<>();
41 |
42 | public Builder(String serverId) {
43 | this.serverId = serverId;
44 | }
45 |
46 | public Builder addOperation(Operation operation) {
47 | this.operations.add(operation);
48 | return this;
49 | }
50 |
51 | public ServerUpdateDto build() {
52 | return new ServerUpdateDto(this);
53 | }
54 | }
55 |
56 | private ServerUpdateDto(Builder b) {
57 | this.serverId = b.serverId;
58 | this.operations = b.operations;
59 | }
60 | }
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/security/WebSecurityConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.security;
19 |
20 | import org.springframework.context.annotation.Bean;
21 | import org.springframework.context.annotation.Configuration;
22 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
23 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
24 | import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
25 | import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
26 | import org.springframework.security.crypto.password.PasswordEncoder;
27 | import org.springframework.security.web.SecurityFilterChain;
28 |
29 | /**
30 | * Created by Kyriakos Bompotis on 4/9/20.
31 | */
32 | @Configuration
33 | @EnableWebSecurity
34 | public class WebSecurityConfig {
35 |
36 | @Bean
37 | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
38 | return http.csrf(AbstractHttpConfigurer::disable)
39 | .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()).build();
40 | }
41 |
42 | @Bean
43 | public PasswordEncoder passwordEncoder() {
44 | return Argon2PasswordEncoder.defaultsForSpringSecurity_v5_8();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/assembler/CertificateModelAssembler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model.assembler;
19 |
20 | import com.bompotis.netcheck.api.controller.DomainsController;
21 | import com.bompotis.netcheck.api.model.CertificateModel;
22 | import com.bompotis.netcheck.service.dto.CertificateDetailsDto;
23 | import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
24 | import org.springframework.lang.NonNull;
25 |
26 | /**
27 | * Created by Kyriakos Bompotis on 17/6/20.
28 | */
29 | public class CertificateModelAssembler extends RepresentationModelAssemblerSupport {
30 |
31 | public CertificateModelAssembler() {
32 | super(DomainsController.class, CertificateModel.class);
33 | }
34 |
35 | @NonNull
36 | @Override
37 | public CertificateModel toModel(CertificateDetailsDto certificateDetailsDto) {
38 | return new CertificateModel(
39 | certificateDetailsDto.getIssuedBy(),
40 | certificateDetailsDto.getIssuedFor(),
41 | certificateDetailsDto.getNotBefore(),
42 | certificateDetailsDto.getNotAfter(),
43 | certificateDetailsDto.isValid(),
44 | certificateDetailsDto.getExpired()
45 | );
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/writer/CheckEventItemWriter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.writer;
19 |
20 | import com.bompotis.netcheck.data.entity.DomainCheckEntity;
21 | import com.bompotis.netcheck.scheduler.batch.notification.CheckEventDto;
22 | import org.slf4j.Logger;
23 | import org.slf4j.LoggerFactory;
24 | import org.springframework.batch.item.Chunk;
25 | import org.springframework.batch.item.ItemWriter;
26 | import org.springframework.beans.factory.annotation.Autowired;
27 | import org.springframework.context.ApplicationEventPublisher;
28 | import org.springframework.stereotype.Component;
29 |
30 | /**
31 | * Created by Kyriakos Bompotis on 25/8/20.
32 | */
33 | @Component
34 | public class CheckEventItemWriter implements ItemWriter {
35 |
36 | private static final Logger logger = LoggerFactory.getLogger(CheckEventItemWriter.class);
37 |
38 | private final ApplicationEventPublisher eventPublisher;
39 |
40 | @Autowired
41 | public CheckEventItemWriter(ApplicationEventPublisher eventPublisher) {
42 | this.eventPublisher = eventPublisher;
43 | }
44 |
45 | @Override
46 | public void write(Chunk extends DomainCheckEntity> chunk) {
47 | logger.info("Publishing {} events", chunk.size());
48 | chunk.forEach((check) -> eventPublisher.publishEvent(new CheckEventDto(this,check)));
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/notification/CheckEventDto.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.notification;
19 |
20 | import com.bompotis.netcheck.data.entity.DomainCheckEntity;
21 | import com.google.gson.Gson;
22 | import org.springframework.context.ApplicationEvent;
23 | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
24 |
25 | import java.util.HashMap;
26 | import java.util.Map;
27 |
28 | import static org.springframework.http.MediaType.APPLICATION_JSON;
29 |
30 | /**
31 | * Created by Kyriakos Bompotis on 25/8/20.
32 | */
33 | public class CheckEventDto extends ApplicationEvent implements EventDto {
34 |
35 | private final SseEmitter.SseEventBuilder event;
36 |
37 | public CheckEventDto(Object source, DomainCheckEntity domainCheckEntity) {
38 | super(source);
39 | Map messageMap = new HashMap<>();
40 | messageMap.put("domain",domainCheckEntity.getDomain());
41 | messageMap.put("timeCheckedOn", domainCheckEntity.getTimeCheckedOn());
42 | messageMap.put("changeType", domainCheckEntity.getChangeType());
43 | event = SseEmitter.event()
44 | .data(new Gson().toJson(messageMap), APPLICATION_JSON)
45 | .reconnectTime(1000L)
46 | .name("DomainCheck_"+domainCheckEntity.getDomain());
47 | }
48 |
49 | public SseEmitter.SseEventBuilder getEvent() {
50 | return event;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/resources/db/migration/V1_4_0__add_server_tables.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE public.server (
2 | id varchar(255) NOT NULL,
3 | created_at timestamp NOT NULL,
4 | updated_at timestamp NOT NULL,
5 | server_name varchar(255) NOT NULL,
6 | description varchar(255) NULL,
7 | password varchar(255) NOT NULL,
8 | CONSTRAINT server_pkey PRIMARY KEY (id)
9 | );
10 |
11 | CREATE TABLE public.server_metric (
12 | id varchar(255) NOT NULL,
13 | created_at timestamp NOT NULL,
14 | updated_at timestamp NOT NULL,
15 | collected_at timestamp NOT NULL,
16 | server_id varchar(255) NOT NULL,
17 | metrics jsonb NOT NULL,
18 | CONSTRAINT server_metric_pkey PRIMARY KEY (id),
19 | CONSTRAINT server_metric_server_fk FOREIGN KEY (server_id) REFERENCES server(id)
20 | );
21 |
22 | CREATE TABLE public.server_metric_definition (
23 | field_name varchar(255) NOT NULL,
24 | server_id varchar(255) NOT NULL,
25 | created_at timestamp NOT NULL,
26 | updated_at timestamp NOT NULL,
27 | label varchar(255) NOT NULL,
28 | suffix varchar(255) NULL,
29 | max_threshold varchar(255) NULL,
30 | min_threshold varchar(255) NULL,
31 | notify bool NOT NULL DEFAULT FALSE,
32 | value_type varchar(255) NOT NULL,
33 | extended_type varchar(255) NULL,
34 | metric_kind varchar(255) NOT NULL,
35 | CONSTRAINT server_metric_definition_pkey PRIMARY KEY (field_name),
36 | CONSTRAINT server_metric_definition_server_fk FOREIGN KEY (server_id) REFERENCES server(id)
37 | );
38 |
39 | CREATE TABLE public.server_domain (
40 | server_id varchar(255) NOT NULL,
41 | domain varchar(255) NOT NULL,
42 | CONSTRAINT server_domain_pkey PRIMARY KEY (server_id, domain),
43 | CONSTRAINT server_domain_server_fk FOREIGN KEY (server_id) REFERENCES server(id),
44 | CONSTRAINT server_domain_domain_fk FOREIGN KEY (domain) REFERENCES domain(domain)
45 | );
46 |
47 | CREATE INDEX server__id_password_idx ON public.server USING btree (id, password);
48 | CREATE INDEX server_metric__server_created_idx ON public.server_metric USING btree (server_id, created_at);
49 | CREATE INDEX server_metric__server_collected_idx ON public.server_metric USING btree (server_id, collected_at);
50 | CREATE INDEX server_metric_definition__server_created_idx ON public.server_metric_definition USING btree (server_id, created_at);
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/dto/DomainCheckConfigDto.java:
--------------------------------------------------------------------------------
1 | package com.bompotis.netcheck.service.dto;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.Optional;
6 |
7 | /**
8 | * Created by Kyriakos Bompotis on 2/9/20.
9 | */
10 | public class DomainCheckConfigDto {
11 | private final String domain;
12 | private final String endpoint;
13 | private final Map headers;
14 | private final int timeoutMs;
15 |
16 | public String getDomain() {
17 | return domain;
18 | }
19 |
20 | public String getEndpoint() {
21 | return endpoint;
22 | }
23 |
24 | public Map getHeaders() {
25 | return headers;
26 | }
27 |
28 | public int getTimeoutMs() {
29 | return timeoutMs;
30 | }
31 |
32 | public static class Builder implements DtoBuilder{
33 | private String domain;
34 | private String endpoint = "";
35 | private int timeoutMs = 30000;
36 | private final Map headers = new HashMap<>();
37 |
38 | public Builder domain(String domain) {
39 | this.domain = domain;
40 | return this;
41 | }
42 |
43 | public Builder endpoint(String endpoint) {
44 | this.endpoint = Optional.ofNullable(endpoint).orElse("");
45 | return this;
46 | }
47 |
48 | public Builder timeoutMs(Integer timeoutMs) {
49 | this.timeoutMs = Optional.ofNullable(timeoutMs).orElse(30000);
50 | return this;
51 | }
52 |
53 | public Builder withHeader(String key, String value) {
54 | this.headers.put(key,value);
55 | return this;
56 | }
57 |
58 | public Builder withHeaders(Map headers) {
59 | if (Optional.ofNullable(headers).isPresent()) {
60 | this.headers.putAll(headers);
61 | }
62 | return this;
63 | }
64 |
65 | public DomainCheckConfigDto build() {
66 | return new DomainCheckConfigDto(this);
67 | }
68 | }
69 |
70 | private DomainCheckConfigDto(Builder b) {
71 | this.domain = b.domain;
72 | this.endpoint = b.endpoint;
73 | this.timeoutMs = b.timeoutMs;
74 | this.headers = Map.copyOf(b.headers);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/DomainRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model;
19 |
20 | import jakarta.validation.constraints.Max;
21 | import jakarta.validation.constraints.Min;
22 | import java.util.Map;
23 |
24 | /**
25 | * Created by Kyriakos Bompotis on 2/9/20.
26 | */
27 | public record DomainRequest(
28 | @Min(value = 1, message = "checkFrequencyMinutes should not be less than 1") Integer checkFrequencyMinutes,
29 | String endpoint,
30 | @Min(value = 1, message = "port should not be less than 1") @Max(value = 65535, message = "port should be no more than 65535") Integer httpPort,
31 | @Min(value = 1, message = "port should not be less than 1") @Max(value = 65535, message = "port should be no more than 65535") Integer httpsPort,
32 | Map headers,
33 | @Min(value = 1, message = "timeoutMs should not be less than 1") Integer timeoutMs) {
34 | public DomainRequest(Integer checkFrequencyMinutes, String endpoint, Integer httpPort, Integer httpsPort, Map headers, Integer timeoutMs) {
35 | this.checkFrequencyMinutes = checkFrequencyMinutes;
36 | this.endpoint = endpoint;
37 | this.httpPort = httpPort;
38 | this.httpsPort = httpsPort;
39 | this.headers = headers;
40 | this.timeoutMs = timeoutMs;
41 | }
42 |
43 | @Override
44 | public Integer checkFrequencyMinutes() {
45 | return checkFrequencyMinutes;
46 | }
47 |
48 | @Override
49 | public Integer timeoutMs() {
50 | return timeoutMs;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/reader/OldDomainCheckItemReader.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.reader;
19 |
20 | import com.bompotis.netcheck.data.entity.DomainCheckEntity;
21 | import com.bompotis.netcheck.data.repository.DomainCheckRepository;
22 | import org.springframework.batch.item.data.RepositoryItemReader;
23 | import org.springframework.data.domain.Sort;
24 | import org.springframework.lang.NonNull;
25 |
26 | import java.time.LocalDateTime;
27 | import java.time.ZoneOffset;
28 | import java.util.Date;
29 | import java.util.List;
30 | import java.util.Map;
31 |
32 | /**
33 | * Created by Kyriakos Bompotis on 13/7/20.
34 | */
35 | public class OldDomainCheckItemReader extends RepositoryItemReader {
36 |
37 | private final int threshold;
38 |
39 | public OldDomainCheckItemReader(DomainCheckRepository domainCheckRepository, Integer threshold) {
40 | this.setRepository(domainCheckRepository);
41 | this.setMethodName("findAllNonFirstCheckedBeforeDate");
42 | this.setPageSize(10);
43 | this.setSort(Map.of("createdAt", Sort.Direction.ASC));
44 | if (threshold > 0) {
45 | this.threshold = threshold;
46 | }
47 | else {
48 | this.threshold = 3;
49 | }
50 | }
51 |
52 | @NonNull
53 | @Override
54 | protected List doPageRead() throws Exception {
55 | this.setArguments(List.of(Date.from(LocalDateTime.now().minusDays(1).minusMonths(threshold).toInstant(ZoneOffset.UTC))));
56 | return super.doPageRead();
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/assembler/ServerUpdateDtoAssembler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model.assembler;
19 |
20 | import com.bompotis.netcheck.service.dto.Operation;
21 | import com.bompotis.netcheck.service.dto.ServerUpdateDto;
22 |
23 | import java.util.Map;
24 | import java.util.Set;
25 |
26 | /**
27 | * Created by Kyriakos Bompotis on 2/9/20.
28 | */
29 | public class ServerUpdateDtoAssembler implements AbstractUpdateDtoAssembler{
30 | private final String domain;
31 |
32 | private static final Map OPERATIONS_TO_ACTION_MAP = Map.of(
33 | "delete", Operation.Action.REMOVE,
34 | "replace", Operation.Action.UPDATE,
35 | "add", Operation.Action.ADD
36 | );
37 |
38 | private static final Set VALID_FIELDS = Set.of(
39 | "serverName",
40 | "description",
41 | "password"
42 | );
43 |
44 | public ServerUpdateDtoAssembler(String domain) {
45 | this.domain = domain;
46 | }
47 |
48 | @Override
49 | public Map getOperationsToActionMap() {
50 | return OPERATIONS_TO_ACTION_MAP;
51 | }
52 |
53 | @Override
54 | public Set getValidFields() {
55 | return VALID_FIELDS;
56 | }
57 |
58 | @Override
59 | public Set getRequiredFieldsForPath() {
60 | return Set.of();
61 | }
62 |
63 | @Override
64 | public ServerUpdateDto.Builder getDtoBuilder() {
65 | return new ServerUpdateDto.Builder(domain);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/traefik.docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.6'
2 |
3 | services:
4 | db:
5 | image: postgres
6 | env_file:
7 | - database.env
8 | volumes:
9 | - db-data:/var/lib/postgresql/data
10 |
11 | traefik:
12 | image: "traefik"
13 | command:
14 | - "--api.insecure=true"
15 | - "--providers.docker=true"
16 | - "--providers.docker.exposedbydefault=false"
17 | - "--entrypoints.web.address=:80"
18 | - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
19 | - "--entrypoints.web.http.redirections.entryPoint.scheme=https"
20 | - "--entrypoints.web.http.redirections.entrypoint.permanent=true"
21 | - "--entrypoints.websecure.address=:443"
22 | - "--certificatesresolvers.mainresolver.acme.httpchallenge=true"
23 | - "--certificatesresolvers.mainresolver.acme.httpchallenge.entrypoint=web"
24 | - "--certificatesresolvers.mainresolver.acme.email="
25 | - "--certificatesresolvers.mainresolver.acme.storage=/letsencrypt/acme.json"
26 | ports:
27 | - "80:80"
28 | - "443:443"
29 | volumes:
30 | - letsencrypt:/letsencrypt
31 | - "/var/run/docker.sock:/var/run/docker.sock:ro"
32 |
33 | api:
34 | image: memphisx/netcheck-api:latest
35 | env_file:
36 | - database.env
37 | - .env
38 | depends_on:
39 | - db
40 | labels:
41 | - "traefik.enable=true"
42 | - "traefik.http.routers.netcheck-api.rule=Host(``) && PathPrefix(`/api`,`/docs`,`/events`)"
43 | - "traefik.http.routers.netcheck-api.entrypoints=websecure"
44 | - "traefik.http.routers.netcheck-api.service=netcheck-api"
45 | - "traefik.http.routers.netcheck-api.tls.certresolver=mainresolver"
46 | - "traefik.http.services.netcheck-api.loadbalancer.server.port=8080"
47 |
48 |
49 |
50 | frontend:
51 | image: memphisx/netcheck-frontend:latest
52 | depends_on:
53 | - api
54 | labels:
55 | - "traefik.enable=true"
56 | - "traefik.http.services.netcheck-frontend.loadbalancer.server.port=80"
57 | - "traefik.http.routers.netcheck-frontend.service=netcheck-frontend"
58 | - "traefik.http.routers.netcheck-frontend.rule=Host(``)"
59 | - "traefik.http.routers.netcheck-frontend.entrypoints=websecure"
60 | - "traefik.http.routers.netcheck-frontend.tls.certresolver=mainresolver"
61 |
62 |
63 | volumes:
64 | db-data:
65 | driver: local
66 | letsencrypt:
67 | driver: local
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/data/entity/AbstractTimestampable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.data.entity;
19 |
20 | import org.springframework.data.annotation.CreatedDate;
21 | import org.springframework.data.annotation.LastModifiedDate;
22 | import org.springframework.data.domain.Persistable;
23 |
24 | import jakarta.persistence.MappedSuperclass;
25 | import jakarta.persistence.Column;
26 | import jakarta.persistence.PrePersist;
27 | import jakarta.persistence.PreUpdate;
28 | import jakarta.persistence.PreRemove;
29 | import java.io.Serializable;
30 | import java.util.Date;
31 |
32 | /**
33 | * Created by Kyriakos Bompotis on 16/6/20.
34 | */
35 | @MappedSuperclass
36 | public abstract class AbstractTimestampable implements Persistable {
37 | @CreatedDate
38 | @Column(name = "created_at")
39 | protected Date createdAt;
40 |
41 | @LastModifiedDate
42 | @Column(name = "updated_at")
43 | private Date updatedAt;
44 |
45 | protected AbstractTimestampable() {}
46 |
47 | public Date getCreatedAt() {
48 | return createdAt;
49 | }
50 |
51 | public Date getUpdatedAt() {
52 | return updatedAt;
53 | }
54 |
55 | @PrePersist
56 | protected void prePersist() {
57 | if (this.createdAt == null) createdAt = new Date();
58 | if (this.updatedAt == null) updatedAt = new Date();
59 | }
60 |
61 | @PreUpdate
62 | protected void preUpdate() {
63 | if (this.createdAt == null) createdAt = new Date();
64 | this.updatedAt = new Date();
65 | }
66 |
67 | @PreRemove
68 | protected void preRemove() {
69 | this.updatedAt = new Date();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/NetcheckApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck;
19 |
20 | import com.bompotis.netcheck.scheduler.batch.notification.config.PushoverConfig;
21 | import com.bompotis.netcheck.scheduler.batch.notification.config.WebhookConfig;
22 | import io.swagger.v3.oas.annotations.OpenAPIDefinition;
23 | import io.swagger.v3.oas.annotations.info.Contact;
24 | import io.swagger.v3.oas.annotations.info.Info;
25 | import io.swagger.v3.oas.annotations.info.License;
26 | import org.springframework.boot.SpringApplication;
27 | import org.springframework.boot.autoconfigure.SpringBootApplication;
28 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
29 | import org.springframework.context.annotation.PropertySource;
30 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
31 | import org.springframework.scheduling.annotation.EnableScheduling;
32 |
33 | @OpenAPIDefinition(info =
34 | @Info(
35 | title = "${info.app.name}",
36 | version = "${build.version}",
37 | description = "${info.app.description}",
38 | license = @License(name = "GPL 3.0", url = "https://www.gnu.org/licenses/gpl-3.0.en.html"),
39 | contact = @Contact(url = "https://github.com/memphisx", name = "Kyriakos Bompotis")
40 | )
41 | )
42 | @SpringBootApplication
43 | @EnableJpaRepositories
44 | @EnableScheduling
45 | @EnableConfigurationProperties({PushoverConfig.class, WebhookConfig.class})
46 | @PropertySource(value="classpath:META-INF/build-info.properties", ignoreResourceNotFound=true)
47 | public class NetcheckApplication {
48 |
49 | public static void main(String[] args) {
50 | SpringApplication.run(NetcheckApplication.class, args);
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/writer/DomainMetricListWriter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.writer;
19 |
20 | import com.bompotis.netcheck.data.entity.DomainMetricEntity;
21 | import jakarta.persistence.EntityManagerFactory;
22 | import org.apache.commons.logging.Log;
23 | import org.apache.commons.logging.LogFactory;
24 | import org.springframework.batch.item.Chunk;
25 | import org.springframework.batch.item.ItemWriter;
26 | import org.springframework.batch.item.database.JpaItemWriter;
27 |
28 | import java.util.List;
29 |
30 | /**
31 | * Created by Kyriakos Bompotis on 30/6/20.
32 | */
33 | public class DomainMetricListWriter implements ItemWriter> {
34 | protected static final Log logger = LogFactory.getLog(DomainMetricListWriter.class);
35 | private final JpaItemWriter jpaItemWriter;
36 |
37 | public DomainMetricListWriter() {
38 | this.jpaItemWriter = new JpaItemWriter<>();
39 | }
40 |
41 | public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
42 | jpaItemWriter.setEntityManagerFactory(entityManagerFactory);
43 | }
44 |
45 | public void afterPropertiesSet() throws Exception {
46 | this.jpaItemWriter.afterPropertiesSet();
47 | }
48 |
49 | public void setUsePersist(boolean usePersist) {
50 | this.jpaItemWriter.setUsePersist(usePersist);
51 | }
52 |
53 | @Override
54 | public void write(Chunk extends List> chunk) {
55 | Chunk metricEntities = new Chunk<>();
56 | chunk.forEach(metricEntities::addAll);
57 | jpaItemWriter.write(metricEntities);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/controller/StreamController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.controller;
19 |
20 | import com.bompotis.netcheck.scheduler.batch.notification.CheckEventDto;
21 | import com.bompotis.netcheck.scheduler.batch.notification.NotificationEventDto;
22 | import com.bompotis.netcheck.scheduler.batch.notification.ServerMetricEventDto;
23 | import io.swagger.v3.oas.annotations.tags.Tag;
24 | import org.springframework.context.event.EventListener;
25 | import org.springframework.web.bind.annotation.CrossOrigin;
26 | import org.springframework.web.bind.annotation.GetMapping;
27 | import org.springframework.web.bind.annotation.RequestMapping;
28 | import org.springframework.web.bind.annotation.RestController;
29 | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
30 |
31 | /**
32 | * Created by Kyriakos Bompotis on 25/8/20.
33 | */
34 | @RestController
35 | @CrossOrigin(origins = {"${settings.cors.origin}"})
36 | @RequestMapping(value = "/events")
37 | @Tag(name = "Check Events", description = "Server sent events endpoint")
38 | public class StreamController extends AbstractStreamController {
39 | @GetMapping
40 | public SseEmitter stream() {
41 | return addSseEmitter();
42 | }
43 |
44 | @EventListener
45 | public void handleCheckEvent(CheckEventDto eventDto) {
46 | sendToSseEmitter(eventDto.getEvent());
47 | }
48 |
49 | @EventListener
50 | public void handleNotificationEvent(NotificationEventDto eventDto) {
51 | sendToSseEmitter(eventDto.getEvent());
52 | }
53 |
54 | @EventListener
55 | public void handleServerMetricsEvent(ServerMetricEventDto eventDto) {
56 | sendToSseEmitter(eventDto.getEvent());
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/assembler/DomainUpdateDtoAssembler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model.assembler;
19 |
20 | import com.bompotis.netcheck.service.dto.DomainUpdateDto;
21 | import com.bompotis.netcheck.service.dto.Operation;
22 |
23 | import java.util.Map;
24 | import java.util.Set;
25 |
26 | /**
27 | * Created by Kyriakos Bompotis on 2/9/20.
28 | */
29 | public class DomainUpdateDtoAssembler implements AbstractUpdateDtoAssembler{
30 | private final String domain;
31 |
32 | private static final Map OPERATIONS_TO_ACTION_MAP = Map.of(
33 | "delete", Operation.Action.REMOVE,
34 | "replace", Operation.Action.UPDATE,
35 | "add", Operation.Action.ADD
36 | );
37 |
38 | private static final Set VALID_FIELDS = Set.of(
39 | "frequency",
40 | "endpoint",
41 | "header",
42 | "headers",
43 | "timeout"
44 | );
45 |
46 | private static final Set REQUIRED_FIELDS_FOR_PATH = Set.of(
47 | "header"
48 | );
49 |
50 | public DomainUpdateDtoAssembler(String domain) {
51 | this.domain = domain;
52 | }
53 |
54 | @Override
55 | public Map getOperationsToActionMap() {
56 | return OPERATIONS_TO_ACTION_MAP;
57 | }
58 |
59 | @Override
60 | public Set getValidFields() {
61 | return VALID_FIELDS;
62 | }
63 |
64 | @Override
65 | public Set getRequiredFieldsForPath() {
66 | return REQUIRED_FIELDS_FOR_PATH;
67 | }
68 |
69 | @Override
70 | public DomainUpdateDto.Builder getDtoBuilder() {
71 | return new DomainUpdateDto.Builder(domain);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/dto/HttpsCheckDto.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.service.dto;
19 |
20 | import java.util.ArrayList;
21 | import java.util.Collections;
22 | import java.util.List;
23 |
24 | /**
25 | * Created by Kyriakos Bompotis on 15/6/20.
26 | */
27 | public class HttpsCheckDto {
28 | private final HttpCheckDto httpCheckDto;
29 | private final List caCertificates;
30 | private final CertificateDetailsDto issuerCertificate;
31 |
32 | public List getCaCertificates() {
33 | return caCertificates;
34 | }
35 |
36 | public CertificateDetailsDto getIssuerCertificate() {
37 | return issuerCertificate;
38 | }
39 |
40 | public HttpCheckDto getHttpCheckDto() {
41 | return httpCheckDto;
42 | }
43 |
44 | public static class Builder implements DtoBuilder {
45 | private final List caCertificates = new ArrayList<>();
46 | private CertificateDetailsDto issuerCertificate;
47 | private HttpCheckDto httpCheckDto;
48 |
49 | public HttpsCheckDto.Builder httpCheckDto(HttpCheckDto httpCheckDto) {
50 | this.httpCheckDto = httpCheckDto;
51 | return this;
52 | }
53 |
54 | public HttpsCheckDto.Builder certificate(CertificateDetailsDto cert) {
55 | if (cert.getBasicConstraints() < 0) {
56 | this.issuerCertificate = cert;
57 | } else {
58 | this.caCertificates.add(cert);
59 | }
60 | return this;
61 | }
62 |
63 | public HttpsCheckDto build() {
64 | return new HttpsCheckDto(this);
65 | }
66 | }
67 |
68 | private HttpsCheckDto(HttpsCheckDto.Builder b) {
69 | this.caCertificates = Collections.unmodifiableList(b.caCertificates);
70 | this.issuerCertificate = b.issuerCertificate;
71 | this.httpCheckDto = b.httpCheckDto;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/notification/config/WebhookConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.notification.config;
19 |
20 | import org.springframework.boot.context.properties.ConfigurationProperties;
21 |
22 | import java.util.HashSet;
23 | import java.util.Optional;
24 | import java.util.Set;
25 |
26 | /**
27 | * Created by Kyriakos Bompotis on 10/8/20.
28 | */
29 | @ConfigurationProperties(prefix = "settings.notifications.webhook")
30 | public class WebhookConfig {
31 | private final Boolean enabled;
32 |
33 | private final String baseUrl;
34 |
35 | private final String endpoint;
36 |
37 | private final Set notifyOnlyFor;
38 |
39 | public WebhookConfig(Boolean enabled, String baseUrl, String endpoint, Set notifyOnlyFor) {
40 | this.enabled = Optional.ofNullable(enabled).orElse(false);
41 | this.baseUrl = baseUrl;
42 | this.endpoint = endpoint;
43 | var acceptableEntries = Set.of("HTTP","HTTPS","CERTIFICATE");
44 | if (Optional.ofNullable(notifyOnlyFor).isEmpty() || notifyOnlyFor.isEmpty()) {
45 | this.notifyOnlyFor = acceptableEntries;
46 | } else {
47 | var finalSet = new HashSet();
48 | for (var entry: notifyOnlyFor) {
49 | if (acceptableEntries.contains(entry.toUpperCase())) {
50 | finalSet.add(entry.toUpperCase());
51 | }
52 | else {
53 | throw new IllegalArgumentException("No such type of notification:" + entry);
54 | }
55 | }
56 | this.notifyOnlyFor = finalSet;
57 | }
58 | }
59 |
60 | public Boolean getEnabled() {
61 | return enabled;
62 | }
63 |
64 | public String getBaseUrl() {
65 | return baseUrl;
66 | }
67 |
68 | public Set getNotifyOnlyFor() {
69 | return notifyOnlyFor;
70 | }
71 |
72 | public String getEndpoint() {
73 | return endpoint;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/notification/config/PushoverConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.notification.config;
19 |
20 | import org.springframework.boot.context.properties.ConfigurationProperties;
21 |
22 | import java.util.HashSet;
23 | import java.util.Optional;
24 | import java.util.Set;
25 |
26 | /**
27 | * Created by Kyriakos Bompotis on 15/7/20.
28 | */
29 | @ConfigurationProperties(prefix = "settings.notifications.pushover")
30 | public class PushoverConfig {
31 |
32 | private final boolean enabled;
33 |
34 | private final String userIdToken;
35 |
36 | private final String apiToken;
37 |
38 | private final Set notifyOnlyFor;
39 |
40 | public PushoverConfig(Boolean enabled, String userIdToken, String apiToken, Set notifyOnlyFor) {
41 | this.enabled = Optional.ofNullable(enabled).orElse(false);
42 | this.userIdToken = userIdToken;
43 | this.apiToken = apiToken;
44 | var acceptableEntries = Set.of("HTTP","HTTPS","CERTIFICATE");
45 | if (Optional.ofNullable(notifyOnlyFor).isEmpty() || notifyOnlyFor.isEmpty()) {
46 | this.notifyOnlyFor = acceptableEntries;
47 | } else {
48 | var finalSet = new HashSet();
49 | for (var entry: notifyOnlyFor) {
50 | if (acceptableEntries.contains(entry.toUpperCase())) {
51 | finalSet.add(entry.toUpperCase());
52 | }
53 | else {
54 | throw new IllegalArgumentException("No such type of notification:" + entry);
55 | }
56 | }
57 | this.notifyOnlyFor = finalSet;
58 | }
59 | }
60 |
61 | public Boolean getEnabled() {
62 | return enabled;
63 | }
64 |
65 | public String getUserIdToken() {
66 | return userIdToken;
67 | }
68 |
69 | public String getApiToken() {
70 | return apiToken;
71 | }
72 |
73 | public Set getNotifyOnlyFor() {
74 | return notifyOnlyFor;
75 | }
76 | }
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/DomainCheckModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model;
19 |
20 | import com.fasterxml.jackson.annotation.JsonInclude;
21 | import com.fasterxml.jackson.annotation.JsonProperty;
22 | import org.springframework.hateoas.RepresentationModel;
23 | import org.springframework.hateoas.server.core.Relation;
24 |
25 | import java.util.Collection;
26 | import java.util.List;
27 |
28 | /**
29 | * Created by Kyriakos Bompotis on 10/6/20.
30 | */
31 | @Relation(collectionRelation = "domainChecks", itemRelation = "domainCheck")
32 | public class DomainCheckModel extends RepresentationModel {
33 | private final Collection httpChecks;
34 | private final CertificateModel issuerCertificate;
35 | private final List caCertificates;
36 | private final Boolean monitored;
37 | private final String domain;
38 |
39 | public DomainCheckModel(@JsonProperty("domain") String domain,
40 | @JsonProperty("monitored") Boolean monitored,
41 | @JsonProperty("httpChecks") Collection httpChecks,
42 | @JsonProperty("issuerCertificate") CertificateModel issuerCertificate,
43 | @JsonProperty("caCertificates") List caCertificates) {
44 | this.domain = domain;
45 | this.monitored = monitored;
46 | this.httpChecks = httpChecks;
47 | this.issuerCertificate = issuerCertificate;
48 | this.caCertificates = caCertificates;
49 | }
50 |
51 | public CertificateModel getIssuerCertificate() {
52 | return issuerCertificate;
53 | }
54 |
55 | public List getCaCertificates() {
56 | return caCertificates;
57 | }
58 |
59 | public Collection getHttpChecks() {
60 | return httpChecks;
61 | }
62 |
63 | public String getDomain() {
64 | return domain;
65 | }
66 |
67 | @JsonInclude(JsonInclude.Include.NON_NULL)
68 | public Boolean getMonitored() {
69 | return monitored;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/notification/PushoverService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.notification;
19 |
20 | import com.bompotis.netcheck.scheduler.batch.notification.client.PushoverMessage;
21 | import com.bompotis.netcheck.scheduler.batch.notification.client.PushoverRestClient;
22 | import com.bompotis.netcheck.scheduler.batch.notification.config.PushoverConfig;
23 | import org.slf4j.Logger;
24 | import org.slf4j.LoggerFactory;
25 | import org.springframework.beans.factory.annotation.Autowired;
26 | import org.springframework.stereotype.Service;
27 |
28 | import java.util.Optional;
29 | import java.util.Set;
30 |
31 | /**
32 | * Created by Kyriakos Bompotis on 1/7/20.
33 | */
34 | @Service
35 | public class PushoverService implements NotificationService {
36 |
37 | private final PushoverConfig pushoverConfig;
38 |
39 | private static final Logger log = LoggerFactory.getLogger(PushoverService.class);
40 |
41 | @Autowired
42 | public PushoverService(PushoverConfig pushoverConfig) {
43 | this.pushoverConfig = pushoverConfig;
44 | }
45 |
46 | @Override
47 | public boolean isEnabled() {
48 | return Optional.ofNullable(pushoverConfig.getEnabled()).orElse(false);
49 | }
50 |
51 | @Override
52 | public String name() {
53 | return "Pushover";
54 | }
55 |
56 | @Override
57 | public void notify(NotificationDto notification) {
58 | var protocols = pushoverConfig.getNotifyOnlyFor().isEmpty()
59 | ? Set.of("HTTP","HTTPS","CERTIFICATE")
60 | : Set.copyOf(pushoverConfig.getNotifyOnlyFor());
61 | if (protocols.contains(notification.getType().name())) {
62 | new PushoverRestClient().pushMessage(PushoverMessage
63 | .builderWithApiToken(pushoverConfig.getApiToken())
64 | .setUserId(pushoverConfig.getUserIdToken())
65 | .setMessage(notification.getMessage())
66 | .build()
67 | );
68 | } else {
69 | log.info("Pushover notifications for type {} are disabled. Skipping!", notification.getType().name());
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/ServerModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model;
19 |
20 | import com.fasterxml.jackson.annotation.JsonInclude;
21 | import com.fasterxml.jackson.annotation.JsonProperty;
22 | import org.springframework.hateoas.RepresentationModel;
23 | import org.springframework.hateoas.server.core.Relation;
24 |
25 | import java.util.Date;
26 | import java.util.List;
27 |
28 | /**
29 | * Created by Kyriakos Bompotis on 4/9/20.
30 | */
31 | @Relation(collectionRelation = "servers", itemRelation = "server")
32 | public class ServerModel extends RepresentationModel {
33 | private final String serverId;
34 | private final String serverName;
35 | private final String description;
36 | private final Date dateAdded;
37 | private final String password;
38 | private final List metricDefinitions;
39 |
40 | public ServerModel(@JsonProperty("serverId") String serverId,
41 | @JsonProperty("serverName") String serverName,
42 | @JsonProperty("description") String description,
43 | @JsonProperty("password") String password,
44 | @JsonProperty("dateAdded") Date dateAdded,
45 | @JsonProperty("metricDefinitions") List metricDefinitions) {
46 | this.serverId = serverId;
47 | this.serverName = serverName;
48 | this.description = description;
49 | this.password = password;
50 | this.dateAdded = dateAdded;
51 | this.metricDefinitions = metricDefinitions;
52 | }
53 |
54 | public String getServerId() {
55 | return serverId;
56 | }
57 |
58 | public String getServerName() {
59 | return serverName;
60 | }
61 |
62 | @JsonInclude(JsonInclude.Include.NON_NULL)
63 | public String getPassword() {
64 | return password;
65 | }
66 |
67 | public Date getDateAdded() {
68 | return dateAdded;
69 | }
70 |
71 | public String getDescription() {
72 | return description;
73 | }
74 |
75 | @JsonInclude(JsonInclude.Include.NON_NULL)
76 | public List getMetricDefinitions() {
77 | return metricDefinitions;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/resources/db/migration/V1_1_0__init_spring_batch.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE public.BATCH_JOB_INSTANCE (
2 | JOB_INSTANCE_ID BIGINT NOT NULL PRIMARY KEY ,
3 | VERSION BIGINT ,
4 | JOB_NAME VARCHAR(100) NOT NULL,
5 | JOB_KEY VARCHAR(32) NOT NULL,
6 | constraint JOB_INST_UN unique (JOB_NAME, JOB_KEY)
7 | ) ;
8 |
9 | CREATE TABLE public.BATCH_JOB_EXECUTION (
10 | JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY ,
11 | VERSION BIGINT ,
12 | JOB_INSTANCE_ID BIGINT NOT NULL,
13 | CREATE_TIME TIMESTAMP NOT NULL,
14 | START_TIME TIMESTAMP DEFAULT NULL ,
15 | END_TIME TIMESTAMP DEFAULT NULL ,
16 | STATUS VARCHAR(10) ,
17 | EXIT_CODE VARCHAR(2500) ,
18 | EXIT_MESSAGE VARCHAR(2500) ,
19 | LAST_UPDATED TIMESTAMP,
20 | JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL,
21 | constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID)
22 | references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)
23 | ) ;
24 |
25 | CREATE TABLE public.BATCH_JOB_EXECUTION_PARAMS (
26 | JOB_EXECUTION_ID BIGINT NOT NULL ,
27 | TYPE_CD VARCHAR(6) NOT NULL ,
28 | KEY_NAME VARCHAR(100) NOT NULL ,
29 | STRING_VAL VARCHAR(250) ,
30 | DATE_VAL TIMESTAMP DEFAULT NULL ,
31 | LONG_VAL BIGINT ,
32 | DOUBLE_VAL DOUBLE PRECISION ,
33 | IDENTIFYING CHAR(1) NOT NULL ,
34 | constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
35 | references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
36 | ) ;
37 |
38 | CREATE TABLE public.BATCH_STEP_EXECUTION (
39 | STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY ,
40 | VERSION BIGINT NOT NULL,
41 | STEP_NAME VARCHAR(100) NOT NULL,
42 | JOB_EXECUTION_ID BIGINT NOT NULL,
43 | START_TIME TIMESTAMP NOT NULL ,
44 | END_TIME TIMESTAMP DEFAULT NULL ,
45 | STATUS VARCHAR(10) ,
46 | COMMIT_COUNT BIGINT ,
47 | READ_COUNT BIGINT ,
48 | FILTER_COUNT BIGINT ,
49 | WRITE_COUNT BIGINT ,
50 | READ_SKIP_COUNT BIGINT ,
51 | WRITE_SKIP_COUNT BIGINT ,
52 | PROCESS_SKIP_COUNT BIGINT ,
53 | ROLLBACK_COUNT BIGINT ,
54 | EXIT_CODE VARCHAR(2500) ,
55 | EXIT_MESSAGE VARCHAR(2500) ,
56 | LAST_UPDATED TIMESTAMP,
57 | constraint JOB_EXEC_STEP_FK foreign key (JOB_EXECUTION_ID)
58 | references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
59 | ) ;
60 |
61 | CREATE TABLE public.BATCH_STEP_EXECUTION_CONTEXT (
62 | STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY,
63 | SHORT_CONTEXT VARCHAR(2500) NOT NULL,
64 | SERIALIZED_CONTEXT TEXT ,
65 | constraint STEP_EXEC_CTX_FK foreign key (STEP_EXECUTION_ID)
66 | references BATCH_STEP_EXECUTION(STEP_EXECUTION_ID)
67 | ) ;
68 |
69 | CREATE TABLE public.BATCH_JOB_EXECUTION_CONTEXT (
70 | JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY,
71 | SHORT_CONTEXT VARCHAR(2500) NOT NULL,
72 | SERIALIZED_CONTEXT TEXT ,
73 | constraint JOB_EXEC_CTX_FK foreign key (JOB_EXECUTION_ID)
74 | references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
75 | ) ;
76 |
77 | CREATE SEQUENCE BATCH_STEP_EXECUTION_SEQ MAXVALUE 9223372036854775807 NO CYCLE;
78 | CREATE SEQUENCE BATCH_JOB_EXECUTION_SEQ MAXVALUE 9223372036854775807 NO CYCLE;
79 | CREATE SEQUENCE BATCH_JOB_SEQ MAXVALUE 9223372036854775807 NO CYCLE;
80 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/ServerDefinitionModel.java:
--------------------------------------------------------------------------------
1 | package com.bompotis.netcheck.api.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 | import com.fasterxml.jackson.annotation.JsonProperty;
5 | import org.springframework.hateoas.RepresentationModel;
6 |
7 | import jakarta.validation.constraints.NotNull;
8 |
9 | /**
10 | * Created by Kyriakos Bompotis on 9/9/20.
11 | */
12 | public class ServerDefinitionModel extends RepresentationModel {
13 |
14 | @NotNull(message = "label is mandatory")
15 | private String label;
16 |
17 | @NotNull(message = "fieldName is mandatory")
18 | private String fieldName;
19 |
20 | private String suffix;
21 |
22 | @NotNull(message = "valueType is mandatory")
23 | private String valueType;
24 |
25 | @NotNull(message = "metricKind is mandatory")
26 | private String metricKind;
27 |
28 | private String extendedType;
29 |
30 | private String minThreshold;
31 |
32 | private String maxThreshold;
33 |
34 | private Boolean notify;
35 |
36 | public ServerDefinitionModel() {}
37 |
38 | public ServerDefinitionModel(@JsonProperty("label") String label,
39 | @JsonProperty("fieldName") String fieldName,
40 | @JsonProperty("suffix") String suffix,
41 | @JsonProperty("valueType") String valueType,
42 | @JsonProperty("metricKind") String metricKind,
43 | @JsonProperty("extendedType") String extendedType,
44 | @JsonProperty("minThreshold") String minThreshold,
45 | @JsonProperty("maxThreshold") String maxThreshold,
46 | @JsonProperty("notify") Boolean notify) {
47 | this.label = label;
48 | this.fieldName = fieldName;
49 | this.suffix = suffix;
50 | this.valueType = valueType;
51 | this.metricKind = metricKind;
52 | this.extendedType = extendedType;
53 | this.minThreshold = minThreshold;
54 | this.maxThreshold = maxThreshold;
55 | this.notify = notify;
56 | }
57 |
58 | public String getLabel() {
59 | return label;
60 | }
61 |
62 | public String getFieldName() {
63 | return fieldName;
64 | }
65 |
66 | @JsonInclude(JsonInclude.Include.NON_NULL)
67 | public String getSuffix() {
68 | return suffix;
69 | }
70 |
71 | public String getValueType() {
72 | return valueType;
73 | }
74 |
75 | public String getMetricKind() {
76 | return metricKind;
77 | }
78 |
79 | @JsonInclude(JsonInclude.Include.NON_NULL)
80 | public String getExtendedType() {
81 | return extendedType;
82 | }
83 |
84 | @JsonInclude(JsonInclude.Include.NON_NULL)
85 | public String getMinThreshold() {
86 | return minThreshold;
87 | }
88 |
89 | @JsonInclude(JsonInclude.Include.NON_NULL)
90 | public String getMaxThreshold() {
91 | return maxThreshold;
92 | }
93 |
94 | public Boolean getNotify() {
95 | return notify;
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/data/entity/AbstractTimestampablePersistable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.data.entity;
19 |
20 | import org.hibernate.annotations.GenericGenerator;
21 | import org.springframework.data.annotation.CreatedDate;
22 | import org.springframework.data.annotation.LastModifiedDate;
23 | import org.springframework.data.annotation.Transient;
24 | import org.springframework.data.domain.Persistable;
25 |
26 | import jakarta.persistence.MappedSuperclass;
27 | import jakarta.persistence.Id;
28 | import jakarta.persistence.GeneratedValue;
29 | import jakarta.persistence.Column;
30 | import jakarta.persistence.PrePersist;
31 | import jakarta.persistence.PreUpdate;
32 | import jakarta.persistence.PreRemove;
33 | import java.io.Serializable;
34 | import java.util.Date;
35 |
36 | /**
37 | * Created by Kyriakos Bompotis on 16/6/20.
38 | */
39 | @MappedSuperclass
40 | public abstract class AbstractTimestampablePersistable implements Persistable {
41 |
42 | @Id
43 | @GeneratedValue(generator="uuid")
44 | @GenericGenerator(name="uuid", strategy = "uuid2")
45 | @Column(name = "id")
46 | protected K id;
47 |
48 | @CreatedDate
49 | @Column(name = "created_at")
50 | protected Date createdAt;
51 |
52 | @LastModifiedDate
53 | @Column(name = "updated_at")
54 | private Date updatedAt;
55 |
56 | protected AbstractTimestampablePersistable() {}
57 |
58 | public K getId() {
59 | return this.id;
60 | }
61 |
62 | @Transient
63 | public boolean isNew() {
64 | return null == this.getId();
65 | }
66 |
67 | public Date getCreatedAt() {
68 | return null == createdAt ? null : createdAt;
69 | }
70 |
71 | public Date getUpdatedAt() {
72 | return updatedAt;
73 | }
74 |
75 | @PrePersist
76 | protected void prePersist() {
77 | if (this.createdAt == null) createdAt = new Date();
78 | if (this.updatedAt == null) updatedAt = new Date();
79 | }
80 |
81 | @PreUpdate
82 | protected void preUpdate() {
83 | this.updatedAt = new Date();
84 | }
85 |
86 | @PreRemove
87 | protected void preRemove() {
88 | this.updatedAt = new Date();
89 | }
90 |
91 | public String toString() {
92 | return String.format("Entity of type %s with id: %s", this.getClass().getName(), this.getId());
93 | }
94 | }
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/controller/AbstractStreamController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.controller;
19 |
20 | import org.slf4j.Logger;
21 | import org.slf4j.LoggerFactory;
22 | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
23 |
24 | import java.io.IOException;
25 | import java.util.ArrayList;
26 | import java.util.List;
27 | import java.util.concurrent.CopyOnWriteArrayList;
28 |
29 | /**
30 | * Created by Kyriakos Bompotis on 26/8/20.
31 | */
32 | public abstract class AbstractStreamController {
33 | private static final Logger logger = LoggerFactory.getLogger(AbstractStreamController.class);
34 |
35 | private final List emitters = new CopyOnWriteArrayList<>();
36 |
37 | protected SseEmitter addSseEmitter() {
38 | return addSseEmitter(new SseEmitter(0L));
39 | }
40 |
41 | protected SseEmitter addSseEmitter(SseEmitter emitter) {
42 | this.emitters.add(emitter);
43 |
44 | emitter.onCompletion(() -> {
45 | logger.info("Emitter completed: {}", emitter);
46 | this.emitters.remove(emitter);
47 | });
48 | emitter.onTimeout(() -> {
49 | logger.info("Emitter timed out: {}", emitter);
50 | emitter.complete();
51 | this.emitters.remove(emitter);
52 | });
53 |
54 | return emitter;
55 | }
56 |
57 | protected void sendToSseEmitter(SseEmitter.SseEventBuilder builder) {
58 | send(emitter -> emitter.send(builder));
59 | }
60 |
61 | protected void send(SseEmitterConsumer consumer) {
62 | List failedEmitters = new ArrayList<>();
63 |
64 | this.emitters.forEach(emitter -> {
65 | try {
66 | consumer.accept(emitter);
67 | } catch (IOException e) {
68 | emitter.completeWithError(e);
69 | failedEmitters.add(emitter);
70 | logger.error("Emitter failed: {} - {}", emitter, e.getMessage());
71 | } catch (Exception e) {
72 | emitter.completeWithError(e);
73 | failedEmitters.add(emitter);
74 | logger.error("Emitter failed: {}", emitter, e);
75 | }
76 | });
77 |
78 | this.emitters.removeAll(failedEmitters);
79 | }
80 |
81 | @FunctionalInterface
82 | protected interface SseEmitterConsumer {
83 | void accept(T t) throws IOException;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/CertificateModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model;
19 |
20 | import com.fasterxml.jackson.annotation.JsonProperty;
21 | import org.springframework.hateoas.RepresentationModel;
22 | import org.springframework.hateoas.server.core.Relation;
23 |
24 | import javax.naming.InvalidNameException;
25 | import javax.naming.ldap.LdapName;
26 | import javax.naming.ldap.Rdn;
27 | import java.util.Date;
28 | import java.util.HashMap;
29 | import java.util.Map;
30 | import java.util.stream.Collectors;
31 |
32 | /**
33 | * Created by Kyriakos Bompotis on 11/6/20.
34 | */
35 | @Relation(collectionRelation = "certificates", itemRelation = "certificate")
36 | public class CertificateModel extends RepresentationModel {
37 | private final String issuedBy;
38 | private final String issuedFor;
39 | private final Date notBefore;
40 | private final Date notAfter;
41 | private final Boolean isValid;
42 | private final Boolean expired;
43 |
44 | public CertificateModel(
45 | @JsonProperty("issuedBy") String issuedBy,
46 | @JsonProperty("issuedFor") String issuedFor,
47 | @JsonProperty("notBefore") Date notBefore,
48 | @JsonProperty("notAfter") Date notAfter,
49 | @JsonProperty("isValid") Boolean isValid,
50 | @JsonProperty("expired") Boolean expired) {
51 | this.issuedBy = issuedBy;
52 | this.issuedFor = issuedFor;
53 | this.notBefore = notBefore;
54 | this.notAfter = notAfter;
55 | this.isValid = isValid;
56 | this.expired = expired;
57 | }
58 |
59 | public Map getIssuedBy() throws InvalidNameException {
60 | return ldapNameToMap(issuedBy);
61 | }
62 |
63 | public Map getIssuedFor() throws InvalidNameException {
64 | return ldapNameToMap(issuedFor);
65 | }
66 |
67 | private Map ldapNameToMap(String ldapName) throws InvalidNameException {
68 | return new LdapName(ldapName)
69 | .getRdns()
70 | .stream()
71 | .collect(Collectors.toMap(Rdn::getType, Rdn::getValue, (a, b) -> b, HashMap::new));
72 | }
73 |
74 | public Date getNotBefore() {
75 | return notBefore;
76 | }
77 |
78 | public Date getNotAfter() {
79 | return notAfter;
80 | }
81 |
82 | public Boolean getValid() {
83 | return isValid;
84 | }
85 |
86 | public Boolean getExpired() {
87 | return expired;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/assembler/AbstractUpdateDtoAssembler.java:
--------------------------------------------------------------------------------
1 | package com.bompotis.netcheck.api.model.assembler;
2 |
3 | import com.bompotis.netcheck.api.model.PatchOperation;
4 | import com.bompotis.netcheck.service.dto.Operation;
5 | import com.bompotis.netcheck.service.dto.PatchDtoBuilder;
6 |
7 | import java.util.List;
8 | import java.util.Map;
9 | import java.util.Optional;
10 | import java.util.Set;
11 | import java.util.concurrent.atomic.AtomicReference;
12 |
13 | /**
14 | * Created by Kyriakos Bompotis on 7/9/20.
15 | */
16 | public interface AbstractUpdateDtoAssembler > {
17 |
18 | Map getOperationsToActionMap();
19 |
20 | Set getValidFields();
21 |
22 | Set getRequiredFieldsForPath();
23 |
24 | B getDtoBuilder();
25 |
26 | default T validateObject(T object, String type) {
27 | var atomicObject = new AtomicReference();
28 | Optional.ofNullable(object).ifPresentOrElse(
29 | atomicObject::set,
30 | () -> {
31 | throw new IllegalArgumentException("Property " + type + " cannot be empty or null");
32 | }
33 | );
34 | return atomicObject.get();
35 | }
36 |
37 | default T validateValue(T object, Operation.Action action) {
38 | var errorMessage = "Property `value` cannot be empty or null when adding or updating a field";
39 | return action.equals(Operation.Action.REMOVE) ?
40 | object :
41 | validateNonEmpty(object, errorMessage);
42 | }
43 |
44 | default T validatePath(T object, String field) {
45 | var errorMessage = "Property `path` cannot be empty or null when operating on a " + field;
46 | return getRequiredFieldsForPath().contains(field) ?
47 | validateNonEmpty(object, errorMessage) :
48 | object;
49 | }
50 |
51 | default T validateNonEmpty(T object, String message) {
52 | var atomicObject = new AtomicReference();
53 | Optional.ofNullable(object).ifPresentOrElse(
54 | atomicObject::set,
55 | () -> {
56 | throw new IllegalArgumentException(message);
57 | }
58 | );
59 | return atomicObject.get();
60 | }
61 |
62 | default D toDto(List patchOperations) {
63 | var dto = getDtoBuilder();
64 | for (var patchOperation : patchOperations) {
65 | var field = validateObject(patchOperation.field(), "field");
66 | var path = validatePath(patchOperation.path(), field);
67 | var op = validateObject(patchOperation.op(), "op");
68 | if (!getOperationsToActionMap().containsKey(op)) {
69 | throw new IllegalArgumentException("Invalid value for property `op`: " + op);
70 | }
71 | var action = getOperationsToActionMap().get(op);
72 | var value = validateValue(patchOperation.value(), action);
73 | if (!getValidFields().contains(field)) {
74 | throw new IllegalArgumentException("Invalid value for property `field`: " + field);
75 | }
76 | dto.addOperation(new Operation(field, action, value, path));
77 | }
78 | return dto.build();
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/DomainResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model;
19 |
20 | import com.fasterxml.jackson.annotation.JsonCreator;
21 | import com.fasterxml.jackson.annotation.JsonInclude;
22 | import com.fasterxml.jackson.annotation.JsonProperty;
23 | import org.springframework.hateoas.RepresentationModel;
24 | import org.springframework.hateoas.server.core.Relation;
25 |
26 | import java.util.Date;
27 | import java.util.Map;
28 |
29 | /**
30 | * Created by Kyriakos Bompotis on 9/6/20.
31 | */
32 | @Relation(collectionRelation = "domains", itemRelation = "domain")
33 | public class DomainResponse extends RepresentationModel {
34 | private final String domain;
35 |
36 | private final DomainCheckModel lastDomainCheck;
37 |
38 | private final Integer checkFrequencyMinutes;
39 |
40 | private final Date dateAdded;
41 |
42 | private final String endpoint;
43 |
44 | private final Map headers;
45 |
46 | private final Integer timeoutMs;
47 |
48 | @JsonCreator
49 | public DomainResponse(@JsonProperty("domain") String domain,
50 | @JsonProperty("lastDomainCheck") DomainCheckModel lastDomainCheck,
51 | @JsonProperty("dateAdded") Date dateAdded,
52 | @JsonProperty("checkFrequencyMinutes") Integer checkFrequencyMinutes,
53 | @JsonProperty("endpoint") String endpoint,
54 | @JsonProperty("headers") Map headers,
55 | @JsonProperty("timeoutMs") Integer timeoutMs) {
56 | this.domain = domain;
57 | this.lastDomainCheck = lastDomainCheck;
58 | this.dateAdded = dateAdded;
59 | this.checkFrequencyMinutes = checkFrequencyMinutes;
60 | this.endpoint = endpoint;
61 | this.headers = headers;
62 | this.timeoutMs = timeoutMs;
63 | }
64 |
65 | public String getDomain() {
66 | return domain;
67 | }
68 |
69 | @JsonInclude(JsonInclude.Include.NON_NULL)
70 | public DomainCheckModel getLastChecks() {
71 | return lastDomainCheck;
72 | }
73 |
74 | public Date getDateAdded() {
75 | return dateAdded;
76 | }
77 |
78 | public Integer getCheckFrequencyMinutes() {
79 | return checkFrequencyMinutes;
80 | }
81 |
82 | public String getEndpoint() {
83 | return endpoint;
84 | }
85 |
86 | public Map getHeaders() {
87 | return headers;
88 | }
89 |
90 | public Integer getTimeoutMs() {
91 | return timeoutMs;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/dto/RequestOptionsDto.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.service.dto;
19 |
20 | import org.springframework.data.domain.PageRequest;
21 | import org.springframework.data.domain.Sort;
22 |
23 | import java.util.Optional;
24 |
25 | /**
26 | * Created by Kyriakos Bompotis on 7/9/20.
27 | */
28 | public class RequestOptionsDto {
29 | private final Integer page;
30 | private final Integer size;
31 | private final String filter;
32 | private final String sortBy;
33 | private final boolean desc;
34 |
35 | public Boolean getDesc() {
36 | return desc;
37 | }
38 |
39 | public String getSortBy() {
40 | return sortBy;
41 | }
42 |
43 | public String getFilter() {
44 | return filter;
45 | }
46 |
47 | public Integer getSize() {
48 | return size;
49 | }
50 |
51 | public Integer getPage() {
52 | return page;
53 | }
54 |
55 | public PageRequest getPageRequest() {
56 | var sort = desc ? Sort.by(sortBy).descending() : Sort.by(sortBy).ascending();
57 | return PageRequest.of(page, size, sort);
58 | }
59 |
60 | public static class Builder implements DtoBuilder{
61 | private Integer page;
62 | private Integer size;
63 | private String filter;
64 | private String sortBy;
65 | private boolean desc;
66 |
67 | public Builder page(Integer page) {
68 | this.page = Optional.ofNullable(page).orElse(0);
69 | return this;
70 | }
71 |
72 | public Builder size(Integer size) {
73 | this.size = Optional.ofNullable(size).orElse(10);
74 | return this;
75 | }
76 |
77 | public Builder filter(String filter) {
78 | this.filter = Optional.ofNullable(filter).orElse("");
79 | return this;
80 | }
81 |
82 | public Builder sortBy(String sortBy) {
83 | this.sortBy = Optional.ofNullable(sortBy).orElse("createdAt");
84 | return this;
85 | }
86 |
87 | public Builder desc(Boolean desc) {
88 | this.desc = Optional.ofNullable(desc).orElse(true);
89 | return this;
90 | }
91 |
92 | public RequestOptionsDto build() {
93 | return new RequestOptionsDto(this);
94 | }
95 | }
96 |
97 | private RequestOptionsDto(Builder b) {
98 | this.page = b.page;
99 | this.size = b.size;
100 | this.filter = b.filter;
101 | this.sortBy = b.sortBy;
102 | this.desc = b.desc;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/MetricModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model;
19 |
20 | import com.fasterxml.jackson.annotation.JsonCreator;
21 | import com.fasterxml.jackson.annotation.JsonProperty;
22 | import org.springframework.hateoas.RepresentationModel;
23 | import org.springframework.hateoas.server.core.Relation;
24 |
25 | import java.util.Date;
26 |
27 | /**
28 | * Created by Kyriakos Bompotis on 22/6/20.
29 | */
30 | @Relation(collectionRelation = "metrics", itemRelation = "metric")
31 | public class MetricModel extends RepresentationModel {
32 | private final Date metricPeriodStart;
33 | private final Date metricPeriodEnd;
34 | private final Integer totalChecks;
35 | private final Integer successfulChecks;
36 | private final Long averageResponseTime;
37 | private final Long maxResponseTime;
38 | private final Long minResponseTime;
39 | private final String protocol;
40 |
41 | @JsonCreator
42 | public MetricModel(
43 | @JsonProperty("metricPeriodStart") Date metricPeriodStart,
44 | @JsonProperty("metricPeriodEnd") Date metricPeriodEnd,
45 | @JsonProperty("totalChecks") Integer totalChecks,
46 | @JsonProperty("successfulChecks") Integer successfulChecks,
47 | @JsonProperty("averageResponseTime") Long averageResponseTime,
48 | @JsonProperty("maxResponseTime") Long maxResponseTime,
49 | @JsonProperty("minResponseTime") Long minResponseTime,
50 | @JsonProperty("protocol") String protocol) {
51 | this.metricPeriodStart = metricPeriodStart;
52 | this.metricPeriodEnd = metricPeriodEnd;
53 | this.totalChecks = totalChecks;
54 | this.successfulChecks = successfulChecks;
55 | this.averageResponseTime = averageResponseTime;
56 | this.maxResponseTime = maxResponseTime;
57 | this.minResponseTime = minResponseTime;
58 | this.protocol = protocol;
59 | }
60 |
61 | public Date getMetricPeriodStart() {
62 | return metricPeriodStart;
63 | }
64 |
65 | public Date getMetricPeriodEnd() {
66 | return metricPeriodEnd;
67 | }
68 |
69 | public Integer getTotalChecks() {
70 | return totalChecks;
71 | }
72 |
73 | public Integer getSuccessfulChecks() {
74 | return successfulChecks;
75 | }
76 |
77 | public Long getAverageResponseTime() {
78 | return averageResponseTime;
79 | }
80 |
81 | public Long getMaxResponseTime() {
82 | return maxResponseTime;
83 | }
84 |
85 | public Long getMinResponseTime() {
86 | return minResponseTime;
87 | }
88 |
89 | public String getProtocol() {
90 | return protocol;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/writer/NotificationItemWriter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.writer;
19 |
20 | import com.bompotis.netcheck.data.entity.DomainCheckEntity;
21 | import com.bompotis.netcheck.scheduler.batch.notification.NotificationDto;
22 | import com.bompotis.netcheck.scheduler.batch.notification.NotificationService;
23 | import com.bompotis.netcheck.scheduler.batch.processor.DomainMetricProcessor;
24 | import org.slf4j.Logger;
25 | import org.slf4j.LoggerFactory;
26 | import org.springframework.batch.item.Chunk;
27 | import org.springframework.batch.item.ItemWriter;
28 | import org.springframework.beans.factory.annotation.Autowired;
29 | import org.springframework.lang.NonNull;
30 | import org.springframework.stereotype.Component;
31 |
32 | import java.util.ArrayList;
33 | import java.util.Collections;
34 | import java.util.List;
35 |
36 | /**
37 | * Created by Kyriakos Bompotis on 1/7/20.
38 | */
39 | @Component
40 | public class NotificationItemWriter extends AbstractNotificationWriter implements ItemWriter {
41 |
42 | private static final Logger log = LoggerFactory.getLogger(DomainMetricProcessor.class);
43 |
44 | private final List notificationServices;
45 |
46 | @Autowired
47 | public NotificationItemWriter(List notificationServices) {
48 | var enabledNotificationServices = new ArrayList();
49 | for (var notificationService : notificationServices) {
50 | log.info("Notification provider: {} - Enabled: {}", notificationService.getClass(), notificationService.isEnabled());
51 | if (notificationService.isEnabled()) {
52 | enabledNotificationServices.add(notificationService);
53 | }
54 | }
55 | this.notificationServices = Collections.unmodifiableList(enabledNotificationServices);
56 | }
57 |
58 | public boolean isEnabled() {
59 | return !notificationServices.isEmpty();
60 | }
61 |
62 | private void send(List notifications) {
63 | notifications.forEach(this::send);
64 | }
65 |
66 | private void send(NotificationDto notification){
67 | for (NotificationService service : notificationServices) {
68 | try {
69 | service.notify(notification);
70 | } catch (Exception e) {
71 | log.error("Failure to send notification for service {}. Failed notification message: {}", service.getClass(), notification.getMessage(), e);
72 | }
73 | }
74 | }
75 |
76 | @Override
77 | public void write(@NonNull Chunk extends DomainCheckEntity> chunk) {
78 | var notifications = generateNotifications(chunk);
79 | send(notifications);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/controller/NotificationTestController.java:
--------------------------------------------------------------------------------
1 | package com.bompotis.netcheck.api.controller;
2 |
3 | import com.bompotis.netcheck.api.model.DomainCheckModel;
4 | import com.bompotis.netcheck.scheduler.batch.notification.NotificationDto;
5 | import com.bompotis.netcheck.scheduler.batch.notification.NotificationService;
6 | import io.swagger.v3.oas.annotations.Operation;
7 | import io.swagger.v3.oas.annotations.media.Content;
8 | import io.swagger.v3.oas.annotations.responses.ApiResponse;
9 | import io.swagger.v3.oas.annotations.responses.ApiResponses;
10 | import io.swagger.v3.oas.annotations.tags.Tag;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.http.ResponseEntity;
13 | import org.springframework.web.bind.annotation.*;
14 |
15 | import java.util.ArrayList;
16 | import java.util.Date;
17 | import java.util.List;
18 | import java.util.Optional;
19 |
20 | import static org.springframework.http.ResponseEntity.*;
21 |
22 | @RestController
23 | @CrossOrigin(origins = {"${settings.cors.origin}"})
24 | @RequestMapping(value = "/api/v1/notification")
25 | @Tag(name = "Notification Test", description = "Operations for testing notification providers")
26 | public class NotificationTestController {
27 |
28 | private final List notificationServices;
29 |
30 | @Autowired
31 | public NotificationTestController(List notificationServices) {
32 | this.notificationServices = notificationServices;
33 | }
34 |
35 | @Operation(summary = "Get available notification services")
36 | @GetMapping(produces={"application/hal+json"})
37 | public ResponseEntity> getNotificationServices() {
38 | var services = new ArrayList<>(notificationServices.stream().map(NotificationService::name).toList());
39 | return ok(services);
40 | }
41 |
42 | @Operation(summary = "Send test notification to service")
43 | @ApiResponses(value = {
44 | @ApiResponse(responseCode = "200", description = "Test Notification successfully sent"),
45 | @ApiResponse(responseCode = "400", description = "Notification service is disabled", content = @Content),
46 | @ApiResponse(responseCode = "404", description = "Notification service not found", content = @Content)})
47 | @PostMapping(produces={"application/hal+json"}, path = "/{notificationServiceName}")
48 | public ResponseEntity sendTestNotificationTo(
49 | @PathVariable("notificationServiceName") String notificationServiceName
50 | ) throws Exception {
51 | Optional foundService = Optional.empty();
52 | for (var service: notificationServices) {
53 | if (service.name().equals(notificationServiceName)) {
54 | foundService = Optional.of(service);
55 | break;
56 | }
57 | }
58 | if (foundService.isEmpty()) {
59 | return notFound().build();
60 | }
61 | var notificationService = foundService.get();
62 | if (!notificationService.isEnabled()) {
63 | return badRequest().build();
64 | }
65 | notificationService.notify(new NotificationDto.Builder()
66 | .hostname("test")
67 | .connectionAccepted(true)
68 | .dnsResolves(true)
69 | .ipAddress("0.0.0.0")
70 | .redirectUri("")
71 | .responseTimeNs(0L)
72 | .statusCode(200)
73 | .timeCheckedOn(new Date())
74 | .type(NotificationDto.Type.HTTP)
75 | .build());
76 | return ok().build();
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/dto/DomainCheckDto.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.service.dto;
19 |
20 | import java.io.IOException;
21 | import java.security.KeyManagementException;
22 | import java.security.NoSuchAlgorithmException;
23 |
24 | /**
25 | * Created by Kyriakos Bompotis on 10/6/20.
26 | */
27 | public class DomainCheckDto {
28 | private final HttpCheckDto httpCheckDto;
29 | private final HttpsCheckDto httpsCheckDto;
30 | private final Boolean monitored;
31 | private final String domain;
32 | private final String id;
33 |
34 | public HttpCheckDto getHttpCheckDto() {
35 | return httpCheckDto;
36 | }
37 |
38 | public HttpsCheckDto getHttpsCheckDto() {
39 | return httpsCheckDto;
40 | }
41 |
42 | public String getDomain() {
43 | return domain;
44 | }
45 |
46 | public String getId() {
47 | return id;
48 | }
49 |
50 | public Boolean getMonitored() {
51 | return monitored;
52 | }
53 |
54 | public static class Builder extends AbstractHttpChecker implements DtoBuilder{
55 | private HttpCheckDto httpCheckDto;
56 | private HttpsCheckDto httpsCheckDto;
57 | private final String domain;
58 | private Boolean monitored;
59 | private String id;
60 |
61 | public Builder(String domain) {
62 | this.domain = domain;
63 | }
64 |
65 | public Builder monitored(Boolean monitored) {
66 | this.monitored = monitored;
67 | return this;
68 | }
69 |
70 | public Builder httpCheck(HttpCheckDto httpCheckDto) {
71 | this.httpCheckDto = httpCheckDto;
72 | return this;
73 | }
74 |
75 | public Builder httpsCheckDto(HttpsCheckDto httpsCheckDto) {
76 | this.httpsCheckDto = httpsCheckDto;
77 | return this;
78 | }
79 |
80 | public Builder withCurrentHttpCheck(DomainCheckConfigDto config, int port) {
81 | this.httpCheckDto = checkHttp(config, port);
82 | return this;
83 | }
84 |
85 | public Builder withCurrentHttpsCheck(DomainCheckConfigDto config, int port) {
86 | this.httpsCheckDto = checkHttps(config, port);
87 | return this;
88 | }
89 |
90 | public Builder id(String id) {
91 | this.id = id;
92 | return this;
93 | }
94 |
95 | public DomainCheckDto build() {
96 | return new DomainCheckDto(this);
97 | }
98 | }
99 |
100 | private DomainCheckDto(Builder b) {
101 | this.httpCheckDto = b.httpCheckDto;
102 | this.domain = b.domain;
103 | this.httpsCheckDto = b.httpsCheckDto;
104 | this.monitored = b.monitored;
105 | this.id = b.id;
106 | }
107 | }
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/StateModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model;
19 |
20 | import com.fasterxml.jackson.annotation.JsonCreator;
21 | import com.fasterxml.jackson.annotation.JsonInclude;
22 | import com.fasterxml.jackson.annotation.JsonProperty;
23 | import org.springframework.hateoas.RepresentationModel;
24 | import org.springframework.hateoas.server.core.Relation;
25 |
26 | import java.util.Date;
27 |
28 | /**
29 | * Created by Kyriakos Bompotis on 24/6/20.
30 | */
31 | @Relation(collectionRelation = "states", itemRelation = "state")
32 | public class StateModel extends RepresentationModel {
33 | private final Boolean isUp;
34 | private final Integer statusCode;
35 | private final Date timeCheckedOn;
36 | private final Boolean dnsResolves;
37 | private final String hostname;
38 | private final String protocol;
39 | private final String redirectUri;
40 | private final String reason;
41 | private final Long durationSeconds;
42 |
43 | @JsonCreator
44 | public StateModel(
45 | @JsonProperty("hostname") String hostname,
46 | @JsonProperty("statusCode") Integer statusCode,
47 | @JsonProperty("checkedOn") Date timeCheckedOn,
48 | @JsonProperty("reason") String reason,
49 | @JsonProperty("dnsResolves") Boolean dnsResolves,
50 | @JsonProperty("protocol") String protocol,
51 | @JsonProperty("redirectUri") String redirectUri,
52 | @JsonProperty("isUp") Boolean isUp,
53 | @JsonProperty("durationSeconds") Long durationSeconds) {
54 | this.isUp = isUp;
55 | this.hostname = hostname;
56 | this.statusCode = statusCode;
57 | this.timeCheckedOn = timeCheckedOn;
58 | this.reason = reason;
59 | this.dnsResolves = dnsResolves;
60 | this.protocol = protocol;
61 | this.redirectUri = redirectUri;
62 | this.durationSeconds = durationSeconds;
63 | }
64 |
65 | public Integer getStatusCode() {
66 | return statusCode;
67 | }
68 |
69 | public Boolean getDnsResolves() {
70 | return dnsResolves;
71 | }
72 |
73 | public Date getTimeCheckedOn() {
74 | return timeCheckedOn;
75 | }
76 |
77 | public String getHostname() {
78 | return hostname;
79 | }
80 |
81 | public String getProtocol() {
82 | return protocol;
83 | }
84 |
85 | @JsonInclude(JsonInclude.Include.NON_NULL)
86 | public String getRedirectUri() {
87 | return redirectUri;
88 | }
89 |
90 | public Boolean getUp() {
91 | return isUp;
92 | }
93 |
94 | public String getReason() {
95 | return reason;
96 | }
97 |
98 | public Long getDurationSeconds() {
99 | return durationSeconds;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/dto/ServerDto.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.service.dto;
19 |
20 | import java.util.Date;
21 | import java.util.List;
22 |
23 | /**
24 | * Created by Kyriakos Bompotis on 4/9/20.
25 | */
26 | public class ServerDto {
27 |
28 | private final String serverId;
29 | private final String serverName;
30 | private final String password;
31 | private final Date dateAdded;
32 | private final String description;
33 | private final List serverDefinitionDtos;
34 |
35 | public String getServerId() {
36 | return serverId;
37 | }
38 |
39 | public String getServerName() {
40 | return serverName;
41 | }
42 |
43 | public String getPassword() {
44 | return password;
45 | }
46 |
47 | public Date getDateAdded() {
48 | return dateAdded;
49 | }
50 |
51 | public String getDescription() {
52 | return description;
53 | }
54 |
55 | public List getServerDefinitionDtos() {
56 | return serverDefinitionDtos;
57 | }
58 |
59 | public static class Builder implements DtoBuilder {
60 | private String serverId;
61 | private String serverName;
62 | private String description;
63 | private String password;
64 | private Date dateAdded;
65 | private List serverDefinitionDtos = List.of();
66 |
67 | public Builder serverId(String serverId) {
68 | this.serverId = serverId;
69 | return this;
70 | }
71 |
72 | public Builder description(String description) {
73 | this.description = description;
74 | return this;
75 | }
76 |
77 | public Builder serverName(String serverName) {
78 | this.serverName = serverName;
79 | return this;
80 | }
81 |
82 | public Builder password(String password) {
83 | this.password = password;
84 | return this;
85 | }
86 |
87 | public Builder dateAdded(Date dateAdded) {
88 | this.dateAdded = dateAdded;
89 | return this;
90 | }
91 |
92 | public Builder serverDefinitionDtos(List serverDefinitionDtos) {
93 | this.serverDefinitionDtos = List.copyOf(serverDefinitionDtos);
94 | return this;
95 | }
96 |
97 | public ServerDto build() {
98 | return new ServerDto(this);
99 | }
100 | }
101 |
102 | private ServerDto(Builder b) {
103 | this.serverId = b.serverId;
104 | this.serverName = b.serverName;
105 | this.password = b.password;
106 | this.dateAdded = b.dateAdded;
107 | this.description = b.description;
108 | this.serverDefinitionDtos = b.serverDefinitionDtos;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/notification/WebhookService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.scheduler.batch.notification;
19 |
20 | import com.bompotis.netcheck.scheduler.batch.notification.config.WebhookConfig;
21 | import org.slf4j.Logger;
22 | import org.slf4j.LoggerFactory;
23 | import org.springframework.beans.factory.annotation.Autowired;
24 | import org.springframework.http.HttpHeaders;
25 | import org.springframework.http.MediaType;
26 | import org.springframework.stereotype.Service;
27 | import org.springframework.web.reactive.function.BodyInserters;
28 | import org.springframework.web.reactive.function.client.WebClient;
29 |
30 | import java.time.Duration;
31 | import java.util.Collections;
32 | import java.util.Objects;
33 | import java.util.Optional;
34 | import java.util.Set;
35 |
36 | /**
37 | * Created by Kyriakos Bompotis on 10/8/20.
38 | */
39 | @Service
40 | public class WebhookService implements NotificationService {
41 |
42 | private final WebhookConfig webhookConfig;
43 |
44 | private static final Logger log = LoggerFactory.getLogger(WebhookService.class);
45 |
46 | @Autowired
47 | public WebhookService(WebhookConfig webhookConfig) {
48 | this.webhookConfig = webhookConfig;
49 | }
50 |
51 | @Override
52 | public boolean isEnabled() {
53 | return Optional.ofNullable(webhookConfig.getEnabled()).orElse(false);
54 | }
55 |
56 | @Override
57 | public String name() {
58 | return "Webhook";
59 | }
60 |
61 | @Override
62 | public void notify(NotificationDto notification) {
63 | Set protocols = webhookConfig.getNotifyOnlyFor().isEmpty() ? Set.of("HTTP","HTTPS","CERTIFICATE") : Set.copyOf(webhookConfig.getNotifyOnlyFor());
64 | if (protocols.contains(notification.getType().name())) {
65 | log.info("Preparing client for domain {}", webhookConfig.getBaseUrl());
66 | var client = WebClient
67 | .builder()
68 | .baseUrl(webhookConfig.getBaseUrl())
69 | .defaultCookie("cookieKey", "cookieValue")
70 | .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
71 | .defaultUriVariables(Collections.singletonMap("url", webhookConfig.getBaseUrl()))
72 | .build();
73 | log.info("Sending notification to {}", webhookConfig.getEndpoint());
74 | var response = Objects.requireNonNull(client.post()
75 | .uri(webhookConfig.getEndpoint())
76 | .body(BodyInserters.fromValue(notification))
77 | .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
78 | .exchange()
79 | .block(Duration.ofSeconds(30)))
80 | .rawStatusCode();
81 | log.info("Webhook response code: {}", response);
82 | } else {
83 | log.info("Webhook notifications for type {} are disabled. Skipping!", notification.getType().name());
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/scheduler/batch/notification/client/PushoverRestClient.java:
--------------------------------------------------------------------------------
1 | package com.bompotis.netcheck.scheduler.batch.notification.client;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.http.HttpStatus;
6 | import org.springframework.http.HttpStatusCode;
7 | import org.springframework.http.MediaType;
8 | import org.springframework.util.LinkedMultiValueMap;
9 | import org.springframework.util.MultiValueMap;
10 | import org.springframework.web.reactive.function.BodyInserters;
11 | import org.springframework.web.reactive.function.client.WebClient;
12 | import reactor.core.publisher.Mono;
13 |
14 | public class PushoverRestClient {
15 |
16 | private record PushoverErrorResponse(HttpStatusCode statusCode) {}
17 |
18 | public static final String PUSH_MESSAGE_URL = "https://api.pushover.net/1/messages.json";
19 |
20 | public static final String REQUEST_ID_HEADER = "X-Request-Id";
21 |
22 | private static final Logger log = LoggerFactory.getLogger(PushoverRestClient.class);
23 |
24 | public void pushMessage(PushoverMessage msg) {
25 |
26 | final var post = WebClient.create().post().uri(PUSH_MESSAGE_URL)
27 | .contentType(MediaType.APPLICATION_FORM_URLENCODED);
28 |
29 | final var valueMap = new LinkedMultiValueMap();
30 |
31 | valueMap.add("token", msg.getApiToken());
32 | valueMap.add("user", msg.getUserId());
33 | if (msg.getHtmlMessage() != null && !msg.getHtmlMessage().trim().isEmpty()) {
34 | valueMap.add("message", msg.getHtmlMessage());
35 | } else {
36 | valueMap.add("message", msg.getMessage());
37 | }
38 |
39 | addPairIfNotNull(valueMap, "title", msg.getTitle());
40 |
41 | addPairIfNotNull(valueMap, "url", msg.getUrl());
42 | addPairIfNotNull(valueMap, "url_title", msg.getTitleForURL());
43 |
44 | addPairIfNotNull(valueMap, "device", msg.getDevice());
45 | addPairIfNotNull(valueMap, "timestamp", msg.getTimestamp());
46 | addPairIfNotNull(valueMap, "sound", msg.getSound());
47 |
48 | if (msg.getHtmlMessage() != null && !msg.getHtmlMessage().trim().isEmpty()) {
49 | addPairIfNotNull(valueMap, "html", "1");
50 | }
51 |
52 | if (!MessagePriority.NORMAL.equals(msg.getPriority())) {
53 | addPairIfNotNull(valueMap, "priority", msg.getPriority());
54 | }
55 |
56 | var ref = new Object() {
57 | String requestId;
58 | };
59 | post.body(BodyInserters.fromFormData(valueMap)).exchangeToMono(response -> {
60 | var statusCode = response.statusCode();
61 | if (statusCode.equals(HttpStatus.OK)) {
62 | ref.requestId = response.headers().header(REQUEST_ID_HEADER).get(0);
63 | return response.bodyToMono(PushoverResponse.class);
64 | }
65 | return Mono.just(new PushoverErrorResponse(statusCode));
66 | }).single().subscribe(result -> {
67 | if (result.getClass().equals(PushoverResponse.class)) {
68 | var r = (PushoverResponse) result;
69 | log.info("Pushover notification response: status {}, requestId {}.",r.status, ref.requestId);
70 | } else if (result.getClass().equals(PushoverErrorResponse.class)) {
71 | var r = (PushoverErrorResponse) result;
72 | log.error("Pushover request failed with status code {}.",r.statusCode.value());
73 | }
74 | });
75 | }
76 |
77 |
78 | private void addPairIfNotNull(MultiValueMap multiValueMap, String key, Object value) {
79 | if (value != null) {
80 | multiValueMap.add(key, value.toString());
81 | }
82 | }
83 |
84 | public static class PushoverResponse {
85 | int status;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/data/entity/ServerMetricEntity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.data.entity;
19 |
20 | import io.hypersistence.utils.hibernate.type.json.JsonBinaryType;
21 | import jakarta.persistence.*;
22 | import org.hibernate.annotations.Type;
23 | import org.springframework.lang.NonNull;
24 |
25 | import java.util.Date;
26 | import java.util.Map;
27 | import java.util.Objects;
28 |
29 | /**
30 | * Created by Kyriakos Bompotis on 5/9/20.
31 | */
32 | @Entity
33 | @Table(name = "server_metric", indexes = {
34 | @Index(name = "server_metrics__server_created_idx", columnList = "server_id, created_at")
35 | })
36 | public class ServerMetricEntity extends AbstractTimestampablePersistable{
37 |
38 | @NonNull
39 | @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
40 | @JoinColumn(name = "server_id")
41 | private ServerEntity serverEntity;
42 |
43 | @NonNull
44 | @Type(JsonBinaryType.class)
45 | @Column(columnDefinition = "jsonb", name = "metrics")
46 | private Map metrics;
47 |
48 | @NonNull
49 | @Column(name = "collected_at")
50 | private Date collectedAt;
51 |
52 | @NonNull
53 | public ServerEntity getServerEntity() {
54 | return serverEntity;
55 | }
56 |
57 | @NonNull
58 | public Map getMetrics() {
59 | return metrics;
60 | }
61 |
62 | @NonNull
63 | public Date getCollectedAt() {
64 | return collectedAt;
65 | }
66 |
67 | protected ServerMetricEntity() {}
68 |
69 | public static class Builder {
70 | private ServerEntity serverEntity;
71 | private Map metrics;
72 | private Date collectedAt;
73 |
74 | public Builder metrics(Map metrics) {
75 | this.metrics = metrics;
76 | return this;
77 | }
78 |
79 | public Builder serverEntity(ServerEntity serverEntity) {
80 | this.serverEntity = serverEntity;
81 | return this;
82 | }
83 |
84 | public Builder collectedAt(Date collectedAt) {
85 | this.collectedAt = collectedAt;
86 | return this;
87 | }
88 |
89 | public ServerMetricEntity build() {
90 | return new ServerMetricEntity(this);
91 | }
92 | }
93 |
94 | private ServerMetricEntity(Builder b) {
95 | this.metrics = b.metrics;
96 | this.serverEntity = b.serverEntity;
97 | this.collectedAt = b.collectedAt;
98 | }
99 |
100 |
101 | @Override
102 | public boolean equals(Object o) {
103 | if (this == o) return true;
104 | if (o == null || getClass() != o.getClass()) return false;
105 | ServerMetricEntity that = (ServerMetricEntity) o;
106 | return serverEntity.equals(that.serverEntity) &&
107 | metrics.equals(that.metrics);
108 | }
109 |
110 | @Override
111 | public int hashCode() {
112 | return Objects.hash(serverEntity, metrics);
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/service/dto/DomainsOptionsDto.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.service.dto;
19 |
20 | import org.springframework.data.domain.PageRequest;
21 | import org.springframework.data.domain.Sort;
22 |
23 | import java.util.Optional;
24 |
25 | /**
26 | * Created by Kyriakos Bompotis on 31/8/20.
27 | */
28 | public class DomainsOptionsDto {
29 | private final Integer page;
30 | private final Integer size;
31 | private final boolean showLastChecks;
32 | private final String filter;
33 | private final String sortBy;
34 | private final boolean desc;
35 |
36 | public Boolean getDesc() {
37 | return desc;
38 | }
39 |
40 | public String getSortBy() {
41 | return sortBy;
42 | }
43 |
44 | public String getFilter() {
45 | return filter;
46 | }
47 |
48 | public Boolean getShowLastChecks() {
49 | return showLastChecks;
50 | }
51 |
52 | public Integer getSize() {
53 | return size;
54 | }
55 |
56 | public Integer getPage() {
57 | return page;
58 | }
59 |
60 | public PageRequest getPageRequest() {
61 | var sort = desc ? Sort.by(sortBy).descending() : Sort.by(sortBy).ascending();
62 | return PageRequest.of(page, size, sort);
63 | }
64 |
65 | public static class Builder implements DtoBuilder{
66 | private Integer page;
67 | private Integer size;
68 | private boolean showLastChecks;
69 | private String filter;
70 | private String sortBy;
71 | private boolean desc;
72 |
73 | public Builder page(Integer page) {
74 | this.page = Optional.ofNullable(page).orElse(0);
75 | return this;
76 | }
77 |
78 | public Builder size(Integer size) {
79 | this.size = Optional.ofNullable(size).orElse(10);
80 | return this;
81 | }
82 |
83 | public Builder showLastChecks(Boolean showLastChecks) {
84 | this.showLastChecks = Optional.ofNullable(showLastChecks).orElse(true);
85 | return this;
86 | }
87 |
88 | public Builder filter(String filter) {
89 | this.filter = Optional.ofNullable(filter).orElse("");
90 | return this;
91 | }
92 |
93 | public Builder sortBy(String sortBy) {
94 | this.sortBy = Optional.ofNullable(sortBy).orElse("createdAt");
95 | return this;
96 | }
97 |
98 | public Builder desc(Boolean desc) {
99 | this.desc = Optional.ofNullable(desc).orElse(true);
100 | return this;
101 | }
102 |
103 | public DomainsOptionsDto build() {
104 | return new DomainsOptionsDto(this);
105 | }
106 | }
107 |
108 | private DomainsOptionsDto(Builder b) {
109 | this.page = b.page;
110 | this.size = b.size;
111 | this.showLastChecks = b.showLastChecks;
112 | this.filter = b.filter;
113 | this.sortBy = b.sortBy;
114 | this.desc = b.desc;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/HttpCheckModel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model;
19 |
20 | import com.fasterxml.jackson.annotation.JsonCreator;
21 | import com.fasterxml.jackson.annotation.JsonInclude;
22 | import com.fasterxml.jackson.annotation.JsonProperty;
23 | import org.springframework.hateoas.RepresentationModel;
24 | import org.springframework.hateoas.server.core.Relation;
25 |
26 | import java.util.Date;
27 |
28 | /**
29 | * Created by Kyriakos Bompotis on 15/6/20.
30 | */
31 | @Relation(collectionRelation = "checks", itemRelation = "check")
32 | public class HttpCheckModel extends RepresentationModel {
33 | private final Boolean isUp;
34 | private final Integer statusCode;
35 | private final Date timeCheckedOn;
36 | private final Boolean dnsResolves;
37 | private final String hostname;
38 | private final String ipAddress;
39 | private final Long responseTimeNs;
40 | private final String protocol;
41 | private final String redirectUri;
42 | private final String errorMessage;
43 |
44 | @JsonCreator
45 | public HttpCheckModel(
46 | @JsonProperty("hostname") String hostname,
47 | @JsonProperty("statusCode") Integer statusCode,
48 | @JsonProperty("checkedOn") Date timeCheckedOn,
49 | @JsonProperty("responseTimeNs") Long responseTimeNs,
50 | @JsonProperty("dnsResolves") Boolean dnsResolves,
51 | @JsonProperty("ipAddress") String ipAddress,
52 | @JsonProperty("protocol") String protocol,
53 | @JsonProperty("redirectUri") String redirectUri,
54 | @JsonProperty("up") Boolean isUp,
55 | @JsonProperty("errorMessage") String errorMessage) {
56 | this.isUp = isUp;
57 | this.hostname = hostname;
58 | this.statusCode = statusCode;
59 | this.timeCheckedOn = timeCheckedOn;
60 | this.responseTimeNs = responseTimeNs;
61 | this.dnsResolves = dnsResolves;
62 | this.ipAddress = ipAddress;
63 | this.protocol = protocol;
64 | this.redirectUri = redirectUri;
65 | this.errorMessage = errorMessage;
66 | }
67 |
68 | public Integer getStatusCode() {
69 | return statusCode;
70 | }
71 |
72 | public Boolean getDnsResolves() {
73 | return dnsResolves;
74 | }
75 |
76 | public Date getTimeCheckedOn() {
77 | return timeCheckedOn;
78 | }
79 |
80 | public String getHostname() {
81 | return hostname;
82 | }
83 |
84 | public Long getResponseTimeNs() {
85 | return responseTimeNs;
86 | }
87 |
88 | public String getIpAddress() {
89 | return ipAddress;
90 | }
91 |
92 | public String getProtocol() {
93 | return protocol;
94 | }
95 |
96 | @JsonInclude(JsonInclude.Include.NON_NULL)
97 | public String getRedirectUri() {
98 | return redirectUri;
99 | }
100 |
101 | public Boolean getUp() {
102 | return isUp;
103 | }
104 |
105 | public String getErrorMessage() {
106 | return errorMessage;
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/assembler/MetricModelAssembler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model.assembler;
19 |
20 | import com.bompotis.netcheck.api.controller.DomainsController;
21 | import com.bompotis.netcheck.api.model.MetricModel;
22 | import com.bompotis.netcheck.service.dto.MetricDto;
23 | import com.bompotis.netcheck.service.dto.PaginatedDto;
24 | import org.springframework.hateoas.CollectionModel;
25 | import org.springframework.hateoas.IanaLinkRelations;
26 | import org.springframework.hateoas.Link;
27 | import org.springframework.hateoas.PagedModel;
28 | import org.springframework.lang.NonNull;
29 |
30 | import java.util.ArrayList;
31 |
32 | import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
33 | import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
34 |
35 | /**
36 | * Created by Kyriakos Bompotis on 22/6/20.
37 | */
38 | public class MetricModelAssembler extends PaginatedRepresentationModelAssemblerSupport {
39 | public MetricModelAssembler() {
40 | super(DomainsController.class, MetricModel.class);
41 | }
42 |
43 | @NonNull
44 | @Override
45 | public MetricModel toModel(MetricDto entity) {
46 | return new MetricModel(
47 | entity.getMetricPeriodStart(),
48 | entity.getMetricPeriodEnd(),
49 | entity.getTotalChecks(),
50 | entity.getSuccessfulChecks(),
51 | entity.getAverageResponseTime(),
52 | entity.getMaxResponseTime(),
53 | entity.getMinResponseTime(),
54 | entity.getProtocol()
55 | );
56 | }
57 |
58 | public CollectionModel toCollectionModel(PaginatedDto paginatedMetricsDto, String domain, String protocol, String period) {
59 | final var metricModels = this.toCollectionModel(paginatedMetricsDto.getDtoList()).getContent();
60 | final var links = new ArrayList();
61 | links.add(linkTo(methodOn(DomainsController.class)
62 | .getDomainsMetrics(domain, protocol, period, paginatedMetricsDto.getNumber(), paginatedMetricsDto.getSize()))
63 | .withSelfRel()
64 | );
65 | if (isValidPage(paginatedMetricsDto.getNumber(),paginatedMetricsDto.getTotalPages())) {
66 | if (isNotLastPage(paginatedMetricsDto.getNumber(), paginatedMetricsDto.getTotalPages())) {
67 | links.add(linkTo(methodOn(DomainsController.class)
68 | .getDomainsMetrics(domain, protocol, period, paginatedMetricsDto.getNumber()+1, paginatedMetricsDto.getSize()))
69 | .withRel(IanaLinkRelations.NEXT)
70 | );
71 | }
72 | if (isNotFirstPage(paginatedMetricsDto.getNumber())) {
73 | links.add(linkTo(methodOn(DomainsController.class)
74 | .getDomainsMetrics(domain, protocol, period, paginatedMetricsDto.getNumber()-1, paginatedMetricsDto.getSize()))
75 | .withRel(IanaLinkRelations.PREVIOUS)
76 | );
77 | }
78 | }
79 | return PagedModel.of(
80 | metricModels,
81 | new PagedModel.PageMetadata(
82 | metricModels.size(),
83 | paginatedMetricsDto.getNumber(),
84 | paginatedMetricsDto.getTotalElements(),
85 | paginatedMetricsDto.getTotalPages()
86 | ),
87 | links
88 | );
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/model/assembler/StateModelAssembler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.model.assembler;
19 |
20 | import com.bompotis.netcheck.api.controller.DomainsController;
21 | import com.bompotis.netcheck.api.model.StateModel;
22 | import com.bompotis.netcheck.service.dto.PaginatedDto;
23 | import com.bompotis.netcheck.service.dto.StateDto;
24 | import org.springframework.hateoas.CollectionModel;
25 | import org.springframework.hateoas.IanaLinkRelations;
26 | import org.springframework.hateoas.Link;
27 | import org.springframework.hateoas.PagedModel;
28 | import org.springframework.lang.NonNull;
29 |
30 | import java.util.ArrayList;
31 |
32 | import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
33 | import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
34 |
35 | /**
36 | * Created by Kyriakos Bompotis on 24/6/20.
37 | */
38 | public class StateModelAssembler extends PaginatedRepresentationModelAssemblerSupport {
39 | public StateModelAssembler() {
40 | super(DomainsController.class, StateModel.class);
41 | }
42 |
43 | @NonNull
44 | @Override
45 | public StateModel toModel(StateDto stateDto) {
46 | return new StateModel(
47 | stateDto.getHostname(),
48 | stateDto.getStatusCode(),
49 | stateDto.getTimeCheckedOn(),
50 | stateDto.getReason(),
51 | stateDto.getDnsResolves(),
52 | stateDto.getProtocol(),
53 | stateDto.getRedirectUri(),
54 | stateDto.isUp(),
55 | stateDto.getDuration().getSeconds());
56 | }
57 |
58 | public CollectionModel toCollectionModel(PaginatedDto paginatedStatesDto, String domain, String protocol, Boolean includeCertificates) {
59 | final var stateModels = this.toCollectionModel(paginatedStatesDto.getDtoList()).getContent();
60 | final var links = new ArrayList();
61 | links.add(linkTo(methodOn(DomainsController.class)
62 | .getDomainsStates(domain, protocol, includeCertificates, paginatedStatesDto.getNumber(), paginatedStatesDto.getSize()))
63 | .withSelfRel()
64 | );
65 | if (isValidPage(paginatedStatesDto.getNumber(),paginatedStatesDto.getTotalPages())) {
66 | if (isNotLastPage(paginatedStatesDto.getNumber(), paginatedStatesDto.getTotalPages())) {
67 | links.add(linkTo(methodOn(DomainsController.class)
68 | .getDomainsStates(domain, protocol, includeCertificates, paginatedStatesDto.getNumber()+1, paginatedStatesDto.getSize()))
69 | .withRel(IanaLinkRelations.NEXT)
70 | );
71 | }
72 | if (isNotFirstPage(paginatedStatesDto.getNumber())) {
73 | links.add(linkTo(methodOn(DomainsController.class)
74 | .getDomainsStates(domain, protocol, includeCertificates,paginatedStatesDto.getNumber()-1, paginatedStatesDto.getSize()))
75 | .withRel(IanaLinkRelations.PREVIOUS)
76 | );
77 | }
78 | }
79 | return PagedModel.of(
80 | stateModels,
81 | new PagedModel.PageMetadata(
82 | stateModels.size(),
83 | paginatedStatesDto.getNumber(),
84 | paginatedStatesDto.getTotalElements(),
85 | paginatedStatesDto.getTotalPages()
86 | ),
87 | links
88 | );
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/main/java/com/bompotis/netcheck/api/exception/ControllerAdvisor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 | *
5 | * This code is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This code is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package com.bompotis.netcheck.api.exception;
19 |
20 | import org.springframework.context.support.DefaultMessageSourceResolvable;
21 | import org.springframework.http.HttpHeaders;
22 | import org.springframework.http.HttpStatus;
23 | import org.springframework.http.HttpStatusCode;
24 | import org.springframework.http.ResponseEntity;
25 | import org.springframework.web.bind.MethodArgumentNotValidException;
26 | import org.springframework.web.bind.annotation.ControllerAdvice;
27 | import org.springframework.web.bind.annotation.ExceptionHandler;
28 | import org.springframework.web.context.request.WebRequest;
29 | import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
30 | import reactor.util.annotation.NonNull;
31 |
32 | import java.time.LocalDateTime;
33 | import java.time.format.DateTimeFormatter;
34 | import java.util.LinkedHashMap;
35 | import java.util.List;
36 | import java.util.Map;
37 | import java.util.stream.Collectors;
38 |
39 | /**
40 | * Created by Kyriakos Bompotis on 3/9/20.
41 | */
42 | @ControllerAdvice
43 | public class ControllerAdvisor extends ResponseEntityExceptionHandler {
44 |
45 | @ExceptionHandler(IllegalArgumentException.class)
46 | public ResponseEntity