From 3d8fc9a77081886599cc93acd26105b433770b43 Mon Sep 17 00:00:00 2001 From: rameshiyer27 Date: Fri, 5 Nov 2021 14:24:02 +0000 Subject: Add health check, metrics and prometheus endpoints for CL participants Issue-ID: POLICY-3747 Signed-off-by: zrrmmua Change-Id: I9cb1ffcc2f9996c5b0e9f67fec9c706e48cfa800 --- .../participant/policy/config/SecurityConfig.java | 45 ++++++++ .../src/main/resources/config/application.yaml | 16 ++- .../policy/main/rest/ActuatorControllerTest.java | 92 +++++++++++++++++ .../main/utils/CommonActuatorController.java | 114 +++++++++++++++++++++ .../src/test/resources/application_test.properties | 6 +- 5 files changed, 270 insertions(+), 3 deletions(-) create mode 100644 participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/SecurityConfig.java create mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/rest/ActuatorControllerTest.java create mode 100644 participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/CommonActuatorController.java (limited to 'participant/participant-impl/participant-impl-policy/src') diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/SecurityConfig.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/SecurityConfig.java new file mode 100644 index 000000000..4ee8c41b0 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/SecurityConfig.java @@ -0,0 +1,45 @@ +/*- + * ========================LICENSE_START================================= + * Copyright (C) 2021 Nordix Foundation. All rights reserved. + * ====================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================LICENSE_END=================================== + */ + +package org.onap.policy.clamp.controlloop.participant.policy.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Value("${security.enable-csrf:true}") + private boolean csrfEnabled = true; + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.authorizeRequests() + .antMatchers().authenticated() + .anyRequest().authenticated() + .and().httpBasic(); + // @formatter:on + + if (!csrfEnabled) { + http.csrf().disable(); + } + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/main/resources/config/application.yaml b/participant/participant-impl/participant-impl-policy/src/main/resources/config/application.yaml index e5b2b2ab1..a2236226e 100644 --- a/participant/participant-impl/participant-impl-policy/src/main/resources/config/application.yaml +++ b/participant/participant-impl/participant-impl-policy/src/main/resources/config/application.yaml @@ -1,5 +1,8 @@ -server: - port: 8082 +spring: + security: + user: + name: participantUser + password: zb!XztG34 participant: pdpGroup: defaultGroup @@ -43,3 +46,12 @@ participant: servers: - ${topicServer:localhost} topicCommInfrastructure: dmaap +management: + endpoints: + web: + exposure: + include: health, metrics, prometheus +server: + port: 8085 + servlet: + context-path: /onap/policyparticipant diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/rest/ActuatorControllerTest.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/rest/ActuatorControllerTest.java new file mode 100644 index 000000000..9cc16e287 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/rest/ActuatorControllerTest.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.participant.policy.main.rest; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import javax.ws.rs.client.Invocation; +import javax.ws.rs.core.Response; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.onap.policy.clamp.controlloop.participant.policy.main.utils.CommonActuatorController; +import org.springframework.boot.test.autoconfigure.actuate.metrics.AutoConfigureMetrics; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@AutoConfigureMetrics +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@TestPropertySource(locations = {"classpath:application_test.properties"}) +class ActuatorControllerTest extends CommonActuatorController { + + private static final String HEALTH_ENDPOINT = "health"; + private static final String METRICS_ENDPOINT = "metrics"; + private static final String PROMETHEUS_ENDPOINT = "prometheus"; + + @LocalServerPort + private int randomServerPort; + + @BeforeEach + public void setUpPort() { + super.setHttpPrefix(randomServerPort); + } + + @Test + void testGetHealth_Unauthorized() throws Exception { + assertUnauthorizedActGet(HEALTH_ENDPOINT); + } + + @Test + void testGetMetrics_Unauthorized() throws Exception { + assertUnauthorizedActGet(METRICS_ENDPOINT); + } + + @Test + void testGetPrometheus_Unauthorized() throws Exception { + assertUnauthorizedActGet(PROMETHEUS_ENDPOINT); + } + + @Test + void testGetHealth() throws Exception { + Invocation.Builder invocationBuilder = super.sendActRequest(HEALTH_ENDPOINT); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } + + @Test + void testGetMetrics() throws Exception { + Invocation.Builder invocationBuilder = super.sendActRequest(METRICS_ENDPOINT); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } + + @Test + void testGePrometheus() throws Exception { + Invocation.Builder invocationBuilder = super.sendActRequest(PROMETHEUS_ENDPOINT); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + } + +} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/CommonActuatorController.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/CommonActuatorController.java new file mode 100644 index 000000000..ec6e30918 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/CommonActuatorController.java @@ -0,0 +1,114 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.participant.policy.main.utils; + +import static org.junit.Assert.assertEquals; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.onap.policy.common.gson.GsonMessageBodyHandler; +import org.onap.policy.common.utils.network.NetworkUtil; + +/** + * Class to perform Rest unit tests. + * + */ +public class CommonActuatorController { + + public static final String SELF = NetworkUtil.getHostname(); + public static final String CONTEXT_PATH = "onap/policyparticipant"; + public static final String ACTUATOR_ENDPOINT = CONTEXT_PATH + "/actuator/"; + + private static String httpPrefix; + + /** + * Sends a request to an actuator endpoint. + * + * @param endpoint the target endpoint + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendActRequest(final String endpoint) throws Exception { + return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, true); + } + + /** + * Sends a request to an actuator endpoint, without any authorization header. + * + * @param endpoint the target endpoint + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendNoAuthActRequest(final String endpoint) throws Exception { + return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, false); + } + + /** + * Sends a request to a fully qualified endpoint. + * + * @param fullyQualifiedEndpoint the fully qualified target endpoint + * @param includeAuth if authorization header should be included + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendFqeRequest(final String fullyQualifiedEndpoint, boolean includeAuth) + throws Exception { + final Client client = ClientBuilder.newBuilder().build(); + + client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); + client.register(GsonMessageBodyHandler.class); + + if (includeAuth) { + client.register(HttpAuthenticationFeature.basic("participantUser", "zb!XztG34")); + } + + final WebTarget webTarget = client.target(fullyQualifiedEndpoint); + + return webTarget.request(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN); + } + + /** + * Assert that GET call to actuator endpoint is Unauthorized. + * + * @param endPoint the endpoint + * @throws Exception if an error occurs + */ + protected void assertUnauthorizedActGet(final String endPoint) throws Exception { + Response rawresp = sendNoAuthActRequest(endPoint).buildGet().invoke(); + assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); + } + + /** + * Set Up httpPrefix. + * + * @param port the port + */ + protected void setHttpPrefix(int port) { + httpPrefix = "http://" + SELF + ":" + port + "/"; + } + +} diff --git a/participant/participant-impl/participant-impl-policy/src/test/resources/application_test.properties b/participant/participant-impl/participant-impl-policy/src/test/resources/application_test.properties index 70d52b413..f857704d3 100644 --- a/participant/participant-impl/participant-impl-policy/src/test/resources/application_test.properties +++ b/participant/participant-impl/participant-impl-policy/src/test/resources/application_test.properties @@ -1,5 +1,8 @@ -server.servlet.context-path=/onap/participantsim +spring.security.user.name=participantUser +spring.security.user.password=zb!XztG34 +server.servlet.context-path=/onap/policyparticipant server.error.path=/error +server.http-port=8085 participant.policyApiParameters.clientName=api participant.policyApiParameters.hostname=localhost @@ -22,3 +25,4 @@ participant.intermediaryParameters.clampControlLoopTopics.topicSources[0].fetchT participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].topic=POLICY-CLRUNTIME-PARTICIPANT participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].servers[0]=localhost participant.intermediaryParameters.clampControlLoopTopics.topicSinks[0].topicCommInfrastructure=dmaap +management.endpoints.web.exposure.include=health,metrics,prometheus -- cgit 1.2.3-korg