diff options
6 files changed, 450 insertions, 1 deletions
diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/PapRestServer.java b/main/src/main/java/org/onap/policy/pap/main/rest/PapRestServer.java index 87db6ad3..85c6f3c6 100644 --- a/main/src/main/java/org/onap/policy/pap/main/rest/PapRestServer.java +++ b/main/src/main/java/org/onap/policy/pap/main/rest/PapRestServer.java @@ -98,7 +98,8 @@ public class PapRestServer implements Startable { PdpGroupDeployControllerV1.class.getName(), PdpGroupDeleteControllerV1.class.getName(), PdpGroupStateChangeControllerV1.class.getName(), - PdpGroupQueryControllerV1.class.getName())); + PdpGroupQueryControllerV1.class.getName(), + PdpGroupHealthCheckControllerV1.class.getName())); props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, "false"); props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SWAGGER_SUFFIX, "true"); props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_AUTH_USERNAME_SUFFIX, diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupHealthCheckControllerV1.java b/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupHealthCheckControllerV1.java new file mode 100644 index 00000000..752d382c --- /dev/null +++ b/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupHealthCheckControllerV1.java @@ -0,0 +1,102 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 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.pap.main.rest; + +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Authorization; +import io.swagger.annotations.Extension; +import io.swagger.annotations.ExtensionProperty; +import io.swagger.annotations.ResponseHeader; + +import java.util.UUID; + +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.commons.lang3.tuple.Pair; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.pdp.concepts.Pdps; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class to provide REST end point for PAP component to fetch health status of all PDPs registered with PAP. + * + * @author Ram Krishna Verma (ram.krishna.verma@est.tech) + */ +public class PdpGroupHealthCheckControllerV1 extends PapRestControllerV1 { + + private static final Logger LOGGER = LoggerFactory.getLogger(PdpGroupHealthCheckControllerV1.class); + + private final PdpGroupHealthCheckProvider provider = new PdpGroupHealthCheckProvider(); + + /** + * Returns health status of all PDPs registered with PAP. + * + * @param requestId request ID used in ONAP logging + * @return a response + */ + // @formatter:off + @GET + @Path("pdps/healthcheck") + @ApiOperation(value = "Returns health status of all PDPs registered with PAP", + notes = "Queries health status of all PDPs, returning all pdps health status", + response = Pdps.class, + tags = {"Policy Administration (PAP) API"}, + authorizations = @Authorization(value = AUTHORIZATION_TYPE), + responseHeaders = { + @ResponseHeader(name = VERSION_MINOR_NAME, description = VERSION_MINOR_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_PATCH_NAME, description = VERSION_PATCH_DESCRIPTION, + response = String.class), + @ResponseHeader(name = VERSION_LATEST_NAME, description = VERSION_LATEST_DESCRIPTION, + response = String.class), + @ResponseHeader(name = REQUEST_ID_NAME, description = REQUEST_ID_HDR_DESCRIPTION, + response = UUID.class)}, + extensions = {@Extension(name = EXTENSION_NAME, + properties = {@ExtensionProperty(name = API_VERSION_NAME, value = API_VERSION), + @ExtensionProperty(name = LAST_MOD_NAME, value = LAST_MOD_RELEASE)})}) + @ApiResponses(value = {@ApiResponse(code = AUTHENTICATION_ERROR_CODE, message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse(code = AUTHORIZATION_ERROR_CODE, message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse(code = SERVER_ERROR_CODE, message = SERVER_ERROR_MESSAGE)}) + // @formatter:on + + public Response pdpGroupHealthCheck( + @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) final UUID requestId) { + + try { + final Pair<Status, Pdps> pair = provider.fetchPdpGroupHealthStatus(); + return addLoggingHeaders(addVersionControlHeaders(Response.status(pair.getLeft())), requestId) + .entity(pair.getRight()).build(); + } catch (final PfModelException exp) { + LOGGER.info("pdpGroup health check failed", exp); + return addLoggingHeaders( + addVersionControlHeaders(Response.status(exp.getErrorResponse().getResponseCode())), requestId) + .entity(exp.getErrorResponse()).build(); + } + } +} diff --git a/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupHealthCheckProvider.java b/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupHealthCheckProvider.java new file mode 100644 index 00000000..12470b14 --- /dev/null +++ b/main/src/main/java/org/onap/policy/pap/main/rest/PdpGroupHealthCheckProvider.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 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.pap.main.rest; + +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.core.Response; + +import org.apache.commons.lang3.tuple.Pair; +import org.onap.policy.common.utils.services.Registry; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.pdp.concepts.Pdp; +import org.onap.policy.models.pdp.concepts.PdpGroup; +import org.onap.policy.models.pdp.concepts.PdpSubGroup; +import org.onap.policy.models.pdp.concepts.Pdps; +import org.onap.policy.models.provider.PolicyModelsProvider; +import org.onap.policy.pap.main.PapConstants; +import org.onap.policy.pap.main.PolicyModelsProviderFactoryWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provider for PAP component to to fetch health status of all PDPs registered with PAP. + * + * @author Ram Krishna Verma (ram.krishna.verma@est.tech) + */ +public class PdpGroupHealthCheckProvider { + + private static final Logger LOGGER = LoggerFactory.getLogger(PdpGroupHealthCheckProvider.class); + + /** + * Returns health status of all PDPs. + * + * @return a pair containing the status and the response + * @throws PfModelException in case of errors + */ + public Pair<Response.Status, Pdps> fetchPdpGroupHealthStatus() throws PfModelException { + + final Pdps pdps = new Pdps(); + final PolicyModelsProviderFactoryWrapper modelProviderWrapper = + Registry.get(PapConstants.REG_PAP_DAO_FACTORY, PolicyModelsProviderFactoryWrapper.class); + try (PolicyModelsProvider databaseProvider = modelProviderWrapper.create()) { + final List<PdpGroup> groups = databaseProvider.getPdpGroups(null); + final List<Pdp> pdpList = new ArrayList<>(); + for (final PdpGroup group : groups) { + for (final PdpSubGroup subGroup : group.getPdpSubgroups()) { + pdpList.addAll(subGroup.getPdpInstances()); + } + } + pdps.setPdpList(pdpList); + } + LOGGER.debug("PdpGroup HealthCheck Response - {}", pdps); + return Pair.of(Response.Status.OK, pdps); + } +} diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupHealthCheckControllerV1.java b/main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupHealthCheckControllerV1.java new file mode 100644 index 00000000..370582d0 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupHealthCheckControllerV1.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 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.pap.main.rest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import javax.ws.rs.client.Invocation; +import javax.ws.rs.core.Response; + +import org.junit.Test; +import org.onap.policy.models.pdp.concepts.Pdps; + +/** + * Class to perform unit test of {@link PdpGroupHealthCheckControllerV1}. + * + * @author Ram Krishna Verma (ram.krishna.verma@est.tech) + */ +public class TestPdpGroupHealthCheckControllerV1 extends CommonPapRestServer { + + private static final String ENDPOINT = "pdps/healthcheck"; + + @Test + public void testSwagger() throws Exception { + super.testSwagger(ENDPOINT); + } + + @Test + public void testPdpGroupHealthCheck() throws Exception { + final String uri = ENDPOINT; + + final Invocation.Builder invocationBuilder = sendRequest(uri); + Response rawresp = invocationBuilder.get(); + Pdps resp = rawresp.readEntity(Pdps.class); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + assertNotNull(resp); + + rawresp = invocationBuilder.get(); + resp = rawresp.readEntity(Pdps.class); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + assertNotNull(resp); + + // verify it fails when no authorization info is included + checkUnauthRequest(uri, req -> req.get()); + } +} diff --git a/main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupHealthCheckProvider.java b/main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupHealthCheckProvider.java new file mode 100644 index 00000000..977c5262 --- /dev/null +++ b/main/src/test/java/org/onap/policy/pap/main/rest/TestPdpGroupHealthCheckProvider.java @@ -0,0 +1,110 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 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.pap.main.rest; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.util.List; + +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.apache.commons.lang3.tuple.Pair; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.common.utils.services.Registry; +import org.onap.policy.models.pdp.concepts.Pdp; +import org.onap.policy.models.pdp.concepts.PdpGroup; +import org.onap.policy.models.pdp.concepts.PdpGroups; +import org.onap.policy.models.pdp.concepts.PdpSubGroup; +import org.onap.policy.models.pdp.concepts.Pdps; +import org.onap.policy.models.provider.PolicyModelsProvider; +import org.onap.policy.pap.main.PapConstants; +import org.onap.policy.pap.main.PolicyModelsProviderFactoryWrapper; + +/** + * Class to perform unit test of {@link PdpGroupHealthCheckProvider}. + * + * @author Ram Krishna Verma (ram.krishna.verma@est.tech) + */ +public class TestPdpGroupHealthCheckProvider { + + @Mock + private PolicyModelsProvider dao; + private PolicyModelsProviderFactoryWrapper daofact; + private List<PdpGroup> groups; + private Coder coder = new StandardCoder(); + + /** + * Configures DAO and mocks. + */ + @Before + public void setUp() throws Exception { + + Registry.newRegistry(); + MockitoAnnotations.initMocks(this); + daofact = mock(PolicyModelsProviderFactoryWrapper.class); + when(daofact.create()).thenReturn(dao); + + groups = loadFile("pdpGroup.json").getGroups(); + + when(dao.getPdpGroups(any())).thenReturn(groups); + + Registry.register(PapConstants.REG_PAP_DAO_FACTORY, daofact); + } + + @Test + public void testFetchPdpGroupHealthStatus() throws Exception { + final PdpGroupHealthCheckProvider provider = new PdpGroupHealthCheckProvider(); + final Pair<Status, Pdps> pair = provider.fetchPdpGroupHealthStatus(); + assertEquals(Response.Status.OK, pair.getLeft()); + verifyPdps(pair.getRight().getPdpList(), groups); + } + + private void verifyPdps(final List<Pdp> pdpList, final List<PdpGroup> groups) { + assertEquals(5, pdpList.size()); + for (final PdpGroup group : groups) { + for (final PdpSubGroup subGroup : group.getPdpSubgroups()) { + pdpList.containsAll(subGroup.getPdpInstances()); + } + } + } + + private PdpGroups loadFile(final String fileName) { + final File propFile = new File(ResourceUtils.getFilePath4Resource("rest/" + fileName)); + try { + return coder.decode(propFile, PdpGroups.class); + + } catch (final CoderException e) { + throw new RuntimeException(e); + } + } +} diff --git a/main/src/test/resources/rest/pdpGroup.json b/main/src/test/resources/rest/pdpGroup.json new file mode 100644 index 00000000..2a7b4edc --- /dev/null +++ b/main/src/test/resources/rest/pdpGroup.json @@ -0,0 +1,98 @@ +{ + "groups": [ + { + "name": "queryGroup1", + "description": "my description", + "pdpGroupState": "PASSIVE", + "properties": { + "abc": "def" + }, + "pdpSubgroups": [ + { + "pdpType": "pdpTypeA", + "currentInstanceCount": 3, + "desiredInstanceCount": 2, + "properties": { + "ten": 10 + }, + "pdpInstances": [ + { + "instanceId": "pdpAA_1", + "pdpState": "PASSIVE", + "healthy": "HEALTHY" + }, + { + "instanceId": "pdpAA_2", + "pdpState": "PASSIVE", + "healthy": "HEALTHY" + } + ], + "supportedPolicyTypes": [ + { + "name": "onap.policies.monitoring.cdap.tca.hi.lo.app", + "version": "1.0.0" + } + ], + "policies": [ + { + "name": "onap.restart.tca", + "version": "1.0.0" + } + ] + }, + { + "pdpType": "pdpTypeB", + "desiredInstanceCount": 1, + "pdpInstances": [ + { + "instanceId": "pdpAB_1", + "pdpState": "PASSIVE", + "healthy": "HEALTHY" + } + ], + "supportedPolicyTypes": [ + { + "name": "onap.policies.monitoring.cdap.tca.hi.lo.app", + "version": "1.0.0" + } + ], + "policies": [] + } + ] + }, + { + "name": "queryGroup2", + "pdpGroupState": "ACTIVE", + "pdpSubgroups": [ + { + "pdpType": "pdpTypeA", + "desiredInstanceCount": 2, + "pdpInstances": [ + { + "instanceId": "pdpBA_1", + "pdpState": "PASSIVE", + "healthy": "HEALTHY" + }, + { + "instanceId": "pdpBA_2", + "pdpState": "PASSIVE", + "healthy": "HEALTHY" + } + ], + "supportedPolicyTypes": [ + { + "name": "onap.policies.monitoring.cdap.tca.hi.lo.app", + "version": "1.0.0" + } + ], + "policies": [ + { + "name": "onap.restart.tcaB", + "version": "1.0.0" + } + ] + } + ] + } + ] +} |