├── .env.example
├── .github
├── dependabot.yml
└── workflows
│ └── test-and-release.yaml
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── amd64.openj9.Dockerfile
├── database.env.example
├── docker-compose.dockerhub.yml
├── docker-compose.yml
├── pom.xml
├── src
├── main
│ ├── java
│ │ └── com
│ │ │ └── bompotis
│ │ │ └── netcheck
│ │ │ ├── NetcheckApplication.java
│ │ │ ├── api
│ │ │ ├── controller
│ │ │ │ ├── AbstractStreamController.java
│ │ │ │ ├── CheckController.java
│ │ │ │ ├── DomainsController.java
│ │ │ │ ├── NotificationTestController.java
│ │ │ │ ├── ServerController.java
│ │ │ │ └── StreamController.java
│ │ │ ├── exception
│ │ │ │ ├── ControllerAdvisor.java
│ │ │ │ ├── EntityNotFoundException.java
│ │ │ │ ├── InvalidAuthHeaders.java
│ │ │ │ └── UnauthorizedStatusException.java
│ │ │ ├── model
│ │ │ │ ├── CertificateModel.java
│ │ │ │ ├── DomainCheckModel.java
│ │ │ │ ├── DomainRequest.java
│ │ │ │ ├── DomainResponse.java
│ │ │ │ ├── HttpCheckModel.java
│ │ │ │ ├── MetricModel.java
│ │ │ │ ├── PatchOperation.java
│ │ │ │ ├── RegisterServerRequest.java
│ │ │ │ ├── ServerDefinitionModel.java
│ │ │ │ ├── ServerMetricModel.java
│ │ │ │ ├── ServerMetricRequest.java
│ │ │ │ ├── ServerModel.java
│ │ │ │ ├── StateModel.java
│ │ │ │ └── assembler
│ │ │ │ │ ├── AbstractUpdateDtoAssembler.java
│ │ │ │ │ ├── CertificateModelAssembler.java
│ │ │ │ │ ├── DomainCheckModelAssembler.java
│ │ │ │ │ ├── DomainModelAssembler.java
│ │ │ │ │ ├── DomainUpdateDtoAssembler.java
│ │ │ │ │ ├── HttpCheckModelAssembler.java
│ │ │ │ │ ├── MetricModelAssembler.java
│ │ │ │ │ ├── PaginatedRepresentationModelAssemblerSupport.java
│ │ │ │ │ ├── ServerDefinitionAssembler.java
│ │ │ │ │ ├── ServerMetricModelAssembler.java
│ │ │ │ │ ├── ServerModelAssembler.java
│ │ │ │ │ ├── ServerUpdateDtoAssembler.java
│ │ │ │ │ └── StateModelAssembler.java
│ │ │ └── security
│ │ │ │ └── WebSecurityConfig.java
│ │ │ ├── data
│ │ │ ├── entity
│ │ │ │ ├── AbstractTimestampable.java
│ │ │ │ ├── AbstractTimestampablePersistable.java
│ │ │ │ ├── CertificateEntity.java
│ │ │ │ ├── DomainCheckEntity.java
│ │ │ │ ├── DomainEntity.java
│ │ │ │ ├── DomainMetricEntity.java
│ │ │ │ ├── EntityBuilder.java
│ │ │ │ ├── OperationUpdater.java
│ │ │ │ ├── ProtocolCheckEntity.java
│ │ │ │ ├── ServerEntity.java
│ │ │ │ ├── ServerMetricDefinitionEntity.java
│ │ │ │ └── ServerMetricEntity.java
│ │ │ └── repository
│ │ │ │ ├── DomainCheckRepository.java
│ │ │ │ ├── DomainMetricRepository.java
│ │ │ │ ├── DomainRepository.java
│ │ │ │ ├── ServerMetricDefinitionRepository.java
│ │ │ │ ├── ServerMetricRepository.java
│ │ │ │ └── ServerRepository.java
│ │ │ ├── scheduler
│ │ │ ├── batch
│ │ │ │ ├── BatchConfiguration.java
│ │ │ │ ├── JobCompletionNotificationListener.java
│ │ │ │ ├── notification
│ │ │ │ │ ├── CheckEventDto.java
│ │ │ │ │ ├── EventDto.java
│ │ │ │ │ ├── NotificationDto.java
│ │ │ │ │ ├── NotificationEventDto.java
│ │ │ │ │ ├── NotificationEventService.java
│ │ │ │ │ ├── NotificationService.java
│ │ │ │ │ ├── PushoverService.java
│ │ │ │ │ ├── ServerMetricEventDto.java
│ │ │ │ │ ├── WebhookService.java
│ │ │ │ │ ├── client
│ │ │ │ │ │ ├── MessagePriority.java
│ │ │ │ │ │ ├── PushoverMessage.java
│ │ │ │ │ │ └── PushoverRestClient.java
│ │ │ │ │ └── config
│ │ │ │ │ │ ├── PushoverConfig.java
│ │ │ │ │ │ └── WebhookConfig.java
│ │ │ │ ├── processor
│ │ │ │ │ ├── DomainCheckProcessor.java
│ │ │ │ │ └── DomainMetricProcessor.java
│ │ │ │ ├── reader
│ │ │ │ │ └── OldDomainCheckItemReader.java
│ │ │ │ └── writer
│ │ │ │ │ ├── AbstractNotificationWriter.java
│ │ │ │ │ ├── CheckEventItemWriter.java
│ │ │ │ │ ├── DomainMetricListWriter.java
│ │ │ │ │ └── NotificationItemWriter.java
│ │ │ └── task
│ │ │ │ └── CheckDomainTask.java
│ │ │ └── service
│ │ │ ├── AbstractService.java
│ │ │ ├── DomainService.java
│ │ │ ├── MetricService.java
│ │ │ ├── ServerMetricsService.java
│ │ │ └── dto
│ │ │ ├── AbstractHttpChecker.java
│ │ │ ├── AbstractPaginatedDto.java
│ │ │ ├── CertificateDetailsDto.java
│ │ │ ├── DomainCheckConfigDto.java
│ │ │ ├── DomainCheckDto.java
│ │ │ ├── DomainDto.java
│ │ │ ├── DomainUpdateDto.java
│ │ │ ├── DomainsOptionsDto.java
│ │ │ ├── DtoBuilder.java
│ │ │ ├── HttpCheckDto.java
│ │ │ ├── HttpsCheckDto.java
│ │ │ ├── MetricDto.java
│ │ │ ├── Operation.java
│ │ │ ├── PaginatedDto.java
│ │ │ ├── PatchDtoBuilder.java
│ │ │ ├── RequestOptionsDto.java
│ │ │ ├── ServerDefinitionDto.java
│ │ │ ├── ServerDto.java
│ │ │ ├── ServerMetricDto.java
│ │ │ ├── ServerUpdateDto.java
│ │ │ └── StateDto.java
│ └── resources
│ │ ├── META-INF
│ │ └── additional-spring-configuration-metadata.json
│ │ ├── application.yaml
│ │ ├── banner.txt
│ │ └── db
│ │ └── migration
│ │ ├── V1_0_0__init_schema.sql
│ │ ├── V1_1_0__init_spring_batch.sql
│ │ ├── V1_2_0__add_domain_endpoint_column.sql
│ │ ├── V1_3_0__add_domain_headers_column.sql
│ │ ├── V1_3_1__add_domain_timeout_column.sql
│ │ ├── V1_3_2__update_new_fields_to_defaults.sql
│ │ ├── V1_4_0__add_server_tables.sql
│ │ └── V1_5_0__spring_batch_5_migration.sql
└── test
│ ├── java
│ └── com
│ │ └── bompotis
│ │ └── netcheck
│ │ ├── NetcheckApplicationStartupTests.java
│ │ └── api
│ │ └── controller
│ │ ├── CheckControllerTests.java
│ │ └── DomainsControllerTests.java
│ └── resources
│ └── application.yaml
├── test-depedancies.docker-compose.yml
├── traefik.docker-compose.yml
└── version.txt
/.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=
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.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
--------------------------------------------------------------------------------
/database.env.example:
--------------------------------------------------------------------------------
1 | POSTGRES_USER=netcheck
2 | POSTGRES_PASSWORD=netcheck
3 | POSTGRES_DB=netcheck
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/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/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/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/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/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/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