diff options
author | liamfallon <liam.fallon@est.tech> | 2019-04-17 13:58:26 +0000 |
---|---|---|
committer | liamfallon <liam.fallon@est.tech> | 2019-04-17 13:58:26 +0000 |
commit | 900920306a0be309f389880325558bb96ff76356 (patch) | |
tree | e0570422d911b55cd5a6c61e0a4f16f8869b0586 | |
parent | 70be3b7d76f6bd8d2c834496c688d349933e7130 (diff) |
Add DMaaP simulator for CSIT testing
A rudimentary DMaaP simulator that simply holds requests and responds
to all readers with whatever message comes in on a topic. The simulator
is placed in policy models for now but should be submitted to DMaaP.
The simulator is now working but is still extremely rough.
Issue-ID: POLICY-1643
Change-Id: I28645a73cf198fe825c897243b30cd34dc29f20d
Signed-off-by: liamfallon <liam.fallon@est.tech>
26 files changed, 1657 insertions, 0 deletions
diff --git a/models-sim/models-sim-dmaap/pom.xml b/models-sim/models-sim-dmaap/pom.xml new file mode 100644 index 000000000..b21926b5c --- /dev/null +++ b/models-sim/models-sim-dmaap/pom.xml @@ -0,0 +1,81 @@ +<!-- + ============LICENSE_START======================================================= + Copyright (C) 2019 Nordix Foundation. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 + ============LICENSE_END========================================================= +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onap.policy.models.sim</groupId> + <artifactId>policy-models-sim</artifactId> + <version>2.0.0-SNAPSHOT</version> + </parent> + + <artifactId>policy-models-sim-dmaap</artifactId> + + <name>${project.artifactId}</name> + <description>A module that implements a very simple DMaaP simulator.</description> + + <dependencies> + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + </dependency> + <dependency> + <groupId>org.onap.policy.common</groupId> + <artifactId>common-parameters</artifactId> + <version>${policy.common.version}</version> + </dependency> + <dependency> + <groupId>org.onap.policy.common</groupId> + <artifactId>utils</artifactId> + <version>${policy.common.version}</version> + </dependency> + <dependency> + <groupId>org.onap.policy.common</groupId> + <artifactId>policy-endpoints</artifactId> + <version>${policy.common.version}</version> + </dependency> + <dependency> + <groupId>org.onap.policy.common</groupId> + <artifactId>gson</artifactId> + <version>${policy.common.version}</version> + </dependency> + </dependencies> + + <build> + <resources> + <!-- Output the version of the pap service --> + <resource> + <directory>src/main/resources</directory> + <filtering>true</filtering> + <includes> + <include>**/version.txt</include> + </includes> + </resource> + <resource> + <directory>src/main/resources</directory> + <filtering>false</filtering> + <excludes> + <exclude>**/version.txt</exclude> + </excludes> + </resource> + </resources> + </build> +</project> diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/DmaapSimConstants.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/DmaapSimConstants.java new file mode 100644 index 000000000..1682eb991 --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/DmaapSimConstants.java @@ -0,0 +1,32 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap; + +/** + * Names of various items contained in the Registry. + */ +public class DmaapSimConstants { + + // Registry keys + public static final String REG_DMAAP_SIM_ACTIVATOR = "object:activator/dmaap-sim"; + + private DmaapSimConstants() { + super(); + } +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/DmaapSimException.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/DmaapSimException.java new file mode 100644 index 000000000..aaf8980f8 --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/DmaapSimException.java @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap; + +/** + * This exception will be called if an error occurs in the DMaaP simulator. + */ +public class DmaapSimException extends Exception { + private static final long serialVersionUID = -8507246953751956974L; + + /** + * Instantiates a new exception with a message. + * + * @param message the message + */ + public DmaapSimException(final String message) { + super(message); + } + + /** + * Instantiates a new exception with a caused by exception. + * + * @param exp the exception that caused this exception to be thrown + */ + public DmaapSimException(final Exception exp) { + super(exp); + } + + /** + * Instantiates a new exception with a message and a caused by exception. + * + * @param message the message + * @param exp the exception that caused this exception to be thrown + */ + public DmaapSimException(final String message, final Exception exp) { + super(message, exp); + } +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/DmaapSimRuntimeException.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/DmaapSimRuntimeException.java new file mode 100644 index 000000000..fe8b7e21b --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/DmaapSimRuntimeException.java @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap; + +/** + * This runtime exception will be called if a runtime error occurs when using the DMaaP simulator. + */ +public class DmaapSimRuntimeException extends RuntimeException { + private static final long serialVersionUID = -8507246953751956974L; + + /** + * Instantiates a new policy pap runtime exception with a message. + * + * @param message the message + */ + public DmaapSimRuntimeException(final String message) { + super(message); + } + + /** + * Instantiates a new runtime exception with a caused by exception. + * + * @param exp the exception that caused this exception to be thrown + */ + public DmaapSimRuntimeException(final Exception exp) { + super(exp); + } + + /** + * Instantiates a new runtime exception with a message and a caused by exception. + * + * @param message the message + * @param exp the exception that caused this exception to be thrown + */ + public DmaapSimRuntimeException(final String message, final Exception exp) { + super(message, exp); + } +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/parameters/DmaapSimParameterGroup.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/parameters/DmaapSimParameterGroup.java new file mode 100644 index 000000000..caae287b8 --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/parameters/DmaapSimParameterGroup.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap.parameters; + +import lombok.Getter; + +import org.onap.policy.common.parameters.ParameterGroupImpl; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; + +/** + * Class to hold all parameters needed for the DMaaP simulator component. + */ +@NotNull +@NotBlank +@Getter +public class DmaapSimParameterGroup extends ParameterGroupImpl { + private RestServerParameters restServerParameters; + + /** + * Create the DMaaP simulator parameter group. + * + * @param name the parameter group name + */ + public DmaapSimParameterGroup(final String name) { + super(name); + } +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/parameters/DmaapSimParameterHandler.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/parameters/DmaapSimParameterHandler.java new file mode 100644 index 000000000..8eb76ec00 --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/parameters/DmaapSimParameterHandler.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap.parameters; + +import java.io.File; + +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; +import org.onap.policy.models.sim.dmaap.DmaapSimException; +import org.onap.policy.models.sim.dmaap.startstop.DmaapSimCommandLineArguments; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class handles reading, parsing and validating of DMaaP simulator parameters from JSON files. + */ +public class DmaapSimParameterHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(DmaapSimParameterHandler.class); + + private static final Coder CODER = new StandardCoder(); + + /** + * Read the parameters from the parameter file. + * + * @param arguments the arguments passed to DMaaP simulator + * @return the parameters read from the configuration file + * @throws DmaapSimException on parameter exceptions + */ + public DmaapSimParameterGroup getParameters(final DmaapSimCommandLineArguments arguments) throws DmaapSimException { + DmaapSimParameterGroup dmaapSimParameterGroup = null; + + // Read the parameters + try { + // Read the parameters from JSON + File file = new File(arguments.getFullConfigurationFilePath()); + dmaapSimParameterGroup = CODER.decode(file, DmaapSimParameterGroup.class); + } catch (final CoderException e) { + final String errorMessage = "error reading parameters from \"" + arguments.getConfigurationFilePath() + + "\"\n" + "(" + e.getClass().getSimpleName() + "):" + e.getMessage(); + LOGGER.error(errorMessage, e); + throw new DmaapSimException(errorMessage, e); + } + + // The JSON processing returns null if there is an empty file + if (dmaapSimParameterGroup == null) { + final String errorMessage = "no parameters found in \"" + arguments.getConfigurationFilePath() + "\""; + LOGGER.error(errorMessage); + throw new DmaapSimException(errorMessage); + } + + // validate the parameters + final GroupValidationResult validationResult = dmaapSimParameterGroup.validate(); + if (!validationResult.isValid()) { + String returnMessage = + "validation error(s) on parameters from \"" + arguments.getConfigurationFilePath() + "\"\n"; + returnMessage += validationResult.getResult(); + + LOGGER.error(returnMessage); + throw new DmaapSimException(returnMessage); + } + + return dmaapSimParameterGroup; + } +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/parameters/RestServerParameters.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/parameters/RestServerParameters.java new file mode 100644 index 000000000..c7269f66d --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/parameters/RestServerParameters.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap.parameters; + +import lombok.Getter; +import org.onap.policy.common.parameters.ParameterGroupImpl; +import org.onap.policy.common.parameters.annotations.Min; +import org.onap.policy.common.parameters.annotations.NotBlank; +import org.onap.policy.common.parameters.annotations.NotNull; + +/** + * Class to hold all parameters needed for DMaaP simulator rest server. + */ +@NotNull +@NotBlank +@Getter +public class RestServerParameters extends ParameterGroupImpl { + private String host; + + @Min(value = 1) + private int port; + + public RestServerParameters() { + super("RestServerParameters"); + } +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/provider/DmaapSimProvider.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/provider/DmaapSimProvider.java new file mode 100644 index 000000000..42a653d6f --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/provider/DmaapSimProvider.java @@ -0,0 +1,186 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap.provider; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +import javax.ws.rs.core.Response; + +import org.apache.commons.lang3.tuple.MutablePair; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.sim.dmaap.DmaapSimRuntimeException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provider to simulate DMaaP. + * + * @author Liam Fallon (liam.fallon@est.tech) + */ +public class DmaapSimProvider { + private static final Logger LOGGER = LoggerFactory.getLogger(DmaapSimProvider.class); + + // Time for a get to wait before checking of a message has come + private static final long DMAAP_SIM_WAIT_TIME = 50; + + // recurring constants + private static final String WITH_TIMEOUT = " with timeout "; + + // The map of topic messages + private static final Map<String, SortedMap<Integer, Object>> topicMessageMap = new LinkedHashMap<>(); + + // The map of topic messages + private static final Map<String, Map<String, MutablePair<Integer, String>>> consumerGroupsMap = + new LinkedHashMap<>(); + + /** + * Process a DMaaP message. + * + * @param topicName The topic name + * @param dmaapMessage the message to process + * @return a response to the message + */ + public Response processDmaapMessagePut(final String topicName, final Object dmaapMessage) { + LOGGER.debug("Topic:" + topicName + ", Received DMaaP message: " + dmaapMessage); + + synchronized (topicMessageMap) { + SortedMap<Integer, Object> messageMap = topicMessageMap.get(topicName); + if (messageMap == null) { + messageMap = new TreeMap<>(); + topicMessageMap.put(topicName, messageMap); + LOGGER.debug("Topic:" + topicName + ", created topic message map"); + } + + int nextKey = (messageMap.isEmpty() ? 0 : messageMap.lastKey() + 1); + + messageMap.put(nextKey, dmaapMessage); + LOGGER.debug("Topic:" + topicName + ", cached DMaaP message " + nextKey + ": " + dmaapMessage); + } + + return Response.status(Response.Status.OK).entity("{\n \"serverTimeMs\": 0,\n \"count\": 1\n}").build(); + } + + /** + * Wait for and return a DMaaP message. + * + * @param topicName The topic to wait on + * @param consumerGroup the consumer group that is waiting + * @param consumerId the consumer ID that is waiting + * @param timeout the length of time to wait for + * @return the DMaaP message or + */ + public Response processDmaapMessageGet(final String topicName, final String consumerGroup, final String consumerId, + final int timeout) { + + LOGGER.debug("Topic:" + topicName + ", Request for DMaaP message: " + consumerGroup + ":" + consumerId + + WITH_TIMEOUT + timeout); + + MutablePair<Integer, String> consumerGroupPair = null; + + synchronized (consumerGroupsMap) { + Map<String, MutablePair<Integer, String>> consumerGroupMap = consumerGroupsMap.get(topicName); + if (consumerGroupMap == null) { + consumerGroupMap = new LinkedHashMap<>(); + consumerGroupsMap.put(topicName, consumerGroupMap); + LOGGER.trace("Topic:" + topicName + ", Created consumer map entry for consumer group " + consumerGroup); + } + + consumerGroupPair = consumerGroupMap.get(consumerGroup); + if (consumerGroupPair == null) { + consumerGroupPair = new MutablePair<>(-1, consumerId); + consumerGroupMap.put(consumerGroup, consumerGroupPair); + LOGGER.trace("Topic:" + topicName + ", Created consumer group entry for consumer group " + consumerGroup + + ":" + consumerId); + } + } + + long timeOfTimeout = System.currentTimeMillis() + timeout; + + do { + + Object waitingMessages = getWaitingMessages(topicName, consumerGroupPair); + if (waitingMessages != null) { + LOGGER.debug("Topic:" + topicName + ", Request for DMaaP message: " + consumerGroup + ":" + consumerId + + WITH_TIMEOUT + timeout + ", returning messages " + waitingMessages); + return Response.status(Response.Status.OK).entity(waitingMessages).build(); + } + + try { + Thread.sleep(DMAAP_SIM_WAIT_TIME); + } catch (InterruptedException ie) { + String errorMessage = "Interrupt on wait on simulation of DMaaP topic " + topicName + " for request ID " + + consumerGroup + ":" + consumerId + WITH_TIMEOUT + timeout; + LOGGER.warn(errorMessage, ie); + throw new DmaapSimRuntimeException(errorMessage, ie); + } + } + while (timeOfTimeout > System.currentTimeMillis()); + + LOGGER.trace("Topic:" + topicName + ", timed out waiting for messages : " + consumerGroup + ":" + consumerId + + WITH_TIMEOUT + timeout); + return Response.status(Response.Status.REQUEST_TIMEOUT).build(); + } + + /** + * Return any messages on this topic with a message number greater than the supplied message number. + * + * @param topicName the topic name to check + * @param consumerGroupPair the pair with the information on the last message retrieved + * @return the messages or null if there are none + */ + private Object getWaitingMessages(final String topicName, final MutablePair<Integer, String> consumerGroupPair) { + String foundMessageList = "["; + + synchronized (topicMessageMap) { + SortedMap<Integer, Object> messageMap = topicMessageMap.get(topicName); + if (messageMap == null || messageMap.lastKey() <= consumerGroupPair.getLeft()) { + return null; + } + + boolean first = true; + for (Object dmaapMessage : messageMap.tailMap(consumerGroupPair.getLeft() + 1).values()) { + if (first) { + first = false; + } else { + foundMessageList += ","; + } + try { + foundMessageList += new StandardCoder().encode(dmaapMessage); + } catch (CoderException e) { + e.printStackTrace(); + } + } + foundMessageList += ']'; + + LOGGER.debug("Topic:" + topicName + ", returning DMaaP messages from " + consumerGroupPair.getLeft() + + " to " + messageMap.lastKey()); + synchronized (consumerGroupsMap) { + consumerGroupPair.setLeft(messageMap.lastKey()); + } + } + + return (foundMessageList.length() < 3 ? null : foundMessageList); + } +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/BaseRestControllerV1.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/BaseRestControllerV1.java new file mode 100644 index 000000000..bcde4b522 --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/BaseRestControllerV1.java @@ -0,0 +1,116 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap.rest; + +import io.swagger.annotations.Api; +import io.swagger.annotations.BasicAuthDefinition; +import io.swagger.annotations.Info; +import io.swagger.annotations.SecurityDefinition; +import io.swagger.annotations.SwaggerDefinition; +import io.swagger.annotations.Tag; +import java.net.HttpURLConnection; +import java.util.UUID; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response.ResponseBuilder; + +/** + * Version v1 common superclass to provide DMaaP endpoints for the DMaaP simulator component. + */ +// @formatter:off +@Api(value = "DMaaP Simulator API") +@Produces("application/json") +@Consumes({"application/cambria", "application/json"}) +@SwaggerDefinition( + info = @Info(description = + "Simulator for DMaaP, follows API as described at " + + "\"https://onap.readthedocs.io/en/amsterdam/submodules/dmaap/messagerouter/messageservice.git/" + + "docs/message-router/message-router.html", version = "v1.0", + title = "Policy Administration"), + consumes = {MediaType.APPLICATION_JSON}, + produces = {MediaType.APPLICATION_JSON}, + schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS}, + tags = {@Tag(name = "dmaap-simulator", description = "DMaaP simulation")}, + securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")})) +// @formatter:on +public class BaseRestControllerV1 { + public static final String EXTENSION_NAME = "interface info"; + + public static final String API_VERSION_NAME = "api-version"; + public static final String API_VERSION = "1.0.0"; + + public static final String LAST_MOD_NAME = "last-mod-release"; + public static final String LAST_MOD_RELEASE = "Dublin"; + + public static final String VERSION_MINOR_NAME = "X-MinorVersion"; + public static final String VERSION_MINOR_DESCRIPTION = + "Used to request or communicate a MINOR version back from the client" + + " to the server, and from the server back to the client"; + + public static final String VERSION_PATCH_NAME = "X-PatchVersion"; + public static final String VERSION_PATCH_DESCRIPTION = "Used only to communicate a PATCH version in a response for" + + " troubleshooting purposes only, and will not be provided by" + " the client on request"; + + public static final String VERSION_LATEST_NAME = "X-LatestVersion"; + public static final String VERSION_LATEST_DESCRIPTION = "Used only to communicate an API's latest version"; + + public static final String REQUEST_ID_NAME = "X-ONAP-RequestID"; + public static final String REQUEST_ID_HDR_DESCRIPTION = "Used to track REST transactions for logging purpose"; + public static final String REQUEST_ID_PARAM_DESCRIPTION = "RequestID for http transaction"; + + public static final String AUTHORIZATION_TYPE = "basicAuth"; + + public static final int AUTHENTICATION_ERROR_CODE = HttpURLConnection.HTTP_UNAUTHORIZED; + public static final int AUTHORIZATION_ERROR_CODE = HttpURLConnection.HTTP_FORBIDDEN; + public static final int SERVER_ERROR_CODE = HttpURLConnection.HTTP_INTERNAL_ERROR; + + public static final String AUTHENTICATION_ERROR_MESSAGE = "Authentication Error"; + public static final String AUTHORIZATION_ERROR_MESSAGE = "Authorization Error"; + public static final String SERVER_ERROR_MESSAGE = "Internal Server Error"; + + /** + * Adds version headers to the response. + * + * @param respBuilder response builder + * @return the response builder, with version headers + */ + public ResponseBuilder addVersionControlHeaders(ResponseBuilder respBuilder) { + return respBuilder.header(VERSION_MINOR_NAME, "0").header(VERSION_PATCH_NAME, "0").header(VERSION_LATEST_NAME, + API_VERSION); + } + + /** + * Adds logging headers to the response. + * + * @param respBuilder response builder + * @return the response builder, with version logging + */ + public ResponseBuilder addLoggingHeaders(ResponseBuilder respBuilder, UUID requestId) { + if (requestId == null) { + // Generate a random uuid if client does not embed requestId in rest request + return respBuilder.header(REQUEST_ID_NAME, UUID.randomUUID()); + } + + return respBuilder.header(REQUEST_ID_NAME, requestId); + } +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/CambriaMessageBodyHandler.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/CambriaMessageBodyHandler.java new file mode 100644 index 000000000..e269ac00b --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/CambriaMessageBodyHandler.java @@ -0,0 +1,66 @@ +/* + * ============LICENSE_START======================================================= ONAP + * ================================================================================ Copyright (C) 2019 AT&T Intellectual + * Property. All rights reserved. ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap.rest; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.Provider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provider that serializes and de-serializes JSON via gson. + */ +@Provider +@Consumes(CambriaMessageBodyHandler.MEDIA_TYPE_APPLICATION_CAMBRIA) +@Produces(CambriaMessageBodyHandler.MEDIA_TYPE_APPLICATION_CAMBRIA) +public class CambriaMessageBodyHandler implements MessageBodyReader<Object> { + // Media type for Cambria + public static final String MEDIA_TYPE_APPLICATION_CAMBRIA = "application/cambria"; + + public static final Logger logger = LoggerFactory.getLogger(CambriaMessageBodyHandler.class); + + @Override + public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { + return MEDIA_TYPE_APPLICATION_CAMBRIA.equals(mediaType.toString()); + } + + @Override + public String readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, + MultivaluedMap<String, String> httpHeaders, InputStream entityStream) + throws IOException { + + String cambriaString = ""; + try (BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(entityStream))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + cambriaString += line; + } + + return cambriaString.substring(cambriaString.indexOf('{'), cambriaString.length()); + } + } +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/DmaapSimRestControllerV1.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/DmaapSimRestControllerV1.java new file mode 100644 index 000000000..e3fdd4884 --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/DmaapSimRestControllerV1.java @@ -0,0 +1,116 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap.rest; + +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import io.swagger.annotations.Authorization; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; + +import org.onap.policy.models.sim.dmaap.provider.DmaapSimProvider; + +/** + * Class to provide REST endpoints for DMaaP simulator component statistics. + */ +@Path("/events") +public class DmaapSimRestControllerV1 extends BaseRestControllerV1 { + + /** + * Get a DMaaP message. + * + * @param topicName topic to get message from + * @param consumerGroup consumer group that is getting the message + * @param consumerId consumer ID that is getting the message + * @param timeout timeout for the message + * @return the message + */ + @GET + @Path("{topicName}/{consumerGroup}/{consumerId}") + // @formatter:off + @ApiOperation( + value = "Get a DMaaP event on a topic", + notes = "Returns an event on a DMaaP topic", + response = Object.class, + authorizations = + @Authorization(value = AUTHORIZATION_TYPE) + ) + @ApiResponses( + value = { + @ApiResponse( + code = AUTHENTICATION_ERROR_CODE, + message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse( + code = AUTHORIZATION_ERROR_CODE, + message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse( + code = SERVER_ERROR_CODE, + message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public Response getDmaaapMessage(@PathParam("topicName") final String topicName, + @PathParam("consumerGroup") final String consumerGroup, @PathParam("consumerId") final String consumerId, + @QueryParam("timeout") final int timeout) { + + return new DmaapSimProvider().processDmaapMessageGet(topicName, consumerGroup, consumerId, timeout); + } + + /** + * Post a DMaaP message. + * + * @param topicName topic to get message from415 + * @return the response to the post + */ + @POST + @Path("{topicName}") + // @formatter:off + @ApiOperation( + value = "Post a DMaaP event on a topic", + notes = "Returns an event on a DMaaP topic", + response = Response.class, + authorizations = + @Authorization(value = AUTHORIZATION_TYPE) + ) + @ApiResponses( + value = { + @ApiResponse( + code = AUTHENTICATION_ERROR_CODE, + message = AUTHENTICATION_ERROR_MESSAGE), + @ApiResponse( + code = AUTHORIZATION_ERROR_CODE, + message = AUTHORIZATION_ERROR_MESSAGE), + @ApiResponse( + code = SERVER_ERROR_CODE, + message = SERVER_ERROR_MESSAGE) + } + ) + // @formatter:on + public Response postDmaaapMessage(@PathParam("topicName") final String topicName, final Object dmaapMessage) { + + return new DmaapSimProvider().processDmaapMessagePut(topicName, dmaapMessage); + } +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/DmaapSimRestServer.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/DmaapSimRestServer.java new file mode 100644 index 000000000..6853cc9dc --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/DmaapSimRestServer.java @@ -0,0 +1,138 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap.rest; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.onap.policy.common.capabilities.Startable; +import org.onap.policy.common.endpoints.http.server.HttpServletServer; +import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; +import org.onap.policy.models.sim.dmaap.parameters.RestServerParameters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class to manage life cycle of DMaaP Simulator rest server. + */ +public class DmaapSimRestServer implements Startable { + + private static final Logger LOGGER = LoggerFactory.getLogger(DmaapSimRestServer.class); + + private List<HttpServletServer> servers = new ArrayList<>(); + + private RestServerParameters restServerParameters; + + /** + * Constructor for instantiating DmaapSimRestServer. + * + * @param restServerParameters the rest server parameters + */ + public DmaapSimRestServer(final RestServerParameters restServerParameters) { + this.restServerParameters = restServerParameters; + } + + /** + * {@inheritDoc}. + */ + @Override + public boolean start() { + try { + servers = HttpServletServer.factory.build(getServerProperties()); + for (final HttpServletServer server : servers) { + server.start(); + } + } catch (final Exception exp) { + LOGGER.error("Failed to start DMaaP simulator http server", exp); + return false; + } + return true; + } + + /** + * Creates the server properties object using restServerParameters. + * + * @return the properties object + */ + private Properties getServerProperties() { + final Properties props = new Properties(); + props.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES, restServerParameters.getName()); + + final String svcpfx = + PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + restServerParameters.getName(); + + props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX, restServerParameters.getHost()); + props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX, + Integer.toString(restServerParameters.getPort())); + props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_REST_CLASSES_SUFFIX, + String.join(",", DmaapSimRestControllerV1.class.getName())); + props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, "false"); + props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SWAGGER_SUFFIX, "true"); + props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER, + CambriaMessageBodyHandler.class.getName() + "," + JsonMessageBodyHandler.class.getName()); + return props; + } + + /** + * {@inheritDoc}. + */ + @Override + public boolean stop() { + for (final HttpServletServer server : servers) { + try { + server.stop(); + } catch (final Exception exp) { + LOGGER.error("Failed to stop DMaaP simulator http server", exp); + } + } + return true; + } + + /** + * {@inheritDoc}. + */ + @Override + public void shutdown() { + stop(); + } + + /** + * {@inheritDoc}. + */ + @Override + public boolean isAlive() { + return !servers.isEmpty(); + } + + /** + * {@inheritDoc}. + */ + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("DmaapSimRestServer [servers="); + builder.append(servers); + builder.append("]"); + return builder.toString(); + } + +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/JsonMessageBodyHandler.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/JsonMessageBodyHandler.java new file mode 100644 index 000000000..a3eebda00 --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/rest/JsonMessageBodyHandler.java @@ -0,0 +1,63 @@ +/* + * ============LICENSE_START======================================================= ONAP + * ================================================================================ Copyright (C) 2019 AT&T Intellectual + * Property. All rights reserved. ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap.rest; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import javax.ws.rs.Consumes; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.Provider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provider that serializes and de-serializes JSON via gson. + */ +@Provider +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public class JsonMessageBodyHandler implements MessageBodyReader<Object> { + public static final Logger logger = LoggerFactory.getLogger(JsonMessageBodyHandler.class); + + @Override + public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { + return MediaType.APPLICATION_JSON.equals(mediaType.toString()); + } + + @Override + public String readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType, + MultivaluedMap<String, String> httpHeaders, InputStream entityStream) + throws IOException { + + String jsonString = ""; + try (BufferedReader bufferedReader = new BufferedReader( + new InputStreamReader(entityStream))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + jsonString += line; + } + + return jsonString; + } + } +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/startstop/DmaapSimActivator.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/startstop/DmaapSimActivator.java new file mode 100644 index 000000000..899c0e081 --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/startstop/DmaapSimActivator.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap.startstop; + +import org.onap.policy.common.parameters.ParameterService; +import org.onap.policy.common.utils.services.ServiceManagerContainer; +import org.onap.policy.models.sim.dmaap.parameters.DmaapSimParameterGroup; +import org.onap.policy.models.sim.dmaap.rest.DmaapSimRestServer; + +/** + * This class activates the DMaaP simulator as a complete service. + */ +public class DmaapSimActivator extends ServiceManagerContainer { + /** + * The DMaaP simulator REST API server. + */ + private DmaapSimRestServer restServer; + + /** + * Instantiate the activator for the DMaaP simulator as a complete service. + * + * @param dmaapSimParameterGroup the parameters for the DMaaP simulator service + */ + public DmaapSimActivator(final DmaapSimParameterGroup dmaapSimParameterGroup) { + super("DMaaP Simulator"); + + // @formatter:off + addAction("DMaaP Simulator parameters", + () -> ParameterService.register(dmaapSimParameterGroup), + () -> ParameterService.deregister(dmaapSimParameterGroup.getName())); + + addAction("Create REST server", + () -> restServer = new DmaapSimRestServer(dmaapSimParameterGroup.getRestServerParameters()), + () -> restServer = null + ); + + addAction("REST server", + () -> restServer.start(), + () -> restServer.stop()); + // @formatter:on + } +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/startstop/DmaapSimCommandLineArguments.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/startstop/DmaapSimCommandLineArguments.java new file mode 100644 index 000000000..c0db8a7ed --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/startstop/DmaapSimCommandLineArguments.java @@ -0,0 +1,242 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap.startstop; + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.URL; +import java.util.Arrays; + +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.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.sim.dmaap.DmaapSimException; +import org.onap.policy.models.sim.dmaap.DmaapSimRuntimeException; + + +/** + * This class reads and handles command line parameters for the DMaaP simulator service. + */ +public class DmaapSimCommandLineArguments { + private static final String FILE_MESSAGE_PREAMBLE = " file \""; + private static final int HELP_LINE_LENGTH = 120; + + private final Options options; + private String configurationFilePath = null; + + /** + * Construct the options for the CLI editor. + */ + public DmaapSimCommandLineArguments() { + //@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 DMaaP simulator") + .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 DMaaP simulator parameters") + .hasArg() + .argName("CONFIG_FILE") + .required(false) + .type(String.class) + .build()); + //@formatter:on + } + + /** + * Construct the options for the CLI editor and parse in the given arguments. + * + * @param args The command line arguments + */ + public DmaapSimCommandLineArguments(final String[] args) { + // Set up the options with the default constructor + this(); + + // Parse the arguments + try { + parse(args); + } catch (final DmaapSimException e) { + throw new DmaapSimRuntimeException("parse error on DMaaP simulator 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 DmaapSimException on command argument errors + */ + public String parse(final String[] args) throws DmaapSimException { + // Clear all our arguments + setConfigurationFilePath(null); + + CommandLine commandLine = null; + try { + commandLine = new DefaultParser().parse(options, args); + } catch (final ParseException e) { + throw new DmaapSimException("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 && commandLine.hasOption('c') || remainingArgs.length > 0) { + throw new DmaapSimException("too many command line arguments specified : " + Arrays.toString(args)); + } + + if (remainingArgs.length == 1) { + configurationFilePath = remainingArgs[0]; + } + + if (commandLine.hasOption('h')) { + return help(Main.class.getCanonicalName()); + } + + if (commandLine.hasOption('v')) { + return version(); + } + + if (commandLine.hasOption('c')) { + setConfigurationFilePath(commandLine.getOptionValue('c')); + } + + return null; + } + + /** + * Validate the command line options. + * + * @throws DmaapSimException on command argument validation errors + */ + public void validate() throws DmaapSimException { + validateReadableFile("DMaaP simulator configuration", configurationFilePath); + } + + /** + * Print version information for DMaaP simulator. + * + * @return the version string + */ + public String version() { + return ResourceUtils.getResourceAsString("version.txt"); + } + + /** + * Print help information for DMaaP simulator. + * + * @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 configuration file path. + * + * @return the configuration file path + */ + public String getConfigurationFilePath() { + return configurationFilePath; + } + + /** + * Gets the full expanded configuration file path. + * + * @return the configuration file path + */ + public String getFullConfigurationFilePath() { + return ResourceUtils.getFilePath4Resource(getConfigurationFilePath()); + } + + /** + * Sets the configuration file path. + * + * @param configurationFilePath the configuration file path + */ + public void setConfigurationFilePath(final String configurationFilePath) { + this.configurationFilePath = configurationFilePath; + + } + + /** + * Check set configuration file path. + * + * @return true, if check set configuration file path + */ + public boolean checkSetConfigurationFilePath() { + return configurationFilePath != null && configurationFilePath.length() > 0; + } + + /** + * Validate readable file. + * + * @param fileTag the file tag + * @param fileName the file name + * @throws DmaapSimException on the file name passed as a parameter + */ + private void validateReadableFile(final String fileTag, final String fileName) throws DmaapSimException { + if (fileName == null || fileName.length() == 0) { + throw new DmaapSimException(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 DmaapSimException(fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" does not exist"); + } + + final File theFile = new File(fileUrl.getPath()); + if (!theFile.exists()) { + throw new DmaapSimException(fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" does not exist"); + } + if (!theFile.isFile()) { + throw new DmaapSimException(fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" is not a normal file"); + } + if (!theFile.canRead()) { + throw new DmaapSimException(fileTag + FILE_MESSAGE_PREAMBLE + fileName + "\" is ureadable"); + } + } +} diff --git a/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/startstop/Main.java b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/startstop/Main.java new file mode 100644 index 000000000..878d008a8 --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/java/org/onap/policy/models/sim/dmaap/startstop/Main.java @@ -0,0 +1,146 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.models.sim.dmaap.startstop; + +import java.util.Arrays; + +import org.onap.policy.common.utils.services.Registry; +import org.onap.policy.models.sim.dmaap.DmaapSimConstants; +import org.onap.policy.models.sim.dmaap.DmaapSimException; +import org.onap.policy.models.sim.dmaap.parameters.DmaapSimParameterGroup; +import org.onap.policy.models.sim.dmaap.parameters.DmaapSimParameterHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class initiates the DMaaP simulator component. + */ +public class Main { + + private static final Logger LOGGER = LoggerFactory.getLogger(Main.class); + + private DmaapSimActivator activator; + private DmaapSimParameterGroup parameterGroup; + + /** + * Instantiates the DMaap Simulator service. + * + * @param args the command line arguments + */ + public Main(final String[] args) { + final String argumentString = Arrays.toString(args); + LOGGER.info("Starting DMaaP simulator service with arguments - {}", argumentString); + + // Check the arguments + final DmaapSimCommandLineArguments arguments = new DmaapSimCommandLineArguments(); + 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(); + } catch (final DmaapSimException e) { + LOGGER.error("start of DMaaP simulator service failed", e); + return; + } + + // Read the parameters + try { + parameterGroup = new DmaapSimParameterHandler().getParameters(arguments); + } catch (final Exception e) { + LOGGER.error("start of DMaaP simulator service failed", e); + return; + } + + // Now, create the activator for the DMaaP Simulator service + activator = new DmaapSimActivator(parameterGroup); + Registry.register(DmaapSimConstants.REG_DMAAP_SIM_ACTIVATOR, activator); + + // Start the activator + try { + activator.start(); + } catch (final RuntimeException e) { + LOGGER.error("start of DMaaP simulator service failed, used parameters are {}", Arrays.toString(args), e); + Registry.unregister(DmaapSimConstants.REG_DMAAP_SIM_ACTIVATOR); + return; + } + + // Add a shutdown hook to shut everything down in an orderly manner + Runtime.getRuntime().addShutdownHook(new DmaapSimShutdownHookClass()); + LOGGER.info("Started DMaaP simulator service"); + } + + /** + * Get the parameters specified in JSON. + * + * @return the parameters + */ + public DmaapSimParameterGroup getParameters() { + return parameterGroup; + } + + /** + * Shut down Execution. + * + * @throws DmaapSimException on shutdown errors + */ + public void shutdown() throws DmaapSimException { + // clear the parameterGroup variable + parameterGroup = null; + + // clear the DMaaP simulator activator + if (activator != null) { + activator.stop(); + } + } + + /** + * The Class DmaapSimShutdownHookClass terminates the DMaaP simulator service when its run method is called. + */ + private class DmaapSimShutdownHookClass extends Thread { + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + try { + // Shutdown the DMaaP simulator service and wait for everything to stop + activator.stop(); + } catch (final RuntimeException e) { + LOGGER.warn("error occured during shut down of the DMaaP simulator service", e); + } + } + } + + /** + * The main method. + * + * @param args the arguments + */ + public static void main(final String[] args) { + new Main(args); + } +} diff --git a/models-sim/models-sim-dmaap/src/main/resources/version.txt b/models-sim/models-sim-dmaap/src/main/resources/version.txt new file mode 100644 index 000000000..d629db844 --- /dev/null +++ b/models-sim/models-sim-dmaap/src/main/resources/version.txt @@ -0,0 +1,4 @@ +ONAP DMaaP simulator Service +Version: ${project.version} +Built (UTC): ${maven.build.timestamp} +ONAP https://wiki.onap.org
\ No newline at end of file diff --git a/models-sim/models-sim-dmaap/src/test/resources/logback-test.xml b/models-sim/models-sim-dmaap/src/test/resources/logback-test.xml new file mode 100644 index 000000000..de7ef98da --- /dev/null +++ b/models-sim/models-sim-dmaap/src/test/resources/logback-test.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + Copyright (C) 2019 Nordix Foundation. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 + ============LICENSE_END========================================================= +--> + +<configuration> + + <contextName>DMaaPSim</contextName> + <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /> + <property name="LOG_DIR" value="${java.io.tmpdir}/pf_logging/" /> + + <!-- USE FOR STD OUT ONLY --> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern> + </encoder> + </appender> + + <root level="info"> + <appender-ref ref="STDOUT" /> + </root> + + <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <file>${LOG_DIR}/apex.log</file> + <encoder> + <pattern>%d %-5relative [procId=${processId}] [%thread] %-5level + %logger{26} - %msg %n %ex{full}</pattern> + </encoder> + </appender> + + <logger name="org.eclipse.jetty" level="info" additivity="false"> + <appender-ref ref="STDOUT" /> + </logger> + + <logger name="org.onap.policy.models.sim.dmaap" level="trace" additivity="false"> + <appender-ref ref="STDOUT" /> + </logger> +</configuration> diff --git a/models-sim/models-sim-dmaap/src/test/resources/parameters/EmptyParameters.json b/models-sim/models-sim-dmaap/src/test/resources/parameters/EmptyParameters.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/models-sim/models-sim-dmaap/src/test/resources/parameters/EmptyParameters.json @@ -0,0 +1 @@ +[]
\ No newline at end of file diff --git a/models-sim/models-sim-dmaap/src/test/resources/parameters/InvalidParameters.json b/models-sim/models-sim-dmaap/src/test/resources/parameters/InvalidParameters.json new file mode 100644 index 000000000..de2040cc8 --- /dev/null +++ b/models-sim/models-sim-dmaap/src/test/resources/parameters/InvalidParameters.json @@ -0,0 +1,3 @@ +{ + "name" : [] +}
\ No newline at end of file diff --git a/models-sim/models-sim-dmaap/src/test/resources/parameters/MinimumParameters.json b/models-sim/models-sim-dmaap/src/test/resources/parameters/MinimumParameters.json new file mode 100644 index 000000000..aeedf9d6e --- /dev/null +++ b/models-sim/models-sim-dmaap/src/test/resources/parameters/MinimumParameters.json @@ -0,0 +1,7 @@ +{ + "name":"DMaapSim", + "restServerParameters":{ + "host":"0.0.0.0", + "port":6845 + } +} diff --git a/models-sim/models-sim-dmaap/src/test/resources/parameters/NoParameters.json b/models-sim/models-sim-dmaap/src/test/resources/parameters/NoParameters.json new file mode 100644 index 000000000..7a73a41bf --- /dev/null +++ b/models-sim/models-sim-dmaap/src/test/resources/parameters/NoParameters.json @@ -0,0 +1,2 @@ +{ +}
\ No newline at end of file diff --git a/models-sim/models-sim-dmaap/src/test/resources/parameters/NormalParameters.json b/models-sim/models-sim-dmaap/src/test/resources/parameters/NormalParameters.json new file mode 100644 index 000000000..a2a036645 --- /dev/null +++ b/models-sim/models-sim-dmaap/src/test/resources/parameters/NormalParameters.json @@ -0,0 +1,7 @@ +{ + "name": "DMaapSim", + "restServerParameters": { + "host": "0.0.0.0", + "port": 6845 + } +} diff --git a/models-sim/models-sim-dmaap/src/test/resources/parameters/Parameters_InvalidName.json b/models-sim/models-sim-dmaap/src/test/resources/parameters/Parameters_InvalidName.json new file mode 100644 index 000000000..fba033e52 --- /dev/null +++ b/models-sim/models-sim-dmaap/src/test/resources/parameters/Parameters_InvalidName.json @@ -0,0 +1,9 @@ +{ + "name":" ", + "restServerParameters":{ + "host":"0.0.0.0", + "port":6969, + "userName":"dmaapsim", + "password":"zb!XztG34" + } +} diff --git a/models-sim/pom.xml b/models-sim/pom.xml new file mode 100644 index 000000000..c6165cc16 --- /dev/null +++ b/models-sim/pom.xml @@ -0,0 +1,36 @@ +<!-- + ============LICENSE_START======================================================= + Copyright (C) 2019 Nordix Foundation. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 + ============LICENSE_END========================================================= +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onap.policy.models</groupId> + <artifactId>policy-models</artifactId> + <version>2.0.0-SNAPSHOT</version> + </parent> + + <groupId>org.onap.policy.models.sim</groupId> + <artifactId>policy-models-sim</artifactId> + <packaging>pom</packaging> + <name>${project.artifactId}</name> + <modules> + <module>models-sim-dmaap</module> + </modules> +</project> @@ -59,6 +59,7 @@ <module>models-provider</module> <module>models-examples</module> <module>models-interactions</module> + <module>models-sim</module> </modules> <distributionManagement> |