diff options
Diffstat (limited to 'participant')
63 files changed, 2596 insertions, 2031 deletions
diff --git a/participant/participant-impl/participant-impl-dcae/pom.xml b/participant/participant-impl/participant-impl-dcae/pom.xml index 308084255..50a2a526d 100644 --- a/participant/participant-impl/participant-impl-dcae/pom.xml +++ b/participant/participant-impl/participant-impl-dcae/pom.xml @@ -34,10 +34,37 @@ <properties> <mockserver.version>5.11.2</mockserver.version> + <springboot.version>2.4.4</springboot.version> </properties> + <dependencyManagement> + <dependencies> + <!-- Spring Boot BOM --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-dependencies</artifactId> + <version>${springboot.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + <dependencies> <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-validation</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.mock-server</groupId> <artifactId>mockserver-netty</artifactId> <version>${mockserver.version}</version> @@ -50,4 +77,22 @@ <scope>test</scope> </dependency> </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <version>${springboot.version}</version> + <executions> + <execution> + <goals> + <goal>repackage</goal> + </goals> + <phase>package</phase> + </execution> + </executions> + </plugin> + </plugins> + </build> </project> diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/DcaeParticipantApplication.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/DcaeParticipantApplication.java new file mode 100644 index 000000000..25edaf552 --- /dev/null +++ b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/DcaeParticipantApplication.java @@ -0,0 +1,41 @@ +/*-
+ * ============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.dcae;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
+import org.springframework.context.annotation.ComponentScan;
+
+/**
+ * Starter.
+ *
+ */
+@SpringBootApplication
+@ComponentScan({"org.onap.policy.clamp.controlloop.participant.dcae",
+ "org.onap.policy.clamp.controlloop.participant.intermediary"})
+@ConfigurationPropertiesScan("org.onap.policy.clamp.controlloop.participant.dcae.main.parameters")
+public class DcaeParticipantApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(DcaeParticipantApplication.class, args);
+ }
+}
diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/config/ParametersConfig.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/config/ParametersConfig.java new file mode 100644 index 000000000..ee649c993 --- /dev/null +++ b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/config/ParametersConfig.java @@ -0,0 +1,40 @@ +/*- + * ============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.dcae.config; + +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; +import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameterHandler; +import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ParametersConfig { + + @Value("${participant.file}") + private String file; + + @Bean + public ParticipantDcaeParameters participantDcaeParameters() throws ControlLoopException { + return new ParticipantDcaeParameterHandler().toParticipantDcaeParameters(file); + } +} diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/config/ParticipantConfig.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/config/ParticipantConfig.java new file mode 100644 index 000000000..ff828abab --- /dev/null +++ b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/config/ParticipantConfig.java @@ -0,0 +1,49 @@ +/*- + * ============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.dcae.config; + +import org.onap.policy.clamp.controlloop.participant.dcae.main.handler.ControlLoopElementHandler; +import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ParticipantConfig { + + /** + * Create ParticipantIntermediaryApi. + * + * @param parameters the Participant Dcae Parameters + * @param clElementHandler the ControlLoop Element Handler + * @return ParticipantIntermediaryApi + */ + @Bean + public ParticipantIntermediaryApi participantIntermediaryApi(ParticipantDcaeParameters parameters, + ControlLoopElementHandler clElementHandler) { + ParticipantIntermediaryApi intermediaryApi = new ParticipantIntermediaryFactory().createApiImplementation(); + intermediaryApi.init(parameters.getIntermediaryParameters()); + intermediaryApi.registerControlLoopElementListener(clElementHandler); + clElementHandler.setIntermediaryApi(intermediaryApi); + return intermediaryApi; + } +} diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/AbstractHttpClient.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/AbstractHttpClient.java index b2d0b61d0..e23aaaf23 100644 --- a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/AbstractHttpClient.java +++ b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/AbstractHttpClient.java @@ -22,133 +22,89 @@ package org.onap.policy.clamp.controlloop.participant.dcae.httpclient; import java.io.Closeable; import java.io.IOException; +import java.util.Collections; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; -import org.apache.http.HttpEntity; -import org.apache.http.HttpHost; -import org.apache.http.HttpRequest; -import org.apache.http.ParseException; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.AuthCache; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.conn.ssl.NoopHostnameVerifier; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.TrustSelfSignedStrategy; -import org.apache.http.impl.auth.BasicScheme; -import org.apache.http.impl.client.BasicAuthCache; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.ssl.SSLContextBuilder; -import org.apache.http.util.EntityUtils; import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; import org.onap.policy.clamp.controlloop.participant.dcae.model.Loop; -import org.onap.policy.common.endpoints.parameters.RestServerParameters; +import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; +import org.onap.policy.common.endpoints.http.client.HttpClient; +import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance; 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.slf4j.Logger; import org.slf4j.LoggerFactory; public abstract class AbstractHttpClient implements Closeable { + private static final String MSG_REQUEST_FAILED = "request to {} failed"; + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractHttpClient.class); - private final HttpClientContext localContext; - private final CloseableHttpClient httpclient; - private final HttpHost target; + private final HttpClient httpclient; public static final Coder CODER = new StandardCoder(); /** * Constructor. */ - protected AbstractHttpClient(RestServerParameters restServerParameters) { + protected AbstractHttpClient(BusTopicParams restClientParameters) { try { - final String scheme = restServerParameters.isHttps() ? "https" : "http"; - target = new HttpHost(restServerParameters.getHost(), restServerParameters.getPort(), scheme); - - CredentialsProvider credsProvider = new BasicCredentialsProvider(); - credsProvider.setCredentials(new AuthScope(target.getHostName(), target.getPort()), - new UsernamePasswordCredentials(restServerParameters.getUserName(), - restServerParameters.getPassword())); - - AuthCache authCache = new BasicAuthCache(); - BasicScheme basicAuth = new BasicScheme(); - authCache.put(target, basicAuth); - localContext = HttpClientContext.create(); - localContext.setAuthCache(authCache); - - HttpClientBuilder builder = HttpClients.custom().setDefaultCredentialsProvider(credsProvider); - if (restServerParameters.isHttps()) { - final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(new SSLContextBuilder() - .loadTrustMaterial(null, new TrustSelfSignedStrategy()).setProtocol("TLSv1.2").build(), - new NoopHostnameVerifier()); - builder.setSSLSocketFactory(sslsf); - } - httpclient = builder.build(); - + httpclient = HttpClientFactoryInstance.getClientFactory().build(restClientParameters); } catch (final Exception e) { throw new ControlLoopRuntimeException(Status.INTERNAL_SERVER_ERROR, - restServerParameters.getName() + " Client failed to start", e); + restClientParameters.getClientName() + " Client failed to start", e); } } - CloseableHttpResponse execute(HttpRequest request) throws IOException { - return httpclient.execute(target, request, localContext); + protected boolean executePut(String path, String jsonEntity, int statusCode) { + try { + Response response = httpclient.put(path, Entity.json(jsonEntity), Collections.emptyMap()); + return response.getStatus() == statusCode; + } catch (Exception e) { + LOGGER.error(MSG_REQUEST_FAILED, httpclient.getName(), e); + return false; + } } protected boolean executePut(String path, int statusCode) { - try (CloseableHttpResponse response = execute(new HttpPut(path))) { - return response.getStatusLine().getStatusCode() == statusCode; + try { + Response response = httpclient.put(path, Entity.json(""), Collections.emptyMap()); + return response.getStatus() == statusCode; } catch (Exception e) { + LOGGER.error(MSG_REQUEST_FAILED, httpclient.getName(), e); return false; } } protected Loop executePost(String path, int statusCode) { - try (CloseableHttpResponse response = execute(new HttpPost(path))) { - if (response.getStatusLine().getStatusCode() != statusCode) { + try { + Response response = httpclient.post(path, Entity.json(""), Collections.emptyMap()); + if (response.getStatus() != statusCode) { return null; } - return entityToMap(response.getEntity()); + return response.readEntity(Loop.class); } catch (Exception e) { + LOGGER.error(MSG_REQUEST_FAILED, httpclient.getName(), e); return null; } } protected Loop executeGet(String path, int statusCode) { - try (CloseableHttpResponse response = execute(new HttpGet(path))) { - if (response.getStatusLine().getStatusCode() != statusCode) { + try { + Response response = httpclient.get(path); + + if (response.getStatus() != statusCode) { return null; } - return entityToMap(response.getEntity()); + return response.readEntity(Loop.class); } catch (Exception e) { + LOGGER.error(MSG_REQUEST_FAILED, httpclient.getName(), e); return null; } } - private Loop entityToMap(HttpEntity httpEntity) { - if (httpEntity == null) { - return new Loop(); - } - try { - return CODER.convert(EntityUtils.toString(httpEntity), Loop.class); - } catch (ParseException | IOException e) { - LOGGER.error("error reading Entity", e); - return new Loop(); - } catch (CoderException e) { - LOGGER.error("cannot convert to Loop Object", e); - return new Loop(); - } - } - @Override public void close() throws IOException { - httpclient.close(); + httpclient.shutdown(); } } diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ClampHttpClient.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ClampHttpClient.java index eb805054d..e928c138f 100644 --- a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ClampHttpClient.java +++ b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ClampHttpClient.java @@ -21,19 +21,16 @@ package org.onap.policy.clamp.controlloop.participant.dcae.httpclient; import org.apache.http.HttpStatus; +import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters; import org.onap.policy.clamp.controlloop.participant.dcae.model.ExternalComponent; import org.onap.policy.clamp.controlloop.participant.dcae.model.Loop; -import org.onap.policy.common.endpoints.parameters.RestServerParameters; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +@Component public class ClampHttpClient extends AbstractHttpClient { - private static final Logger LOGGER = LoggerFactory.getLogger(ClampHttpClient.class); - private static final String STATUS = "/restservices/clds/v2/loop/getstatus/"; private static final String CREATE = "/restservices/clds/v2/loop/create/%s?templateName=%s"; - private static final String UPDATE = "/restservices/clds/v2/loop/updateMicroservicePolicy/"; private static final String DEPLOY = "/restservices/clds/v2/loop/deploy/"; private static final String STOP = "/restservices/clds/v2/loop/stop/"; private static final String DELETE = "/restservices/clds/v2/loop/delete/"; @@ -44,8 +41,8 @@ public class ClampHttpClient extends AbstractHttpClient { /** * Constructor. */ - public ClampHttpClient(RestServerParameters restServerParameters) { - super(restServerParameters); + public ClampHttpClient(ParticipantDcaeParameters parameters) { + super(parameters.getClampClientParameters()); } /** @@ -60,23 +57,12 @@ public class ClampHttpClient extends AbstractHttpClient { } /** - * Update. - * - * @param loopName the loopName - * @param jsonEntity the Json entity - * @return true - */ - public boolean update(String loopName, String jsonEntity) { - return executePost(UPDATE + loopName, HttpStatus.SC_OK) != null; - } - - /** * Deploy. * * @param loopName the loopName * @return true */ - public boolean deploy(String loopName) { // DCAE + public boolean deploy(String loopName) { return executePut(DEPLOY + loopName, HttpStatus.SC_ACCEPTED); } diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ConsulDcaeHttpClient.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ConsulDcaeHttpClient.java index cd84a2feb..4f76e3025 100644 --- a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ConsulDcaeHttpClient.java +++ b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ConsulDcaeHttpClient.java @@ -21,26 +21,28 @@ package org.onap.policy.clamp.controlloop.participant.dcae.httpclient; import org.apache.http.HttpStatus; -import org.onap.policy.common.endpoints.parameters.RestServerParameters; +import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters; +import org.springframework.stereotype.Component; +@Component public class ConsulDcaeHttpClient extends AbstractHttpClient { - private static final String DEPLOY = "/v1/kv/dcae-pmsh:policy"; + private static final String DEPLOY = "/v1/kv/dcae-pmsh:"; /** - * constructor. + * Constructor. */ - public ConsulDcaeHttpClient(RestServerParameters restServerParameters) { - super(restServerParameters); + public ConsulDcaeHttpClient(ParticipantDcaeParameters parameters) { + super(parameters.getConsulClientParameters()); } /** - * call consult. + * Call consult. * * @param jsonEntity the Entity * @return true */ - public boolean deploy(String jsonEntity) { - return executePut(DEPLOY + jsonEntity, HttpStatus.SC_ACCEPTED); + public boolean deploy(String name, String jsonEntity) { + return executePut(DEPLOY + name, jsonEntity, HttpStatus.SC_OK); } } diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/ControlLoopElementHandler.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/ControlLoopElementHandler.java index 96677f320..76ed1122c 100644 --- a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/ControlLoopElementHandler.java +++ b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/ControlLoopElementHandler.java @@ -20,11 +20,10 @@ package org.onap.policy.clamp.controlloop.participant.dcae.main.handler; -import java.io.Closeable; -import java.io.IOException; import java.time.Instant; import java.util.UUID; import java.util.concurrent.TimeUnit; +import lombok.Setter; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; @@ -33,23 +32,29 @@ import org.onap.policy.clamp.controlloop.participant.dcae.httpclient.ClampHttpCl import org.onap.policy.clamp.controlloop.participant.dcae.httpclient.ConsulDcaeHttpClient; import org.onap.policy.clamp.controlloop.participant.dcae.model.Loop; import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; -import org.onap.policy.common.endpoints.parameters.RestServerParameters; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; /** * This class handles implementation of controlLoopElement updates. */ -public class ControlLoopElementHandler implements ControlLoopElementListener, Closeable { +@Component +public class ControlLoopElementHandler implements ControlLoopElementListener { private static final Logger LOGGER = LoggerFactory.getLogger(ControlLoopElementHandler.class); private final ClampHttpClient clampClient; private final ConsulDcaeHttpClient consulClient; + @Setter + private ParticipantIntermediaryApi intermediaryApi; + private static final String LOOP = "pmsh_loop"; private static final String TEMPLATE = "LOOP_TEMPLATE_k8s_pmsh"; + private static final String POLICY = "policy"; private static final String BLUEPRINT_DEPLOYED = "BLUEPRINT_DEPLOYED"; private static final String MICROSERVICE_INSTALLED_SUCCESSFULLY = "MICROSERVICE_INSTALLED_SUCCESSFULLY"; @@ -70,9 +75,9 @@ public class ControlLoopElementHandler implements ControlLoopElementListener, Cl /** * Constructor. */ - public ControlLoopElementHandler(RestServerParameters clampParameters, RestServerParameters consulParameters) { - clampClient = new ClampHttpClient(clampParameters); - consulClient = new ConsulDcaeHttpClient(consulParameters); + public ControlLoopElementHandler(ClampHttpClient clampClient, ConsulDcaeHttpClient consulClient) { + this.clampClient = clampClient; + this.consulClient = consulClient; } /** @@ -90,17 +95,15 @@ public class ControlLoopElementHandler implements ControlLoopElementListener, Cl Loop loop = clampClient.getstatus(LOOP); if (loop != null) { clampClient.undeploy(LOOP); - DcaeHandler.getInstance().getDcaeProvider().getIntermediaryApi() - .updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.UNINITIALISED); + intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, + ControlLoopState.UNINITIALISED); } break; case PASSIVE: - DcaeHandler.getInstance().getDcaeProvider().getIntermediaryApi() - .updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.PASSIVE); + intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.PASSIVE); break; case RUNNING: - DcaeHandler.getInstance().getDcaeProvider().getIntermediaryApi() - .updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.RUNNING); + intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.RUNNING); break; default: LOGGER.debug("Unknown orderedstate {}", newState); @@ -120,7 +123,7 @@ public class ControlLoopElementHandler implements ControlLoopElementListener, Cl } private void deploy() throws PfModelException { - if (!consulClient.deploy(BODY_CONSUL)) { + if (!consulClient.deploy(POLICY, BODY_CONSUL)) { throw new PfModelException(null, "deploy to consul failed"); } if (!clampClient.deploy(LOOP)) { @@ -145,23 +148,21 @@ public class ControlLoopElementHandler implements ControlLoopElementListener, Cl deploy(); boolean deployedFlag = false; for (int i = 0; i < CHECK_COUNT; i++) { - //sleep 10 seconds + // sleep 10 seconds TimeUnit.SECONDS.sleep(CHECK_COUNT); loop = getStatus(); String status = ClampHttpClient.getStatusCode(loop); if (MICROSERVICE_INSTALLED_SUCCESSFULLY.equals(status)) { - DcaeHandler.getInstance().getDcaeProvider().getIntermediaryApi() - .updateControlLoopElementState(element.getId(), element.getOrderedState(), - ControlLoopState.PASSIVE); + intermediaryApi.updateControlLoopElementState(element.getId(), element.getOrderedState(), + ControlLoopState.PASSIVE); deployedFlag = true; break; } } if (!deployedFlag) { LOGGER.warn("DCAE is not deployed properly, ClElement state will be UNINITIALISED2PASSIVE"); - DcaeHandler.getInstance().getDcaeProvider().getIntermediaryApi() - .updateControlLoopElementState(element.getId(), element.getOrderedState(), - ControlLoopState.UNINITIALISED2PASSIVE); + intermediaryApi.updateControlLoopElementState(element.getId(), element.getOrderedState(), + ControlLoopState.UNINITIALISED2PASSIVE); } } } catch (PfModelException e) { @@ -178,20 +179,12 @@ public class ControlLoopElementHandler implements ControlLoopElementListener, Cl */ @Override public void handleStatistics(UUID controlLoopElementId) { - ControlLoopElement clElement = DcaeHandler.getInstance().getDcaeProvider() - .getIntermediaryApi().getControlLoopElement(controlLoopElementId); + ControlLoopElement clElement = intermediaryApi.getControlLoopElement(controlLoopElementId); if (clElement != null) { ClElementStatistics clElementStatistics = new ClElementStatistics(); clElementStatistics.setControlLoopState(clElement.getState()); clElementStatistics.setTimeStamp(Instant.now()); - DcaeHandler.getInstance().getDcaeProvider().getIntermediaryApi() - .updateControlLoopElementStatistics(controlLoopElementId, clElementStatistics); + intermediaryApi.updateControlLoopElementStatistics(controlLoopElementId, clElementStatistics); } } - - @Override - public void close() throws IOException { - clampClient.close(); - consulClient.close(); - } } diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/DcaeHandler.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/DcaeHandler.java deleted file mode 100644 index 1963e38b1..000000000 --- a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/DcaeHandler.java +++ /dev/null @@ -1,82 +0,0 @@ -/*- - * ============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.dcae.main.handler; - -import java.io.IOException; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import javax.ws.rs.core.Response; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler; -import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters; -import org.onap.policy.common.endpoints.event.comm.TopicSink; -import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher; -import org.onap.policy.common.utils.services.Registry; -import org.onap.policy.models.base.PfModelRuntimeException; - -/** - * This class handles dcae of participants and control loop elements. - * - * </p> - * It is effectively a singleton that is started at system start. - */ -public class DcaeHandler extends ControlLoopHandler { - - private final ParticipantDcaeParameters parameters; - @Getter - private DcaeProvider dcaeProvider; - - /** - * Create a handler. - * - * @param parameters the parameters for access to the database - */ - public DcaeHandler(ParticipantDcaeParameters parameters) { - super(parameters.getDatabaseProviderParameters()); - this.parameters = parameters; - } - - public static DcaeHandler getInstance() { - return Registry.get(DcaeHandler.class.getName()); - } - - @Override - public Set<Class<?>> getProviderClasses() { - return Collections.emptySet(); - } - - @Override - public void startProviders() { - dcaeProvider = new DcaeProvider(parameters); - } - - @Override - public void stopProviders() { - try { - dcaeProvider.close(); - } catch (IOException e) { - throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()); - } finally { - dcaeProvider = null; - } - } -} diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/DcaeProvider.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/DcaeProvider.java deleted file mode 100644 index afaf1c754..000000000 --- a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/DcaeProvider.java +++ /dev/null @@ -1,133 +0,0 @@ -/*- - * ============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.dcae.main.handler; - -import java.io.Closeable; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; -import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant; -import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse; -import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryFactory; - -/** - * This provider class dcae of participants and control loop elements. - */ -public class DcaeProvider implements Closeable { - @Getter - private final ParticipantIntermediaryApi intermediaryApi; - - private final ControlLoopElementHandler clElementHandler; - - /** - * Create a participant dcae provider. - * - * @throws ControlLoopRuntimeException on errors creating the provider - */ - public DcaeProvider(ParticipantDcaeParameters parameters) throws ControlLoopRuntimeException { - intermediaryApi = new ParticipantIntermediaryFactory().createApiImplementation(); - intermediaryApi.init(parameters.getIntermediaryParameters()); - clElementHandler = new ControlLoopElementHandler(parameters.getClampClientParameters(), - parameters.getConsulClientParameters()); - intermediaryApi.registerControlLoopElementListener(clElementHandler); - } - - @Override - public void close() throws IOException { - intermediaryApi.close(); - clElementHandler.close(); - } - - /** - * Get the control loops. - * - * @param name the controlLoop, null to get all - * @param version the controlLoop, null to get all - * @return the control loops - * @throws ControlLoopException on errors getting the control loops - */ - public ControlLoops getControlLoops(String name, String version) throws ControlLoopException { - return intermediaryApi.getControlLoops(name, version); - } - - /** - * Get the dcae control loop elements. - * - * @param name the controlLoopElement, null to get all - * @param version the controlLoopElement, null to get all - * @return the control loop elements - * @throws ControlLoopException on errors getting the control loop elements - */ - public Map<UUID, ControlLoopElement> getControlLoopElements(String name, String version) - throws ControlLoopException { - return intermediaryApi.getControlLoopElements(name, version); - } - - /** - * Update the given control loop element in the dcae. - * - * @param element the control loop element to update - * @return response simple response returned - * @throws ControlLoopException on errors updating the control loop element - */ - public TypedSimpleResponse<ControlLoopElement> updateControlLoopElement(ControlLoopElement element) - throws ControlLoopException { - TypedSimpleResponse<ControlLoopElement> response = new TypedSimpleResponse<>(); - response.setResponse(intermediaryApi.updateControlLoopElementState(element.getId(), - element.getOrderedState(), element.getState())); - return response; - } - - /** - * Get the current dcae participants. - * - * @param name the participant, null to get all - * @param version the participant, null to get all - * @return the list of participants - * @throws ControlLoopException on errors getting the participants - */ - public List<Participant> getParticipants(String name, String version) throws ControlLoopException { - return intermediaryApi.getParticipants(name, version); - } - - /** - * Update a dcae participant. - * - * @param participant the participant to update - * @return TypedSimpleResponse simple response - * @throws ControlLoopException on errors updating the participant - */ - - public TypedSimpleResponse<Participant> updateParticipant(Participant participant) throws ControlLoopException { - TypedSimpleResponse<Participant> response = new TypedSimpleResponse<>(); - response.setResponse( - intermediaryApi.updateParticipantState(participant.getDefinition(), participant.getParticipantState())); - return response; - } -} diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/ParticipantDcaeParameterHandler.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/ParticipantDcaeParameterHandler.java index 8d9bef98c..689bb40c2 100644 --- a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/ParticipantDcaeParameterHandler.java +++ b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/ParticipantDcaeParameterHandler.java @@ -23,56 +23,60 @@ package org.onap.policy.clamp.controlloop.participant.dcae.main.parameters; import java.io.File; import javax.ws.rs.core.Response; import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.participant.dcae.main.startstop.ParticipantDcaeCommandLineArguments; -import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.BeanValidationResult; 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.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This class handles reading, parsing and validating of control loop runtime parameters from JSON files. */ public class ParticipantDcaeParameterHandler { + private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantDcaeParameterHandler.class); + private static final Coder CODER = new StandardCoder(); /** - * Read the parameters from the parameter file. + * Read the parameters from the path of the file. * - * @param arguments the arguments passed to dcae + * @param path path of the config file. * @return the parameters read from the configuration file * @throws ControlLoopException on parameter exceptions */ - public ParticipantDcaeParameters getParameters(final ParticipantDcaeCommandLineArguments arguments) - throws ControlLoopException { + public ParticipantDcaeParameters toParticipantDcaeParameters(String path) throws ControlLoopException { ParticipantDcaeParameters parameters = null; - // Read the parameters try { // Read the parameters from JSON - File file = new File(arguments.getFullConfigurationFilePath()); + File file = new File(path); parameters = CODER.decode(file, ParticipantDcaeParameters.class); } catch (final CoderException e) { - final String errorMessage = "error reading parameters from \"" + arguments.getConfigurationFilePath() - + "\"\n" + "(" + e.getClass().getSimpleName() + ")"; + final String errorMessage = + "error reading parameters from \"" + path + "\"\n" + "(" + e.getClass().getSimpleName() + ")"; throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, errorMessage, e); } // The JSON processing returns null if there is an empty file if (parameters == null) { - final String errorMessage = "no parameters found in \"" + arguments.getConfigurationFilePath() + "\""; + final String errorMessage = "no parameters found in \"" + path + "\""; + LOGGER.error(errorMessage); throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, errorMessage); } // validate the parameters - final ValidationResult validationResult = parameters.validate(); + final BeanValidationResult validationResult = parameters.validate(); if (!validationResult.isValid()) { - String returnMessage = - "validation error(s) on parameters from \"" + arguments.getConfigurationFilePath() + "\"\n"; - returnMessage += validationResult.getResult(); + final String returnMessage = + "validation error(s) on parameters from \"" + path + "\"\n" + validationResult.getResult(); + + LOGGER.error(returnMessage); throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, returnMessage); } return parameters; } + } diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/ParticipantDcaeParameters.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/ParticipantDcaeParameters.java index beb273086..469a6fe79 100644 --- a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/ParticipantDcaeParameters.java +++ b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/ParticipantDcaeParameters.java @@ -24,7 +24,7 @@ import javax.validation.constraints.NotBlank; import lombok.Getter; import org.apache.commons.lang3.StringUtils; import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; -import org.onap.policy.common.endpoints.parameters.RestServerParameters; +import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams; import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.common.parameters.ParameterGroupImpl; import org.onap.policy.common.parameters.ValidationStatus; @@ -40,11 +40,14 @@ import org.onap.policy.models.provider.PolicyModelsProviderParameters; @NotBlank @Getter public class ParticipantDcaeParameters extends ParameterGroupImpl { + + private static final String MSG_IS_BLANK = "is blank"; + @Valid - private RestServerParameters clampClientParameters; + private BusTopicParams clampClientParameters; @Valid - private RestServerParameters consulClientParameters; + private BusTopicParams consulClientParameters; private ParticipantIntermediaryParameters intermediaryParameters; private PolicyModelsProviderParameters databaseProviderParameters; @@ -71,21 +74,21 @@ public class ParticipantDcaeParameters extends ParameterGroupImpl { return result; } - private BeanValidationResult checkMissingMandatoryParams(RestServerParameters clientParameters) { - BeanValidationResult result = new BeanValidationResult(clientParameters.getName(), clientParameters); - if (StringUtils.isBlank(clientParameters.getHost())) { - result.addResult("Host", clientParameters.getHost(), ValidationStatus.INVALID, "is blank"); + private BeanValidationResult checkMissingMandatoryParams(BusTopicParams clientParameters) { + BeanValidationResult result = new BeanValidationResult(clientParameters.getClientName(), clientParameters); + if (clientParameters.isHostnameInvalid()) { + result.addResult("Host", clientParameters.getHostname(), ValidationStatus.INVALID, MSG_IS_BLANK); } - if (StringUtils.isBlank(clientParameters.getName())) { - result.addResult("Name", clientParameters.getName(), ValidationStatus.INVALID, "is blank"); + if (clientParameters.isClientNameInvalid()) { + result.addResult("Name", clientParameters.getClientName(), ValidationStatus.INVALID, MSG_IS_BLANK); } if (StringUtils.isBlank(clientParameters.getPassword())) { - result.addResult("Password", clientParameters.getPassword(), ValidationStatus.INVALID, "is blank"); + result.addResult("Password", clientParameters.getPassword(), ValidationStatus.INVALID, MSG_IS_BLANK); } if (StringUtils.isBlank(clientParameters.getUserName())) { - result.addResult("UserName", clientParameters.getUserName(), ValidationStatus.INVALID, "is blank"); + result.addResult("UserName", clientParameters.getUserName(), ValidationStatus.INVALID, MSG_IS_BLANK); } - if (clientParameters.getPort() <= 0 || clientParameters.getPort() >= 65535) { + if (clientParameters.isPortInvalid()) { result.addResult("Port", clientParameters.getPort(), ValidationStatus.INVALID, "is not valid"); } return result; diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/Main.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/Main.java deleted file mode 100644 index 2b47a2c13..000000000 --- a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/Main.java +++ /dev/null @@ -1,151 +0,0 @@ -/*- - * ============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.dcae.main.startstop; - -import java.util.Arrays; -import javax.ws.rs.core.Response; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.common.ControlLoopConstants; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameterHandler; -import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters; -import org.onap.policy.common.utils.resources.MessageConstants; -import org.onap.policy.common.utils.services.Registry; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This class initiates ONAP Policy Framework Control Loop participant component. - */ -public class Main { - - private static final Logger LOGGER = LoggerFactory.getLogger(Main.class); - - private ParticipantDcaeActivator activator; - - @Getter - private ParticipantDcaeParameters parameterGroup; - - /** - * Instantiates the control loop participant service. - * - * @param args the command line arguments - */ - public Main(final String[] args) { - final String argumentString = Arrays.toString(args); - LOGGER.info("Starting the control loop participant service with arguments - {}", argumentString); - - // Check the arguments - final ParticipantDcaeCommandLineArguments arguments = new ParticipantDcaeCommandLineArguments(); - try { - // The arguments return a string if there is a message to print and we should exit - final String argumentMessage = arguments.parse(args); - if (argumentMessage != null) { - LOGGER.info(argumentMessage); - return; - } - // Validate that the arguments are sane - arguments.validate(); - - // Read the parameters - parameterGroup = new ParticipantDcaeParameterHandler().getParameters(arguments); - - // Now, create the activator for the service - activator = new ParticipantDcaeActivator(parameterGroup); - Registry.register(ControlLoopConstants.REG_CLRUNTIME_ACTIVATOR, activator); - - // Start the activator - activator.start(); - } catch (Exception exp) { - if (null != activator) { - Registry.unregister(ControlLoopConstants.REG_CLRUNTIME_ACTIVATOR); - } - throw new ControlLoopRuntimeException(Response.Status.BAD_REQUEST, - String.format(MessageConstants.START_FAILURE_MSG, MessageConstants.POLICY_CLAMP), exp); - } - - // Add a shutdown hook to shut everything down in an orderly manner - Runtime.getRuntime().addShutdownHook(new ClRuntimeShutdownHookClass()); - String successMsg = String.format(MessageConstants.START_SUCCESS_MSG, MessageConstants.POLICY_CLAMP); - LOGGER.info(successMsg); - } - - /** - * Check if main is running. - */ - public boolean isRunning() { - return activator != null && activator.isAlive(); - } - - /** - * Shut down Execution. - * - * @throws ControlLoopException on shutdown errors - */ - public void shutdown() throws ControlLoopException { - // clear the parameterGroup variable - parameterGroup = null; - - // clear the cl participant activator - if (activator != null) { - activator.stop(); - } - } - - /** - * The Class ClRuntimeShutdownHookClass terminates the control loop participant service - * when its run method is called. - */ - private class ClRuntimeShutdownHookClass extends Thread { - /* - * (non-Javadoc) - * - * @see java.lang.Runnable#run() - */ - @Override - public void run() { - if (!activator.isAlive()) { - return; - } - - try { - // Shutdown the control loop participant service and wait for everything to stop - activator.stop(); - } catch (final RuntimeException e) { - LOGGER.warn("error occured during shut down of the control loop participant service", e); - } - } - } - - /** - * The main method. - * - * @param args the arguments - */ - public static void main(final String[] args) { // NOSONAR - /* - * NOTE: arguments are validated by the constructor, thus sonar is disabled. - */ - - new Main(args); - } -} diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/ParticipantDcaeActivator.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/ParticipantDcaeActivator.java deleted file mode 100644 index d485895cf..000000000 --- a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/ParticipantDcaeActivator.java +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * ============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.dcae.main.startstop; - -import java.util.concurrent.atomic.AtomicReference; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.participant.dcae.main.handler.DcaeHandler; -import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters; -import org.onap.policy.common.utils.services.ServiceManagerContainer; - -/** - * This class activates the control loop runtime component as a complete service together with all its controllers, - * listeners & handlers. - */ -public class ParticipantDcaeActivator extends ServiceManagerContainer { - @Getter - private final ParticipantDcaeParameters parameters; - - /** - * Instantiate the activator for the dcae as a complete service. - * - * @param parameters the parameters for the control loop runtime service - */ - public ParticipantDcaeActivator(final ParticipantDcaeParameters parameters) { - this.parameters = parameters; - - final AtomicReference<DcaeHandler> dcaeHandler = new AtomicReference<>(); - - // @formatter:off - addAction("Dcae Handler", - () -> dcaeHandler.set(new DcaeHandler(parameters)), - () -> dcaeHandler.get().close()); - - addAction("Dcae Providers", - () -> dcaeHandler.get().startProviders(), - () -> dcaeHandler.get().stopProviders()); - - // @formatter:on - } -} diff --git a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/ParticipantDcaeCommandLineArguments.java b/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/ParticipantDcaeCommandLineArguments.java deleted file mode 100644 index 0bf382ab1..000000000 --- a/participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/ParticipantDcaeCommandLineArguments.java +++ /dev/null @@ -1,151 +0,0 @@ -/*- - * ============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.dcae.main.startstop; - -import java.io.File; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.net.URL; -import java.util.Arrays; -import javax.ws.rs.core.Response; -import lombok.Getter; -import lombok.Setter; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.commons.lang3.StringUtils; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.clamp.controlloop.common.startstop.CommonCommandLineArguments; -import org.onap.policy.common.utils.resources.ResourceUtils; - -/** - * This class reads and handles command line parameters for the control loop runtime service. - * - */ -public class ParticipantDcaeCommandLineArguments { - private static final String FILE_MESSAGE_PREAMBLE = " file \""; - private static final int HELP_LINE_LENGTH = 120; - - private final Options options; - private final CommonCommandLineArguments commonCommandLineArguments; - - @Getter() - @Setter() - private String configurationFilePath = null; - - /** - * Construct the options for the dcae participant. - */ - public ParticipantDcaeCommandLineArguments() { - options = new Options(); - commonCommandLineArguments = new CommonCommandLineArguments(options); - } - - /** - * Construct the options for the CLI editor and parse in the given arguments. - * - * @param args The command line arguments - */ - public ParticipantDcaeCommandLineArguments(final String[] args) { - // Set up the options with the default constructor - this(); - - // Parse the arguments - try { - parse(args); - } catch (final ControlLoopException e) { - throw new ControlLoopRuntimeException(Response.Status.NOT_ACCEPTABLE, - "parse error on dcae participant parameters", e); - } - } - - /** - * Parse the command line options. - * - * @param args The command line arguments - * @return a string with a message for help and version, or null if there is no message - * @throws ControlLoopException on command argument errors - */ - public String parse(final String[] args) throws ControlLoopException { - // Clear all our arguments - setConfigurationFilePath(null); - CommandLine commandLine = null; - try { - commandLine = new DefaultParser().parse(options, args); - } catch (final ParseException e) { - throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, - "invalid command line arguments specified : " + e.getMessage()); - } - - // Arguments left over after Commons CLI does its stuff - final String[] remainingArgs = commandLine.getArgs(); - - if (remainingArgs.length > 0) { - throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, - "too many command line arguments specified : " + Arrays.toString(args)); - } - - if (commandLine.hasOption('h')) { - return commonCommandLineArguments.help(Main.class.getName(), options); - } - - if (commandLine.hasOption('v')) { - return commonCommandLineArguments.version(); - } - - if (commandLine.hasOption('c')) { - setConfigurationFilePath(commandLine.getOptionValue('c')); - } - - return null; - } - - /** - * Validate the command line options. - * - * @throws ControlLoopException on command argument validation errors - */ - public void validate() throws ControlLoopException { - commonCommandLineArguments.validate(configurationFilePath); - } - - /** - * Gets the full expanded configuration file path. - * - * @return the configuration file path - */ - public String getFullConfigurationFilePath() { - return ResourceUtils.getFilePath4Resource(getConfigurationFilePath()); - } - - /** - * Check set configuration file path. - * - * @return true, if check set configuration file path - */ - public boolean checkSetConfigurationFilePath() { - return !StringUtils.isEmpty(configurationFilePath); - } -} diff --git a/participant/participant-impl/participant-impl-dcae/src/main/resources/config/DCAEParticipantConfig.json b/participant/participant-impl/participant-impl-dcae/src/main/resources/config/DCAEParticipantConfig.json index 863c135d5..a7ea089b2 100644 --- a/participant/participant-impl/participant-impl-dcae/src/main/resources/config/DCAEParticipantConfig.json +++ b/participant/participant-impl/participant-impl-dcae/src/main/resources/config/DCAEParticipantConfig.json @@ -1,22 +1,21 @@ { "name": "ControlLoopParticipantDcae", "clampClientParameters": { - "name": "Clamp", - "host": "0.0.0.0", + "clientName": "Clamp", + "hostname": "0.0.0.0", "port": 8443, "userName": "admin", "password": "password", - "https": true, - "aaf": false + "useHttps": true, + "allowSelfSignedCerts": false }, "consulClientParameters": { - "name": "Consul", - "host": "consul", + "clientName": "Consul", + "hostname": "consul", "port": 31321, "userName": "admin", "password": "password", - "https": false, - "aaf": false + "useHttps": false }, "intermediaryParameters": { "name": "Participant parameters", diff --git a/participant/participant-impl/participant-impl-dcae/src/main/resources/config/application.yaml b/participant/participant-impl/participant-impl-dcae/src/main/resources/config/application.yaml new file mode 100644 index 000000000..58908cf8d --- /dev/null +++ b/participant/participant-impl/participant-impl-dcae/src/main/resources/config/application.yaml @@ -0,0 +1,3 @@ + +participant: + file: src/main/resources/config/DCAEParticipantConfig.json diff --git a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/endtoend/PartecipantDcaeTest.java b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/endtoend/PartecipantDcaeTest.java new file mode 100644 index 000000000..6d7592db0 --- /dev/null +++ b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/endtoend/PartecipantDcaeTest.java @@ -0,0 +1,171 @@ +/*- + * ============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.dcae.endtoend; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockserver.integration.ClientAndServer; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; +import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopStateChange; +import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopUpdate; +import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.CommonTestData; +import org.onap.policy.clamp.controlloop.participant.dcae.main.rest.TestListenerUtils; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ControlLoopStateChangeListener; +import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ControlLoopUpdateListener; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.utils.coder.CoderException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@TestPropertySource(properties = "participant.file=src/test/resources/parameters/TestParameters.json") +class PartecipantDcaeTest { + + private static final CommInfrastructure INFRA = CommInfrastructure.NOOP; + private static final String TOPIC = "my-topic"; + + private static final String LOOP = "pmsh_loop"; + private static final String BLUEPRINT_DEPLOYED = "BLUEPRINT_DEPLOYED"; + + private static ClientAndServer mockClampServer; + private static ClientAndServer mockConsulServer; + + @Autowired + private ParticipantIntermediaryApi participantIntermediaryApi; + + /** + * start Servers. + */ + @BeforeAll + public static void startServers() { + + // Clamp + mockClampServer = ClientAndServer.startClientAndServer(8443); + + mockClampServer.when(request().withMethod("GET").withPath("/restservices/clds/v2/loop/getstatus/" + LOOP)) + .respond(response().withBody(CommonTestData.createJsonStatus(BLUEPRINT_DEPLOYED).toString()) + .withStatusCode(200)); + + mockClampServer.when(request().withMethod("PUT").withPath("/restservices/clds/v2/loop/deploy/" + LOOP)) + .respond(response().withStatusCode(202)); + + mockClampServer.when(request().withMethod("PUT").withPath("/restservices/clds/v2/loop/undeploy/" + LOOP)) + .respond(response().withStatusCode(202)); + + // Consul + mockConsulServer = ClientAndServer.startClientAndServer(31321); + + mockConsulServer.when(request().withMethod("PUT").withPath("/v1/kv/dcae-pmsh:policy")) + .respond(response().withStatusCode(200)); + } + + /** + * stop Server. + */ + @AfterAll + public static void stopServer() { + mockClampServer.stop(); + mockClampServer = null; + + mockConsulServer.stop(); + mockConsulServer = null; + } + + @Test + void testParticipantControlLoopStateChangeMessageListener() { + ParticipantControlLoopStateChange participantControlLoopStateChangeMsg = + TestListenerUtils.createControlLoopStateChangeMsg(ControlLoopOrderedState.UNINITIALISED); + participantControlLoopStateChangeMsg.setOrderedState(ControlLoopOrderedState.PASSIVE); + + ControlLoopStateChangeListener clStateChangeListener = + new ControlLoopStateChangeListener(participantIntermediaryApi.getParticipantHandler()); + + clStateChangeListener.onTopicEvent(INFRA, TOPIC, null, participantControlLoopStateChangeMsg); + assertEquals(ControlLoopOrderedState.PASSIVE, participantControlLoopStateChangeMsg.getOrderedState()); + + participantControlLoopStateChangeMsg.setOrderedState(ControlLoopOrderedState.RUNNING); + clStateChangeListener.onTopicEvent(INFRA, TOPIC, null, participantControlLoopStateChangeMsg); + assertEquals(ControlLoopOrderedState.RUNNING, participantControlLoopStateChangeMsg.getOrderedState()); + + participantControlLoopStateChangeMsg.setOrderedState(ControlLoopOrderedState.RUNNING); + clStateChangeListener.onTopicEvent(INFRA, TOPIC, null, participantControlLoopStateChangeMsg); + assertEquals(ControlLoopOrderedState.RUNNING, participantControlLoopStateChangeMsg.getOrderedState()); + } + + @Test + void testControlLoopUpdateListener_ParticipantIdNoMatch() throws CoderException { + ParticipantControlLoopUpdate participantControlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg(); + participantControlLoopUpdateMsg.getParticipantId().setName("DummyName"); + participantControlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.PASSIVE); + + ControlLoopUpdateListener clUpdateListener = + new ControlLoopUpdateListener(participantIntermediaryApi.getParticipantHandler()); + clUpdateListener.onTopicEvent(INFRA, TOPIC, null, participantControlLoopUpdateMsg); + + // Verify the content in participantHandler + assertNotEquals(participantControlLoopUpdateMsg.getParticipantId().getName(), + participantIntermediaryApi.getParticipantHandler().getParticipantId().getName()); + } + + @Test + void testControlLoopUpdateListenerPassive() throws CoderException { + ParticipantControlLoopUpdate participantControlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg(); + participantControlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.PASSIVE); + + ControlLoopUpdateListener clUpdateListener = + new ControlLoopUpdateListener(participantIntermediaryApi.getParticipantHandler()); + clUpdateListener.onTopicEvent(INFRA, TOPIC, null, participantControlLoopUpdateMsg); + + // Verify the content in participantHandler + assertEquals(participantIntermediaryApi.getParticipantHandler().getParticipantId(), + participantControlLoopUpdateMsg.getParticipantId()); + assertEquals(1, participantIntermediaryApi.getParticipantHandler().getControlLoopHandler().getControlLoops() + .getControlLoopList().size()); + } + + @Test + void testControlLoopUpdateListenerUninitialised() throws CoderException { + ParticipantControlLoopUpdate participantControlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg(); + participantControlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.UNINITIALISED); + + ControlLoopUpdateListener clUpdateListener = + new ControlLoopUpdateListener(participantIntermediaryApi.getParticipantHandler()); + clUpdateListener.onTopicEvent(INFRA, TOPIC, null, participantControlLoopUpdateMsg); + + // Verify the content in participantHandler + assertEquals(participantIntermediaryApi.getParticipantHandler().getParticipantId(), + participantControlLoopUpdateMsg.getParticipantId()); + assertEquals(1, participantIntermediaryApi.getParticipantHandler().getControlLoopHandler().getControlLoops() + .getControlLoopList().size()); + } +} diff --git a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ClampHttpClientTest.java b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ClampHttpClientTest.java index 040b33f5e..6e375222e 100644 --- a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ClampHttpClientTest.java +++ b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ClampHttpClientTest.java @@ -26,21 +26,25 @@ import static org.junit.Assert.assertTrue; import static org.mockserver.model.HttpRequest.request; import static org.mockserver.model.HttpResponse.response; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import javax.ws.rs.core.MediaType; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockserver.integration.ClientAndServer; import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.CommonTestData; import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters; import org.onap.policy.clamp.controlloop.participant.dcae.model.Loop; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.StandardCoder; +import org.springframework.test.context.junit.jupiter.SpringExtension; /** * Class to perform unit test of {@link ClampHttpClient}. * */ -public class ClampHttpClientTest { +@ExtendWith(SpringExtension.class) +class ClampHttpClientTest { private static final String LOOP = "pmsh_loop"; private static final String BLUEPRINT_DEPLOYED = "BLUEPRINT_DEPLOYED"; @@ -52,7 +56,7 @@ public class ClampHttpClientTest { /** * Set up. */ - @BeforeClass + @BeforeAll public static void setUp() { CommonTestData commonTestData = new CommonTestData(); @@ -63,7 +67,8 @@ public class ClampHttpClientTest { mockServer = ClientAndServer.startClientAndServer(parameters.getClampClientParameters().getPort()); mockServer.when(request().withMethod("GET").withPath("/restservices/clds/v2/loop/getstatus/" + LOOP)) - .respond(response().withBody(CommonTestData.createJsonStatus(BLUEPRINT_DEPLOYED)).withStatusCode(200)); + .respond(response().withBody(CommonTestData.createJsonStatus(BLUEPRINT_DEPLOYED)).withStatusCode(200) + .withHeader("Content-Type", MediaType.APPLICATION_JSON)); mockServer.when(request().withMethod("PUT").withPath("/restservices/clds/v2/loop/deploy/" + LOOP)) .respond(response().withStatusCode(202)); @@ -72,15 +77,15 @@ public class ClampHttpClientTest { .respond(response().withStatusCode(202)); } - @AfterClass + @AfterAll public static void stopServer() { mockServer.stop(); mockServer = null; } @Test - public void test_getstatus() throws Exception { - try (ClampHttpClient client = new ClampHttpClient(parameters.getClampClientParameters())) { + void test_getstatus() throws Exception { + try (ClampHttpClient client = new ClampHttpClient(parameters)) { Loop status = client.getstatus(LOOP); @@ -95,8 +100,8 @@ public class ClampHttpClientTest { } @Test - public void test_deploy() throws Exception { - try (ClampHttpClient client = new ClampHttpClient(parameters.getClampClientParameters())) { + void test_deploy() throws Exception { + try (ClampHttpClient client = new ClampHttpClient(parameters)) { assertTrue(client.deploy(LOOP)); @@ -106,8 +111,8 @@ public class ClampHttpClientTest { } @Test - public void test_undeploy() throws Exception { - try (ClampHttpClient client = new ClampHttpClient(parameters.getClampClientParameters())) { + void test_undeploy() throws Exception { + try (ClampHttpClient client = new ClampHttpClient(parameters)) { assertTrue(client.undeploy(LOOP)); @@ -117,12 +122,12 @@ public class ClampHttpClientTest { } @Test - public void test_getStatusCodeNull() { + void test_getStatusCodeNull() { assertThat(ClampHttpClient.getStatusCode(null)).isEqualTo(ClampHttpClient.STATUS_NOT_FOUND); } @Test - public void test_getStatusEmptyMap() { + void test_getStatusEmptyMap() { assertThat(ClampHttpClient.getStatusCode(new Loop())).isEqualTo(ClampHttpClient.STATUS_NOT_FOUND); } } diff --git a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ConsulDcaeHttpClientTest.java b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ConsulDcaeHttpClientTest.java new file mode 100644 index 000000000..734919e4c --- /dev/null +++ b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/httpclient/ConsulDcaeHttpClientTest.java @@ -0,0 +1,77 @@ +/*- + * ============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.dcae.httpclient; + +import static org.junit.Assert.assertTrue; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockserver.integration.ClientAndServer; +import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.CommonTestData; +import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +/** + * Class to perform unit test of {@link ConsulDcaeHttpClient}. + * + */ +@ExtendWith(SpringExtension.class) +class ConsulDcaeHttpClientTest { + + private static ClientAndServer mockServer; + private static ParticipantDcaeParameters parameters; + + @BeforeAll + public static void startServer() { + CommonTestData commonTestData = new CommonTestData(); + + parameters = commonTestData.toObject( + commonTestData.getParticipantParameterGroupMap(CommonTestData.PARTICIPANT_GROUP_NAME), + ParticipantDcaeParameters.class); + + mockServer = ClientAndServer.startClientAndServer(parameters.getConsulClientParameters().getPort()); + + mockServer.when(request().withMethod("PUT").withPath("/v1/kv/dcae-pmsh:policy")) + .respond(response().withStatusCode(200)); + } + + @AfterAll + public static void stopServer() { + mockServer.stop(); + mockServer = null; + } + + @Test + void test_deploy() throws Exception { + try (ConsulDcaeHttpClient client = new ConsulDcaeHttpClient(parameters)) { + + assertTrue(client.deploy("policy", "")); + + } catch (Exception e) { + Assertions.fail(e.getMessage()); + } + } +} diff --git a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/CommonTestData.java b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/CommonTestData.java index bcfaf8bb9..cb06fcb15 100644 --- a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/CommonTestData.java +++ b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/CommonTestData.java @@ -35,6 +35,7 @@ import org.onap.policy.common.parameters.ParameterGroup; 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.network.NetworkUtil; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; /** @@ -47,10 +48,8 @@ public class CommonTestData { public static final List<TopicParameters> TOPIC_PARAMS = Arrays.asList(getTopicParams()); private static final String REST_CLIENT_PASSWORD = "password"; private static final String REST_CLIENT_USER = "admin"; - private static final int REST_CLAMP_PORT = 8443; - private static final int REST_CONSUL_PORT = 31321; - private static final String REST_CLAMP_HOST = "localhost"; - private static final String REST_CONSUL_HOST = "consul"; + private static final String REST_CLAMP_HOST = "0.0.0.0"; + private static final String REST_CONSUL_HOST = "0.0.0.0"; private static final boolean REST_CLAMP_HTTPS = false; private static final boolean REST_CONSUL_HTTPS = false; private static final boolean REST_CLIENT_AAF = false; @@ -99,12 +98,17 @@ public class CommonTestData { */ public Map<String, Object> getClampClientParametersMap(final boolean isEmpty) { final Map<String, Object> map = new TreeMap<>(); + map.put("clientName", "Clamp"); map.put("https", REST_CLAMP_HTTPS); map.put("aaf", REST_CLIENT_AAF); if (!isEmpty) { - map.put("host", REST_CLAMP_HOST); - map.put("port", REST_CLAMP_PORT); + map.put("hostname", REST_CLAMP_HOST); + try { + map.put("port", NetworkUtil.allocPort()); + } catch (IOException e) { + throw new ControlLoopRuntimeException(Response.Status.NOT_ACCEPTABLE, "not valid port", e); + } map.put("userName", REST_CLIENT_USER); map.put("password", REST_CLIENT_PASSWORD); } @@ -120,12 +124,17 @@ public class CommonTestData { */ public Map<String, Object> getConsulClientParametersMap(final boolean isEmpty) { final Map<String, Object> map = new TreeMap<>(); + map.put("clientName", "Consul"); map.put("https", REST_CONSUL_HTTPS); map.put("aaf", REST_CLIENT_AAF); if (!isEmpty) { - map.put("host", REST_CONSUL_HOST); - map.put("port", REST_CONSUL_PORT); + map.put("hostname", REST_CONSUL_HOST); + try { + map.put("port", NetworkUtil.allocPort()); + } catch (IOException e) { + throw new ControlLoopRuntimeException(Response.Status.NOT_ACCEPTABLE, "not valid port", e); + } map.put("userName", REST_CLIENT_USER); map.put("password", REST_CLIENT_PASSWORD); } @@ -209,7 +218,7 @@ public class CommonTestData { */ public static ToscaConceptIdentifier getParticipantId() { final ToscaConceptIdentifier participantId = new ToscaConceptIdentifier(); - participantId.setName("CDSParticipant0"); + participantId.setName("DCAEParticipant0"); participantId.setVersion("1.0.0"); return participantId; } @@ -276,7 +285,7 @@ public class CommonTestData { } /** - * create Json response from getstatus call. + * Create Json response from getstatus call. * * @param status the status of Partecipant * @return the JSON diff --git a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/TestParticipantDcaeParameterHandler.java b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/TestParticipantDcaeParameterHandler.java index 058a3dae4..2eb833204 100644 --- a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/TestParticipantDcaeParameterHandler.java +++ b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/TestParticipantDcaeParameterHandler.java @@ -20,83 +20,45 @@ package org.onap.policy.clamp.controlloop.participant.dcae.main.parameters; -import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import java.io.FileNotFoundException; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameterHandler; -import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters; -import org.onap.policy.clamp.controlloop.participant.dcae.main.startstop.ParticipantDcaeCommandLineArguments; import org.onap.policy.common.utils.coder.CoderException; + /** * Class to perform unit test of {@link ParticipantParameterHandler}. * */ -public class TestParticipantDcaeParameterHandler { +class TestParticipantDcaeParameterHandler { @Test - public void testParameterHandlerNoParameterFile() throws ControlLoopException { - final String[] emptyArgumentString = { "-c", "src/test/resources/parameters/NoParametersFile.json" }; - - final ParticipantDcaeCommandLineArguments emptyArguments = new ParticipantDcaeCommandLineArguments(); - emptyArguments.parse(emptyArgumentString); + void testParameterHandlerNoParameterFile() throws ControlLoopException { + final String path = "src/test/resources/parameters/NoParametersFile.json"; - assertThatThrownBy(() -> new ParticipantDcaeParameterHandler().getParameters(emptyArguments)) + assertThatThrownBy(() -> new ParticipantDcaeParameterHandler().toParticipantDcaeParameters(path)) .hasCauseInstanceOf(CoderException.class) .hasRootCauseInstanceOf(FileNotFoundException.class); } @Test - public void testParameterHandlerInvalidParameters() throws ControlLoopException { - final String[] invalidArgumentString = { "-c", "src/test/resources/parameters/InvalidParameters.json" }; + void testParameterHandlerInvalidParameters() throws ControlLoopException { + final String path = "src/test/resources/parameters/InvalidParameters.json"; - final ParticipantDcaeCommandLineArguments invalidArguments = - new ParticipantDcaeCommandLineArguments(); - invalidArguments.parse(invalidArgumentString); - - assertThatThrownBy(() -> new ParticipantDcaeParameterHandler().getParameters(invalidArguments)) + assertThatThrownBy(() -> new ParticipantDcaeParameterHandler().toParticipantDcaeParameters(path)) .hasMessageStartingWith("error reading parameters from") .hasCauseInstanceOf(CoderException.class); } @Test - public void testParticipantParameterGroup() throws ControlLoopException { - final String[] participantConfigParameters = { "-c", "src/test/resources/parameters/TestParameters.json" }; - - final ParticipantDcaeCommandLineArguments arguments = new ParticipantDcaeCommandLineArguments(); - arguments.parse(participantConfigParameters); + void testParticipantParameterGroup() throws ControlLoopException { + final String path = "src/test/resources/parameters/TestParameters.json"; final ParticipantDcaeParameters parGroup = new ParticipantDcaeParameterHandler() - .getParameters(arguments); - assertTrue(arguments.checkSetConfigurationFilePath()); + .toParticipantDcaeParameters(path); assertEquals(CommonTestData.PARTICIPANT_GROUP_NAME, parGroup.getName()); } - - @Test - public void testParticipantVersion() throws ControlLoopException { - final String[] participantConfigParameters = { "-v" }; - final ParticipantDcaeCommandLineArguments arguments = new ParticipantDcaeCommandLineArguments(); - assertThat(arguments.parse(participantConfigParameters)).startsWith( - "ONAP Tosca defined control loop Participant"); - } - - @Test - public void testParticipantHelp() throws ControlLoopException { - final String[] participantConfigParameters = { "-h" }; - final ParticipantDcaeCommandLineArguments arguments = new ParticipantDcaeCommandLineArguments(); - assertThat(arguments.parse(participantConfigParameters)).startsWith("usage:"); - } - - @Test - public void testParticipantInvalidOption() throws ControlLoopException { - final String[] participantConfigParameters = { "-d" }; - final ParticipantDcaeCommandLineArguments arguments = new ParticipantDcaeCommandLineArguments(); - assertThatThrownBy(() -> arguments.parse(participantConfigParameters)) - .hasMessageStartingWith("invalid command line arguments specified"); - } } diff --git a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/TestParticipantDcaeParameters.java b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/TestParticipantDcaeParameters.java index edb429322..2320ae07b 100644 --- a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/TestParticipantDcaeParameters.java +++ b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/parameters/TestParticipantDcaeParameters.java @@ -20,14 +20,12 @@ package org.onap.policy.clamp.controlloop.participant.dcae.main.parameters; -import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Map; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; import org.onap.policy.common.endpoints.parameters.TopicParameterGroup; import org.onap.policy.common.parameters.ValidationResult; @@ -36,17 +34,17 @@ import org.onap.policy.common.parameters.ValidationResult; * Class to perform unit test of {@link ParticipantParameterGroup}. * */ -public class TestParticipantDcaeParameters { +class TestParticipantDcaeParameters { CommonTestData commonTestData = new CommonTestData(); @Test - public void testParticipantParameterGroup_Named() { + void testParticipantParameterGroup_Named() { final ParticipantDcaeParameters participantParameters = new ParticipantDcaeParameters("my-name"); assertEquals("my-name", participantParameters.getName()); } @Test - public void testParticipantParameterGroup() { + void testParticipantParameterGroup() { final ParticipantDcaeParameters participantParameters = commonTestData.toObject( commonTestData.getParticipantParameterGroupMap(CommonTestData.PARTICIPANT_GROUP_NAME), ParticipantDcaeParameters.class); @@ -64,7 +62,7 @@ public class TestParticipantDcaeParameters { } @Test - public void testParticipantParameterGroup_EmptyParticipantIntermediaryParameters() { + void testParticipantParameterGroup_EmptyParticipantIntermediaryParameters() { final Map<String, Object> map = commonTestData.getParticipantParameterGroupMap(CommonTestData.PARTICIPANT_GROUP_NAME); map.replace("intermediaryParameters", commonTestData.getIntermediaryParametersMap(true)); @@ -75,7 +73,7 @@ public class TestParticipantDcaeParameters { } @Test - public void testParticipantParameterGroup_EmptyTopicParameters() { + void testParticipantParameterGroup_EmptyTopicParameters() { final Map<String, Object> map = commonTestData.getParticipantParameterGroupMap(CommonTestData.PARTICIPANT_GROUP_NAME); final Map<String, Object> intermediaryParametersMap = commonTestData.getIntermediaryParametersMap(false); diff --git a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/rest/TestListenerUtils.java b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/rest/TestListenerUtils.java index c3cc8b755..f414b7a10 100644 --- a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/rest/TestListenerUtils.java +++ b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/rest/TestListenerUtils.java @@ -25,7 +25,6 @@ import java.time.Instant; import java.util.LinkedHashMap; import java.util.Map; import java.util.UUID; -import lombok.Getter; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; @@ -35,10 +34,7 @@ import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.Parti import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopUpdate; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantHealthCheck; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStateChange; -import org.onap.policy.clamp.controlloop.participant.dcae.main.handler.DcaeProvider; import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.CommonTestData; -import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; @@ -55,23 +51,6 @@ public class TestListenerUtils { private static final String TOSCA_TEMPLATE_YAML = "examples/controlloop/PMSubscriptionHandling.yaml"; static CommonTestData commonTestData = new CommonTestData(); - @Getter - private static ParticipantHandler participantHandler; - - /** - * Method to initialize participantHandler. - */ - public static void initParticipantHandler() { - - final ParticipantDcaeParameters parameters = commonTestData.toObject( - commonTestData.getParticipantParameterGroupMap(CommonTestData.PARTICIPANT_GROUP_NAME), - ParticipantDcaeParameters.class); - - DcaeProvider dcaeProvider = new DcaeProvider(parameters); - - participantHandler = dcaeProvider.getIntermediaryApi().getParticipantHandler(); - } - /** * Method to create a controlLoop from a yaml file. * @@ -120,7 +99,7 @@ public class TestListenerUtils { public static ParticipantStateChange createParticipantStateChangeMsg(final ParticipantState participantState) { final ParticipantStateChange participantStateChangeMsg = new ParticipantStateChange(); ToscaConceptIdentifier participantId = new ToscaConceptIdentifier(); - participantId.setName("CDSParticipant0"); + participantId.setName("DCAEParticipant0"); participantId.setVersion("1.0.0"); participantStateChangeMsg.setParticipantId(participantId); @@ -146,7 +125,7 @@ public class TestListenerUtils { controlLoopId.setVersion("1.0.0"); ToscaConceptIdentifier participantId = new ToscaConceptIdentifier(); - participantId.setName("CDSParticipant0"); + participantId.setName("DCAEParticipant0"); participantId.setVersion("1.0.0"); participantClStateChangeMsg.setControlLoopId(controlLoopId); @@ -169,7 +148,7 @@ public class TestListenerUtils { controlLoopId.setVersion("1.0.0"); ToscaConceptIdentifier participantId = new ToscaConceptIdentifier(); - participantId.setName("CDSParticipant0"); + participantId.setName("DCAEParticipant0"); participantId.setVersion("1.0.0"); clUpdateMsg.setControlLoopId(controlLoopId); @@ -212,7 +191,7 @@ public class TestListenerUtils { */ public static ParticipantHealthCheck createParticipantHealthCheckMsg() { ToscaConceptIdentifier participantId = new ToscaConceptIdentifier(); - participantId.setName("CDSParticipant0"); + participantId.setName("DCAEParticipant0"); participantId.setVersion("1.0.0"); ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier(); diff --git a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/TestMain.java b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/TestMain.java deleted file mode 100644 index f779f3a57..000000000 --- a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/TestMain.java +++ /dev/null @@ -1,151 +0,0 @@ -/*- - * ============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.dcae.main.startstop; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.onap.policy.clamp.controlloop.common.ControlLoopConstants; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.clamp.controlloop.participant.dcae.main.startstop.Main; -import org.onap.policy.clamp.controlloop.participant.dcae.main.startstop.ParticipantDcaeActivator; -import org.onap.policy.common.utils.resources.MessageConstants; -import org.onap.policy.common.utils.services.Registry; - -/** - * Class to perform unit test of {@link Main}}. - */ -public class TestMain { - - /** - * Set up. - */ - @BeforeClass - public static void setUp() { - Registry.newRegistry(); - } - - /** - * Shuts "main" down. - * - * @throws Exception if an error occurs - */ - @AfterClass - public static void tearDown() throws Exception { - // shut down activator - final ParticipantDcaeActivator activator = - Registry.getOrDefault(ControlLoopConstants.REG_CLRUNTIME_ACTIVATOR, - ParticipantDcaeActivator.class, null); - if (activator != null && activator.isAlive()) { - activator.shutdown(); - } - } - - @Test - public void testMain_Help() { - final String[] configParameters = {"-h"}; - Main main = new Main(configParameters); - assertFalse(main.isRunning()); - } - - @Test - public void testMain_Version() { - final String[] configParameters = {"-v"}; - Main main = new Main(configParameters); - assertFalse(main.isRunning()); - } - - @Test - public void testMain_Valid() { - final String[] configParameters = {"-c", "src/test/resources/parameters/TestParameters.json"}; - Main main = new Main(configParameters); - assertTrue(main.isRunning()); - - // ensure items were added to the registry - assertNotNull(Registry.get(ControlLoopConstants.REG_CLRUNTIME_ACTIVATOR, ParticipantDcaeActivator.class)); - - assertThatCode(() -> main.shutdown()).doesNotThrowAnyException(); - - assertFalse(main.isRunning()); - } - - @Test - public void testMain_NoParameter() { - assertThatConfigParameterThrownException(new String[] {}); - } - - @Test - public void testMain_FilePathNotDefined() { - assertThatConfigParameterThrownException(new String[] {"-c"}); - } - - @Test - public void testMain_TooManyCommand() { - assertThatConfigParameterThrownException(new String[] {"-h", "d"}); - } - - @Test - public void testMain_WrongParameter() { - assertThatConfigParameterThrownException(new String[] {"-d"}); - } - - private void assertThatConfigParameterThrownException(final String[] configParameters) { - assertThatThrownBy(() -> Main.main(configParameters)).isInstanceOf(ControlLoopRuntimeException.class) - .hasMessage(String.format(MessageConstants.START_FAILURE_MSG, MessageConstants.POLICY_CLAMP)); - } - - @Test - public void testParticipant_NoFileWithThisName() { - assertThatConfigFileThrownException("src/test/resources/parameters/NoFileWithThisName.json"); - } - - @Test - public void testParticipant_NotValidFile() { - assertThatConfigFileThrownException("src/test/resources/parameters"); - } - - @Test - public void testParticipant_NoParameters() { - assertThatConfigFileThrownException("src/test/resources/parameters/NoParameters.json"); - } - - @Test - public void testParticipant_InvalidParameters() { - assertThatConfigFileThrownException("src/test/resources/parameters/InvalidParameters.json"); - } - - @Test - public void testParticipant_WrongJsonFormat() { - assertThatConfigFileThrownException("src/test/resources/parameters/Unreadable.json"); - } - - private void assertThatConfigFileThrownException(final String configFilePath) { - final String[] configParameters = new String[] {"-c", configFilePath}; - assertThatThrownBy(() -> new Main(configParameters)).isInstanceOf(ControlLoopRuntimeException.class) - .hasMessage(String.format(MessageConstants.START_FAILURE_MSG, MessageConstants.POLICY_CLAMP)); - } -} diff --git a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/TestParticipantDcaeActivator.java b/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/TestParticipantDcaeActivator.java deleted file mode 100644 index 1903868e2..000000000 --- a/participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/startstop/TestParticipantDcaeActivator.java +++ /dev/null @@ -1,94 +0,0 @@ -/*- - * ============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.dcae.main.startstop; - -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.CommonTestData; -import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameterHandler; -import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters; -import org.onap.policy.clamp.controlloop.participant.dcae.main.startstop.ParticipantDcaeActivator; -import org.onap.policy.clamp.controlloop.participant.dcae.main.startstop.ParticipantDcaeCommandLineArguments; -import org.onap.policy.common.utils.services.Registry; - -/** - * Class to perform unit test of {@link ParticipantDcaeActivator}}. - * - */ -public class TestParticipantDcaeActivator { - - private static ParticipantDcaeActivator activator; - - /** - * Initializes an activator. - * - * @throws Exception if an error occurs - */ - @BeforeClass - public static void setUp() throws Exception { - Registry.newRegistry(); - final String[] participantConfigParameters = { "-c", "src/test/resources/parameters/TestParameters.json"}; - final ParticipantDcaeCommandLineArguments arguments = - new ParticipantDcaeCommandLineArguments(participantConfigParameters); - final ParticipantDcaeParameters parGroup = - new ParticipantDcaeParameterHandler().getParameters(arguments); - activator = new ParticipantDcaeActivator(parGroup); - } - - /** - * Method for cleanup after each test. - * - * @throws Exception if an error occurs - */ - @AfterClass - public static void teardown() throws Exception { - // shut down activator - if (activator != null && activator.isAlive()) { - activator.shutdown(); - } - } - - @Test - public void testParticipantActivator() { - activator.start(); - assertTrue(activator.isAlive()); - assertTrue(activator.getParameters().isValid()); - assertEquals(CommonTestData.PARTICIPANT_GROUP_NAME, activator.getParameters().getName()); - - // repeat - should throw an exception - assertThatIllegalStateException().isThrownBy(() -> activator.start()); - assertTrue(activator.isAlive()); - assertTrue(activator.getParameters().isValid()); - - activator.shutdown(); - assertFalse(activator.isAlive()); - - // repeat - should throw an exception - assertThatIllegalStateException().isThrownBy(() -> activator.shutdown()); - assertFalse(activator.isAlive()); - } -} diff --git a/participant/participant-impl/participant-impl-dcae/src/test/resources/parameters/TestParameters.json b/participant/participant-impl/participant-impl-dcae/src/test/resources/parameters/TestParameters.json index 789fc7bbd..580eea734 100644 --- a/participant/participant-impl/participant-impl-dcae/src/test/resources/parameters/TestParameters.json +++ b/participant/participant-impl/participant-impl-dcae/src/test/resources/parameters/TestParameters.json @@ -1,22 +1,21 @@ { "name": "ControlLoopParticipantGroup", "clampClientParameters": { - "name": "Clamp", - "host": "0.0.0.0", + "clientName": "Clamp", + "hostname": "0.0.0.0", "port": 8443, "userName": "admin", "password": "password", - "https": true, - "aaf": false + "useHttps": true, + "allowSelfSignedCerts": false }, "consulClientParameters": { - "name": "Clamp", - "host": "consul", + "clientName": "Consul", + "hostname": "consul", "port": 31321, "userName": "admin", "password": "password", - "https": false, - "aaf": false + "useHttps": false }, "intermediaryParameters": { "name": "Participant parameters", diff --git a/participant/participant-impl/participant-impl-kubernetes/pom.xml b/participant/participant-impl/participant-impl-kubernetes/pom.xml index a85c5fdbf..504d91d78 100644 --- a/participant/participant-impl/participant-impl-kubernetes/pom.xml +++ b/participant/participant-impl/participant-impl-kubernetes/pom.xml @@ -19,7 +19,7 @@ --> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> @@ -30,5 +30,116 @@ <artifactId>policy-clamp-participant-impl-kubernetes</artifactId> <name>${project.artifactId}</name> - <description>Kubernetes participant, that allows microservices running in Kubernetes to partake in control loops</description> + <description>Kubernetes participant, that allows k8s pods to partake in control loops</description> + + <properties> + <springboot.version>2.5.0</springboot.version> + <immutable.version>2.8.8</immutable.version> + <springfox.version>3.0.0</springfox.version> + </properties> + + <dependencyManagement> + <dependencies> + <!-- Spring Boot BOM --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-dependencies</artifactId> + <version>${springboot.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-webflux</artifactId> + </dependency> + <dependency> + <groupId>org.apache.tomcat.embed</groupId> + <artifactId>tomcat-embed-core</artifactId> + </dependency> + <dependency> + <groupId>org.immutables</groupId> + <artifactId>value</artifactId> + <version>${immutable.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.immutables</groupId> + <artifactId>gson</artifactId> + <version>${immutable.version}</version> + </dependency> + <dependency> + <groupId>org.json</groupId> + <artifactId>json</artifactId> + </dependency> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger2</artifactId> + <version>${springfox.version}</version> + </dependency> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger-ui</artifactId> + <version>${springfox.version}</version> + <scope>runtime</scope> + </dependency> + <dependency> + <groupId>commons-fileupload</groupId> + <artifactId>commons-fileupload</artifactId> + <version>1.4</version> + </dependency> + <dependency> + <groupId>org.onap.policy.clamp.participant</groupId> + <artifactId>policy-clamp-participant-intermediary</artifactId> + <version>${project.version}</version> + </dependency> + + </dependencies> + + <build> + <resources> + <!-- Output the version of the control loop system --> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + <includes> + <include>**/version.txt</include> + </includes> + </resource> + <resource> + <directory>src/main/resources</directory> + <filtering>false</filtering> + <excludes> + <exclude>**/version.txt</exclude> + </excludes> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <version>${springboot.version}</version> + <executions> + <execution> + <goals> + <goal>repackage</goal> + </goals> + <phase>package</phase> + </execution> + </executions> + </plugin> + </plugins> + </build> </project> diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/Application.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/Application.java new file mode 100644 index 000000000..ffa0bceb9 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/Application.java @@ -0,0 +1,40 @@ +/*- + * ============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.kubernetes; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Starter. + * + */ +@SpringBootApplication +public class Application { + /** + * Main class. + * @param args args + */ + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} + diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/BeanFactory.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/BeanFactory.java new file mode 100644 index 000000000..3199d0cd9 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/BeanFactory.java @@ -0,0 +1,71 @@ +/*- + * ========================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.kubernetes.configurations; + +import org.apache.catalina.connector.Connector; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.servlet.server.ServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.multipart.MultipartResolver; +import org.springframework.web.multipart.commons.CommonsMultipartResolver; + +/** + * Bean Factory class for helm client. + */ +@Configuration +public class BeanFactory { + + @Value("${server.http-port}") + private int httpPort = 0; + + /** + * Method to create servlet container bean. + * @return webserver factory + */ + @Bean + public ServletWebServerFactory servletContainer() { + var tomcat = new TomcatServletWebServerFactory(); + if (httpPort > 0) { + tomcat.addAdditionalTomcatConnectors(getHttpConnector(httpPort)); + } + return tomcat; + } + + private static Connector getHttpConnector(int httpPort) { + var connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL); + connector.setScheme("http"); + connector.setPort(httpPort); + connector.setSecure(false); + return connector; + } + + /** + * Method to create multipartResolver bean. + * @return MultipartResolver + */ + @Bean(name = "multipartResolver") + public MultipartResolver multipartResolver() { + var multipartResolver = new CommonsMultipartResolver(); + multipartResolver.setMaxUploadSize(100000); + return multipartResolver; + } + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParametersConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParametersConfig.java new file mode 100644 index 000000000..5f2a4e4ad --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParametersConfig.java @@ -0,0 +1,41 @@ +/*- + * ============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.kubernetes.configurations; + +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; +import org.onap.policy.clamp.controlloop.participant.kubernetes.parameters.ParticipantK8sParameterHandler; +import org.onap.policy.clamp.controlloop.participant.kubernetes.parameters.ParticipantK8sParameters; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ParametersConfig { + + @Value("${participant.file}") + private String file; + + @Bean + public ParticipantK8sParameters participantK8sParameters() throws ControlLoopException { + return new ParticipantK8sParameterHandler().toParticipantK8sParameters(file); + } +} + diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantIntermediaryConfig.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantIntermediaryConfig.java new file mode 100644 index 000000000..d8c39925b --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/configurations/ParticipantIntermediaryConfig.java @@ -0,0 +1,48 @@ +/*- + * ============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.kubernetes.configurations; + +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryFactory; +import org.onap.policy.clamp.controlloop.participant.kubernetes.handler.ControlLoopElementHandler; +import org.onap.policy.clamp.controlloop.participant.kubernetes.parameters.ParticipantK8sParameters; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ParticipantIntermediaryConfig { + + /** + * Create ParticipantIntermediaryApi. + * + * @param parameters the K8s Participant Parameters + * @param clElementHandler the ControlLoop Element Handler + * @return ParticipantIntermediaryApi + */ + @Bean + public ParticipantIntermediaryApi participantIntermediaryApi(ParticipantK8sParameters parameters, + ControlLoopElementHandler clElementHandler) { + ParticipantIntermediaryApi intermediaryApi = new ParticipantIntermediaryFactory().createApiImplementation(); + intermediaryApi.init(parameters.getIntermediaryParameters()); + intermediaryApi.registerControlLoopElementListener(clElementHandler); + return intermediaryApi; + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java new file mode 100644 index 000000000..427b06fc5 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/controller/ChartController.java @@ -0,0 +1,166 @@ +/*- + * ========================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.kubernetes.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import java.io.IOException; +import java.util.ArrayList; +import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartList; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.InstallationInfo; +import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartService; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +@RestController("chartController") +@RequestMapping("helm") +@Api(tags = {"chart"}) +public class ChartController { + + @Autowired + private ChartService chartService; + + private static final StandardCoder CODER = new StandardCoder(); + + /** + * REST endpoint to get all the charts. + * + * @return List of charts installed + */ + @GetMapping(path = "/charts", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(value = "Return all Charts") + @ApiResponses(value = {@ApiResponse(code = 200, message = "chart List")}) + public ResponseEntity<ChartList> getAllCharts() { + return new ResponseEntity<>(ChartList.builder().charts(new ArrayList<>(chartService.getAllCharts())).build(), + HttpStatus.OK); + } + + /** + * REST endpoint to install a helm chart. + * + * @param info Info of the chart to be installed + * @return Status of the install operation + * @throws ServiceException incase of error + */ + @PostMapping(path = "/install", consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(value = "Install the chart") + @ApiResponses(value = {@ApiResponse(code = 201, message = "chart Installed")}) + public ResponseEntity<Object> installChart(@RequestBody InstallationInfo info) + throws ServiceException, IOException { + ChartInfo chart = chartService.getChart(info.getName(), info.getVersion()); + if (chart == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + chartService.installChart(chart); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + /** + * REST endpoint to uninstall a specific chart. + * + * @param name name of the chart + * @param version version of the chart + * @return Status of operation + * @throws ServiceException incase of error. + */ + @DeleteMapping(path = "/uninstall/{name}/{version}", produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(value = "Uninstall the Chart") + @ApiResponses(value = {@ApiResponse(code = 201, message = "chart Uninstalled")}) + public ResponseEntity<Object> uninstallChart(@PathVariable("name") String name, + @PathVariable("version") String version) throws ServiceException { + ChartInfo chart = chartService.getChart(name, version); + if (chart == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + chartService.uninstallChart(chart); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + /** + * REST endpoint to onboard a chart. + * + * @param chartFile Multipart file for the helm chart + * @param infoJson AppInfo of the chart + * @return Status of onboard operation + * @throws ServiceException incase of error + * @throws IOException incase of IO error + */ + @PostMapping(path = "/charts", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation(value = "Onboard the Chart") + @ApiResponses(value = {@ApiResponse(code = 201, message = "Chart Onboarded")}) + public ResponseEntity<String> onboardChart(@RequestPart("chart") MultipartFile chartFile, + @RequestParam(name = "values", required = false) MultipartFile overrideFile, + @RequestParam("info") String infoJson) throws ServiceException, IOException { + + ChartInfo info; + try { + info = CODER.decode(infoJson, ChartInfo.class); + } catch (CoderException e) { + throw new ServiceException("Error parsing the chart information", e); + } + + chartService.saveChart(info, chartFile, overrideFile); + return new ResponseEntity<>(HttpStatus.OK); + } + + /** + * REST endpoint to delete a specific helm chart. + * + * @param name name of the chart + * @param version version of the chart + * @return Status of operation + * @throws ServiceException incase of error. + */ + @DeleteMapping(path = "/charts/{name}/{version}") + @ApiOperation(value = "Delete the chart") + @ApiResponses(value = {@ApiResponse(code = 204, message = "Chart Deleted")}) + public ResponseEntity<Object> deleteChart(@PathVariable("name") String name, + @PathVariable("version") String version) throws ServiceException { + + ChartInfo chart = chartService.getChart(name, version); + if (chart == null) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + chartService.deleteChart(chart); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/exception/ServiceException.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/exception/ServiceException.java new file mode 100644 index 000000000..9a825cf75 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/exception/ServiceException.java @@ -0,0 +1,32 @@ +/*- + * ========================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.kubernetes.exception; + +public class ServiceException extends Exception { + + private static final long serialVersionUID = 6810785674716590648L; + + public ServiceException(String message) { + super(message); + } + + public ServiceException(String message, Exception originalException) { + super(message, originalException); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java new file mode 100644 index 000000000..5f1dcb8d4 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java @@ -0,0 +1,147 @@ +/*- + * ============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.kubernetes.handler; + + +import java.io.IOException; +import java.lang.invoke.MethodHandles; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartService; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * This class handles implementation of controlLoopElement updates. + */ +@Component +public class ControlLoopElementHandler implements ControlLoopElementListener { + private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + @Autowired + private ChartService chartService; + + @Autowired + private ParticipantIntermediaryApi intermediaryApi; + + // Map of CLElement Id and installed Helm charts + private final Map<UUID, ChartInfo> chartMap = new HashMap<>(); + + /** + * Callback method to handle a control loop element state change. + * + * @param controlLoopElementId the ID of the control loop element + * @param currentState the current state of the control loop element + * @param newState the state to which the control loop element is changing to + */ + @Override + public synchronized void controlLoopElementStateChange(UUID controlLoopElementId, ControlLoopState currentState, + ControlLoopOrderedState newState) { + switch (newState) { + case UNINITIALISED: + ChartInfo chart = chartMap.get(controlLoopElementId); + if (chart != null) { + LOGGER.info("Helm deployment to be deleted {} ", chart.getReleaseName()); + try { + chartService.uninstallChart(chart); + intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, + ControlLoopState.UNINITIALISED); + } catch (ServiceException se) { + LOGGER.warn("deletion of Helm deployment failed", se); + } + } + break; + case PASSIVE: + intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.PASSIVE); + break; + case RUNNING: + intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.RUNNING); + break; + default: + LOGGER.warn("cannot transition from state {} to state {}", currentState, newState); + break; + } + } + + + /** + * Callback method to handle an update on a control loop element. + * + * @param element the information on the control loop element + * @param controlLoopDefinition toscaServiceTemplate + * @throws PfModelException in case of an exception + */ + @Override + public synchronized void controlLoopElementUpdate(ControlLoopElement element, + ToscaServiceTemplate controlLoopDefinition) throws PfModelException { + + for (Map.Entry<String, ToscaNodeTemplate> nodeTemplate : controlLoopDefinition.getToscaTopologyTemplate() + .getNodeTemplates().entrySet()) { + + // Fetching the node template of corresponding CL element + if (element.getDefinition().getName().equals(nodeTemplate.getKey()) + && nodeTemplate.getValue().getProperties().containsKey("chart")) { + @SuppressWarnings("unchecked") + Map<String, Object> chartData = + (Map<String, Object>) nodeTemplate.getValue().getProperties().get("chart"); + + LOGGER.info("Installation request received for the Helm Chart {} ", chartData); + var chart = new ChartInfo(String.valueOf(chartData.get("release_name")), + String.valueOf(chartData.get("chart_name")), String.valueOf(chartData.get("version")), + String.valueOf(chartData.get("namespace"))); + try { + var repositoryValue = chartData.get("repository"); + if (repositoryValue != null) { + chart.setRepository(String.valueOf(repositoryValue)); + } + chartService.installChart(chart); + chartMap.put(element.getId(), chart); + } catch (IOException | ServiceException ise) { + LOGGER.warn("installation of Helm chart failed", ise); + } + } + } + } + + /** + * Overridden method. + * + * @param controlLoopElementId controlLoopElement id + * @throws PfModelException incase of error + */ + @Override + public synchronized void handleStatistics(UUID controlLoopElementId) throws PfModelException { + // TODO Implement statistics functionality + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java new file mode 100644 index 000000000..456122f3d --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/helm/HelmClient.java @@ -0,0 +1,201 @@ +/*- + * ========================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.kubernetes.helm; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.invoke.MethodHandles; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.apache.commons.io.IOUtils; +import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.controlloop.participant.kubernetes.service.ChartStore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Client to talk with Helm cli. Supports helm3 + version + */ +@Component +public class HelmClient { + + @Autowired + private ChartStore chartStore; + + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + + /** + * Install a chart. + * + * @param chart name and version. + * @throws ServiceException incase of error + */ + public void installChart(ChartInfo chart) throws ServiceException { + var processBuilder = prepareCreateNamespaceCommand(chart.getNamespace()); + try { + executeCommand(processBuilder); + } catch (ServiceException e) { + logger.warn("Namespace not created", e); + } + processBuilder = prepareInstallCommand(chart); + logger.info("Installing helm chart {} from the repository {} ", chart.getChartName(), chart.getRepository()); + executeCommand(processBuilder); + logger.info("Chart {} installed successfully", chart.getChartName()); + } + + /** + * Finds helm chart repository for the chart. + * + * @param chart ChartInfo. + * @throws ServiceException incase of error + */ + public String findChartRepository(ChartInfo chart) throws ServiceException, IOException { + updateHelmRepo(); + logger.info("Looking for helm chart {} in all the configured helm repositories", chart.getChartName()); + String repository = null; + + var process = helmRepoVerifyCommand(chart.getChartName()).start(); + + try (var reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line = reader.readLine(); + while (line != null) { + if (line.contains(chart.getChartName())) { + repository = line.split("/")[0]; + logger.info("Helm chart located in the repository {} ", repository); + return repository; + } + line = reader.readLine(); + } + } + + var localHelmChartDir = chartStore.getAppPath(chart.getChartName(), chart.getVersion()).toString(); + logger.info("Chart not found in helm repositories, verifying local repo {} ", localHelmChartDir); + if (verifyLocalHelmRepo(localHelmChartDir + "/" + chart.getChartName())) { + repository = localHelmChartDir; + } + + return repository; + } + + /** + * Uninstall a chart. + * + * @param chart name and version. + * @throws ServiceException incase of error + */ + public void uninstallChart(ChartInfo chart) throws ServiceException { + executeCommand(prepareUnInstallCommand(chart)); + } + + static String executeCommand(ProcessBuilder processBuilder) throws ServiceException { + var commandStr = toString(processBuilder); + + processBuilder.redirectInput(ProcessBuilder.Redirect.DISCARD); + + try { + var process = processBuilder.start(); + process.waitFor(); + int exitValue = process.exitValue(); + + if (exitValue != 0) { + var error = IOUtils.toString(process.getErrorStream(), StandardCharsets.UTF_8); + throw new ServiceException("Command execution failed: " + commandStr + " " + error); + } + var output = IOUtils.toString(process.getInputStream(), StandardCharsets.UTF_8); + logger.debug("Command <{}> execution, output: {}", commandStr, output); + return output; + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + throw new ServiceException( + "Failed to execute the Command: " + commandStr + ", the command was interrupted", ie); + } catch (Exception exc) { + throw new ServiceException("Failed to execute the Command: " + commandStr, exc); + } + } + + private ProcessBuilder prepareInstallCommand(ChartInfo chart) { + + // @formatter:off + List<String> helmArguments = new ArrayList<>( + Arrays.asList( + "helm", + "install", chart.getReleaseName(), chart.getRepository() + "/" + chart.getChartName(), + "--version", chart.getVersion(), + "--namespace", chart.getNamespace() + ) + ); + // @formatter:on + + // Verify if values.yaml available for the chart + var overrideFile = chartStore.getOverrideFile(chart).getPath(); + if (verifyLocalHelmRepo(overrideFile)) { + logger.info("Override yaml file available for the helm chart"); + helmArguments.addAll(Arrays.asList("--values", overrideFile)); + } + + return new ProcessBuilder().command(helmArguments); + } + + private ProcessBuilder prepareUnInstallCommand(ChartInfo chart) { + return new ProcessBuilder("helm", "delete", chart.getReleaseName(), "--namespace", chart.getNamespace()); + } + + private ProcessBuilder prepareCreateNamespaceCommand(String namespace) { + return new ProcessBuilder().command("kubectl", "create", "namespace", namespace); + } + + private ProcessBuilder helmRepoVerifyCommand(String chartName) { + return new ProcessBuilder().command("bash", "-c", "helm search repo | grep " + chartName); + } + + private ProcessBuilder localRepoVerifyCommand(String localFile) { + return new ProcessBuilder().command("bash", "-c", "ls " + localFile); + } + + private void updateHelmRepo() throws ServiceException { + logger.info("Updating local helm repositories before verifying the chart"); + List<String> helmArguments = Arrays.asList("helm", "repo", "update"); + + executeCommand(new ProcessBuilder().command(helmArguments)); + logger.debug("Helm repositories updated successfully"); + } + + private boolean verifyLocalHelmRepo(String localFile) { + var isVerified = false; + var processBuilder = localRepoVerifyCommand(localFile); + try { + executeCommand(processBuilder); + isVerified = true; + } catch (ServiceException e) { + logger.error("Unable to verify file in local repository", e); + } + return isVerified; + } + + protected static String toString(ProcessBuilder processBuilder) { + return String.join(" ", processBuilder.command()); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartInfo.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartInfo.java new file mode 100644 index 000000000..6bfb7aed5 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartInfo.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.kubernetes.models; + +import lombok.Data; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.immutables.gson.Gson; + +@Data +@RequiredArgsConstructor +@Gson.TypeAdapters +public class ChartInfo { + + @NonNull + private String releaseName; + + @NonNull + private String chartName; + + @NonNull + private String version; + + @NonNull + private String namespace; + + private String repository; + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartList.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartList.java new file mode 100644 index 000000000..c86bff58a --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/ChartList.java @@ -0,0 +1,31 @@ +/*- + * ========================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.kubernetes.models; + +import java.util.Collection; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class ChartList { + private Collection<ChartInfo> charts; +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/InstallationInfo.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/InstallationInfo.java new file mode 100644 index 000000000..b21e93a01 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/models/InstallationInfo.java @@ -0,0 +1,29 @@ +/*- + * ========================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.kubernetes.models; + +import lombok.Getter; +import org.immutables.gson.Gson; + +@Getter +@Gson.TypeAdapters +public class InstallationInfo { + private String name; + private String version; +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameterHandler.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameterHandler.java new file mode 100644 index 000000000..1a7dc35e8 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameterHandler.java @@ -0,0 +1,73 @@ +/*- + * ============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.kubernetes.parameters; + +import java.io.File; +import javax.ws.rs.core.Response; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; +import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; + +/** + * This class handles reading, parsing and validating of control loop participant parameters from JSON files. + */ +public class ParticipantK8sParameterHandler { + private static final Coder CODER = new StandardCoder(); + + /** + * Read the parameters from the path of the file. + * + * @param path path of the config file. + * @return the parameters read from the configuration file + * @throws ControlLoopException on parameter exceptions + */ + public ParticipantK8sParameters toParticipantK8sParameters(String path) throws ControlLoopException { + ParticipantK8sParameters parameters = null; + // Read the parameters + try { + // Read the parameters from JSON + var file = new File(path); + parameters = CODER.decode(file, ParticipantK8sParameters.class); + } catch (final CoderException e) { + final String errorMessage = + "error reading parameters from \"" + path + "\"\n" + "(" + e.getClass().getSimpleName() + ")"; + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, errorMessage, e); + } + + // The JSON processing returns null if there is an empty file + if (parameters == null) { + final String errorMessage = "no parameters found in \"" + path + "\""; + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, errorMessage); + } + + // validate the parameters + final BeanValidationResult validationResult = parameters.validate(); + if (!validationResult.isValid()) { + String returnMessage = + "validation error(s) on parameters from \"" + path + "\"\n" + validationResult.getResult(); + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, returnMessage); + } + + return parameters; + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameters.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameters.java new file mode 100644 index 000000000..65b32433c --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/parameters/ParticipantK8sParameters.java @@ -0,0 +1,59 @@ +/*- + * ============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.kubernetes.parameters; + +import javax.validation.constraints.NotBlank; +import lombok.Getter; +import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; +import org.onap.policy.common.parameters.ParameterGroupImpl; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.common.parameters.annotations.Valid; +import org.onap.policy.models.provider.PolicyModelsProviderParameters; + +/** + * Class to hold all parameters needed for the kubernetes participant. + * + */ +@NotNull +@NotBlank +@Getter +public class ParticipantK8sParameters extends ParameterGroupImpl { + public static final String DEFAULT_LOCAL_CHART_DIR = "/var/helm-manager/local-charts"; + public static final String DEFAULT_INFO_FILE_NAME = "CHART_INFO.json"; + + @Valid + private ParticipantIntermediaryParameters intermediaryParameters; + @Valid + private PolicyModelsProviderParameters databaseProviderParameters; + + + private String localChartDirectory = DEFAULT_LOCAL_CHART_DIR; + private String infoFileName = DEFAULT_INFO_FILE_NAME; + + /** + * Create the kubernetes participant parameter group. + * + * @param name the parameter group name + */ + public ParticipantK8sParameters(final String name) { + super(name); + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java new file mode 100644 index 000000000..6accac339 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartService.java @@ -0,0 +1,122 @@ +/*- + * ========================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.kubernetes.service; + +import java.io.IOException; +import java.lang.invoke.MethodHandles; +import java.util.Collection; +import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.controlloop.participant.kubernetes.helm.HelmClient; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +@Service +public class ChartService { + private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + @Autowired + private ChartStore chartStore; + + @Autowired + private HelmClient helmClient; + + /** + * Get all the installed charts. + * @return list of charts. + */ + public Collection<ChartInfo> getAllCharts() { + return chartStore.getAllCharts(); + } + + /** + * Get specific chart info. + * @param name name of the app + * @param version version of the app + * @return chart + * @throws ServiceException incase of error. + */ + public ChartInfo getChart(String name, String version) throws ServiceException { + return chartStore.getChart(name, version); + } + + /** + * Save a helm chart. + * @param chartInfo name and version of the app. + * @param chartFile Helm chart file + * @return chart details of the helm chart + * @throws IOException incase of IO error + * @throws ServiceException incase of error + */ + public ChartInfo saveChart(ChartInfo chartInfo, MultipartFile chartFile, MultipartFile overrideFile) + throws IOException, ServiceException { + return chartStore.saveChart(chartInfo, chartFile, overrideFile); + } + + /** + * Delete a helm chart. + * @param chart name and version of the chart. + */ + public void deleteChart(ChartInfo chart) { + chartStore.deleteChart(chart); + } + + /** + * Install a helm chart. + * @param chart name and version. + * @throws ServiceException incase of error + */ + public void installChart(ChartInfo chart) throws ServiceException, IOException { + if (chart.getRepository() == null) { + String repository = findChartRepo(chart); + if (repository == null) { + logger.error("Chart repository could not be found. Skipping chart Installation " + + "for the chart {} ", chart.getChartName()); + return; + } else { + chart.setRepository(repository); + } + } + helmClient.installChart(chart); + } + + /** + * Finds helm chart repository for a given chart. + * @param chart chartInfo. + * @throws ServiceException incase of error + */ + public String findChartRepo(ChartInfo chart) throws ServiceException, IOException { + logger.info("Fetching helm chart repository for the given chart {} ", chart.getChartName()); + return helmClient.findChartRepository(chart); + } + + /** + * Uninstall a helm chart. + * @param chart name and version + * @throws ServiceException incase of error. + */ + public void uninstallChart(ChartInfo chart) throws ServiceException { + logger.info("Uninstalling helm deployment {}", chart.getReleaseName()); + helmClient.uninstallChart(chart); + } + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStore.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStore.java new file mode 100644 index 000000000..2d0ce7a83 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/service/ChartStore.java @@ -0,0 +1,215 @@ +/*- + * ========================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.kubernetes.service; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.lang.invoke.MethodHandles; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException; +import org.onap.policy.clamp.controlloop.participant.kubernetes.models.ChartInfo; +import org.onap.policy.clamp.controlloop.participant.kubernetes.parameters.ParticipantK8sParameters; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.FileSystemUtils; +import org.springframework.web.multipart.MultipartFile; + +@Component +public class ChartStore { + private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + private static final StandardCoder STANDARD_CODER = new StandardCoder(); + + @Autowired + private ParticipantK8sParameters participantK8sParameters; + + /** + * The chartStore map contains chart name as key & ChartInfo as value. + */ + private Map<String, ChartInfo> localChartMap = new ConcurrentHashMap<>(); + + /** + * Constructor method. + */ + public ChartStore() { + this.restoreFromLocalFileSystem(); + } + + /** + * Get local helm chart file. + * + * @param chart ChartInfo + * @return the chart file. + */ + public File getHelmChartFile(ChartInfo chart) { + var appPath = getAppPath(chart.getChartName(), chart.getVersion()); + return new File(appPath.toFile(), chart.getChartName()); + } + + /** + * Get the override yaml file. + * + * @param chart ChartInfo + * @return the override yaml file + */ + public File getOverrideFile(ChartInfo chart) { + var appPath = getAppPath(chart.getChartName(), chart.getVersion()); + return new File(appPath.toFile(), "values.yaml"); + } + + + /** + * Saves the helm chart. + * + * @param chartInfo chartInfo + * @param chartFile helm chart file. + * @return chart + * @throws IOException incase of IO error + * @throws ServiceException incase of error. + */ + public synchronized ChartInfo saveChart(ChartInfo chartInfo, MultipartFile chartFile, MultipartFile overrideFile) + throws IOException, ServiceException { + if (localChartMap.containsKey(key(chartInfo.getChartName(), chartInfo.getVersion()))) { + throw new ServiceException("Chart already exist"); + } + var appPath = getAppPath(chartInfo.getChartName(), chartInfo.getVersion()); + Files.createDirectories(appPath); + + chartFile.transferTo(getHelmChartFile(chartInfo)); + if (overrideFile != null) { + overrideFile.transferTo(getOverrideFile(chartInfo)); + } + + localChartMap.put(key(chartInfo), chartInfo); + storeChartInFile(chartInfo); + return chartInfo; + } + + /** + * Get the chart info. + * + * @param name name of the chart + * @param version version of the chart + * @return chart + */ + public synchronized ChartInfo getChart(String name, String version) { + return localChartMap.get(key(name, version)); + } + + /** + * Get all the charts installed. + * + * @return list of charts. + */ + public synchronized List<ChartInfo> getAllCharts() { + return new ArrayList<>(localChartMap.values()); + } + + /** + * Delete a chart. + * + * @param chart chart info + */ + public synchronized void deleteChart(ChartInfo chart) { + var appPath = getAppPath(chart.getChartName(), chart.getVersion()); + try { + FileSystemUtils.deleteRecursively(appPath); + } catch (IOException exc) { + LOGGER.warn("Could not delete chart from local file system : {}", appPath, exc); + } + + localChartMap.remove(key(chart)); + } + + /** + * Fetch the local chart directory of specific chart. + * + * @param chartName name of the chart + * @param chartVersion version of the chart + * @return path + */ + public Path getAppPath(String chartName, String chartVersion) { + return Path.of(participantK8sParameters.getLocalChartDirectory(), chartName, chartVersion); + } + + private void storeChartInFile(ChartInfo chart) { + try (var out = new PrintStream(new FileOutputStream(getFile(chart)))) { + out.print(STANDARD_CODER.encode(chart)); + } catch (Exception exc) { + LOGGER.warn("Could not store chart: {} {}", chart.getChartName(), exc); + } + } + + private File getFile(ChartInfo chart) { + var appPath = getAppPath(chart.getChartName(), chart.getVersion()).toString(); + return Path.of(appPath, participantK8sParameters.getInfoFileName()).toFile(); + } + + private synchronized void restoreFromLocalFileSystem() { + Path localChartDirectoryPath = Paths.get(participantK8sParameters.getLocalChartDirectory()); + + try { + Files.createDirectories(localChartDirectoryPath); + restoreFromLocalFileSystem(localChartDirectoryPath); + } catch (IOException ioe) { + LOGGER.warn("Could not restore charts from local file system: {}", ioe); + } + } + + private synchronized void restoreFromLocalFileSystem(Path localChartDirectoryPath) + throws IOException { + + Files.walkFileTree(localChartDirectoryPath, new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult visitFile(Path localChartFile, BasicFileAttributes attrs) throws IOException { + try { + ChartInfo chart = STANDARD_CODER.decode(localChartFile.toFile(), ChartInfo.class); + localChartMap.put(key(chart), chart); + return FileVisitResult.CONTINUE; + } catch (CoderException ce) { + throw new IOException("Error decoding chart file", ce); + } + } + }); + } + + private String key(ChartInfo chart) { + return key(chart.getChartName(), chart.getVersion()); + } + + private String key(String chartName, String chartVersion) { + return chartName + "_" + chartVersion; + } + +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/KubernetesParticipantConfig.json b/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/KubernetesParticipantConfig.json new file mode 100644 index 000000000..620e05552 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/KubernetesParticipantConfig.json @@ -0,0 +1,56 @@ +{ + "name": "ControlLoopParticipantK8s", + "localChartDirectory": "/var/helm-manager/local-charts", + "infoFileName": "CHART_INFO.json", + + "intermediaryParameters":{ + "name":"Participant parameters", + "reportingTimeInterval":120000, + "description":"Participant Description", + "participantId":{ + "name":"K8sParticipant0", + "version":"1.0.0" + }, + "participantType":{ + "name":"org.onap.k8s.controlloop.K8SControlLoopParticipant", + "version":"2.3.4" + }, + "clampControlLoopTopics":{ + "topicSources":[ + { + "topic":"POLICY-CLRUNTIME-PARTICIPANT", + "servers":[ + "localhost" + ], + "topicCommInfrastructure":"dmaap", + "fetchTimeout":15000 + } + ], + "topicSinks":[ + { + "topic":"POLICY-CLRUNTIME-PARTICIPANT", + "servers":[ + "localhost" + ], + "topicCommInfrastructure":"dmaap" + }, + { + "topic":"POLICY-NOTIFICATION", + "servers":[ + "localhost" + ], + "topicCommInfrastructure":"dmaap" + } + ] + } + }, + "databaseProviderParameters":{ + "name":"PolicyProviderParameterGroup", + "implementation":"org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl", + "databaseDriver":"org.mariadb.jdbc.Driver", + "databaseUrl":"jdbc:mariadb://localhost:3306/controlloop", + "databaseUser":"admin", + "databasePassword":"passme", + "persistenceUnit":"ToscaConceptTest" + } +} diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml b/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml new file mode 100644 index 000000000..b4240036b --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/main/resources/config/application.yaml @@ -0,0 +1,25 @@ +spring: + profiles: + active: prod + +participant: + file: src/main/resources/config/KubernetesParticipantConfig.json +management: + endpoints: + web: + exposure: + include: "loggers,logfile,health,info,metrics,threaddump,heapdump" +server: + # Configuration of the HTTP/REST server. The parameters are defined and handled by the springboot framework. + # See springboot documentation. + http-port : 8083 + +logging: + # Configuration of logging + level: + ROOT: INFO + org.springframework: ERROR + org.springframework.data: ERROR + org.springframework.web.reactive.function.client.ExchangeFunctions: ERROR + file: + name: /var/log/helm-manager/application.log diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/resources/KubernetesHelm.yaml b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/KubernetesHelm.yaml new file mode 100644 index 000000000..3212b5ad2 --- /dev/null +++ b/participant/participant-impl/participant-impl-kubernetes/src/test/resources/KubernetesHelm.yaml @@ -0,0 +1,154 @@ +# ============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========================================================= +tosca_definitions_version: tosca_simple_yaml_1_3 +data_types: + onap.datatypes.ToscaConceptIdentifier: + derived_from: tosca.datatypes.Root + properties: + name: + type: string + required: true + version: + type: string + required: true +node_types: + org.onap.policy.clamp.controlloop.Participant: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + org.onap.policy.clamp.controlloop.ControlLoopElement: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + participant_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true + org.onap.policy.clamp.controlloop.ControlLoop: + version: 1.0.1 + derived_from: tosca.nodetypes.Root + properties: + provider: + type: string + requred: false + elements: + type: list + required: true + entry_schema: + type: onap.datatypes.ToscaConceptIdentifier + org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement + properties: + chart: + type: string + required: true + configs: + type: list + required: false + requirements: + type: string + requred: false + templates: + type: list + required: false + entry_schema: + values: + type: string + requred: true +topology_template: + node_templates: + org.onap.k8s.controlloop.K8SControlLoopParticipant: + version: 2.3.4 + type: org.onap.policy.clamp.controlloop.Participant + type_version: 1.0.1 + description: Participant for K8S + properties: + provider: ONAP + + org.onap.domain.database.HelloWorld_K8SMicroserviceControlLoopElement: + # Chart from any chart repository configured on helm client. + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement + type_version: 1.0.0 + description: Control loop element for the K8S microservice for Hello World + properties: + provider: ONAP + participant_id: + name: org.onap.k8s.controlloop.K8SControlLoopParticipant + version: 2.3.4 + chart: + release_name: helloworld + chart_name: hello + version: 0.1.0 + repository: chartMuseum + namespace: onap + + org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement: + # Chart from local file system + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement + type_version: 1.0.0 + description: Control loop element for the K8S microservice for PMSH + properties: + provider: ONAP + participant_id: + name: org.onap.k8s.controlloop.K8SControlLoopParticipant + version: 2.3.4 + chart: + release_name: pmshmicroservice + chart_name: test + version: 1.0.1 + namespace: onap + + org.onap.domain.database.Local_K8SMicroserviceControlLoopElement: + # Chart installation without passing repository name + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement + type_version: 1.0.0 + description: Control loop element for the K8S microservice for local chart + properties: + provider: ONAP + participant_id: + name: org.onap.k8s.controlloop.K8SControlLoopParticipant + version: 2.3.4 + chart: + release_name: nginxms + chart_name: nginx-ingress + version: 0.9.1 + namespace: onap + + org.onap.domain.sample.GenericK8s_ControlLoopDefinition: + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.ControlLoop + type_version: 1.0.0 + description: Control loop for Hello World + properties: + provider: ONAP + elements: + - name: org.onap.domain.database.HelloWorld_K8SMicroserviceControlLoopElement + version: 1.2.3 + - name: org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement + version: 1.2.3 + - name: org.onap.domain.database.Local_K8SMicroserviceControlLoopElement + version: 1.2.3 diff --git a/participant/participant-impl/participant-impl-policy/pom.xml b/participant/participant-impl/participant-impl-policy/pom.xml index a5a75626e..a0176588b 100644 --- a/participant/participant-impl/participant-impl-policy/pom.xml +++ b/participant/participant-impl/participant-impl-policy/pom.xml @@ -31,4 +31,55 @@ <artifactId>policy-clamp-participant-impl-policy</artifactId> <name>${project.artifactId}</name> <description>Policy participant, that allows Policy to partake in control loops</description> + + <properties> + <springboot.version>2.4.4</springboot.version> + </properties> + + <dependencyManagement> + <dependencies> + <!-- Spring Boot BOM --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-dependencies</artifactId> + <version>${springboot.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-validation</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <version>${springboot.version}</version> + <executions> + <execution> + <goals> + <goal>repackage</goal> + </goals> + <phase>package</phase> + </execution> + </executions> + </plugin> + </plugins> + </build> </project> diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/PolicyParticipantApplication.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/PolicyParticipantApplication.java new file mode 100644 index 000000000..bdc09c8b9 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/PolicyParticipantApplication.java @@ -0,0 +1,41 @@ +/*- + * ============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; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; +import org.springframework.context.annotation.ComponentScan; + +/** + * Starter. + * + */ +@SpringBootApplication +@ComponentScan({"org.onap.policy.clamp.controlloop.participant.policy", + "org.onap.policy.clamp.controlloop.participant.intermediary"}) +@ConfigurationPropertiesScan("org.onap.policy.clamp.controlloop.participant.policy.main.parameters") +public class PolicyParticipantApplication { + + public static void main(String[] args) { + SpringApplication.run(PolicyParticipantApplication.class, args); + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/ParametersConfig.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/ParametersConfig.java new file mode 100644 index 000000000..9c65d029c --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/ParametersConfig.java @@ -0,0 +1,40 @@ +/*- + * ============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.config; + +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; +import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.ParticipantPolicyParameterHandler; +import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.ParticipantPolicyParameters; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ParametersConfig { + + @Value("${participant.file}") + private String file; + + @Bean + public ParticipantPolicyParameters participantPolicyParameters() throws ControlLoopException { + return new ParticipantPolicyParameterHandler().toParticipantDcaeParameters(file); + } +} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/ParticipantConfig.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/ParticipantConfig.java new file mode 100644 index 000000000..afef1a5d2 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/config/ParticipantConfig.java @@ -0,0 +1,65 @@ +/*- + * ============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.config; + +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryFactory; +import org.onap.policy.clamp.controlloop.participant.policy.main.handler.ControlLoopElementHandler; +import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.ParticipantPolicyParameters; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.provider.PolicyModelsProvider; +import org.onap.policy.models.provider.PolicyModelsProviderFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ParticipantConfig { + + /** + * Create ParticipantIntermediaryApi. + * + * @param parameters the Participant Policy Parameters + * @param controlLoopElementHandler the ControlLoop Element Handler + * @return ParticipantIntermediaryApi + */ + @Bean + public ParticipantIntermediaryApi participantIntermediaryApi(ParticipantPolicyParameters parameters, + ControlLoopElementHandler controlLoopElementHandler) { + ParticipantIntermediaryApi intermediaryApi = new ParticipantIntermediaryFactory().createApiImplementation(); + intermediaryApi.init(parameters.getIntermediaryParameters()); + intermediaryApi.registerControlLoopElementListener(controlLoopElementHandler); + controlLoopElementHandler.setIntermediaryApi(intermediaryApi); + return intermediaryApi; + } + + /** + * Create PolicyModelsProvider. + * + * @param parameters the Participant Policy Parameters + * @return PolicyModelsProvider + * @throws PfModelException in case of an exception + */ + @Bean + public PolicyModelsProvider databaseProvider(ParticipantPolicyParameters parameters) throws PfModelException { + return new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters.getDatabaseProviderParameters()); + } + +} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandler.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandler.java index 932ebbece..5b07568da 100644 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandler.java +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandler.java @@ -25,11 +25,13 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; +import lombok.Setter; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.provider.PolicyModelsProvider; @@ -38,15 +40,31 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; /** * This class handles implementation of controlLoopElement updates. */ +@Component public class ControlLoopElementHandler implements ControlLoopElementListener { private static final Logger LOGGER = LoggerFactory.getLogger(ControlLoopElementHandler.class); - private static final Map<String, String> policyTypeMap = new LinkedHashMap<>(); - private static final Map<String, String> policyMap = new LinkedHashMap<>(); + private final Map<String, String> policyTypeMap = new LinkedHashMap<>(); + private final Map<String, String> policyMap = new LinkedHashMap<>(); + + private final PolicyModelsProvider databaseProvider; + + @Setter + private ParticipantIntermediaryApi intermediaryApi; + + /** + * constructor. + * + * @param databaseProvider the Policy Models Provider + */ + public ControlLoopElementHandler(PolicyModelsProvider databaseProvider) { + this.databaseProvider = databaseProvider; + } /** * Callback method to handle a control loop element state change. @@ -55,12 +73,10 @@ public class ControlLoopElementHandler implements ControlLoopElementListener { * @param currentState the current state of the control loop element * @param newState the state to which the control loop element is changing to * @throws PfModelException in case of an exception - */ + */ @Override - public void controlLoopElementStateChange(UUID controlLoopElementId, - ControlLoopState currentState, + public void controlLoopElementStateChange(UUID controlLoopElementId, ControlLoopState currentState, ControlLoopOrderedState newState) throws PfModelException { - PolicyProvider policyProvider = PolicyHandler.getInstance().getPolicyProvider(); switch (newState) { case UNINITIALISED: try { @@ -70,14 +86,10 @@ public class ControlLoopElementHandler implements ControlLoopElementListener { } break; case PASSIVE: - policyProvider.getIntermediaryApi() - .updateControlLoopElementState(controlLoopElementId, newState, - ControlLoopState.PASSIVE); + intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.PASSIVE); break; case RUNNING: - policyProvider.getIntermediaryApi() - .updateControlLoopElementState(controlLoopElementId, newState, - ControlLoopState.RUNNING); + intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.RUNNING); break; default: LOGGER.debug("Unknown orderedstate {}", newState); @@ -85,25 +97,18 @@ public class ControlLoopElementHandler implements ControlLoopElementListener { } } - private void deletePolicyData(UUID controlLoopElementId, - ControlLoopOrderedState newState) throws PfModelException { - PolicyModelsProvider dbProvider = PolicyHandler.getInstance().getDatabaseProvider(); - PolicyProvider policyProvider = PolicyHandler.getInstance().getPolicyProvider(); - if (policyMap != null) { - // Delete all policies of this controlLoop from policy framework - for (Entry<String, String> policy : policyMap.entrySet()) { - dbProvider.deletePolicy(policy.getKey(), policy.getValue()); - } + private void deletePolicyData(UUID controlLoopElementId, ControlLoopOrderedState newState) throws PfModelException { + // Delete all policies of this controlLoop from policy framework + for (Entry<String, String> policy : policyMap.entrySet()) { + databaseProvider.deletePolicy(policy.getKey(), policy.getValue()); } - if (policyTypeMap != null) { - // Delete all policy types of this control loop from policy framework - for (Entry<String, String> policy : policyTypeMap.entrySet()) { - dbProvider.deletePolicyType(policy.getKey(), policy.getValue()); - } + policyMap.clear(); + // Delete all policy types of this control loop from policy framework + for (Entry<String, String> policyType : policyTypeMap.entrySet()) { + databaseProvider.deletePolicyType(policyType.getKey(), policyType.getValue()); } - policyProvider.getIntermediaryApi() - .updateControlLoopElementState(controlLoopElementId, newState, - ControlLoopState.UNINITIALISED); + policyTypeMap.clear(); + intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.UNINITIALISED); } /** @@ -114,27 +119,25 @@ public class ControlLoopElementHandler implements ControlLoopElementListener { * @throws PfModelException in case of an exception */ @Override - public void controlLoopElementUpdate(ControlLoopElement element, - ToscaServiceTemplate controlLoopDefinition) throws PfModelException { - PolicyModelsProvider dbProvider = PolicyHandler.getInstance().getDatabaseProvider(); - PolicyProvider policyProvider = PolicyHandler.getInstance().getPolicyProvider(); - - policyProvider.getIntermediaryApi() - .updateControlLoopElementState(element.getId(), element.getOrderedState(), ControlLoopState.PASSIVE); + public void controlLoopElementUpdate(ControlLoopElement element, ToscaServiceTemplate controlLoopDefinition) + throws PfModelException { + intermediaryApi.updateControlLoopElementState(element.getId(), element.getOrderedState(), + ControlLoopState.PASSIVE); if (controlLoopDefinition.getPolicyTypes() != null) { for (ToscaPolicyType policyType : controlLoopDefinition.getPolicyTypes().values()) { policyTypeMap.put(policyType.getName(), policyType.getVersion()); } - dbProvider.createPolicyTypes(controlLoopDefinition); + databaseProvider.createPolicyTypes(controlLoopDefinition); } if (controlLoopDefinition.getToscaTopologyTemplate().getPolicies() != null) { - for (Map<String, ToscaPolicy> foundPolicyMap : controlLoopDefinition - .getToscaTopologyTemplate().getPolicies()) { - for (ToscaPolicy policy : foundPolicyMap.values()) { + for (Map<String, ToscaPolicy> foundPolicyMap : controlLoopDefinition.getToscaTopologyTemplate() + .getPolicies()) { + for (Entry<String, ToscaPolicy> policyEntry : foundPolicyMap.entrySet()) { + ToscaPolicy policy = policyEntry.getValue(); policyMap.put(policy.getName(), policy.getVersion()); } } - dbProvider.createPolicies(controlLoopDefinition); + databaseProvider.createPolicies(controlLoopDefinition); } } @@ -144,16 +147,13 @@ public class ControlLoopElementHandler implements ControlLoopElementListener { * @param controlLoopElementId controlloop element id */ @Override - public void handleStatistics(UUID controlLoopElementId) { - PolicyProvider policyProvider = PolicyHandler.getInstance().getPolicyProvider(); - ControlLoopElement clElement = policyProvider.getIntermediaryApi() - .getControlLoopElement(controlLoopElementId); + public void handleStatistics(UUID controlLoopElementId) throws PfModelException { + ControlLoopElement clElement = intermediaryApi.getControlLoopElement(controlLoopElementId); if (clElement != null) { ClElementStatistics clElementStatistics = new ClElementStatistics(); clElementStatistics.setControlLoopState(clElement.getState()); clElementStatistics.setTimeStamp(Instant.now()); - policyProvider.getIntermediaryApi() - .updateControlLoopElementStatistics(controlLoopElementId, clElementStatistics); + intermediaryApi.updateControlLoopElementStatistics(controlLoopElementId, clElementStatistics); } } } diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/PolicyHandler.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/PolicyHandler.java deleted file mode 100644 index d62e5f9f3..000000000 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/PolicyHandler.java +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * ============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.handler; - -import java.io.IOException; -import java.util.List; -import java.util.Set; -import javax.ws.rs.core.Response; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; -import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.ParticipantPolicyParameters; -import org.onap.policy.common.endpoints.event.comm.TopicSink; -import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher; -import org.onap.policy.common.utils.services.Registry; -import org.onap.policy.models.base.PfModelException; -import org.onap.policy.models.base.PfModelRuntimeException; -import org.onap.policy.models.provider.PolicyModelsProvider; -import org.onap.policy.models.provider.PolicyModelsProviderFactory; - -/** - * This class handles policy participant and control loop elements. - * - * <p/>It is effectively a singleton that is started at system start. - */ -public class PolicyHandler extends ControlLoopHandler { - - private final ParticipantIntermediaryParameters participantParameters; - private final ParticipantPolicyParameters policyParameters; - - @Getter - private PolicyProvider policyProvider; - @Getter - private PolicyModelsProvider databaseProvider; - - /** - * Create a handler. - * - * @param parameters the parameters for access to the database - * @throws PfModelException in case of an exception - */ - public PolicyHandler(ParticipantPolicyParameters parameters) throws PfModelException { - super(parameters.getDatabaseProviderParameters()); - participantParameters = parameters.getIntermediaryParameters(); - policyParameters = parameters; - } - - public static PolicyHandler getInstance() { - return Registry.get(PolicyHandler.class.getName()); - } - - @Override - public Set<Class<?>> getProviderClasses() { - return null; - } - - @Override - public void startProviders() { - try { - policyProvider = new PolicyProvider(participantParameters); - databaseProvider = new PolicyModelsProviderFactory().createPolicyModelsProvider( - policyParameters.getDatabaseProviderParameters()); - } catch (PfModelException e) { - throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, "Start providers failed ", e); - } - } - - @Override - public void stopProviders() { - try { - policyProvider.close(); - } catch (IOException e) { - throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, "Stop providers failed ", e); - } - - try { - databaseProvider.close(); - } catch (PfModelException e) { - throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, "Stop providers failed ", e); - } - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/PolicyProvider.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/PolicyProvider.java deleted file mode 100644 index 420c77ee3..000000000 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/PolicyProvider.java +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * ============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.handler; - -import java.io.Closeable; -import java.io.IOException; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; -import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryFactory; -import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters; - -/** - * Provider class for policy participant. - */ -public class PolicyProvider implements Closeable { - @Getter - private final ParticipantIntermediaryApi intermediaryApi; - - private final ControlLoopElementHandler controlLoopElementHandler; - - /** - * Create a policy participant provider. - * - * @throws ControlLoopRuntimeException on errors creating the provider - */ - public PolicyProvider(ParticipantIntermediaryParameters participantParameters) - throws ControlLoopRuntimeException { - intermediaryApi = new ParticipantIntermediaryFactory().createApiImplementation(); - intermediaryApi.init(participantParameters); - controlLoopElementHandler = new ControlLoopElementHandler(); - intermediaryApi.registerControlLoopElementListener(controlLoopElementHandler); - } - - @Override - public void close() throws IOException { - intermediaryApi.close(); - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/ParticipantPolicyParameterHandler.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/ParticipantPolicyParameterHandler.java index 98cea821a..0d8e70013 100644 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/ParticipantPolicyParameterHandler.java +++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/ParticipantPolicyParameterHandler.java @@ -23,8 +23,7 @@ package org.onap.policy.clamp.controlloop.participant.policy.main.parameters; import java.io.File; import javax.ws.rs.core.Response; import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.participant.policy.main.startstop.ParticipantPolicyCommandLineArguments; -import org.onap.policy.common.parameters.ValidationResult; +import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; @@ -39,37 +38,34 @@ public class ParticipantPolicyParameterHandler { /** * Read the parameters from the parameter file. * - * @param arguments the arguments passed to policy + * @param path the path passed to policy * @return the parameters read from the configuration file * @throws ControlLoopException on parameter exceptions */ - public ParticipantPolicyParameters getParameters(final ParticipantPolicyCommandLineArguments arguments) - throws ControlLoopException { + public ParticipantPolicyParameters toParticipantDcaeParameters(final String path) throws ControlLoopException { ParticipantPolicyParameters parameters = null; // Read the parameters try { // Read the parameters from JSON - File file = new File(arguments.getFullConfigurationFilePath()); + File file = new File(path); parameters = CODER.decode(file, ParticipantPolicyParameters.class); } catch (final CoderException e) { - final String errorMessage = "error reading parameters from \"" + arguments.getConfigurationFilePath() - + "\"\n" + "(" + e.getClass().getSimpleName() + ")"; + final String errorMessage = + "error reading parameters from \"" + path + "\"\n" + "(" + e.getClass().getSimpleName() + ")"; throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, errorMessage, e); } // The JSON processing returns null if there is an empty file if (parameters == null) { - final String errorMessage = "no parameters found in \"" + arguments.getConfigurationFilePath() + "\""; - throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, errorMessage); + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, "no parameters found in \"" + path + "\""); } // validate the parameters - final ValidationResult validationResult = parameters.validate(); + final BeanValidationResult validationResult = parameters.validate(); if (!validationResult.isValid()) { - String returnMessage = - "validation error(s) on parameters from \"" + arguments.getConfigurationFilePath() + "\"\n"; - returnMessage += validationResult.getResult(); + final String returnMessage = + "validation error(s) on parameters from \"" + path + "\"\n" + validationResult.getResult(); throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, returnMessage); } diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/Main.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/Main.java deleted file mode 100644 index 9a6bfdf7d..000000000 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/Main.java +++ /dev/null @@ -1,141 +0,0 @@ -/*- - * ============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.startstop; - -import java.util.Arrays; -import javax.ws.rs.core.Response; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.ParticipantPolicyParameterHandler; -import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.ParticipantPolicyParameters; -import org.onap.policy.common.utils.resources.MessageConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This class initiates Policy Participant. - */ -public class Main { - - private static final Logger LOGGER = LoggerFactory.getLogger(Main.class); - - private ParticipantPolicyActivator activator; - - @Getter - private ParticipantPolicyParameters parameterGroup; - - /** - * Instantiates policy participant. - * - * @param args the command line arguments - */ - public Main(final String[] args) { - final String argumentString = Arrays.toString(args); - LOGGER.info("Starting the control loop participant service with arguments - {}", argumentString); - - // Check the arguments - final ParticipantPolicyCommandLineArguments arguments = new ParticipantPolicyCommandLineArguments(); - try { - // The arguments return a string if there is a message to print and we should exit - final String argumentMessage = arguments.parse(args); - if (argumentMessage != null) { - LOGGER.info(argumentMessage); - return; - } - // Validate that the arguments are sane - arguments.validate(); - - // Read the parameters - parameterGroup = new ParticipantPolicyParameterHandler().getParameters(arguments); - - // Now, create the activator for the service - activator = new ParticipantPolicyActivator(parameterGroup); - - // Start the activator - activator.start(); - } catch (Exception exp) { - throw new ControlLoopRuntimeException(Response.Status.BAD_REQUEST, - String.format(MessageConstants.START_FAILURE_MSG, MessageConstants.POLICY_CLAMP), exp); - } - - // Add a shutdown hook to shut everything down in an orderly manner - Runtime.getRuntime().addShutdownHook(new ClRuntimeShutdownHookClass()); - String successMsg = String.format(MessageConstants.START_SUCCESS_MSG, MessageConstants.POLICY_CLAMP); - LOGGER.info(successMsg); - } - - /** - * Check if main is running. - */ - public boolean isRunning() { - return activator != null && activator.isAlive(); - } - - /** - * Shut down Execution. - * - * @throws ControlLoopException on shutdown errors - */ - public void shutdown() throws ControlLoopException { - // clear the parameterGroup variable - parameterGroup = null; - - // clear the cl participant activator - if (activator != null) { - activator.stop(); - } - } - - /** - * The Class ClRuntimeShutdownHookClass terminates the policy participant - * when its run method is called. - */ - private class ClRuntimeShutdownHookClass extends Thread { - /* - * (non-Javadoc) - * - * @see java.lang.Runnable#run() - */ - @Override - public void run() { - try { - // Shutdown the control loop participant service and wait for everything to stop - shutdown(); - } catch (final RuntimeException | ControlLoopException e) { - LOGGER.warn("error occured during shut down of the policy participant", e); - } - } - } - - /** - * The main method. - * - * @param args the arguments - */ - public static void main(final String[] args) { // NOSONAR - /* - * NOTE: arguments are validated by the constructor, thus sonar is disabled. - */ - - new Main(args); - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/ParticipantPolicyActivator.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/ParticipantPolicyActivator.java deleted file mode 100644 index 760f8267d..000000000 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/ParticipantPolicyActivator.java +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * ============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.startstop; - -import java.util.concurrent.atomic.AtomicReference; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.participant.policy.main.handler.PolicyHandler; -import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.ParticipantPolicyParameters; -import org.onap.policy.common.utils.services.ServiceManagerContainer; - -/** - * This class activates the policy participant. - * - */ -public class ParticipantPolicyActivator extends ServiceManagerContainer { - @Getter - private final ParticipantPolicyParameters parameters; - - /** - * Instantiate the activator for the policy participant. - * - * @param parameters the parameters for the policy participant - */ - public ParticipantPolicyActivator(final ParticipantPolicyParameters parameters) { - this.parameters = parameters; - - final AtomicReference<PolicyHandler> policyHandler = new AtomicReference<>(); - - // @formatter:off - addAction("Policy Handler", - () -> policyHandler.set(new PolicyHandler(parameters)), - () -> policyHandler.get().close()); - - addAction("Policy Providers", - () -> policyHandler.get().startProviders(), - () -> policyHandler.get().stopProviders()); - // @formatter:on - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/ParticipantPolicyCommandLineArguments.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/ParticipantPolicyCommandLineArguments.java deleted file mode 100644 index af7a189f6..000000000 --- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/ParticipantPolicyCommandLineArguments.java +++ /dev/null @@ -1,145 +0,0 @@ -/*- - * ============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.startstop; - -import java.util.Arrays; -import javax.ws.rs.core.Response; -import lombok.Getter; -import lombok.Setter; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.commons.lang3.StringUtils; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.clamp.controlloop.common.startstop.CommonCommandLineArguments; -import org.onap.policy.common.utils.resources.ResourceUtils; - -/** - * This class reads and handles command line parameters for the policy participant. - * - */ -public class ParticipantPolicyCommandLineArguments { - private static final String FILE_MESSAGE_PREAMBLE = " file \""; - private static final int HELP_LINE_LENGTH = 120; - - private final Options options; - private final CommonCommandLineArguments commonCommandLineArguments; - - @Getter() - @Setter() - private String configurationFilePath = null; - - /** - * Construct the options for the policy participant. - */ - public ParticipantPolicyCommandLineArguments() { - options = new Options(); - commonCommandLineArguments = new CommonCommandLineArguments(options); - } - - /** - * Construct the options for the CLI editor and parse in the given arguments. - * - * @param args The command line arguments - */ - public ParticipantPolicyCommandLineArguments(final String[] args) { - // Set up the options with the default constructor - this(); - - // Parse the arguments - try { - parse(args); - } catch (final ControlLoopException e) { - throw new ControlLoopRuntimeException(Response.Status.NOT_ACCEPTABLE, - "parse error on policy participant parameters", e); - } - } - - /** - * Parse the command line options. - * - * @param args The command line arguments - * @return a string with a message for help and version, or null if there is no message - * @throws ControlLoopException on command argument errors - */ - public String parse(final String[] args) throws ControlLoopException { - // Clear all our arguments - setConfigurationFilePath(null); - CommandLine commandLine = null; - try { - commandLine = new DefaultParser().parse(options, args); - } catch (final ParseException e) { - throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, - "invalid command line arguments specified : " + e.getMessage()); - } - - // Arguments left over after Commons CLI does its stuff - final String[] remainingArgs = commandLine.getArgs(); - - if (remainingArgs.length > 0) { - throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, - "too many command line arguments specified : " + Arrays.toString(args)); - } - - if (commandLine.hasOption('h')) { - return commonCommandLineArguments.help(Main.class.getName(), options); - } - - if (commandLine.hasOption('v')) { - return commonCommandLineArguments.version(); - } - - if (commandLine.hasOption('c')) { - setConfigurationFilePath(commandLine.getOptionValue('c')); - } - - return null; - } - - /** - * Validate the command line options. - * - * @throws ControlLoopException on command argument validation errors - */ - public void validate() throws ControlLoopException { - commonCommandLineArguments.validate(configurationFilePath); - } - - /** - * Gets the full expanded configuration file path. - * - * @return the configuration file path - */ - public String getFullConfigurationFilePath() { - return ResourceUtils.getFilePath4Resource(getConfigurationFilePath()); - } - - /** - * Check set configuration file path. - * - * @return true, if check set configuration file path - */ - public boolean checkSetConfigurationFilePath() { - return !StringUtils.isEmpty(configurationFilePath); - } -} 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 new file mode 100644 index 000000000..79eca8f92 --- /dev/null +++ b/participant/participant-impl/participant-impl-policy/src/main/resources/config/application.yaml @@ -0,0 +1,3 @@ + +participant: + file: src/main/resources/config/PolicyParticipantConfig.json diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/TestPolicyHandler.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/endtoend/ParticipantPolicyTest.java index abc3e71b8..2a6f4b005 100644 --- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/TestPolicyHandler.java +++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/endtoend/ParticipantPolicyTest.java @@ -18,117 +18,112 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.controlloop.participant.policy.main.handler; +package org.onap.policy.clamp.controlloop.participant.policy.endtoend; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.onap.policy.clamp.controlloop.common.ControlLoopConstants; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopStateChange; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopUpdate; +import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ControlLoopStateChangeListener; import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ControlLoopUpdateListener; -import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.CommonTestData; -import org.onap.policy.clamp.controlloop.participant.policy.main.startstop.Main; -import org.onap.policy.clamp.controlloop.participant.policy.main.startstop.ParticipantPolicyActivator; import org.onap.policy.clamp.controlloop.participant.policy.main.utils.TestListenerUtils; import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; -import org.onap.policy.common.utils.services.Registry; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; -public class TestPolicyHandler { +@ExtendWith(SpringExtension.class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@TestPropertySource(properties = "participant.file=src/test/resources/parameters/TestParameters.json") +class ParticipantPolicyTest { - private static ControlLoopUpdateListener clUpdateListener; - private ControlLoopStateChangeListener clStateChangeListener; - private static ParticipantControlLoopUpdate participantControlLoopUpdateMsg; - private ParticipantControlLoopStateChange participantControlLoopStateChangeMsg; - private static final String PARTICIPANTS_ENDPOINT = "participants"; - private static final String ELEMENTS_ENDPOINT = "elements"; + private static final Object lockit = new Object(); private static final CommInfrastructure INFRA = CommInfrastructure.NOOP; private static final String TOPIC = "my-topic"; - private static final Object lockit = new Object(); - static CommonTestData commonTestData = new CommonTestData(); - - /** - * Setup before class, instantiate Main. - * - */ - @BeforeClass - public static void setUpBeforeClass() throws Exception { - Registry.newRegistry(); - final String[] configParameters = {"-c", "src/test/resources/parameters/TestParameters.json"}; - Main main = new Main(configParameters); - assertTrue(main.isRunning()); - TestListenerUtils.initParticipantHandler(); - - clUpdateListener = new ControlLoopUpdateListener( - PolicyHandler.getInstance() - .getPolicyProvider() - .getIntermediaryApi() - .getParticipantHandler()); - participantControlLoopUpdateMsg = - TestListenerUtils.createControlLoopUpdateMsg(); - participantControlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.PASSIVE); - } + + @Autowired + private ParticipantIntermediaryApi participantIntermediaryApi; @Test - public void testUpdatePolicyTypes() throws Exception { + void testUpdatePolicyTypes() { + ParticipantControlLoopUpdate participantControlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg(); + participantControlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.PASSIVE); + // Verify that the ToscaServicetemplate has policy_types assertNotNull(participantControlLoopUpdateMsg.getControlLoopDefinition().getPolicyTypes()); synchronized (lockit) { + ControlLoopUpdateListener clUpdateListener = + new ControlLoopUpdateListener(participantIntermediaryApi.getParticipantHandler()); + clUpdateListener.onTopicEvent(INFRA, TOPIC, null, participantControlLoopUpdateMsg); } // Verify the result of GET participants with what is stored assertEquals("org.onap.PM_Policy", - TestListenerUtils.getParticipantHandler().getParticipantId().getName()); + participantIntermediaryApi.getParticipantHandler().getParticipantId().getName()); } @Test - public void testUpdatePolicies() throws Exception { + void testUpdatePolicies() throws Exception { + ParticipantControlLoopUpdate participantControlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg(); + participantControlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.PASSIVE); + // Add policies to the toscaServiceTemplate TestListenerUtils.addPoliciesToToscaServiceTemplate(participantControlLoopUpdateMsg.getControlLoopDefinition()); // Verify that the ToscaServicetemplate has policies - assertNotNull(participantControlLoopUpdateMsg.getControlLoopDefinition() - .getToscaTopologyTemplate().getPolicies()); + assertNotNull( + participantControlLoopUpdateMsg.getControlLoopDefinition().getToscaTopologyTemplate().getPolicies()); synchronized (lockit) { + ControlLoopUpdateListener clUpdateListener = + new ControlLoopUpdateListener(participantIntermediaryApi.getParticipantHandler()); + clUpdateListener.onTopicEvent(INFRA, TOPIC, null, participantControlLoopUpdateMsg); } // Verify the result of GET participants with what is stored assertEquals("org.onap.PM_Policy", - TestListenerUtils.getParticipantHandler().getParticipantId().getName()); + participantIntermediaryApi.getParticipantHandler().getParticipantId().getName()); } @Test - public void testDeletePoliciesAndPolicyTypes() throws Exception { + void testDeletePoliciesAndPolicyTypes() throws Exception { + ParticipantControlLoopUpdate participantControlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg(); + participantControlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.PASSIVE); + // Add policies to the toscaServiceTemplate TestListenerUtils.addPoliciesToToscaServiceTemplate(participantControlLoopUpdateMsg.getControlLoopDefinition()); // Verify that the ToscaServicetemplate has policies - assertNotNull(participantControlLoopUpdateMsg.getControlLoopDefinition() - .getToscaTopologyTemplate().getPolicies()); + assertNotNull( + participantControlLoopUpdateMsg.getControlLoopDefinition().getToscaTopologyTemplate().getPolicies()); synchronized (lockit) { + ControlLoopUpdateListener clUpdateListener = + new ControlLoopUpdateListener(participantIntermediaryApi.getParticipantHandler()); + clUpdateListener.onTopicEvent(INFRA, TOPIC, null, participantControlLoopUpdateMsg); } // Verify the result of GET participants with what is stored assertEquals("org.onap.PM_Policy", - TestListenerUtils.getParticipantHandler().getParticipantId().getName()); + participantIntermediaryApi.getParticipantHandler().getParticipantId().getName()); - clStateChangeListener = new ControlLoopStateChangeListener(TestListenerUtils.getParticipantHandler()); - participantControlLoopStateChangeMsg = + ControlLoopStateChangeListener clStateChangeListener = + new ControlLoopStateChangeListener(participantIntermediaryApi.getParticipantHandler()); + ParticipantControlLoopStateChange participantControlLoopStateChangeMsg = TestListenerUtils.createControlLoopStateChangeMsg(ControlLoopOrderedState.UNINITIALISED); participantControlLoopStateChangeMsg.setOrderedState(ControlLoopOrderedState.UNINITIALISED); clStateChangeListener.onTopicEvent(INFRA, TOPIC, null, participantControlLoopStateChangeMsg); // Verify the result of GET participants with what is stored assertEquals("org.onap.PM_Policy", - TestListenerUtils.getParticipantHandler().getParticipantId().getName()); + participantIntermediaryApi.getParticipantHandler().getParticipantId().getName()); } } diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/TestParticipantPolicyParameterHandler.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/TestParticipantPolicyParameterHandler.java index dd62dbfc4..8c12a4038 100644 --- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/TestParticipantPolicyParameterHandler.java +++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/parameters/TestParticipantPolicyParameterHandler.java @@ -20,79 +20,39 @@ package org.onap.policy.clamp.controlloop.participant.policy.main.parameters; -import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import java.io.FileNotFoundException; -import org.apache.commons.io.DirectoryWalker.CancelException; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.participant.policy.main.startstop.ParticipantPolicyCommandLineArguments; import org.onap.policy.common.utils.coder.CoderException; -public class TestParticipantPolicyParameterHandler { +class TestParticipantPolicyParameterHandler { @Test - public void testParameterHandlerNoParameterFile() throws ControlLoopException { - final String[] emptyArgumentString = { "-c", "src/test/resources/parameters/NoParametersFile.json" }; + void testParameterHandlerNoParameterFile() throws ControlLoopException { + final String path = "src/test/resources/parameters/NoParametersFile.json"; - final ParticipantPolicyCommandLineArguments emptyArguments = new ParticipantPolicyCommandLineArguments(); - emptyArguments.parse(emptyArgumentString); - - assertThatThrownBy(() -> new ParticipantPolicyParameterHandler().getParameters(emptyArguments)) + assertThatThrownBy(() -> new ParticipantPolicyParameterHandler().toParticipantDcaeParameters(path)) .hasCauseInstanceOf(CoderException.class) .hasRootCauseInstanceOf(FileNotFoundException.class); } @Test - public void testParameterHandlerInvalidParameters() throws ControlLoopException { - final String[] invalidArgumentString = { "-c", "src/test/resources/parameters/InvalidParameters.json" }; - - final ParticipantPolicyCommandLineArguments invalidArguments = - new ParticipantPolicyCommandLineArguments(); - invalidArguments.parse(invalidArgumentString); + void testParameterHandlerInvalidParameters() throws ControlLoopException { + final String path = "src/test/resources/parameters/InvalidParameters.json"; - assertThatThrownBy(() -> new ParticipantPolicyParameterHandler().getParameters(invalidArguments)) + assertThatThrownBy(() -> new ParticipantPolicyParameterHandler().toParticipantDcaeParameters(path)) .hasMessageStartingWith("error reading parameters from") .hasCauseInstanceOf(CoderException.class); } @Test - public void testParticipantPolicyParameters() throws ControlLoopException { - final String[] participantConfigParameters = { "-c", "src/test/resources/parameters/TestParameters.json" }; - - final ParticipantPolicyCommandLineArguments arguments = new ParticipantPolicyCommandLineArguments(); - arguments.parse(participantConfigParameters); - + void testParticipantParameterGroup() throws ControlLoopException { + final String path = "src/test/resources/parameters/TestParameters.json"; final ParticipantPolicyParameters parGroup = new ParticipantPolicyParameterHandler() - .getParameters(arguments); - assertTrue(arguments.checkSetConfigurationFilePath()); + .toParticipantDcaeParameters(path); assertEquals(CommonTestData.PARTICIPANT_GROUP_NAME, parGroup.getName()); } - - @Test - public void testParticipantVersion() throws ControlLoopException { - final String[] participantConfigParameters = { "-v" }; - final ParticipantPolicyCommandLineArguments arguments = new ParticipantPolicyCommandLineArguments(); - final String version = arguments.parse(participantConfigParameters); - assertThat(arguments.parse(participantConfigParameters)).startsWith( - "ONAP Tosca defined control loop Participant"); - } - - @Test - public void testParticipantHelp() throws ControlLoopException { - final String[] participantConfigParameters = { "-h" }; - final ParticipantPolicyCommandLineArguments arguments = new ParticipantPolicyCommandLineArguments(); - assertThat(arguments.parse(participantConfigParameters)).startsWith("usage:"); - } - - @Test - public void testParticipantInvalidOption() throws ControlLoopException { - final String[] participantConfigParameters = { "-d" }; - final ParticipantPolicyCommandLineArguments arguments = new ParticipantPolicyCommandLineArguments(); - assertThatThrownBy(() -> arguments.parse(participantConfigParameters)) - .hasMessageStartingWith("invalid command line arguments specified"); - } } diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/TestMain.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/TestMain.java deleted file mode 100644 index f77b678c0..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/TestMain.java +++ /dev/null @@ -1,143 +0,0 @@ -/*- - * ============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.startstop; - -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.onap.policy.clamp.controlloop.common.ControlLoopConstants; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.common.utils.resources.MessageConstants; -import org.onap.policy.common.utils.services.Registry; - -public class TestMain { - - /** - * Set up. - */ - @BeforeClass - public static void setUp() { - Registry.newRegistry(); - } - - /** - * Shuts "main" down. - * - * @throws Exception if an error occurs - */ - @AfterClass - public static void tearDown() throws Exception { - // shut down activator - final ParticipantPolicyActivator activator = - Registry.getOrDefault(ControlLoopConstants.REG_CLRUNTIME_ACTIVATOR, - ParticipantPolicyActivator.class, null); - if (activator != null && activator.isAlive()) { - activator.shutdown(); - } - } - - @Test - public void testMain_Help() { - final String[] configParameters = {"-h"}; - Main main = new Main(configParameters); - assertFalse(main.isRunning()); - } - - @Test - public void testMain_Version() { - final String[] configParameters = {"-v"}; - Main main = new Main(configParameters); - assertFalse(main.isRunning()); - } - - @Test - public void testMain_Valid() { - final String[] configParameters = {"-c", "src/test/resources/parameters/TestParameters.json"}; - Main main = new Main(configParameters); - assertTrue(main.isRunning()); - - assertThatCode(() -> main.shutdown()).doesNotThrowAnyException(); - - assertFalse(main.isRunning()); - } - - @Test - public void testMain_NoParameter() { - assertThatConfigParameterThrownException(new String[] {}); - } - - @Test - public void testMain_FilePathNotDefined() { - assertThatConfigParameterThrownException(new String[] {"-c"}); - } - - @Test - public void testMain_TooManyCommand() { - assertThatConfigParameterThrownException(new String[] {"-h", "d"}); - } - - @Test - public void testMain_WrongParameter() { - assertThatConfigParameterThrownException(new String[] {"-d"}); - } - - private void assertThatConfigParameterThrownException(final String[] configParameters) { - assertThatThrownBy(() -> Main.main(configParameters)).isInstanceOf(ControlLoopRuntimeException.class) - .hasMessage(String.format(MessageConstants.START_FAILURE_MSG, MessageConstants.POLICY_CLAMP)); - } - - @Test - public void testParticipant_NoFileWithThisName() { - assertThatConfigFileThrownException("src/test/resources/parameters/NoFileWithThisName.json"); - } - - @Test - public void testParticipant_NotValidFile() { - assertThatConfigFileThrownException("src/test/resources/parameters"); - } - - @Test - public void testParticipant_NoParameters() { - assertThatConfigFileThrownException("src/test/resources/parameters/NoParameters.json"); - } - - @Test - public void testParticipant_InvalidParameters() { - assertThatConfigFileThrownException("src/test/resources/parameters/InvalidParameters.json"); - } - - @Test - public void testParticipant_WrongJsonFormat() { - assertThatConfigFileThrownException("src/test/resources/parameters/Unreadable.json"); - } - - private void assertThatConfigFileThrownException(final String configFilePath) { - final String[] configParameters = new String[] {"-c", configFilePath}; - assertThatThrownBy(() -> new Main(configParameters)).isInstanceOf(ControlLoopRuntimeException.class) - .hasMessage(String.format(MessageConstants.START_FAILURE_MSG, MessageConstants.POLICY_CLAMP)); - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/TestParticipantPolicyActivator.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/TestParticipantPolicyActivator.java deleted file mode 100644 index afb0f6cb4..000000000 --- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/startstop/TestParticipantPolicyActivator.java +++ /dev/null @@ -1,88 +0,0 @@ -/*- - * ============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.startstop; - -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.CommonTestData; -import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.ParticipantPolicyParameterHandler; -import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.ParticipantPolicyParameters; -import org.onap.policy.common.utils.services.Registry; - -public class TestParticipantPolicyActivator { - - private static ParticipantPolicyActivator activator; - - /** - * Initializes an activator. - * - * @throws Exception if an error occurs - */ - @BeforeClass - public static void setUp() throws Exception { - Registry.newRegistry(); - final String[] participantConfigParameters = { "-c", "src/test/resources/parameters/TestParameters.json"}; - final ParticipantPolicyCommandLineArguments arguments = - new ParticipantPolicyCommandLineArguments(participantConfigParameters); - final ParticipantPolicyParameters parGroup = - new ParticipantPolicyParameterHandler().getParameters(arguments); - activator = new ParticipantPolicyActivator(parGroup); - } - - /** - * Method for cleanup after each test. - * - * @throws Exception if an error occurs - */ - @AfterClass - public static void teardown() throws Exception { - // shut down activator - if (activator != null && activator.isAlive()) { - activator.shutdown(); - } - } - - @Test - public void testParticipantActivator() { - activator.start(); - assertTrue(activator.isAlive()); - assertTrue(activator.getParameters().isValid()); - assertEquals(CommonTestData.PARTICIPANT_GROUP_NAME, activator.getParameters().getName()); - - // repeat - should throw an exception - assertThatIllegalStateException().isThrownBy(() -> activator.start()); - assertTrue(activator.isAlive()); - assertTrue(activator.getParameters().isValid()); - - activator.shutdown(); - assertFalse(activator.isAlive()); - - // repeat - should throw an exception - assertThatIllegalStateException().isThrownBy(() -> activator.shutdown()); - assertFalse(activator.isAlive()); - } -} diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/TestListenerUtils.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/TestListenerUtils.java index 4f3d6d62c..794b9ff69 100644 --- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/TestListenerUtils.java +++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/TestListenerUtils.java @@ -29,7 +29,6 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import java.util.UUID; -import lombok.Getter; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState; @@ -39,10 +38,7 @@ import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.Parti import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopUpdate; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantHealthCheck; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStateChange; -import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler; -import org.onap.policy.clamp.controlloop.participant.policy.main.handler.PolicyProvider; import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.CommonTestData; -import org.onap.policy.clamp.controlloop.participant.policy.main.parameters.ParticipantPolicyParameters; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.common.utils.coder.StandardCoder; @@ -61,27 +57,9 @@ public class TestListenerUtils { static CommonTestData commonTestData = new CommonTestData(); private static final Logger LOGGER = LoggerFactory.getLogger(TestListenerUtils.class); - @Getter - private static ParticipantHandler participantHandler; - private TestListenerUtils() {} /** - * Method to initialize participantHandler. - */ - public static void initParticipantHandler() { - - final ParticipantPolicyParameters participantParameters = commonTestData.toObject( - commonTestData.getParticipantPolicyParametersMap(CommonTestData.PARTICIPANT_GROUP_NAME), - ParticipantPolicyParameters.class); - - PolicyProvider policyProvider = - new PolicyProvider(participantParameters.getIntermediaryParameters()); - - participantHandler = policyProvider.getIntermediaryApi().getParticipantHandler(); - } - - /** * Method to create a controlLoop from a yaml file. * * @return ControlLoop controlloop |