diff options
32 files changed, 2890 insertions, 11 deletions
diff --git a/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java index b2a5e43a3..520e9b864 100644 --- a/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java +++ b/tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java @@ -29,6 +29,7 @@ import lombok.NonNull; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaControlLoop; import org.onap.policy.common.parameters.BeanValidationResult; +import org.onap.policy.models.base.PfAuthorative; import org.onap.policy.models.base.PfConceptKey; import org.onap.policy.models.base.PfKey; import org.onap.policy.models.base.PfModelException; @@ -36,7 +37,10 @@ import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.provider.PolicyModelsProviderParameters; import org.onap.policy.models.provider.impl.AbstractModelsProvider; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter; +import org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate; /** * This class provides information on control loop concepts in the database to callers. @@ -88,7 +92,7 @@ public class ControlLoopProvider extends AbstractModelsProvider { */ public List<ControlLoop> getControlLoops(final String name, final String version) throws PfModelException { - return asControlLoopList(getPfDao().getFiltered(JpaControlLoop.class, name, version)); + return asEntityList(getPfDao().getFiltered(JpaControlLoop.class, name, version)); } /** @@ -96,12 +100,12 @@ public class ControlLoopProvider extends AbstractModelsProvider { * * @param filter the filter for the control loops to get * @return the control loops found - * @throws PfModelException on errors getting policies + * @throws PfModelException on errors getting control loops */ public List<ControlLoop> getFilteredControlLoops(@NonNull final ToscaTypedEntityFilter<ControlLoop> filter) { - return filter.filter(asControlLoopList( - getPfDao().getFiltered(JpaControlLoop.class, filter.getName(), PfKey.NULL_KEY_VERSION))); + return filter.filter( + asEntityList(getPfDao().getFiltered(JpaControlLoop.class, filter.getName(), PfKey.NULL_KEY_VERSION))); } /** @@ -207,12 +211,38 @@ public class ControlLoopProvider extends AbstractModelsProvider { } /** + * Get Node Templates. + * + * @param name the name of the node template to get, null to get all node templates + * @param version the version of the node template to get, null to get all node templates + * @return the node templates found + * @throws PfModelException on errors getting node templates + */ + public List<ToscaNodeTemplate> getNodeTemplates(final String name, final String version) { + return asEntityList(getPfDao().getFiltered(JpaToscaNodeTemplate.class, name, version)); + } + + /** + * Get filtered node templates. + * + * @param filter the filter for the node templates to get + * @return the node templates found + * @throws PfModelException on errors getting node templates + */ + public List<ToscaNodeTemplate> getFilteredNodeTemplates( + @NonNull final ToscaTypedEntityFilter<ToscaNodeTemplate> filter) { + + return filter.filter(asEntityList( + getPfDao().getFiltered(JpaToscaNodeTemplate.class, filter.getName(), filter.getVersion()))); + } + + /** * Convert JPA control loop list to an authorative control loop list. * - * @param jpaControlLoopList the list to convert + * @param jpaEntityList the list to convert * @return the authorative list */ - private List<ControlLoop> asControlLoopList(List<JpaControlLoop> jpaControlLoopList) { - return jpaControlLoopList.stream().map(JpaControlLoop::toAuthorative).collect(Collectors.toList()); + private <T extends ToscaEntity, J extends PfAuthorative<T>> List<T> asEntityList(List<J> jpaEntityList) { + return jpaEntityList.stream().map(J::toAuthorative).collect(Collectors.toList()); } } diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameterHandler.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameterHandler.java new file mode 100644 index 000000000..7bd2851df --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameterHandler.java @@ -0,0 +1,78 @@ +/*- + * ============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.simulator.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.simulator.main.startstop.ParticipantSimulatorCommandLineArguments; +import org.onap.policy.common.parameters.GroupValidationResult; +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 participant simulator parameters from JSON files. + */ +public class ParticipantSimulatorParameterHandler { + + private static final Coder CODER = new StandardCoder(); + + /** + * Read the parameters from the parameter file. + * + * @param arguments the arguments passed to simulator + * @return the parameters read from the configuration file + * @throws ControlLoopException on parameter exceptions + */ + public ParticipantSimulatorParameters getParameters(final ParticipantSimulatorCommandLineArguments arguments) + throws ControlLoopException { + ParticipantSimulatorParameters parameters = null; + + // Read the parameters + try { + // Read the parameters from JSON + File file = new File(arguments.getFullConfigurationFilePath()); + parameters = CODER.decode(file, ParticipantSimulatorParameters.class); + } catch (final CoderException e) { + final String errorMessage = "error reading parameters from \"" + arguments.getConfigurationFilePath() + + "\"\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); + } + + // validate the parameters + final GroupValidationResult validationResult = parameters.validate(); + if (!validationResult.isValid()) { + String returnMessage = + "validation error(s) on parameters from \"" + arguments.getConfigurationFilePath() + "\"\n"; + returnMessage += validationResult.getResult(); + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, returnMessage); + } + + return parameters; + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameters.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameters.java new file mode 100644 index 000000000..dd28d4e5b --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/ParticipantSimulatorParameters.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.simulator.main.parameters; + +import javax.validation.constraints.NotBlank; +import lombok.Getter; +import org.onap.policy.common.endpoints.parameters.RestServerParameters; +import org.onap.policy.common.parameters.ParameterGroupImpl; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.models.provider.PolicyModelsProviderParameters; + +/** + * Class to hold all parameters needed for the participant simulator. + * + */ +@NotNull +@NotBlank +@Getter +public class ParticipantSimulatorParameters extends ParameterGroupImpl { + private RestServerParameters restServerParameters; + private PolicyModelsProviderParameters databaseProviderParameters; + + /** + * Create the participant simulator parameter group. + * + * @param name the parameter group name + */ + public ParticipantSimulatorParameters(final String name) { + super(name); + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/ParticipantSimulatorAafFilter.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/ParticipantSimulatorAafFilter.java new file mode 100644 index 000000000..f200f975a --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/ParticipantSimulatorAafFilter.java @@ -0,0 +1,38 @@ +/*- + * ============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.simulator.main.rest; + +import org.onap.policy.common.endpoints.http.server.aaf.AafGranularAuthFilter; +import org.onap.policy.common.utils.resources.MessageConstants; + +/** + * Class to manage AAF filters for the participant simulator component. + */ +public class ParticipantSimulatorAafFilter extends AafGranularAuthFilter { + + public static final String AAF_NODETYPE = MessageConstants.POLICY_CLAMP + "-participant-simulator"; + public static final String AAF_ROOT_PERMISSION = DEFAULT_NAMESPACE + "." + AAF_NODETYPE; + + @Override + public String getPermissionTypeRoot() { + return AAF_ROOT_PERMISSION; + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/Main.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/Main.java new file mode 100644 index 000000000..e6c93d55d --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/Main.java @@ -0,0 +1,141 @@ +/*- + * ============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.simulator.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.simulator.main.parameters.ParticipantSimulatorParameterHandler; +import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.ParticipantSimulatorParameters; +import org.onap.policy.common.utils.resources.MessageConstants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class initiates participant simulator. + */ +public class Main { + + private static final Logger LOGGER = LoggerFactory.getLogger(Main.class); + + private ParticipantSimulatorActivator activator; + + @Getter + private ParticipantSimulatorParameters 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 participant service with arguments - {}", argumentString); + + // Check the arguments + final ParticipantSimulatorCommandLineArguments arguments = new ParticipantSimulatorCommandLineArguments(); + 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 ParticipantSimulatorParameterHandler().getParameters(arguments); + + // Now, create the activator for the service + activator = new ParticipantSimulatorActivator(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 ClParticipantSimulatorShutdownHookClass()); + 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 ClParticipantSimulatorShutdownHookClass terminates the control loop participant service + * when its run method is called. + */ + private class ClParticipantSimulatorShutdownHookClass extends Thread { + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + try { + // Shutdown the participant simulator and wait for everything to stop + shutdown(); + } catch (final RuntimeException | ControlLoopException e) { + LOGGER.warn("error occured during shut down of the participant simulator", 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/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/ParticipantSimulatorActivator.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/ParticipantSimulatorActivator.java new file mode 100644 index 000000000..8658750f8 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/ParticipantSimulatorActivator.java @@ -0,0 +1,71 @@ +/*- + * ============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.simulator.main.startstop; + +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; +import lombok.Getter; +import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.ParticipantSimulatorParameters; +import org.onap.policy.clamp.controlloop.participant.simulator.main.rest.ParticipantSimulatorAafFilter; +import org.onap.policy.clamp.controlloop.participant.simulator.simulation.SimulationHandler; +import org.onap.policy.common.endpoints.http.server.RestServer; +import org.onap.policy.common.utils.services.ServiceManagerContainer; + +/** + * This class activates the participant simulator component as a complete service together with all its controllers, + * listeners and handlers. + */ +public class ParticipantSimulatorActivator extends ServiceManagerContainer { + @Getter + private final ParticipantSimulatorParameters parameters; + + /** + * Instantiate the activator for the simulator as a complete service. + * + * @param parameters the parameters for the participant service + */ + public ParticipantSimulatorActivator(final ParticipantSimulatorParameters parameters) { + this.parameters = parameters; + + final AtomicReference<SimulationHandler> simulationHandler = new AtomicReference<>(); + final AtomicReference<RestServer> restServer = new AtomicReference<>(); + + // @formatter:off + addAction("Simulation Handler", + () -> simulationHandler.set(new SimulationHandler(parameters)), + () -> simulationHandler.get().close()); + + parameters.getRestServerParameters().setName(parameters.getName()); + + addAction("REST server", + () -> { + Set<Class<?>> providerClasses = simulationHandler.get().getProviderClasses(); + + RestServer server = new RestServer(parameters.getRestServerParameters(), + ParticipantSimulatorAafFilter.class, + providerClasses.toArray(new Class<?>[providerClasses.size()])); + restServer.set(server); + restServer.get().start(); + }, + () -> restServer.get().stop()); + // @formatter:on + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/ParticipantSimulatorCommandLineArguments.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/ParticipantSimulatorCommandLineArguments.java new file mode 100644 index 000000000..24c4b7d2f --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/ParticipantSimulatorCommandLineArguments.java @@ -0,0 +1,232 @@ +/*- + * ============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.simulator.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.common.utils.resources.ResourceUtils; + +/** + * This class reads and handles command line parameters for the participant simulator service. + * + */ +public class ParticipantSimulatorCommandLineArguments { + private static final String FILE_MESSAGE_PREAMBLE = " file \""; + private static final int HELP_LINE_LENGTH = 120; + + private final Options options; + @Getter() + @Setter() + private String configurationFilePath = null; + + /** + * Construct the options for the participant component. + */ + public ParticipantSimulatorCommandLineArguments() { + //@formatter:off + options = new Options(); + options.addOption(Option.builder("h") + .longOpt("help") + .desc("outputs the usage of this command") + .required(false) + .type(Boolean.class) + .build()); + options.addOption(Option.builder("v") + .longOpt("version") + .desc("outputs the version of participant") + .required(false) + .type(Boolean.class) + .build()); + options.addOption(Option.builder("c") + .longOpt("config-file") + .desc("the full path to the configuration file to use, " + + "the configuration file must be a Json file containing the participant parameters") + .hasArg() + .argName("CONFIG_FILE") + .required(false) + .type(String.class) + .build()); + //@formatter:on + } + + /** + * Construct the options for the participant component and parse in the given arguments. + * + * @param args The command line arguments + */ + public ParticipantSimulatorCommandLineArguments(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 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 help(Main.class.getName()); + } + + if (commandLine.hasOption('v')) { + return 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 { + validateReadableFile("participant configuration", configurationFilePath); + } + + /** + * Print version information for participant. + * + * @return the version string + */ + public String version() { + return ResourceUtils.getResourceAsString("version.txt"); + } + + /** + * Print help information for participant. + * + * @param mainClassName the main class name + * @return the help string + */ + public String help(final String mainClassName) { + final HelpFormatter helpFormatter = new HelpFormatter(); + final StringWriter stringWriter = new StringWriter(); + final PrintWriter printWriter = new PrintWriter(stringWriter); + + helpFormatter.printHelp(printWriter, HELP_LINE_LENGTH, mainClassName + " [options...]", "options", options, 0, + 0, ""); + + return stringWriter.toString(); + } + + /** + * 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); + } + + /** + * Validate readable file. + * + * @param fileTag the file tag + * @param fileName the file name + * @throws ControlLoopException on the file name passed as a parameter + */ + private void validateReadableFile(final String fileTag, final String fileName) throws ControlLoopException { + if (StringUtils.isEmpty(fileName)) { + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, + fileTag + " file was not specified as an argument"); + } + + // The file name refers to a resource on the local file system + final URL fileUrl = ResourceUtils.getUrl4Resource(fileName); + if (fileUrl == null) { + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, + fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" does not exist"); + } + + final File theFile = new File(fileUrl.getPath()); + if (!theFile.exists()) { + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, + fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" does not exist"); + } + if (!theFile.isFile()) { + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, + fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" is not a normal file"); + } + if (!theFile.canRead()) { + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, + fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" is ureadable"); + } + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationHandler.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationHandler.java new file mode 100644 index 000000000..7260318f0 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationHandler.java @@ -0,0 +1,75 @@ +/*- + * ============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.simulator.simulation; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler; +import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.ParticipantSimulatorParameters; +import org.onap.policy.clamp.controlloop.participant.simulator.simulation.rest.SimulationQueryElementController; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher; + +/** + * This class handles simulation of participants and control loop elements. + * + * <p/>It is effectively a singleton that is started at system start. + */ +public class SimulationHandler extends ControlLoopHandler { + /** + * Create a handler. + * + * @param parameters the parameters for access to the database + */ + public SimulationHandler(ParticipantSimulatorParameters parameters) { + super(parameters.getDatabaseProviderParameters()); + } + + @Override + public Set<Class<?>> getProviderClasses() { + Set<Class<?>> providerClasses = new HashSet<>(); + + providerClasses.add(SimulationQueryElementController.class); + + return providerClasses; + } + + @Override + public void startAndRegisterListeners(MessageTypeDispatcher msgDispatcher) { + // No topic communication on this handler + } + + @Override + public void startAndRegisterPublishers(List<TopicSink> topicSinks) { + // No topic communication on this handler + } + + @Override + public void stopAndUnregisterPublishers() { + // No topic communication on this handler + } + + @Override + public void stopAndUnregisterListeners(MessageTypeDispatcher msgDispatcher) { + // No topic communication on this handler + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationQueryElementController.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationQueryElementController.java new file mode 100644 index 000000000..2165da797 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/rest/SimulationQueryElementController.java @@ -0,0 +1,31 @@ +/*- + * ============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.simulator.simulation.rest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class to provide REST end points for participant simulator to query details of controlLoopElements. + */ +public class SimulationQueryElementController { + private static final Logger LOGGER = LoggerFactory.getLogger(SimulationQueryElementController.class); +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/resources/config/CDSParticipantConfig.json b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/resources/config/CDSParticipantConfig.json new file mode 100644 index 000000000..80f035cb2 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/resources/config/CDSParticipantConfig.json @@ -0,0 +1,27 @@ +{ + "name":"ParticipantParameterGroup", + "participantStatusParameters":{ + "timeIntervalMs": 10000, + "description":"Participant Status", + "participantId":{ + "name": "CDSParticipant0", + "version":"1.0.0" + }, + "participantDefinition":{ + "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant", + "version":"3.2.1" + } + }, + "topicParameterGroup": { + "topicSources" : [{ + "topic" : "POLICY-CLRUNTIME-PARTICIPANT", + "servers" : [ "127.0.0.1:3904" ], + "topicCommInfrastructure" : "dmaap" + }], + "topicSinks" : [{ + "topic" : "POLICY-CLRUNTIME-PARTICIPANT", + "servers" : [ "127.0.0.1:3904" ], + "topicCommInfrastructure" : "dmaap" + }] + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/resources/config/DCAEParticipantConfig.json b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/resources/config/DCAEParticipantConfig.json new file mode 100644 index 000000000..5c3d05d6f --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/resources/config/DCAEParticipantConfig.json @@ -0,0 +1,27 @@ +{ + "name":"ParticipantParameterGroup", + "participantStatusParameters":{ + "timeIntervalMs": 10000, + "description":"Participant Status", + "participantId":{ + "name": "DCAEParticipant0", + "version":"1.0.0" + }, + "participantDefinition":{ + "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant", + "version":"2.3.4" + } + }, + "topicParameterGroup": { + "topicSources" : [{ + "topic" : "POLICY-CLRUNTIME-PARTICIPANT", + "servers" : [ "127.0.0.1:3904" ], + "topicCommInfrastructure" : "dmaap" + }], + "topicSinks" : [{ + "topic" : "POLICY-CLRUNTIME-PARTICIPANT", + "servers" : [ "127.0.0.1:3904" ], + "topicCommInfrastructure" : "dmaap" + }] + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/resources/config/PolicyParticipantConfig.json b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/resources/config/PolicyParticipantConfig.json new file mode 100644 index 000000000..57c578451 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/resources/config/PolicyParticipantConfig.json @@ -0,0 +1,27 @@ +{ + "name":"ParticipantParameterGroup", + "participantStatusParameters":{ + "timeIntervalMs":10000, + "description":"Participant Status", + "participantId":{ + "name": "PolicyParticipant0", + "version":"1.0.0" + }, + "participantDefinition":{ + "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant", + "version":"2.3.1" + } + }, + "topicParameterGroup": { + "topicSources" : [{ + "topic" : "POLICY-CLRUNTIME-PARTICIPANT", + "servers" : [ "127.0.0.1:3904" ], + "topicCommInfrastructure" : "dmaap" + }], + "topicSinks" : [{ + "topic" : "POLICY-CLRUNTIME-PARTICIPANT", + "servers" : [ "127.0.0.1:3904" ], + "topicCommInfrastructure" : "dmaap" + }] + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/resources/version.txt b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/resources/version.txt new file mode 100644 index 000000000..dbd67585f --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/main/resources/version.txt @@ -0,0 +1,4 @@ +ONAP Tosca defined control loop Participant +Version: ${project.version} +Built (UTC): ${maven.build.timestamp} +ONAP https://wiki.onap.org diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/CommonTestData.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/CommonTestData.java new file mode 100644 index 000000000..e0e001743 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/CommonTestData.java @@ -0,0 +1,251 @@ +/*- + * ============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.simulator.main.parameters; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import javax.ws.rs.core.Response; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; +import org.onap.policy.common.endpoints.parameters.TopicParameters; +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.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * Class to hold/create all parameters for test cases. + */ +public class CommonTestData { + public static final String PARTICIPANT_GROUP_NAME = "ControlLoopParticipantGroup"; + public static final String DESCRIPTION = "Participant description"; + public static final long TIME_INTERVAL = 2000; + public static final List<TopicParameters> TOPIC_PARAMS = Arrays.asList(getTopicParams()); + private static final String REST_SERVER_PASSWORD = "zb!XztG34"; + private static final String REST_SERVER_USER = "healthcheck"; + private static final int REST_SERVER_PORT = 6969; + private static final String REST_SERVER_HOST = "0.0.0.0"; + private static final boolean REST_SERVER_HTTPS = true; + private static final boolean REST_SERVER_AAF = false; + + public static final Coder coder = new StandardCoder(); + + /** + * Converts the contents of a map to a parameter class. + * + * @param source property map + * @param clazz class of object to be created from the map + * @return a new object represented by the map + */ + public <T extends ParameterGroup> T toObject(final Map<String, Object> source, final Class<T> clazz) { + try { + return coder.convert(source, clazz); + } catch (final CoderException e) { + throw new RuntimeException("cannot create " + clazz.getName() + " from map", e); + } + } + + /** + * Returns a property map for a ApexStarterParameterGroup map for test cases. + * + * @param name name of the parameters + * + * @return a property map suitable for constructing an object + */ + public Map<String, Object> getParticipantParameterGroupMap(final String name) { + final Map<String, Object> map = new TreeMap<>(); + + map.put("name", name); + map.put("restServerParameters", getRestServerParametersMap(false)); + map.put("intermediaryParameters", getIntermediaryParametersMap(false)); + map.put("databaseProviderParameters", getDatabaseProviderParametersMap(false)); + return map; + } + + /** + * Returns a property map for a RestServerParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map<String, Object> getRestServerParametersMap(final boolean isEmpty) { + final Map<String, Object> map = new TreeMap<>(); + map.put("https", REST_SERVER_HTTPS); + map.put("aaf", REST_SERVER_AAF); + + if (!isEmpty) { + map.put("host", REST_SERVER_HOST); + map.put("port", REST_SERVER_PORT); + map.put("userName", REST_SERVER_USER); + map.put("password", REST_SERVER_PASSWORD); + } + + return map; + } + + /** + * Returns a property map for a databaseProviderParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map<String, Object> getDatabaseProviderParametersMap(final boolean isEmpty) { + final Map<String, Object> map = new TreeMap<>(); + if (!isEmpty) { + map.put("name", "PolicyProviderParameterGroup"); + map.put("implementation", "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl"); + map.put("databaseDriver", "org.h2.Driver"); + map.put("databaseUrl", "jdbc:h2:mem:testdb"); + map.put("databaseUser", "policy"); + map.put("databasePassword", "P01icY"); + map.put("persistenceUnit", "ToscaConceptTest"); + } + + return map; + } + + /** + * Returns a property map for a intermediaryParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map<String, Object> getIntermediaryParametersMap(final boolean isEmpty) { + final Map<String, Object> map = new TreeMap<>(); + if (!isEmpty) { + map.put("name", "Participant parameters"); + map.put("reportingTimeInterval", TIME_INTERVAL); + map.put("description", DESCRIPTION); + map.put("participantId", getParticipantId()); + map.put("participantType", getParticipantId()); + map.put("clampControlLoopTopics", getTopicParametersMap(false)); + } + + return map; + } + + /** + * Returns a property map for a TopicParameters map for test cases. + * + * @param isEmpty boolean value to represent that object created should be empty or not + * @return a property map suitable for constructing an object + */ + public Map<String, Object> getTopicParametersMap(final boolean isEmpty) { + final Map<String, Object> map = new TreeMap<>(); + if (!isEmpty) { + map.put("topicSources", TOPIC_PARAMS); + map.put("topicSinks", TOPIC_PARAMS); + } + return map; + } + + /** + * Returns topic parameters for test cases. + * + * @return topic parameters + */ + public static TopicParameters getTopicParams() { + final TopicParameters topicParams = new TopicParameters(); + topicParams.setTopic("POLICY-CLRUNTIME-PARTICIPANT"); + topicParams.setTopicCommInfrastructure("dmaap"); + topicParams.setServers(Arrays.asList("localhost")); + return topicParams; + } + + /** + * Returns participantId for test cases. + * + * @return participant Id + */ + public static ToscaConceptIdentifier getParticipantId() { + final ToscaConceptIdentifier participantId = new ToscaConceptIdentifier(); + participantId.setName("CDSParticipant0"); + participantId.setVersion("1.0.0"); + return participantId; + } + + /** + * Gets the standard participant parameters. + * + * @param port port to be inserted into the parameters + * @return the standard participant parameters + */ + public ParticipantSimulatorParameters getParticipantParameterGroup(int port) { + try { + return coder.decode(getParticipantParameterGroupAsString(port), ParticipantSimulatorParameters.class); + + } catch (CoderException e) { + throw new ControlLoopRuntimeException(Response.Status.NOT_ACCEPTABLE, + "cannot read participant parameters", e); + } + } + + /** + * Gets the standard participant parameters, as a String. + * + * @param port port to be inserted into the parameters + * @return the standard participant parameters + */ + public static String getParticipantParameterGroupAsString(int port) { + + try { + File file = new File(getParamFile()); + String json = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8); + + json = json.replace("${port}", String.valueOf(port)); + json = json.replace("${dbName}", "jdbc:h2:mem:testdb"); + + return json; + + } catch (IOException e) { + throw new ControlLoopRuntimeException(Response.Status.NOT_ACCEPTABLE, + "cannot read participant parameters", e); + + } + } + + /** + * Gets the full path to the parameter file, which may vary depending on whether or + * not this is an end-to-end test. + * + * @return the parameter file name + */ + private static String getParamFile() { + String paramFile = "src/test/resources/parameters/TestParametersStd.json"; + return paramFile; + } + + /** + * Nulls out a field within a JSON string. + * @param json JSON string + * @param field field to be nulled out + * @return a new JSON string with the field nulled out + */ + public String nullifyField(String json, String field) { + return json.replace(field + "\"", field + "\":null, \"" + field + "Xxx\""); + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/TestParticipantSimulatorParameterHandler.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/TestParticipantSimulatorParameterHandler.java new file mode 100644 index 000000000..f8b11d723 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/TestParticipantSimulatorParameterHandler.java @@ -0,0 +1,120 @@ +/*- + * ============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.simulator.main.parameters; + +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.onap.policy.clamp.controlloop.common.exception.ControlLoopException; +import org.onap.policy.clamp.controlloop.participant.simulator.main.startstop.ParticipantSimulatorCommandLineArguments; +import org.onap.policy.common.utils.coder.CoderException; + +/** + * Class to perform unit test of {@link ParticipantParameterHandler}. + */ +public class TestParticipantSimulatorParameterHandler { + + @Test + public void testParameterHandlerNoParameterFile() throws ControlLoopException { + final String[] emptyArgumentString = { "-c", "src/test/resources/parameters/NoParametersFile.json" }; + + final ParticipantSimulatorCommandLineArguments emptyArguments = new ParticipantSimulatorCommandLineArguments(); + emptyArguments.parse(emptyArgumentString); + + assertThatThrownBy(() -> new ParticipantSimulatorParameterHandler().getParameters(emptyArguments)) + .hasCauseInstanceOf(CoderException.class) + .hasRootCauseInstanceOf(FileNotFoundException.class); + } + + @Test + public void testParameterHandlerInvalidParameters() throws ControlLoopException { + final String[] invalidArgumentString = { "-c", "src/test/resources/parameters/InvalidParameters.json" }; + + final ParticipantSimulatorCommandLineArguments invalidArguments = + new ParticipantSimulatorCommandLineArguments(); + invalidArguments.parse(invalidArgumentString); + + assertThatThrownBy(() -> new ParticipantSimulatorParameterHandler().getParameters(invalidArguments)) + .hasMessageStartingWith("error reading parameters from") + .hasCauseInstanceOf(CoderException.class); + } + + @Test + public void testParameterHandlerNoParameters() throws CancelException, ControlLoopException { + final String[] noArgumentString = { "-c", "src/test/resources/parameters/EmptyParameters.json" }; + + final ParticipantSimulatorCommandLineArguments noArguments = new ParticipantSimulatorCommandLineArguments(); + noArguments.parse(noArgumentString); + + assertThatThrownBy(() -> new ParticipantSimulatorParameterHandler().getParameters(noArguments)) + .hasMessageContaining("no parameters found"); + } + + @Test + public void testParticipantParameterGroup() throws ControlLoopException { + final String[] participantConfigParameters = { "-c", "src/test/resources/parameters/TestParameters.json"}; + + final ParticipantSimulatorCommandLineArguments arguments = new ParticipantSimulatorCommandLineArguments(); + arguments.parse(participantConfigParameters); + + final ParticipantSimulatorParameters parGroup = new ParticipantSimulatorParameterHandler() + .getParameters(arguments); + assertTrue(arguments.checkSetConfigurationFilePath()); + assertEquals(CommonTestData.PARTICIPANT_GROUP_NAME, parGroup.getName()); + } + + @Test + public void testParticipantVersion() throws ControlLoopException { + final String[] participantConfigParameters = { "-v" }; + final ParticipantSimulatorCommandLineArguments arguments = new ParticipantSimulatorCommandLineArguments(); + final String version = arguments.parse(participantConfigParameters); + assertTrue(version.startsWith("ONAP Tosca defined control loop Participant")); + } + + @Test + public void testParticipantHelp() throws ControlLoopException { + final String[] participantConfigParameters = { "-h" }; + final ParticipantSimulatorCommandLineArguments arguments = new ParticipantSimulatorCommandLineArguments(); + final String help = arguments.parse(participantConfigParameters); + assertTrue(help.startsWith("usage:")); + } + + @Test + public void testParticipant_TooManyArguments() throws ControlLoopException { + final String[] participantConfigParameters = { "-c", "src/test/resources/parameters/TestParameters.json", + "TooMany"}; + final ParticipantSimulatorCommandLineArguments arguments = new ParticipantSimulatorCommandLineArguments(); + assertThatThrownBy(() -> arguments.parse(participantConfigParameters)) + .hasMessageStartingWith("too many command line arguments specified"); + } + + @Test + public void testParticipantInvalidOption() throws ControlLoopException { + final String[] participantConfigParameters = { "-d" }; + final ParticipantSimulatorCommandLineArguments arguments = new ParticipantSimulatorCommandLineArguments(); + assertThatThrownBy(() -> arguments.parse(participantConfigParameters)) + .hasMessageStartingWith("invalid command line arguments specified"); + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/TestParticipantSimulatorParameters.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/TestParticipantSimulatorParameters.java new file mode 100644 index 000000000..dcfbe94b7 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/parameters/TestParticipantSimulatorParameters.java @@ -0,0 +1,84 @@ +/*- + * ============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.simulator.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.assertTrue; + +import org.junit.Test; +import org.onap.policy.common.parameters.GroupValidationResult; + +/** + * Class to perform unit test of {@link ParticipantParameterGroup}. + */ +public class TestParticipantSimulatorParameters { + CommonTestData commonTestData = new CommonTestData(); + + @Test + public void testParticipantParameterGroup_Named() { + final ParticipantSimulatorParameters participantParameters = new ParticipantSimulatorParameters("my-name"); + assertEquals("my-name", participantParameters.getName()); + } + + @Test + public void testParticipantParameterGroup() { + final ParticipantSimulatorParameters participantParameters = commonTestData.toObject( + commonTestData.getParticipantParameterGroupMap(CommonTestData.PARTICIPANT_GROUP_NAME), + ParticipantSimulatorParameters.class); + assertThat(participantParameters.validate().isValid()).isTrue(); + assertEquals(CommonTestData.PARTICIPANT_GROUP_NAME, participantParameters.getName()); + } + + @Test + public void testParticipantParameterGroup_NullName() { + final ParticipantSimulatorParameters participantParameters = commonTestData + .toObject(commonTestData.getParticipantParameterGroupMap(null), + ParticipantSimulatorParameters.class); + final GroupValidationResult validationResult = participantParameters.validate(); + assertFalse(validationResult.isValid()); + assertEquals(null, participantParameters.getName()); + assertTrue(validationResult.getResult().contains("is null")); + } + + @Test + public void testParticipantParameterGroup_EmptyName() { + final ParticipantSimulatorParameters participantParameters = commonTestData + .toObject(commonTestData.getParticipantParameterGroupMap(""), + ParticipantSimulatorParameters.class); + final GroupValidationResult validationResult = participantParameters.validate(); + assertFalse(validationResult.isValid()); + assertEquals("", participantParameters.getName()); + assertTrue(validationResult.getResult().contains( + "field \"name\" type \"java.lang.String\" value \"\" INVALID, " + "must be a non-blank string")); + } + + @Test + public void testParticipantParameterGroup_SetName() { + final ParticipantSimulatorParameters participantParameters = commonTestData.toObject( + commonTestData.getParticipantParameterGroupMap(CommonTestData.PARTICIPANT_GROUP_NAME), + ParticipantSimulatorParameters.class); + participantParameters.setName("ParticipantNewGroup"); + assertThat(participantParameters.validate().isValid()).isTrue(); + assertEquals("ParticipantNewGroup", participantParameters.getName()); + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/TestMain.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/TestMain.java new file mode 100644 index 000000000..137bec205 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/TestMain.java @@ -0,0 +1,121 @@ +/*- + * ============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.simulator.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; + +/** + * Class to perform unit test of {@link Main}}. + */ +public class TestMain { + + @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_FileEmpty() { + assertThatConfigFileThrownException("src/test/resources/parameters/EmptyParameters.json"); + } + + @Test + public void testParticipant_NoParameters() { + assertThatConfigFileThrownException("src/test/resources/parameters/NoParameters.json"); + } + + @Test + public void testParticipant_InvalidParameters() { + assertThatConfigFileThrownException("src/test/resources/parameters/InvalidParameters.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/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/TestParticipantSimulatorActivator.java b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/TestParticipantSimulatorActivator.java new file mode 100644 index 000000000..c695d5f24 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/startstop/TestParticipantSimulatorActivator.java @@ -0,0 +1,89 @@ +/*- + * ============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.simulator.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.simulator.main.parameters.CommonTestData; +import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.ParticipantSimulatorParameterHandler; +import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.ParticipantSimulatorParameters; + +/** + * Class to perform unit test of {@link ParticipantActivator}}. + */ +public class TestParticipantSimulatorActivator { + + private static ParticipantSimulatorActivator activator; + + /** + * Initializes an activator. + * + * @throws Exception if an error occurs + */ + @BeforeClass + public static void setUp() throws Exception { + final String[] participantConfigParameters = { "-c", "src/test/resources/parameters/TestParameters.json"}; + final ParticipantSimulatorCommandLineArguments arguments = + new ParticipantSimulatorCommandLineArguments(participantConfigParameters); + final ParticipantSimulatorParameters parGroup = + new ParticipantSimulatorParameterHandler().getParameters(arguments); + activator = new ParticipantSimulatorActivator(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/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/EmptyParameters.json b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/EmptyParameters.json new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/EmptyParameters.json diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/InvalidParameters.json b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/InvalidParameters.json new file mode 100644 index 000000000..1035ccb67 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/InvalidParameters.json @@ -0,0 +1,3 @@ +{ + "name": " +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/NoParameters.json b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/NoParameters.json new file mode 100644 index 000000000..7a73a41bf --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/NoParameters.json @@ -0,0 +1,2 @@ +{ +}
\ No newline at end of file diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/TestParameters.json b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/TestParameters.json new file mode 100644 index 000000000..82bb917a9 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/TestParameters.json @@ -0,0 +1,61 @@ +{ + "name": "ControlLoopParticipantGroup", + "restServerParameters": { + "host": "0.0.0.0", + "port": 6969, + "userName": "healthcheck", + "password": "zb!XztG34", + "https": false, + "aaf": false + }, + "intermediaryParameters": { + "name": "Participant parameters", + "reportingTimeInterval": 120000, + "description": "Participant Description", + "participantId": { + "name": "CDSParticipant0", + "version": "1.0.0" + }, + "participantType": { + "name": "CDSParticipant0", + "version": "1.0.0" + }, + "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.h2.Driver", + "databaseUrl": "jdbc:h2:mem:testdb", + "databaseUser": "policy", + "databasePassword": "P01icY", + "persistenceUnit": "ToscaConceptTest" + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/TestParametersStd.json b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/TestParametersStd.json new file mode 100644 index 000000000..1599fc395 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/TestParametersStd.json @@ -0,0 +1,61 @@ +{ + "name": "ControlLoopParticipantGroup", + "restServerParameters": { + "host": "0.0.0.0", + "port": ${port}, + "userName": "healthcheck", + "password": "zb!XztG34", + "https": false, + "aaf": false + }, + "intermediaryParameters": { + "name": "Participant parameters", + "reportingTimeInterval": 120000, + "description": "Participant Description", + "participantId": { + "name": "CDSParticipant0", + "version": "1.0.0" + }, + "participantType": { + "name": "CDSParticipant0", + "version": "1.0.0" + }, + "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.h2.Driver", + "databaseUrl": "jdbc:h2:mem:testdb", + "databaseUser": "policy", + "databasePassword": "P01icY", + "persistenceUnit": "ToscaConceptTest" + } +} diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/Unreadable.json b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/Unreadable.json new file mode 100644 index 000000000..f11bd8c95 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/Unreadable.json @@ -0,0 +1,81 @@ +{ + "name": "ControlLoopRuntimeGroup", + "restServerParameters": { + "host": "0.0.0.0", + "port": 6969, + "userName": "healthcheck", + "password": "zb!XztG34", + "https": false, + "aaf": false + }, + "participantParameters": { + "heartBeatMs": 120000, + "updateParameters": { + "maxRetryCount": 1, + "maxWaitMs": 30000 + }, + "stateChangeParameters": { + "maxRetryCount": 1, + "maxWaitMs": 30000 + } + }, + "databaseProviderParameters": { + "name": "PolicyProviderParameterGroup", + "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl", + "databaseDriver": "org.h2.Driver", + "databaseUrl": "jdbc:h2:mem:testdb", + "databaseUser": "policy", + "databasePassword": "P01icY", + "persistenceUnit": "ToscaConceptTest" + }, + "topicParameterGroup": { + "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" + } + ] + }, + "healthCheckRestClientParameters": [ + { + "clientName": "api", + "hostname": "policy-api", + "port": 6969, + "userName": "healthcheck", + "password": "zb!XztG34", + "useHttps": true, + "basePath": "policy/api/v1/healthcheck" + }, + { + "clientName": "distribution", + "hostname": "policy-distribution", + "port": 6969, + "userName": "healthcheck", + "password": "zb!XztG34", + "useHttps": true, + "basePath": "healthcheck" + } + ] +} + + diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/logback-test.xml b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/logback-test.xml new file mode 100644 index 000000000..54b578653 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/parameters/logback-test.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============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========================================================= +--> + +<configuration> + + <contextName>Participant</contextName> + <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /> + <property name="LOG_DIR" value="${java.io.tmpdir}/clamp_logging/" /> + + <!-- USE FOR STD OUT ONLY --> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <Pattern>%d %level %msg%n</Pattern> + </encoder> + </appender> + + <root level="info"> + <appender-ref ref="STDOUT" /> + </root> + + <logger name="org.onap.policy.clamp.controlloop.participant" level="trace" additivity="false"> + <appender-ref ref="STDOUT" /> + </logger> +</configuration> diff --git a/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/rest/servicetemplates/pm_control_loop_tosca.yaml b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/rest/servicetemplates/pm_control_loop_tosca.yaml new file mode 100644 index 000000000..01f825fc9 --- /dev/null +++ b/tosca-controlloop/participant/participant-impl/participant-impl-simulator/src/test/resources/rest/servicetemplates/pm_control_loop_tosca.yaml @@ -0,0 +1,452 @@ +tosca_definitions_version: tosca_simple_yaml_1_3 +capability_types: + org.onap.EventProducer: + properties: + carrier_protocol_type: + type: string + required: true + constraints: + - valid_values: + - DMAAP_message_router + - SOMETHING_ELSE + - REST + data_format: + type: string + required: true + constraints: + - valid_values: + - JSON + - YAML + - JMS + event_format: + type: string + required: true + event_format_version: + type: string + required: false + config_keys: + type: list + required: false + entry_schema: + type: string + constraints: + - valid_values: + - all valid values should be added here + - if not specified, events of any config key may be generated + - 'examples for config_key: ves-measurement, ves-syslog, tca_handle_out, + etc.' + version: 0.0.1 + derived_from: tosca.capabilities.Root + org.onap.EventConsumer: + properties: + responding_capability: + type: string + required: false + carrier_protocol_type: + type: string + required: true + constraints: + - valid_values: + - DMAAP_message_router + - SOMETHING_ELSE + - REST + data_format: + type: string + required: true + constraints: + - valid_values: + - JSON + - YAML + - JMS + - all valid values should be added here + event_format: + type: string + description: 'examples for event_format: Ves_specification, LinkUp, VnfConfigured, + etc.' + required: true + event_format_version: + type: string + description: 'examples for event_format_version: 5.28.4, 7.30.1, etc.' + required: false + config_keys: + type: list + required: false + entry_schema: + type: string + constraints: + - valid_values: + - all valid values should be added here + - if not specified, events of any config key may be generated + - 'examples for config_key: ves-measurement, ves-syslog, tca_handle_out, + etc.' + version: 0.0.1 + derived_from: tosca.capabilities.Root +node_types: + org.onap.DynamicConfig: + properties: + application_name: + type: string + description: Value used to tie the config to an application ? should we be + using a relationship here instead? + required: true + application_version: + type: string + required: true + application_provider: + type: string + required: false + data_types: + type: object + required: false + schema: + type: object + required: false + version: 0.0.1 + derived_from: tosca.nodes.Root + org.onap.APP: + properties: + application_name: + type: string + description: Human readable name for the application Product + required: false + provider: + type: string + description: Provider of the application and of the descriptor + required: true + application_version: + type: string + description: Software version of the application + required: true + blueprint_id: + type: string + description: A reference to the app blueprint + required: false + monitoring_policy: + type: string + description: A reference to the monitoring policy + required: false + requirements: + - receive: + capability: org.onap.EventProducer + relationship: org.onap.PropagateEvent + occurrences: + - 0.0 + - UNBOUNDED + version: 0.0.0 + - send: + capability: org.onap.EventConsumer + relationship: org.onap.PropagateEvent + occurrences: + - 0.0 + - UNBOUNDED + version: 0.0.0 + version: 0.0.1 + derived_from: tosca.nodes.Root + org.onap.EventRelay: + properties: + event_format: + type: string + description: 'examples for event_format: Ves_specification, etc.' + required: true + event_format_version: + type: string + description: 'examples for event_format_version: 5.28.4, 7.30.1, etc.' + required: true + config_keys: + type: list + required: false + entry_schema: + type: string + constraints: + - valid_values: + - all valid values should be added here + - if not specified, events of any config key is relayed + - 'examples for config_key: ves-measurement, ves-syslog, tca_handle_out, + etc.' + supported_carrier_protocols: + type: map + description: 'A map describing supported carrier protocols and translations. + The tuples define what protocol combinations are supported on the producer + and consumer side: e.g. { REST: REST, DMAAP: REST, DMAAP: DMAAP}' + required: true + key_schema: + type: string + constraints: + - valid_values: + - DMAAP_message_router + - SOMETHING_ELSE + - REST + - all valid values should be added here + entry_schema: + type: string + constraints: + - valid_values: + - DMAAP_message_router + - SOMETHING_ELSE + - REST + - all valid values should be added here + supported_data_formats: + type: map + description: 'Is a map describing supported data formats and translation. + The tuples define what protocol combinations are supported on the producer + and consumer side: e.g. { JSON: JSON, JMS: JSON, YAML:YAML }' + required: true + key_schema: + type: string + constraints: + - valid_values: + - JSON + - JMS + - YAML + - etc + - all valid values should be added here + entry_schema: + type: string + constraints: + - valid_values: + - JSON + - JMS + - YAML + - etc + - all valid values should be added here + requirements: + - receive: + capability: org.onap.EventProducer + relationship: org.onap.PropagateEvent + occurrences: + - 0.0 + - UNBOUNDED + version: 0.0.0 + - send: + capability: org.onap.EventConsumer + relationship: org.onap.PropagateEvent + occurrences: + - 0.0 + - UNBOUNDED + version: 0.0.0 + version: 0.0.1 + derived_from: tosca.nodes.Root +relationship_types: + org.onap.PropagateEvent: + properties: + config_keys: + type: list + description: The relationship type used on requirements to org.onap.EventProducer + and org.onap.EventConsumer capabilities. Filters events by specific config_keys + to be transferred by this relationship. That is, any event with a specific + config_key found in the list is transferred. If list is not defined or is + empty, events with all config_keys are transferred. + required: false + entry_schema: + type: string + version: 0.0.1 + derived_from: tosca.relationships.Root +topology_template: + inputs: + pm_subscription_topic: + type: string + pm_subscription_response_topic: + type: string + pm_subscription_handler_blueprint_id: + type: string + pm_subscription_operational_policy_id: + type: string + pm_subscription_cds_blueprint_id: + type: string + enable_tls: + type: string + node_templates: + org.onap.PM_Subscription_Handler: + type: org.onap.APP + properties: + application_name: PM Subscription Handler + provider: Ericsson + application_version: 1.0.0 + artifact_id: + get_input: pm_subscription_handler_blueprint_id + description: Is this a reference to the DCAE Cloudify Blueprint that is + already stored(or will be stored before CL configuration & instatiation) + in DCAE Inventory? + artifact_config: + enable_tls: + get_input: enable_tls + pmsh_publish_topic_name: + get_input: pm_subscription_topic + capabilities: + pm-subscription-event-publisher: + properties: + carrier_protocol_type: DMAAP_message_router + data_format: JSON + event_format: pm-subscription-event-format + event_format_version: 1.0.0 + attributes: + type: org.onap.EventProducer + occurrences: + - 0.0 + - UNBOUNDED + version: 0.0.0 + pm-subscription-event-receiver: + properties: + carrier_protocol_type: DMAAP_message_router + data_format: JSON + event_format: pm-subscription-event-response-format + event_format_version: 1.0.0 + relationships: + - type: tosca.relationships.DependsOn + - description: any ideas on a better realtionship ? or is it better to + just use the root realtionship ? + - target: org.onap.PM_Monitoring_Policy + attributes: + type: org.onap.EventConsumer + occurrences: + - 0.0 + - UNBOUNDED + version: 0.0.0 + version: 0.0.0 + org.onap.PM_Monitoring_Policy: + type: org.onap.DynamicConfig + properties: + application_name: PM Subscription Handler + application_version: 1.0.0 + provider: Ericsson + data_types: + measurementType: + type: string + DN: + type: string + nfFilter: + properties: + nfNames: + type: list + entry_schema: string + modelInvariantIDs: + type: list + entry_schema: + type: string + modelVersionIDs: + type: list + entry_schema: + type: string + measurementGroup: + properties: + masurementTypes: + type: list + entry_schema: + type: measurementType + managedObjectDNsBasic: + type: list + entry_schema: + type: DN + schema: + subscription: + subscriptionName: + type: string + required: true + administrativeState: + type: string + required: true + filebasedGP: + type: integer + required: true + fileLocation: + type: string + required: true + nfFilter: + type: nfFilter + measurementGroups: + type: list + entry_schema: + type: measurementGroup + version: 0.0.0 + description: Should I be showing a dependency between PM Subscription Handler + and the PM Monitoring Policy + org.onap.PM_Policy: + type: org.onap.APP + properties: + application_name: PM Subscription Operational Policy + provider: Ericsson + application_version: 1.0.0 + artifact_id: + get_input: pm_subscription_operational_policy_id + artifact_config: NOT_DEFINED + requirements: + - receive_0: + capability: pm-subscription-event-publisher + node: org.onap.PM_Subscription_Handler + relationship: NOT_DEFINED + properties: + config_keys: + - topic_name: + get_input: pm_subscription_topic + version: 0.0.0 + - send_0: + capability: cds-rest-receive + node: org.onap.CDS + version: 0.0.0 + - receive_1: + capability: cds-rest-response + node: org.onap.CDS + version: 0.0.0 + - send_1: + capability: pm-subscription-event-receiver + node: org.onap.PM_Subscription_Handler + relationship: NOT_DEFINED + properties: + config_keys: + - topic_name: + get_input: pm_subscription_response_topic + version: 0.0.0 + capabilities: + pm-subscription-response-event-publisher: + properties: + type: org.onap.EventProducer + carrier_protocol_type: DMAAP_message_router + data_format: JSON + event_format: pm-subscription-event-response-format + event_format_version: 1.0.0 + occurrences: + - 0.0 + - UNBOUNDED + version: 0.0.0 + version: 0.0.0 + org.onap.PM_CDS_Blueprint: + type: org.onap.APP + properties: + application_name: PM Subscription CDS Blueprint + provider: Ericsson + application_version: 1.0.0 + artifact_id: + get_input: pm_subscription_cds_blueprint_id + capabilities: + cds-rest-receive: + properties: + type: org.onap.EventConsumer + protocol_type: REST + data_format: JSON + event_format: cds_action_format + event_format_version: 1.0.0 + responding_capability: cds-rest-response + occurrences: + - 0.0 + - UNBOUNDED + version: 0.0.0 + cds-rest-response: + properties: + type: org.onap.EventProducer + protocol_type: REST + data_format: JSON + event_format: cds_action_response_format + event_format_version: 1.0.0 + occurrences: + - 0.0 + version: 0.0.0 + version: 0.0.0 + org.onap.controlloop0: + type: org.onap.APP + properties: + application_name: Test Control Loop + provider: Ericsson + application_version: 1.0.0 + status: NOT_DEPLOYED + version: 0.0.0 +version: 0.0.0 diff --git a/tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantIntermediaryParameters.java b/tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantIntermediaryParameters.java new file mode 100644 index 000000000..8e3440e42 --- /dev/null +++ b/tosca-controlloop/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantIntermediaryParameters.java @@ -0,0 +1,58 @@ +/*- + * ============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.intermediary.parameters; + +import lombok.Getter; +import org.onap.policy.common.endpoints.parameters.TopicParameterGroup; +import org.onap.policy.common.parameters.ParameterGroupImpl; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * Class to hold all parameters needed for participant component. + */ +@NotNull +@NotBlank +@Getter +public class ParticipantIntermediaryParameters extends ParameterGroupImpl { + // The ID and description of this participant + private ToscaConceptIdentifier participantId; + private String description; + + // The participant type of this participant + private ToscaConceptIdentifier participantType; + + // The time interval for periodic reporting of status to the CLAMP control loop server + private long reportingTimeInterval; + + // DMaaP topics for communicating with the CLAMP control loop server + private TopicParameterGroup clampControlLoopTopics; + + /** + * Create the participant parameter group. + * + * @param instanceId instance id of the event. + */ + public ParticipantIntermediaryParameters(final String instanceId) { + super(instanceId); + } +} diff --git a/tosca-controlloop/runtime/pom.xml b/tosca-controlloop/runtime/pom.xml index 76af73d33..6f336b9e4 100644 --- a/tosca-controlloop/runtime/pom.xml +++ b/tosca-controlloop/runtime/pom.xml @@ -34,12 +34,12 @@ <name>${project.artifactId}</name> <dependencies> - <dependency> + <dependency> <groupId>org.onap.policy.clamp.controlloop</groupId> <artifactId>controlloop-common</artifactId> <version>${project.version}</version> </dependency> - <dependency> + <dependency> <groupId>org.onap.policy.clamp.controlloop</groupId> <artifactId>controlloop-models</artifactId> <version>${project.version}</version> diff --git a/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java new file mode 100644 index 000000000..41d85726e --- /dev/null +++ b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java @@ -0,0 +1,193 @@ +/*- + * ============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.runtime.commissioning; + +import java.io.Closeable; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; +import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider; +import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse; +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; +import org.onap.policy.models.provider.PolicyModelsProviderParameters; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter; + +/** + * This class provides the create, read and delete actions on Commissioning of Control Loop concepts in the database to + * the callers. + */ +public class CommissioningProvider implements Closeable { + public static final String CONTROL_LOOP_NODE_TYPE = "org.onap.policy.clamp.controlloop.ControlLoop"; + + private final PolicyModelsProvider modelsProvider; + private final ControlLoopProvider clProvider; + + private static final Object lockit = new Object(); + + /** + * Create a commissioning provider. + * + * @throws ControlLoopRuntimeException on errors creating the provider + */ + public CommissioningProvider(PolicyModelsProviderParameters databaseProviderParameters) + throws ControlLoopRuntimeException { + try { + modelsProvider = new PolicyModelsProviderFactory() + .createPolicyModelsProvider(databaseProviderParameters); + } catch (PfModelException e) { + throw new PfModelRuntimeException(e); + } + + try { + clProvider = new ControlLoopProvider(databaseProviderParameters); + } catch (PfModelException e) { + throw new PfModelRuntimeException(e); + } + } + + @Override + public void close() throws IOException { + try { + modelsProvider.close(); + } catch (PfModelException e) { + throw new IOException("error closing modelsProvider", e); + } + } + + /** + * Create control loops from a service template. + * + * @param serviceTemplate the service template + * @return the result of the commissioning operation + * @throws PfModelException on creation errors + */ + public CommissioningResponse createControlLoopDefinitions(ToscaServiceTemplate serviceTemplate) + throws PfModelException { + synchronized (lockit) { + modelsProvider.createServiceTemplate(serviceTemplate); + } + + CommissioningResponse response = new CommissioningResponse(); + // @formatter:off + response.setAffectedControlLoopDefinitions(serviceTemplate.getToscaTopologyTemplate().getNodeTemplates() + .values() + .stream() + .map(template -> template.getKey().asIdentifier()) + .collect(Collectors.toList())); + // @formatter:on + + return response; + } + + /** + * Delete the control loop definition with the given name and version. + * + * @param name the name of the control loop definition to delete + * @param version the version of the control loop to delete + * @return the result of the deletion + * @throws PfModelException on deletion errors + */ + public CommissioningResponse deleteControlLoopDefinition(String name, String version) throws PfModelException { + synchronized (lockit) { + modelsProvider.deleteServiceTemplate(name, version); + } + + CommissioningResponse response = new CommissioningResponse(); + response.setAffectedControlLoopDefinitions( + Collections.singletonList(new ToscaConceptIdentifier(name, version))); + + return response; + } + + /** + * Get control loop node templates. + * + * @param clName the name of the control loop, null for all + * @param clVersion the version of the control loop, null for all + * @return list of control loop node templates + * @throws PfModelException on errors getting control loop definitions + */ + public List<ToscaNodeTemplate> getControlLoopDefinitions(String clName, String clVersion) throws PfModelException { + + // @formatter:off + ToscaTypedEntityFilter<ToscaNodeTemplate> nodeTemplateFilter = ToscaTypedEntityFilter + .<ToscaNodeTemplate>builder() + .name(clName) + .version(clVersion) + .type(CONTROL_LOOP_NODE_TYPE) + .build(); + // @formatter:on + + return clProvider.getFilteredNodeTemplates(nodeTemplateFilter); + } + + /** + * Get the control loop elements from a control loop node template. + * + * @param controlLoopNodeTemplate the control loop node template + * @return a list of the control loop element node templates in a control loop node template + * @throws PfModelException on errors get control loop element node templates + */ + public List<ToscaNodeTemplate> getControlLoopElementDefinitions(ToscaNodeTemplate controlLoopNodeTemplate) + throws PfModelException { + if (!CONTROL_LOOP_NODE_TYPE.equals(controlLoopNodeTemplate.getType())) { + return Collections.emptyList(); + } + + if (MapUtils.isEmpty(controlLoopNodeTemplate.getProperties())) { + return Collections.emptyList(); + } + + @SuppressWarnings("unchecked") + List<Map<String, String>> controlLoopElements = + (List<Map<String, String>>) controlLoopNodeTemplate.getProperties().get("elements"); + + if (CollectionUtils.isEmpty(controlLoopElements)) { + return Collections.emptyList(); + } + + List<ToscaNodeTemplate> controlLoopElementList = new ArrayList<>(); + // @formatter:off + controlLoopElementList.addAll( + controlLoopElements + .stream() + .map(elementMap -> clProvider.getNodeTemplates(elementMap.get("name"), + elementMap.get("version"))) + .flatMap(List::stream) + .collect(Collectors.toList()) + ); + // @formatter:on + + return controlLoopElementList; + } +} diff --git a/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProviderTest.java b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProviderTest.java new file mode 100644 index 000000000..97599cd64 --- /dev/null +++ b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProviderTest.java @@ -0,0 +1,211 @@ +/*- + * ============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.runtime.commissioning; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; +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.coder.YamlJsonTranslator; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.provider.PolicyModelsProviderParameters; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; + +public class CommissioningProviderTest { + private static final String TOSCA_SERVICE_TEMPLATE_YAML = + "src/test/resources/servicetemplates/pmsh_multiple_cl_tosca.yaml"; + private static final String TEMPLATE_IS_NULL = ".*serviceTemplate is marked non-null but is null"; + private static final Coder CODER = new StandardCoder(); + private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); + private static int dbNum = 0; + private static final Object lockit = new Object(); + private PolicyModelsProviderParameters databaseProviderParameters; + + private static String getParameterGroupAsString() { + dbNum++; + return ResourceUtils.getResourceAsString("src/test/resources/parameters/TestParameters.json") + .replace("jdbc:h2:mem:testdb", "jdbc:h2:mem:commissioningdb" + dbNum); + } + + /** + * Sets up db provider parameters before each test. + * + * @throws CoderException . + */ + @Before + public void setupDbProviderParameters() throws CoderException { + synchronized (lockit) { + databaseProviderParameters = CODER.decode(getParameterGroupAsString(), ClRuntimeParameterGroup.class) + .getDatabaseProviderParameters(); + } + } + + /** + * Test the fetching of control loop definitions (ToscaServiceTemplates). + * + * @throws Exception . + */ + @Test + public void testGetControlLoopDefinitions() throws Exception { + List<ToscaNodeTemplate> listOfTemplates; + + try (CommissioningProvider provider = new CommissioningProvider(databaseProviderParameters)) { + ToscaServiceTemplate serviceTemplate = yamlTranslator + .fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML), + ToscaServiceTemplate.class); + + + listOfTemplates = provider.getControlLoopDefinitions(null, null); + assertThat(listOfTemplates).isEmpty(); + + provider.createControlLoopDefinitions(serviceTemplate); + listOfTemplates = provider.getControlLoopDefinitions(null, null); + assertThat(listOfTemplates).hasSize(2); + + //Test Filtering + listOfTemplates = provider.getControlLoopDefinitions("org.onap.domain.pmsh.PMSHControlLoopDefinition", + "1.2.3"); + assertThat(listOfTemplates).hasSize(1); + for (ToscaNodeTemplate template : listOfTemplates) { + //Other CL elements contain PMSD instead of PMSH in their name + assertFalse(template.getName().contains("PMSD")); + } + + //Test Wrong Name + listOfTemplates = provider.getControlLoopDefinitions("WrongControlLoopName", "0.0.0"); + assertThat(listOfTemplates).isEmpty(); + } + } + + /** + * Test the creation of control loop definitions (ToscaServiceTemplates). + * + * @throws Exception . + */ + @Test + public void testCreateControlLoopDefinitions() throws Exception { + List<ToscaNodeTemplate> listOfTemplates; + + try (CommissioningProvider provider = new CommissioningProvider(databaseProviderParameters)) { + //Test Service template is null + assertThatThrownBy(() -> provider.createControlLoopDefinitions(null)).hasMessageMatching(TEMPLATE_IS_NULL); + listOfTemplates = provider.getControlLoopDefinitions(null, null); + assertThat(listOfTemplates).isEmpty(); + + ToscaServiceTemplate serviceTemplate = yamlTranslator + .fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML), + ToscaServiceTemplate.class); + + // Response should return the number of node templates present in the service template + List<ToscaConceptIdentifier> affectedDefinitions = + provider.createControlLoopDefinitions(serviceTemplate).getAffectedControlLoopDefinitions(); + assertThat(affectedDefinitions).hasSize(13); + listOfTemplates = provider.getControlLoopDefinitions(null, null); + assertThat(listOfTemplates).hasSize(2); + } + } + + /** + * Test the deletion of control loop definitions (ToscaServiceTemplate). + * + * @throws Exception . + */ + @Test + public void testDeleteControlLoopDefinitions() throws Exception { + List<ToscaNodeTemplate> listOfTemplates; + + try (CommissioningProvider provider = new CommissioningProvider(databaseProviderParameters)) { + ToscaServiceTemplate serviceTemplate = yamlTranslator + .fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML), + ToscaServiceTemplate.class); + + provider.createControlLoopDefinitions(serviceTemplate); + listOfTemplates = provider.getControlLoopDefinitions(null, null); + assertThat(listOfTemplates).hasSize(2); + + provider.deleteControlLoopDefinition(serviceTemplate.getName(), serviceTemplate.getVersion()); + listOfTemplates = provider.getControlLoopDefinitions(null, null); + assertThat(listOfTemplates).isEmpty(); + } + } + + /** + * Test the fetching of control loop element definitions. + * + * @throws Exception . + */ + @Test + public void testGetControlLoopElementDefinitions() throws Exception { + try (CommissioningProvider provider = new CommissioningProvider(databaseProviderParameters)) { + ToscaServiceTemplate serviceTemplate = yamlTranslator + .fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML), + ToscaServiceTemplate.class); + + provider.createControlLoopDefinitions(serviceTemplate); + List<ToscaNodeTemplate> controlLoopDefinitionList = provider.getControlLoopDefinitions( + "org.onap.domain.pmsh.PMSHControlLoopDefinition", "1.2.3"); + + List<ToscaNodeTemplate> controlLoopElementNodeTemplates = + provider.getControlLoopElementDefinitions(controlLoopDefinitionList.get(0)); + + // 4 PMSH control loop elements definitions. + assertThat(controlLoopElementNodeTemplates).hasSize(4); + + List<ToscaNodeType> derivedTypes = getDerivedNodeTypes(serviceTemplate); + for (ToscaNodeTemplate template : controlLoopElementNodeTemplates) { + assertTrue(checkNodeType(template, derivedTypes)); + } + } + } + + private boolean checkNodeType(ToscaNodeTemplate template, List<ToscaNodeType> derivedNodeTypes) { + String controlLoopElementType = "org.onap.policy.clamp.controlloop.ControlLoopElement"; + for (ToscaNodeType derivedType : derivedNodeTypes) { + if (template.getType().equals(derivedType.getName()) || template.getType().equals(controlLoopElementType)) { + return true; + } + } + return false; + } + + private List<ToscaNodeType> getDerivedNodeTypes(ToscaServiceTemplate serviceTemplate) { + String type = "org.onap.policy.clamp.controlloop.ControlLoopElement"; + List<ToscaNodeType> nodeTypes = new ArrayList<>(); + for (ToscaNodeType nodeType : serviceTemplate.getNodeTypes().values()) { + if (nodeType.getDerivedFrom().equals(type)) { + nodeTypes.add(nodeType); + } + } + return nodeTypes; + } +} diff --git a/tosca-controlloop/runtime/src/test/resources/META-INF/persistence.xml b/tosca-controlloop/runtime/src/test/resources/META-INF/persistence.xml index ff532fe97..610bfe97e 100644 --- a/tosca-controlloop/runtime/src/test/resources/META-INF/persistence.xml +++ b/tosca-controlloop/runtime/src/test/resources/META-INF/persistence.xml @@ -48,7 +48,7 @@ <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaControlLoopElement</class> <properties> - <property name="eclipselink.ddl-generation" value="create-or-extend-tables" /> + <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> <property name="eclipselink.ddl-generation.output-mode" value="database" /> <property name="eclipselink.logging.level" value="INFO" /> </properties> @@ -56,4 +56,3 @@ </persistence-unit> </persistence> - diff --git a/tosca-controlloop/runtime/src/test/resources/servicetemplates/pmsh_multiple_cl_tosca.yaml b/tosca-controlloop/runtime/src/test/resources/servicetemplates/pmsh_multiple_cl_tosca.yaml new file mode 100644 index 000000000..099e2e945 --- /dev/null +++ b/tosca-controlloop/runtime/src/test/resources/servicetemplates/pmsh_multiple_cl_tosca.yaml @@ -0,0 +1,221 @@ +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.DCAEMicroserviceControlLoopElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement + properties: + dcae_blueprint_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true + org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement + properties: + policy_type_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true + org.onap.policy.clamp.controlloop.CDSControlLoopElement: + version: 1.0.1 + derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement + properties: + cds_blueprint_id: + type: onap.datatypes.ToscaConceptIdentifier + requred: true +topology_template: + node_templates: + org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant: + version: 2.3.4 + type: org.onap.policy.clamp.controlloop.Participant + type_version: 1.0.1 + description: Participant for DCAE microservices + properties: + provider: ONAP + org.onap.policy.controlloop.PolicyControlLoopParticipant: + version: 2.2.1 + type: org.onap.policy.clamp.controlloop.Participant + type_version: 1.0.1 + description: Participant for DCAE microservices + properties: + provider: ONAP + org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant: + version: 2.2.1 + type: org.onap.policy.clamp.controlloop.Participant + type_version: 1.0.1 + description: Participant for DCAE microservices + properties: + provider: ONAP + org.onap.domain.pmsh.PMSH_DCAEMicroservice: + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement + type_version: 1.0.0 + description: Control loop element for the DCAE microservice for Performance Management Subscription Handling + properties: + provider: Ericsson + participant_id: + name: org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant + version: 2.3.4 + dcae_blueprint_id: + name: org.onap.dcae.blueprints.PMSHBlueprint + version: 1.0.0 + org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement: + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement + type_version: 1.0.0 + description: Control loop element for the monitoring policy for Performance Management Subscription Handling + properties: + provider: Ericsson + participant_id: + name: org.onap.policy.controlloop.PolicyControlLoopParticipant + version: 2.2.1 + policy_type_id: + name: onap.policies.monitoring.pm-subscription-handler + version: 1.0.0 + org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement: + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement + type_version: 1.0.0 + description: Control loop element for the operational policy for Performance Management Subscription Handling + properties: + provider: Ericsson + participant_id: + name: org.onap.policy.controlloop.PolicyControlLoopParticipant + version: 2.2.1 + policy_type_id: + name: onap.policies.operational.pm-subscription-handler + version: 1.0.0 + org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement: + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.ControlLoopElement + type_version: 1.0.0 + description: Control loop element for CDS for Performance Management Subscription Handling + properties: + provider: Ericsson + participant_Id: + name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant + version: 3.2.1 + cds_blueprint_id: + name: org.onap.ccsdk.cds.PMSHCdsBlueprint + version: 1.0.0 + org.onap.domain.pmsh.PMSHControlLoopDefinition: + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.ControlLoop + type_version: 1.0.0 + description: Control loop for Performance Management Subscription Handling + properties: + provider: Ericsson + elements: + - name: org.onap.domain.pmsh.PMSH_DCAEMicroservice + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement + version: 1.2.3 + org.onap.domain.pmsh.PMSD_DCAEMicroservice: + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement + type_version: 1.0.0 + description: Control loop element for the DCAE microservice for Performance Management Subscription Handling + properties: + provider: Ericsson + participant_id: + name: org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant + version: 2.3.4 + dcae_blueprint_id: + name: org.onap.dcae.blueprints.PMSDBlueprint + version: 1.0.0 + org.onap.domain.pmsh.PMSD_MonitoringPolicyControlLoopElement: + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement + type_version: 1.0.0 + description: Control loop element for the monitoring policy for Performance Management Subscription Handling + properties: + provider: Ericsson + participant_id: + name: org.onap.policy.controlloop.PolicyControlLoopParticipant + version: 2.2.1 + policy_type_id: + name: onap.policies.monitoring.pm-subscription-handler + version: 1.0.0 + org.onap.domain.pmsh.PMSD_OperationalPolicyControlLoopElement: + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement + type_version: 1.0.0 + description: Control loop element for the operational policy for Performance Management Subscription Handling + properties: + provider: Ericsson + participant_id: + name: org.onap.policy.controlloop.PolicyControlLoopParticipant + version: 2.2.1 + policy_type_id: + name: onap.policies.operational.pm-subscription-handler + version: 1.0.0 + org.onap.domain.pmsh.PMSD_CDS_ControlLoopElement: + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.ControlLoopElement + type_version: 1.0.0 + description: Control loop element for CDS for Performance Management Subscription Handling + properties: + provider: Ericsson + participant_Id: + name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant + version: 3.2.1 + cds_blueprint_id: + name: org.onap.ccsdk.cds.PMSDCdsBlueprint + version: 1.0.0 + org.onap.domain.pmsh.PMSDControlLoopDefinition: + version: 1.2.3 + type: org.onap.policy.clamp.controlloop.ControlLoop + type_version: 1.0.0 + description: Control loop for Performance Management Subscription Handling + properties: + provider: Ericsson + elements: + - name: org.onap.domain.pmsh.PMSD_DCAEMicroservice + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSD_MonitoringPolicyControlLoopElement + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSD_OperationalPolicyControlLoopElement + version: 1.2.3 + - name: org.onap.domain.pmsh.PMSD_CDS_ControlLoopElement + version: 1.2.3 |