diff --git a/.gitignore b/.gitignore
index 844ff2d825..9f56b19cfd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -278,4 +278,5 @@ ready-for-integration.sh
update-pr.sh
/chpl/chpl-api/e2e/env/*.postman_environment.json
newman/
+/Servers
Servers/
diff --git a/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/OnDemandUrlCheckerController.java b/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/OnDemandUrlCheckerController.java
new file mode 100644
index 0000000000..5f002c7de3
--- /dev/null
+++ b/chpl/chpl-api/src/main/java/gov/healthit/chpl/web/controller/OnDemandUrlCheckerController.java
@@ -0,0 +1,46 @@
+package gov.healthit.chpl.web.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.datadog.api.client.ApiException;
+
+import gov.healthit.chpl.datadog.OnDemandUrlCheckerManager;
+import gov.healthit.chpl.datadog.OnDemandUrlCheckerResponse;
+import gov.healthit.chpl.datadog.OnDemandUrlRequest;
+import gov.healthit.chpl.exception.ValidationException;
+import gov.healthit.chpl.util.SwaggerSecurityRequirement;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.extern.log4j.Log4j2;
+
+@Log4j2
+@Tag(name = "urls", description = "")
+@RestController
+@RequestMapping("/urls")
+public class OnDemandUrlCheckerController {
+
+ private OnDemandUrlCheckerManager onDemandUrlCheckerManager;
+
+ @Autowired
+ public OnDemandUrlCheckerController(OnDemandUrlCheckerManager onDemandUrlCheckerManager) {
+ this.onDemandUrlCheckerManager = onDemandUrlCheckerManager;
+ }
+
+ @Operation(summary = "Validates a URL. Three checks are performed: 1) HTTP Status code is 200, 2) Response time is less than 30 seconds, and 3) Response body is not empty.",
+ description = "Security Restrictions: chpl-admin, chpl-onc, or chpl-onc-acb",
+ security = {
+ @SecurityRequirement(name = SwaggerSecurityRequirement.API_KEY),
+ @SecurityRequirement(name = SwaggerSecurityRequirement.BEARER)
+ })
+ @RequestMapping(value = "/validate", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = "application/json; charset=utf-8")
+ public OnDemandUrlCheckerResponse checkUrl(@RequestBody OnDemandUrlRequest url) throws InterruptedException, ApiException, ValidationException {
+ return onDemandUrlCheckerManager.checkUrl(url.getUrl());
+ }
+
+}
diff --git a/chpl/chpl-resources/src/main/resources/errors.properties b/chpl/chpl-resources/src/main/resources/errors.properties
index c9dbbe6263..a1ce2768c1 100644
--- a/chpl/chpl-resources/src/main/resources/errors.properties
+++ b/chpl/chpl-resources/src/main/resources/errors.properties
@@ -649,6 +649,8 @@ listing.realWorldTesting.eligibilityYearNotUpdatable=Real World Eligibility Year
listing.svap.url.invalid=SVAP Notice URL is not a well formed URL.
+onDemandUrlTest.invalidUrl=URL to test is not a well formed URL.
+
job.missingRequiredData=%s must be specified for every job.
job.doesNotExist=The job with ID %s does not exist.
job.exists=A job with ID %s already exists.
diff --git a/chpl/chpl-service/pom.xml b/chpl/chpl-service/pom.xml
index c42a0084b2..5290e30f04 100644
--- a/chpl/chpl-service/pom.xml
+++ b/chpl/chpl-service/pom.xml
@@ -383,7 +383,7 @@
provided
-
+
org.springframework.boot
@@ -419,6 +419,13 @@
0.4.0
+
+
+ dev.failsafe
+ failsafe
+ 3.3.2
+
+
org.junit.jupiter
diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/datadog/OnDemandUrlCheckerAssertionResult.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/datadog/OnDemandUrlCheckerAssertionResult.java
new file mode 100644
index 0000000000..b5a3e1cccf
--- /dev/null
+++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/datadog/OnDemandUrlCheckerAssertionResult.java
@@ -0,0 +1,11 @@
+package gov.healthit.chpl.datadog;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class OnDemandUrlCheckerAssertionResult {
+ private Boolean passed;
+ private String actualValue;
+}
diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/datadog/OnDemandUrlCheckerManager.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/datadog/OnDemandUrlCheckerManager.java
new file mode 100644
index 0000000000..522f721668
--- /dev/null
+++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/datadog/OnDemandUrlCheckerManager.java
@@ -0,0 +1,202 @@
+package gov.healthit.chpl.datadog;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+
+import com.datadog.api.client.ApiException;
+import com.datadog.api.client.v1.model.SyntheticsAPITest;
+import com.datadog.api.client.v1.model.SyntheticsAPITestResultFull;
+import com.datadog.api.client.v1.model.SyntheticsApiTestFailureCode;
+import com.datadog.api.client.v1.model.SyntheticsGetAPITestLatestResultsResponse;
+import com.datadog.api.client.v1.model.SyntheticsTriggerBody;
+import com.datadog.api.client.v1.model.SyntheticsTriggerTest;
+
+import dev.failsafe.Failsafe;
+import dev.failsafe.RetryPolicy;
+import gov.healthit.chpl.exception.ValidationException;
+import gov.healthit.chpl.scheduler.job.urluptime.DatadogSyntheticsTestResultService;
+import gov.healthit.chpl.scheduler.job.urluptime.DatadogSyntheticsTestService;
+import gov.healthit.chpl.util.ErrorMessageUtil;
+import gov.healthit.chpl.util.ValidationUtils;
+import lombok.extern.log4j.Log4j2;
+
+@Log4j2
+@Component
+public class OnDemandUrlCheckerManager {
+ public static final Long TEMP_DEVELOPER_ID = -99L;
+ private static final Integer MAX_ATTEMPTS = 45;
+ private static final Integer MAX_SECONDS = 45;
+ private static final String ASSERTION_RESULTS_KEY = "assertionResults";
+ private static final String TYPE_KEY = "type";
+ private static final String ACTUAL_KEY = "actual";
+ private static final String VALID_KEY = "valid";
+ private static final String TYPE_VALUE_STATUS_CODE = "statusCode";
+ private static final String TYPE_VALUE_BODY = "body";
+ private static final String TYPE_VALUE_RESPONSE_TIME = "responseTime";
+
+ private List errorsToIgnore = List.of("BODY_TOO_LARGE_TO_PROCESS");
+
+ private DatadogSyntheticsTestService datadogSyntheticsTestService;
+ private DatadogSyntheticsTestResultService datadogSyntheticsTestResultService;
+ private ValidationUtils validationUtils;
+ private ErrorMessageUtil errorMessageUtil;
+
+ @Autowired
+ public OnDemandUrlCheckerManager(DatadogSyntheticsTestService datadogSyntheticsTestService, DatadogSyntheticsTestResultService datadogSyntheticsTestResultService,
+ ValidationUtils validationUtils, ErrorMessageUtil errorMessageUtil) {
+ this.datadogSyntheticsTestService = datadogSyntheticsTestService;
+ this.datadogSyntheticsTestResultService = datadogSyntheticsTestResultService;
+ this.validationUtils = validationUtils;
+ this.errorMessageUtil = errorMessageUtil;
+ }
+
+ @PreAuthorize("@permissions.hasAccess(T(gov.healthit.chpl.permissions.Permissions).URL_CHECKER, "
+ + "T(gov.healthit.chpl.permissions.domains.UrlCheckerDomainPermissions).CHECK)")
+ public OnDemandUrlCheckerResponse checkUrl(String url) throws ApiException, ValidationException {
+ SyntheticsAPITest test = null;
+ validateUrlWellFormed(url);
+ try {
+ test = createTest(url);
+ triggerTest(test);
+ SyntheticsGetAPITestLatestResultsResponse result = awaitTestResults(test);
+ OnDemandUrlCheckerResponse response = analyzeTestResults(result, test);
+ return response;
+ } finally {
+ try {
+ LOGGER.info("Completed On Demand URL Check");
+ if (test != null) {
+ LOGGER.info("Deleting On Demand URL Check: {}", test.getPublicId());
+ datadogSyntheticsTestService.deleteSyntheticsTests(List.of(test.getPublicId()));
+ LOGGER.info("Deleted On Demand URL Check: {}", test.getPublicId());
+ }
+ } catch (Exception e) {
+ LOGGER.error("Failed to delete On Demand URL Check", e);
+ }
+
+ }
+ }
+
+ private void validateUrlWellFormed(String url) throws ValidationException {
+ if (!validationUtils.isWellFormedUrl(url)) {
+ throw new ValidationException(errorMessageUtil.getMessage("onDemandUrlTest.invalidUrl"));
+ }
+ }
+
+ private SyntheticsAPITest createTest(String url) {
+ LOGGER.info("Creating On Demand URL Check for: {}", url);
+ var x = datadogSyntheticsTestService.createSyntheticsTest(url, List.of(TEMP_DEVELOPER_ID));
+ LOGGER.info("Created On Demand URL Check: {}", x.getPublicId());
+ return x;
+ }
+
+ private void triggerTest(SyntheticsAPITest test) throws ApiException {
+ LOGGER.info("Triggering On Demand URL Check");
+ SyntheticsTriggerBody body = new SyntheticsTriggerBody()
+ .tests(List.of(new SyntheticsTriggerTest().publicId(test.getPublicId())));
+
+ datadogSyntheticsTestService.getApiProvider().getApiInstance().triggerTests(body);
+ }
+
+ private SyntheticsGetAPITestLatestResultsResponse awaitTestResults(SyntheticsAPITest test) throws ApiException {
+ LOGGER.info("Awaiting On Demand URL Check");
+ RetryPolicy retryPolicy = RetryPolicy.builder()
+ .withMaxAttempts(MAX_ATTEMPTS)
+ .withDelay(Duration.ofSeconds(1))
+ .withMaxDuration(Duration.ofSeconds(MAX_SECONDS))
+ .onRetry(e -> LOGGER.info("Failure #{}. Retrying.", e.getAttemptCount()))
+ .onSuccess(e -> LOGGER.info("Success #{}.", e.getAttemptCount()))
+ .handleResultIf(res -> res == null || res.getResults().size() == 0)
+ .build();
+
+ return Failsafe.with(retryPolicy)
+ .get(() -> datadogSyntheticsTestResultService.getSyntheticsTestResults(test.getPublicId()));
+ }
+
+ private OnDemandUrlCheckerResponse analyzeTestResults(SyntheticsGetAPITestLatestResultsResponse result, SyntheticsAPITest test) throws ApiException {
+ SyntheticsAPITestResultFull fullTestResults = null;
+ OnDemandUrlCheckerResponse response = null;
+ if (result != null
+ && result.getResults().size() > 0) {
+ fullTestResults = datadogSyntheticsTestResultService.getDetailedTestResult(test.getPublicId(), result.getResults().get(0).getResultId());
+ response = convertToResponse(test.getConfig().getRequest().getUrl(), fullTestResults);
+ if (fullTestResults.getResult().getFailure() != null
+ && isErrorIgnorable(fullTestResults.getResult().getFailure().getCode())) {
+ response.setPassed(true);
+ response.setErrorMessage("");
+ } else {
+ response.setPassed(result.getResults().get(0).getResult().getPassed());
+ if (!result.getResults().get(0).getResult().getPassed()) {
+ response.setErrorMessage(fullTestResults.getResult().getFailure().getMessage());
+ }
+ }
+ } else {
+ throw new ApiException("No results found for test " + test.getPublicId());
+ }
+ return response;
+ }
+
+ private OnDemandUrlCheckerResponse convertToResponse(String url, SyntheticsAPITestResultFull fullTestResults) {
+ if (doAdditionalPropertiesExist(fullTestResults)) {
+ if (fullTestResults.getResult().getFailure() != null
+ && isErrorIgnorable(fullTestResults.getResult().getFailure().getCode())) {
+ return OnDemandUrlCheckerResponse.builder()
+ .httpResponseAssertion(OnDemandUrlCheckerAssertionResult.builder().passed(true).actualValue("").build())
+ .responseTimeAssertion(OnDemandUrlCheckerAssertionResult.builder().passed(true).actualValue("").build())
+ .bodyNotEmptyAssertion(OnDemandUrlCheckerAssertionResult.builder().passed(true).actualValue("").build())
+ .url(url)
+ .build();
+ }
+ return OnDemandUrlCheckerResponse.builder()
+ .httpResponseAssertion(getAssertionResult(fullTestResults.getResult().getAdditionalProperties(), TYPE_VALUE_STATUS_CODE))
+ .responseTimeAssertion(getAssertionResult(fullTestResults.getResult().getAdditionalProperties(), TYPE_VALUE_RESPONSE_TIME))
+ .bodyNotEmptyAssertion(getAssertionResult(fullTestResults.getResult().getAdditionalProperties(), TYPE_VALUE_BODY))
+ .url(url)
+ .build();
+ } else {
+ return OnDemandUrlCheckerResponse.builder()
+ .url(url)
+ .build();
+ }
+ }
+
+ private OnDemandUrlCheckerAssertionResult getAssertionResult(Map results, String value) {
+ if (results.containsKey(ASSERTION_RESULTS_KEY)
+ && results.get(ASSERTION_RESULTS_KEY) instanceof List>) {
+
+ return ((List>) results.get(ASSERTION_RESULTS_KEY)).stream()
+ .filter(map -> map instanceof Map, ?>)
+ .filter(map -> ((Map, ?>) map).containsKey(TYPE_KEY)
+ && ((Map, ?>) map).containsKey(VALID_KEY)
+ && ((String) ((Map, ?>) map).get(TYPE_KEY)).equals(value))
+
+ .findAny()
+ .map(map -> OnDemandUrlCheckerAssertionResult.builder()
+ .passed((Boolean) ((Map, ?>) map).get(VALID_KEY))
+ .actualValue(((Map, ?>) map).containsKey(ACTUAL_KEY) ? ((Map, ?>) map).get(ACTUAL_KEY).toString() : "")
+ .build())
+ .orElse(OnDemandUrlCheckerAssertionResult.builder()
+ .passed(false)
+ .actualValue("Unknown")
+ .build());
+ }
+ return null;
+ }
+
+ private Boolean doAdditionalPropertiesExist(SyntheticsAPITestResultFull fullTestResults) {
+ return fullTestResults.getResult().getAdditionalProperties().containsKey(ASSERTION_RESULTS_KEY)
+ && fullTestResults.getResult().getAdditionalProperties().get(ASSERTION_RESULTS_KEY) instanceof List>;
+ }
+
+ private boolean isErrorIgnorable(SyntheticsApiTestFailureCode errorCode) {
+ return errorsToIgnore.stream()
+ .filter(code -> code.equals(errorCode.getValue()))
+ .findAny()
+ .isPresent();
+ }
+
+}
diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/datadog/OnDemandUrlCheckerResponse.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/datadog/OnDemandUrlCheckerResponse.java
new file mode 100644
index 0000000000..1fd973b2d9
--- /dev/null
+++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/datadog/OnDemandUrlCheckerResponse.java
@@ -0,0 +1,15 @@
+package gov.healthit.chpl.datadog;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class OnDemandUrlCheckerResponse {
+ private String url;
+ private String errorMessage;
+ private Boolean passed;
+ private OnDemandUrlCheckerAssertionResult responseTimeAssertion;
+ private OnDemandUrlCheckerAssertionResult bodyNotEmptyAssertion;
+ private OnDemandUrlCheckerAssertionResult httpResponseAssertion;
+}
diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/datadog/OnDemandUrlRequest.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/datadog/OnDemandUrlRequest.java
new file mode 100644
index 0000000000..3d0c0b7ccc
--- /dev/null
+++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/datadog/OnDemandUrlRequest.java
@@ -0,0 +1,18 @@
+package gov.healthit.chpl.datadog;
+
+import java.io.Serializable;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class OnDemandUrlRequest implements Serializable {
+ private static final long serialVersionUID = -3009297190983937267L;
+
+ private String url;
+}
diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/permissions/Permissions.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/permissions/Permissions.java
index f766a307c1..9b0eddcb16 100644
--- a/chpl/chpl-service/src/main/java/gov/healthit/chpl/permissions/Permissions.java
+++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/permissions/Permissions.java
@@ -39,6 +39,7 @@
import gov.healthit.chpl.permissions.domains.TestToolDomainPermissions;
import gov.healthit.chpl.permissions.domains.TestingLabDomainPermissions;
import gov.healthit.chpl.permissions.domains.UcdProcessDomainPermissions;
+import gov.healthit.chpl.permissions.domains.UrlCheckerDomainPermissions;
import gov.healthit.chpl.permissions.domains.UserPermissionsDomainPermissions;
@Component
@@ -79,6 +80,7 @@ public class Permissions {
public static final String STANDARD = "STANDARD";
public static final String CODE_SET = "CODE_SET";
public static final String API_KEY = "API_KEY";
+ public static final String URL_CHECKER = "URL_CHECKER";
private Map domainPermissions = new HashMap();
@@ -116,7 +118,8 @@ public Permissions(CertificationResultsDomainPermissions certificationResultsDom
FunctionalityTestedDomainPermissions functionalityTestedDomainPermissions,
StandardDomainPermissions standardDomainPermissions,
CodeSetDomainPermissions codeSetPermissions,
- ApiKeyDomainPermissions apiKeyPermissions) {
+ ApiKeyDomainPermissions apiKeyPermissions,
+ UrlCheckerDomainPermissions urlCheckerDomainPermissions) {
domainPermissions.put(ACCESSIBILITY_STANDARD, accessibilityStandardDomainPermissions);
domainPermissions.put(ACTIVITY, activityDomainPermissions);
@@ -151,6 +154,7 @@ public Permissions(CertificationResultsDomainPermissions certificationResultsDom
domainPermissions.put(UCD_PROCESS, ucdProcessDomainPermissions);
domainPermissions.put(USER_PERMISSIONS, userPermissionsDomainPermissions);
domainPermissions.put(API_KEY, apiKeyPermissions);
+ domainPermissions.put(URL_CHECKER, urlCheckerDomainPermissions);
}
public boolean hasAccess(final String domain, final String action) {
diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/permissions/domains/UrlCheckerDomainPermissions.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/permissions/domains/UrlCheckerDomainPermissions.java
new file mode 100644
index 0000000000..c06f4690aa
--- /dev/null
+++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/permissions/domains/UrlCheckerDomainPermissions.java
@@ -0,0 +1,18 @@
+package gov.healthit.chpl.permissions.domains;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
+import gov.healthit.chpl.permissions.domains.testinglab.urlchecker.CheckActionPermissions;
+
+@Component
+public class UrlCheckerDomainPermissions extends DomainPermissions {
+ public static final String CHECK = "CHECK";
+
+ @Autowired
+ public UrlCheckerDomainPermissions(
+ @Qualifier("urlCheckerCheckActionPermissions") CheckActionPermissions checkActionPermissions) {
+ getActionPermissions().put(CHECK, checkActionPermissions);
+ }
+}
diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/permissions/domains/testinglab/urlchecker/CheckActionPermissions.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/permissions/domains/testinglab/urlchecker/CheckActionPermissions.java
new file mode 100644
index 0000000000..ab7109085d
--- /dev/null
+++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/permissions/domains/testinglab/urlchecker/CheckActionPermissions.java
@@ -0,0 +1,21 @@
+package gov.healthit.chpl.permissions.domains.testinglab.urlchecker;
+
+import org.springframework.stereotype.Component;
+
+import gov.healthit.chpl.permissions.domains.ActionPermissions;
+
+@Component("urlCheckerCheckActionPermissions")
+public class CheckActionPermissions extends ActionPermissions {
+
+ @Override
+ public boolean hasAccess() {
+ return getResourcePermissions().isUserRoleAdmin()
+ || getResourcePermissions().isUserRoleOnc()
+ || getResourcePermissions().isUserRoleAcbAdmin();
+ }
+
+ @Override
+ public boolean hasAccess(Object obj) {
+ return false;
+ }
+}
diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/scheduler/job/urluptime/DatadogSyntheticsTestResultService.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/scheduler/job/urluptime/DatadogSyntheticsTestResultService.java
index aeb79db028..a4bd8a5a53 100644
--- a/chpl/chpl-service/src/main/java/gov/healthit/chpl/scheduler/job/urluptime/DatadogSyntheticsTestResultService.java
+++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/scheduler/job/urluptime/DatadogSyntheticsTestResultService.java
@@ -24,7 +24,6 @@ public class DatadogSyntheticsTestResultService {
private DatadogSyntheticsTestApiProvider apiProvider;
-
@Autowired
public DatadogSyntheticsTestResultService(DatadogSyntheticsTestApiProvider apiProvider) {
this.apiProvider = apiProvider;
@@ -58,6 +57,15 @@ public List getSyntheticsTestResults(String public
return testResults;
}
+ public SyntheticsGetAPITestLatestResultsResponse getSyntheticsTestResults(String publicTestKey) {
+ try {
+ return apiProvider.getApiInstance().getAPITestLatestResults(publicTestKey);
+ } catch (ApiException e) {
+ LOGGER.error("Could not retrieve results for test key: {}", publicTestKey, e);
+ return null;
+ }
+ }
+
public SyntheticsAPITestResultFull getDetailedTestResult(String publicTestKey, String resultId) {
try {
return apiProvider.getApiInstance().getAPITestResult(publicTestKey, resultId);
diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/scheduler/job/urluptime/DatadogSyntheticsTestService.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/scheduler/job/urluptime/DatadogSyntheticsTestService.java
index befdbe58fa..98ff6d0209 100644
--- a/chpl/chpl-service/src/main/java/gov/healthit/chpl/scheduler/job/urluptime/DatadogSyntheticsTestService.java
+++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/scheduler/job/urluptime/DatadogSyntheticsTestService.java
@@ -38,7 +38,6 @@ public class DatadogSyntheticsTestService {
private static final Long SECONDS_IN_A_MINUTE = 60L;
private DatadogSyntheticsTestApiProvider apiProvider;
- private Boolean datadogIsReadOnly;
private String datadogTestStartTime;
private String datadogTestEndTime;
private Long datadogCheckEveryMinutes;
@@ -46,14 +45,12 @@ public class DatadogSyntheticsTestService {
private String datadogTestLocation;
public DatadogSyntheticsTestService(DatadogSyntheticsTestApiProvider apiProvider,
- @Value("${datadog.syntheticsTest.readOnly}") Boolean datadogIsReadOnly,
@Value("${datadog.syntheticsTest.startTime}") String datadogTestStartTime,
@Value("${datadog.syntheticsTest.endTime}") String datadogTestEndTime,
@Value("${datadog.syntheticsTest.checkEveryMinutes}") Long datadogCheckEveryMinutes,
@Value("${datadog.syntheticsTest.timeout}") Integer datadogTestTimeout,
@Value("${datadog.syntheticsTest.location}") String datadogTestLocation) {
this.apiProvider = apiProvider;
- this.datadogIsReadOnly = datadogIsReadOnly;
this.datadogTestStartTime = datadogTestStartTime;
this.datadogTestEndTime = datadogTestEndTime;
this.datadogCheckEveryMinutes = datadogCheckEveryMinutes;
@@ -61,7 +58,7 @@ public DatadogSyntheticsTestService(DatadogSyntheticsTestApiProvider apiProvider
this.datadogTestLocation = datadogTestLocation;
}
- protected DatadogSyntheticsTestApiProvider getApiProvider() {
+ public DatadogSyntheticsTestApiProvider getApiProvider() {
return apiProvider;
}
@@ -86,12 +83,7 @@ public SyntheticsAPITest getSyntheticsTest(String publicId) {
public void deleteSyntheticsTests(List publicIds) {
try {
- if (datadogIsReadOnly) {
- LOGGER.info("Not deleting from datadog (due to environment setting) with Public Ids: {}", publicIds);
- } else {
- apiProvider.getApiInstance().deleteTests(new SyntheticsDeleteTestsPayload().publicIds(publicIds));
- }
-
+ apiProvider.getApiInstance().deleteTests(new SyntheticsDeleteTestsPayload().publicIds(publicIds));
} catch (ApiException e) {
LOGGER.error("Could not delete Synthetic Tests from Datadog: {}", publicIds, e);
}
@@ -114,8 +106,8 @@ public SyntheticsAPITest createSyntheticsTest(String url, List developerId
.target(NOT_EMPTY_REGEX)
.type(SyntheticsAssertionType.BODY))))
.request(new SyntheticsTestRequest()
- .url(url)
- .method(HTTP_METHOD_GET)))
+ .url(url)
+ .method(HTTP_METHOD_GET)))
.options(new SyntheticsTestOptions()
.httpVersion(SyntheticsTestOptionsHTTPVersion.ANY)
.minFailureDuration(0L)
@@ -150,13 +142,8 @@ public SyntheticsAPITest createSyntheticsTest(String url, List developerId
.tags(developerIdsToTags(developerIds));
try {
- if (datadogIsReadOnly) {
- LOGGER.info("Not updating datadog (due to environment setting) with Developers: {} and URL: {}", developerIds, url);
- return body;
- } else {
- LOGGER.info("Adding Synthetics Test for URL: {}, with Developers: {}", url, developerIds);
- return apiProvider.getApiInstance().createSyntheticsAPITest(body);
- }
+ LOGGER.info("Adding Synthetics Test for URL: {}, with Developers: {}", url, developerIds);
+ return apiProvider.getApiInstance().createSyntheticsAPITest(body);
} catch (ApiException e) {
LOGGER.error("Could not create Synthetics Test for URL: {}", url, e);
return null;
@@ -174,11 +161,7 @@ public void setApplicableDevelopersForTest(String syntheticsApiTestPublicId, Lis
.path("/tags")
.value(test.getTags()));
try {
- if (datadogIsReadOnly) {
- LOGGER.info("Not adding Developer(s) (due to environment setting) to existing Synthetics Test {}", developerIds);
- } else {
- apiProvider.getApiInstance().patchTest(syntheticsApiTestPublicId, body);
- }
+ apiProvider.getApiInstance().patchTest(syntheticsApiTestPublicId, body);
} catch (ApiException e) {
LOGGER.error("Could not add Developer(s) to existing Synthetics Test {}", developerIds, e);
}
diff --git a/chpl/chpl-service/src/main/java/gov/healthit/chpl/scheduler/job/urluptime/DatadogUrlUptimeSynchonizer.java b/chpl/chpl-service/src/main/java/gov/healthit/chpl/scheduler/job/urluptime/DatadogUrlUptimeSynchonizer.java
index 11480bfd8e..fef186f3d0 100644
--- a/chpl/chpl-service/src/main/java/gov/healthit/chpl/scheduler/job/urluptime/DatadogUrlUptimeSynchonizer.java
+++ b/chpl/chpl-service/src/main/java/gov/healthit/chpl/scheduler/job/urluptime/DatadogUrlUptimeSynchonizer.java
@@ -22,6 +22,7 @@
import com.datadog.api.client.v1.model.SyntheticsApiTestFailureCode;
import com.datadog.api.client.v1.model.SyntheticsTestDetails;
+import gov.healthit.chpl.datadog.OnDemandUrlCheckerManager;
import gov.healthit.chpl.domain.Developer;
import lombok.extern.log4j.Log4j2;
@@ -204,11 +205,14 @@ public static Predicate distinctByKey(Function super T, Object> keyExtr
}
private void addUrlUptimeMonitor(UrlUptimeMonitor urlUptimeMonitor) {
- try {
- LOGGER.info("Adding the following URL to url_uptime_monitor table: {}, {}", urlUptimeMonitor.getUrl(), urlUptimeMonitor.getDeveloper().getId());
- urlUptimeMonitorDAO.create(urlUptimeMonitor);
- } catch (Exception e) {
- LOGGER.error("Could not add the following URL to url_uptime_monitor table: {}", urlUptimeMonitor.getUrl(), e);
+ // Ignore monitors URL monitors with a developer of -99. These are from the On Demand Checker.
+ if (urlUptimeMonitor.getDeveloper().getId() != OnDemandUrlCheckerManager.TEMP_DEVELOPER_ID) {
+ try {
+ LOGGER.info("Adding the following URL to url_uptime_monitor table: {}, {}", urlUptimeMonitor.getUrl(), urlUptimeMonitor.getDeveloper().getId());
+ urlUptimeMonitorDAO.create(urlUptimeMonitor);
+ } catch (Exception e) {
+ LOGGER.error("Could not add the following URL to url_uptime_monitor table: {}", urlUptimeMonitor.getUrl(), e);
+ }
}
}