diff options
158 files changed, 23690 insertions, 1 deletions
diff --git a/auth/cli-editor/pom.xml b/auth/cli-editor/pom.xml index 1f1863da6..0252fedc5 100644 --- a/auth/cli-editor/pom.xml +++ b/auth/cli-editor/pom.xml @@ -41,7 +41,7 @@ <dependency> <groupId>commons-cli</groupId> <artifactId>commons-cli</artifactId> - <version>1.4</version> + <version>${version.commons-cli}</version> </dependency> </dependencies> </project>
\ No newline at end of file @@ -40,6 +40,7 @@ <encoding>UTF-8</encoding> <file.encoding>UTF-8</file.encoding> <version.derby>10.13.1.1</version.derby> + <version.commons-cli>1.4</version.commons-cli> </properties> <distributionManagement> @@ -137,6 +138,7 @@ <module>context</module> <module>core</module> <module>auth</module> + <module>services</module> <module>plugins</module> </modules> </project>
\ No newline at end of file diff --git a/services/pom.xml b/services/pom.xml new file mode 100644 index 000000000..031dd9c78 --- /dev/null +++ b/services/pom.xml @@ -0,0 +1,40 @@ +<!-- + ============LICENSE_START======================================================= + Copyright (C) 2018 Ericsson. 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. + + 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.apex-pdp</groupId> + <artifactId>apex-pdp</artifactId> + <version>2.0.0-SNAPSHOT</version> + </parent> + + <groupId>org.onap.policy.apex-pdp.services</groupId> + <artifactId>services</artifactId> + <packaging>pom</packaging> + + <name>${project.artifactId}</name> + <description>The main services of Apex, deployment independent.</description> + + <modules> + <module>services-engine</module> + </modules> +</project>
\ No newline at end of file diff --git a/services/services-engine/pom.xml b/services/services-engine/pom.xml new file mode 100644 index 000000000..cde5d3b6f --- /dev/null +++ b/services/services-engine/pom.xml @@ -0,0 +1,81 @@ +<!-- + ============LICENSE_START======================================================= + Copyright (C) 2018 Ericsson. 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. + + 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.apex-pdp.services</groupId> + <artifactId>services</artifactId> + <version>2.0.0-SNAPSHOT</version> + </parent> + + <artifactId>services-engine</artifactId> + <name>${project.artifactId}</name> + <description>External services provided by the Apex policy execution engine</description> + + <dependencies> + <dependency> + <groupId>org.onap.policy.apex-pdp.core</groupId> + <artifactId>core-engine</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.policy.apex-pdp.core</groupId> + <artifactId>core-infrastructure</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.policy.apex-pdp.core</groupId> + <artifactId>core-protocols</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onap.policy.apex-pdp.context</groupId> + <artifactId>context-test</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>${version.commons-cli}</version> + </dependency> + </dependencies> + + <build> + <resources> + <!-- Output the version of Apex --> + <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>
\ No newline at end of file diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/engdep/EngDepMessageListener.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/engdep/EngDepMessageListener.java new file mode 100644 index 000000000..311e3b660 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/engdep/EngDepMessageListener.java @@ -0,0 +1,364 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.engdep; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.TimeUnit; + +import org.java_websocket.WebSocket; +import org.onap.policy.apex.core.infrastructure.messaging.MessageHolder; +import org.onap.policy.apex.core.infrastructure.messaging.MessageListener; +import org.onap.policy.apex.core.infrastructure.messaging.impl.ws.messageblock.MessageBlock; +import org.onap.policy.apex.core.infrastructure.messaging.util.MessagingUtils; +import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities; +import org.onap.policy.apex.core.protocols.Message; +import org.onap.policy.apex.core.protocols.engdep.EngDepAction; +import org.onap.policy.apex.core.protocols.engdep.messages.EngineServiceInfoResponse; +import org.onap.policy.apex.core.protocols.engdep.messages.GetEngineInfo; +import org.onap.policy.apex.core.protocols.engdep.messages.GetEngineServiceInfo; +import org.onap.policy.apex.core.protocols.engdep.messages.GetEngineStatus; +import org.onap.policy.apex.core.protocols.engdep.messages.Response; +import org.onap.policy.apex.core.protocols.engdep.messages.StartEngine; +import org.onap.policy.apex.core.protocols.engdep.messages.StartPeriodicEvents; +import org.onap.policy.apex.core.protocols.engdep.messages.StopEngine; +import org.onap.policy.apex.core.protocols.engdep.messages.StopPeriodicEvents; +import org.onap.policy.apex.core.protocols.engdep.messages.UpdateModel; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.service.engine.runtime.EngineService; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +import com.google.common.eventbus.Subscribe; + +/** + * The listener interface for receiving engDepMessage events. The class that is interested in + * processing a engDepMessage event implements this interface, and the object created with that + * class is registered with a component using the component's <code>addEngDepMessageListener</code> + * method. When the engDepMessage event occurs, that object's appropriate method is invoked. + * + * This class uses a queue to buffer incoming messages. When the listener is called, it places the + * incoming message on the queue. A thread runs which removes the messages from the queue and + * forwards them to the Apex engine. + * + * @author Sajeevan Achuthan (sajeevan.achuthan@ericsson.com) + */ +public class EngDepMessageListener implements MessageListener<Message>, Runnable { + private static final int LISTENER_STOP_WAIT_INTERVAL = 10; + + private static final XLogger LOGGER = XLoggerFactory.getXLogger(EngDepMessageListener.class); + + // The timeout to wait between queue poll timeouts in milliseconds + private static final long QUEUE_POLL_TIMEOUT = 50; + + // The Apex service itself + private final EngineService apexService; + + // The message listener thread and stopping flag + private Thread messageListenerThread; + private boolean stopOrderedFlag = false; + + // The message queue is used to hold messages prior to forwarding to Apex + private final BlockingQueue<MessageBlock<Message>> messageQueue = new LinkedBlockingDeque<>(); + + /** + * Instantiates a new EngDep message listener for listening for messages coming in from the + * Deployment client. The <code>apexService</code> is the Apex service to send the messages + * onto. + * + * @param apexService the Apex engine service + */ + protected EngDepMessageListener(final EngineService apexService) { + this.apexService = apexService; + } + + /** + * This method is an implementation of the message listener. It receives a message and places it + * on the queue for processing by the message listening thread. + * + * @param data the data + * @see org.onap.policy.apex.core.infrastructure.messaging.MessageListener#onMessage + * (org.onap.policy.apex.core.infrastructure.messaging.impl.ws.data.Data) + */ + @Subscribe + @Override + public void onMessage(final MessageBlock<Message> data) { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("message received from client application {} port {}", + data.getConnection().getRemoteSocketAddress().getAddress(), + data.getConnection().getRemoteSocketAddress().getPort()); + } + messageQueue.add(data); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.core.infrastructure.messaging.MessageListener#onMessage(java.lang. + * String) + */ + @Override + public void onMessage(final String messageString) { + throw new UnsupportedOperationException("String messages are not supported on the EngDep protocol"); + } + + /** + * This method gets a new message listening thread from the thread factory and starts it. + */ + public void startProcessorThread() { + LOGGER.entry(); + messageListenerThread = new Thread(this); + messageListenerThread.setDaemon(true); + messageListenerThread.start(); + LOGGER.exit(); + } + + /** + * Stops the message listening threads. + */ + public void stopProcessorThreads() { + LOGGER.entry(); + stopOrderedFlag = true; + + while (messageListenerThread.isAlive()) { + ThreadUtilities.sleep(LISTENER_STOP_WAIT_INTERVAL); + } + LOGGER.exit(); + } + + /** + * Runs the message listening thread. Here, the messages come in on the message queue and are + * processed one by one + */ + @Override + public void run() { + // Take messages off the queue and forward them to the Apex engine + while (messageListenerThread.isAlive() && !stopOrderedFlag) { + try { + final MessageBlock<Message> data = messageQueue.poll(QUEUE_POLL_TIMEOUT, TimeUnit.MILLISECONDS); + if (data != null) { + final List<Message> messages = data.getMessages(); + for (final Message message : messages) { + handleMessage(message, data.getConnection()); + } + } + } catch (final InterruptedException e) { + LOGGER.debug("message listener execution has been interrupted"); + break; + } + } + } + + /** + * This method handles EngDep messages as they come in. It uses the inevitable switch statement + * to handle the messages. + * + * @param message the incoming EngDep message + * @param webSocket the web socket on which the message came in + */ + private void handleMessage(final Message message, final WebSocket webSocket) { + LOGGER.entry(webSocket.getRemoteSocketAddress().toString()); + if (message.getAction() == null) { + // This is a response message + return; + } + + try { + LOGGER.debug("Manager action {} being applied to engine", message.getAction()); + + // Get and check the incoming action for validity + EngDepAction enDepAction = null; + if (message.getAction() instanceof EngDepAction) { + enDepAction = (EngDepAction) message.getAction(); + } else { + throw new ApexException(message.getAction().getClass().getName() + + "action on received message invalid, action must be of type \"EnDepAction\""); + } + + // Handle each incoming message using the inevitable switch statement for the EngDep + // protocol + switch (enDepAction) { + case GET_ENGINE_SERVICE_INFO: + final GetEngineServiceInfo engineServiceInformationMessage = (GetEngineServiceInfo) message; + LOGGER.debug("getting engine service information for engine service " + apexService.getKey().getID() + + " . . ."); + // Send a reply with the engine service information + sendServiceInfoReply(webSocket, engineServiceInformationMessage, apexService.getKey(), + apexService.getEngineKeys(), apexService.getApexModelKey()); + LOGGER.debug( + "returned engine service information for engine service " + apexService.getKey().getID()); + break; + + case UPDATE_MODEL: + final UpdateModel updateModelMessage = (UpdateModel) message; + LOGGER.debug("updating model in engine {} . . .", updateModelMessage.getTarget().getID()); + // Update the model + apexService.updateModel(updateModelMessage.getTarget(), updateModelMessage.getMessageData(), + updateModelMessage.isForceInstall()); + // Send a reply indicating the message action worked + sendReply(webSocket, updateModelMessage, true, + "updated model in engine " + updateModelMessage.getTarget().getID()); + LOGGER.debug("updated model in engine service {}", updateModelMessage.getTarget().getID()); + break; + + case START_ENGINE: + final StartEngine startEngineMessage = (StartEngine) message; + LOGGER.debug("starting engine {} . . .", startEngineMessage.getTarget().getID()); + // Start the engine + apexService.start(startEngineMessage.getTarget()); + // Send a reply indicating the message action worked + sendReply(webSocket, startEngineMessage, true, + "started engine " + startEngineMessage.getTarget().getID()); + LOGGER.debug("started engine {}", startEngineMessage.getTarget().getID()); + break; + + case STOP_ENGINE: + final StopEngine stopEngineMessage = (StopEngine) message; + LOGGER.debug("stopping engine {} . . .", stopEngineMessage.getTarget().getID()); + // Stop the engine + apexService.stop(stopEngineMessage.getTarget()); + // Send a reply indicating the message action worked + sendReply(webSocket, stopEngineMessage, true, + "stopped engine " + stopEngineMessage.getTarget().getID()); + LOGGER.debug("stopping engine {}", stopEngineMessage.getTarget().getID()); + break; + + case START_PERIODIC_EVENTS: + final StartPeriodicEvents startPeriodicEventsMessage = (StartPeriodicEvents) message; + LOGGER.debug("starting periodic events on engine {} . . .", + startPeriodicEventsMessage.getTarget().getID()); + // Start periodic events with the period specified in the message + final Long period = Long.parseLong(startPeriodicEventsMessage.getMessageData()); + apexService.startPeriodicEvents(period); + // Send a reply indicating the message action worked + sendReply(webSocket, startPeriodicEventsMessage, true, "started periodic events on engine " + + startPeriodicEventsMessage.getTarget().getID() + " with period " + period); + LOGGER.debug("started periodic events on engine " + startPeriodicEventsMessage.getTarget().getID() + + " with period " + period); + break; + + case STOP_PERIODIC_EVENTS: + final StopPeriodicEvents stopPeriodicEventsMessage = (StopPeriodicEvents) message; + LOGGER.debug("stopping periodic events on engine {} . . .", + stopPeriodicEventsMessage.getTarget().getID()); + // Stop periodic events + apexService.stopPeriodicEvents(); + // Send a reply indicating the message action worked + sendReply(webSocket, stopPeriodicEventsMessage, true, + "stopped periodic events on engine " + stopPeriodicEventsMessage.getTarget().getID()); + LOGGER.debug("stopped periodic events on engine " + stopPeriodicEventsMessage.getTarget().getID()); + break; + + case GET_ENGINE_STATUS: + final GetEngineStatus getEngineStatusMessage = (GetEngineStatus) message; + LOGGER.debug("getting status for engine{} . . .", getEngineStatusMessage.getTarget().getID()); + // Send a reply with the engine status + sendReply(webSocket, getEngineStatusMessage, true, + apexService.getStatus(getEngineStatusMessage.getTarget())); + LOGGER.debug("returned status for engine {}", getEngineStatusMessage.getTarget().getID()); + break; + + case GET_ENGINE_INFO: + final GetEngineInfo getEngineInfo = (GetEngineInfo) message; + LOGGER.debug("getting runtime information for engine {} . . .", getEngineInfo.getTarget().getID()); + // Send a reply with the engine runtime information + sendReply(webSocket, getEngineInfo, true, apexService.getRuntimeInfo(getEngineInfo.getTarget())); + LOGGER.debug("returned runtime information for engine {}", getEngineInfo.getTarget().getID()); + break; + case RESPONSE: + throw new ApexException("RESPONSE action on received message not handled by engine"); + + default: + break; + } + } catch (final ApexException e) { + LOGGER.warn("apex failed to execute message", e); + sendReply(webSocket, message, false, e.getCascadedMessage()); + } catch (final Exception e) { + LOGGER.warn("system failure executing message", e); + sendReply(webSocket, message, false, e.getMessage()); + } + LOGGER.exit(); + } + + /** + * Send the Response message to the client. + * + * @param client the client to which to send the response message + * @param requestMessage the message to which we are responding + * @param result the result indicating success or failure + * @param messageData the message data + */ + private void sendReply(final WebSocket client, final Message requestMessage, final boolean result, + final String messageData) { + LOGGER.entry(result, messageData); + + if (client == null || !client.isOpen()) { + LOGGER.debug("error sending reply {}, client has disconnected", requestMessage.getAction()); + return; + } + + LOGGER.debug("sending {} to web socket {}", requestMessage.getAction(), + client.getRemoteSocketAddress().toString()); + + final Response responseMessage = new Response(requestMessage.getTarget(), result, requestMessage); + responseMessage.setMessageData(messageData); + + final MessageHolder<Message> messageHolder = new MessageHolder<>(MessagingUtils.getHost()); + messageHolder.addMessage(responseMessage); + client.send(MessagingUtils.serializeObject(messageHolder)); + + LOGGER.exit(); + } + + /** + * Send the EngineServiceInfoResponse message to the client. + * + * @param client the client to which to send the response message + * @param requestMessage the message to which we are responding + * @param engineServiceKey The key of this engine service + * @param engineKeyCollection The keys of the engines in this engine service + * @param apexModelKey the apex model key + */ + private void sendServiceInfoReply(final WebSocket client, final Message requestMessage, + final AxArtifactKey engineServiceKey, final Collection<AxArtifactKey> engineKeyCollection, + final AxArtifactKey apexModelKey) { + LOGGER.entry(); + LOGGER.debug("sending {} to web socket {}", requestMessage.getAction(), + client.getRemoteSocketAddress().toString()); + + final EngineServiceInfoResponse responseMessage = + new EngineServiceInfoResponse(requestMessage.getTarget(), true, requestMessage); + responseMessage.setMessageData("engine service information"); + responseMessage.setEngineServiceKey(engineServiceKey); + responseMessage.setEngineKeyArray(engineKeyCollection); + responseMessage.setApexModelKey(apexModelKey); + + final MessageHolder<Message> messageHolder = new MessageHolder<>(MessagingUtils.getHost()); + messageHolder.addMessage(responseMessage); + client.send(MessagingUtils.serializeObject(messageHolder)); + + LOGGER.exit(); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/engdep/EngDepMessagingService.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/engdep/EngDepMessagingService.java new file mode 100644 index 000000000..86589ac81 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/engdep/EngDepMessagingService.java @@ -0,0 +1,107 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.engdep; + +import java.net.InetSocketAddress; + +import org.onap.policy.apex.service.engine.runtime.EngineService; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +import org.onap.policy.apex.core.infrastructure.messaging.MessagingService; +import org.onap.policy.apex.core.infrastructure.messaging.MessagingServiceFactory; +import org.onap.policy.apex.core.infrastructure.messaging.util.MessagingUtils; +import org.onap.policy.apex.core.protocols.Message; + +/** + * The Class EngDepMessagingService is used to encapsulate the server side of EngDep communication. + * This class allows users to create and start an EngDep server. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class EngDepMessagingService { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(EngDepMessagingService.class); + + // Messaging service is used to transmit and receive messages over a communication protocol + private static MessagingServiceFactory<Message> messageServiceFactory = new MessagingServiceFactory<>(); + private final MessagingService<Message> messageService; + + // The listener that is listening for messages coming in on the EngDep protocol from clients + private final EngDepMessageListener messageListener; + + /** + * Instantiates a new EngDep messaging service. It creates the message service instance, a + * listener for incoming messages, and starts the message listener thread for handling incoming + * messages. + * + * @param service the Apex engine service that this EngDep service is running for + * @param port the port The port to use for EngDep communication + */ + public EngDepMessagingService(final EngineService service, final int port) { + LOGGER.entry(service); + + // Create the service and listener and add the listener. + messageService = messageServiceFactory.createServer(new InetSocketAddress(MessagingUtils.checkPort(port))); + messageListener = new EngDepMessageListener(service); + messageService.addMessageListener(messageListener); + + // Start incoming message processing on the listener + messageListener.startProcessorThread(); + LOGGER.exit(); + } + + /** + * Start the server, open the communication mechanism for connections. + */ + public void start() { + LOGGER.info("engine<-->deployment messaging starting . . ."); + messageService.startConnection(); + LOGGER.info("engine<-->deployment messaging started"); + } + + /** + * Start the server, close the communication mechanism. + */ + public void stop() { + LOGGER.info("engine<-->deployment messaging stopping . . ."); + messageService.stopConnection(); + messageListener.stopProcessorThreads(); + LOGGER.info("engine<-->deployment messaging stopped"); + } + + /** + * Is the server started?. + * + * @return true, if checks if is started + */ + public boolean isStarted() { + return messageService.isStarted(); + } + + /** + * Is the server stopped?. + * + * @return true, if checks if is stopped + */ + public boolean isStopped() { + return !messageService.isStarted(); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/engdep/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/engdep/package-info.java new file mode 100644 index 000000000..41f644465 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/engdep/package-info.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Gives access to the APEX EngDep protocol for APEX engine management at runtime over a Java API. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine.engdep; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEvent.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEvent.java new file mode 100644 index 000000000..552f949a2 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEvent.java @@ -0,0 +1,342 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; + +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * The Class ApexEvent is an event class that external systems use to send events to and receive events from Apex engines. The event itself is a hash map of + * string keys and object values, used to pass data. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexEvent extends HashMap<String, Object> implements Serializable { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexEvent.class); + + private static final long serialVersionUID = -4451918242101961685L; + + // Holds the next identifier for event execution. + private static AtomicLong nextExecutionID = new AtomicLong(0L); + + /** The name of the Apex event, a mandatory field. All Apex events must have a name so that the event can be looked up in the Apex policy model. */ + public static final String NAME_HEADER_FIELD = "name"; + + /** + * The version of the Apex event, an optional field. If a version is specified on an Apex event, the definition of that version of the event is taken from + * the Apex policy model. If no version is specified, the latest version of the event is used. + */ + public static final String VERSION_HEADER_FIELD = "version"; + + /** + * The name space of the Apex event, an optional field. If a name space is specified on an Apex event it must match the name space on the event definition + * taken from the Apex policy model. If no name space is specified, the name space from the event definition in the Apex policy model is used. + */ + public static final String NAMESPACE_HEADER_FIELD = "nameSpace"; + + /** + * The source of the Apex event, an optional field. It specifies where the Apex event has come from and its use is reserved for now. If no source is + * specified, the source from the event definition in the Apex policy model is used. + */ + public static final String SOURCE_HEADER_FIELD = "source"; + + /** + * The target of the Apex event, an optional field. It specifies where the Apex event is going to and its use is reserved for now. If no target is + * specified, the target from the event definition in the Apex policy model is used. + */ + public static final String TARGET_HEADER_FIELD = "target"; + + /** + * The exception message field of an Apex event is an exception message indicating that an event failed. + */ + public static final String EXCEPTION_MESSAGE_HEADER_FIELD = "exceptionMessage"; + + /** The name of an Apex event must match this regular expression. */ + public static final String NAME_REGEXP = "[A-Za-z0-9\\-_.]+"; + + /** The version of an Apex event must match this regular expression. */ + public static final String VERSION_REGEXP = "[A-Za-z0-9.]+"; + + /** The name space of an Apex event must match this regular expression. */ + public static final String NAMESPACE_REGEXP = "([a-zA_Z_][\\.\\w]*)"; + + /** The source of an Apex event must match this regular expression. */ + public static final String SOURCE_REGEXP = "^$|[A-Za-z0-9\\.\\-_:]+"; + + /** The target of an Apex event must match this regular expression. */ + public static final String TARGET_REGEXP = "^$|[A-Za-z0-9\\.\\-_:]+"; + + // The fields of the event + // @formatter:off + private final String name; + private final String version; + private final String nameSpace; + private final String source; + private final String target; + // @formatter:on + + // An identifier for the current event execution. The default value here will always be unique in a single JVM + private long executionID = ApexEvent.getNextExecutionID(); + + // A string holding a message that indicates why processing of this event threw an exception + private String exceptionMessage; + + /** + * Private utility to get the next candidate value for a Execution ID. This value will always be unique in a single JVM + * + * @return the next candidate value for a Execution ID + */ + private static synchronized long getNextExecutionID() { + return nextExecutionID.getAndIncrement(); + } + + /** + * Instantiates a new apex event. + * + * @param name the name of the event + * @param version the version of the event + * @param nameSpace the name space (java package) of the event + * @param source the source of the event + * @param target the target of the event + * @throws ApexEventException thrown on validation errors on event names and versions + */ + public ApexEvent(final String name, final String version, final String nameSpace, final String source, final String target) throws ApexEventException { + // @formatter:off + this.name = validateField("name", name, NAME_REGEXP); + this.version = validateField("version", version, VERSION_REGEXP); + this.nameSpace = validateField("nameSpace", nameSpace, NAMESPACE_REGEXP); + this.source = validateField("source", source, SOURCE_REGEXP); + this.target = validateField("target", target, TARGET_REGEXP); + // @formatter:on + } + + /** + * Check that a field of the event is valid. + * + * @param fieldName the name of the field to check + * @param fieldValue the value of the field to check + * @param fieldRegexp the regular expression to check the field against + * @return the validated field value + * @throws ApexEventException thrown if the field is invalid + */ + private String validateField(final String fieldName, final String fieldValue, final String fieldRegexp) throws ApexEventException { + if (fieldValue.matches(fieldRegexp)) { + return fieldValue; + } + else { + LOGGER.warn("event \"" + name + ": field \"" + fieldName + "=" + fieldValue + "\" is illegal. It doesn't match regex '" + fieldRegexp + "'"); + throw new ApexEventException("event \"" + name + ": field \"" + fieldName + "=" + fieldValue + "\" is illegal"); + } + } + + /** + * Check that the key of an event is valid. + * + * @param key the key + * @return the string + * @throws ApexEventException the apex event exception + */ + private String validKey(final String key) throws ApexEventException { + if (key.matches(NAME_REGEXP)) { + return key; + } + else { + LOGGER.warn("event \"" + name + ": key \"" + key + "\" is illegal"); + throw new ApexEventException("event \"" + name + ": key \"" + key + "\" is illegal"); + } + } + + /** + * Gets the name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * Gets the version. + * + * @return the version + */ + public String getVersion() { + return version; + } + + /** + * Gets the name space. + * + * @return the name space + */ + public String getNameSpace() { + return nameSpace; + } + + /** + * Gets the source. + * + * @return the source + */ + public String getSource() { + return source; + } + + /** + * Gets the target. + * + * @return the target + */ + public String getTarget() { + return target; + } + + /** + * Gets the pass-thru executionID for this event. + * + * @return the executionID + */ + public long getExecutionID() { + return executionID; + } + + /** + * Sets the pass-thru executionID for this event. The default value for executionID will be be unique in the current JVM. For some applications/deployments + * this executionID may need to globally unique + * + * @param executionID the executionID + */ + public void setExecutionID(final long executionID) { + this.executionID = executionID; + } + + /** + * Gets the exception message explaining why processing of this event to fail. + * + * @return the exception message + */ + public String getExceptionMessage() { + return exceptionMessage; + } + + /** + * Sets the exception message explaining why processing of this event to fail. + * + * @param exceptionMessage the exception message + */ + public void setExceptionMessage(final String exceptionMessage) { + this.exceptionMessage = exceptionMessage; + } + + /* + * Map overrides from here + */ + + /* + * (non-Javadoc) + * + * @see java.util.Map#put(java.lang.Object, java.lang.Object) + */ + @Override + public Object put(final String key, final Object value) { + // Check if the key is valid + try { + return super.put(validKey(key), value); + } + catch (final ApexEventException e) { + return null; + } + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#putAll(java.util.Map) + */ + @Override + public void putAll(final Map<? extends String, ? extends Object> incomingMap) { + // Check the keys are valid + try { + for (final String key : incomingMap.keySet()) { + validKey(key); + } + } + catch (final ApexEventException e) { + // One of the keys is invalid + return; + } + + // Go ahead and put everything + super.putAll(incomingMap); + } + + /* + * Object overrides from here + */ + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("name="); + builder.append(name); + builder.append(",version="); + builder.append(version); + builder.append(",nameSpace="); + builder.append(nameSpace); + builder.append(",source="); + builder.append(source); + builder.append(",target="); + builder.append(target); + builder.append(",executionID="); + builder.append(executionID); + builder.append(",exceptionMessage="); + builder.append(exceptionMessage); + builder.append(","); + builder.append("["); + + boolean firstData = true; + for (final Map.Entry<String, Object> dataEntry : this.entrySet()) { + if (firstData) { + firstData = false; + } + else { + builder.append(','); + } + + builder.append(dataEntry.getKey()); + builder.append('='); + builder.append(dataEntry.getValue()); + } + + builder.append("]"); + return builder.toString(); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventConsumer.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventConsumer.java new file mode 100644 index 000000000..53f11dd61 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventConsumer.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; + +/** + * This interface is used by technology specific consumers and listeners that are are listening for + * or collecting events for input into Apex. Users specify the consumer technology to use in the + * Apex configuration and Apex uses a factory to start the appropriate consumer plugin that + * implements this interface for its input. The technology specific implementation details are + * hidden behind this interface. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public interface ApexEventConsumer { + /** + * Initialize the consumer. + * + * @param name a name for this consumer + * @param consumerParameters the parameters to initialize this consumer + * @param apexEventReceiver the apex event receiver that should be used to pass events received + * by the consumer into Apex + * @throws ApexEventException container exception on errors initializing event handling + */ + void init(String name, EventHandlerParameters consumerParameters, ApexEventReceiver apexEventReceiver) + throws ApexEventException; + + /** + * Start the consumer, start input of events into Apex. + */ + void start(); + + /** + * Get the peered reference object for this consumer. + * + * @param peeredMode the peered mode for which to return the reference + * @return the peered reference object for this consumer + */ + PeeredReference getPeeredReference(EventHandlerPeeredMode peeredMode); + + /** + * Set the peered reference object for this consumer. + * + * @param peeredMode the peered mode for which to return the reference + * @param peeredReference the peered reference object for this consumer + */ + void setPeeredReference(EventHandlerPeeredMode peeredMode, PeeredReference peeredReference); + + /** + * Get the name of this event consumer. + * + * @return the event consumer name + */ + String getName(); + + /** + * Stop the event consumer. + */ + void stop(); +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventConverter.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventConverter.java new file mode 100644 index 000000000..11f005ddf --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventConverter.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import java.util.List; + +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; + +/** + * The Interface ApexEventConverter is used for applications that want to convert arbitrary event + * types to and from Apex events. Application implement this interface to convert their events to + * and from Apex events.The Apex service can then use this interface to transparently transfer + * events into and out of an Apex system. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public interface ApexEventConverter { + + /** + * Convert an event of arbitrary type into an Apex event. + * + * @param name the name of the incoming event + * @param eventOfOtherType the event of some other type to convert + * @return the apex event + * @throws ApexException thrown on conversion errors + */ + List<ApexEvent> toApexEvent(String name, Object eventOfOtherType) throws ApexException; + + /** + * Convert an Apex event into an event of arbitrary type {@code OTHER_EVENT_TYPE}. + * + * @param apexEvent the apex event to convert + * @return the event converted into the other type + * @throws ApexException thrown on conversion errors + */ + Object fromApexEvent(ApexEvent apexEvent) throws ApexException; +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventException.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventException.java new file mode 100644 index 000000000..24f57d741 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventException.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; + +/** + * This class will be called if an error occurs in handling Apex events. + * + * @author eeilfn + */ +public class ApexEventException extends ApexException { + private static final long serialVersionUID = -4245694568321686450L; + + /** + * Instantiates a new apex event exception. + * + * @param message the message + */ + public ApexEventException(final String message) { + super(message); + } + + /** + * Instantiates a new apex event exception. + * + * @param message the message + * @param e the e + */ + public ApexEventException(final String message, final Exception e) { + super(message, e); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventList.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventList.java new file mode 100644 index 000000000..9fe03ef47 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventList.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import java.util.ArrayList; + +/** + * The Class ApexEventList holds a list of APEX events. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexEventList extends ArrayList<ApexEvent> { + private static final long serialVersionUID = -8496211897512202896L; +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventProducer.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventProducer.java new file mode 100644 index 000000000..414fbc9e3 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventProducer.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; + +/** + * This interface is used by technology specific producers and publishers that are handling events + * output by Apex. Users specify the producer technology to use in the Apex configuration and Apex + * uses a factory to start the appropriate producer plugin that implements this interface for its + * output. The technology specific implementation details are hidden behind this interface. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public interface ApexEventProducer { + + /** + * Initialize the producer. + * + * @param name a name for this producer + * @param producerParameters the parameters to initialise this producer + * @throws ApexEventException exception on errors initializing an event producer + */ + void init(String name, EventHandlerParameters producerParameters) throws ApexEventException; + + /** + * Get the peered reference object for this producer. + * + * @param peeredMode the peered mode for which to return the reference + * @return the peered reference object for this producer + */ + PeeredReference getPeeredReference(EventHandlerPeeredMode peeredMode); + + /** + * Set the peered reference object for this producer. + * + * @param peeredMode the peered mode for which to return the reference + * @param peeredReference the peered reference object for this producer + */ + void setPeeredReference(EventHandlerPeeredMode peeredMode, PeeredReference peeredReference); + + /** + * Send an event to the producer. + * + * @param executionId the unique ID that produced this event + * @param eventName The name of the event + * @param event The converted event as an object + */ + void sendEvent(long executionId, String eventName, Object event); + + /** + * Get the name of this event producer. + * + * @return the event producer name + */ + String getName(); + + /** + * Stop the event producer. + */ + void stop(); +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventProtocolConverter.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventProtocolConverter.java new file mode 100644 index 000000000..ec19e65c3 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventProtocolConverter.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters; + +/** + * The Interface ApexEventProtocolConverter extends ApexEventConverter to allow + * EventProtocolParameters conversion parameters to be passed to the converter. + * + * @author John Keeney (john.keeney@ericsson.com) + */ +public interface ApexEventProtocolConverter extends ApexEventConverter { + + /** + * Initialise the converter instance with the parameters for the EventProtocol. + * + * @param parameters the parameters for the EventProtocol + */ + void init(EventProtocolParameters parameters); +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventReceiver.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventReceiver.java new file mode 100644 index 000000000..8d7e7bae5 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventReceiver.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +/** + * This interface is used by an Apex event consumer {@link ApexEventConsumer} consumer to pass a + * received event to Apex. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public interface ApexEventReceiver { + /** + * Receive an event from a consumer for processing. + * + * @param executionId the unique ID for execution of this event + * @param event the event to receive + * @throws ApexEventException on exceptions receiving an event into Apex + */ + void receiveEvent(long executionId, Object event) throws ApexEventException; + + /** + * Receive an event from a consumer for processing. + * + * @param event the event to receive + * @throws ApexEventException on exceptions receiving an event into Apex + */ + void receiveEvent(Object event) throws ApexEventException; +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventRuntimeException.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventRuntimeException.java new file mode 100644 index 000000000..1a624face --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexEventRuntimeException.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException; + +/** + * This exception will be called if a runtime error occurs in Apex event handling. + * + * @author Liam Fallon + */ +public class ApexEventRuntimeException extends ApexRuntimeException { + private static final long serialVersionUID = -8507246953751956974L; + + /** + * Instantiates a new apex runtime event exception with a message. + * + * @param message the message + */ + public ApexEventRuntimeException(final String message) { + super(message); + } + + /** + * Instantiates a new apex runtime event exception with a message and a caused by exception. + * + * @param message the message + * @param e the exception that caused this exception to be thrown + */ + public ApexEventRuntimeException(final String message, final Exception e) { + super(message, e); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexPeriodicEventGenerator.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexPeriodicEventGenerator.java new file mode 100644 index 000000000..62663b9f1 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/ApexPeriodicEventGenerator.java @@ -0,0 +1,176 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import java.util.HashMap; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; + +import org.onap.policy.apex.service.engine.runtime.EngineServiceEventInterface; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This class is used to generate periodic events into an Apex engine service. It is used to trigger + * policies that perform housekeeping operations. + * + * @author eeilfn + */ +public class ApexPeriodicEventGenerator extends TimerTask { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexPeriodicEventGenerator.class); + + /** The name of the periodic event. */ + public static final String PERIODIC_EVENT_NAME = "PERIODIC_EVENT"; + + /** The version of the periodic event. */ + public static final String PERIODIC_EVENT_VERSION = "0.0.1"; + + /** The name space of the periodic event. */ + public static final String PERIODIC_EVENT_NAMESPACE = "com.ericsson.apex.service.engine.event"; + + /** The source of the periodic event. */ + public static final String PERIODIC_EVENT_SOURCE = "internal"; + + /** The target of the periodic event. */ + public static final String PERIODIC_EVENT_TARGET = "internal"; + + /** + * The field name in the periodic event for the delay between occurrences of the periodic event. + */ + public static final String PERIODIC_DELAY = "PERIODIC_DELAY"; + + /** + * The field name in the periodic event for the time at which the first periodic event will + * occur. + */ + public static final String PERIODIC_FIRST_TIME = "PERIODIC_FIRST_TIME"; + + /** + * The field name in the periodic event for the time at which the last periodic event will + * occur. + */ + public static final String PERIODIC_LAST_TIME = "PERIODIC_LAST_TIME"; + + /** The field name in the periodic event for the time at which the event was sent. */ + public static final String PERIODIC_CURRENT_TIME = "PERIODIC_CURRENT_TIME"; + + /** + * The field name in the periodic event for the number of occurrences of this event that have + * been sent to date, this is a sequence number for the periodic event. + */ + public static final String PERIODIC_EVENT_COUNT = "PERIODIC_EVENT_COUNT"; + + // The Java timer used to send periodic events + private Timer timer = null; + + // The engine service interface we'll send periodic events to + private final EngineServiceEventInterface engineServiceEventInterface; + + // Timing information + private long period = 0; + private long firstEventTime = 0; + private long lastEventTime = 0; + private long eventCount = 0; + + /** + * Constructor, save a reference to the event stream handler. + * + * @param engineServiceEventInterface the engine service event interface on which to send + * periodic events + * @param period The period in milliseconds between events + */ + public ApexPeriodicEventGenerator(final EngineServiceEventInterface engineServiceEventInterface, + final long period) { + // Save the engine service reference and delay + this.engineServiceEventInterface = engineServiceEventInterface; + this.period = period; + + timer = new Timer(ApexPeriodicEventGenerator.class.getSimpleName(), true); + timer.schedule(this, period, period); + } + + /** + * Output the metrics for stream loading. + */ + @Override + public void run() { + final Map<String, Object> periodicEventMap = new HashMap<>(); + + // Record the current event time + final long currentEventTime = System.currentTimeMillis(); + + // Check if this is the first periodic event + if (firstEventTime == 0) { + firstEventTime = currentEventTime; + lastEventTime = currentEventTime; + } + + // Increment the event counter + eventCount++; + + // Set the fields in the periodic event + periodicEventMap.put(PERIODIC_DELAY, period); + periodicEventMap.put(PERIODIC_FIRST_TIME, firstEventTime); + periodicEventMap.put(PERIODIC_LAST_TIME, lastEventTime); + periodicEventMap.put(PERIODIC_CURRENT_TIME, currentEventTime); + periodicEventMap.put(PERIODIC_EVENT_COUNT, eventCount); + + // Send the periodic event + try { + final ApexEvent periodicEvent = new ApexEvent(PERIODIC_EVENT_NAME, PERIODIC_EVENT_VERSION, + PERIODIC_EVENT_NAMESPACE, PERIODIC_EVENT_SOURCE, PERIODIC_EVENT_TARGET); + periodicEvent.putAll(periodicEventMap); + engineServiceEventInterface.sendEvent(periodicEvent); + } catch (final ApexEventException e) { + LOGGER.warn("could not send Apex periodic event " + PERIODIC_EVENT_NAME + ":" + PERIODIC_EVENT_VERSION, e); + return; + } + + // Save the current time as the last time + lastEventTime = currentEventTime; + } + + /** + * Cancel the timer. + * + * @return true, if cancel + */ + @Override + public boolean cancel() { + // Cancel the timer + if (timer != null) { + timer.cancel(); + } + return true; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "ApexPeriodicEventGenerator [period=" + period + ", firstEventTime=" + firstEventTime + + ", lastEventTime=" + lastEventTime + ", eventCount=" + eventCount + "]"; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/PeeredReference.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/PeeredReference.java new file mode 100644 index 000000000..9560a834c --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/PeeredReference.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; + +/** + * This class holds a reference to an event consumer and producer that have been peered. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class PeeredReference { + // The consumer putting events into APEX + private final ApexEventConsumer peeredConsumer; + + // The synchronous producer taking events out of APEX + private final ApexEventProducer peeredProducer; + + /** + * Create a peered consumer/producer reference + * + * @param peeredMode the peered mode for which to return the reference + * @param consumer the consumer that is receiving event + * @param producer the producer that is sending events + */ + public PeeredReference(final EventHandlerPeeredMode peeredMode, final ApexEventConsumer consumer, final ApexEventProducer producer) { + this.peeredConsumer = consumer; + this.peeredProducer = producer; + + // Set the peered reference on the producer and consumer + peeredConsumer.setPeeredReference(peeredMode, this); + peeredProducer.setPeeredReference(peeredMode, this); + } + + /** + * Gets the synchronous consumer putting events into the cache. + * + * @return the source synchronous consumer + */ + public ApexEventConsumer getPeeredConsumer() { + return peeredConsumer; + } + + /** + * Gets the synchronous producer taking events from the cache. + * + * @return the synchronous producer that is taking events from the cache + */ + public ApexEventProducer getPeeredProducer() { + return peeredProducer; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/SynchronousEventCache.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/SynchronousEventCache.java new file mode 100644 index 000000000..25f92d843 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/SynchronousEventCache.java @@ -0,0 +1,294 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import java.util.AbstractMap.SimpleEntry; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This class holds a cache of the synchronous events sent into Apex and that have not yet been replied to. It runs a thread to time out events that have not + * been replied to in the specified timeout. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class SynchronousEventCache extends PeeredReference implements Runnable { + // Get a reference to the logger + private static final XLogger LOGGER = XLoggerFactory.getXLogger(SynchronousEventCache.class); + + // The default amount of time to wait for a synchronous event to be replied to is 1 second + private static final long DEFAULT_SYNCHRONOUS_EVENT_TIMEOUT = 1000; + + // The timeout to wait between event polls in milliseconds and the time to wait for the thread to stop + private static final long OUTSTANDING_EVENT_POLL_TIMEOUT = 50; + private static final long CACHE_STOP_WAIT_INTERVAL = 10; + + // The time in milliseconds to wait for the reply to a sent synchronous event + private long synchronousEventTimeout = DEFAULT_SYNCHRONOUS_EVENT_TIMEOUT; + + // Map holding outstanding synchronous events + private final Map<Long, SimpleEntry<Long, Object>> toApexEventMap = new HashMap<Long, SimpleEntry<Long, Object>>(); + + // Map holding reply events + private final Map<Long, SimpleEntry<Long, Object>> fromApexEventMap = new HashMap<Long, SimpleEntry<Long, Object>>(); + + // The message listener thread and stopping flag + private final Thread synchronousEventCacheThread; + private boolean stopOrderedFlag = false; + + /** + * Create a synchronous event cache that caches outstanding synchronous Apex events. + * + * @param peeredMode the peered mode for which to return the reference + * @param consumer the consumer that is populating the cache + * @param producer the producer that is emptying the cache + * @param synchronousEventTimeout the time in milliseconds to wait for the reply to a sent synchronous event + */ + public SynchronousEventCache(final EventHandlerPeeredMode peeredMode, final ApexEventConsumer consumer, final ApexEventProducer producer, final long synchronousEventTimeout) { + super(peeredMode, consumer, producer); + + if (synchronousEventTimeout != 0) { + this.synchronousEventTimeout = synchronousEventTimeout; + } + else { + this.synchronousEventTimeout = DEFAULT_SYNCHRONOUS_EVENT_TIMEOUT; + } + + // Start scanning the outstanding events + synchronousEventCacheThread = new Thread(this); + synchronousEventCacheThread.setDaemon(true); + synchronousEventCacheThread.start(); + } + + /** + * Gets the timeout value for synchronous events. + * + * @return the synchronous event timeout + */ + public long getSynchronousEventTimeout() { + return synchronousEventTimeout; + } + + /** + * Cache a synchronized event sent into Apex in the event cache. + * + * @param executionId the execution ID that was assigned to the event + * @param event the apex event + */ + public void cacheSynchronizedEventToApex(final long executionId, final Object event) { + // Add the event to the map + synchronized (toApexEventMap) { + cacheSynchronizedEvent(toApexEventMap, executionId, event); + } + } + + /** + * Remove the record of an event sent to Apex if it exists in the cache. + * + * @param executionId the execution ID of the event + * @return The removed event + */ + public Object removeCachedEventToApexIfExists(final long executionId) { + synchronized (toApexEventMap) { + return removeCachedEventIfExists(toApexEventMap, executionId); + } + } + + /** + * Check if an event exists in the to apex cache. + * + * @param executionId the execution ID of the event + * @return true if the event exists, false otherwise + */ + public boolean existsEventToApex(final long executionId) { + synchronized (toApexEventMap) { + return toApexEventMap.containsKey(executionId); + } + } + + /** + * Cache synchronized event received from Apex in the event cache. + * + * @param executionId the execution ID of the event + * @param event the apex event + */ + public void cacheSynchronizedEventFromApex(final long executionId, final Object event) { + // Add the event to the map + synchronized (fromApexEventMap) { + cacheSynchronizedEvent(fromApexEventMap, executionId, event); + } + } + + /** + * Remove the record of an event received from Apex if it exists in the cache. + * + * @param executionId the execution ID of the event + * @return The removed event + */ + public Object removeCachedEventFromApexIfExists(final long executionId) { + synchronized (fromApexEventMap) { + return removeCachedEventIfExists(fromApexEventMap, executionId); + } + } + + /** + * Check if an event exists in the from apex cache. + * + * @param executionId the execution ID of the event + * @return true if the event exists, false otherwise + */ + public boolean existsEventFromApex(final long executionId) { + synchronized (fromApexEventMap) { + return fromApexEventMap.containsKey(executionId); + } + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + LOGGER.entry(); + + // Periodic scan of outstanding events + while (synchronousEventCacheThread.isAlive() && !stopOrderedFlag) { + ThreadUtilities.sleep(OUTSTANDING_EVENT_POLL_TIMEOUT); + + // Check for timeouts on events + synchronized (toApexEventMap) { + timeoutEventsOnCache(toApexEventMap); + } + synchronized (fromApexEventMap) { + timeoutEventsOnCache(fromApexEventMap); + } + } + + LOGGER.exit(); + } + + /** + * Stops the scanning thread and clears the cache. + */ + public synchronized void stop() { + LOGGER.entry(); + stopOrderedFlag = true; + + while (synchronousEventCacheThread.isAlive()) { + ThreadUtilities.sleep(CACHE_STOP_WAIT_INTERVAL); + } + + // Check if there are any unprocessed events + if (!toApexEventMap.isEmpty()) { + LOGGER.warn(toApexEventMap.size() + " synchronous events dropped due to system shutdown"); + } + + toApexEventMap.clear(); + LOGGER.exit(); + } + + /** + * Cache a synchronized event sent in an event cache. + * @param eventCacheMap the map to cache the event on + * @param executionId the execution ID of the event + * @param event the event to cache + */ + private void cacheSynchronizedEvent(final Map<Long, SimpleEntry<Long, Object>> eventCacheMap, final long executionId, final Object event) { + LOGGER.entry("Adding event with execution ID: " + executionId); + + // Check if the event is already in the cache + if (eventCacheMap.containsKey(executionId)) { + // If there was no sent event then the event timed out or some unexpected event was received + final String errorMessage = "an event with ID " + executionId + + " already exists in the synchronous event cache, execution IDs must be unique in the system"; + LOGGER.warn(errorMessage); + throw new ApexEventRuntimeException(errorMessage); + } + + // Add the event to the map + eventCacheMap.put(executionId, new SimpleEntry<Long, Object>(System.currentTimeMillis(), event)); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("event has been cached:" + event); + } + + LOGGER.exit("Added: " + executionId); + } + + /** + * Remove the record of an event if it exists in the cache. + * + * @param eventCacheMap the map to remove the event from + * @param executionId the execution ID of the event + * @return The removed event + */ + private Object removeCachedEventIfExists(final Map<Long, SimpleEntry<Long, Object>> eventCacheMap, final long executionId) { + LOGGER.entry("Removing: " + executionId); + + final SimpleEntry<Long, Object> removedEventEntry = eventCacheMap.remove(executionId); + + if (removedEventEntry != null) { + LOGGER.exit("Removed: " + executionId); + return removedEventEntry.getValue(); + } + else { + // The event may not be one of the events in our cache, so we just ignore removal failures + return null; + } + } + + /** + * Time out events on an event cache map. Events that have a timeout longer than the configured timeout are timed out. + * @param eventCacheMap the event cache to operate on + */ + private void timeoutEventsOnCache(final Map<Long, SimpleEntry<Long, Object>> eventCacheMap) { + // Use a set to keep track of the events that have timed out + final Set<Long> timedOutEventSet = new HashSet<>(); + + for (final Entry<Long, SimpleEntry<Long, Object>> cachedEventEntry : eventCacheMap.entrySet()) { + // The amount of time we are waiting for the event reply + final long eventWaitTime = System.currentTimeMillis() - cachedEventEntry.getValue().getKey(); + + // Have we a timeout? + if (eventWaitTime > synchronousEventTimeout) { + timedOutEventSet.add(cachedEventEntry.getKey()); + } + } + + // Remove timed out events from the map + for (final long timedoutEventExecutionID : timedOutEventSet) { + // Remove the map entry and issue a warning + final SimpleEntry<Long, Object> timedOutEventEntry = eventCacheMap.remove(timedoutEventExecutionID); + + LOGGER.warn("synchronous event timed out, reply not received in " + synchronousEventTimeout + " milliseconds on event " + + timedOutEventEntry.getValue()); + } + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/EventConsumerFactory.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/EventConsumerFactory.java new file mode 100644 index 000000000..8f54c049b --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/EventConsumerFactory.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl; + +import org.onap.policy.apex.service.engine.event.ApexEventConsumer; +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This factory class creates event consumers of various technology types for Apex engines. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class EventConsumerFactory { + // The logger for this class + private static final XLogger LOGGER = XLoggerFactory.getXLogger(EventConsumerFactory.class); + + /** + * Empty constructor with no generic overloading. + */ + public EventConsumerFactory() {} + + /** + * Create an event consumer of the required type for the specified consumer technology. + * + * @param name the name of the consumer + * @param consumerParameters The parameters for the Apex engine, we use the technology type of + * the required consumer + * @return the event consumer + * @throws ApexEventException on errors creating the Apex event consumer + */ + public ApexEventConsumer createConsumer(final String name, final EventHandlerParameters consumerParameters) + throws ApexEventException { + // Get the carrier technology parameters + final CarrierTechnologyParameters technologyParameters = consumerParameters.getCarrierTechnologyParameters(); + + // Get the class for the event consumer using reflection + final String consumerPluginClass = technologyParameters.getEventConsumerPluginClass(); + Object consumerPluginObject = null; + try { + consumerPluginObject = Class.forName(consumerPluginClass).newInstance(); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + final String errorMessage = "could not create an Apex event consumer for \"" + name + + "\" for the carrier technology \"" + technologyParameters.getLabel() + + "\", specified event consumer plugin class \"" + consumerPluginClass + "\" not found"; + LOGGER.error(errorMessage, e); + throw new ApexEventException(errorMessage, e); + } + + // Check the class is an event consumer + if (!(consumerPluginObject instanceof ApexEventConsumer)) { + final String errorMessage = "could not create an Apex event consumer \"" + name + + "\" for the carrier technology \"" + technologyParameters.getLabel() + + "\", specified event consumer plugin class \"" + consumerPluginClass + + "\" is not an instance of \"" + ApexEventConsumer.class.getCanonicalName() + "\""; + LOGGER.error(errorMessage); + throw new ApexEventException(errorMessage); + } + + return (ApexEventConsumer) consumerPluginObject; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/EventProducerFactory.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/EventProducerFactory.java new file mode 100644 index 000000000..9bbbad362 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/EventProducerFactory.java @@ -0,0 +1,82 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl; + +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.engine.event.ApexEventProducer; +import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This factory class creates event producers for the defined technology type for Apex engines. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class EventProducerFactory { + // The logger for this class + private static final XLogger LOGGER = XLoggerFactory.getXLogger(EventProducerFactory.class); + + /** + * Empty constructor with no generic overloading. + */ + public EventProducerFactory() {} + + /** + * Create an event producer of the required type for the specified producer technology. + * + * @param name the name of the producer + * @param producerParameters The Apex parameters containing the configuration for the producer + * @return the event producer + * @throws ApexEventException on errors creating the Apex event producer + */ + public ApexEventProducer createProducer(final String name, final EventHandlerParameters producerParameters) + throws ApexEventException { + // Get the carrier technology parameters + final CarrierTechnologyParameters technologyParameters = producerParameters.getCarrierTechnologyParameters(); + + // Get the class for the event producer using reflection + final String producerPluginClass = technologyParameters.getEventProducerPluginClass(); + Object producerPluginObject = null; + try { + producerPluginObject = Class.forName(producerPluginClass).newInstance(); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + final String errorMessage = "could not create an Apex event producer for Producer \"" + name + + "\" for the carrier technology \"" + technologyParameters.getLabel() + + "\", specified event producer plugin class \"" + producerPluginClass + "\" not found"; + LOGGER.error(errorMessage, e); + throw new ApexEventException(errorMessage, e); + } + + // Check the class is an event producer + if (!(producerPluginObject instanceof ApexEventProducer)) { + final String errorMessage = "could not create an Apex event producer for Producer \"" + name + + "\" for the carrier technology \"" + technologyParameters.getLabel() + + "\", specified event producer plugin class \"" + producerPluginClass + + "\" is not an instance of \"" + ApexEventProducer.class.getCanonicalName() + "\""; + LOGGER.error(errorMessage); + throw new ApexEventException(errorMessage); + } + + return (ApexEventProducer) producerPluginObject; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/EventProtocolFactory.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/EventProtocolFactory.java new file mode 100644 index 000000000..85c5bf03f --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/EventProtocolFactory.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl; + +import org.onap.policy.apex.service.engine.event.ApexEventProtocolConverter; +import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This factory class uses the Apex event protocol parameters to create and return an instance of + * the correct Apex event protocol converter plugin for the specified event protocol. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class EventProtocolFactory { + // The logger for this class + private static final XLogger LOGGER = XLoggerFactory.getXLogger(EventProtocolFactory.class); + + /** + * Create an event converter that converts between an + * {@link org.onap.policy.apex.service.engine.event.ApexEvent} and the specified event protocol. + * + * @param name the name of the event protocol + * @param eventProtocolParameters the event protocol parameters defining what to convert from + * and to + * @return The event converter for converting events to and from Apex format + */ + public ApexEventProtocolConverter createConverter(final String name, + final EventProtocolParameters eventProtocolParameters) { + // Get the class for the event protocol plugin using reflection + final String eventProtocolPluginClass = eventProtocolParameters.getEventProtocolPluginClass(); + Object eventProtocolPluginObject = null; + try { + eventProtocolPluginObject = Class.forName(eventProtocolPluginClass).newInstance(); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + final String errorMessage = "could not create an Apex event protocol converter for \"" + name + + "\" for the protocol \"" + eventProtocolParameters.getLabel() + + "\", specified event protocol converter plugin class \"" + eventProtocolPluginClass + + "\" not found"; + LOGGER.error(errorMessage, e); + throw new ApexEventRuntimeException(errorMessage, e); + } + + // Check the class is an event consumer + if (!(eventProtocolPluginObject instanceof ApexEventProtocolConverter)) { + final String errorMessage = "could not create an Apex event protocol converter for \"" + name + + "\" for the protocol \"" + eventProtocolParameters.getLabel() + + "\", specified event protocol converter plugin class \"" + eventProtocolPluginClass + + "\" is not an instance of \"" + ApexEventProtocolConverter.class.getCanonicalName() + "\""; + LOGGER.error(errorMessage); + throw new ApexEventRuntimeException(errorMessage); + } + ((ApexEventProtocolConverter) eventProtocolPluginObject).init(eventProtocolParameters); + return (ApexEventProtocolConverter) eventProtocolPluginObject; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/apexprotocolplugin/Apex2ApexEventConverter.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/apexprotocolplugin/Apex2ApexEventConverter.java new file mode 100644 index 000000000..b73aeb567 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/apexprotocolplugin/Apex2ApexEventConverter.java @@ -0,0 +1,140 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.apexprotocolplugin; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.policy.apex.service.engine.event.ApexEvent; +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.engine.event.ApexEventList; +import org.onap.policy.apex.service.engine.event.ApexEventProtocolConverter; +import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * The Class Apex2ApexEventConverter passes through {@link ApexEvent} instances. It is used for + * transferring Apex events directly as POJOs between APEX producers and consumers. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class Apex2ApexEventConverter implements ApexEventProtocolConverter { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(Apex2ApexEventConverter.class); + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.ApexEventProtocolConverter#init(org.onap.policy. + * apex. service.parameters.eventprotocol.EventProtocolParameters) + */ + @Override + public void init(final EventProtocolParameters parameters) { + // Check and get the APEX parameters + if (!(parameters instanceof ApexEventProtocolParameters)) { + final String errorMessage = "specified consumer properties are not applicable to the APEX event protocol"; + LOGGER.warn(errorMessage); + throw new ApexEventRuntimeException(errorMessage); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.ApexEventConverter#toApexEvent(java.lang.String, + * java.lang.Object) + */ + @Override + public List<ApexEvent> toApexEvent(final String eventName, final Object eventObject) throws ApexEventException { + // Check the event eventObject + if (eventObject == null) { + LOGGER.warn("event processing failed, event is null"); + throw new ApexEventException("event processing failed, event is null"); + } + + // The list of events we will return + final List<ApexEvent> eventList = new ArrayList<>(); + + try { + // Check if its a single APEX event + if (!(eventObject instanceof ApexEvent)) { + throw new ApexEventException("incoming event (" + eventObject + ") is not an ApexEvent"); + } + + final ApexEvent event = (ApexEvent) eventObject; + + // Check whether we have any ApexEventList fields, if so this is an event of events and + // all fields should be of type ApexEventList + boolean foundEventListFields = false; + boolean foundOtherFields = false; + for (final Object fieldObject : event.values()) { + if (fieldObject instanceof ApexEventList) { + foundEventListFields = true; + + // Add the events to the event list + eventList.addAll((ApexEventList) fieldObject); + } else { + foundOtherFields = true; + } + } + + // If we found both event list fields and other fields we're in trouble + if (foundEventListFields && foundOtherFields) { + throw new ApexEventException("incoming event (" + eventObject + + ") has both event list fields and other fields, it cannot be processed"); + } + + // Check if the incoming event just has other fields, if so it's just a regular event + // and we add it to the event list as the only event there + if (foundOtherFields) { + eventList.add(event); + } + } catch (final Exception e) { + final String errorString = "Failed to unmarshal APEX event: " + e.getMessage() + ", event=" + eventObject; + LOGGER.warn(errorString, e); + throw new ApexEventException(errorString, e); + } + + // Return the list of events we have unmarshalled + return eventList; + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.ApexEventConverter#fromApexEvent(org.onap.policy. + * apex.service.engine.event.ApexEvent) + */ + @Override + public Object fromApexEvent(final ApexEvent apexEvent) throws ApexEventException { + // Check the Apex event + if (apexEvent == null) { + LOGGER.warn("event processing failed, Apex event is null"); + throw new ApexEventException("event processing failed, Apex event is null"); + } + + return apexEvent; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/apexprotocolplugin/ApexEventProtocolParameters.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/apexprotocolplugin/ApexEventProtocolParameters.java new file mode 100644 index 000000000..10cd58eb7 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/apexprotocolplugin/ApexEventProtocolParameters.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.apexprotocolplugin; + +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters; + +/** + * Event protocol parameters for JSON as an event protocol, there are no user defined parameters. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexEventProtocolParameters extends EventProtocolParameters { + /** The label of this event protocol. */ + public static final String APEX_EVENT_PROTOCOL_LABEL = "APEX"; + + /** + * Constructor to create a JSON event protocol parameter instance and register the instance with + * the parameter service. + */ + public ApexEventProtocolParameters() { + this(ApexEventProtocolParameters.class.getCanonicalName(), APEX_EVENT_PROTOCOL_LABEL); + } + + /** + * Constructor to create an event protocol parameters instance with the name of a sub class of + * this class. + * + * @param parameterClassName the class name of a sub class of this class + * @param eventProtocolLabel the name of the event protocol for this plugin + */ + public ApexEventProtocolParameters(final String parameterClassName, final String eventProtocolLabel) { + super(parameterClassName); + + // Set the event protocol properties for the JSON event protocol + this.setLabel(eventProtocolLabel); + + // Set the event protocol plugin class + this.setEventProtocolPluginClass(Apex2ApexEventConverter.class.getCanonicalName()); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/apexprotocolplugin/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/apexprotocolplugin/package-info.java new file mode 100644 index 000000000..a3c7d0d79 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/apexprotocolplugin/package-info.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Contains the implementation of the APEX event protocol converter plugin for events in Json + * format. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine.event.impl.apexprotocolplugin; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/enevent/ApexEvent2EnEventConverter.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/enevent/ApexEvent2EnEventConverter.java new file mode 100644 index 000000000..90a19fff2 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/enevent/ApexEvent2EnEventConverter.java @@ -0,0 +1,143 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.enevent; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.policy.apex.service.engine.event.ApexEvent; +import org.onap.policy.apex.service.engine.event.ApexEventConverter; +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +import org.onap.policy.apex.core.engine.engine.ApexEngine; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.service.ModelService; +import org.onap.policy.apex.model.eventmodel.concepts.AxEvent; +import org.onap.policy.apex.model.eventmodel.concepts.AxEvents; + +/** + * The Class ApexEvent2EnEventConverter converts externally facing {@link ApexEvent} instances to + * and from instances of {@link EnEvent} that are used internally in the Apex engine core. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public final class ApexEvent2EnEventConverter implements ApexEventConverter { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexEvent2EnEventConverter.class); + + // The Apex engine with its event definitions + private final ApexEngine apexEngine; + + /** + * Set up the event converter. + * + * @param apexEngine The engine to use to create events to be converted + */ + public ApexEvent2EnEventConverter(final ApexEngine apexEngine) { + this.apexEngine = apexEngine; + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.ApexEventConverter#toApexEvent(java.lang.String, + * java.lang.Object) + */ + @Override + public List<ApexEvent> toApexEvent(final String eventName, final Object event) throws ApexException { + // Check the Engine event + if (event == null) { + LOGGER.warn("event processing failed, engine event is null"); + throw new ApexEventException("event processing failed, engine event is null"); + } + + // Cast the event to an Engine event event, if our conversion is correctly configured, this + // cast should always work + EnEvent enEvent = null; + try { + enEvent = (EnEvent) event; + } catch (final Exception e) { + final String errorMessage = "error transferring event \"" + event + "\" to the Apex engine"; + LOGGER.debug(errorMessage, e); + throw new ApexEventRuntimeException(errorMessage, e); + } + + // Create the Apex event + final AxEvent axEvent = enEvent.getAxEvent(); + final ApexEvent apexEvent = new ApexEvent(axEvent.getKey().getName(), axEvent.getKey().getVersion(), + axEvent.getNameSpace(), axEvent.getSource(), axEvent.getTarget()); + + // Copy the ExecutionID from the EnEvent into the ApexEvent + apexEvent.setExecutionID(enEvent.getExecutionID()); + + // Copy he exception message to the Apex event if it is set + if (enEvent.getExceptionMessage() != null) { + apexEvent.setExceptionMessage(enEvent.getExceptionMessage()); + } + + // Set the data on the apex event + apexEvent.putAll(enEvent); + + // Return the event in a single element + final ArrayList<ApexEvent> eventList = new ArrayList<ApexEvent>(); + eventList.add(apexEvent); + return eventList; + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.ApexEventConverter#fromApexEvent(org.onap.policy. + * apex.service.engine.event.ApexEvent) + */ + @Override + public EnEvent fromApexEvent(final ApexEvent apexEvent) throws ApexException { + // Check the Apex model + if (apexEngine == null) { + LOGGER.warn("event processing failed, apex engine is null"); + throw new ApexEventException("event processing failed, apex engine is null"); + } + + // Get the event definition + final AxEvent eventDefinition = ModelService.getModel(AxEvents.class).get(apexEvent.getName()); + if (eventDefinition == null) { + LOGGER.warn("event processing failed, event \"" + apexEvent.getName() + "\" not found in apex model"); + throw new ApexEventException( + "event processing failed, event \"" + apexEvent.getName() + "\" not found in apex model"); + } + + // Create the internal engine event + final EnEvent enEvent = apexEngine.createEvent(eventDefinition.getKey()); + + // Set the data on the engine event + enEvent.putAll(apexEvent); + + // copy the ExecutionID from the ApexEvent into the EnEvent + enEvent.setExecutionID(apexEvent.getExecutionID()); + + return enEvent; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/enevent/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/enevent/package-info.java new file mode 100644 index 000000000..6bc6bc2b3 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/enevent/package-info.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Provides conversion between externally facing + * {@link org.onap.policy.apex.service.engine.event.ApexEvent} instances and internal + * {@link org.onap.policy.apex.core.engine.event.EnEvent} instances. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine.event.impl.enevent; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/eventrequestor/EventRequestorCarrierTechnologyParameters.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/eventrequestor/EventRequestorCarrierTechnologyParameters.java new file mode 100644 index 000000000..fb722ea2f --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/eventrequestor/EventRequestorCarrierTechnologyParameters.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.eventrequestor; + +import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters; + +/** + * This class holds the parameters that allows an output event to to be sent back into APEX as one + * or multiple input events, there are no user defined parameters. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class EventRequestorCarrierTechnologyParameters extends CarrierTechnologyParameters { + // @formatter:off + /** The label of this carrier technology. */ + public static final String EVENT_REQUESTOR_CARRIER_TECHNOLOGY_LABEL = "EVENT_REQUESTOR"; + + /** The producer plugin class for the EVENT_REQUESTOR carrier technology. */ + public static final String EVENT_REQUESTOR_EVENT_PRODUCER_PLUGIN_CLASS = + EventRequestorProducer.class.getCanonicalName(); + + /** The consumer plugin class for the EVENT_REQUESTOR carrier technology. */ + public static final String EVENT_REQUESTOR_EVENT_CONSUMER_PLUGIN_CLASS = + EventRequestorConsumer.class.getCanonicalName(); + // @formatter:on + + /** + * Constructor to create an event requestor carrier technology parameters instance and register + * the instance with the parameter service. + */ + public EventRequestorCarrierTechnologyParameters() { + super(EventRequestorCarrierTechnologyParameters.class.getCanonicalName()); + + // Set the carrier technology properties for the EVENT_REQUESTOR carrier technology + this.setLabel(EVENT_REQUESTOR_CARRIER_TECHNOLOGY_LABEL); + this.setEventProducerPluginClass(EVENT_REQUESTOR_EVENT_PRODUCER_PLUGIN_CLASS); + this.setEventConsumerPluginClass(EVENT_REQUESTOR_EVENT_CONSUMER_PLUGIN_CLASS); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.apps.uservice.parameters.ApexParameterValidator#validate() + */ + @Override + public String validate() { + return ""; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/eventrequestor/EventRequestorConsumer.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/eventrequestor/EventRequestorConsumer.java new file mode 100644 index 000000000..b472cc9c7 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/eventrequestor/EventRequestorConsumer.java @@ -0,0 +1,218 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.eventrequestor; + +import java.util.EnumMap; +import java.util.Map; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory; +import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities; +import org.onap.policy.apex.service.engine.event.ApexEventConsumer; +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.engine.event.ApexEventReceiver; +import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException; +import org.onap.policy.apex.service.engine.event.PeeredReference; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class implements an Apex event consumer that receives events from its peered event requestor + * producer. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class EventRequestorConsumer implements ApexEventConsumer, Runnable { + // Get a reference to the logger + private static final Logger LOGGER = LoggerFactory.getLogger(EventRequestorConsumer.class); + + // The amount of time to wait in milliseconds between checks that the consumer thread has + // stopped + private static final long EVENT_REQUESTOR_WAIT_SLEEP_TIME = 50; + + // The event receiver that will receive events from this consumer + private ApexEventReceiver eventReceiver; + + // The name for this consumer + private String name = null; + + // The peer references for this event handler + private final Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = + new EnumMap<>(EventHandlerPeeredMode.class); + + // Temporary request holder for incoming event send requests + private final BlockingQueue<Object> incomingEventRequestQueue = new LinkedBlockingQueue<>(); + + // The consumer thread and stopping flag + private Thread consumerThread; + private boolean stopOrderedFlag = false; + + // The number of events received to date + private int eventsReceived = 0; + + @Override + public void init(final String consumerName, final EventHandlerParameters consumerParameters, + final ApexEventReceiver incomingEventReceiver) throws ApexEventException { + this.eventReceiver = incomingEventReceiver; + this.name = consumerName; + + // Check and get the event requestor consumer properties + if (!(consumerParameters + .getCarrierTechnologyParameters() instanceof EventRequestorCarrierTechnologyParameters)) { + final String errorMessage = + "specified consumer properties are not applicable to event Requestor consumer (" + this.name + ")"; + LOGGER.warn(errorMessage); + throw new ApexEventException(errorMessage); + } + + // Check if we are in peered mode + if (!consumerParameters.isPeeredMode(EventHandlerPeeredMode.REQUESTOR)) { + final String errorMessage = "event Requestor consumer (" + this.name + + ") must run in peered requestor mode with a event Requestor producer"; + LOGGER.warn(errorMessage); + throw new ApexEventException(errorMessage); + } + + } + + /** + * Receive an incoming event send request from the peered event Requestor producer and queue it + * + * @param eventObject the incoming event to process + * @throws ApexEventRuntimeException on queueing errors + */ + public void processEvent(final Object eventObject) { + // Push the event onto the queue for handling + try { + incomingEventRequestQueue.add(eventObject); + } catch (final Exception e) { + final String errorMessage = + "could not queue request \"" + eventObject + "\" on event Requestor consumer (" + this.name + ")"; + LOGGER.warn(errorMessage); + throw new ApexEventRuntimeException(errorMessage); + } + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#start() + */ + @Override + public void start() { + // Configure and start the event reception thread + final String threadName = this.getClass().getName() + ":" + this.name; + consumerThread = new ApplicationThreadFactory(threadName).newThread(this); + consumerThread.setDaemon(true); + consumerThread.start(); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getName() + */ + @Override + public String getName() { + return name; + } + + /** + * Get the number of events received to date + * + * @return the number of events received + */ + public int getEventsReceived() { + return eventsReceived; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getPeeredReference(org.onap. + * policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode) + */ + @Override + public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) { + return peerReferenceMap.get(peeredMode); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#setPeeredReference(org.onap. + * policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode, + * org.onap.policy.apex.service.engine.event.PeeredReference) + */ + @Override + public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) { + peerReferenceMap.put(peeredMode, peeredReference); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + // The endless loop that receives events using REST calls + while (consumerThread.isAlive() && !stopOrderedFlag) { + try { + // Take the next event from the queue + final Object eventObject = + incomingEventRequestQueue.poll(EVENT_REQUESTOR_WAIT_SLEEP_TIME, TimeUnit.MILLISECONDS); + if (eventObject == null) { + // Poll timed out, wait again + continue; + } + + // Send the event into Apex + eventReceiver.receiveEvent(eventObject); + + eventsReceived++; + } catch (final InterruptedException e) { + LOGGER.debug("Thread interrupted, Reason {}", e.getMessage()); + Thread.currentThread().interrupt(); + } catch (final Exception e) { + LOGGER.warn("error receiving events on thread {}", consumerThread.getName(), e); + } + } + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.apps.uservice.producer.ApexEventConsumer#stop() + */ + @Override + public void stop() { + stopOrderedFlag = true; + + while (consumerThread.isAlive()) { + ThreadUtilities.sleep(EVENT_REQUESTOR_WAIT_SLEEP_TIME); + } + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/eventrequestor/EventRequestorProducer.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/eventrequestor/EventRequestorProducer.java new file mode 100644 index 000000000..4a972f2ce --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/eventrequestor/EventRequestorProducer.java @@ -0,0 +1,178 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.eventrequestor; + +import java.util.EnumMap; +import java.util.Map; + +import org.onap.policy.apex.service.engine.event.ApexEventConsumer; +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.engine.event.ApexEventProducer; +import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException; +import org.onap.policy.apex.service.engine.event.PeeredReference; +import org.onap.policy.apex.service.engine.event.SynchronousEventCache; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Concrete implementation of an Apex event producer that sends one or more events to its peered + * event requestor consumer. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + * + */ +public class EventRequestorProducer implements ApexEventProducer { + private static final Logger LOGGER = LoggerFactory.getLogger(EventRequestorProducer.class); + + // The name for this producer + private String name = null; + + // The peer references for this event handler + private final Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = + new EnumMap<>(EventHandlerPeeredMode.class); + + // The number of events sent + private int eventsSent = 0; + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#init(java.lang.String, + * org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters) + */ + @Override + public void init(final String producerName, final EventHandlerParameters producerParameters) + throws ApexEventException { + this.name = producerName; + + // Check and get the producer Properties + if (!(producerParameters + .getCarrierTechnologyParameters() instanceof EventRequestorCarrierTechnologyParameters)) { + final String errorMessage = + "specified consumer properties are not applicable to event requestor producer (" + this.name + ")"; + LOGGER.warn(errorMessage); + throw new ApexEventException(errorMessage); + } + + // Check if we are in peered mode + if (!producerParameters.isPeeredMode(EventHandlerPeeredMode.REQUESTOR)) { + final String errorMessage = "Event Requestor producer (" + this.name + + ") must run in peered requestor mode with a Event Requestor consumer"; + LOGGER.warn(errorMessage); + throw new ApexEventException(errorMessage); + } + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getName() + */ + @Override + public String getName() { + return name; + } + + /** + * Get the number of events sent to date + * + * @return the number of events received + */ + public int getEventsSent() { + return eventsSent; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getPeeredReference(org.onap. + * policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode) + */ + @Override + public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) { + return peerReferenceMap.get(peeredMode); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#setPeeredReference(org.onap. + * policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode, + * org.onap.policy.apex.service.engine.event.PeeredReference) + */ + @Override + public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) { + peerReferenceMap.put(peeredMode, peeredReference); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#sendEvent(long, java.lang. + * String, java.lang.Object) + */ + @Override + public void sendEvent(final long executionId, final String eventName, final Object eventObject) { + // Check if this is a synchronized event, if so we have received a reply + final SynchronousEventCache synchronousEventCache = + (SynchronousEventCache) peerReferenceMap.get(EventHandlerPeeredMode.SYNCHRONOUS); + if (synchronousEventCache != null) { + synchronousEventCache.removeCachedEventToApexIfExists(executionId); + } + + // Find the peered consumer for this producer + final PeeredReference peeredRequestorReference = peerReferenceMap.get(EventHandlerPeeredMode.REQUESTOR); + if (peeredRequestorReference != null) { + // Find the event Response Consumer that will handle this request + final ApexEventConsumer consumer = peeredRequestorReference.getPeeredConsumer(); + if (!(consumer instanceof EventRequestorConsumer)) { + final String errorMessage = "send of event to event consumer \"" + + peeredRequestorReference.getPeeredConsumer() + "\" failed," + + " event response consumer is not an instance of EventRequestorConsumer\n" + eventObject; + LOGGER.warn(errorMessage); + throw new ApexEventRuntimeException(errorMessage); + } + + // Use the consumer to handle this event + final EventRequestorConsumer eventRequstConsumer = (EventRequestorConsumer) consumer; + eventRequstConsumer.processEvent(eventObject); + + eventsSent++; + } else { + // No peered consumer defined + final String errorMessage = "send of event failed, event response consumer is not defined\n" + eventObject; + LOGGER.warn(errorMessage); + throw new ApexEventRuntimeException(errorMessage); + } + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#stop() + */ + @Override + public void stop() { + // For event requestor, all the implementation is in the consumer + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/eventrequestor/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/eventrequestor/package-info.java new file mode 100644 index 000000000..3b6da08a4 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/eventrequestor/package-info.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Implements the Event Requestor carrier technology for multiple event input from an output event. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine.event.impl.eventrequestor; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/FILECarrierTechnologyParameters.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/FILECarrierTechnologyParameters.java new file mode 100644 index 000000000..f7f25cb9e --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/FILECarrierTechnologyParameters.java @@ -0,0 +1,208 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.filecarrierplugin; + +import org.onap.policy.apex.model.utilities.ResourceUtils; +import org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer.ApexFileEventConsumer; +import org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.producer.ApexFileEventProducer; +import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters; + +/** + * This class holds the parameters that allows transport of events into and out of Apex using files + * and standard input and output. + * + * <p> + * The following parameters are defined: + * <ol> + * <li>fileName: The full path to the file from which to read events or to which to write events. + * <li>standardIO: If this flag is set to true, then standard input is used to read events in or + * standard output is used to write events and the fileName parameter is ignored if present + * <li>standardError: If this flag is set to true, then standard error is used to write events + * <li>streamingMode: If this flag is set to true, then streaming mode is set for reading events and + * event handling will wait on the input stream for events until the stream is closed. If streaming + * model is off, then event reading completes when the end of input is detected. + * <li>startDelay: The amount of milliseconds to wait at startup startup before processing the first + * event. + * </ol> + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class FILECarrierTechnologyParameters extends CarrierTechnologyParameters { + // @formatter:off + /** The label of this carrier technology. */ + public static final String FILE_CARRIER_TECHNOLOGY_LABEL = "FILE"; + + /** The producer plugin class for the FILE carrier technology. */ + public static final String FILE_EVENT_PRODUCER_PLUGIN_CLASS = ApexFileEventProducer.class.getCanonicalName(); + + /** The consumer plugin class for the FILE carrier technology. */ + public static final String FILE_EVENT_CONSUMER_PLUGIN_CLASS = ApexFileEventConsumer.class.getCanonicalName(); + + private String fileName; + private boolean standardIO = false; + private boolean standardError = false; + private boolean streamingMode = false; + private long startDelay = 0; + // @formatter:on + + /** + * Constructor to create a file carrier technology parameters instance and register the instance + * with the parameter service. + */ + public FILECarrierTechnologyParameters() { + super(FILECarrierTechnologyParameters.class.getCanonicalName()); + + // Set the carrier technology properties for the FILE carrier technology + this.setLabel(FILE_CARRIER_TECHNOLOGY_LABEL); + this.setEventProducerPluginClass(FILE_EVENT_PRODUCER_PLUGIN_CLASS); + this.setEventConsumerPluginClass(FILE_EVENT_CONSUMER_PLUGIN_CLASS); + } + + /** + * Gets the file name from which to read or to which to write events. + * + * @return the file name from which to read or to which to write events + */ + public String getFileName() { + return ResourceUtils.getFilePath4Resource(fileName); + } + + /** + * Checks if is standard IO should be used for input or output. + * + * @return true, if standard IO should be used for input or output + */ + public boolean isStandardIO() { + return standardIO; + } + + /** + * Checks if is standard error should be used for output. + * + * @return true, if standard error should be used for output + */ + public boolean isStandardError() { + return standardError; + } + + /** + * Checks if is streaming mode is on. + * + * @return true, if streaming mode is on + */ + public boolean isStreamingMode() { + return streamingMode; + } + + /** + * Sets the file name from which to read or to which to write events. + * + * @param fileName the file name from which to read or to which to write events + */ + public void setFileName(final String fileName) { + this.fileName = fileName; + } + + /** + * Sets if standard IO should be used for event input or output. + * + * @param standardIO if standard IO should be used for event input or output + */ + public void setStandardIO(final boolean standardIO) { + this.standardIO = standardIO; + } + + /** + * Sets if standard error should be used for event output. + * + * @param standardError if standard error should be used for event output + */ + public void setStandardError(final boolean standardError) { + this.standardError = standardError; + } + + /** + * Sets streaming mode. + * + * @param streamingMode the streaming mode value + */ + public void setStreamingMode(final boolean streamingMode) { + this.streamingMode = streamingMode; + } + + /** + * Gets the delay in milliseconds before the plugin starts processing + * + * @return the delay + */ + public long getStartDelay() { + return startDelay; + } + + /** + * Sets the delay in milliseconds before the plugin starts processing + * + * @param startDelay the delay + */ + public void setStartDelay(final long startDelay) { + this.startDelay = startDelay; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters# + * toString() + */ + @Override + public String toString() { + return "FILECarrierTechnologyParameters [fileName=" + fileName + ", standardIO=" + standardIO + + ", standardError=" + standardError + ", streamingMode=" + streamingMode + ", startDelay=" + startDelay + + "]"; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.apps.uservice.parameters.ApexParameterValidator#validate() + */ + @Override + public String validate() { + final StringBuilder errorMessageBuilder = new StringBuilder(); + + errorMessageBuilder.append(super.validate()); + + if (!standardIO && !standardError && (fileName == null || fileName.trim().length() == 0)) { + errorMessageBuilder.append( + " fileName not specified or is blank or null, it must be specified as a valid file location\n"); + } + + if (standardIO || standardError) { + streamingMode = true; + } + + if (startDelay < 0) { + errorMessageBuilder.append(" startDelay must be zero or a positive number of milliseconds\n"); + } + + return errorMessageBuilder.toString(); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/ApexFileEventConsumer.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/ApexFileEventConsumer.java new file mode 100644 index 000000000..7521c3a08 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/ApexFileEventConsumer.java @@ -0,0 +1,247 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.EnumMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; + +import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory; +import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities; +import org.onap.policy.apex.service.engine.event.ApexEventConsumer; +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.engine.event.ApexEventReceiver; +import org.onap.policy.apex.service.engine.event.PeeredReference; +import org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.FILECarrierTechnologyParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Concrete implementation an Apex event consumer that reads events from a file. This consumer also + * implements ApexEventProducer and therefore can be used as a synchronous consumer. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexFileEventConsumer implements ApexEventConsumer, Runnable { + + // Get a reference to the logger + private static final Logger LOGGER = LoggerFactory.getLogger(ApexFileEventConsumer.class); + + // The input stream to read events from + private InputStream eventInputStream; + + // The text block reader that will read text blocks from the contents of the file + private TextBlockReader textBlockReader; + + // The event receiver that will receive asynchronous events from this consumer + private ApexEventReceiver eventReceiver = null; + + // The consumer thread and stopping flag + private Thread consumerThread; + + // The name for this consumer + private String consumerName = null; + + // The specific carrier technology parameters for this consumer + private FILECarrierTechnologyParameters fileCarrierTechnologyParameters; + + // The peer references for this event handler + private final Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = + new EnumMap<>(EventHandlerPeeredMode.class); + + // Holds the next identifier for event execution. + private static AtomicLong nextExecutionID = new AtomicLong(0L); + + /** + * Private utility to get the next candidate value for a Execution ID. This value will always be + * unique in a single JVM + * + * @return the next candidate value for a Execution ID + */ + private static synchronized long getNextExecutionID() { + return nextExecutionID.getAndIncrement(); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.apps.uservice.consumer.ApexEventConsumer#init(org.onap.policy.apex.apps. + * uservice.consumer.ApexEventReceiver) + */ + @Override + public void init(final String name, final EventHandlerParameters consumerParameters, + final ApexEventReceiver incomingEventReceiver) throws ApexEventException { + this.eventReceiver = incomingEventReceiver; + this.consumerName = name; + + // Get and check the Apex parameters from the parameter service + if (consumerParameters == null) { + final String errorMessage = "Consumer parameters for ApexFileConsumer \"" + consumerName + "\" is null"; + LOGGER.warn(errorMessage); + throw new ApexEventException(errorMessage); + } + + // Check and get the file Properties + if (!(consumerParameters.getCarrierTechnologyParameters() instanceof FILECarrierTechnologyParameters)) { + final String errorMessage = "specified consumer properties for ApexFileConsumer \"" + consumerName + + "\" are not applicable to a File consumer"; + LOGGER.warn(errorMessage); + throw new ApexEventException(errorMessage); + } + fileCarrierTechnologyParameters = + (FILECarrierTechnologyParameters) consumerParameters.getCarrierTechnologyParameters(); + + // Open the file producing events + try { + if (fileCarrierTechnologyParameters.isStandardIO()) { + eventInputStream = System.in; + } else { + eventInputStream = new FileInputStream(fileCarrierTechnologyParameters.getFileName()); + } + + // Get an event composer for our event source + textBlockReader = new TextBlockReaderFactory().getTaggedReader(eventInputStream, + consumerParameters.getEventProtocolParameters()); + } catch (final IOException e) { + final String errorMessage = "ApexFileConsumer \"" + consumerName + "\" failed to open file for reading: \"" + + fileCarrierTechnologyParameters.getFileName() + "\""; + LOGGER.warn(errorMessage, e); + throw new ApexEventException(errorMessage, e); + } + + if (fileCarrierTechnologyParameters.getStartDelay() > 0) { + ThreadUtilities.sleep(fileCarrierTechnologyParameters.getStartDelay()); + } + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getName() + */ + @Override + public String getName() { + return consumerName; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getPeeredReference(org.onap. + * policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode) + */ + @Override + public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) { + return peerReferenceMap.get(peeredMode); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#setPeeredReference(org.onap. + * policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode, + * org.onap.policy.apex.service.engine.event.PeeredReference) + */ + @Override + public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) { + peerReferenceMap.put(peeredMode, peeredReference); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#start() + */ + @Override + public void start() { + // Configure and start the event reception thread + final String threadName = this.getClass().getName() + " : " + consumerName; + consumerThread = new ApplicationThreadFactory(threadName).newThread(this); + consumerThread.setDaemon(true); + consumerThread.start(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + // Check that we have been initialized in async or sync mode + if (eventReceiver == null) { + LOGGER.warn("\"{}\" has not been initilaized for either asynchronous or synchronous event handling", + consumerName); + return; + } + + // Read the events from the file while there are still events in the file + try { + // Read all the text blocks + TextBlock textBlock; + do { + // Read the text block + textBlock = textBlockReader.readTextBlock(); + + // Process the event from the text block if there is one there + if (textBlock.getText() != null) { + eventReceiver.receiveEvent(getNextExecutionID(), textBlock.getText()); + } + } while (!textBlock.isEndOfText()); + } catch (final Exception e) { + LOGGER.warn("\"" + consumerName + "\" failed to read event from file: \"" + + fileCarrierTechnologyParameters.getFileName() + "\"", e); + } finally { + try { + eventInputStream.close(); + } catch (final IOException e) { + LOGGER.warn("ApexFileConsumer \"" + consumerName + "\" failed to close file: \"" + + fileCarrierTechnologyParameters.getFileName() + "\"", e); + } + } + + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.apps.uservice.producer.ApexEventProducer#stop() + */ + @Override + public void stop() { + try { + eventInputStream.close(); + } catch (final IOException e) { + LOGGER.warn("ApexFileConsumer \"" + consumerName + "\" failed to close file for reading: \"" + + fileCarrierTechnologyParameters.getFileName() + "\"", e); + } + + if (consumerThread.isAlive() && !consumerThread.isInterrupted()) { + consumerThread.interrupt(); + } + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/CharacterDelimitedTextBlockReader.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/CharacterDelimitedTextBlockReader.java new file mode 100644 index 000000000..b286f8afe --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/CharacterDelimitedTextBlockReader.java @@ -0,0 +1,141 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer; + +import java.io.IOException; +import java.io.InputStream; + +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolTextCharDelimitedParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * The class CharacterDelimitedTextBlockReader reads the next block of text between two character + * tags from an input stream. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class CharacterDelimitedTextBlockReader implements TextBlockReader { + // The logger for this class + private static final XLogger LOGGER = XLoggerFactory.getXLogger(CharacterDelimitedTextBlockReader.class); + + // The character tags + private final char startTagChar; + private final char endTagChar; + + // The input stream for text + private InputStream inputStream; + + // Flag indicating we have seen EOF on the stream + private boolean eofOnInputStream = false; + + /** + * Constructor, set the delimiters. + * + * @param startTagChar The start tag for text blocks + * @param endTagChar The end tag for text blocks + */ + public CharacterDelimitedTextBlockReader(final char startTagChar, final char endTagChar) { + this.startTagChar = startTagChar; + this.endTagChar = endTagChar; + } + + /** + * Constructor, set the delimiters from a character delimited event protocol parameter class. + * + * @param charDelimitedParameters the character delimited event protocol parameter class + */ + public CharacterDelimitedTextBlockReader(final EventProtocolTextCharDelimitedParameters charDelimitedParameters) { + this.startTagChar = charDelimitedParameters.getStartChar(); + this.endTagChar = charDelimitedParameters.getEndChar(); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer.TextBlockReader#init( + * java.io.InputStream) + */ + @Override + public void init(final InputStream incomingInputStream) { + this.inputStream = incomingInputStream; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer.TextBlockReader# + * readTextBlock() + */ + @Override + public TextBlock readTextBlock() throws IOException { + // Check if there was a previous end of a text block with a non-empty text block returned + if (eofOnInputStream) { + return new TextBlock(eofOnInputStream, null); + } + + // The initial nesting level of incoming text blocks is always zero + int nestingLevel = 0; + + // Holder for the text block + final StringBuilder textBlockBuilder = new StringBuilder(); + + // Read the next text block + while (true) { + final char nextChar = (char) inputStream.read(); + + // Check for EOF + if (nextChar == (char) -1) { + eofOnInputStream = true; + break; + } + + if (nextChar == startTagChar) { + nestingLevel++; + } else if (nestingLevel == 0 && !Character.isWhitespace(nextChar)) { + LOGGER.warn("invalid input on consumer: " + nextChar); + continue; + } + + textBlockBuilder.append(nextChar); + + // Check for end of the text block, we have come back to level 0 + if (nextChar == endTagChar) { + if (nestingLevel > 0) { + nestingLevel--; + } + + if (nestingLevel == 0) { + break; + } + } + } + + // Condition the text block and return it + final String textBlock = textBlockBuilder.toString().trim(); + if (textBlock.length() > 0) { + return new TextBlock(eofOnInputStream, textBlock); + } else { + return new TextBlock(eofOnInputStream, null); + } + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/HeaderDelimitedTextBlockReader.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/HeaderDelimitedTextBlockReader.java new file mode 100644 index 000000000..e40bc756c --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/HeaderDelimitedTextBlockReader.java @@ -0,0 +1,167 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Queue; +import java.util.concurrent.LinkedBlockingQueue; + +import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory; +import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolTextTokenDelimitedParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * The Class TextBlockReader reads the next block of text from an input stream. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class HeaderDelimitedTextBlockReader implements TextBlockReader, Runnable { + // The logger for this class + private static final XLogger LOGGER = XLoggerFactory.getXLogger(HeaderDelimitedTextBlockReader.class); + + // The amount of time to wait for input on the text block reader + private static final long TEXT_BLOCK_DELAY = 250; + + // Tag for the start of a text block + private final String blockStartToken; + + // The input stream for text + private InputStream inputStream; + + // The lines of input read from the input stream + private final Queue<String> textLineQueue = new LinkedBlockingQueue<>(); + + // The thread used to read text from the input stream + private Thread textConsumputionThread; + + // True while EOF has not been seen on input + private boolean eofOnInputStream = false; + + /** + * Constructor, initialize the text block reader. + * + * @param blockStartToken the block start token for the start of a text block + */ + public HeaderDelimitedTextBlockReader(final String blockStartToken) { + this.blockStartToken = blockStartToken; + } + + /** + * Constructor, initialize the text block reader using token delimited event protocol + * parameters. + * + * @param tokenDelimitedParameters the token delimited event protocol parameters + */ + public HeaderDelimitedTextBlockReader(final EventProtocolTextTokenDelimitedParameters tokenDelimitedParameters) { + this.blockStartToken = tokenDelimitedParameters.getDelimiterToken(); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer.TextBlockReader# + * init( java.io.InputStream) + */ + @Override + public void init(final InputStream incomingInputStream) { + this.inputStream = incomingInputStream; + + // Configure and start the text reading thread + textConsumputionThread = new ApplicationThreadFactory(this.getClass().getName()).newThread(this); + textConsumputionThread.setDaemon(true); + textConsumputionThread.start(); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer.TextBlockReader# + * readTextBlock() + */ + @Override + public TextBlock readTextBlock() throws IOException { + // Holder for the current text block + final StringBuilder textBlockBuilder = new StringBuilder(); + + // Wait for the timeout period if there is no input + if (!eofOnInputStream && textLineQueue.size() == 0) { + ThreadUtilities.sleep(TEXT_BLOCK_DELAY); + } + + // Scan the lines in the queue + while (textLineQueue.size() > 0) { + // Scroll down in the available lines looking for the start of the text block + if (textLineQueue.peek().startsWith(blockStartToken)) { + // Process the input line header + textBlockBuilder.append(textLineQueue.remove()); + textBlockBuilder.append('\n'); + break; + } else { + LOGGER.warn("invalid input on consumer: " + textLineQueue.remove()); + } + } + + // Get the rest of the text document + while (textLineQueue.size() > 0 && !textLineQueue.peek().startsWith(blockStartToken)) { + textBlockBuilder.append(textLineQueue.remove()); + textBlockBuilder.append('\n'); + } + + // Condition the text block and return it + final String textBlock = textBlockBuilder.toString().trim(); + final boolean endOfText = (eofOnInputStream && textLineQueue.size() == 0 ? true : false); + + if (textBlock.length() > 0) { + return new TextBlock(endOfText, textBlock); + } else { + return new TextBlock(endOfText, null); + } + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + final BufferedReader textReader = new BufferedReader(new InputStreamReader(inputStream)); + + try { + // Read the input line by line until we see end of file on the stream + String line; + while ((line = textReader.readLine()) != null) { + textLineQueue.add(line); + } + } catch (final IOException e) { + LOGGER.warn("I/O exception on text input on consumer: ", e); + } finally { + eofOnInputStream = true; + } + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/TextBlock.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/TextBlock.java new file mode 100644 index 000000000..526d9c318 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/TextBlock.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer; + +/** + * This class is a bean that holds a block of text read from an incoming text file. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class TextBlock { + private boolean endOfText = false; + private String text; + + /** + * Constructor to initiate the text block. + * + * @param endOfText the end of text + * @param text the text + */ + public TextBlock(final boolean endOfText, final String text) { + this.endOfText = endOfText; + this.text = text; + } + + /** + * Checks if is end of text. + * + * @return true, if checks if is end of text + */ + public boolean isEndOfText() { + return endOfText; + } + + /** + * Sets whether end of text has been reached. + * + * @param endOfText the end of text flag value + */ + public void setEndOfText(final boolean endOfText) { + this.endOfText = endOfText; + } + + /** + * Gets the text of the text block. + * + * @return the text of the text block + */ + public String getText() { + return text; + } + + /** + * Sets the text of the text block. + * + * @param text the text of the text block + */ + public void setText(final String text) { + this.text = text; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/TextBlockReader.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/TextBlockReader.java new file mode 100644 index 000000000..627718402 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/TextBlockReader.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer; + +import java.io.IOException; +import java.io.InputStream; + +/** + * Implementers of the interface TextBlockReader read the next block of text from an input stream. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public interface TextBlockReader { + /** + * Initialize the text block reader reader. + * + * @param inputStream The stream to read from + */ + void init(InputStream inputStream); + + /** + * Read a block of text between two delimiters. + * + * @return The text block + * @throws IOException On reading errors + */ + TextBlock readTextBlock() throws IOException; +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/TextBlockReaderFactory.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/TextBlockReaderFactory.java new file mode 100644 index 000000000..e48266634 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/TextBlockReaderFactory.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer; + +import java.io.InputStream; + +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolTextCharDelimitedParameters; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolTextTokenDelimitedParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This factory creates text block readers for breaking character streams into blocks of text. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class TextBlockReaderFactory { + // The logger for this class + private static final XLogger LOGGER = XLoggerFactory.getXLogger(TextBlockReaderFactory.class); + + /** + * Get a text block reader for the given event protocol. + * + * @param inputStream the input stream that will be used for reading + * @param eventProtocolParameters the parameters that have been specified for event protocols + * @return the tagged reader + * @throws ApexEventException On an unsupported event protocol + */ + public TextBlockReader getTaggedReader(final InputStream inputStream, + final EventProtocolParameters eventProtocolParameters) throws ApexEventException { + // Check the type of event protocol we have + if (eventProtocolParameters instanceof EventProtocolTextCharDelimitedParameters) { + // We have character delimited textual input + final EventProtocolTextCharDelimitedParameters charDelimitedParameters = + (EventProtocolTextCharDelimitedParameters) eventProtocolParameters; + + // Create the text block reader + final TextBlockReader characterDelimitedTextBlockReader = + new CharacterDelimitedTextBlockReader(charDelimitedParameters); + characterDelimitedTextBlockReader.init(inputStream); + return characterDelimitedTextBlockReader; + } else if (eventProtocolParameters instanceof EventProtocolTextTokenDelimitedParameters) { + // We have token delimited textual input + final EventProtocolTextTokenDelimitedParameters tokenDelimitedParameters = + (EventProtocolTextTokenDelimitedParameters) eventProtocolParameters; + + // Create the text block reader + final HeaderDelimitedTextBlockReader headerDelimitedTextBlockReader = + new HeaderDelimitedTextBlockReader(tokenDelimitedParameters); + headerDelimitedTextBlockReader.init(inputStream); + return headerDelimitedTextBlockReader; + } else { + final String errorMessage = + "could not create text block reader for a textual event protocol, the required type " + + eventProtocolParameters.getLabel() + " is not supported"; + LOGGER.error(errorMessage); + throw new ApexEventException(errorMessage); + } + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/package-info.java new file mode 100644 index 000000000..05833ac7c --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/consumer/package-info.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Implements the FILE carrier technology consumer that sends events to APEX from files, standard IO + * or named pipes. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/package-info.java new file mode 100644 index 000000000..de0b1b56e --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/package-info.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Implements the FILE carrier technology for event input and output to and from Apex using files, + * named pipes, and standard IO. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine.event.impl.filecarrierplugin; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/producer/ApexFileEventProducer.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/producer/ApexFileEventProducer.java new file mode 100644 index 000000000..d5f9ff1b2 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/producer/ApexFileEventProducer.java @@ -0,0 +1,181 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.producer; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.EnumMap; +import java.util.Map; + +import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities; +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.engine.event.ApexEventProducer; +import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException; +import org.onap.policy.apex.service.engine.event.PeeredReference; +import org.onap.policy.apex.service.engine.event.SynchronousEventCache; +import org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.FILECarrierTechnologyParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Concrete implementation of an Apex event producer that sends events to a file. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexFileEventProducer implements ApexEventProducer { + // Get a reference to the logger + private static final Logger LOGGER = LoggerFactory.getLogger(ApexFileEventProducer.class); + + // The name for this producer + private String producerName = null; + + // The output stream to write events to + private PrintStream eventOutputStream; + + // The peer references for this event handler + private final Map<EventHandlerPeeredMode, PeeredReference> peerReferenceMap = + new EnumMap<>(EventHandlerPeeredMode.class); + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.apps.uservice.producer.ApexEventProducer#init() + */ + @Override + public void init(final String name, final EventHandlerParameters producerParameters) throws ApexEventException { + producerName = name; + + // Get and check the Apex parameters from the parameter service + if (producerParameters == null) { + final String errorMessage = "Producer parameters for ApexFileProducer \"" + producerName + "\" is null"; + LOGGER.warn(errorMessage); + throw new ApexEventException(errorMessage); + } + + // Check and get the file Properties + if (!(producerParameters.getCarrierTechnologyParameters() instanceof FILECarrierTechnologyParameters)) { + final String errorMessage = "specified producer properties for ApexFileProducer \"" + producerName + + "\" are not applicable to a FILE producer"; + LOGGER.warn(errorMessage); + throw new ApexEventException(errorMessage); + } + final FILECarrierTechnologyParameters fileCarrierTechnologyParameters = + (FILECarrierTechnologyParameters) producerParameters.getCarrierTechnologyParameters(); + + // Now we create a writer for events + try { + if (fileCarrierTechnologyParameters.isStandardError()) { + eventOutputStream = System.err; + } else if (fileCarrierTechnologyParameters.isStandardIO()) { + eventOutputStream = System.out; + } else { + eventOutputStream = + new PrintStream(new FileOutputStream(fileCarrierTechnologyParameters.getFileName()), true); + } + } catch (final IOException e) { + final String errorMessage = "ApexFileProducer \"" + producerName + "\" failed to open file for writing: \"" + + fileCarrierTechnologyParameters.getFileName() + "\""; + LOGGER.warn(errorMessage, e); + throw new ApexEventException(errorMessage, e); + } + + if (fileCarrierTechnologyParameters.getStartDelay() > 0) { + ThreadUtilities.sleep(fileCarrierTechnologyParameters.getStartDelay()); + } + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getName() + */ + @Override + public String getName() { + return producerName; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#getPeeredReference(org.onap. + * policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode) + */ + @Override + public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) { + return peerReferenceMap.get(peeredMode); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#setPeeredReference(org.onap. + * policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode, + * org.onap.policy.apex.service.engine.event.PeeredReference) + */ + @Override + public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) { + peerReferenceMap.put(peeredMode, peeredReference); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventProducer#sendEvent(long, + * java.lang.String, java.lang.Object) + */ + @Override + public void sendEvent(final long executionId, final String eventName, final Object event) { + // Check if this is a synchronized event, if so we have received a reply + final SynchronousEventCache synchronousEventCache = + (SynchronousEventCache) peerReferenceMap.get(EventHandlerPeeredMode.SYNCHRONOUS); + if (synchronousEventCache != null) { + synchronousEventCache.removeCachedEventToApexIfExists(executionId); + } + + // Cast the event to a string, if our conversion is correctly configured, this cast should + // always work + String stringEvent = null; + try { + stringEvent = (String) event; + } catch (final Exception e) { + final String errorMessage = "error in ApexFileProducer \"" + producerName + "\" while transferring event \"" + + event + "\" to the output stream"; + LOGGER.debug(errorMessage, e); + throw new ApexEventRuntimeException(errorMessage, e); + } + + eventOutputStream.println(stringEvent); + eventOutputStream.flush(); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.apps.uservice.producer.ApexEventProducer#stop() + */ + @Override + public void stop() { + eventOutputStream.close(); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/producer/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/producer/package-info.java new file mode 100644 index 000000000..f7d7cbfbd --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/filecarrierplugin/producer/package-info.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Implements the FILE carrier technology producer that outputs events from APEX to files, standard + * IO or named pipes. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.producer; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/jsonprotocolplugin/Apex2JSONEventConverter.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/jsonprotocolplugin/Apex2JSONEventConverter.java new file mode 100644 index 000000000..3b21a29ca --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/jsonprotocolplugin/Apex2JSONEventConverter.java @@ -0,0 +1,433 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.jsonprotocolplugin; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.policy.apex.context.SchemaHelper; +import org.onap.policy.apex.context.impl.schema.SchemaHelperFactory; +import org.onap.policy.apex.model.basicmodel.service.ModelService; +import org.onap.policy.apex.model.eventmodel.concepts.AxEvent; +import org.onap.policy.apex.model.eventmodel.concepts.AxEvents; +import org.onap.policy.apex.model.eventmodel.concepts.AxField; +import org.onap.policy.apex.service.engine.event.ApexEvent; +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.engine.event.ApexEventProtocolConverter; +import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +/** + * The Class Apex2JSONEventConverter converts {@link ApexEvent} instances to and from JSON string + * representations of Apex events. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class Apex2JSONEventConverter implements ApexEventProtocolConverter { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(Apex2JSONEventConverter.class); + + // The parameters for the JSON event protocol + private JSONEventProtocolParameters jsonPars; + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.ApexEventProtocolConverter#init(org.onap.policy. + * apex.service.parameters.eventprotocol.EventProtocolParameters) + */ + @Override + public void init(final EventProtocolParameters parameters) { + // Check and get the JSON parameters + if (!(parameters instanceof JSONEventProtocolParameters)) { + final String errorMessage = "specified consumer properties are not applicable to the JSON event protocol"; + LOGGER.warn(errorMessage); + throw new ApexEventRuntimeException(errorMessage); + } + + jsonPars = (JSONEventProtocolParameters) parameters; + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.ApexEventConverter#toApexEvent(java.lang.String, + * java.lang.Object) + */ + @Override + public List<ApexEvent> toApexEvent(final String eventName, final Object eventObject) throws ApexEventException { + // Check the event eventObject + if (eventObject == null) { + LOGGER.warn("event processing failed, event is null"); + throw new ApexEventException("event processing failed, event is null"); + } + + // Cast the event to a string, if our conversion is correctly configured, this cast should + // always work + String jsonEventString = null; + try { + jsonEventString = (String) eventObject; + } catch (final Exception e) { + final String errorMessage = "error converting event \"" + eventObject + "\" to a string"; + LOGGER.debug(errorMessage, e); + throw new ApexEventRuntimeException(errorMessage, e); + } + + // The list of events we will return + final List<ApexEvent> eventList = new ArrayList<ApexEvent>(); + + try { + // We may have a single JSON object with a single event or an array of JSON objects + final Object decodedJsonObject = + new GsonBuilder().serializeNulls().create().fromJson(jsonEventString, Object.class); + + // Check if we have a list of objects + if (decodedJsonObject instanceof List) { + // Check if it's a list of JSON objects or a list of strings + @SuppressWarnings("unchecked") + final List<Object> decodedJsonList = (List<Object>) decodedJsonObject; + + // Decode each of the list elements in sequence + for (final Object jsonListObject : decodedJsonList) { + if (jsonListObject instanceof String) { + eventList.add(jsonStringApexEvent(eventName, (String) jsonListObject)); + } else if (jsonListObject instanceof JsonObject) { + eventList.add(jsonObject2ApexEvent(eventName, (JsonObject) jsonListObject)); + } else { + throw new ApexEventException("incoming event (" + jsonEventString + + ") is a JSON object array containing an invalid object " + jsonListObject); + } + } + } else { + eventList.add(jsonStringApexEvent(eventName, jsonEventString)); + } + } catch (final Exception e) { + final String errorString = + "Failed to unmarshal JSON event: " + e.getMessage() + ", event=" + jsonEventString; + LOGGER.warn(errorString, e); + throw new ApexEventException(errorString, e); + } + + // Return the list of events we have unmarshalled + return eventList; + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.ApexEventConverter#fromApexEvent(org.onap.policy. + * apex.service.engine.event.ApexEvent) + */ + @Override + public Object fromApexEvent(final ApexEvent apexEvent) throws ApexEventException { + // Check the Apex event + if (apexEvent == null) { + LOGGER.warn("event processing failed, Apex event is null"); + throw new ApexEventException("event processing failed, Apex event is null"); + } + + // Get the event definition for the event from the model service + final AxEvent eventDefinition = + ModelService.getModel(AxEvents.class).get(apexEvent.getName(), apexEvent.getVersion()); + + // Use a GSON Json object to marshal the Apex event to JSON + final Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create(); + final JsonObject jsonObject = new JsonObject(); + + jsonObject.addProperty(ApexEvent.NAME_HEADER_FIELD, apexEvent.getName()); + jsonObject.addProperty(ApexEvent.VERSION_HEADER_FIELD, apexEvent.getVersion()); + jsonObject.addProperty(ApexEvent.NAMESPACE_HEADER_FIELD, apexEvent.getNameSpace()); + jsonObject.addProperty(ApexEvent.SOURCE_HEADER_FIELD, apexEvent.getSource()); + jsonObject.addProperty(ApexEvent.TARGET_HEADER_FIELD, apexEvent.getTarget()); + + if (apexEvent.getExceptionMessage() != null) { + jsonObject.addProperty(ApexEvent.EXCEPTION_MESSAGE_HEADER_FIELD, apexEvent.getExceptionMessage()); + } + + for (final AxField eventField : eventDefinition.getFields()) { + final String fieldName = eventField.getKey().getLocalName(); + + if (!apexEvent.containsKey(fieldName)) { + if (!eventField.getOptional()) { + final String errorMessage = "error parsing " + eventDefinition.getID() + " event to Json. " + + "Field \"" + fieldName + "\" is missing, but is mandatory. Fields: " + apexEvent; + LOGGER.debug(errorMessage); + throw new ApexEventRuntimeException(errorMessage); + } + continue; + } + + final Object fieldValue = apexEvent.get(fieldName); + + // Get the schema helper + final SchemaHelper fieldSchemaHelper = + new SchemaHelperFactory().createSchemaHelper(eventField.getKey(), eventField.getSchema()); + jsonObject.add(fieldName, fieldSchemaHelper.marshal2JsonElement(fieldValue)); + } + + // Output JSON string in a pretty format + return gson.toJson(jsonObject); + } + + /** + * This method converts a JSON object into an Apex event. + * + * @param eventName the name of the event + * @param jsonEventString the JSON string that holds the event + * @return the apex event that we have converted the JSON object into + * @throws ApexEventException thrown on unmarshaling exceptions + */ + private ApexEvent jsonStringApexEvent(final String eventName, final String jsonEventString) + throws ApexEventException { + // Use GSON to read the event string + final JsonObject jsonObject = + new GsonBuilder().serializeNulls().create().fromJson(jsonEventString, JsonObject.class); + + if (jsonObject == null || !jsonObject.isJsonObject()) { + throw new ApexEventException( + "incoming event (" + jsonEventString + ") is not a JSON object or an JSON object array"); + } + + return jsonObject2ApexEvent(eventName, jsonObject); + } + + /** + * This method converts a JSON object into an Apex event. + * + * @param eventName the name of the event + * @param jsonObject the JSON object that holds the event + * @return the apex event that we have converted the JSON object into + * @throws ApexEventException thrown on unmarshaling exceptions + */ + private ApexEvent jsonObject2ApexEvent(final String eventName, final JsonObject jsonObject) + throws ApexEventException { + // Process the mandatory Apex header + final ApexEvent apexEvent = processApexEventHeader(eventName, jsonObject); + + // Get the event definition for the event from the model service + final AxEvent eventDefinition = + ModelService.getModel(AxEvents.class).get(apexEvent.getName(), apexEvent.getVersion()); + + // Iterate over the input fields in the event + for (final AxField eventField : eventDefinition.getFields()) { + final String fieldName = eventField.getKey().getLocalName(); + if (!hasJSONField(jsonObject, fieldName)) { + if (!eventField.getOptional()) { + final String errorMessage = "error parsing " + eventDefinition.getID() + " event from Json. " + + "Field \"" + fieldName + "\" is missing, but is mandatory."; + LOGGER.debug(errorMessage); + throw new ApexEventException(errorMessage); + } + continue; + } + + final JsonElement fieldValue = getJSONField(jsonObject, fieldName, null, !eventField.getOptional()); + + if (fieldValue != null && !fieldValue.isJsonNull()) { + // Get the schema helper + final SchemaHelper fieldSchemaHelper = + new SchemaHelperFactory().createSchemaHelper(eventField.getKey(), eventField.getSchema()); + apexEvent.put(fieldName, fieldSchemaHelper.createNewInstance(fieldValue)); + } else { + apexEvent.put(fieldName, null); + } + } + return apexEvent; + + } + + /** + * This method processes the event header of an Apex event. + * + * @param eventName the name of the event + * @param jsonObject the JSON object containing the JSON representation of the incoming event + * @return an apex event constructed using the header fields of the event + * @throws ApexEventRuntimeException the apex event runtime exception + * @throws ApexEventException on invalid events with missing header fields + */ + private ApexEvent processApexEventHeader(final String eventName, final JsonObject jsonObject) + throws ApexEventRuntimeException, ApexEventException { + // Get the event header fields + // @formatter:off + String name = getJSONStringField(jsonObject, ApexEvent.NAME_HEADER_FIELD, jsonPars.getNameAlias(), ApexEvent.NAME_REGEXP, false); + String version = getJSONStringField(jsonObject, ApexEvent.VERSION_HEADER_FIELD, jsonPars.getVersionAlias(), ApexEvent.VERSION_REGEXP, false); + String namespace = getJSONStringField(jsonObject, ApexEvent.NAMESPACE_HEADER_FIELD, jsonPars.getNameSpaceAlias(), ApexEvent.NAMESPACE_REGEXP, false); + String source = getJSONStringField(jsonObject, ApexEvent.SOURCE_HEADER_FIELD, jsonPars.getSourceAlias(), ApexEvent.SOURCE_REGEXP, false); + String target = getJSONStringField(jsonObject, ApexEvent.TARGET_HEADER_FIELD, jsonPars.getTargetAlias(), ApexEvent.TARGET_REGEXP, false); + // @formatter:on + + // Check if an event name was specified on the event parameters + if (eventName != null) { + if (name != null && !eventName.equals(name)) { + LOGGER.warn("The incoming event name \"" + name + "\" does not match the configured event name \"" + + eventName + "\", using configured event name"); + } + name = eventName; + } else { + if (name == null) { + throw new ApexEventRuntimeException( + "event received without mandatory parameter \"name\" on configuration or on event"); + } + } + + // Now, find the event definition in the model service. If version is null, the newest event + // definition in the model service is used + final AxEvent eventDefinition = ModelService.getModel(AxEvents.class).get(name, version); + if (eventDefinition == null) { + if (version == null) { + throw new ApexEventRuntimeException( + "an event definition for an event named \"" + name + "\" not found in Apex model"); + } else { + throw new ApexEventRuntimeException("an event definition for an event named \"" + name + + "\" with version \"" + version + "\" not found in Apex model"); + } + } + + // Use the defined event version if no version is specified on the incoming fields + if (version == null) { + version = eventDefinition.getKey().getVersion(); + } + + // Check the name space is OK if it is defined, if not, use the name space from the model + if (namespace != null) { + if (!namespace.equals(eventDefinition.getNameSpace())) { + throw new ApexEventRuntimeException( + "namespace \"" + namespace + "\" on event \"" + name + "\" does not match namespace \"" + + eventDefinition.getNameSpace() + "\" for that event in the Apex model"); + } + } else { + namespace = eventDefinition.getNameSpace(); + } + + // For source, use the defined source only if the source is not found on the incoming event + if (source == null) { + source = eventDefinition.getSource(); + } + + // For target, use the defined source only if the source is not found on the incoming event + if (target == null) { + target = eventDefinition.getTarget(); + } + + return new ApexEvent(name, version, namespace, source, target); + } + + /** + * This method gets an event string field from a JSON object. + * + * @param jsonObject the JSON object containing the JSON representation of the incoming event + * @param fieldName the field name to find in the event + * @param fieldAlias the alias for the field to find in the event, overrides the field name if + * it is not null + * @param fieldRE the regular expression to check the field against for validity + * @param mandatory true if the field is mandatory + * @return the value of the field in the JSON object or null if the field is optional + * @throws ApexEventRuntimeException the apex event runtime exception + */ + private String getJSONStringField(final JsonObject jsonObject, final String fieldName, final String fieldAlias, + final String fieldRE, final boolean mandatory) throws ApexEventRuntimeException { + // Get the JSON field for the string field + final JsonElement jsonField = getJSONField(jsonObject, fieldName, fieldAlias, mandatory); + + // Null strings are allowed + if (jsonField == null || jsonField.isJsonNull()) { + return null; + } + + // Check if this is a string field + String fieldValueString = null; + try { + fieldValueString = jsonField.getAsString(); + } catch (final Exception e) { + // The element is not a string so throw an error + throw new ApexEventRuntimeException("field \"" + fieldName + "\" with type \"" + + jsonField.getClass().getCanonicalName() + "\" is not a string value"); + } + + // Is regular expression checking required + if (fieldRE == null) { + return fieldValueString; + } + + // Check the event field against its regular expression + if (!fieldValueString.matches(fieldRE)) { + throw new ApexEventRuntimeException( + "field \"" + fieldName + "\" with value \"" + fieldValueString + "\" is invalid"); + } + + return fieldValueString; + } + + /** + * This method gets an event field from a JSON object. + * + * @param jsonObject the JSON object containing the JSON representation of the incoming event + * @param fieldName the field name to find in the event + * @param fieldAlias the alias for the field to find in the event, overrides the field name if + * it is not null + * @param mandatory true if the field is mandatory + * @return the value of the field in the JSON object or null if the field is optional + * @throws ApexEventRuntimeException the apex event runtime exception + */ + private JsonElement getJSONField(final JsonObject jsonObject, final String fieldName, final String fieldAlias, + final boolean mandatory) throws ApexEventRuntimeException { + + // Check if we should use the alias for this field + String fieldToFind = fieldName; + if (fieldAlias != null) { + fieldToFind = fieldAlias; + } + + // Get the event field + final JsonElement eventElement = jsonObject.get(fieldToFind); + if (eventElement == null) { + if (!mandatory) { + return null; + } else { + throw new ApexEventRuntimeException("mandatory field \"" + fieldToFind + "\" is missing"); + } + } + + return eventElement; + } + + /** + * This method if a JSON object has a named field. + * + * @param jsonObject the JSON object containing the JSON representation of the incoming event + * @param fieldName the field name to find in the event + * @return true if the field is present + * @throws ApexEventRuntimeException the apex event runtime exception + */ + private boolean hasJSONField(final JsonObject jsonObject, final String fieldName) throws ApexEventRuntimeException { + // check for the field + return jsonObject.has(fieldName); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/jsonprotocolplugin/JSONEventProtocolParameters.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/jsonprotocolplugin/JSONEventProtocolParameters.java new file mode 100644 index 000000000..b4a4055d7 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/jsonprotocolplugin/JSONEventProtocolParameters.java @@ -0,0 +1,135 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event.impl.jsonprotocolplugin; + +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolTextCharDelimitedParameters; + +/** + * Event protocol parameters for JSON as an event protocol. + * + * The parameters for this plugin are: + * <ol> + * <li>nameAlias: The field in a JSON event to use as an alias for the event name. This parameter is + * optional. + * <li>versionAlias: The field in a JSON event to use as an alias for the event version. This + * parameter is optional. + * <li>nameSpaceAlias: The field in a JSON event to use as an alias for the event name space. This + * parameter is optional. + * <li>sourceAlias: The field in a JSON event to use as an alias for the event source. This + * parameter is optional. + * <li>targetAlias: The field in a JSON event to use as an alias for the event target. This + * parameter is optional. + * </ol> + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class JSONEventProtocolParameters extends EventProtocolTextCharDelimitedParameters { + /** The label of this event protocol. */ + public static final String JSON_EVENT_PROTOCOL_LABEL = "JSON"; + + // Constants for text block delimiters + private static final char JSON_TEXT_BLOCK_START_DELIMITER = '{'; + private static final char JSON_TEXT_BLOCK_END_DELIMITER = '}'; + + // Aliases for Apex event header fields + // @formatter:off + private final String nameAlias = null; + private final String versionAlias = null; + private final String nameSpaceAlias = null; + private final String sourceAlias = null; + private final String targetAlias = null; + // @formatter:on + + /** + * Constructor to create a JSON event protocol parameter instance and register the instance with + * the parameter service. + */ + public JSONEventProtocolParameters() { + this(JSONEventProtocolParameters.class.getCanonicalName(), JSON_EVENT_PROTOCOL_LABEL); + } + + /** + * Constructor to create an event protocol parameters instance with the name of a sub class of + * this class. + * + * @param parameterClassName the class name of a sub class of this class + * @param eventProtocolLabel the name of the event protocol for this plugin + */ + public JSONEventProtocolParameters(final String parameterClassName, final String eventProtocolLabel) { + super(parameterClassName); + + // Set the event protocol properties for the JSON event protocol + this.setLabel(eventProtocolLabel); + + // Set the starting and ending delimiters for text blocks of JSON events + this.setStartChar(JSON_TEXT_BLOCK_START_DELIMITER); + this.setEndChar(JSON_TEXT_BLOCK_END_DELIMITER); + + // Set the event protocol plugin class + this.setEventProtocolPluginClass(Apex2JSONEventConverter.class.getCanonicalName()); + } + + /** + * Gets the name alias. + * + * @return the name alias + */ + public String getNameAlias() { + return nameAlias; + } + + /** + * Gets the version alias. + * + * @return the version alias + */ + public String getVersionAlias() { + return versionAlias; + } + + /** + * Gets the name space alias. + * + * @return the name space alias + */ + public String getNameSpaceAlias() { + return nameSpaceAlias; + } + + /** + * Gets the source alias. + * + * @return the source alias + */ + public String getSourceAlias() { + return sourceAlias; + } + + /** + * Gets the target alias. + * + * @return the target alias + */ + public String getTargetAlias() { + return targetAlias; + } + +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/jsonprotocolplugin/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/jsonprotocolplugin/package-info.java new file mode 100644 index 000000000..65f4831ec --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/jsonprotocolplugin/package-info.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Contains the implementation of the APEX event protocol cinverter plugin for events in Json + * format. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine.event.impl.jsonprotocolplugin; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/package-info.java new file mode 100644 index 000000000..ae2d58701 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/impl/package-info.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Contains implementations for conversion between externally facing + * {@link org.onap.policy.apex.service.engine.event.ApexEvent} instances and internal APEX engine + * {@link org.onap.policy.apex.core.engine.event.EnEvent} instances. It also contains the + * implementation of the default APEX File carrier technology plugin as well as the protocol plugins + * for XML and JSON event protocols. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine.event.impl; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/package-info.java new file mode 100644 index 000000000..75404137e --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/event/package-info.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Provides a generic externally-facing {@link ApexEvent} class that can be sent into an APEX engine + * and processed by an APEX engine. It provides the producer {@link ApexEventProducer} producer and + * {@link ApexEventConsumer} consumer interfaces that APEX uses to send events to and receive events + * from other systems. It also provides the {@link ApexEventConverter} interface that can be + * implemented by plugins that wish to convert some external event format into the APEX event + * format. It also provides a periodic event generator that can be used to send periodic events into + * an APEX engine for triggering of policies to carry out housekeeping tasks. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine.event; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexActivator.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexActivator.java new file mode 100644 index 000000000..20af31496 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexActivator.java @@ -0,0 +1,193 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.main; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.utilities.TextFileUtils; +import org.onap.policy.apex.service.engine.engdep.EngDepMessagingService; +import org.onap.policy.apex.service.engine.runtime.EngineService; +import org.onap.policy.apex.service.engine.runtime.impl.EngineServiceImpl; +import org.onap.policy.apex.service.parameters.ApexParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This class wraps an Apex engine so that it can be activated as a complete service together with + * all its context, executor, and event plugins. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexActivator { + // The logger for this class + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexActivator.class); + + // The parameters of this Apex activator + private final ApexParameters apexParameters; + + // Event unmarshalers are used to receive events asynchronously into Apex + private final Map<String, ApexEventUnmarshaller> unmarshallerMap = new LinkedHashMap<>(); + + // Event marshalers are used to send events asynchronously from Apex + private final Map<String, ApexEventMarshaller> marshallerMap = new LinkedHashMap<>(); + + // The engine service handler holds the references to the engine and its EngDep deployment + // interface. It also acts as a receiver for asynchronous + // and synchronous events from the engine. + private ApexEngineServiceHandler engineServiceHandler = null; + + /** + * Instantiate the activator for the Apex engine as a complete service. + * + * @param parameters the apex parameters for the Apex service + */ + public ApexActivator(final ApexParameters parameters) { + apexParameters = parameters; + } + + /** + * Initialize the Apex engine as a complete service. + * + * @throws ApexActivatorException on errors in initializing the engine + */ + public void initialize() throws ApexActivatorException { + LOGGER.debug("Apex engine starting as a service . . ."); + + try { + // Create engine with specified thread count + LOGGER.debug("starting apex engine service . . ."); + final EngineService apexEngineService = + EngineServiceImpl.create(apexParameters.getEngineServiceParameters()); + + // Instantiate and start the messaging service for Deployment + LOGGER.debug("starting apex deployment service . . ."); + final EngDepMessagingService engDepService = new EngDepMessagingService(apexEngineService, + apexParameters.getEngineServiceParameters().getDeploymentPort()); + engDepService.start(); + + // Create the engine holder to hold the engine's references and act as an event receiver + engineServiceHandler = new ApexEngineServiceHandler(apexEngineService, engDepService); + + // Check if a policy model file has been specified + if (apexParameters.getEngineServiceParameters().getPolicyModelFileName() != null) { + LOGGER.debug("deploying policy model in \"" + + apexParameters.getEngineServiceParameters().getPolicyModelFileName() + + "\" to the apex engines . . ."); + + // Set the policy model in the engine + final String policyModelString = TextFileUtils + .getTextFileAsString(apexParameters.getEngineServiceParameters().getPolicyModelFileName()); + apexEngineService.updateModel(apexParameters.getEngineServiceParameters().getEngineKey(), + policyModelString, true); + apexEngineService.startAll(); + } + + // Producer parameters specify what event marshalers to handle events leaving Apex are + // set up and how they are set up + for (final Entry<String, EventHandlerParameters> outputParameters : apexParameters + .getEventOutputParameters().entrySet()) { + final ApexEventMarshaller marshaller = new ApexEventMarshaller(outputParameters.getKey(), + apexParameters.getEngineServiceParameters(), outputParameters.getValue()); + marshaller.init(); + apexEngineService.registerActionListener(outputParameters.getKey(), marshaller); + marshallerMap.put(outputParameters.getKey(), marshaller); + } + + // Consumer parameters specify what event unmarshalers to handle events coming into Apex + // are set up and how they are set up + for (final Entry<String, EventHandlerParameters> inputParameters : apexParameters.getEventInputParameters() + .entrySet()) { + final ApexEventUnmarshaller unmarshaller = new ApexEventUnmarshaller(inputParameters.getKey(), + apexParameters.getEngineServiceParameters(), inputParameters.getValue()); + unmarshallerMap.put(inputParameters.getKey(), unmarshaller); + unmarshaller.init(engineServiceHandler); + } + + // Set up unmarshaler/marshaler pairing for synchronized event handling. We only need to + // traverse the unmarshalers because the + // unmarshalers and marshalers are paired one to one uniquely so if we find a + // synchronized unmarshaler we'll also find its + // paired marshaler + for (final Entry<String, EventHandlerParameters> inputParameters : apexParameters.getEventInputParameters() + .entrySet()) { + final ApexEventUnmarshaller unmarshaller = unmarshallerMap.get(inputParameters.getKey()); + + // Pair up peered unmarshalers and marshalers + for (final EventHandlerPeeredMode peeredMode : EventHandlerPeeredMode.values()) { + // Check if the unmarshaler is synchronized with a marshaler + if (inputParameters.getValue().isPeeredMode(peeredMode)) { + // Find the unmarshaler and marshaler + final ApexEventMarshaller peeredMarshaler = + marshallerMap.get(inputParameters.getValue().getPeer(peeredMode)); + + // Connect the unmarshaler and marshaler + unmarshaller.connectMarshaler(peeredMode, peeredMarshaler); + } + } + // Now let's get events flowing + unmarshaller.start(); + } + } catch (final Exception e) { + LOGGER.debug("Apex engine failed to start as a service", e); + throw new ApexActivatorException("Apex engine failed to start as a service", e); + } + + LOGGER.debug("Apex engine started as a service"); + } + + /** + * Terminate the Apex engine. + * + * @throws ApexException on termination errors + */ + public void terminate() throws ApexException { + // Shut down all marshalers and unmarshalers + for (final ApexEventMarshaller marshaller : marshallerMap.values()) { + marshaller.stop(); + } + marshallerMap.clear(); + + for (final ApexEventUnmarshaller unmarshaller : unmarshallerMap.values()) { + unmarshaller.stop(); + } + unmarshallerMap.clear(); + + // Check if the engine service handler has been shut down already + if (engineServiceHandler != null) { + engineServiceHandler.terminate(); + engineServiceHandler = null; + } + } + + /** + * Get the parameters used by the adapter. + * + * @return the parameters of the adapter + */ + public ApexParameters getApexParameters() { + return apexParameters; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexActivatorException.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexActivatorException.java new file mode 100644 index 000000000..371a3a882 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexActivatorException.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.main; + +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; + +/** + * This exception will be called if an error occurs when running Apex as a complete service. + * + * @author Liam Fallon + */ +public class ApexActivatorException extends ApexException { + private static final long serialVersionUID = -8507246953751956974L; + + /** + * Instantiates a new apex activator exception with a message. + * + * @param message the message + */ + public ApexActivatorException(final String message) { + super(message); + } + + /** + * Instantiates a new apex activator exception with a message and a caused by exception. + * + * @param message the message + * @param e the exception that caused this exception to be thrown + */ + public ApexActivatorException(final String message, final Exception e) { + super(message, e); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexActivatorRuntimeException.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexActivatorRuntimeException.java new file mode 100644 index 000000000..cf1842dbe --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexActivatorRuntimeException.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.main; + +import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException; + +/** + * This runtime exception will be called if a runtime error occurs when running Apex as a complete + * service. + * + * @author Liam Fallon + */ +public class ApexActivatorRuntimeException extends ApexRuntimeException { + private static final long serialVersionUID = -8507246953751956974L; + + /** + * Instantiates a new apex activator exception with a message. + * + * @param message the message + */ + public ApexActivatorRuntimeException(final String message) { + super(message); + } + + /** + * Instantiates a new apex activator exception with a message and a caused by exception. + * + * @param message the message + * @param e the exception that caused this exception to be thrown + */ + public ApexActivatorRuntimeException(final String message, final Exception e) { + super(message, e); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexCommandLineArguments.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexCommandLineArguments.java new file mode 100644 index 000000000..02dc248b4 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexCommandLineArguments.java @@ -0,0 +1,285 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.main; + +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.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException; +import org.onap.policy.apex.model.utilities.ResourceUtils; + +/** + * This class reads and handles command line parameters for the Apex main program. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexCommandLineArguments { + private static final int HELP_LINE_LENGTH = 120; + + // Apache Commons CLI options + private final Options options; + + // The command line options + private String modelFilePath = null; + private String configurationFilePath = null; + + /** + * Construct the options for the CLI editor. + */ + public ApexCommandLineArguments() { + //@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 Apex") + .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 Apex configuration parameters") + .hasArg() + .argName("CONFIG_FILE") + .required(false) + .type(String.class) + .build()); + options.addOption(Option.builder("m").longOpt("model-file") + .desc("the full path to the model file to use, if set it overrides the model file set in the configuration file").hasArg().argName("MODEL_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 ApexCommandLineArguments(final String[] args) { + // Set up the options with the default constructor + this(); + + // Parse the arguments + try { + parse(args); + } catch (final ApexException e) { + throw new ApexRuntimeException("parse error on Apex parameters"); + } + } + + /** + * 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 ApexException on command argument errors + */ + public String parse(final String[] args) throws ApexException { + // Clear all our arguments + setConfigurationFilePath(null); + setModelFilePath(null); + + CommandLine commandLine = null; + try { + commandLine = new DefaultParser().parse(options, args); + } catch (final ParseException e) { + throw new ApexException("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 > 1) { + throw new ApexException("too many command line arguments specified : " + Arrays.toString(args)); + } + + if (remainingArgs.length == 1) { + configurationFilePath = remainingArgs[0]; + } + + if (commandLine.hasOption('h')) { + return help(ApexMain.class.getCanonicalName()); + } + + if (commandLine.hasOption('v')) { + return version(); + } + + if (commandLine.hasOption('c')) { + setConfigurationFilePath(commandLine.getOptionValue('c')); + } + + if (commandLine.hasOption('m')) { + setModelFilePath(commandLine.getOptionValue('m')); + } + + return null; + } + + /** + * Validate the command line options. + * + * @throws ApexException on command argument validation errors + */ + public void validate() throws ApexException { + validateReadableFile("Apex configuration", configurationFilePath); + + if (checkSetModelFilePath()) { + validateReadableFile("Apex model", modelFilePath); + } + } + + /** + * Print version information for Apex. + * + * @return the version string + */ + public String version() { + return ResourceUtils.getResourceAsString("version.txt"); + } + + /** + * Print help information for Apex. + * + * @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 stringPW = new PrintWriter(stringWriter); + + helpFormatter.printHelp(stringPW, HELP_LINE_LENGTH, mainClassName + " [options...]", "options", options, 0, 0, + ""); + + return stringWriter.toString(); + } + + /** + * Gets the model file path. + * + * @return the model file path + */ + public String getModelFilePath() { + return ResourceUtils.getFilePath4Resource(modelFilePath); + } + + /** + * Sets the model file path. + * + * @param modelFilePath the model file path + */ + public void setModelFilePath(final String modelFilePath) { + this.modelFilePath = modelFilePath; + } + + /** + * Check set model file path. + * + * @return true, if check set model file path + */ + public boolean checkSetModelFilePath() { + return modelFilePath != null && modelFilePath.length() > 0; + } + + /** + * 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 ApexException the apex exception + */ + private void validateReadableFile(final String fileTag, final String fileName) throws ApexException { + if (fileName == null || fileName.length() == 0) { + throw new ApexException(fileTag + " file was not specified as an argument"); + } + + // The file name can refer to a resource on the local file system or on the class path + final URL fileURL = ResourceUtils.getURL4Resource(fileName); + if (fileURL == null) { + throw new ApexException(fileTag + " file \"" + fileName + "\" does not exist"); + } + + final File theFile = new File(fileURL.getPath()); + if (!theFile.exists()) { + throw new ApexException(fileTag + " file \"" + fileName + "\" does not exist"); + } + if (!theFile.isFile()) { + throw new ApexException(fileTag + " file \"" + fileName + "\" is not a normal file"); + } + if (!theFile.canRead()) { + throw new ApexException(fileTag + " file \"" + fileName + "\" is ureadable"); + } + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexEngineServiceHandler.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexEngineServiceHandler.java new file mode 100644 index 000000000..ad7af9449 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexEngineServiceHandler.java @@ -0,0 +1,88 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.main; + +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.service.engine.engdep.EngDepMessagingService; +import org.onap.policy.apex.service.engine.event.ApexEvent; +import org.onap.policy.apex.service.engine.runtime.EngineService; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * The Class ApexEngineServiceHandler holds the reference to the Apex engine service and the EngDep + * service for that engine. It also acts as an event receiver for asynchronous and synchronous + * events. + */ +public class ApexEngineServiceHandler { + // The logger for this class + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexEngineServiceHandler.class); + + // The Apex engine service, the Apex engine itself + private final EngineService apexEngineService; + + // The interface between the Apex engine and Apex policy deployment for the Apex engine + private final EngDepMessagingService engDepService; + + /** + * Instantiates a new engine holder with its engine service and EngDep service. + * + * @param apexEngineService the apex engine service + * @param engDepService the EngDep service + */ + ApexEngineServiceHandler(final EngineService apexEngineService, final EngDepMessagingService engDepService) { + this.apexEngineService = apexEngineService; + this.engDepService = engDepService; + } + + /** + * This method forwards an event to the Apex service. + * + * @param apexEvent The event to forward to Apex + */ + public void forwardEvent(final ApexEvent apexEvent) { + try { + // Send the event to the engine runtime + apexEngineService.getEngineServiceEventInterface().sendEvent(apexEvent); + } catch (final Exception e) { + final String errorMessage = "error transferring event \"" + apexEvent.getName() + "\" to the Apex engine"; + LOGGER.debug(errorMessage, e); + throw new ApexActivatorRuntimeException(errorMessage, e); + } + } + + /** + * Terminate the Apex engine. + * + * @throws ApexException on termination errors + */ + public void terminate() throws ApexException { + // Shut down engine management + if (engDepService != null) { + engDepService.stop(); + } + + // Shut down each engine instance + if (apexEngineService != null) { + apexEngineService.stop(); + } + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexEventMarshaller.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexEventMarshaller.java new file mode 100644 index 000000000..b4ba2ac3e --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexEventMarshaller.java @@ -0,0 +1,232 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.main; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory; +import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities; +import org.onap.policy.apex.service.engine.event.ApexEvent; +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.engine.event.ApexEventProducer; +import org.onap.policy.apex.service.engine.event.ApexEventProtocolConverter; +import org.onap.policy.apex.service.engine.event.impl.EventProducerFactory; +import org.onap.policy.apex.service.engine.event.impl.EventProtocolFactory; +import org.onap.policy.apex.service.engine.runtime.ApexEventListener; +import org.onap.policy.apex.service.parameters.engineservice.EngineServiceParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This event marshaler handles events coming out of Apex and sends them on, handles threading, + * event queuing, transformations and sending using the configured sending technology. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexEventMarshaller implements ApexEventListener, Runnable { + // Get a reference to the logger + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexEventMarshaller.class); + + // Interval to wait between thread shutdown checks + private static final int MARSHALLER_SHUTDOWN_WAIT_INTERVAL = 10; + + // The amount of time to wait between polls of the event queue in milliseconds + private static final long EVENT_QUEUE_POLL_INTERVAL = 20; + + // The name of the marshaler + private final String name; + + // The engine service and producer parameters + private final EngineServiceParameters engineServiceParameters; + private final EventHandlerParameters producerParameters; + + // Apex event producer and event converter, all conversions are to and from string + // representation of events + private ApexEventProducer producer; + private ApexEventProtocolConverter converter; + + // Temporary event holder for events coming out of Apex + private final BlockingQueue<ApexEvent> queue = new LinkedBlockingQueue<>(); + + // The marshaler thread and stopping flag + private Thread marshallerThread; + private boolean stopOrderedFlag = false; + + /** + * Create the marshaler. + * + * @param name the name of the marshaler + * @param engineServiceParameters the engine service parameters for this Apex engine + * @param producerParameters the producer parameters for this specific marshaler + */ + public ApexEventMarshaller(final String name, final EngineServiceParameters engineServiceParameters, + final EventHandlerParameters producerParameters) { + this.name = name; + this.engineServiceParameters = engineServiceParameters; + this.producerParameters = producerParameters; + } + + /** + * Configure the marshaler by setting up the producer and event converter and initialize the + * thread for event sending. + * + * @throws ApexActivatorException on errors initializing the producer + * @throws ApexEventException on errors initializing event handling + */ + public void init() throws ApexActivatorException, ApexEventException { + // Create the producer for sending events and the converter for transforming events + producer = new EventProducerFactory().createProducer(name, producerParameters); + + // Initialize the producer + producer.init(this.name, this.producerParameters); + + // Create the converter for transforming events + converter = new EventProtocolFactory().createConverter(name, producerParameters.getEventProtocolParameters()); + + // Configure and start the event sending thread + final String threadName = + engineServiceParameters.getEngineKey().getName() + ':' + this.getClass().getName() + ':' + this.name; + marshallerThread = new ApplicationThreadFactory(threadName).newThread(this); + marshallerThread.setDaemon(true); + marshallerThread.start(); + } + + /** + * Gets the name of the marshaler. + * + * @return the marshaler name + */ + public String getName() { + return name; + } + + /** + * Gets the technology specific producer for this marshaler. + * + * @return the producer + */ + public ApexEventProducer getProducer() { + return producer; + } + + /** + * Gets the event protocol converter for this marshaler. + * + * @return the event protocol converter + */ + public ApexEventProtocolConverter getConverter() { + return converter; + } + + /** + * Callback method called on implementations of this interface when Apex emits an event. + * + * @param apexEvent the apex event emitted by Apex + */ + @Override + public void onApexEvent(final ApexEvent apexEvent) { + // Check if we are filtering events on this marshaler, if so check the event name against + // the filter + if (producerParameters.isSetEventNameFilter() + && !apexEvent.getName().matches(producerParameters.getEventNameFilter())) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("onMessage(): event {} not processed, filtered out by filter", apexEvent, + producerParameters.getEventNameFilter()); + } + + // Ignore this event + return; + } + + // Push the event onto the queue for handling + try { + queue.put(apexEvent); + } catch (final InterruptedException e) { + LOGGER.warn("Failed to queue the event: " + apexEvent, e); + } + } + + /** + * Run a thread that runs forever (well until system termination anyway) and listens for + * outgoing events on the queue. + */ + @Override + public void run() { + // Run until interrupted + while (marshallerThread.isAlive() && !stopOrderedFlag) { + try { + // Take the next event from the queue + final ApexEvent apexEvent = queue.poll(EVENT_QUEUE_POLL_INTERVAL, TimeUnit.MILLISECONDS); + if (apexEvent == null) { + continue; + } + + // Process the next Apex event from the queue + final Object event = converter.fromApexEvent(apexEvent); + + producer.sendEvent(apexEvent.getExecutionID(), apexEvent.getName(), event); + + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("event sent : " + apexEvent.toString()); + } + } catch (final InterruptedException e) { + LOGGER.debug("Thread interrupted, Reason {}", e.getMessage()); + break; + } catch (final Exception e) { + LOGGER.warn("Error while forwarding events for " + marshallerThread.getName(), e); + continue; + } + } + + // Stop event production if we are not synchronized,;in the synchronized case, the producer + // takes care of its own cleanup. + producer.stop(); + } + + /** + * Get the marshaler thread. + * + * @return the marshaler thread + */ + public Thread getThread() { + return marshallerThread; + } + + /** + * Stop the Apex event marshaller's event producer using its termination mechanism. + */ + public void stop() { + LOGGER.entry("shutting down Apex event marshaller . . ."); + + // Order the stop + stopOrderedFlag = true; + + // Wait for thread shutdown + while (marshallerThread.isAlive()) { + ThreadUtilities.sleep(MARSHALLER_SHUTDOWN_WAIT_INTERVAL); + } + + LOGGER.exit("shut down Apex event marshaller"); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexEventUnmarshaller.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexEventUnmarshaller.java new file mode 100644 index 000000000..a9385751e --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexEventUnmarshaller.java @@ -0,0 +1,323 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.main; + +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory; +import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.service.engine.event.ApexEvent; +import org.onap.policy.apex.service.engine.event.ApexEventConsumer; +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.engine.event.ApexEventProtocolConverter; +import org.onap.policy.apex.service.engine.event.ApexEventReceiver; +import org.onap.policy.apex.service.engine.event.PeeredReference; +import org.onap.policy.apex.service.engine.event.SynchronousEventCache; +import org.onap.policy.apex.service.engine.event.impl.EventConsumerFactory; +import org.onap.policy.apex.service.engine.event.impl.EventProtocolFactory; +import org.onap.policy.apex.service.parameters.engineservice.EngineServiceParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This event unmarshaler handles events coming into Apex, handles threading, event queuing, + * transformation and receiving using the configured receiving technology. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexEventUnmarshaller implements ApexEventReceiver, Runnable { + // Get a reference to the logger + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexEventUnmarshaller.class); + + // Interval to wait between thread shutdown checks + private static final int UNMARSHALLER_SHUTDOWN_WAIT_INTERVAL = 10; + + // The amount of time to wait between polls of the event queue in milliseconds + private static final long EVENT_QUEUE_POLL_INTERVAL = 20; + + // The name of the unmarshaler + private final String name; + + // The engine service and consumer parameters + private final EngineServiceParameters engineServiceParameters; + private final EventHandlerParameters consumerParameters; + + // The engine service handler to use for forwarding on of unmarshalled events + private ApexEngineServiceHandler engineServiceHandler; + + // Apex event producer and event converter, all events are sent as string representations + private ApexEventConsumer consumer; + private ApexEventProtocolConverter converter; + + // Temporary event holder for events going into Apex + private final BlockingQueue<ApexEvent> queue = new LinkedBlockingQueue<>(); + + // The unmarshaler thread and stopping flag + private Thread unmarshallerThread = null; + private boolean stopOrderedFlag = false; + + /** + * Create the unmarshaler. + * + * @param name the name of the unmarshaler + * @param engineServiceParameters the engine service parameters for this Apex engine + * @param consumerParameters the consumer parameters for this specific unmarshaler + */ + public ApexEventUnmarshaller(final String name, final EngineServiceParameters engineServiceParameters, + final EventHandlerParameters consumerParameters) { + this.name = name; + this.engineServiceParameters = engineServiceParameters; + this.consumerParameters = consumerParameters; + } + + /** + * Configure the consumer and initialize the thread for event sending. + * + * @param incomingEngineServiceHandler the Apex engine service handler for passing events to + * Apex + * @throws ApexEventException on errors initializing event handling + */ + public void init(final ApexEngineServiceHandler incomingEngineServiceHandler) throws ApexEventException { + this.engineServiceHandler = incomingEngineServiceHandler; + + // Create the consumer for sending events and the converter for transforming events + consumer = new EventConsumerFactory().createConsumer(name, consumerParameters); + consumer.init(this.name, this.consumerParameters, this); + + converter = new EventProtocolFactory().createConverter(name, consumerParameters.getEventProtocolParameters()); + } + + /** + * Start the unmarshaler and consumer threads. + */ + public void start() { + // Start the consumer + consumer.start(); + + // Configure and start the event reception thread + final String threadName = + engineServiceParameters.getEngineKey().getName() + ":" + this.getClass().getName() + ":" + name; + unmarshallerThread = new ApplicationThreadFactory(threadName).newThread(this); + unmarshallerThread.setDaemon(true); + unmarshallerThread.start(); + } + + /** + * Gets the name of the unmarshaler. + * + * @return the unmarshaler name + */ + public String getName() { + return name; + } + + /** + * Gets the technology specific consumer for this unmarshaler. + * + * @return the consumer + */ + public ApexEventConsumer getConsumer() { + return consumer; + } + + /** + * Gets the event protocol converter for this unmarshaler. + * + * @return the event protocol converter + */ + public ApexEventProtocolConverter getConverter() { + return converter; + } + + /** + * Connect a synchronous unmarshaler with a synchronous marshaler. + * + * @param peeredMode the peered mode under which the unmarshaler and marshaler are connected + * @param peeredMarshaller the synchronous marshaler to connect with + */ + public void connectMarshaler(final EventHandlerPeeredMode peeredMode, final ApexEventMarshaller peeredMarshaller) { + switch (peeredMode) { + case SYNCHRONOUS: + // To connect a synchronous unmarshaler and marshaler, we create a synchronous event + // cache on the consumer/producer pair + new SynchronousEventCache(peeredMode, consumer, peeredMarshaller.getProducer(), + consumerParameters.getPeerTimeout(EventHandlerPeeredMode.SYNCHRONOUS)); + return; + + case REQUESTOR: + new PeeredReference(peeredMode, consumer, peeredMarshaller.getProducer()); + return; + + default: + return; + } + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.ApexEventReceiver#receiveEvent(java.lang.Object) + */ + @Override + public void receiveEvent(final Object event) throws ApexEventException { + receiveEvent(0, event, true); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventReceiver#receiveEvent(long, + * java.lang.Object) + */ + @Override + public void receiveEvent(final long executionId, final Object event) throws ApexEventException { + receiveEvent(executionId, event, false); + } + + /** + * Receive an event from a consumer, convert its protocol and forward it to Apex. + * + * @param executionId the execution id the incoming execution ID + * @param event the event in its native format + * @param generateExecutionId if true, let Apex generate the execution ID, if false, use the + * incoming execution ID + * @throws ApexEventException on unmarshaling errors on events + */ + private void receiveEvent(final long executionId, final Object event, final boolean generateExecutionId) + throws ApexEventException { + // Push the event onto the queue + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("onMessage(): event received: {}", event.toString()); + } + + // Convert the incoming events to Apex events + try { + final List<ApexEvent> apexEventList = converter.toApexEvent(consumerParameters.getEventName(), event); + for (final ApexEvent apexEvent : apexEventList) { + // Check if we are filtering events on this unmarshaler, if so check the event name + // against the filter + if (consumerParameters.isSetEventNameFilter() + && !apexEvent.getName().matches(consumerParameters.getEventNameFilter())) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("onMessage(): event {} not processed, filtered out by filter", apexEvent, + consumerParameters.getEventNameFilter()); + } + + // Ignore this event + continue; + } + + if (!generateExecutionId) { + apexEvent.setExecutionID(executionId); + } + + // Enqueue the event + queue.add(apexEvent); + + // Cache synchronized events that are sent + if (consumerParameters.isPeeredMode(EventHandlerPeeredMode.SYNCHRONOUS)) { + final SynchronousEventCache synchronousEventCache = + (SynchronousEventCache) consumer.getPeeredReference(EventHandlerPeeredMode.SYNCHRONOUS); + synchronousEventCache.cacheSynchronizedEventToApex(apexEvent.getExecutionID(), apexEvent); + } + } + } catch (final ApexException e) { + final String errorMessage = "Error while converting event into an ApexEvent for " + name + ": " + + e.getMessage() + ", Event=" + event; + LOGGER.warn(errorMessage, e); + throw new ApexEventException(errorMessage, e); + } + } + + /** + * Run a thread that runs forever (well until system termination anyway) and listens for + * incoming events on the queue. + */ + @Override + public void run() { + // Run until interruption + while (unmarshallerThread.isAlive() && !stopOrderedFlag) { + try { + // Take the next event from the queue + final ApexEvent apexEvent = queue.poll(EVENT_QUEUE_POLL_INTERVAL, TimeUnit.MILLISECONDS); + if (apexEvent == null) { + continue; + } + + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("event received {}", apexEvent.toString()); + } + + // Pass the event to the activator for forwarding to Apex + engineServiceHandler.forwardEvent(apexEvent); + } catch (final InterruptedException e) { + LOGGER.warn("BatchProcessor thread interrupted, Reason {}", e.getMessage()); + break; + } catch (final Exception e) { + LOGGER.warn("Error while forwarding events for " + unmarshallerThread.getName(), e); + continue; + } + } + + // Stop event production + consumer.stop(); + } + + /** + * Get the unmarshaler thread. + * + * @return the unmarshaler thread + */ + public Thread getThread() { + return unmarshallerThread; + } + + /** + * Stop the Apex event unmarshaller's event producer using its termination mechanism. + */ + public void stop() { + LOGGER.entry("shutting down Apex event unmarshaller . . ."); + + // Order the stop + stopOrderedFlag = true; + + // Order a stop on the synchronous cache if one exists + if (consumerParameters != null && consumerParameters.isPeeredMode(EventHandlerPeeredMode.SYNCHRONOUS)) { + if (consumer.getPeeredReference(EventHandlerPeeredMode.SYNCHRONOUS) != null) { + ((SynchronousEventCache) consumer.getPeeredReference(EventHandlerPeeredMode.SYNCHRONOUS)).stop(); + } + } + + // Wait for thread shutdown + while (unmarshallerThread != null && unmarshallerThread.isAlive()) { + ThreadUtilities.sleep(UNMARSHALLER_SHUTDOWN_WAIT_INTERVAL); + } + + LOGGER.exit("shut down Apex event unmarshaller"); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexMain.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexMain.java new file mode 100644 index 000000000..1b5603482 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/ApexMain.java @@ -0,0 +1,169 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.main; + +import java.util.Arrays; +import java.util.Map.Entry; + +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.service.parameters.ApexParameterHandler; +import org.onap.policy.apex.service.parameters.ApexParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This class initiates Apex as a complete service from the command line. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexMain { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexMain.class); + + // The Apex Activator that activates the Apex engine + private ApexActivator activator; + + // The parameters read in from JSON + private ApexParameters parameters; + + /** + * Instantiates the Apex Apex service. + * + * @param args the commaind line arguments + */ + public ApexMain(final String[] args) { + System.out.println("Starting Apex service with parameters " + Arrays.toString(args) + " . . ."); + LOGGER.entry("Starting Apex service with parameters " + Arrays.toString(args) + " . . ."); + + // Check the arguments + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(); + 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); + System.out.println(argumentMessage); + return; + } + + // Validate that the arguments are sane + arguments.validate(); + } catch (final ApexException e) { + System.err.println("start of Apex service failed: " + e.getMessage()); + LOGGER.error("start of Apex service failed", e); + System.err.println(arguments.help(ApexMain.class.getCanonicalName())); + return; + } + + // Read the parameters + try { + parameters = new ApexParameterHandler().getParameters(arguments); + } catch (final Exception e) { + System.err.println("start of Apex service failed\n" + e.getMessage()); + LOGGER.error("start of Apex service failed", e); + return; + } + + // Set the name of the event handler parameters for producers and consumers + for (final Entry<String, EventHandlerParameters> ehParameterEntry : parameters.getEventOutputParameters() + .entrySet()) { + if (!ehParameterEntry.getValue().checkSetName()) { + ehParameterEntry.getValue().setName(ehParameterEntry.getKey()); + } + } + for (final Entry<String, EventHandlerParameters> ehParameterEntry : parameters.getEventInputParameters() + .entrySet()) { + if (!ehParameterEntry.getValue().checkSetName()) { + ehParameterEntry.getValue().setName(ehParameterEntry.getKey()); + } + } + + // Now, create the activator for the Apex service + activator = new ApexActivator(parameters); + + // Start the activator + try { + activator.initialize(); + } catch (final ApexActivatorException e) { + System.err.println("start of Apex service failed, used parameters are " + Arrays.toString(args)); + e.printStackTrace(System.err); + LOGGER.error("start of Apex service failed, used parameters are " + Arrays.toString(args), e); + return; + } + + // Add a shutdown hook to shut everything down in an orderly manner + Runtime.getRuntime().addShutdownHook(new ApexMainShutdownHookClass()); + LOGGER.exit("Started Apex"); + System.out.println("Started Apex service"); + } + + /** + * Get the parameters specified in JSON. + * + * @return the parameters + */ + public ApexParameters getParameters() { + return parameters; + } + + /** + * Shut down Execution. + * + * @throws ApexException on shutdown errors + */ + public void shutdown() throws ApexException { + if (activator != null) { + activator.terminate(); + } + } + + /** + * The Class ApexMainShutdownHookClass terminates the Apex engine for the Apex service when its + * run method is called. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ + private class ApexMainShutdownHookClass extends Thread { + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + try { + // Shutdown the Apex engine and wait for everything to stop + activator.terminate(); + } catch (final ApexException e) { + LOGGER.warn("error occured during shut down of the Apex service", e); + } + } + } + + /** + * The main method. + * + * @param args the arguments + */ + public static void main(final String[] args) { + new ApexMain(args); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/package-info.java new file mode 100644 index 000000000..488d5ab19 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/main/package-info.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Provides the APEX as a complete service together with all its context, executor and event + * handling plugins. A main method to allow APEX execution from the command line is also provided. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine.main; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/package-info.java new file mode 100644 index 000000000..cdd6c5e16 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/package-info.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Provides Java APIs for Apex. APIs are provided to give access to the APEX engine runtime, to give + * access to APEX event handling, and to give access to the ApexEngDep protocol for engine + * management. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/ApexEventListener.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/ApexEventListener.java new file mode 100644 index 000000000..a498bcff8 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/ApexEventListener.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.runtime; + +import org.onap.policy.apex.service.engine.event.ApexEvent; + +/** + * The listener interface for receiving apexEvent events. The class that is interested in processing + * a apexEvent event implements this interface, and the object created with that class is registered + * with a component using the component's {@code addApexEventListener} method. When the apexEvent + * event occurs, that object's appropriate method is invoked. + * + * @author Sajeevan Achuthan (sajeevan.achuthan@ericsson.com) + */ +public interface ApexEventListener { + + /** + * Callback method called on implementations of this interface when APEX emits an event. + * + * @param apexEvent the apex event emitted by APEX + */ + void onApexEvent(ApexEvent apexEvent); +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/EngineService.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/EngineService.java new file mode 100644 index 000000000..e6fc332f2 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/EngineService.java @@ -0,0 +1,214 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.runtime; + +import java.util.Collection; + +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.enginemodel.concepts.AxEngineState; +import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel; + +/** + * The administration interface for Apex engine users. Apex engine implementations expose this + * interface and external users use it to manage Apex engines. + * + * @author Sajeevan Achuthan (sajeevan.achuthan@ericsson.com) + */ +public interface EngineService { + /** + * A method to attach a listener to the engine. + * + * @param listenerName a unique name for the listener + * @param listener is a callback interface to the engine. + */ + void registerActionListener(String listenerName, ApexEventListener listener); + + /** + * A method to detach a listener from the engine. + * + * @param listenerName the unique name of the listener to deregister + */ + void deregisterActionListener(String listenerName); + + /** + * This method gets the current runtime information for the running Apex engines. + * + * @return the engine service event interface + */ + EngineServiceEventInterface getEngineServiceEventInterface(); + + /** + * Gets the key of the engine service or worker. + * + * @return the key + */ + AxArtifactKey getKey(); + + /** + * This method gets the keys of the engines on the engine service. + * + * @return the engine keys + */ + Collection<AxArtifactKey> getEngineKeys(); + + /** + * The the key of the Apex model the engine service is running on. + * + * @return the Apex model key + */ + AxArtifactKey getApexModelKey(); + + /** + * This method updates the Apex model on Apex execution engines using a string representation of + * the model. + * + * @param engineServiceKey The key of the engine service on which to update the model + * @param apexModelString the apex model string + * @param forceFlag if true, model updates will be executed even on incompatible models + * (different model names) and versions (different model version) + * @throws ApexException on model update errors + */ + void updateModel(AxArtifactKey engineServiceKey, String apexModelString, boolean forceFlag) throws ApexException; + + /** + * This method updates the Apex model on Apex execution engines using a policy model as input. + * + * @param engineServiceKey The key of the engine service on which to update the model + * @param apexModel is a policy definition model + * @param forceFlag if true, model updates will be executed even on incompatible models + * (different model names) and versions (different model version) + * @throws ApexException on model update errors + */ + void updateModel(AxArtifactKey engineServiceKey, AxPolicyModel apexModel, boolean forceFlag) throws ApexException; + + /** + * This method returns the state of an engine service or engine. + * + * @return The engine service or engine state + */ + AxEngineState getState(); + + /** + * This method starts all Apex engines in the engine service. + * + * @throws ApexException on start errors + */ + void startAll() throws ApexException; + + /** + * This method starts an Apex engine in the engine service. + * + * @param engineKey The key of the Apex engine to start + * @throws ApexException on start errors + */ + void start(AxArtifactKey engineKey) throws ApexException; + + /** + * This method stops all Apex engines in the engine service. + * + * @throws ApexException on stop errors + */ + void stop() throws ApexException; + + /** + * This method stops an Apex engine in the engine service. + * + * @param engineKey The key of the Apex engine to stop + * @throws ApexException on stop errors + */ + void stop(AxArtifactKey engineKey) throws ApexException; + + /** + * This method checks if all Apex engines in the engine service are started. + * <p> + * Note: an engine can be both not stopped and not started, for example, when it is starting or + * stopping + * + * @return true if all Apex engines in the engine service are started. + */ + boolean isStarted(); + + /** + * This method checks if an Apex engine in the engine service is started. + * <p> + * Note: an engine can be both not stopped and not started, for example, when it is starting or + * stopping + * + * @param engineKey The key of the Apex engine to check + * @return true if all Apex engines in the engine service are started. + */ + boolean isStarted(AxArtifactKey engineKey); + + /** + * This method checks if all Apex engines in the engine service are stopped. + * <p> + * Note: an engine can be both not stopped and not started, for example, when it is starting or + * stopping + * + * @return true if all Apex engines in the engine service are stopped. + */ + boolean isStopped(); + + /** + * This method checks if an Apex engine in the engine service is stopped. + * <p> + * Note: an engine can be both not stopped and not started, for example, when it is starting or + * stopping + * + * @param engineKey The key of the Apex engine to check + * @return true if all Apex engines in the engine service are stopped. + */ + boolean isStopped(AxArtifactKey engineKey); + + /** + * This method starts periodic event generation. + * + * @param period The period in milliseconds between periodic events + * @throws ApexException On periodic event start errors + */ + void startPeriodicEvents(long period) throws ApexException; + + /** + * This method stops periodic event generation. + * + * @throws ApexException On periodic event stop errors + */ + void stopPeriodicEvents() throws ApexException; + + /** + * This method gets the status of an Apex engine in the engine service. + * + * @param engineKey the engine key + * @return the engine runtime information + * @throws ApexException on status read errors + */ + String getStatus(AxArtifactKey engineKey) throws ApexException; + + /** + * This method gets the runtime information of all Apex engines in the engine service. + * + * @param engineKey the engine key + * @return the engine runtime information + * @throws ApexException on runtime information read errors + */ + String getRuntimeInfo(AxArtifactKey engineKey) throws ApexException; +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/EngineServiceEventInterface.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/EngineServiceEventInterface.java new file mode 100644 index 000000000..8e4cb82e2 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/EngineServiceEventInterface.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.runtime; + +import org.onap.policy.apex.service.engine.event.ApexEvent; + +/** + * The run time interface for APEX engine users. APEX engine implementations expose this interface + * and external users use it to send events to the engine. + * + * @author Sajeevan Achuthan (sajeevan.achuthan@ericsson.com), John Keeney + * (john.keeney@ericsson.com) + */ +public interface EngineServiceEventInterface { + /** + * This method forwards an event to the APEX engine. + * + * @param event is an instance {@link ApexEvent} + */ + void sendEvent(ApexEvent event); +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/EnEventListenerImpl.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/EnEventListenerImpl.java new file mode 100644 index 000000000..abd6db2d9 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/EnEventListenerImpl.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.runtime.impl; + +import org.onap.policy.apex.core.engine.engine.EnEventListener; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.service.engine.event.ApexEvent; +import org.onap.policy.apex.service.engine.event.impl.enevent.ApexEvent2EnEventConverter; +import org.onap.policy.apex.service.engine.runtime.ApexEventListener; + +/** + * The Class EnEventListenerImpl is used by the Apex engine implementation to listen for events + * coming from the core APEX engine. This listener converts the {@link EnEvent} instances into + * {@link ApexEvent} instances using an {@link ApexEvent2EnEventConverter} instance and forwards the + * events to an {@link ApexEventListener} instance for outputting to listening applications. The + * {@link ApexEventListener} is implemented in the external application communicating with Apex. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public final class EnEventListenerImpl implements EnEventListener { + // Listener for ApexEvents + private ApexEventListener apexEventListener = null; + + // Converter for Engine events to Apex Events + private ApexEvent2EnEventConverter apexEnEventConverter = null; + + /** + * Instantiates a new listener implementation. + * + * @param apexEventListener the apex event listener + * @param apexEnEventConverter the ApexEvent to enEvent converter + */ + public EnEventListenerImpl(final ApexEventListener apexEventListener, + final ApexEvent2EnEventConverter apexEnEventConverter) { + this.apexEventListener = apexEventListener; + this.apexEnEventConverter = apexEnEventConverter; + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.core.engine.engine.EnEventListener#onEnEvent(org.onap.policy.apex.core. + * engine.event.EnEvent) + */ + @Override + public void onEnEvent(final EnEvent enEvent) throws ApexException { + for (final ApexEvent apexEvent : apexEnEventConverter.toApexEvent(enEvent.getName(), enEvent)) { + apexEventListener.onApexEvent(apexEvent); + } + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/EngineServiceImpl.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/EngineServiceImpl.java new file mode 100644 index 000000000..24d8263f4 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/EngineServiceImpl.java @@ -0,0 +1,682 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.runtime.impl; + +import java.io.ByteArrayInputStream; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import org.onap.policy.apex.context.ContextException; +import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory; +import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.basicmodel.handling.ApexModelException; +import org.onap.policy.apex.model.basicmodel.handling.ApexModelReader; +import org.onap.policy.apex.model.basicmodel.service.ModelService; +import org.onap.policy.apex.model.enginemodel.concepts.AxEngineState; +import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel; +import org.onap.policy.apex.service.engine.event.ApexEvent; +import org.onap.policy.apex.service.engine.event.ApexPeriodicEventGenerator; +import org.onap.policy.apex.service.engine.runtime.ApexEventListener; +import org.onap.policy.apex.service.engine.runtime.EngineService; +import org.onap.policy.apex.service.engine.runtime.EngineServiceEventInterface; +import org.onap.policy.apex.service.parameters.engineservice.EngineServiceParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * The Class EngineServiceImpl controls a thread pool that runs a set of Apex engine workers, each + * of which is running on an identical Apex model. This class handles the management of the engine + * worker instances, their threads, and event forwarding to and from the engine workers. + * + * @author Sajeevan Achuthan (sajeevan.achuthan@ericsson.com) + * @author Liam Fallon (liam.fallon@ericsson.com) + * @author John Keeney (john.keeney@ericsson.com) + */ +public final class EngineServiceImpl implements EngineService, EngineServiceEventInterface { + // Logging static variables + private static final XLogger LOGGER = XLoggerFactory.getXLogger(EngineServiceImpl.class); + private static final boolean DEBUG_ENABLED = LOGGER.isDebugEnabled(); + + // Constants for timing + private static final long MAX_START_WAIT_TIME = 5000; // 5 seconds + private static final long MAX_STOP_WAIT_TIME = 5000; // 5 seconds + private static final int ENGINE_SERVICE_STOP_START_WAIT_INTERVAL = 200; + + // The ID of this engine + private AxArtifactKey engineServiceKey = null; + + // The Apex engine workers this engine service is handling + private final Map<AxArtifactKey, EngineService> engineWorkerMap = + Collections.synchronizedMap(new LinkedHashMap<AxArtifactKey, EngineService>()); + + // Event queue for events being sent into the Apex engines, it used by all engines within a + // group. + private final BlockingQueue<ApexEvent> queue = new LinkedBlockingQueue<>(); + + // Thread factory for thread management + private final ApplicationThreadFactory tFactory = new ApplicationThreadFactory("apex-engine-service", 512); + + // Periodic event generator and its period in milliseconds + private ApexPeriodicEventGenerator periodicEventGenerator = null; + private long periodicEventPeriod; + + /** + * This constructor instantiates engine workers and adds them to the set of engine workers to be + * managed. The constructor is private to prevent subclassing. + * + * @param engineServiceKey the engine service key + * @param incomingThreadCount the thread count, the number of engine workers to start + * @param periodicEventPeriod the period in milliseconds at which periodic events are generated + * @throws ApexException on worker instantiation errors + */ + private EngineServiceImpl(final AxArtifactKey engineServiceKey, final int incomingThreadCount, + final long periodicEventPeriod) throws ApexException { + LOGGER.entry(engineServiceKey, incomingThreadCount); + + this.engineServiceKey = engineServiceKey; + this.periodicEventPeriod = periodicEventPeriod; + + int threadCount = incomingThreadCount; + if (threadCount <= 0) { + // Just start one engine worker + threadCount = 1; + } + + // Start engine workers + for (int engineCounter = 0; engineCounter < threadCount; engineCounter++) { + final AxArtifactKey engineWorkerKey = + new AxArtifactKey(engineServiceKey.getName() + '-' + engineCounter, engineServiceKey.getVersion()); + engineWorkerMap.put(engineWorkerKey, new EngineWorker(engineWorkerKey, queue, tFactory)); + LOGGER.info("Created apex engine {} .", engineWorkerKey.getID()); + } + + LOGGER.info("APEX service created."); + LOGGER.exit(); + } + + /** + * Create an Apex Engine Service instance. This method is deprecated and will be removed in the + * next version. + * + * @param engineServiceKey the engine service key + * @param threadCount the thread count, the number of engine workers to start + * @return the Engine Service instance + * @throws ApexException on worker instantiation errors + * @deprecated Do not use this version. Use {@link #create(EngineServiceParameters)} + */ + @Deprecated + public static EngineServiceImpl create(final AxArtifactKey engineServiceKey, final int threadCount) + throws ApexException { + // Check if the Apex model specified is sane + if (engineServiceKey == null) { + LOGGER.warn("engine service key is null"); + throw new ApexException("engine service key is null"); + } + return new EngineServiceImpl(engineServiceKey, threadCount, 0); + } + + /** + * Create an Apex Engine Service instance. This method does not load the policy so + * {@link #updateModel(AxArtifactKey, AxPolicyModel, boolean)} or + * {@link #updateModel(AxArtifactKey, AxPolicyModel, boolean)} must be used to load a model. + * This method does not start the Engine Service so {@link #start(AxArtifactKey)} or + * {@link #startAll()} must be used. + * + * @param config the configuration for this Apex Engine Service. + * @return the Engine Service instance + * @throws ApexException on worker instantiation errors + */ + public static EngineServiceImpl create(final EngineServiceParameters config) throws ApexException { + if (config == null) { + LOGGER.warn("Engine service configuration parameters is null"); + throw new ApexException("engine service configuration parameters is null"); + } + final String validation = config.validate(); + if (validation != null && validation.length() > 0) { + LOGGER.warn("Invalid engine service configuration parameters: " + validation); + throw new ApexException("Invalid engine service configuration parameters: " + validation); + } + final AxArtifactKey engineServiceKey = config.getEngineKey(); + final int threadCount = config.getInstanceCount(); + + // Check if the Apex model specified is sane + if (engineServiceKey == null) { + LOGGER.warn("engine service key is null"); + throw new ApexException("engine service key is null"); + } + + return new EngineServiceImpl(engineServiceKey, threadCount, config.getPeriodicEventPeriod()); + } + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.runtime.EngineService#registerActionListener(java.lang. + * String, com.ericsson.apex.service.engine.runtime.ApexEventListener) + */ + @Override + public void registerActionListener(final String listenerName, final ApexEventListener apexEventListener) { + LOGGER.entry(apexEventListener); + + // Register the Apex event listener on all engine workers, each worker will return Apex + // events to the listening application + for (final EngineService engineWorker : engineWorkerMap.values()) { + engineWorker.registerActionListener(listenerName, apexEventListener); + } + + LOGGER.info("Added the action listener to the engine"); + LOGGER.exit(); + } + + /* + * (non-Javadoc) + * + * @see + * com.ericsson.apex.service.engine.runtime.EngineService#deregisterActionListener(java.lang. + * String) + */ + @Override + public void deregisterActionListener(final String listenerName) { + LOGGER.entry(listenerName); + + // Register the Apex event listener on all engine workers, each worker will return Apex + // events to the listening application + for (final EngineService engineWorker : engineWorkerMap.values()) { + engineWorker.deregisterActionListener(listenerName); + } + + LOGGER.info("Removed the action listener from the engine"); + LOGGER.exit(); + } + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.runtime.EngineService#getEngineServiceEventInterface() + */ + @Override + public EngineServiceEventInterface getEngineServiceEventInterface() { + return this; + } + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.runtime.EngineService#getKey() + */ + @Override + public AxArtifactKey getKey() { + return engineServiceKey; + } + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.runtime.EngineService#getInfo() + */ + @Override + public Collection<AxArtifactKey> getEngineKeys() { + return engineWorkerMap.keySet(); + } + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.runtime.EngineService#getApexModelKey() + */ + @Override + public AxArtifactKey getApexModelKey() { + if (engineWorkerMap.size() == 0) { + return null; + } + + return engineWorkerMap.entrySet().iterator().next().getValue().getApexModelKey(); + } + + /* + * (non-Javadoc) + * + * @see + * com.ericsson.apex.service.engine.runtime.EngineService#updateModel(com.ericsson.apex.model. + * basicmodel.concepts.AxArtifactKey, java.lang.String, boolean) + */ + @Override + public void updateModel(final AxArtifactKey incomingEngineServiceKey, final String apexModelString, + final boolean forceFlag) throws ApexException { + // Check if the Apex model specified is sane + if (apexModelString == null || apexModelString.trim().length() == 0) { + LOGGER.warn( + "model for updating on engine service with key " + incomingEngineServiceKey.getID() + " is empty"); + throw new ApexException( + "model for updating on engine service with key " + incomingEngineServiceKey.getID() + " is empty"); + } + + // Read the Apex model into memory using the Apex Model Reader + AxPolicyModel apexPolicyModel = null; + try { + final ApexModelReader<AxPolicyModel> modelReader = new ApexModelReader<>(AxPolicyModel.class); + apexPolicyModel = modelReader.read(new ByteArrayInputStream(apexModelString.getBytes())); + } catch (final ApexModelException e) { + LOGGER.error("failed to unmarshal the apex model on engine service " + incomingEngineServiceKey.getID(), e); + throw new ApexException( + "failed to unmarshal the apex model on engine service " + incomingEngineServiceKey.getID(), e); + } + + if (apexPolicyModel == null) { + LOGGER.error("apex model null on engine service " + incomingEngineServiceKey.getID()); + throw new ApexException("apex model null on engine service " + incomingEngineServiceKey.getID()); + } + + // Update the model + updateModel(incomingEngineServiceKey, apexPolicyModel, forceFlag); + + LOGGER.exit(); + } + + /* + * (non-Javadoc) + * + * @see + * com.ericsson.apex.service.engine.runtime.EngineService#updateModel(com.ericsson.apex.model. + * basicmodel.concepts.AxArtifactKey, + * com.ericsson.apex.model.policymodel.concepts.AxPolicyModel, boolean) + */ + @Override + public void updateModel(final AxArtifactKey incomingEngineServiceKey, final AxPolicyModel apexModel, + final boolean forceFlag) throws ApexException { + LOGGER.entry(incomingEngineServiceKey); + + // Check if the Apex model specified is sane + if (apexModel == null) { + LOGGER.warn( + "model for updating on engine service with key " + incomingEngineServiceKey.getID() + " is null"); + throw new ApexException( + "model for updating on engine service with key " + incomingEngineServiceKey.getID() + " is null"); + } + + // Check if the key on the update request is correct + if (!this.engineServiceKey.equals(incomingEngineServiceKey)) { + LOGGER.warn("engine service key " + incomingEngineServiceKey.getID() + " does not match the key" + + engineServiceKey.getID() + " of this engine service"); + throw new ApexException("engine service key " + incomingEngineServiceKey.getID() + " does not match the key" + + engineServiceKey.getID() + " of this engine service"); + } + + // Check model compatibility + if (ModelService.existsModel(AxPolicyModel.class)) { + // The current policy model may or may not be defined + final AxPolicyModel currentModel = ModelService.getModel(AxPolicyModel.class); + if (!currentModel.getKey().isCompatible(apexModel.getKey())) { + if (forceFlag) { + LOGGER.warn("apex model update forced, supplied model with key \"" + apexModel.getKey().getID() + + "\" is not a compatible model update from the existing engine model with key \"" + + currentModel.getKey().getID() + "\""); + } else { + throw new ContextException( + "apex model update failed, supplied model with key \"" + apexModel.getKey().getID() + + "\" is not a compatible model update from the existing engine model with key \"" + + currentModel.getKey().getID() + "\""); + } + } + } + + final boolean wasstopped = isStopped(); + + if (!wasstopped) { + // Stop all engines on this engine service + stop(); + final long stoptime = System.currentTimeMillis(); + while (!isStopped() && System.currentTimeMillis() - stoptime < MAX_STOP_WAIT_TIME) { + ThreadUtilities.sleep(ENGINE_SERVICE_STOP_START_WAIT_INTERVAL); + } + // Check if all engines are stopped + final StringBuilder notStoppedEngineIDBuilder = new StringBuilder(); + for (final Entry<AxArtifactKey, EngineService> engineWorkerEntry : engineWorkerMap.entrySet()) { + if (engineWorkerEntry.getValue().getState() != AxEngineState.STOPPED) { + notStoppedEngineIDBuilder.append(engineWorkerEntry.getKey().getID()); + notStoppedEngineIDBuilder.append('('); + notStoppedEngineIDBuilder.append(engineWorkerEntry.getValue().getState()); + notStoppedEngineIDBuilder.append(") "); + } + } + if (notStoppedEngineIDBuilder.length() > 0) { + final String errorString = "cannot update model on engine service with key " + + incomingEngineServiceKey.getID() + ", engines not stopped after " + MAX_STOP_WAIT_TIME + + "ms are: " + notStoppedEngineIDBuilder.toString().trim(); + LOGGER.warn(errorString); + throw new ApexException(errorString); + } + } + + // Update the engines + for (final Entry<AxArtifactKey, EngineService> engineWorkerEntry : engineWorkerMap.entrySet()) { + LOGGER.info("Registering apex model on engine {}", engineWorkerEntry.getKey().getID()); + engineWorkerEntry.getValue().updateModel(engineWorkerEntry.getKey(), apexModel, forceFlag); + } + + if (!wasstopped) { + // start all engines on this engine service if it was not stopped before the update + startAll(); + final long starttime = System.currentTimeMillis(); + while (!isStarted() && System.currentTimeMillis() - starttime < MAX_START_WAIT_TIME) { + ThreadUtilities.sleep(ENGINE_SERVICE_STOP_START_WAIT_INTERVAL); + } + // Check if all engines are running + final StringBuilder notRunningEngineIDBuilder = new StringBuilder(); + for (final Entry<AxArtifactKey, EngineService> engineWorkerEntry : engineWorkerMap.entrySet()) { + if (engineWorkerEntry.getValue().getState() != AxEngineState.READY + && engineWorkerEntry.getValue().getState() != AxEngineState.EXECUTING) { + notRunningEngineIDBuilder.append(engineWorkerEntry.getKey().getID()); + notRunningEngineIDBuilder.append('('); + notRunningEngineIDBuilder.append(engineWorkerEntry.getValue().getState()); + notRunningEngineIDBuilder.append(") "); + } + } + if (notRunningEngineIDBuilder.length() > 0) { + final String errorString = "engine start error on model update on engine service with key " + + incomingEngineServiceKey.getID() + ", engines not running are: " + + notRunningEngineIDBuilder.toString().trim(); + LOGGER.warn(errorString); + throw new ApexException(errorString); + } + } + + LOGGER.exit(); + } + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.runtime.EngineService#getState() + */ + @Override + public AxEngineState getState() { + // If one worker is running then we are running, otherwise we are stopped + for (final EngineService engine : engineWorkerMap.values()) { + if (engine.getState() != AxEngineState.STOPPED) { + return AxEngineState.EXECUTING; + } + } + + return AxEngineState.STOPPED; + } + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.runtime.EngineService#startAll() + */ + @Override + public void startAll() throws ApexException { + for (final EngineService engine : engineWorkerMap.values()) { + start(engine.getKey()); + } + + // Check if periodic events should be turned on + if (periodicEventPeriod > 0) { + startPeriodicEvents(periodicEventPeriod); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.ericsson.apex.service.engine.runtime.EngineService#start(com.ericsson.apex.core.model. + * concepts.AxArtifactKey) + */ + @Override + public void start(final AxArtifactKey engineKey) throws ApexException { + LOGGER.entry(engineKey); + + // Check if we have this key on our map + if (!engineWorkerMap.containsKey(engineKey)) { + LOGGER.warn("engine with key " + engineKey.getID() + " not found in engine service"); + throw new ApexException("engine with key " + engineKey.getID() + " not found in engine service"); + } + + // Start the engine + engineWorkerMap.get(engineKey).start(engineKey); + + LOGGER.exit(engineKey); + } + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.runtime.EngineService#stop() + */ + @Override + public void stop() throws ApexException { + LOGGER.entry(); + + // Stop each engine + for (final EngineService engine : engineWorkerMap.values()) { + if (engine.getState() != AxEngineState.STOPPED) { + engine.stop(); + } + } + + LOGGER.exit(); + } + + /* + * (non-Javadoc) + * + * @see + * com.ericsson.apex.service.engine.runtime.EngineService#stop(com.ericsson.apex.core.model. + * concepts.AxArtifactKey) + */ + @Override + public void stop(final AxArtifactKey engineKey) throws ApexException { + LOGGER.entry(engineKey); + + // Check if we have this key on our map + if (!engineWorkerMap.containsKey(engineKey)) { + LOGGER.warn("engine with key " + engineKey.getID() + " not found in engine service"); + throw new ApexException("engine with key " + engineKey.getID() + " not found in engine service"); + } + + // Stop the engine + engineWorkerMap.get(engineKey).stop(engineKey); + + LOGGER.exit(engineKey); + } + + /** + * Check all engines are started. + * + * @return true if <i>all</i> engines are started + * @see org.onap.policy.apex.service.engine.runtime.EngineService#isStarted() + */ + @Override + public boolean isStarted() { + for (final EngineService engine : engineWorkerMap.values()) { + if (!engine.isStarted()) { + return false; + } + } + return true; + } + + /* + * (non-Javadoc) + * + * @see + * com.ericsson.apex.service.engine.runtime.EngineService#isStarted(com.ericsson.apex.model. + * basicmodel.concepts.AxArtifactKey) + */ + @Override + public boolean isStarted(final AxArtifactKey engineKey) { + // Check if we have this key on our map + if (!engineWorkerMap.containsKey(engineKey)) { + LOGGER.warn("engine with key " + engineKey.getID() + " not found in engine service"); + } + return engineWorkerMap.get(engineKey).isStarted(); + } + + /** + * Check all engines are stopped. + * + * @return true if <i>all</i> engines are stopped + * @see org.onap.policy.apex.service.engine.runtime.EngineService#isStopped() + */ + @Override + public boolean isStopped() { + for (final EngineService engine : engineWorkerMap.values()) { + if (!engine.isStopped()) { + return false; + } + } + return true; + } + + /* + * (non-Javadoc) + * + * @see + * com.ericsson.apex.service.engine.runtime.EngineService#isStopped(com.ericsson.apex.model. + * basicmodel.concepts.AxArtifactKey) + */ + @Override + public boolean isStopped(final AxArtifactKey engineKey) { + // Check if we have this key on our map + if (!engineWorkerMap.containsKey(engineKey)) { + LOGGER.warn("engine with key " + engineKey.getID() + " not found in engine service"); + } + return engineWorkerMap.get(engineKey).isStopped(); + } + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.runtime.EngineService#startPeriodicEvents(long) + */ + @Override + public void startPeriodicEvents(final long period) throws ApexException { + // Check if periodic events are already started + if (periodicEventGenerator != null) { + LOGGER.warn("Peiodic event geneation already running on engine " + engineServiceKey.getID() + ", " + + periodicEventGenerator.toString()); + throw new ApexException("Peiodic event geneation already running on engine " + engineServiceKey.getID() + + ", " + periodicEventGenerator.toString()); + } + + // Set up periodic event execution, its a Java Timer/TimerTask + periodicEventGenerator = new ApexPeriodicEventGenerator(this.getEngineServiceEventInterface(), period); + + // Record the periodic event period because it may have been set over the Web Socket admin + // interface + this.periodicEventPeriod = period; + } + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.runtime.EngineService#stopPeriodicEvents() + */ + @Override + public void stopPeriodicEvents() throws ApexException { + // Check if periodic events are already started + if (periodicEventGenerator == null) { + LOGGER.warn("Peiodic event geneation not running on engine " + engineServiceKey.getID()); + throw new ApexException("Peiodic event geneation not running on engine " + engineServiceKey.getID()); + } + + // Stop periodic events + periodicEventGenerator.cancel(); + periodicEventGenerator = null; + } + + /* + * (non-Javadoc) + * + * @see + * com.ericsson.apex.service.engine.runtime.EngineService#getStatus(com.ericsson.apex.core.model + * .concepts.AxArtifactKey) + */ + @Override + public String getStatus(final AxArtifactKey engineKey) throws ApexException { + // Check if we have this key on our map + if (!engineWorkerMap.containsKey(engineKey)) { + LOGGER.warn("engine with key " + engineKey.getID() + " not found in engine service"); + throw new ApexException("engine with key " + engineKey.getID() + " not found in engine service"); + } + + // Return the information for this worker + return engineWorkerMap.get(engineKey).getStatus(engineKey); + } + + /* + * (non-Javadoc) + * + * @see + * com.ericsson.apex.service.engine.runtime.EngineService#getRuntimeInfo(com.ericsson.apex.core. + * model.concepts.AxArtifactKey) + */ + @Override + public String getRuntimeInfo(final AxArtifactKey engineKey) throws ApexException { + // Check if we have this key on our map + if (!engineWorkerMap.containsKey(engineKey)) { + LOGGER.warn("engine with key " + engineKey.getID() + " not found in engine service"); + throw new ApexException("engine with key " + engineKey.getID() + " not found in engine service"); + } + + // Return the information for this worker + return engineWorkerMap.get(engineKey).getRuntimeInfo(engineKey); + } + + /* + * (non-Javadoc) + * + * @see + * com.ericsson.apex.service.engine.runtime.EngineServiceEventInterface#sendEvent(com.ericsson. + * apex.service.engine.event.ApexEvent) + */ + @Override + public void sendEvent(final ApexEvent event) { + // Check if we have this key on our map + if (getState() == AxEngineState.STOPPED) { + LOGGER.warn("event " + event.getName() + " not processed, no engines on engine service " + + engineServiceKey.getID() + " are running"); + return; + } + + if (event == null) { + LOGGER.warn("Null events cannot be processed, in engine service " + engineServiceKey.getID()); + return; + } + + if (DEBUG_ENABLED) { + LOGGER.debug("Forwarding Apex Event {} to the processing engine", event); + } + + // Add the incoming event to the queue, the next available worker will process it + queue.add(event); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/EngineWorker.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/EngineWorker.java new file mode 100644 index 000000000..20f8aaf75 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/EngineWorker.java @@ -0,0 +1,674 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.runtime.impl; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.BlockingQueue; + +import org.onap.policy.apex.context.ContextException; +import org.onap.policy.apex.context.ContextRuntimeException; +import org.onap.policy.apex.context.SchemaHelper; +import org.onap.policy.apex.context.impl.schema.SchemaHelperFactory; +import org.onap.policy.apex.core.engine.engine.ApexEngine; +import org.onap.policy.apex.core.engine.engine.impl.ApexEngineFactory; +import org.onap.policy.apex.core.engine.event.EnEvent; +import org.onap.policy.apex.core.infrastructure.threading.ApplicationThreadFactory; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.basicmodel.handling.ApexModelException; +import org.onap.policy.apex.model.basicmodel.handling.ApexModelReader; +import org.onap.policy.apex.model.basicmodel.handling.ApexModelWriter; +import org.onap.policy.apex.model.basicmodel.service.ModelService; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbums; +import org.onap.policy.apex.model.enginemodel.concepts.AxEngineModel; +import org.onap.policy.apex.model.enginemodel.concepts.AxEngineState; +import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel; +import org.onap.policy.apex.service.engine.event.ApexEvent; +import org.onap.policy.apex.service.engine.event.impl.enevent.ApexEvent2EnEventConverter; +import org.onap.policy.apex.service.engine.runtime.ApexEventListener; +import org.onap.policy.apex.service.engine.runtime.EngineService; +import org.onap.policy.apex.service.engine.runtime.EngineServiceEventInterface; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; + +/** + * The Class EngineWorker encapsulates a core {@link ApexEngine} instance, which runs policies + * defined in the {@link org.onap.policy.apex.model.basicmodel.concepts.AxModelAxModel}. Each policy + * is triggered by an Apex event, and when the policy is triggered it runs through to completion in + * the ApexEngine. + * + * This class acts as a container for an {@link ApexEngine}, running it in a thread, sending it + * events, and receiving events from it. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +final class EngineWorker implements EngineService { + // Logger for this class + private static final XLogger LOGGER = XLoggerFactory.getXLogger(EngineService.class); + + // The ID of this engine + private final AxArtifactKey engineWorkerKey; + + // The Apex engine which is running the policies in this worker + private final ApexEngine engine; + + // The event processor is an inner class, an instance of which runs as a thread that reads + // incoming events from a queue and forwards them to the Apex engine + private EventProcessor processor = null; + + // Thread handling for the worker + private final ApplicationThreadFactory threadFactory; + private Thread processorThread; + + // Converts ApexEvent instances to and from EnEvent instances + private ApexEvent2EnEventConverter apexEnEventConverter = null; + + /** + * Constructor that creates an Apex engine, an event processor for events to be sent to that + * engine, and an {@link ApexModelReader} instance to read Apex models using JAXB. + * + * @param engineWorkerKey the engine worker key + * @param queue the queue on which events for this Apex worker will come + * @param threadFactory the thread factory to use for creating the event processing thread + * @throws ApexException thrown on errors on worker instantiation + */ + EngineWorker(final AxArtifactKey engineWorkerKey, final BlockingQueue<ApexEvent> queue, + final ApplicationThreadFactory threadFactory) throws ApexException { + LOGGER.entry(engineWorkerKey); + + this.engineWorkerKey = engineWorkerKey; + this.threadFactory = threadFactory; + + // Create the Apex engine + engine = new ApexEngineFactory().createApexEngine(engineWorkerKey); + + // Create and run the event processor + processor = new EventProcessor(queue); + + // Set the Event converter up + apexEnEventConverter = new ApexEvent2EnEventConverter(engine); + + LOGGER.exit(); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.runtime.EngineService#registerActionListener(java.lang. + * String, org.onap.policy.apex.service.engine.runtime.ApexEventListener) + */ + @Override + public void registerActionListener(final String listenerName, final ApexEventListener apexEventListener) { + // Sanity checks on the Apex model + if (engine == null) { + LOGGER.warn("listener registration on engine with key " + engineWorkerKey.getID() + + ", failed, listener is null"); + return; + } + + engine.addEventListener(listenerName, new EnEventListenerImpl(apexEventListener, apexEnEventConverter)); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.runtime.EngineService#deregisterActionListener(java.lang. + * String) + */ + @Override + public void deregisterActionListener(final String listenerName) { + // Sanity checks on the Apex model + if (engine == null) { + LOGGER.warn("listener deregistration on engine with key " + engineWorkerKey.getID() + + ", failed, listener is null"); + return; + } + + engine.removeEventListener(listenerName); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.runtime.EngineService#getEngineServiceEventInterface() + */ + @Override + public EngineServiceEventInterface getEngineServiceEventInterface() { + throw new UnsupportedOperationException( + "getEngineServiceEventInterface() call is not allowed on an Apex Engine Worker"); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.runtime.EngineService#getKey() + */ + @Override + public AxArtifactKey getKey() { + return engineWorkerKey; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.runtime.EngineService#getInfo() + */ + @Override + public Collection<AxArtifactKey> getEngineKeys() { + return Arrays.asList(engineWorkerKey); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.runtime.EngineService#getApexModelKey() + */ + @Override + public AxArtifactKey getApexModelKey() { + if (ModelService.existsModel(AxPolicyModel.class)) { + return ModelService.getModel(AxPolicyModel.class).getKey(); + } else { + return null; + } + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.runtime.EngineService#updateModel(org.onap.policy.apex. + * model. basicmodel.concepts.AxArtifactKey, java.lang.String, boolean) + */ + @Override + public void updateModel(final AxArtifactKey engineKey, final String engineModel, final boolean forceFlag) + throws ApexException { + LOGGER.entry(engineKey); + + // Read the Apex model into memory using the Apex Model Reader + AxPolicyModel apexPolicyModel = null; + try { + final ApexModelReader<AxPolicyModel> modelReader = new ApexModelReader<>(AxPolicyModel.class); + apexPolicyModel = modelReader.read(new ByteArrayInputStream(engineModel.getBytes())); + } catch (final ApexModelException e) { + LOGGER.error("failed to unmarshal the apex model on engine " + engineKey.getID(), e); + throw new ApexException("failed to unmarshal the apex model on engine " + engineKey.getID(), e); + } + + if (apexPolicyModel == null) { + LOGGER.error("apex model null on engine " + engineKey.getID()); + throw new ApexException("apex model null on engine " + engineKey.getID()); + } + + // Update the Apex model in the Apex engine + updateModel(engineKey, apexPolicyModel, forceFlag); + + LOGGER.exit(); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.runtime.EngineService#updateModel(org.onap.policy.apex. + * model. basicmodel.concepts.AxArtifactKey, + * org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel, boolean) + */ + @Override + public void updateModel(final AxArtifactKey engineKey, final AxPolicyModel apexModel, final boolean forceFlag) + throws ApexException { + LOGGER.entry(engineKey); + + // Check if the key on the update request is correct + if (!engineWorkerKey.equals(engineKey)) { + LOGGER.warn("engine key " + engineKey.getID() + " does not match the key" + engineWorkerKey.getID() + + " of this engine"); + throw new ApexException("engine key " + engineKey.getID() + " does not match the key" + + engineWorkerKey.getID() + " of this engine"); + } + + // Sanity checks on the Apex model + if (engine == null) { + LOGGER.warn("engine with key " + engineKey.getID() + " not initialized"); + throw new ApexException("engine with key " + engineKey.getID() + " not initialized"); + } + + // Check model compatibility + if (ModelService.existsModel(AxPolicyModel.class)) { + // The current policy model may or may not be defined + final AxPolicyModel currentModel = ModelService.getModel(AxPolicyModel.class); + if (!currentModel.getKey().isCompatible(apexModel.getKey())) { + if (forceFlag) { + LOGGER.warn("apex model update forced, supplied model with key \"" + apexModel.getKey().getID() + + "\" is not a compatible model update from the existing engine model with key \"" + + currentModel.getKey().getID() + "\""); + } else { + throw new ContextException( + "apex model update failed, supplied model with key \"" + apexModel.getKey().getID() + + "\" is not a compatible model update from the existing engine model with key \"" + + currentModel.getKey().getID() + "\""); + } + } + } + + // Update the Apex model in the Apex engine + engine.updateModel(apexModel); + + LOGGER.debug("engine model {} added to the engine-{}", apexModel.getKey().getID(), engineWorkerKey); + LOGGER.exit(); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.runtime.EngineService#getState() + */ + @Override + public AxEngineState getState() { + return engine.getState(); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.runtime.EngineService#startAll() + */ + @Override + public void startAll() throws ApexException { + start(this.getKey()); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.runtime.EngineService#start(org.onap.policy.apex.core. + * model. concepts.AxArtifactKey) + */ + @Override + public void start(final AxArtifactKey engineKey) throws ApexException { + LOGGER.entry(engineKey); + + // Check if the key on the start request is correct + if (!engineWorkerKey.equals(engineKey)) { + LOGGER.warn("engine key " + engineKey.getID() + " does not match the key" + engineWorkerKey.getID() + + " of this engine"); + throw new ApexException("engine key " + engineKey.getID() + " does not match the key" + + engineWorkerKey.getID() + " of this engine"); + } + + if (engine == null) { + LOGGER.error("apex engine for engine key" + engineWorkerKey.getID() + " null"); + throw new ApexException("apex engine for engine key" + engineWorkerKey.getID() + " null"); + } + + // Starts the event processing thread that handles incoming events + if (processorThread != null && processorThread.isAlive()) { + LOGGER.error("apex engine for engine key" + engineWorkerKey.getID() + " is already running with state " + + getState()); + throw new ApexException("apex engine for engine key" + engineWorkerKey.getID() + + " is already running with state " + getState()); + } + + // Start the engine + engine.start(); + + // Start a thread to process events for the engine + processorThread = threadFactory.newThread(processor); + processorThread.start(); + + LOGGER.exit(engineKey); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.runtime.EngineService#stop() + */ + @Override + public void stop() throws ApexException { + stop(this.getKey()); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.runtime.EngineService#stop(org.onap.policy.apex.core. + * model. concepts.AxArtifactKey) + */ + @Override + public void stop(final AxArtifactKey engineKey) throws ApexException { + // Check if the key on the start request is correct + if (!engineWorkerKey.equals(engineKey)) { + LOGGER.warn("engine key " + engineKey.getID() + " does not match the key" + engineWorkerKey.getID() + + " of this engine"); + throw new ApexException("engine key " + engineKey.getID() + " does not match the key" + + engineWorkerKey.getID() + " of this engine"); + } + + if (engine == null) { + LOGGER.error("apex engine for engine key" + engineWorkerKey.getID() + " null"); + throw new ApexException("apex engine for engine key" + engineWorkerKey.getID() + " null"); + } + + // Interrupt the worker to stop its thread + if (processorThread == null || !processorThread.isAlive()) { + processorThread = null; + + LOGGER.warn("apex engine for engine key" + engineWorkerKey.getID() + " is already stopped with state " + + getState()); + return; + } + + // Interrupt the thread that is handling events toward the engine + processorThread.interrupt(); + + // Stop the engine + engine.stop(); + + LOGGER.exit(engineKey); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.runtime.EngineService#isStarted() + */ + @Override + public boolean isStarted() { + return isStarted(this.getKey()); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.runtime.EngineService#isStarted(org.onap.policy.apex. + * model. basicmodel.concepts.AxArtifactKey) + */ + @Override + public boolean isStarted(final AxArtifactKey engineKey) { + final AxEngineState engstate = getState(); + switch (engstate) { + case STOPPED: + case STOPPING: + case UNDEFINED: + return false; + case EXECUTING: + case READY: + return processorThread != null && processorThread.isAlive() && !processorThread.isInterrupted(); + default: + break; + } + return false; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.runtime.EngineService#isStopped() + */ + @Override + public boolean isStopped() { + return isStopped(this.getKey()); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.runtime.EngineService#isStopped(org.onap.policy.apex. + * model. basicmodel.concepts.AxArtifactKey) + */ + @Override + public boolean isStopped(final AxArtifactKey engineKey) { + final AxEngineState engstate = getState(); + switch (engstate) { + case STOPPING: + case UNDEFINED: + case EXECUTING: + case READY: + return false; + case STOPPED: + return processorThread == null || !processorThread.isAlive(); + default: + break; + } + return false; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.runtime.EngineService#startPeriodicEvents(long) + */ + @Override + public void startPeriodicEvents(final long period) { + throw new UnsupportedOperationException("startPeriodicEvents() call is not allowed on an Apex Engine Worker"); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.runtime.EngineService#stopPeriodicEvents() + */ + @Override + public void stopPeriodicEvents() { + throw new UnsupportedOperationException("stopPeriodicEvents() call is not allowed on an Apex Engine Worker"); + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.runtime.EngineService#getStatus(org.onap.policy.apex.core + * .model .concepts.AxArtifactKey) + */ + @Override + public String getStatus(final AxArtifactKey engineKey) { + // Get the information from the engine that we want to return + final AxEngineModel apexEngineModel = engine.getEngineStatus(); + apexEngineModel.getKeyInformation().generateKeyInfo(apexEngineModel); + + // Convert that information into a string + try { + final ByteArrayOutputStream baOutputStream = new ByteArrayOutputStream(); + final ApexModelWriter<AxEngineModel> modelWriter = new ApexModelWriter<>(AxEngineModel.class); + modelWriter.write(apexEngineModel, baOutputStream); + return baOutputStream.toString(); + } catch (final Exception e) { + LOGGER.warn("error outputting runtime information for engine {}", engineWorkerKey, e); + return null; + } + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.runtime.EngineService#getRuntimeInfo(org.onap.policy.apex + * .core.model.concepts.AxArtifactKey) + */ + @Override + public String getRuntimeInfo(final AxArtifactKey engineKey) { + // We'll build up the JSON string for runtime information bit by bit + final StringBuilder runtimeJsonStringBuilder = new StringBuilder(); + + // Get the engine information + final AxEngineModel engineModel = engine.getEngineStatus(); + final Map<AxArtifactKey, Map<String, Object>> engineContextAlbums = engine.getEngineContext(); + + // Use GSON to convert our context information into JSON + final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + // Get context into a JSON string + runtimeJsonStringBuilder.append("{\"TimeStamp\":"); + runtimeJsonStringBuilder.append(engineModel.getTimestamp()); + runtimeJsonStringBuilder.append(",\"State\":"); + runtimeJsonStringBuilder.append(engineModel.getState()); + runtimeJsonStringBuilder.append(",\"Stats\":"); + runtimeJsonStringBuilder.append(gson.toJson(engineModel.getStats())); + + // Get context into a JSON string + runtimeJsonStringBuilder.append(",\"ContextAlbums\":["); + + boolean firstAlbum = true; + for (final Entry<AxArtifactKey, Map<String, Object>> contextAlbumEntry : engineContextAlbums.entrySet()) { + if (firstAlbum) { + firstAlbum = false; + } else { + runtimeJsonStringBuilder.append(","); + } + + runtimeJsonStringBuilder.append("{\"AlbumKey\":"); + runtimeJsonStringBuilder.append(gson.toJson(contextAlbumEntry.getKey())); + runtimeJsonStringBuilder.append(",\"AlbumContent\":["); + + + // Get the schema helper to use to marshal context album objects to JSON + final AxContextAlbum axContextAlbum = + ModelService.getModel(AxContextAlbums.class).get(contextAlbumEntry.getKey()); + SchemaHelper schemaHelper = null; + + try { + // Get a schema helper to manage the translations between objects on the album map + // for this album + schemaHelper = new SchemaHelperFactory().createSchemaHelper(axContextAlbum.getKey(), + axContextAlbum.getItemSchema()); + } catch (final ContextRuntimeException e) { + final String resultString = + "could not find schema helper to marshal context album \"" + axContextAlbum + "\" to JSON"; + LOGGER.warn(resultString, e); + + // End of context album entry + runtimeJsonStringBuilder.append(resultString); + runtimeJsonStringBuilder.append("]}"); + + continue; + } + + boolean firstEntry = true; + for (final Entry<String, Object> contextEntry : contextAlbumEntry.getValue().entrySet()) { + if (firstEntry) { + firstEntry = false; + } else { + runtimeJsonStringBuilder.append(","); + } + runtimeJsonStringBuilder.append("{\"EntryName\":"); + runtimeJsonStringBuilder.append(gson.toJson(contextEntry.getKey())); + runtimeJsonStringBuilder.append(",\"EntryContent\":"); + runtimeJsonStringBuilder.append(gson.toJson(schemaHelper.marshal2Json(contextEntry.getValue()))); + + // End of context entry + runtimeJsonStringBuilder.append("}"); + } + + // End of context album entry + runtimeJsonStringBuilder.append("]}"); + } + + runtimeJsonStringBuilder.append("]}"); + + // Tidy up the JSON string + final JsonParser jsonParser = new JsonParser(); + final JsonElement jsonElement = jsonParser.parse(runtimeJsonStringBuilder.toString()); + final String tidiedRuntimeString = gson.toJson(jsonElement); + + LOGGER.debug("runtime information=" + tidiedRuntimeString); + + return tidiedRuntimeString; + } + + /** + * This is an event processor thread, this class decouples the events handling logic from core + * business logic. This class runs its own thread and continuously querying the blocking queue + * for the events that have been sent to the worker for processing by the Apex engine. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ + private class EventProcessor implements Runnable { + private final boolean debugEnabled = LOGGER.isDebugEnabled(); + // the events queue + private BlockingQueue<ApexEvent> eventProcessingQueue = null; + + /** + * Constructor accepts {@link ApexEngine} and {@link BlockingQueue} type objects. + * + * @param eventProcessingQueue is reference of {@link BlockingQueue} which contains trigger + * events. + */ + EventProcessor(final BlockingQueue<ApexEvent> eventProcessingQueue) { + this.eventProcessingQueue = eventProcessingQueue; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + LOGGER.debug("Engine {} processing ... ", engineWorkerKey); + + // Take events from the event processing queue of the worker and pass them to the engine + // for processing + while (!processorThread.isInterrupted()) { + ApexEvent event = null; + try { + event = eventProcessingQueue.take(); + } catch (final InterruptedException e) { + LOGGER.debug("Engine {} processing interrupted ", engineWorkerKey); + break; + } + + try { + if (event != null) { + if (debugEnabled) { + LOGGER.debug("Trigger Event {} forwarded to the Apex engine", event); + } + final EnEvent enevent = apexEnEventConverter.fromApexEvent(event); + engine.handleEvent(enevent); + } + } catch (final ApexException e) { + LOGGER.warn("Engine {} failed to process event {}", engineWorkerKey, event.toString(), e); + } catch (final Exception e) { + LOGGER.warn("Engine {} terminated processing event {}", engineWorkerKey, event.toString(), e); + break; + } + } + LOGGER.debug("Engine {} completed processing", engineWorkerKey); + } + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/package-info.java new file mode 100644 index 000000000..b0acca8d7 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/impl/package-info.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Provides the implementation of the APEX engine runtime interfaces. It uses the APEX core engine + * as its implementation. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine.runtime.impl; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/package-info.java new file mode 100644 index 000000000..b54a90349 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/engine/runtime/package-info.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Provides Java APIs for APEX engines at runtime. The {@link EngineService} is used to start, stop + * and manage APEX engines. {@link EngineServiceEventInterface} is used to send events to an APEX + * engine. {@link ApexEventListener} interface is used to receive events from an APEX engine. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.engine.runtime; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterException.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterException.java new file mode 100644 index 000000000..229250bcf --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterException.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters; + +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; + +/** + * This exception will be called if an error occurs in Apex parameter handling. + * + * @author Liam Fallon + */ +public class ApexParameterException extends ApexException { + private static final long serialVersionUID = -8507246953751956974L; + + /** + * Instantiates a new apex parameter handling exception with a message. + * + * @param message the message + */ + public ApexParameterException(final String message) { + super(message); + } + + /** + * Instantiates a new apex parameter handling exception with a message and a caused by + * exception. + * + * @param message the message + * @param e the exception that caused this exception to be thrown + */ + public ApexParameterException(final String message, final Exception e) { + super(message, e); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterHandler.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterHandler.java new file mode 100644 index 000000000..79f10bdea --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterHandler.java @@ -0,0 +1,100 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters; + +import java.io.FileReader; + +import org.onap.policy.apex.core.engine.EngineParameters; +import org.onap.policy.apex.service.engine.main.ApexCommandLineArguments; +import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters; +import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParametersJSONAdapter; +import org.onap.policy.apex.service.parameters.engineservice.EngineServiceParametersJSONAdapter; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParametersJSONAdapter; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +/** + * This class handles reading, parsing and validating of Apex parameters from JSON files. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexParameterHandler { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexParameterHandler.class); + + /** + * Read the parameters from the parameter file. + * + * @param arguments the arguments passed to Apex + * @return the parameters read from the configuration file + * @throws ApexParameterException on parameter exceptions + */ + public ApexParameters getParameters(final ApexCommandLineArguments arguments) throws ApexParameterException { + ApexParameters parameters = null; + + // Read the parameters + try { + // Register the adapters for our carrier technologies and event protocols with GSON + // @formatter:off + final Gson gson = new GsonBuilder() + .registerTypeAdapter(EngineParameters .class, new EngineServiceParametersJSONAdapter()) + .registerTypeAdapter(CarrierTechnologyParameters.class, new CarrierTechnologyParametersJSONAdapter()) + .registerTypeAdapter(EventProtocolParameters .class, new EventProtocolParametersJSONAdapter()) + .create(); + // @formatter:on + parameters = gson.fromJson(new FileReader(arguments.getFullConfigurationFilePath()), ApexParameters.class); + } catch (final Exception e) { + final String errorMessage = "error reading parameters from \"" + arguments.getConfigurationFilePath() + + "\"\n" + "(" + e.getClass().getSimpleName() + "):" + e.getMessage(); + LOGGER.error(errorMessage, e); + throw new ApexParameterException(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() + "\""; + LOGGER.error(errorMessage); + throw new ApexParameterException(errorMessage); + } + + // Check if we should override the model file parameter + final String modelFilePath = arguments.getModelFilePath(); + if (modelFilePath != null && modelFilePath.replaceAll("\\s+", "").length() > 0) { + parameters.getEngineServiceParameters().setPolicyModelFileName(modelFilePath); + } + + // validate the parameters + final String validationResult = parameters.validate(); + if (!validationResult.isEmpty()) { + String returnMessage = + "validation error(s) on parameters from \"" + arguments.getConfigurationFilePath() + "\"\n"; + returnMessage += validationResult; + + LOGGER.error(returnMessage); + throw new ApexParameterException(returnMessage); + } + + return parameters; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterRuntimeException.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterRuntimeException.java new file mode 100644 index 000000000..2334a7e60 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterRuntimeException.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters; + +import org.onap.policy.apex.model.basicmodel.concepts.ApexRuntimeException; + +/** + * This exception will be called if an error occurs in Apex parameter handling. + * + * @author Liam Fallon + */ +public class ApexParameterRuntimeException extends ApexRuntimeException { + private static final long serialVersionUID = -8507246953751956974L; + + /** + * Instantiates a new apex parameter handling exception with a message. + * + * @param message the message + */ + public ApexParameterRuntimeException(final String message) { + super(message); + } + + /** + * Instantiates a new apex parameter handling exception with a message and a caused by + * exception. + * + * @param message the message + * @param e the exception that caused this exception to be thrown + */ + public ApexParameterRuntimeException(final String message, final Exception e) { + super(message, e); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterValidator.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterValidator.java new file mode 100644 index 000000000..a8cbe3b46 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameterValidator.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters; + +/** + * This interface is implemented by Apex parameter classes so that they can be validated. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public interface ApexParameterValidator { + /** + * Validate a parameter java bean, if the parameter bean is valid, an empty string is returned, + * otherwise the string gives details of the invalid parameters. + * + * @return the string with validation errors + */ + String validate(); +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameters.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameters.java new file mode 100644 index 000000000..52c6f4960 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/ApexParameters.java @@ -0,0 +1,357 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.onap.policy.apex.context.parameters.ContextParameters; +import org.onap.policy.apex.model.basicmodel.service.AbstractParameters; +import org.onap.policy.apex.model.basicmodel.service.ParameterService; +import org.onap.policy.apex.service.parameters.engineservice.EngineServiceParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; + +/** + * The main container parameter class for an Apex service. + * <p> + * The following parameters are defined: + * <ol> + * <li>engineServiceParameters: The parameters for the Apex engine service itself, such as the + * number of engine threads to run and the deployment port number to use. + * <li>eventOutputParameters: A map of parameters for event outputs that Apex will use to emit + * events. Apex emits events on all outputs + * <li>eventInputParameters: A map or parameters for event inputs from which Apex will consume + * events. Apex reads events from all its event inputs. + * <li>synchronousEventHandlerParameters: A map of parameters for synchronous event handlers That + * Apex receives events from and replies immediately to those events. + * </ol> + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexParameters extends AbstractParameters implements ApexParameterValidator { + /** + * Constructor to create an apex parameters instance and register the instance with the + * parameter service. + */ + public ApexParameters() { + super(ContextParameters.class.getCanonicalName()); + ParameterService.registerParameters(ApexParameters.class, this); + } + + // Parameters for the engine service and the engine threads in the engine service + private EngineServiceParameters engineServiceParameters; + + // Parameters for the event outputs that Apex will use to send events on its outputs + private Map<String, EventHandlerParameters> eventOutputParameters = new LinkedHashMap<>(); + + // Parameters for the event inputs that Apex will use to receive events on its inputs + private Map<String, EventHandlerParameters> eventInputParameters = new LinkedHashMap<>(); + + /** + * Gets the parameters for the Apex engine service. + * + * @return the engine service parameters + */ + public EngineServiceParameters getEngineServiceParameters() { + return engineServiceParameters; + } + + /** + * Sets the engine service parameters. + * + * @param engineServiceParameters the engine service parameters + */ + public void setEngineServiceParameters(final EngineServiceParameters engineServiceParameters) { + this.engineServiceParameters = engineServiceParameters; + } + + /** + * Gets the event output parameter map. + * + * @return the parameters for all event outputs + */ + public Map<String, EventHandlerParameters> getEventOutputParameters() { + return eventOutputParameters; + } + + /** + * Sets the event output parameters. + * + * @param eventOutputParameters the event outputs parameters + */ + public void setEventOutputParameters(final Map<String, EventHandlerParameters> eventOutputParameters) { + this.eventOutputParameters = eventOutputParameters; + } + + /** + * Gets the event input parameter map. + * + * @return the parameters for all event inputs + */ + public Map<String, EventHandlerParameters> getEventInputParameters() { + return eventInputParameters; + } + + /** + * Sets the event input parameters. + * + * @param eventInputParameters the event input parameters + */ + public void setEventInputParameters(final Map<String, EventHandlerParameters> eventInputParameters) { + this.eventInputParameters = eventInputParameters; + } + + /** + * This method formats a validation result with a header if the result is not empty. + * + * @param validationResultMessage The incoming message + * @param heading The heading to prepend on the message + * @return the formatted message + */ + private String validationResultFormatter(final String validationResultMessage, final String heading) { + final StringBuilder errorMessageBuilder = new StringBuilder(); + + if (validationResultMessage.length() > 0) { + errorMessageBuilder.append(heading); + errorMessageBuilder.append(validationResultMessage); + } + + return errorMessageBuilder.toString(); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.apps.uservice.parameters.ApexParameterValidator#validate() + */ + @Override + public String validate() { + final StringBuilder errorMessageBuilder = new StringBuilder(); + + if (engineServiceParameters == null) { + errorMessageBuilder.append(" engine service parameters are not specified\n"); + } else { + errorMessageBuilder.append(validationResultFormatter(engineServiceParameters.validate(), + " engine service parameters invalid\n")); + } + + // Sanity check, we must have an entry in both output and input maps + if (eventOutputParameters.isEmpty() || eventInputParameters.isEmpty()) { + errorMessageBuilder.append(" at least one event output and one event input must be specified\n"); + } + + // Validate that the values of all parameters are ok + validateEventHandlerMap("event input", errorMessageBuilder, eventInputParameters); + validateEventHandlerMap("event output", errorMessageBuilder, eventOutputParameters); + + // Only do peer mode validate if there are no other errors + if (errorMessageBuilder.length() == 0) { + for (final EventHandlerPeeredMode peeredMode : EventHandlerPeeredMode.values()) { + validatePeeredMode(errorMessageBuilder, peeredMode); + } + } + + // Check if we have any errors + if (errorMessageBuilder.length() > 0) { + errorMessageBuilder.insert(0, "Apex parameters invalid\n"); + } + + return errorMessageBuilder.toString().trim(); + } + + /** + * This method validates the parameters in an event handler map. + * + * @param eventHandlerType the type of the event handler to use on error messages + * @param errorMessageBuilder the builder to use to return validation messages + * @param parsForValidation The event handler parameters to validate (input or output) + */ + // CHECKSTYLE:OFF: checkstyle:finalParameter + private void validateEventHandlerMap(final String eventHandlerType, final StringBuilder errorMessageBuilder, + final Map<String, EventHandlerParameters> parsForValidation) { + // CHECKSTYLE:ON: checkstyle:finalParameter + for (final Entry<String, EventHandlerParameters> parameterEntry : parsForValidation.entrySet()) { + if (parameterEntry.getKey() == null || parameterEntry.getKey().trim().isEmpty()) { + errorMessageBuilder + .append(" invalid " + eventHandlerType + " name \"" + parameterEntry.getKey() + "\" \n"); + } else if (parameterEntry.getValue() == null) { + errorMessageBuilder.append(" invalid/Null event input prameters specified for " + eventHandlerType + + " name \"" + parameterEntry.getKey() + "\" \n"); + } else { + errorMessageBuilder.append(validationResultFormatter(parameterEntry.getValue().validate(), + " " + eventHandlerType + " (" + parameterEntry.getKey() + ") parameters invalid\n")); + } + + parameterEntry.getValue().setName(parameterEntry.getKey()); + + // Validate parameters for peered mode settings + for (final EventHandlerPeeredMode peeredMode : EventHandlerPeeredMode.values()) { + validatePeeredModeParameters(eventHandlerType, errorMessageBuilder, parameterEntry, peeredMode); + } + } + } + + /** + * Validate parameter values for event handlers in a peered mode + * + * @param eventHandlerType The event handler type we are checking + * @param errorMessageBuilder The builder to which to append any error messages + * @param parameterEntry The entry to check the peered mode on + * @param peeredMode The mode to check + */ + private void validatePeeredModeParameters(final String eventHandlerType, final StringBuilder errorMessageBuilder, + final Entry<String, EventHandlerParameters> parameterEntry, final EventHandlerPeeredMode peeredMode) { + final String messagePreamble = " specified peered mode \"" + peeredMode + "\""; + final String peer = parameterEntry.getValue().getPeer(peeredMode); + + if (parameterEntry.getValue().isPeeredMode(peeredMode)) { + if (peer == null || peer.trim().isEmpty()) { + errorMessageBuilder.append(messagePreamble + " mandatory parameter not specified or is null on " + + eventHandlerType + " \"" + parameterEntry.getKey() + "\" \n"); + } + if (parameterEntry.getValue().getPeerTimeout(peeredMode) < 0) { + errorMessageBuilder.append( + messagePreamble + " timeout value \"" + parameterEntry.getValue().getPeerTimeout(peeredMode) + + "\" is illegal on " + eventHandlerType + " \"" + parameterEntry.getKey() + + "\", specify a non-negative timeout value in milliseconds\n"); + } + } else { + if (peer != null) { + errorMessageBuilder.append(messagePreamble + " peer is illegal on non synchronous " + eventHandlerType + + " \"" + parameterEntry.getKey() + "\" \n"); + } + if (parameterEntry.getValue().getPeerTimeout(peeredMode) != 0) { + errorMessageBuilder.append(messagePreamble + " timeout is illegal on non synchronous " + + eventHandlerType + " \"" + parameterEntry.getKey() + "\" \n"); + } + } + } + + /** + * This method validates that the settings are valid for the given peered mode + * + * @param errorMessageBuilder The builder to which to append any error messages + * @param peeredMode The peered mode to check + */ + private void validatePeeredMode(final StringBuilder errorMessageBuilder, final EventHandlerPeeredMode peeredMode) { + // Find the input and output event handlers that use this peered mode + final Map<String, EventHandlerParameters> inputParametersUsingMode = new HashMap<>(); + final Map<String, EventHandlerParameters> outputParametersUsingMode = new HashMap<>(); + + // Find input and output parameters using this mode + for (final Entry<String, EventHandlerParameters> inputParameterEntry : eventInputParameters.entrySet()) { + if (inputParameterEntry.getValue().isPeeredMode(peeredMode)) { + inputParametersUsingMode.put(inputParameterEntry.getKey(), inputParameterEntry.getValue()); + } + } + for (final Entry<String, EventHandlerParameters> outputParameterEntry : eventOutputParameters.entrySet()) { + if (outputParameterEntry.getValue().isPeeredMode(peeredMode)) { + outputParametersUsingMode.put(outputParameterEntry.getKey(), outputParameterEntry.getValue()); + } + } + + // Validate the parameters for each side of the peered mode parameters + validatePeeredModePeers(" event input for peered mode \"" + peeredMode + "\": ", errorMessageBuilder, + peeredMode, inputParametersUsingMode, outputParametersUsingMode); + validatePeeredModePeers(" event output for peered mode \"" + peeredMode + "\": ", errorMessageBuilder, + peeredMode, outputParametersUsingMode, inputParametersUsingMode); + } + + /** + * This method validates that the settings are valid for the event handlers on one + * + * @param messagePreamble the preamble for messages indicating the peered mode side + * @param errorMessageBuilder The builder to which to append any error messages + * @param leftModeParameters The mode parameters being checked + * @param rightModeParameters The mode parameters being referenced by the checked parameters + */ + private void validatePeeredModePeers(final String messagePreamble, final StringBuilder errorMessageBuilder, + final EventHandlerPeeredMode peeredMode, final Map<String, EventHandlerParameters> leftModeParameterMap, + final Map<String, EventHandlerParameters> rightModeParameterMap) { + + // These sets are used to check for duplicate references on the both sides + final Set<String> leftCheckDuplicateSet = new HashSet<>(); + final Set<String> rightCheckDuplicateSet = new HashSet<>(); + + // Check for missing peers, all peers are set because we have checked them previously so no + // need for null checks + for (final Entry<String, EventHandlerParameters> leftModeParameterEntry : leftModeParameterMap.entrySet()) { + final String leftSidePeer = leftModeParameterEntry.getValue().getPeer(peeredMode); + + final EventHandlerParameters leftModeParameters = leftModeParameterEntry.getValue(); + final EventHandlerParameters rightModeParameters = rightModeParameterMap.get(leftSidePeer); + + // Check that the peer reference is OK + if (rightModeParameters == null) { + errorMessageBuilder.append(messagePreamble + "peer \"" + leftModeParameters.getPeer(peeredMode) + + "\" for event handler \"" + leftModeParameterEntry.getKey() + + "\" does not exist or is not defined as being synchronous\n"); + continue; + } + + // Now check that the right side peer is the left side event handler + final String rightSidePeer = rightModeParameters.getPeer(peeredMode); + if (!rightSidePeer.equals(leftModeParameterEntry.getKey())) { + errorMessageBuilder + .append(messagePreamble + "peer value \"" + rightSidePeer + "\" on peer \"" + leftSidePeer + + "\" does not equal event handler \"" + leftModeParameterEntry.getKey() + "\"\n"); + } else { + // Check for duplicates + if (!leftCheckDuplicateSet.add(leftSidePeer)) { + errorMessageBuilder + .append(messagePreamble + "peer value \"" + leftSidePeer + "\" on event handler \"" + + leftModeParameterEntry.getKey() + "\" is used more than once\n"); + } + if (!rightCheckDuplicateSet.add(rightSidePeer)) { + errorMessageBuilder.append(messagePreamble + "peer value \"" + rightSidePeer + "\" on peer \"" + + leftSidePeer + "\" on event handler \"" + leftModeParameterEntry.getKey() + + "\" is used more than once\n"); + } + } + + // Cross-set the timeouts if they are not specified + if (leftModeParameters.getPeerTimeout(peeredMode) != 0) { + if (rightModeParameters.getPeerTimeout(peeredMode) != 0) { + if (leftModeParameters.getPeerTimeout(peeredMode) != rightModeParameters + .getPeerTimeout(peeredMode)) { + errorMessageBuilder.append(messagePreamble + "timeout " + + leftModeParameters.getPeerTimeout(peeredMode) + "on event handler \"" + + leftModeParameters.getName() + "\" does not equal timeout value " + + rightModeParameters.getPeerTimeout(peeredMode) + "on event handler \"" + + rightModeParameters.getName() + "\"\n"); + } + } else { + rightModeParameters.setPeerTimeout(peeredMode, leftModeParameters.getPeerTimeout(peeredMode)); + } + } else { + if (rightModeParameters.getPeerTimeout(peeredMode) != 0) { + leftModeParameters.setPeerTimeout(peeredMode, rightModeParameters.getPeerTimeout(peeredMode)); + } + } + } + + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/carriertechnology/CarrierTechnologyParameters.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/carriertechnology/CarrierTechnologyParameters.java new file mode 100644 index 000000000..ba0327de1 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/carriertechnology/CarrierTechnologyParameters.java @@ -0,0 +1,161 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters.carriertechnology; + +import org.onap.policy.apex.model.basicmodel.service.AbstractParameters; +import org.onap.policy.apex.service.parameters.ApexParameterValidator; + +/** + * The default carrier technology parameter class that may be specialized by carrier technology + * plugins that require plugin specific parameters. + * <p> + * The following parameters are defined: + * <ol> + * <li>label: The label of the carrier technology. + * <li>eventProducerPluginClass: The name of the plugin class that will be used by Apex to produce + * and emit output events for this carrier technology + * <li>eventConsumerPluginClass: The name of the plugin class that will be used by Apex to receive + * and process input events from this carrier technology carrier technology + * </ol> + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public abstract class CarrierTechnologyParameters extends AbstractParameters implements ApexParameterValidator { + + // The carrier technology label + private String label = null; + + // Producer and Consumer plugin classes for the event producer and consumer for this carrier + // technology + private String eventProducerPluginClass = null; + private String eventConsumerPluginClass = null; + + /** + * Constructor to create a carrier technology parameters instance with the name of a sub class + * of this class and register the instance with the parameter service. + * + * @param parameterClassName the class name of a sub class of this class + */ + public CarrierTechnologyParameters(final String parameterClassName) { + super(parameterClassName); + } + + /** + * Gets the label of the carrier technology. + * + * @return the label of the carrier technology + */ + public String getLabel() { + return label; + } + + /** + * Sets the label of the carrier technology. + * + * @param label the label of the carrier technology + */ + public void setLabel(final String label) { + if (label != null) { + this.label = label.replaceAll("\\s+", ""); + } else { + this.label = null; + } + } + + /** + * Gets the event producer plugin class. + * + * @return the event producer plugin class + */ + public String getEventProducerPluginClass() { + return eventProducerPluginClass; + } + + /** + * Sets the event producer plugin class. + * + * @param eventProducerPluginClass the new event producer plugin class + */ + public void setEventProducerPluginClass(final String eventProducerPluginClass) { + if (eventProducerPluginClass != null) { + this.eventProducerPluginClass = eventProducerPluginClass.replaceAll("\\s+", ""); + } else { + this.eventProducerPluginClass = null; + } + } + + /** + * Gets the event consumer plugin class. + * + * @return the event consumer plugin class + */ + public String getEventConsumerPluginClass() { + return eventConsumerPluginClass; + } + + /** + * Sets the event consumer plugin class. + * + * @param eventConsumerPluginClass the new event consumer plugin class + */ + public void setEventConsumerPluginClass(final String eventConsumerPluginClass) { + if (eventConsumerPluginClass != null) { + this.eventConsumerPluginClass = eventConsumerPluginClass.replaceAll("\\s+", ""); + } else { + this.eventConsumerPluginClass = null; + } + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "CarrierTechnologyParameters [label=" + label + ", eventProducerPluginClass=" + eventProducerPluginClass + + ", eventConsumerPluginClass=" + eventConsumerPluginClass + "]"; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.parameters.ApexParameterValidator#validate() + */ + @Override + public String validate() { + final StringBuilder errorMessageBuilder = new StringBuilder(); + + if (label == null || label.length() == 0) { + errorMessageBuilder.append(" carrier technology label not specified or is blank\n"); + } + + if (eventProducerPluginClass == null || eventProducerPluginClass.length() == 0) { + errorMessageBuilder.append(" carrier technology eventProducerPluginClass not specified or is blank\n"); + } + + if (eventConsumerPluginClass == null || eventConsumerPluginClass.length() == 0) { + errorMessageBuilder.append(" carrier technology eventConsumerPluginClass not specified or is blank\n"); + } + + return errorMessageBuilder.toString(); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/carriertechnology/CarrierTechnologyParametersJSONAdapter.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/carriertechnology/CarrierTechnologyParametersJSONAdapter.java new file mode 100644 index 000000000..5aa7d6455 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/carriertechnology/CarrierTechnologyParametersJSONAdapter.java @@ -0,0 +1,176 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters.carriertechnology; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +import org.onap.policy.apex.service.engine.event.impl.eventrequestor.EventRequestorCarrierTechnologyParameters; +import org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.FILECarrierTechnologyParameters; +import org.onap.policy.apex.service.parameters.ApexParameterRuntimeException; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +/** + * This class deserialises various type of carrier technology parameters from JSON. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class CarrierTechnologyParametersJSONAdapter + implements JsonSerializer<CarrierTechnologyParameters>, JsonDeserializer<CarrierTechnologyParameters> { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(CarrierTechnologyParametersJSONAdapter.class); + + private static final String PARAMETER_CLASS_NAME = "parameterClassName"; + + private static final String CARRIER_TECHNOLOGY_TOKEN = "carrierTechnology"; + private static final String CARRIER_TECHNOLOGY_PARAMETERS = "parameters"; + + // Built in technology parameters + private static final Map<String, String> BUILT_IN_CARRIER_TECHNOLOGY_PARMETER_CLASS_MAP = new HashMap<>(); + static { + BUILT_IN_CARRIER_TECHNOLOGY_PARMETER_CLASS_MAP.put("FILE", + FILECarrierTechnologyParameters.class.getCanonicalName()); + BUILT_IN_CARRIER_TECHNOLOGY_PARMETER_CLASS_MAP.put("EVENT_REQUESTOR", + EventRequestorCarrierTechnologyParameters.class.getCanonicalName()); + } + + /* + * (non-Javadoc) + * + * @see com.google.gson.JsonSerializer#serialize(java.lang.Object, java.lang.reflect.Type, + * com.google.gson.JsonSerializationContext) + */ + @Override + public JsonElement serialize(final CarrierTechnologyParameters src, final Type typeOfSrc, + final JsonSerializationContext context) { + final String returnMessage = "serialization of Apex carrier technology parameters to Json is not supported"; + LOGGER.error(returnMessage); + throw new ApexParameterRuntimeException(returnMessage); + } + + /* + * (non-Javadoc) + * + * @see com.google.gson.JsonDeserializer#deserialize(com.google.gson.JsonElement, + * java.lang.reflect.Type, com.google.gson.JsonDeserializationContext) + */ + @Override + public CarrierTechnologyParameters deserialize(final JsonElement json, final Type typeOfT, + final JsonDeserializationContext context) throws JsonParseException { + final JsonObject jsonObject = json.getAsJsonObject(); + + // Get the carrier technology label primitive + final JsonPrimitive labelJsonPrimitive = (JsonPrimitive) jsonObject.get(CARRIER_TECHNOLOGY_TOKEN); + + // Check if we found our carrier technology + if (labelJsonPrimitive == null) { + LOGGER.warn("carrier technology parameter \"" + CARRIER_TECHNOLOGY_TOKEN + "\" not found in JSON file"); + return null; + } + + // Get and check the carrier technology label + final String carrierTechnologyLabel = labelJsonPrimitive.getAsString().replaceAll("\\s+", ""); + if (carrierTechnologyLabel == null || carrierTechnologyLabel.length() == 0) { + final String errorMessage = "carrier technology parameter \"" + CARRIER_TECHNOLOGY_TOKEN + "\" value \"" + + labelJsonPrimitive.getAsString() + "\" invalid in JSON file"; + LOGGER.warn(errorMessage); + throw new ApexParameterRuntimeException(errorMessage); + } + + // We now get the technology carrier parameter class + String carrierTechnologyParameterClassName = null; + + // Get the technology carrier parameter class for the carrier technology plugin class from + // the configuration parameters + final JsonPrimitive classNameJsonPrimitive = (JsonPrimitive) jsonObject.get(PARAMETER_CLASS_NAME); + + // If no technology carrier parameter class was specified, we try to use a built in carrier + // technology + if (classNameJsonPrimitive == null) { + carrierTechnologyParameterClassName = + BUILT_IN_CARRIER_TECHNOLOGY_PARMETER_CLASS_MAP.get(carrierTechnologyLabel); + } else { + // We use the specified one + carrierTechnologyParameterClassName = classNameJsonPrimitive.getAsString().replaceAll("\\s+", ""); + } + + // Check the carrier technology parameter class + if (carrierTechnologyParameterClassName == null || carrierTechnologyParameterClassName.length() == 0) { + final String errorMessage = + "carrier technology \"" + carrierTechnologyLabel + "\" parameter \"" + PARAMETER_CLASS_NAME + + "\" value \"" + classNameJsonPrimitive.getAsString() + "\" invalid in JSON file"; + LOGGER.warn(errorMessage); + throw new ApexParameterRuntimeException(errorMessage); + } + + // Get the class for the carrier technology + Class<?> carrierTechnologyParameterClass = null; + try { + carrierTechnologyParameterClass = Class.forName(carrierTechnologyParameterClassName); + } catch (final ClassNotFoundException e) { + final String errorMessage = + "carrier technology \"" + carrierTechnologyLabel + "\" parameter \"" + PARAMETER_CLASS_NAME + + "\" value \"" + carrierTechnologyParameterClassName + "\", could not find class"; + LOGGER.warn(errorMessage, e); + throw new ApexParameterRuntimeException(errorMessage, e); + } + + // Deserialise the class + CarrierTechnologyParameters carrierTechnologyParameters = + context.deserialize(jsonObject.get(CARRIER_TECHNOLOGY_PARAMETERS), carrierTechnologyParameterClass); + if (carrierTechnologyParameters == null) { + // OK no parameters for the carrier technology have been specified, just instantiate the + // default parameters + try { + carrierTechnologyParameters = + (CarrierTechnologyParameters) carrierTechnologyParameterClass.newInstance(); + } catch (final Exception e) { + final String errorMessage = "could not create default parameters for carrier technology \"" + + carrierTechnologyLabel + "\"\n" + e.getMessage(); + LOGGER.warn(errorMessage, e); + throw new ApexParameterRuntimeException(errorMessage, e); + } + } + + // Check that the carrier technology label matches the label in the carrier technology + // parameters object + if (!carrierTechnologyParameters.getLabel().equals(carrierTechnologyLabel)) { + final String errorMessage = "carrier technology \"" + carrierTechnologyLabel + "\" does not match plugin \"" + + carrierTechnologyParameters.getLabel() + "\" in \"" + carrierTechnologyParameterClassName + + "\", specify correct carrier technology parameter plugin in parameter \"" + PARAMETER_CLASS_NAME + + "\""; + LOGGER.warn(errorMessage); + throw new ApexParameterRuntimeException(errorMessage); + } + + return carrierTechnologyParameters; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/carriertechnology/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/carriertechnology/package-info.java new file mode 100644 index 000000000..5912c0129 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/carriertechnology/package-info.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Defines the structure of carrier technology parameters for APEX. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.parameters.carriertechnology; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/engineservice/EngineServiceParameters.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/engineservice/EngineServiceParameters.java new file mode 100644 index 000000000..6b60732c3 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/engineservice/EngineServiceParameters.java @@ -0,0 +1,329 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters.engineservice; + +import java.io.File; +import java.net.URL; + +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.basicmodel.service.AbstractParameters; +import org.onap.policy.apex.model.basicmodel.service.ParameterService; +import org.onap.policy.apex.model.utilities.ResourceUtils; +import org.onap.policy.apex.service.parameters.ApexParameterValidator; + +import org.onap.policy.apex.core.engine.EngineParameters; + +/** + * This class holds the parameters for an Apex Engine Service with multiple engine threads running + * multiple engines. + * + * <p> + * The following parameters are defined: + * <ol> + * <li>name: The name of the Apex engine service, which can be set to any value that matches the + * regular expression {@link org.onap.policy.apex.model.basicmodel.concepts.AxKey#NAME_REGEXP}. + * <li>version: The name of the Apex engine service, which can be set to any value that matches the + * regular expression {@link org.onap.policy.apex.model.basicmodel.concepts.AxKey#VERSION_REGEXP}. + * <li>id: The ID of the Apex engine service, which can be set to any integer value by a user. + * <li>instanceCount: The number of Apex engines to spawn in this engine service. Each engine + * executes in its own thread. + * <li>deploymentPort: The port that the Apex Engine Service will open so that it can be managed + * using the EngDep protocol. The EngDep protocol allows the engine service to be monitored, to + * start and stop engines in the engine service, and to update the policy model of the engine + * service. + * <li>engineParameters: Parameters (a {@link EngineParameters} instance) that all of the engines in + * the engine service will use. All engine threads use the same parameters and act as a pool of + * engines. Engine parameters specify the executors and context management for the engines. + * <li>policyModelFileName: The full path to the policy model file name to deploy on the engine + * service. + * <li>periodicEventPeriod: The period in milliseconds at which the periodic event PERIOIC_EVENT + * will be generated by APEX, 0 means no periodic event generation, negative values are illegal. + * </ol> + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class EngineServiceParameters extends AbstractParameters implements ApexParameterValidator { + private static final int MAX_PORT = 65535; + + // @formatter:off + /** The default name of the Apex engine service. */ + public static final String DEFAULT_NAME = "ApexEngineService"; + + /** The default version of the Apex engine service. */ + public static final String DEFAULT_VERSION = "1.0.0"; + + /** The default ID of the Apex engine service. */ + public static final int DEFAULT_ID = -1; + + /** The default instance count for the Apex engine service. */ + public static final int DEFAULT_INSTANCE_COUNT = 1; + + /** The default EngDep deployment port of the Apex engine service. */ + public static final int DEFAULT_DEPLOYMENT_PORT = 34421; + + // Apex engine service parameters + private String name = DEFAULT_NAME; + private String version = DEFAULT_VERSION; + private int id = DEFAULT_ID; + private int instanceCount = DEFAULT_INSTANCE_COUNT; + private int deploymentPort = DEFAULT_DEPLOYMENT_PORT; + private String policyModelFileName = null; + private long periodicEventPeriod = 0; + // @formatter:on + + // Apex engine internal parameters + private EngineParameters engineParameters = new EngineParameters(); + + /** + * Constructor to create an apex engine service parameters instance and register the instance + * with the parameter service. + */ + public EngineServiceParameters() { + super(EngineServiceParameters.class.getCanonicalName()); + ParameterService.registerParameters(EngineServiceParameters.class, this); + } + + /** + * Gets the key of the Apex engine service. + * + * @return the Apex engine service key + */ + public AxArtifactKey getEngineKey() { + return new AxArtifactKey(name, version); + } + + /** + * Sets the key of the Apex engine service. + * + * @param key the the Apex engine service key + */ + public void setEngineKey(final AxArtifactKey key) { + this.setName(key.getName()); + this.setVersion(key.getVersion()); + } + + /** + * Gets the name of the engine service. + * + * @return the name of the engine service + */ + public String getName() { + return name; + } + + /** + * Sets the name of the engine service. + * + * @param name the name of the engine service + */ + public void setName(final String name) { + this.name = name; + } + + /** + * Gets the version of the engine service. + * + * @return the version of the engine service + */ + public String getVersion() { + return version; + } + + /** + * Sets the version of the engine service. + * + * @param version the version of the engine service + */ + public void setVersion(final String version) { + this.version = version; + } + + /** + * Gets the id of the engine service. + * + * @return the id of the engine service + */ + public int getId() { + return id; + } + + /** + * Sets the id of the engine service. + * + * @param id the id of the engine service + */ + public void setId(final int id) { + this.id = id; + } + + /** + * Gets the instance count of the engine service. + * + * @return the instance count of the engine service + */ + public int getInstanceCount() { + return instanceCount; + } + + /** + * Sets the instance count of the engine service. + * + * @param instanceCount the instance count of the engine service + */ + public void setInstanceCount(final int instanceCount) { + this.instanceCount = instanceCount; + } + + /** + * Gets the deployment port of the engine service. + * + * @return the deployment port of the engine service + */ + public int getDeploymentPort() { + return deploymentPort; + } + + /** + * Sets the deployment port of the engine service. + * + * @param deploymentPort the deployment port of the engine service + */ + public void setDeploymentPort(final int deploymentPort) { + this.deploymentPort = deploymentPort; + } + + /** + * Gets the file name of the policy engine for deployment on the engine service. + * + * @return the file name of the policy engine for deployment on the engine service + */ + public String getPolicyModelFileName() { + return ResourceUtils.getFilePath4Resource(policyModelFileName); + } + + /** + * Sets the file name of the policy engine for deployment on the engine service. + * + * @param policyModelFileName the file name of the policy engine for deployment on the engine + * service + */ + public void setPolicyModelFileName(final String policyModelFileName) { + this.policyModelFileName = policyModelFileName; + } + + /** + * Get the period in milliseconds at which periodic events are sent, zero means no periodic + * events are being sent. + * + * @return the periodic period + */ + public long getPeriodicEventPeriod() { + return periodicEventPeriod; + } + + /** + * Set the period in milliseconds at which periodic events are sent, zero means no periodic + * events are to be sent, negative values are illegal. + * + * @param periodicEventPeriod the periodic period + */ + public void setPeriodicEventPeriod(final long periodicEventPeriod) { + this.periodicEventPeriod = periodicEventPeriod; + } + + /** + * Gets the engine parameters for engines in the engine service. + * + * @return the engine parameters for engines in the engine service + */ + public EngineParameters getEngineParameters() { + return engineParameters; + } + + /** + * Sets the engine parameters for engines in the engine service. + * + * @param engineParameters the engine parameters for engines in the engine service + */ + public void setEngineParameters(final EngineParameters engineParameters) { + this.engineParameters = engineParameters; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.apps.uservice.parameters.ApexParameterValidator#validate() + */ + @Override + public String validate() { + final StringBuilder errorMessageBuilder = new StringBuilder(); + + try { + new AxArtifactKey(name, version); + } catch (final Exception e) { + errorMessageBuilder.append(" name [" + name + "] and/or version [" + version + "] invalid\n"); + errorMessageBuilder.append(" " + e.getMessage() + "\n"); + } + + if (id < 0) { + errorMessageBuilder.append( + " id not specified or specified value [" + id + "] invalid, must be specified as id >= 0\n"); + } + + if (instanceCount < 1) { + errorMessageBuilder.append( + " instanceCount [" + instanceCount + "] invalid, must be specified as instanceCount >= 1\n"); + } + + if (deploymentPort < 1 || deploymentPort > MAX_PORT) { + errorMessageBuilder.append( + " deploymentPort [" + deploymentPort + "] invalid, must be specified as 1024 <= port <= 65535\n"); + } + + if (policyModelFileName != null) { + if (policyModelFileName.trim().length() == 0) { + errorMessageBuilder.append(" policyModelFileName [" + policyModelFileName + + "] invalid, must be specified as a non-empty string\n"); + } else { + // The file name can refer to a resource on the local file system or on the class + // path + final URL fileURL = ResourceUtils.getURL4Resource(policyModelFileName); + if (fileURL == null) { + errorMessageBuilder.append( + " policyModelFileName [" + policyModelFileName + "] not found or is not a plain file\n"); + } else { + final File policyModelFile = new File(fileURL.getPath()); + if (!policyModelFile.isFile()) { + errorMessageBuilder.append(" policyModelFileName [" + policyModelFileName + + "] not found or is not a plain file\n"); + } + } + } + } + + if (periodicEventPeriod < 0) { + errorMessageBuilder.append(" periodicEventPeriod [" + periodicEventPeriod + + "] invalid, must be specified in milliseconds as >=0\n"); + } + + return errorMessageBuilder.toString(); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/engineservice/EngineServiceParametersJSONAdapter.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/engineservice/EngineServiceParametersJSONAdapter.java new file mode 100644 index 000000000..9fca2fd19 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/engineservice/EngineServiceParametersJSONAdapter.java @@ -0,0 +1,287 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters.engineservice; + +import java.lang.reflect.Type; +import java.util.Map.Entry; + +import org.onap.policy.apex.context.impl.schema.java.JavaSchemaHelperParameters; +import org.onap.policy.apex.context.parameters.ContextParameters; +import org.onap.policy.apex.context.parameters.DistributorParameters; +import org.onap.policy.apex.context.parameters.LockManagerParameters; +import org.onap.policy.apex.context.parameters.PersistorParameters; +import org.onap.policy.apex.context.parameters.SchemaHelperParameters; +import org.onap.policy.apex.context.parameters.SchemaParameters; +import org.onap.policy.apex.core.engine.EngineParameters; +import org.onap.policy.apex.core.engine.ExecutorParameters; +import org.onap.policy.apex.model.basicmodel.service.AbstractParameters; +import org.onap.policy.apex.service.parameters.ApexParameterRuntimeException; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +/** + * This class deserializes engine service parameters from JSON format. The class produces an + * {@link EngineServiceParameters} instance from incoming JSON read from a configuration file in + * JSON format. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class EngineServiceParametersJSONAdapter + implements JsonSerializer<EngineParameters>, JsonDeserializer<EngineParameters> { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(EngineServiceParametersJSONAdapter.class); + + private static final String PARAMETER_CLASS_NAME = "parameterClassName"; + + // @formatter:off + private static final String CONTEXT_PARAMETERS = "contextParameters"; + private static final String DISTRIBUTOR_PARAMETERS = "distributorParameters"; + private static final String LOCK_MANAGER_PARAMETERS = "lockManagerParameters"; + private static final String PERSISTOR_PARAMETERS = "persistorParameters"; + private static final String SCHEMA_PARAMETERS = "schemaParameters"; + private static final String EXECUTOR_PARAMETERS = "executorParameters"; + // @formatter:on + + /* + * (non-Javadoc) + * + * @see com.google.gson.JsonSerializer#serialize(java.lang.Object, java.lang.reflect.Type, + * com.google.gson.JsonSerializationContext) + */ + @Override + public JsonElement serialize(final EngineParameters src, final Type typeOfSrc, + final JsonSerializationContext context) { + final String returnMessage = "serialization of Apex parameters to Json is not supported"; + LOGGER.error(returnMessage); + throw new ApexParameterRuntimeException(returnMessage); + } + + /* + * (non-Javadoc) + * + * @see com.google.gson.JsonDeserializer#deserialize(com.google.gson.JsonElement, + * java.lang.reflect.Type, com.google.gson.JsonDeserializationContext) + */ + @Override + public EngineParameters deserialize(final JsonElement json, final Type typeOfT, + final JsonDeserializationContext context) throws JsonParseException { + final JsonObject engineParametersJsonObject = json.getAsJsonObject(); + + final EngineParameters engineParameters = new EngineParameters(); + + // Deserialise context parameters, they may be a subclass of the ContextParameters class + engineParameters.setContextParameters( + (ContextParameters) context.deserialize(engineParametersJsonObject, ContextParameters.class)); + + // Context parameter wrangling + getContextParameters(engineParametersJsonObject, engineParameters, context); + + // Executor parameter wrangling + getExecutorParameters(engineParametersJsonObject, engineParameters, context); + + return engineParameters; + } + + /** + * Get the context parameters for Apex. + * + * @param engineParametersJsonObject The input JSON + * @param engineParameters The output parameters + * @param context the JSON context + */ + private void getContextParameters(final JsonObject engineParametersJsonObject, + final EngineParameters engineParameters, final JsonDeserializationContext context) { + final JsonElement contextParametersElement = engineParametersJsonObject.get(CONTEXT_PARAMETERS); + + // Context parameters are optional so if the element does not exist, just return + if (contextParametersElement == null) { + return; + } + + // We do this because the JSON parameters may be for a subclass of ContextParameters + final ContextParameters contextParameters = + (ContextParameters) deserializeParameters(CONTEXT_PARAMETERS, contextParametersElement, context); + + // We know this will work because if the context parameters was not a Json object, the + // previous deserializeParameters() call would not have worked + final JsonObject contextParametersObject = engineParametersJsonObject.get(CONTEXT_PARAMETERS).getAsJsonObject(); + + // Now get the distributor, lock manager, and persistence parameters + final JsonElement distributorParametersElement = contextParametersObject.get(DISTRIBUTOR_PARAMETERS); + if (distributorParametersElement != null) { + contextParameters + .setDistributorParameters((DistributorParameters) deserializeParameters(DISTRIBUTOR_PARAMETERS, + distributorParametersElement, context)); + } + + final JsonElement lockManagerParametersElement = contextParametersObject.get(LOCK_MANAGER_PARAMETERS); + if (lockManagerParametersElement != null) { + contextParameters + .setLockManagerParameters((LockManagerParameters) deserializeParameters(LOCK_MANAGER_PARAMETERS, + lockManagerParametersElement, context)); + } + + final JsonElement persistorParametersElement = contextParametersObject.get(PERSISTOR_PARAMETERS); + if (persistorParametersElement != null) { + contextParameters.setPersistorParameters((PersistorParameters) deserializeParameters(PERSISTOR_PARAMETERS, + persistorParametersElement, context)); + } + + // Schema Handler parameter wrangling + getSchemaHandlerParameters(contextParametersObject, contextParameters, context); + + // Get the engine plugin parameters + engineParameters.setContextParameters(contextParameters); + } + + /** + * Get the executor parameters for Apex. + * + * @param engineParametersJsonObject The input JSON + * @param engineParameters The output parameters + * @param context the JSON context + */ + private void getExecutorParameters(final JsonObject engineParametersJsonObject, + final EngineParameters engineParameters, final JsonDeserializationContext context) { + final JsonElement executorParametersElement = engineParametersJsonObject.get(EXECUTOR_PARAMETERS); + + // Executor parameters are mandatory so if the element does not exist throw an exception + if (executorParametersElement == null) { + final String returnMessage = "no \"" + EXECUTOR_PARAMETERS + + "\" entry found in parameters, at least one executor parameter entry must be specified"; + LOGGER.error(returnMessage); + throw new ApexParameterRuntimeException(returnMessage); + } + + // Deserialize the executor parameters + final JsonObject executorParametersJsonObject = + engineParametersJsonObject.get(EXECUTOR_PARAMETERS).getAsJsonObject(); + + for (final Entry<String, JsonElement> executorEntries : executorParametersJsonObject.entrySet()) { + final ExecutorParameters executorParameters = + (ExecutorParameters) deserializeParameters(EXECUTOR_PARAMETERS + ':' + executorEntries.getKey(), + executorEntries.getValue(), context); + engineParameters.getExecutorParameterMap().put(executorEntries.getKey(), executorParameters); + } + } + + /** + * Get the schema parameters for Apex. + * + * @param contextParametersJsonObject The input JSON + * @param contextParameters The output parameters + * @param context the JSON context + */ + private void getSchemaHandlerParameters(final JsonObject contextParametersJsonObject, + final ContextParameters contextParameters, final JsonDeserializationContext context) { + final JsonElement schemaParametersElement = contextParametersJsonObject.get(SCHEMA_PARAMETERS); + + // Insert the default Java schema helper + contextParameters.getSchemaParameters().getSchemaHelperParameterMap() + .put(SchemaParameters.DEFAULT_SCHEMA_FLAVOUR, new JavaSchemaHelperParameters()); + + // Context parameters are optional so if the element does not exist, just return + if (schemaParametersElement == null) { + return; + } + + // Deserialize the executor parameters + final JsonObject schemaHelperParametersJsonObject = + contextParametersJsonObject.get(SCHEMA_PARAMETERS).getAsJsonObject(); + + for (final Entry<String, JsonElement> schemaHelperEntries : schemaHelperParametersJsonObject.entrySet()) { + contextParameters.getSchemaParameters().getSchemaHelperParameterMap().put(schemaHelperEntries.getKey(), + (SchemaHelperParameters) deserializeParameters( + SCHEMA_PARAMETERS + ':' + schemaHelperEntries.getKey(), schemaHelperEntries.getValue(), + context)); + } + } + + /** + * Deserialize a parameter object that's a superclass of the AbstractParameters class. + * + * @param parametersLabel Label to use for error messages + * @param parametersElement The JSON object holding the parameters + * @param context The GSON context + * @return the parameters + * @throws ApexParameterRuntimeException on errors reading the parameters + */ + private AbstractParameters deserializeParameters(final String parametersLabel, final JsonElement parametersElement, + final JsonDeserializationContext context) throws ApexParameterRuntimeException { + JsonObject parametersObject = null; + + // Check that the JSON element is a JSON object + if (parametersElement.isJsonObject()) { + parametersObject = parametersElement.getAsJsonObject(); + } else { + final String returnMessage = "value of \"" + parametersLabel + "\" entry is not a parameter JSON object"; + LOGGER.error(returnMessage); + throw new ApexParameterRuntimeException(returnMessage); + } + + // Get the parameter class name for instantiation in deserialization + final JsonElement parameterClassNameElement = parametersObject.get(PARAMETER_CLASS_NAME); + if (parameterClassNameElement == null) { + final String returnMessage = + "could not find field \"" + PARAMETER_CLASS_NAME + "\" in \"" + parametersLabel + "\" entry"; + LOGGER.error(returnMessage); + throw new ApexParameterRuntimeException(returnMessage); + } + + // Check the parameter is a JSON primitive + if (!parameterClassNameElement.isJsonPrimitive()) { + final String returnMessage = "value for field \"" + PARAMETER_CLASS_NAME + "\" in \"" + parametersLabel + + "\" entry is not a plain string"; + LOGGER.error(returnMessage); + throw new ApexParameterRuntimeException(returnMessage); + } + + // Check the parameter has a value + final String parameterClassName = parameterClassNameElement.getAsString(); + if (parameterClassName == null || parameterClassName.trim().length() == 0) { + final String returnMessage = "value for field \"" + PARAMETER_CLASS_NAME + "\" in \"" + parametersLabel + + "\" entry is not specified or is blank"; + LOGGER.error(returnMessage); + throw new ApexParameterRuntimeException(returnMessage); + } + + // Deserialize the parameters using GSON + AbstractParameters parameters = null; + try { + parameters = context.deserialize(parametersObject, Class.forName(parameterClassName)); + } catch (JsonParseException | ClassNotFoundException e) { + final String returnMessage = + "failed to deserialize the parameters for \"" + parametersLabel + "\" " + "to parameter class \"" + + parameterClassName + "\"\n" + e.getClass().getCanonicalName() + ": " + e.getMessage(); + LOGGER.error(returnMessage, e); + throw new ApexParameterRuntimeException(returnMessage, e); + } + + return parameters; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/engineservice/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/engineservice/package-info.java new file mode 100644 index 000000000..e724ce41c --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/engineservice/package-info.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Defines the parameters for the APEX Engine Service and for engines running in the engine service. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.parameters.engineservice; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventhandler/EventHandlerParameters.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventhandler/EventHandlerParameters.java new file mode 100644 index 000000000..34589f31b --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventhandler/EventHandlerParameters.java @@ -0,0 +1,362 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters.eventhandler; + +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import org.onap.policy.apex.model.basicmodel.service.AbstractParameters; +import org.onap.policy.apex.service.parameters.ApexParameterValidator; +import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters; + +/** + * The parameters for a single event producer, event consumer or synchronous event handler. + * <p> + * Event producers, consumers, and synchronous event handlers all use a carrier technology and an + * event protocol so the actual parameters for each one are the same. Therefore, we use the same + * class for the parameters of each one. + * <p> + * The following parameters are defined: + * <ol> + * <li>carrierTechnologyParameters: The carrier technology is the type of messaging infrastructure + * used to carry events. Examples are File, Kafka or REST. + * <li>eventProtocolParameters: The format that the events are in when being carried. Examples are + * JSON, XML, or Java Beans. carrier technology + * <li>synchronousMode: true if the event handler is working in synchronous mode, defaults to false + * <li>synchronousPeer: the peer event handler (consumer for producer or producer for consumer) of + * this event handler in synchronous mode + * <li>synchronousTimeout: the amount of time to wait for the reply to synchronous events before + * they are timed out + * <li>requestorMode: true if the event handler is working in requestor mode, defaults to false + * <li>requestorPeer: the peer event handler (consumer for producer or producer for consumer) of + * this event handler in requestor mode + * <li>requestorTimeout: the amount of time to wait for the reply to synchronous events before they + * are timed out + * <li>eventNameFilter: a regular expression to apply to events on this event handler. If specified, + * events not matching the given regular expression are ignored. If it is null, all events are + * handledDefaults to null. + * </ol> + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class EventHandlerParameters extends AbstractParameters implements ApexParameterValidator { + private String name = null; + private CarrierTechnologyParameters carrierTechnologyParameters = null; + private EventProtocolParameters eventProtocolParameters = null; + private boolean synchronousMode = false; + private String synchronousPeer = null; + private long synchronousTimeout = 0; + private boolean requestorMode = false; + private String requestorPeer = null; + private long requestorTimeout = 0; + private String eventName = null; + private String eventNameFilter = null; + + /** + * Constructor to create an event handler parameters instance. + */ + public EventHandlerParameters() { + super(EventHandlerParameters.class.getCanonicalName()); + } + + /** + * Constructor to create an event handler parameters instance with the name of a sub class of + * this class. + * + * @param parameterClassName the class name of a sub class of this class + */ + public EventHandlerParameters(final String parameterClassName) { + super(parameterClassName); + } + + /** + * Gets the name of the event handler. + * + * @return the event handler name + */ + public String getName() { + return name; + } + + /** + * Sets the name of the event handler. + * + * @param name the event handler name + */ + public void setName(final String name) { + this.name = name; + } + + /** + * Checks if the name of the event handler is set. + * + * @return true if the name is set + */ + public boolean checkSetName() { + return !(name == null || name.trim().length() == 0); + } + + /** + * Gets the carrier technology parameters of the event handler. + * + * @return the carrierTechnologyParameters of the event handler + */ + public CarrierTechnologyParameters getCarrierTechnologyParameters() { + return carrierTechnologyParameters; + } + + /** + * Sets the carrier technology parameters of the event handler. + * + * @param carrierTechnologyParameters the carrierTechnologyParameters to set + */ + public void setCarrierTechnologyParameters(final CarrierTechnologyParameters carrierTechnologyParameters) { + this.carrierTechnologyParameters = carrierTechnologyParameters; + } + + /** + * Gets the event protocol parameters of the event handler. + * + * @return the eventProtocolParameters + */ + public EventProtocolParameters getEventProtocolParameters() { + return eventProtocolParameters; + } + + /** + * Sets the event protocol parameters. + * + * @param eventProtocolParameters the eventProtocolParameters to set + */ + public void setEventProtocolParameters(final EventProtocolParameters eventProtocolParameters) { + this.eventProtocolParameters = eventProtocolParameters; + } + + + /** + * Checks if the event handler is in the given peered mode. + * + * @param peeredMode the peer mode + * @return true, if the event handler is in the peered mode + */ + public boolean isPeeredMode(final EventHandlerPeeredMode peeredMode) { + switch (peeredMode) { + case SYNCHRONOUS: + return synchronousMode; + case REQUESTOR: + return requestorMode; + default: + return false; + } + } + + /** + * Sets a peered mode as true or false on the event handler. + * + * @param peeredMode the peered mode to set + * @param peeredModeValue the value to set the peered mode to + */ + public void setPeeredMode(final EventHandlerPeeredMode peeredMode, final boolean peeredModeValue) { + switch (peeredMode) { + case SYNCHRONOUS: + synchronousMode = peeredModeValue; + return; + case REQUESTOR: + requestorMode = peeredModeValue; + return; + default: + return; + } + } + + /** + * Gets the peer for the event handler in this peered mode. + * + * @param peeredMode the peered mode to get the peer for + * @return the peer + */ + public String getPeer(final EventHandlerPeeredMode peeredMode) { + switch (peeredMode) { + case SYNCHRONOUS: + return synchronousPeer; + case REQUESTOR: + return requestorPeer; + default: + return null; + } + } + + /** + * Sets the peer for the event handler in this peered mode. + * + * @param peeredMode the peered mode to set the peer for + * @param peer the peer + */ + public void setPeer(final EventHandlerPeeredMode peeredMode, final String peer) { + switch (peeredMode) { + case SYNCHRONOUS: + synchronousPeer = peer; + return; + case REQUESTOR: + requestorPeer = peer; + return; + default: + return; + } + } + + /** + * Get the timeout value for the event handler in peered mode. + * + * @param peeredMode the peered mode to get the timeout for + * @return the timeout value + */ + public long getPeerTimeout(final EventHandlerPeeredMode peeredMode) { + switch (peeredMode) { + case SYNCHRONOUS: + return synchronousTimeout; + case REQUESTOR: + return requestorTimeout; + default: + return -1; + } + } + + /** + * Set the timeout value for the event handler in peered mode. + * + * @param peeredMode the peered mode to set the timeout for + * @param timeout the timeout value + */ + public void setPeerTimeout(final EventHandlerPeeredMode peeredMode, final long timeout) { + switch (peeredMode) { + case SYNCHRONOUS: + synchronousTimeout = timeout; + return; + case REQUESTOR: + requestorTimeout = timeout; + return; + default: + return; + } + } + + /** + * Check if an event name is being used. + * + * @return true if an event name is being used + */ + public boolean isSetEventName() { + return eventName != null; + } + + /** + * Gets the event name for this event handler. + * + * @return the event name + */ + public String getEventName() { + return eventName; + } + + /** + * Sets the event name for this event handler. + * + * @param eventName the event name + */ + public void setEventName(final String eventName) { + this.eventName = eventName; + } + + /** + * Check if event name filtering is being used. + * + * @return true if event name filtering is being used + */ + public boolean isSetEventNameFilter() { + return eventNameFilter != null; + } + + /** + * Gets the event name filter for this event handler. + * + * @return the event name filter + */ + public String getEventNameFilter() { + return eventNameFilter; + } + + /** + * Sets the event name filter for this event handler. + * + * @param eventNameFilter the event name filter + */ + public void setEventNameFilter(final String eventNameFilter) { + this.eventNameFilter = eventNameFilter; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.parameters.ApexParameterValidator#validate() + */ + @Override + public String validate() { + final StringBuilder errorMessageBuilder = new StringBuilder(); + + if (eventProtocolParameters == null) { + errorMessageBuilder.append(" event handler eventProtocolParameters not specified or blank\n"); + } else { + errorMessageBuilder.append(eventProtocolParameters.validate()); + } + + if (carrierTechnologyParameters == null) { + errorMessageBuilder.append(" event handler carrierTechnologyParameters not specified or blank\n"); + } else { + errorMessageBuilder.append(carrierTechnologyParameters.validate()); + } + + if (eventNameFilter != null) { + try { + Pattern.compile(eventNameFilter); + } catch (final PatternSyntaxException pse) { + errorMessageBuilder.append(" event handler eventNameFilter is not a valid regular expression: " + + pse.getMessage() + "\n"); + } + } + return errorMessageBuilder.toString(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "EventHandlerParameters [name=" + name + ", carrierTechnologyParameters=" + carrierTechnologyParameters + + ", eventProtocolParameters=" + eventProtocolParameters + ", synchronousMode=" + synchronousMode + + ", synchronousPeer=" + synchronousPeer + ", synchronousTimeout=" + synchronousTimeout + + ", requestorMode=" + requestorMode + ", requestorPeer=" + requestorPeer + ", requestorTimeout=" + + requestorTimeout + ", eventName=" + eventName + ", eventNameFilter=" + eventNameFilter + "]"; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventhandler/EventHandlerPeeredMode.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventhandler/EventHandlerPeeredMode.java new file mode 100644 index 000000000..b7ee667f3 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventhandler/EventHandlerPeeredMode.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters.eventhandler; + +/** + * This enum specifies the peered mode that an event handler may be in. + * + * <p> + * The following values are defined: + * <ol> + * <li>SYNCHRONOUS: The event handler is tied to another event handler for event handling in APEX, + * used for request-response calls where APEX is the receiver. + * <li>REQUESTOR: The event handler is tied another event handler for event handling in APEX, used + * for request-response calls where APEX is the sender. + * </ol> + * + * @author Liam Fallon (liam.fallon@ericsson.com) + * + * @author liam.fallon@ericsson.com + * + */ +public enum EventHandlerPeeredMode { + SYNCHRONOUS, REQUESTOR +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventhandler/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventhandler/package-info.java new file mode 100644 index 000000000..2866358ff --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventhandler/package-info.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Defines the structure of producer parameters for APEX. + * + * @author John Keeney (john.keeney@ericsson.com) + */ +package org.onap.policy.apex.service.parameters.eventhandler; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/EventProtocolParameters.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/EventProtocolParameters.java new file mode 100644 index 000000000..6e66a18e9 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/EventProtocolParameters.java @@ -0,0 +1,123 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters.eventprotocol; + +import org.onap.policy.apex.model.basicmodel.service.AbstractParameters; +import org.onap.policy.apex.service.parameters.ApexParameterValidator; + +/** + * A default event protocol parameter class that may be specialized by event protocol plugins that + * require plugin specific parameters. + * + * <p> + * The following parameters are defined: + * <ol> + * <li>label: The label of the event protocol technology. + * <li>eventProducerPluginClass: The name of the plugin class that will be used by Apex to produce + * and emit output events for this carrier technology + * </ol> + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public abstract class EventProtocolParameters extends AbstractParameters implements ApexParameterValidator { + // The event protocol label + private String label = null; + + // Event protocol converter plugin class for this event protocol + private String eventProtocolPluginClass; + + /** + * Constructor to create an event protocol parameters instance with the name of a sub class of + * this class and register the instance with the parameter service. + * + * @param parameterClassName the class name of a sub class of this class + */ + public EventProtocolParameters(final String parameterClassName) { + super(parameterClassName); + } + + /** + * Gets the label of the event protocol. + * + * @return the label of the event protocol + */ + public String getLabel() { + return label; + } + + /** + * Sets the label of the event protocol. + * + * @param label the label of the event protocol + */ + public void setLabel(final String label) { + this.label = label.replaceAll("\\s+", ""); + } + + /** + * Gets the event event protocol plugin class. + * + * @return the event event protocol plugin class + */ + public String getEventProtocolPluginClass() { + return eventProtocolPluginClass; + } + + /** + * Sets the event event protocol plugin class. + * + * @param eventProtocolPluginClass the event event protocol plugin class + */ + public void setEventProtocolPluginClass(final String eventProtocolPluginClass) { + this.eventProtocolPluginClass = eventProtocolPluginClass.replaceAll("\\s+", ""); + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.model.basicmodel.service.AbstractParameters#toString() + */ + @Override + public String toString() { + return "CarrierTechnologyParameters [label=" + label + ", EventProtocolPluginClass=" + eventProtocolPluginClass + + "]"; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.parameters.ApexParameterValidator#validate() + */ + @Override + public String validate() { + final StringBuilder errorMessageBuilder = new StringBuilder(); + + if (label == null || label.length() == 0) { + errorMessageBuilder.append(" event protocol label not specified or is blank\n"); + } + + if (eventProtocolPluginClass == null || eventProtocolPluginClass.length() == 0) { + errorMessageBuilder.append(" event protocol eventProtocolPluginClass not specified or is blank\n"); + } + + return errorMessageBuilder.toString(); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/EventProtocolParametersJSONAdapter.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/EventProtocolParametersJSONAdapter.java new file mode 100644 index 000000000..c880756b3 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/EventProtocolParametersJSONAdapter.java @@ -0,0 +1,172 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters.eventprotocol; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +import org.onap.policy.apex.service.engine.event.impl.apexprotocolplugin.ApexEventProtocolParameters; +import org.onap.policy.apex.service.engine.event.impl.jsonprotocolplugin.JSONEventProtocolParameters; +import org.onap.policy.apex.service.parameters.ApexParameterRuntimeException; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +/** + * This class serialises and deserialises various type of event protocol parameters to and from + * JSON. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class EventProtocolParametersJSONAdapter + implements JsonSerializer<EventProtocolParameters>, JsonDeserializer<EventProtocolParameters> { + private static final XLogger LOGGER = XLoggerFactory.getXLogger(EventProtocolParametersJSONAdapter.class); + + private static final String PARAMETER_CLASS_NAME = "parameterClassName"; + + private static final String EVENT_PROTOCOL_TOKEN = "eventProtocol"; + private static final String EVENT_PROTOCOL_PARAMETERS = "parameters"; + + // Built in event protocol parameters + private static final Map<String, String> BUILT_IN_EVENT_RPOTOCOL_PARMETER_CLASS_MAP = new HashMap<>(); + static { + BUILT_IN_EVENT_RPOTOCOL_PARMETER_CLASS_MAP.put("JSON", JSONEventProtocolParameters.class.getCanonicalName()); + BUILT_IN_EVENT_RPOTOCOL_PARMETER_CLASS_MAP.put("APEX", ApexEventProtocolParameters.class.getCanonicalName()); + } + + /* + * (non-Javadoc) + * + * @see com.google.gson.JsonSerializer#serialize(java.lang.Object, java.lang.reflect.Type, + * com.google.gson.JsonSerializationContext) + */ + @Override + public JsonElement serialize(final EventProtocolParameters src, final Type typeOfSrc, + final JsonSerializationContext context) { + final String returnMessage = "serialization of Apex event protocol parameters to Json is not supported"; + LOGGER.error(returnMessage); + throw new ApexParameterRuntimeException(returnMessage); + } + + /* + * (non-Javadoc) + * + * @see com.google.gson.JsonDeserializer#deserialize(com.google.gson.JsonElement, + * java.lang.reflect.Type, com.google.gson.JsonDeserializationContext) + */ + @Override + public EventProtocolParameters deserialize(final JsonElement json, final Type typeOfT, + final JsonDeserializationContext context) throws JsonParseException { + final JsonObject jsonObject = json.getAsJsonObject(); + + // Get the event protocol label primitive + final JsonPrimitive labelJsonPrimitive = (JsonPrimitive) jsonObject.get(EVENT_PROTOCOL_TOKEN); + + // Check if we found our event protocol + if (labelJsonPrimitive == null) { + LOGGER.warn("event protocol parameter \"" + EVENT_PROTOCOL_TOKEN + "\" not found in JSON file"); + return null; + } + + // Get and check the event protocol label + final String eventProtocolLabel = labelJsonPrimitive.getAsString().replaceAll("\\s+", ""); + if (eventProtocolLabel == null || eventProtocolLabel.length() == 0) { + final String errorMessage = "event protocol parameter \"" + EVENT_PROTOCOL_TOKEN + "\" value \"" + + labelJsonPrimitive.getAsString() + "\" invalid in JSON file"; + LOGGER.warn(errorMessage); + throw new ApexParameterRuntimeException(errorMessage); + } + + // We now get the event protocol parameter class + String eventProtocolParameterClassName = null; + + // Get the event protocol parameter class for the event protocol plugin class from the + // configuration parameters + final JsonPrimitive classNameJsonPrimitive = (JsonPrimitive) jsonObject.get(PARAMETER_CLASS_NAME); + + // If no event protocol parameter class was specified, we use the default + if (classNameJsonPrimitive == null) { + eventProtocolParameterClassName = BUILT_IN_EVENT_RPOTOCOL_PARMETER_CLASS_MAP.get(eventProtocolLabel); + } else { + // We use the specified one + eventProtocolParameterClassName = classNameJsonPrimitive.getAsString().replaceAll("\\s+", ""); + } + + // Check the event protocol parameter class + if (eventProtocolParameterClassName == null || eventProtocolParameterClassName.length() == 0) { + final String errorMessage = + "event protocol \"" + eventProtocolLabel + "\" parameter \"" + PARAMETER_CLASS_NAME + "\" value \"" + + classNameJsonPrimitive.getAsString() + "\" invalid in JSON file"; + LOGGER.warn(errorMessage); + throw new ApexParameterRuntimeException(errorMessage); + } + + // Get the class for the event protocol + Class<?> eventProtocolParameterClass = null; + try { + eventProtocolParameterClass = Class.forName(eventProtocolParameterClassName); + } catch (final ClassNotFoundException e) { + final String errorMessage = + "event protocol \"" + eventProtocolLabel + "\" parameter \"" + PARAMETER_CLASS_NAME + "\" value \"" + + eventProtocolParameterClassName + "\", could not find class"; + LOGGER.warn(errorMessage, e); + throw new ApexParameterRuntimeException(errorMessage, e); + } + + // Deserialise the class + EventProtocolParameters eventProtocolParameters = + context.deserialize(jsonObject.get(EVENT_PROTOCOL_PARAMETERS), eventProtocolParameterClass); + if (eventProtocolParameters == null) { + // OK no parameters for the event protocol have been specified, just instantiate the + // default parameters + try { + eventProtocolParameters = (EventProtocolParameters) eventProtocolParameterClass.newInstance(); + } catch (final Exception e) { + final String errorMessage = "could not create default parameters for event protocol \"" + + eventProtocolLabel + "\"\n" + e.getMessage(); + LOGGER.warn(errorMessage, e); + throw new ApexParameterRuntimeException(errorMessage, e); + } + } + + // Check that the event protocol label matches the label in the event protocol parameters + // object + if (!eventProtocolParameters.getLabel().equals(eventProtocolLabel)) { + final String errorMessage = "event protocol \"" + eventProtocolLabel + "\" does not match plugin \"" + + eventProtocolParameters.getLabel() + "\" in \"" + eventProtocolParameterClassName + + "\", specify correct event protocol parameter plugin in parameter \"" + PARAMETER_CLASS_NAME + + "\""; + LOGGER.warn(errorMessage); + throw new ApexParameterRuntimeException(errorMessage); + } + + return eventProtocolParameters; + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/EventProtocolTextCharDelimitedParameters.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/EventProtocolTextCharDelimitedParameters.java new file mode 100644 index 000000000..f8873ada4 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/EventProtocolTextCharDelimitedParameters.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters.eventprotocol; + +import org.onap.policy.apex.service.parameters.ApexParameterValidator; + +/** + * An event protocol parameter class for character delimited textual event protocols that may be + * specialized by event protocol plugins that require plugin specific parameters. + * + * <p> + * The following parameters are defined: + * <ol> + * <li>startChar: starting character delimiter for text blocks containing an event. + * <li>endChar: ending character delimiter for text blocks containing an event. + * </ol> + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public abstract class EventProtocolTextCharDelimitedParameters extends EventProtocolParameters + implements ApexParameterValidator { + // The starting and ending character delimiter + private char startChar = '\0'; + private char endChar = '\0'; + + /** + * Constructor to create an event protocol parameters instance with the name of a sub class of + * this class. + * + * @param parameterClassName the class name of a sub class of this class + */ + public EventProtocolTextCharDelimitedParameters(final String parameterClassName) { + super(parameterClassName); + } + + /** + * Gets the start character that delimits the start of text blocks. + * + * @return the start char + */ + public char getStartChar() { + return startChar; + } + + /** + * Sets the start character that delimits the start of text blocks. + * + * @param startChar the start character + */ + public void setStartChar(final char startChar) { + this.startChar = startChar; + } + + /** + * Gets the end character that delimits the end of text blocks. + * + * @return the end character + */ + public char getEndChar() { + return endChar; + } + + /** + * Sets the end character that delimits the end of text blocks. + * + * @param endChar the end character + */ + public void setEndChar(final char endChar) { + this.endChar = endChar; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters#toString() + */ + @Override + public String toString() { + return "EventProtocolTextCharDelimitedParameters {" + super.toString() + "} [startChar=" + startChar + + ", endChar=" + endChar + "]"; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters#validate() + */ + @Override + public String validate() { + final StringBuilder errorMessageBuilder = new StringBuilder(); + + errorMessageBuilder.append(super.validate()); + + if (startChar == '\0') { + errorMessageBuilder.append(" text character delimited start character has not been specified\n"); + } + + if (endChar == '\0') { + errorMessageBuilder.append(" text character delimited end character has not been specified\n"); + } + + return errorMessageBuilder.toString(); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/EventProtocolTextTokenDelimitedParameters.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/EventProtocolTextTokenDelimitedParameters.java new file mode 100644 index 000000000..37fbd32bf --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/EventProtocolTextTokenDelimitedParameters.java @@ -0,0 +1,95 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.parameters.eventprotocol; + +import org.onap.policy.apex.service.parameters.ApexParameterValidator; + +/** + * An event protocol parameter class for token delimited textual event protocols that may be + * specialized by event protocol plugins that require plugin specific parameters. + * + * <p> + * The following parameters are defined: + * <ol> + * <li>delimiterToken: the token string that delimits text blocks that contain events. + * </ol> + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public abstract class EventProtocolTextTokenDelimitedParameters extends EventProtocolParameters + implements ApexParameterValidator { + // The delimiter token for text blocks + private String delimiterToken = null; + + /** + * Constructor to create an event protocol parameters instance with the name of a sub class of + * this class. + * + * @param parameterClassName the class name of a sub class of this class + */ + public EventProtocolTextTokenDelimitedParameters(final String parameterClassName) { + super(parameterClassName); + } + + /** + * Gets the delimiter token that delimits events in the text. + * + * @return the delimiter token + */ + public String getDelimiterToken() { + return delimiterToken; + } + + + /** + * Sets the delimiter token that delimits events in the text. + * + * @param delimiterToken the delimiter token + */ + public void setDelimiterToken(final String delimiterToken) { + this.delimiterToken = delimiterToken; + } + + + @Override + public String toString() { + return "EventProtocolTextCharDelimitedParameters {" + super.toString() + "} [delimiterToken=" + delimiterToken + + "]"; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.parameters.ApexParameterValidator#validate() + */ + @Override + public String validate() { + final StringBuilder errorMessageBuilder = new StringBuilder(); + + errorMessageBuilder.append(super.validate()); + + if (delimiterToken == null || delimiterToken.length() == 0) { + errorMessageBuilder.append(" text delimiter token not specified or is blank\n"); + } + + return errorMessageBuilder.toString(); + } +} diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/package-info.java new file mode 100644 index 000000000..967198a62 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/eventprotocol/package-info.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Defines the structure of event protocol parameters for APEX. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.parameters.eventprotocol; diff --git a/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/package-info.java b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/package-info.java new file mode 100644 index 000000000..2c6473776 --- /dev/null +++ b/services/services-engine/src/main/java/org/onap/policy/apex/service/parameters/package-info.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +/** + * Implements parameter handling for all parameters in APEX. It uses specializations of (@link + * {@link org.onap.policy.apex.model.basicmodel.service.AbstractParameters} for all parameters and + * works with {@link org.onap.policy.apex.model.basicmodel.service.ParameterService} for storing and + * finding parameters. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +package org.onap.policy.apex.service.parameters; diff --git a/services/services-engine/src/main/resources/version.txt b/services/services-engine/src/main/resources/version.txt new file mode 100644 index 000000000..f1ce55824 --- /dev/null +++ b/services/services-engine/src/main/resources/version.txt @@ -0,0 +1,4 @@ +Apex Adaptive Policy Engine +Version: ${project.version} +Built (UTC): ${timestamp} +ONAP https://wiki.onap.org
\ No newline at end of file diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/event/JSONEventGenerator.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/event/JSONEventGenerator.java new file mode 100644 index 000000000..4da8c4201 --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/event/JSONEventGenerator.java @@ -0,0 +1,442 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import java.util.Random; + +/** + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class JSONEventGenerator { + private static int nextEventNo = 0; + + public static String jsonEvents(final int eventCount) { + final StringBuilder builder = new StringBuilder(); + + for (int i = 0; i < eventCount; i++) { + if (i > 0) { + builder.append("\n"); + } + builder.append(jsonEvent()); + } + + return builder.toString(); + } + + public static String jsonEvent() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final String eventName = (nextEventNo == 0 ? "Event0000" : "Event0100"); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"name\": \"" + eventName + "\",\n"); + builder.append(" \"version\": \"0.0.1\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"target\": \"apex\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventNoName() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final String eventName = (nextEventNo == 0 ? "Event0000" : "Event0100"); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"namez\": \"" + eventName + "\",\n"); + builder.append(" \"version\": \"0.0.1\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"target\": \"apex\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventBadName() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"name\": \"%%%%\",\n"); + builder.append(" \"version\": \"0.0.1\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"target\": \"apex\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventNoExName() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"name\": \"I_DONT_EXIST\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"target\": \"apex\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventNoVersion() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final String eventName = (nextEventNo == 0 ? "Event0000" : "Event0100"); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"name\": \"" + eventName + "\",\n"); + builder.append(" \"versiion\": \"0.0.1\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"target\": \"apex\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventBadVersion() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final String eventName = (nextEventNo == 0 ? "Event0000" : "Event0100"); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"name\": \"" + eventName + "\",\n"); + builder.append(" \"version\": \"#####\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"target\": \"apex\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventNoExVersion() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"name\": \"Event0000\",\n"); + builder.append(" \"version\": \"1.2.3\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"target\": \"apex\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventNoNamespace() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final String eventName = (nextEventNo == 0 ? "Event0000" : "Event0100"); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpacee\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"name\": \"" + eventName + "\",\n"); + builder.append(" \"version\": \"0.0.1\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"target\": \"apex\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventBadNamespace() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final String eventName = (nextEventNo == 0 ? "Event0000" : "Event0100"); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"hello.&&&&\",\n"); + builder.append(" \"name\": \"" + eventName + "\",\n"); + builder.append(" \"version\": \"0.0.1\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"target\": \"apex\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventNoExNamespace() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"pie.in.the.sky\",\n"); + builder.append(" \"name\": \"Event0000\",\n"); + builder.append(" \"version\": \"0.0.1\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"target\": \"apex\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventNoSource() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final String eventName = (nextEventNo == 0 ? "Event0000" : "Event0100"); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"name\": \"" + eventName + "\",\n"); + builder.append(" \"version\": \"0.0.1\",\n"); + builder.append(" \"sourcee\": \"test\",\n"); + builder.append(" \"target\": \"apex\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventBadSource() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final String eventName = (nextEventNo == 0 ? "Event0000" : "Event0100"); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"name\": \"" + eventName + "\",\n"); + builder.append(" \"version\": \"0.0.1\",\n"); + builder.append(" \"source\": \"%!@**@!\",\n"); + builder.append(" \"target\": \"apex\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventNoTarget() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final String eventName = (nextEventNo == 0 ? "Event0000" : "Event0100"); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"name\": \"" + eventName + "\",\n"); + builder.append(" \"version\": \"0.0.1\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"targett\": \"apex\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventBadTarget() { + final Random rand = new Random(); + + final StringBuilder builder = new StringBuilder(); + + int nextEventNo = rand.nextInt(2); + final String eventName = (nextEventNo == 0 ? "Event0000" : "Event0100"); + final int nextMatchCase = rand.nextInt(4); + final float nextTestTemperature = rand.nextFloat() * 10000; + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"name\": \"" + eventName + "\",\n"); + builder.append(" \"version\": \"0.0.1\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"target\": \"KNIO(*S)A(S)D\",\n"); + builder.append(" \"TestSlogan\": \"Test slogan for External Event" + (nextEventNo++) + "\",\n"); + builder.append(" \"TestMatchCase\": " + nextMatchCase + ",\n"); + builder.append(" \"TestTimestamp\": " + System.currentTimeMillis() + ",\n"); + builder.append(" \"TestTemperature\": " + nextTestTemperature + "\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventMissingFields() { + final StringBuilder builder = new StringBuilder(); + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"name\": \"Event0000\",\n"); + builder.append(" \"version\": \"0.0.1\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"target\": \"apex\"\n"); + builder.append("}"); + + return builder.toString(); + } + + public static String jsonEventNullFields() { + final StringBuilder builder = new StringBuilder(); + + builder.append("{\n"); + builder.append(" \"nameSpace\": \"org.onap.policy.apex.sample.events\",\n"); + builder.append(" \"name\": \"Event0000\",\n"); + builder.append(" \"version\": \"0.0.1\",\n"); + builder.append(" \"source\": \"test\",\n"); + builder.append(" \"target\": \"Apex\",\n"); + builder.append(" \"TestSlogan\": null,\n"); + builder.append(" \"TestMatchCase\": -1,\n"); + builder.append(" \"TestTimestamp\": -1,\n"); + builder.append(" \"TestTemperature\": -1.0\n"); + builder.append("}"); + + return builder.toString(); + } + + public static void main(final String[] args) { + if (args.length != 1) { + System.err.println("usage EventGenerator #events"); + return; + } + + int eventCount = 0; + try { + eventCount = Integer.parseInt(args[0]); + } catch (final Exception e) { + System.err.println("usage EventGenerator #events"); + e.printStackTrace(); + return; + } + + System.out.println(jsonEvents(eventCount)); + } + + public static int getNextEventNo() { + return nextEventNo; + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/event/TestJSONEventHandler.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/event/TestJSONEventHandler.java new file mode 100644 index 000000000..be61b165e --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/event/TestJSONEventHandler.java @@ -0,0 +1,316 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.policy.apex.context.parameters.SchemaParameters; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.model.basicmodel.handling.ApexModelException; +import org.onap.policy.apex.model.basicmodel.handling.ApexModelReader; +import org.onap.policy.apex.model.basicmodel.service.ModelService; +import org.onap.policy.apex.model.eventmodel.concepts.AxEvent; +import org.onap.policy.apex.model.eventmodel.concepts.AxEvents; +import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel; +import org.onap.policy.apex.model.utilities.TextFileUtils; +import org.onap.policy.apex.service.engine.event.impl.jsonprotocolplugin.Apex2JSONEventConverter; +import org.onap.policy.apex.service.engine.event.impl.jsonprotocolplugin.JSONEventProtocolParameters; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class TestJSONEventHandler { + private static final XLogger logger = XLoggerFactory.getXLogger(TestJSONEventHandler.class); + + @BeforeClass + public static void setupEventModel() throws IOException, ApexModelException { + final String policyModelString = + TextFileUtils.getTextFileAsString("src/test/resources/policymodels/SamplePolicyModelMVEL.json"); + final ApexModelReader<AxPolicyModel> modelReader = new ApexModelReader<AxPolicyModel>(AxPolicyModel.class); + final AxPolicyModel apexPolicyModel = modelReader.read(new ByteArrayInputStream(policyModelString.getBytes())); + + // Set up the models in the model service + apexPolicyModel.register(); + } + + @Before + public void initializeDefaultSchemaParameters() { + new SchemaParameters(); + } + + @Test + public void testJSONtoApexEvent() throws ApexException { + try { + final Apex2JSONEventConverter jsonEventConverter = new Apex2JSONEventConverter(); + assertNotNull(jsonEventConverter); + jsonEventConverter.init(new JSONEventProtocolParameters()); + + final String apexEventJSONStringIn = JSONEventGenerator.jsonEvent(); + + logger.debug("input event\n" + apexEventJSONStringIn); + + final List<ApexEvent> apexEventList = jsonEventConverter.toApexEvent(null, apexEventJSONStringIn); + for (final ApexEvent apexEvent : apexEventList) { + assertNotNull(apexEvent); + + logger.debug(apexEvent.toString()); + + assertTrue(apexEvent.getName().equals("Event0000") || apexEvent.getName().equals("Event0100")); + assertTrue(apexEvent.getVersion().equals("0.0.1")); + assertTrue(apexEvent.getNameSpace().equals("org.onap.policy.apex.sample.events")); + assertTrue(apexEvent.getSource().equals("test")); + assertTrue(apexEvent.getTarget().equals("apex")); + assertTrue(apexEvent.get("TestSlogan").toString().startsWith("Test slogan for External Event")); + + final Object testMatchCaseSelected = apexEvent.get("TestMatchCaseSelected"); + assertTrue(testMatchCaseSelected == null); + } + } catch (final Exception e) { + e.printStackTrace(); + throw new ApexException("Exception reading Apex event JSON file", e); + } + } + + @Test + public void testJSONtoApexBadEvent() throws ApexException { + try { + final Apex2JSONEventConverter jsonEventConverter = new Apex2JSONEventConverter(); + assertNotNull(jsonEventConverter); + jsonEventConverter.init(new JSONEventProtocolParameters()); + + String apexEventJSONStringIn = null; + + try { + apexEventJSONStringIn = JSONEventGenerator.jsonEventNoName(); + jsonEventConverter.toApexEvent(null, apexEventJSONStringIn); + fail("Test should throw an exception here"); + } catch (final ApexEventException e) { + assertEquals("Failed to unmarshal JSON event: event received without mandatory parameter \"name\" ", + e.getMessage().substring(0, 82)); + } + + try { + apexEventJSONStringIn = JSONEventGenerator.jsonEventBadName(); + jsonEventConverter.toApexEvent(null, apexEventJSONStringIn); + fail("Test should throw an exception here"); + } catch (final ApexEventException e) { + assertTrue(e.getMessage() + .startsWith("Failed to unmarshal JSON event: field \"name\" with value \"%%%%\" is invalid")); + } + + try { + apexEventJSONStringIn = JSONEventGenerator.jsonEventNoExName(); + jsonEventConverter.toApexEvent(null, apexEventJSONStringIn); + fail("Test should throw an exception here"); + } catch (final ApexEventException e) { + assertEquals("Failed to unmarshal JSON event: an event definition for an event named \"I_DONT_EXI", + e.getMessage().substring(0, 82)); + } + + apexEventJSONStringIn = JSONEventGenerator.jsonEventNoVersion(); + ApexEvent event = jsonEventConverter.toApexEvent(null, apexEventJSONStringIn).get(0); + assertEquals("0.0.1", event.getVersion()); + + try { + apexEventJSONStringIn = JSONEventGenerator.jsonEventBadVersion(); + jsonEventConverter.toApexEvent(null, apexEventJSONStringIn); + fail("Test should throw an exception here"); + } catch (final ApexEventException e) { + assertTrue(e.getMessage().startsWith( + "Failed to unmarshal JSON event: field \"version\" with value \"#####\" is invalid")); + } + + try { + apexEventJSONStringIn = JSONEventGenerator.jsonEventNoExVersion(); + jsonEventConverter.toApexEvent(null, apexEventJSONStringIn); + fail("Test should throw an exception here"); + } catch (final ApexEventException e) { + assertTrue(e.getMessage().startsWith( + "Failed to unmarshal JSON event: an event definition for an event named \"Event0000\" with version \"1.2.3\" not found in Apex model")); + } + + apexEventJSONStringIn = JSONEventGenerator.jsonEventNoNamespace(); + event = jsonEventConverter.toApexEvent(null, apexEventJSONStringIn).get(0); + assertEquals("org.onap.policy.apex.sample.events", event.getNameSpace()); + + try { + apexEventJSONStringIn = JSONEventGenerator.jsonEventBadNamespace(); + jsonEventConverter.toApexEvent(null, apexEventJSONStringIn); + fail("Test should throw an exception here"); + } catch (final ApexEventException e) { + assertTrue(e.getMessage().startsWith( + "Failed to unmarshal JSON event: field \"nameSpace\" with value \"hello.&&&&\" is invalid")); + } + + try { + apexEventJSONStringIn = JSONEventGenerator.jsonEventNoExNamespace(); + jsonEventConverter.toApexEvent(null, apexEventJSONStringIn); + fail("Test should throw an exception here"); + } catch (final ApexEventException e) { + assertTrue(e.getMessage().startsWith( + "Failed to unmarshal JSON event: namespace \"pie.in.the.sky\" on event \"Event0000\" " + + "does not match namespace \"org.onap.policy.apex.sample.events\" for that event in the Apex model")); + } + + apexEventJSONStringIn = JSONEventGenerator.jsonEventNoSource(); + event = jsonEventConverter.toApexEvent(null, apexEventJSONStringIn).get(0); + assertEquals("Outside", event.getSource()); + + try { + apexEventJSONStringIn = JSONEventGenerator.jsonEventBadSource(); + jsonEventConverter.toApexEvent(null, apexEventJSONStringIn); + fail("Test should throw an exception here"); + } catch (final ApexEventException e) { + assertTrue(e.getMessage().startsWith( + "Failed to unmarshal JSON event: field \"source\" with value \"%!@**@!\" is invalid")); + } + + apexEventJSONStringIn = JSONEventGenerator.jsonEventNoTarget(); + event = jsonEventConverter.toApexEvent(null, apexEventJSONStringIn).get(0); + assertEquals("Match", event.getTarget()); + + try { + apexEventJSONStringIn = JSONEventGenerator.jsonEventBadTarget(); + jsonEventConverter.toApexEvent(null, apexEventJSONStringIn); + fail("Test should throw an exception here"); + } catch (final ApexEventException e) { + assertTrue(e.getMessage().startsWith( + "Failed to unmarshal JSON event: field \"target\" with value \"KNIO(*S)A(S)D\" is invalid")); + } + + try { + apexEventJSONStringIn = JSONEventGenerator.jsonEventMissingFields(); + jsonEventConverter.toApexEvent(null, apexEventJSONStringIn); + fail("Test should throw an exception here"); + } catch (final ApexEventException e) { + assertTrue(e.getMessage().startsWith("Failed to unmarshal JSON event: error parsing Event0000:0.0.1 " + + "event from Json. Field \"TestMatchCase\" is missing, but is mandatory.")); + } + + apexEventJSONStringIn = JSONEventGenerator.jsonEventNullFields(); + event = jsonEventConverter.toApexEvent(null, apexEventJSONStringIn).get(0); + assertEquals(event.get("TestSlogan"), null); + assertEquals(event.get("TestMatchCase"), (byte) -1); + assertEquals(event.get("TestTimestamp"), (long) -1); + assertEquals(event.get("TestTemperature"), -1.0); + + // Set the missing fields as optional in the model + final AxEvent eventDefinition = ModelService.getModel(AxEvents.class).get("Event0000"); + eventDefinition.getParameterMap().get("TestSlogan").setOptional(true); + eventDefinition.getParameterMap().get("TestMatchCase").setOptional(true); + eventDefinition.getParameterMap().get("TestTimestamp").setOptional(true); + eventDefinition.getParameterMap().get("TestTemperature").setOptional(true); + + apexEventJSONStringIn = JSONEventGenerator.jsonEventMissingFields(); + event = jsonEventConverter.toApexEvent(null, apexEventJSONStringIn).get(0); + assertEquals(null, event.get("TestSlogan")); + assertEquals(null, event.get("TestMatchCase")); + assertEquals(null, event.get("TestTimestamp")); + assertEquals(null, event.get("TestTemperature")); + } catch (final Exception e) { + e.printStackTrace(); + throw new ApexException("Exception reading Apex event JSON file", e); + } + } + + @Test + public void testApexEventToJSON() throws ApexException { + try { + final Apex2JSONEventConverter jsonEventConverter = new Apex2JSONEventConverter(); + assertNotNull(jsonEventConverter); + + final Date event0000StartTime = new Date(); + final Map<String, Object> event0000DataMap = new HashMap<String, Object>(); + event0000DataMap.put("TestSlogan", "This is a test slogan"); + event0000DataMap.put("TestMatchCase", 12345); + event0000DataMap.put("TestTimestamp", event0000StartTime.getTime()); + event0000DataMap.put("TestTemperature", 34.5445667); + + final ApexEvent apexEvent0000 = + new ApexEvent("Event0000", "0.0.1", "org.onap.policy.apex.sample.events", "test", "apex"); + apexEvent0000.putAll(event0000DataMap); + + final String apexEvent0000JSONString = (String) jsonEventConverter.fromApexEvent(apexEvent0000); + + logger.debug(apexEvent0000JSONString); + + assertTrue(apexEvent0000JSONString.contains("\"name\": \"Event0000\"")); + assertTrue(apexEvent0000JSONString.contains("\"version\": \"0.0.1\"")); + assertTrue(apexEvent0000JSONString.contains("\"nameSpace\": \"org.onap.policy.apex.sample.events\"")); + assertTrue(apexEvent0000JSONString.contains("\"source\": \"test\"")); + assertTrue(apexEvent0000JSONString.contains("\"target\": \"apex\"")); + assertTrue(apexEvent0000JSONString.contains("\"TestSlogan\": \"This is a test slogan\"")); + assertTrue(apexEvent0000JSONString.contains("\"TestMatchCase\": 12345")); + assertTrue(apexEvent0000JSONString.contains("\"TestTimestamp\": " + event0000StartTime.getTime())); + assertTrue(apexEvent0000JSONString.contains("\"TestTemperature\": 34.5445667")); + + final Date event0004StartTime = new Date(1434363272000L); + final Map<String, Object> event0004DataMap = new HashMap<String, Object>(); + event0004DataMap.put("TestSlogan", "Test slogan for External Event"); + event0004DataMap.put("TestMatchCase", new Integer(2)); + event0004DataMap.put("TestTimestamp", new Long(event0004StartTime.getTime())); + event0004DataMap.put("TestTemperature", new Double(1064.43)); + event0004DataMap.put("TestMatchCaseSelected", new Integer(2)); + event0004DataMap.put("TestMatchStateTime", new Long(1434370506078L)); + event0004DataMap.put("TestEstablishCaseSelected", new Integer(0)); + event0004DataMap.put("TestEstablishStateTime", new Long(1434370506085L)); + event0004DataMap.put("TestDecideCaseSelected", new Integer(3)); + event0004DataMap.put("TestDecideStateTime", new Long(1434370506092L)); + event0004DataMap.put("TestActCaseSelected", new Integer(2)); + event0004DataMap.put("TestActStateTime", new Long(1434370506095L)); + + final ApexEvent apexEvent0004 = + new ApexEvent("Event0004", "0.0.1", "org.onap.policy.apex.sample.events", "test", "apex"); + apexEvent0004.putAll(event0004DataMap); + + final String apexEvent0004JSONString = (String) jsonEventConverter.fromApexEvent(apexEvent0004); + + logger.debug(apexEvent0004JSONString); + + assertTrue(apexEvent0004JSONString.contains("\"name\": \"Event0004\"")); + assertTrue(apexEvent0004JSONString.contains("\"version\": \"0.0.1\"")); + assertTrue(apexEvent0004JSONString.contains("\"nameSpace\": \"org.onap.policy.apex.sample.events\"")); + assertTrue(apexEvent0004JSONString.contains("\"source\": \"test\"")); + assertTrue(apexEvent0004JSONString.contains("\"target\": \"apex\"")); + assertTrue(apexEvent0004JSONString.contains("\"TestSlogan\": \"Test slogan for External Event\"")); + assertTrue(apexEvent0004JSONString.contains("1434370506078")); + assertTrue(apexEvent0004JSONString.contains("1064.43")); + } catch (final Exception e) { + e.printStackTrace(); + throw new ApexException("Exception reading Apex event JSON file", e); + } + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/event/TestJSONTaggedEventConsumer.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/event/TestJSONTaggedEventConsumer.java new file mode 100644 index 000000000..b19cceec9 --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/event/TestJSONTaggedEventConsumer.java @@ -0,0 +1,130 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.junit.Test; +import org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer.CharacterDelimitedTextBlockReader; +import org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer.TextBlock; + +/** + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class TestJSONTaggedEventConsumer { + + @Test + public void testGarbageText() throws IOException { + final InputStream jsonInputStream = new ByteArrayInputStream("hello there".getBytes()); + + final CharacterDelimitedTextBlockReader taggedReader = new CharacterDelimitedTextBlockReader('{', '}'); + taggedReader.init(jsonInputStream); + + final TextBlock textBlock = taggedReader.readTextBlock(); + assertNull(textBlock.getText()); + assertTrue(textBlock.isEndOfText()); + } + + @Test + public void testPartialEvent() throws IOException { + final InputStream jsonInputStream = new ByteArrayInputStream("\"TestTimestamp\": 1469781869268}".getBytes()); + + final CharacterDelimitedTextBlockReader taggedReader = new CharacterDelimitedTextBlockReader('{', '}'); + taggedReader.init(jsonInputStream); + + final TextBlock textBlock = taggedReader.readTextBlock(); + assertNull(textBlock.getText()); + assertTrue(textBlock.isEndOfText()); + } + + @Test + public void testFullEvent() throws IOException { + final InputStream jsonInputStream = new ByteArrayInputStream("{TestTimestamp\": 1469781869268}".getBytes()); + + final CharacterDelimitedTextBlockReader taggedReader = new CharacterDelimitedTextBlockReader('{', '}'); + taggedReader.init(jsonInputStream); + + TextBlock textBlock = taggedReader.readTextBlock(); + assertEquals(textBlock.getText(), "{TestTimestamp\": 1469781869268}"); + + textBlock = taggedReader.readTextBlock(); + assertNull(textBlock.getText()); + assertTrue(textBlock.isEndOfText()); + } + + @Test + public void testFullEventGarbageBefore() throws IOException { + final InputStream jsonInputStream = + new ByteArrayInputStream("Garbage{TestTimestamp\": 1469781869268}".getBytes()); + + final CharacterDelimitedTextBlockReader taggedReader = new CharacterDelimitedTextBlockReader('{', '}'); + taggedReader.init(jsonInputStream); + + TextBlock textBlock = taggedReader.readTextBlock(); + assertEquals(textBlock.getText(), "{TestTimestamp\": 1469781869268}"); + assertFalse(textBlock.isEndOfText()); + + textBlock = taggedReader.readTextBlock(); + assertNull(textBlock.getText()); + assertTrue(textBlock.isEndOfText()); + } + + @Test + public void testFullEventGarbageBeforeAfter() throws IOException { + final InputStream jsonInputStream = + new ByteArrayInputStream("Garbage{TestTimestamp\": 1469781869268}Rubbish".getBytes()); + + final CharacterDelimitedTextBlockReader taggedReader = new CharacterDelimitedTextBlockReader('{', '}'); + taggedReader.init(jsonInputStream); + + TextBlock textBlock = taggedReader.readTextBlock(); + assertEquals(textBlock.getText(), "{TestTimestamp\": 1469781869268}"); + assertFalse(textBlock.isEndOfText()); + + textBlock = taggedReader.readTextBlock(); + assertNull(textBlock.getText()); + assertTrue(textBlock.isEndOfText()); + } + + @Test + public void testFullEventGarbageAfter() throws IOException { + final InputStream jsonInputStream = + new ByteArrayInputStream("{TestTimestamp\": 1469781869268}Rubbish".getBytes()); + + final CharacterDelimitedTextBlockReader taggedReader = new CharacterDelimitedTextBlockReader('{', '}'); + taggedReader.init(jsonInputStream); + + TextBlock textBlock = taggedReader.readTextBlock(); + assertEquals(textBlock.getText(), "{TestTimestamp\": 1469781869268}"); + assertFalse(textBlock.isEndOfText()); + + textBlock = taggedReader.readTextBlock(); + assertNull(textBlock.getText()); + assertTrue(textBlock.isEndOfText()); + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/event/TestPluginFactories.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/event/TestPluginFactories.java new file mode 100644 index 000000000..5d77bfd2a --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/event/TestPluginFactories.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.event; + +import static org.junit.Assert.assertNotNull; + +import java.util.Map.Entry; + +import org.junit.Test; +import org.onap.policy.apex.service.engine.event.impl.EventConsumerFactory; +import org.onap.policy.apex.service.engine.event.impl.EventProducerFactory; +import org.onap.policy.apex.service.engine.main.ApexCommandLineArguments; + +import org.onap.policy.apex.service.parameters.ApexParameterException; +import org.onap.policy.apex.service.parameters.ApexParameterHandler; +import org.onap.policy.apex.service.parameters.ApexParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; + +/** + * @author Liam Fallon (liam.fallon@ericsson.com) + * @author John Keeney (john.keeney@ericsson.com) + */ +public class TestPluginFactories { + + @Test + public void testEventConsumerFactory() throws ApexEventException, ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/factoryGoodParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + + for (final Entry<String, EventHandlerParameters> ce : parameters.getEventInputParameters().entrySet()) { + final ApexEventConsumer consumer = new EventConsumerFactory().createConsumer( + parameters.getEngineServiceParameters().getName() + "_consumer_" + ce.getKey(), ce.getValue()); + assertNotNull(consumer); + } + + for (final Entry<String, EventHandlerParameters> pe : parameters.getEventOutputParameters().entrySet()) { + final ApexEventProducer producer = new EventProducerFactory().createProducer( + parameters.getEngineServiceParameters().getName() + "_producer_" + pe.getKey(), pe.getValue()); + assertNotNull(producer); + } + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/main/TestApexCommandLineArguments.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/main/TestApexCommandLineArguments.java new file mode 100644 index 000000000..247f9b935 --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/main/TestApexCommandLineArguments.java @@ -0,0 +1,186 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.main; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; + +/** + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class TestApexCommandLineArguments { + + @Test + public void testCommandLineArguments() { + final ApexCommandLineArguments apexArguments = new ApexCommandLineArguments(); + + final String[] args00 = {""}; + try { + apexArguments.parse(args00); + apexArguments.validate(); + fail("Test should throw an exception here"); + } catch (final ApexException e) { + assertEquals("Apex configuration file was not specified as an argument", e.getMessage()); + } + + final String[] args01 = {"-h"}; + try { + final String result = apexArguments.parse(args01); + assertTrue(result.startsWith("usage: org.onap.policy.apex.service.engine.main.ApexMain [options...]")); + } catch (final ApexException e) { + e.printStackTrace(); + fail("Test should not throw an exception"); + } + + final String[] args02 = {"-v"}; + try { + final String result = apexArguments.parse(args02); + assertTrue(result.startsWith("Apex Adaptive Policy Engine")); + } catch (final ApexException e) { + e.printStackTrace(); + fail("Test should not throw an exception"); + } + + final String[] args03 = {"-v", "-h"}; + try { + final String result = apexArguments.parse(args03); + assertTrue(result.startsWith("usage: org.onap.policy.apex.service.engine.main.ApexMain [options...]")); + } catch (final ApexException e) { + e.printStackTrace(); + fail("Test should not throw an exception"); + } + + final String[] args04 = {"-h", "-v"}; + try { + final String result = apexArguments.parse(args04); + assertTrue(result.startsWith("usage: org.onap.policy.apex.service.engine.main.ApexMain [options...]")); + } catch (final ApexException e) { + e.printStackTrace(); + fail("Test should not throw an exception"); + } + + final String[] args05 = {"-a"}; + try { + apexArguments.parse(args05); + } catch (final ApexException e) { + assertEquals("invalid command line arguments specified : Unrecognized option: -a", e.getMessage()); + } + + final String[] args06 = {"-c", "hello", "-m", "goodbye", "-h", "-v"}; + try { + final String result = apexArguments.parse(args06); + assertTrue(result.startsWith("usage: org.onap.policy.apex.service.engine.main.ApexMain [options...]")); + } catch (final ApexException e) { + assertEquals("invalid command line arguments specified : Unrecognized option: -a", e.getMessage()); + } + + final String[] args07 = {"-c", "hello", "-m", "goodbye", "-h", "aaa"}; + try { + final String result = apexArguments.parse(args07); + assertTrue(result.startsWith("usage: org.onap.policy.apex.service.engine.main.ApexMain [options...]")); + } catch (final ApexException e) { + assertEquals("too many command line arguments specified : [-c, hello, -m, goodbye, -h, aaa]", + e.getMessage()); + } + } + + @Test + public void testCommandLineFileParameters() { + final ApexCommandLineArguments apexArguments = new ApexCommandLineArguments(); + + final String[] args00 = {"-c", "zooby"}; + try { + apexArguments.parse(args00); + apexArguments.validate(); + fail("Test should throw an exception here"); + } catch (final ApexException e) { + assertEquals("Apex configuration file \"zooby\" does not exist", e.getMessage()); + } + + final String[] args01 = {"-c"}; + try { + apexArguments.parse(args01); + apexArguments.validate(); + fail("Test should throw an exception here"); + } catch (final ApexException e) { + assertEquals("invalid command line arguments specified : Missing argument for option: c", e.getMessage()); + } + + final String[] args02 = {"-c", "src/test/resources/parameters/goodParams.json"}; + try { + apexArguments.parse(args02); + apexArguments.validate(); + } catch (final ApexException e) { + e.printStackTrace(); + fail("Test should not throw an exception"); + } + + final String[] args03 = {"-c", "src/test/resources/parameters/goodParams.json", "-m", "zooby"}; + try { + apexArguments.parse(args03); + apexArguments.validate(); + fail("Test should throw an exception here"); + } catch (final ApexException e) { + assertEquals("Apex model file \"zooby\" does not exist", e.getMessage()); + } + + final String[] args04 = {"-m"}; + try { + apexArguments.parse(args04); + apexArguments.validate(); + fail("Test should throw an exception here"); + } catch (final ApexException e) { + assertEquals("invalid command line arguments specified : Missing argument for option: m", e.getMessage()); + } + + final String[] args05 = {"-c", "src/test/resources/parameters/goodParams.json", "-m"}; + try { + apexArguments.parse(args05); + apexArguments.validate(); + fail("Test should throw an exception here"); + } catch (final ApexException e) { + assertEquals("invalid command line arguments specified : Missing argument for option: m", e.getMessage()); + } + + final String[] args06 = {"-c", "src/test/resources/parameters/goodParams.json", "-m", + "src/test/resources/main/DummyModelFile.json"}; + try { + apexArguments.parse(args06); + apexArguments.validate(); + } catch (final ApexException e) { + e.printStackTrace(); + fail("Test should not throw an exception"); + } + + final String[] args07 = {"-c", "parameters/goodParams.json", "-m", "main/DummyModelFile.json"}; + try { + apexArguments.parse(args07); + apexArguments.validate(); + } catch (final ApexException e) { + e.printStackTrace(); + fail("Test should not throw an exception"); + } + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/ContextParameterTests.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/ContextParameterTests.java new file mode 100644 index 000000000..33bcd0d5f --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/ContextParameterTests.java @@ -0,0 +1,276 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.parameters; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.onap.policy.apex.service.engine.main.ApexCommandLineArguments; +import org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperDistributorParameters; +import org.onap.policy.apex.service.parameters.ApexParameterException; +import org.onap.policy.apex.service.parameters.ApexParameterHandler; +import org.onap.policy.apex.service.parameters.ApexParameters; + +/** + * Test for an empty parameter file + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ContextParameterTests { + + @Test + public void noParamsTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceContextNoParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceContextNoParams.json\"\n" + + "(ApexParameterRuntimeException):could not find field \"parameterClassName\" in \"contextParameters\" entry", + e.getMessage()); + } + } + + @Test + public void badParamsTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceContextBadParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceContextBadParams.json\"\n" + + "(ApexParameterRuntimeException):failed to deserialize the parameters for \"contextParameters\" to parameter class \"hello\"\n" + + "java.lang.ClassNotFoundException: hello", + e.getMessage()); + } + } + + @Test + public void badPluginParamNameTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceContextBadPluginNameParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceContextBadPluginNameParams.json\"\n" + + "(ApexParameterRuntimeException):could not find field \"parameterClassName\" in \"contextParameters\" entry", + e.getMessage()); + } + } + + @Test + public void badClassParamTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceContextBadClassParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceContextBadClassParams.json\"\n" + + "(ApexParameterRuntimeException):failed to deserialize the parameters for \"contextParameters\" to parameter class \"java.lang.Integer\"\n" + + "com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected NUMBER but was BEGIN_OBJECT at path $", + e.getMessage()); + } + } + + @Test + public void badPluginClassTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceContextBadPluginClassParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceContextBadPluginClassParams.json\"\n" + + "(ClassCastException):org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters cannot be cast to org.onap.policy.apex.context.parameters.ContextParameters", + e.getMessage()); + } + } + + @Test + public void okFlushParamTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceContextOKFlushParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + assertEquals("org.onap.policy.apex.context.parameters.ContextParameters", parameters + .getEngineServiceParameters().getEngineParameters().getContextParameters().getParameterClassName()); + assertEquals(123456, parameters.getEngineServiceParameters().getEngineParameters().getContextParameters() + .getPersistorParameters().getFlushPeriod()); + } catch (final ApexParameterException e) { + fail("This test should not throw any exception: " + e.getMessage()); + } + } + + @Test + public void okDefaultParamTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceContextOKDefaultParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + assertEquals("org.onap.policy.apex.context.parameters.ContextParameters", parameters + .getEngineServiceParameters().getEngineParameters().getContextParameters().getParameterClassName()); + assertEquals(300000, parameters.getEngineServiceParameters().getEngineParameters().getContextParameters() + .getPersistorParameters().getFlushPeriod()); + } catch (final ApexParameterException e) { + fail("This test should not throw any exception: " + e.getMessage()); + } + } + + @Test + public void okDistParamTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceContextOKDistParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + assertEquals("org.onap.policy.apex.context.parameters.ContextParameters", parameters + .getEngineServiceParameters().getEngineParameters().getContextParameters().getParameterClassName()); + assertEquals("org.onap.policy.apex.context.parameters.DistributorParameters", + parameters.getEngineServiceParameters().getEngineParameters().getContextParameters() + .getDistributorParameters().getParameterClassName()); + } catch (final ApexParameterException e) { + fail("This test should not throw any exception: " + e.getMessage()); + } + } + + @Test + public void okFullDefaultParamTest() { + final String[] args = {"-c", "src/test/resources/parameters/goodParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + assertEquals("org.onap.policy.apex.context.parameters.ContextParameters", parameters + .getEngineServiceParameters().getEngineParameters().getContextParameters().getParameterClassName()); + assertEquals("org.onap.policy.apex.context.parameters.DistributorParameters", + parameters.getEngineServiceParameters().getEngineParameters().getContextParameters() + .getDistributorParameters().getParameterClassName()); + assertEquals("org.onap.policy.apex.context.parameters.LockManagerParameters", + parameters.getEngineServiceParameters().getEngineParameters().getContextParameters() + .getLockManagerParameters().getParameterClassName()); + assertEquals("org.onap.policy.apex.context.parameters.PersistorParameters", + parameters.getEngineServiceParameters().getEngineParameters().getContextParameters() + .getPersistorParameters().getParameterClassName()); + assertEquals(300000, parameters.getEngineServiceParameters().getEngineParameters().getContextParameters() + .getPersistorParameters().getFlushPeriod()); + } catch (final ApexParameterException e) { + fail("This test should not throw any exception: " + e.getMessage()); + } + } + + @Test + public void okFullParamTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceContextOKFullParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + assertEquals("org.onap.policy.apex.context.parameters.ContextParameters", parameters + .getEngineServiceParameters().getEngineParameters().getContextParameters().getParameterClassName()); + assertEquals("org.onap.policy.apex.context.parameters.LockManagerParameters", + parameters.getEngineServiceParameters().getEngineParameters().getContextParameters() + .getLockManagerParameters().getParameterClassName()); + assertEquals("org.onap.policy.apex.context.parameters.PersistorParameters", + parameters.getEngineServiceParameters().getEngineParameters().getContextParameters() + .getPersistorParameters().getParameterClassName()); + assertEquals(123456, parameters.getEngineServiceParameters().getEngineParameters().getContextParameters() + .getPersistorParameters().getFlushPeriod()); + + final SuperDooperDistributorParameters infinispanParameters = + (SuperDooperDistributorParameters) parameters.getEngineServiceParameters().getEngineParameters() + .getContextParameters().getDistributorParameters(); + assertEquals("org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperDistributorParameters", + infinispanParameters.getParameterClassName()); + assertEquals("my/lovely/configFile.xml", infinispanParameters.getConfigFile()); + assertEquals("holy/stone.xml", infinispanParameters.getJgroupsFile()); + assertEquals(false, infinispanParameters.preferIPv4Stack()); + assertEquals("fatherted", infinispanParameters.getjGroupsBindAddress()); + + } catch (final ApexParameterException e) { + fail("This test should not throw any exception: " + e.getMessage()); + } + } + + @Test + public void badClassDistParamTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceContextBadClassDistParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceContextBadClassDistParams.json\"\n" + + "(ClassCastException):org.onap.policy.apex.context.parameters.ContextParameters cannot be cast to org.onap.policy.apex.context.parameters.DistributorParameters", + e.getMessage()); + } + } + + @Test + public void badClassLockParamTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceContextBadClassLockParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceContextBadClassLockParams.json\"\n" + + "(ClassCastException):org.onap.policy.apex.context.parameters.ContextParameters cannot be cast to org.onap.policy.apex.context.parameters.LockManagerParameters", + e.getMessage()); + } + } + + @Test + public void badClassPersistParamTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceContextBadClassPersistParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceContextBadClassPersistParams.json\"\n" + + "(ClassCastException):org.onap.policy.apex.context.parameters.ContextParameters cannot be cast to org.onap.policy.apex.context.parameters.PersistorParameters", + e.getMessage()); + } + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/ExecutorParameterTests.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/ExecutorParameterTests.java new file mode 100644 index 000000000..b14cc22be --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/ExecutorParameterTests.java @@ -0,0 +1,184 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.parameters; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.onap.policy.apex.service.engine.main.ApexCommandLineArguments; +import org.onap.policy.apex.service.parameters.ApexParameterException; +import org.onap.policy.apex.service.parameters.ApexParameterHandler; +import org.onap.policy.apex.service.parameters.ApexParameters; + +/** + * Test for an empty parameter file + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ExecutorParameterTests { + + @Test + public void noParamsTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceExecutorNoParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + assertEquals(0, + parameters.getEngineServiceParameters().getEngineParameters().getExecutorParameterMap().size()); + } catch (final ApexParameterException e) { + fail("This test should not throw any exception: " + e.getMessage()); + } + } + + @Test + public void badParamsTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceExecutorBadParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceExecutorBadParams.json\"\n" + + "(ApexParameterRuntimeException):value of \"executorParameters:ZOOBY\" entry is not a parameter JSON object", + e.getMessage()); + } + } + + @Test + public void noExecutorParamsTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceExecutorNoExecutorParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceExecutorNoExecutorParams.json\"\n" + + "(ApexParameterRuntimeException):no \"executorParameters\" entry found in parameters, at least one executor parameter entry must be specified", + e.getMessage()); + } + } + + @Test + public void emptyParamsTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceExecutorEmptyParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceExecutorEmptyParams.json\"\n" + + "(ApexParameterRuntimeException):could not find field \"parameterClassName\" in \"executorParameters:ZOOBY\" entry", + e.getMessage()); + } + } + + @Test + public void badPluginParamNameTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceExecutorBadPluginNameParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceExecutorBadPluginNameParams.json\"\n" + + "(ApexParameterRuntimeException):could not find field \"parameterClassName\" in \"executorParameters:ZOOBY\" entry", + e.getMessage()); + } + } + + @Test + public void badPluginParamObjectTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceExecutorBadPluginValueObjectParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceExecutorBadPluginValueObjectParams.json\"\n" + + "(ApexParameterRuntimeException):value for field \"parameterClassName\" in \"executorParameters:LOOBY\" entry is not a plain string", + e.getMessage()); + } + } + + @Test + public void badPluginParamBlankTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceExecutorBadPluginValueBlankParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceExecutorBadPluginValueBlankParams.json\"\n" + + "(ApexParameterRuntimeException):value for field \"parameterClassName\" in \"executorParameters:LOOBY\" entry is not specified or is blank", + e.getMessage()); + } + } + + + @Test + public void badPluginParamValueTest() { + final String[] args = {"-c", "src/test/resources/parameters/serviceExecutorBadPluginValueParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/serviceExecutorBadPluginValueParams.json\"\n" + + "(ApexParameterRuntimeException):failed to deserialize the parameters for \"executorParameters:LOOBY\" to parameter class \"helloworld\"\n" + + "java.lang.ClassNotFoundException: helloworld", + e.getMessage()); + } + } + + @Test + public void goodParametersTest() { + final String[] args = {"-c", "src/test/resources/parameters/goodParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + + assertEquals("MyApexEngine", parameters.getEngineServiceParameters().getName()); + assertEquals("0.0.1", parameters.getEngineServiceParameters().getVersion()); + assertEquals(45, parameters.getEngineServiceParameters().getId()); + assertEquals(19, parameters.getEngineServiceParameters().getInstanceCount()); + assertEquals(65522, parameters.getEngineServiceParameters().getDeploymentPort()); + } catch (final ApexParameterException e) { + fail("This test should not throw any exception: " + e.getMessage()); + } + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/ParameterTests.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/ParameterTests.java new file mode 100644 index 000000000..6ea8d5924 --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/ParameterTests.java @@ -0,0 +1,239 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.parameters; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; + +import org.junit.Test; +import org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer.ApexFileEventConsumer; +import org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.producer.ApexFileEventProducer; +import org.onap.policy.apex.service.engine.main.ApexCommandLineArguments; +import org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters; +import org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperEventProducer; +import org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperEventSubscriber; +import org.onap.policy.apex.service.parameters.ApexParameterException; +import org.onap.policy.apex.service.parameters.ApexParameterHandler; +import org.onap.policy.apex.service.parameters.ApexParameters; +import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters; + +/** + * Test for an empty parameter file + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ParameterTests { + @Test + public void invalidParametersNoFileTest() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/invalidNoFile.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertTrue(e.getMessage().startsWith("error reading parameters from \"src")); + assertTrue(e.getMessage().contains("FileNotFoundException")); + } + } + + @Test + public void invalidParametersEmptyTest() { + final String[] args = {"-c", "src/test/resources/parameters/empty.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertTrue(e.getMessage() + .startsWith("validation error(s) on parameters from \"src/test/resources/parameters/empty.json\"")); + } + } + + @Test + public void invalidParametersNoParamsTest() { + final String[] args = {"-c", "src/test/resources/parameters/noParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals("validation error(s) on parameters from \"src/test/resources/parameters/noParams.json\"\n" + + "Apex parameters invalid\n" + " engine service parameters are not specified\n" + + " at least one event output and one event input must be specified", e.getMessage()); + } + } + + @Test + public void invalidParametersBlankParamsTest() { + final String[] args = {"-c", "src/test/resources/parameters/blankParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + + assertEquals("validation error(s) on parameters from \"src/test/resources/parameters/blankParams.json\"\n" + + "Apex parameters invalid\n" + " engine service parameters invalid\n" + + " id not specified or specified value [-1] invalid, must be specified as id >= 0\n" + + " at least one event output and one event input must be specified", e.getMessage()); + } + } + + @Test + public void invalidParametersTest() { + final String[] args = {"-c", "src/test/resources/parameters/badParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "validation error(s) on parameters from \"src/test/resources/parameters/badParams.json\"\n" + + "Apex parameters invalid\n" + " engine service parameters invalid\n" + + " name [hello there] and/or version [PA1] invalid\n" + + " parameter \"name\": value \"hello there\", does not match regular expression \"[A-Za-z0-9\\-_\\.]+\"\n" + + " id not specified or specified value [-45] invalid, must be specified as id >= 0\n" + + " instanceCount [-345] invalid, must be specified as instanceCount >= 1\n" + + " deploymentPort [65536] invalid, must be specified as 1024 <= port <= 65535\n" + + " policyModelFileName [/some/file/name.xml] not found or is not a plain file\n" + + " event input (TheFileConsumer1) parameters invalid\n" + + " fileName not specified or is blank or null, it must be specified as a valid file location\n" + + " event output (FirstProducer) parameters invalid\n" + + " fileName not specified or is blank or null, it must be specified as a valid file location", + e.getMessage()); + } + } + + @Test + public void goodParametersTest() { + final String[] args = {"-c", "src/test/resources/parameters/goodParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + + assertEquals(2, parameters.getEventInputParameters().size()); + assertEquals(2, parameters.getEventOutputParameters().size()); + + assertTrue(parameters.getEventOutputParameters().containsKey("FirstProducer")); + assertTrue(parameters.getEventOutputParameters().containsKey("MyOtherProducer")); + assertEquals("FILE", parameters.getEventOutputParameters().get("FirstProducer") + .getCarrierTechnologyParameters().getLabel()); + assertEquals("FILE", parameters.getEventOutputParameters().get("MyOtherProducer") + .getCarrierTechnologyParameters().getLabel()); + assertEquals(ApexFileEventProducer.class.getCanonicalName(), parameters.getEventOutputParameters() + .get("MyOtherProducer").getCarrierTechnologyParameters().getEventProducerPluginClass()); + assertEquals(ApexFileEventConsumer.class.getCanonicalName(), parameters.getEventOutputParameters() + .get("MyOtherProducer").getCarrierTechnologyParameters().getEventConsumerPluginClass()); + assertEquals("JSON", + parameters.getEventOutputParameters().get("FirstProducer").getEventProtocolParameters().getLabel()); + assertEquals("JSON", parameters.getEventOutputParameters().get("MyOtherProducer") + .getEventProtocolParameters().getLabel()); + + assertTrue(parameters.getEventInputParameters().containsKey("TheFileConsumer1")); + assertTrue(parameters.getEventInputParameters().containsKey("MySuperDooperConsumer1")); + assertEquals("FILE", parameters.getEventInputParameters().get("TheFileConsumer1") + .getCarrierTechnologyParameters().getLabel()); + assertEquals("SUPER_DOOPER", parameters.getEventInputParameters().get("MySuperDooperConsumer1") + .getCarrierTechnologyParameters().getLabel()); + assertEquals("JSON", parameters.getEventInputParameters().get("TheFileConsumer1") + .getEventProtocolParameters().getLabel()); + assertEquals("SUPER_TOK_DEL", parameters.getEventInputParameters().get("MySuperDooperConsumer1") + .getEventProtocolParameters().getLabel()); + assertEquals(ApexFileEventProducer.class.getCanonicalName(), parameters.getEventInputParameters() + .get("TheFileConsumer1").getCarrierTechnologyParameters().getEventProducerPluginClass()); + assertEquals(ApexFileEventConsumer.class.getCanonicalName(), parameters.getEventInputParameters() + .get("TheFileConsumer1").getCarrierTechnologyParameters().getEventConsumerPluginClass()); + assertEquals(SuperDooperEventProducer.class.getCanonicalName(), parameters.getEventInputParameters() + .get("MySuperDooperConsumer1").getCarrierTechnologyParameters().getEventProducerPluginClass()); + assertEquals(SuperDooperEventSubscriber.class.getCanonicalName(), parameters.getEventInputParameters() + .get("MySuperDooperConsumer1").getCarrierTechnologyParameters().getEventConsumerPluginClass()); + } catch (final ApexParameterException e) { + fail("This test should not throw an exception"); + } + } + + @Test + public void superDooperParametersTest() { + final String[] args = {"-c", "src/test/resources/parameters/superDooperParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + + assertEquals("MyApexEngine", parameters.getEngineServiceParameters().getName()); + assertEquals("0.0.1", parameters.getEngineServiceParameters().getVersion()); + assertEquals(45, parameters.getEngineServiceParameters().getId()); + assertEquals(345, parameters.getEngineServiceParameters().getInstanceCount()); + assertEquals(65522, parameters.getEngineServiceParameters().getDeploymentPort()); + + final CarrierTechnologyParameters prodCT = + parameters.getEventOutputParameters().get("FirstProducer").getCarrierTechnologyParameters(); + final EventProtocolParameters prodEP = + parameters.getEventOutputParameters().get("FirstProducer").getEventProtocolParameters(); + final CarrierTechnologyParameters consCT = + parameters.getEventInputParameters().get("MySuperDooperConsumer1").getCarrierTechnologyParameters(); + final EventProtocolParameters consEP = + parameters.getEventInputParameters().get("MySuperDooperConsumer1").getEventProtocolParameters(); + + assertEquals("SUPER_DOOPER", prodCT.getLabel()); + assertEquals("SUPER_TOK_DEL", prodEP.getLabel()); + assertEquals("SUPER_DOOPER", consCT.getLabel()); + assertEquals("JSON", consEP.getLabel()); + + assertTrue(prodCT instanceof SuperDooperCarrierTechnologyParameters); + + final SuperDooperCarrierTechnologyParameters superDooperParameters = + (SuperDooperCarrierTechnologyParameters) prodCT; + assertEquals("somehost:12345", superDooperParameters.getBootstrapServers()); + assertEquals("0", superDooperParameters.getAcks()); + assertEquals(25, superDooperParameters.getRetries()); + assertEquals(98765, superDooperParameters.getBatchSize()); + assertEquals(21, superDooperParameters.getLingerTime()); + assertEquals(50505050, superDooperParameters.getBufferMemory()); + assertEquals("first-group-id", superDooperParameters.getGroupId()); + assertFalse(superDooperParameters.isEnableAutoCommit()); + assertEquals(441, superDooperParameters.getAutoCommitTime()); + assertEquals(987, superDooperParameters.getSessionTimeout()); + assertEquals("producer-out", superDooperParameters.getProducerTopic()); + assertEquals(101, superDooperParameters.getConsumerPollTime()); + assertEquals("some.key.serailizer", superDooperParameters.getKeySerializer()); + assertEquals("some.value.serailizer", superDooperParameters.getValueSerializer()); + assertEquals("some.key.deserailizer", superDooperParameters.getKeyDeserializer()); + assertEquals("some.value.deserailizer", superDooperParameters.getValueDeserializer()); + + final String[] consumerTopics = {"consumer-out-0", "consumer-out-1", "consumer-out-2"}; + assertEquals(Arrays.asList(consumerTopics), superDooperParameters.getConsumerTopicList()); + } catch (final ApexParameterException e) { + fail("This test should not throw an exception"); + } + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/ProducerConsumerTests.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/ProducerConsumerTests.java new file mode 100644 index 000000000..dad989913 --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/ProducerConsumerTests.java @@ -0,0 +1,266 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.parameters; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.FILECarrierTechnologyParameters; +import org.onap.policy.apex.service.engine.main.ApexCommandLineArguments; +import org.onap.policy.apex.service.parameters.ApexParameterException; +import org.onap.policy.apex.service.parameters.ApexParameterHandler; +import org.onap.policy.apex.service.parameters.ApexParameters; + +/** + * Test for an empty parameter file + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ProducerConsumerTests { + @Test + public void goodParametersTest() { + final String[] args = {"-c", "src/test/resources/parameters/goodParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + + assertEquals("MyApexEngine", parameters.getEngineServiceParameters().getName()); + assertEquals("0.0.1", parameters.getEngineServiceParameters().getVersion()); + assertEquals(45, parameters.getEngineServiceParameters().getId()); + assertEquals(19, parameters.getEngineServiceParameters().getInstanceCount()); + assertEquals(65522, parameters.getEngineServiceParameters().getDeploymentPort()); + assertEquals("FILE", parameters.getEventOutputParameters().get("FirstProducer") + .getCarrierTechnologyParameters().getLabel()); + assertEquals("JSON", + parameters.getEventOutputParameters().get("FirstProducer").getEventProtocolParameters().getLabel()); + assertEquals("FILE", parameters.getEventOutputParameters().get("MyOtherProducer") + .getCarrierTechnologyParameters().getLabel()); + assertEquals("JSON", parameters.getEventOutputParameters().get("MyOtherProducer") + .getEventProtocolParameters().getLabel()); + assertEquals("FILE", parameters.getEventInputParameters().get("TheFileConsumer1") + .getCarrierTechnologyParameters().getLabel()); + assertEquals("JSON", parameters.getEventInputParameters().get("TheFileConsumer1") + .getEventProtocolParameters().getLabel()); + assertEquals("SUPER_DOOPER", parameters.getEventInputParameters().get("MySuperDooperConsumer1") + .getCarrierTechnologyParameters().getLabel()); + assertEquals("SUPER_TOK_DEL", parameters.getEventInputParameters().get("MySuperDooperConsumer1") + .getEventProtocolParameters().getLabel()); + } catch (final ApexParameterException e) { + fail("This test should not throw an exception"); + } + } + + @Test + public void noCarrierTechnology() { + final String[] args = {"-c", "src/test/resources/parameters/prodConsNoCT.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals("validation error(s) on parameters from \"src/test/resources/parameters/prodConsNoCT.json\"\n" + + "Apex parameters invalid\n" + " event input (aConsumer) parameters invalid\n" + + " event handler carrierTechnologyParameters not specified or blank", e.getMessage()); + } + } + + @Test + public void noEventProcol() { + final String[] args = {"-c", "src/test/resources/parameters/prodConsNoEP.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals("validation error(s) on parameters from \"src/test/resources/parameters/prodConsNoEP.json\"\n" + + "Apex parameters invalid\n" + " event input (aConsumer) parameters invalid\n" + + " fileName not specified or is blank or null, it must be specified as a valid file location\n" + + " event output (aProducer) parameters invalid\n" + + " event handler eventProtocolParameters not specified or blank", e.getMessage()); + } + } + + @Test + public void noCarrierTechnologyParClass() { + final String[] args = {"-c", "src/test/resources/parameters/prodConsNoCTParClass.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/prodConsNoCTParClass.json\"\n" + + "(ApexParameterRuntimeException):carrier technology \"SUPER_DOOPER\" does not match plugin \"FILE\" in " + + "\"com.ericsson.apex.service.engine.event.impl.filecarrierplugin.FILECarrierTechnologyParameters\", " + + "specify correct carrier technology parameter plugin in parameter \"parameterClassName\"", + e.getMessage()); + } + } + + @Test + public void mismatchCarrierTechnologyParClass() { + final String[] args = {"-c", "src/test/resources/parameters/prodConsMismatchCTParClass.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/prodConsMismatchCTParClass.json\"\n" + + "(ApexParameterRuntimeException):carrier technology \"SUPER_LOOPER\" does not match plugin \"SUPER_DOOPER\" in " + + "\"com.ericsson.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters\", " + + "specify correct carrier technology parameter plugin in parameter \"parameterClassName\"", + e.getMessage()); + } + } + + @Test + public void wrongTypeCarrierTechnologyParClass() { + final String[] args = {"-c", "src/test/resources/parameters/prodConsWrongTypeCTParClass.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/prodConsWrongTypeCTParClass.json\"\n" + + "(ApexParameterRuntimeException):could not create default parameters for carrier technology \"SUPER_DOOPER\"\n" + + "com.ericsson.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters " + + "cannot be cast to com.ericsson.apex.service.parameters.carriertechnology.CarrierTechnologyParameters", + e.getMessage()); + } + } + + @Test + public void okFileNameCarrierTechnology() { + final String[] args = {"-c", "src/test/resources/parameters/prodConsOKFileName.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + final FILECarrierTechnologyParameters fileParams = (FILECarrierTechnologyParameters) parameters + .getEventOutputParameters().get("aProducer").getCarrierTechnologyParameters(); + assertEquals("/tmp/aaa.json", fileParams.getFileName()); + assertEquals(false, fileParams.isStandardError()); + assertEquals(false, fileParams.isStandardIO()); + assertEquals(false, fileParams.isStreamingMode()); + } catch (final ApexParameterException e) { + fail("This test should not throw an exception"); + } + } + + @Test + public void badFileNameCarrierTechnology() { + final String[] args = {"-c", "src/test/resources/parameters/prodConsBadFileName.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "validation error(s) on parameters from \"src/test/resources/parameters/prodConsBadFileName.json\"\n" + + "Apex parameters invalid\n" + " event output (aProducer) parameters invalid\n" + + " fileName not specified or is blank or null, it must be specified as a valid file location", + e.getMessage()); + } + } + + + @Test + public void badEventProtocolParClass() { + final String[] args = {"-c", "src/test/resources/parameters/prodConsBadEPParClass.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/prodConsBadEPParClass.json\"\n" + + "(ApexParameterRuntimeException):event protocol \"SUPER_TOK_DEL\" does not match plugin \"JSON\" in " + + "\"com.ericsson.apex.service.engine.event.impl.jsonprotocolplugin.JSONEventProtocolParameters\", " + + "specify correct event protocol parameter plugin in parameter \"parameterClassName\"", + e.getMessage()); + } + } + + @Test + public void noEventProtocolParClass() { + final String[] args = {"-c", "src/test/resources/parameters/prodConsNoEPParClass.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/prodConsNoEPParClass.json\"\n" + + "(ApexParameterRuntimeException):event protocol \"SUPER_TOK_DEL\" does not match plugin \"JSON\" in " + + "\"com.ericsson.apex.service.engine.event.impl.jsonprotocolplugin.JSONEventProtocolParameters\", " + + "specify correct event protocol parameter plugin in parameter \"parameterClassName\"", + e.getMessage()); + } + } + + @Test + public void mismatchEventProtocolParClass() { + final String[] args = {"-c", "src/test/resources/parameters/prodConsMismatchEPParClass.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/prodConsMismatchEPParClass.json\"\n" + + "(ApexParameterRuntimeException):event protocol \"SUPER_TOK_BEL\" does not match plugin \"SUPER_TOK_DEL\" in " + + "\"com.ericsson.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters\", " + + "specify correct event protocol parameter plugin in parameter \"parameterClassName\"", + e.getMessage()); + } + } + + @Test + public void wrongTypeEventProtocolParClass() { + final String[] args = {"-c", "src/test/resources/parameters/prodConsWrongTypeEPParClass.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "error reading parameters from \"src/test/resources/parameters/prodConsWrongTypeEPParClass.json\"\n" + + "(ApexParameterRuntimeException):could not create default parameters for event protocol \"SUPER_TOK_DEL\"\n" + + "com.ericsson.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters " + + "cannot be cast to com.ericsson.apex.service.parameters.eventprotocol.EventProtocolParameters", + e.getMessage()); + } + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/SyncParameterTests.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/SyncParameterTests.java new file mode 100644 index 000000000..62e27eac9 --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/SyncParameterTests.java @@ -0,0 +1,362 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.parameters; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; + +import org.junit.Test; +import org.onap.policy.apex.service.engine.main.ApexCommandLineArguments; +import org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters; +import org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters; +import org.onap.policy.apex.service.parameters.ApexParameterException; +import org.onap.policy.apex.service.parameters.ApexParameterHandler; +import org.onap.policy.apex.service.parameters.ApexParameters; +import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters; + +/** + * Test for an empty parameter file + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class SyncParameterTests { + @Test + public void syncBadNoSyncWithPeer() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/syncBadParamsNoSyncWithPeer.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "validation error(s) on parameters from \"src/test/resources/parameters/syncBadParamsNoSyncWithPeer.json\"\n" + + "Apex parameters invalid\n" + + " parameter \\\"synchronousPeer\\\" is illegal on non synchronous event output \"SyncProducer0\"", + e.getMessage()); + } + } + + @Test + public void syncBadNotSyncWithPeer() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/syncBadParamsNotSyncWithPeer.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "validation error(s) on parameters from \"src/test/resources/parameters/syncBadParamsNotSyncWithPeer.json\"\n" + + "Apex parameters invalid\n" + + " parameter \\\"synchronousPeer\\\" is illegal on non synchronous event output \"SyncProducer0\"", + e.getMessage()); + } + } + + @Test + public void syncBadSyncBadPeers() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/syncBadParamsBadPeers.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "validation error(s) on parameters from \"src/test/resources/parameters/syncBadParamsBadPeers.json\"\n" + + "Apex parameters invalid\n" + + " specified \"synchronousPeer\" parameter value \"SyncConsumer1\" on event input \"SyncConsumer0\" does not exist or is an invalid peer for this event handler\n" + + " specified \"synchronousPeer\" parameter value \"SyncConsumer0\" on event input \"SyncConsumer1\" does not exist or is an invalid peer for this event handler\n" + + " specified \"synchronousPeer\" parameter value \"SyncProducer1\" on event output \"SyncProducer0\" does not exist or is an invalid peer for this event handler\n" + + " specified \"synchronousPeer\" parameter value \"SyncProducer0\" on event output \"SyncProducer1\" does not exist or is an invalid peer for this event handler", + e.getMessage()); + } + } + + @Test + public void syncBadSyncInvalidTimeout() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/syncBadParamsInvalidTimeout.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "validation error(s) on parameters from \"src/test/resources/parameters/syncBadParamsInvalidTimeout.json\"\n" + + "Apex parameters invalid\n" + + " parameter \\\"synchronousTimeout\\\" value \"-1\" is illegal on synchronous event input \"SyncConsumer0\", specify a non-negative timeout value in milliseconds\n" + + " parameter \\\"synchronousTimeout\\\" value \"-99999999\" is illegal on synchronous event input \"SyncConsumer1\", specify a non-negative timeout value in milliseconds\n" + + " parameter \\\"synchronousTimeout\\\" value \"-10\" is illegal on synchronous event output \"SyncProducer0\", specify a non-negative timeout value in milliseconds\n" + + " parameter \\\"synchronousTimeout\\\" value \"-3\" is illegal on synchronous event output \"SyncProducer1\", specify a non-negative timeout value in milliseconds\n" + + " synchronous timeout of event input \"SyncConsumer0\" and event output \"SyncProducer0\" [-1/-10] do not match\n" + + " synchronous timeout of event input \"SyncConsumer1\" and event output \"SyncProducer1\" [-99999999/-3] do not match", + e.getMessage()); + } + } + + @Test + public void syncBadSyncBadTimeout() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/syncBadParamsBadTimeout.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "validation error(s) on parameters from \"src/test/resources/parameters/syncBadParamsBadTimeout.json\"\n" + + "Apex parameters invalid\n" + + " parameter \\\"synchronousTimeout\\\" is illegal on non synchronous event output \"MyOtherProducer\"", + e.getMessage()); + } + } + + @Test + public void syncBadSyncUnpairedTimeout() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/syncBadParamsUnpairedTimeout.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "validation error(s) on parameters from \"src/test/resources/parameters/syncBadParamsUnpairedTimeout.json\"\n" + + "Apex parameters invalid\n" + + " synchronous timeout of event input \"SyncConsumer0\" and event output \"SyncProducer0\" [1/10] do not match\n" + + " synchronous timeout of event input \"SyncConsumer1\" and event output \"SyncProducer1\" [99999999/3] do not match", + e.getMessage()); + } + } + + @Test + public void syncGoodSyncGoodTimeoutProducer() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/syncGoodParamsProducerTimeout.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + assertEquals(12345, parameters.getEventInputParameters().get("SyncConsumer0") + .getPeerTimeout(EventHandlerPeeredMode.SYNCHRONOUS)); + assertEquals(1, parameters.getEventInputParameters().get("SyncConsumer1") + .getPeerTimeout(EventHandlerPeeredMode.SYNCHRONOUS)); + assertEquals(12345, parameters.getEventOutputParameters().get("SyncProducer0") + .getPeerTimeout(EventHandlerPeeredMode.SYNCHRONOUS)); + assertEquals(1, parameters.getEventOutputParameters().get("SyncProducer1") + .getPeerTimeout(EventHandlerPeeredMode.SYNCHRONOUS)); + } catch (final Exception e) { + fail("This test should not throw an exception"); + } + } + + @Test + public void syncGoodSyncGoodTimeoutConsumer() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/syncGoodParamsConsumerTimeout.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + assertEquals(12345, parameters.getEventInputParameters().get("SyncConsumer0") + .getPeerTimeout(EventHandlerPeeredMode.SYNCHRONOUS)); + assertEquals(1, parameters.getEventInputParameters().get("SyncConsumer1") + .getPeerTimeout(EventHandlerPeeredMode.SYNCHRONOUS)); + assertEquals(12345, parameters.getEventOutputParameters().get("SyncProducer0") + .getPeerTimeout(EventHandlerPeeredMode.SYNCHRONOUS)); + assertEquals(1, parameters.getEventOutputParameters().get("SyncProducer1") + .getPeerTimeout(EventHandlerPeeredMode.SYNCHRONOUS)); + } catch (final Exception e) { + fail("This test should not throw an exception"); + } + } + + @Test + public void syncGoodSyncGoodTimeoutBoth() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/syncGoodParamsBothTimeout.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + assertEquals(12345, parameters.getEventInputParameters().get("SyncConsumer0") + .getPeerTimeout(EventHandlerPeeredMode.SYNCHRONOUS)); + assertEquals(1, parameters.getEventInputParameters().get("SyncConsumer1") + .getPeerTimeout(EventHandlerPeeredMode.SYNCHRONOUS)); + assertEquals(12345, parameters.getEventOutputParameters().get("SyncProducer0") + .getPeerTimeout(EventHandlerPeeredMode.SYNCHRONOUS)); + assertEquals(1, parameters.getEventOutputParameters().get("SyncProducer1") + .getPeerTimeout(EventHandlerPeeredMode.SYNCHRONOUS)); + } catch (final Exception e) { + fail("This test should not throw an exception"); + } + } + + @Test + public void syncUnusedConsumerPeers() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/syncUnusedConsumerPeers.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "validation error(s) on parameters from \"src/test/resources/parameters/syncUnusedConsumerPeers.json\"\n" + + "Apex parameters invalid\n" + + " value of parameter \"synchronousPeer\" on event output \"SyncProducer1\" must be unique, it s used on another event output\n" + + "" + + " synchronous peers of event input \"SyncConsumer1\" and event output \"SyncProducer1/SyncConsumer0\" do not match", + e.getMessage()); + } + } + + @Test + public void syncMismatchedPeers() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/syncMismatchedPeers.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "validation error(s) on parameters from \"src/test/resources/parameters/syncMismatchedPeers.json\"\n" + + "Apex parameters invalid\n" + + " synchronous peers of event input \"SyncConsumer0\" and event output \"SyncProducer0/SyncConsumer1\" do not match\n" + + " synchronous peers of event input \"SyncConsumer1\" and event output \"SyncProducer1/SyncConsumer0\" do not match", + e.getMessage()); + } + } + + @Test + public void syncUnusedProducerPeers() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/syncUnusedProducerPeers.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "validation error(s) on parameters from \"src/test/resources/parameters/syncUnusedProducerPeers.json\"\n" + + "Apex parameters invalid\n" + + " value of parameter \"synchronousPeer\" on event input \"SyncConsumer1\" must be unique, it s used on another event input\n" + + " synchronous peers of event input \"SyncConsumer0\" and event output \"SyncProducer1/SyncConsumer1\" do not match", + e.getMessage()); + } + } + + @Test + public void syncMismatchedTimeout() throws ApexParameterException { + final String[] args = {"-c", "src/test/resources/parameters/syncUnusedProducerPeers.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + new ApexParameterHandler().getParameters(arguments); + fail("This test should throw an exception"); + } catch (final ApexParameterException e) { + assertEquals( + "validation error(s) on parameters from \"src/test/resources/parameters/syncUnusedProducerPeers.json\"\n" + + "Apex parameters invalid\n" + + " value of parameter \"synchronousPeer\" on event input \"SyncConsumer1\" must be unique, it s used on another event input\n" + + " synchronous peers of event input \"SyncConsumer0\" and event output \"SyncProducer1/SyncConsumer1\" do not match", + e.getMessage()); + } + } + + @Test + public void syncGoodParametersTest() { + final String[] args = {"-c", "src/test/resources/parameters/SyncGoodParams.json"}; + final ApexCommandLineArguments arguments = new ApexCommandLineArguments(args); + + try { + final ApexParameters parameters = new ApexParameterHandler().getParameters(arguments); + + assertEquals("MyApexEngine", parameters.getEngineServiceParameters().getName()); + assertEquals("0.0.1", parameters.getEngineServiceParameters().getVersion()); + assertEquals(45, parameters.getEngineServiceParameters().getId()); + assertEquals(19, parameters.getEngineServiceParameters().getInstanceCount()); + assertEquals(65522, parameters.getEngineServiceParameters().getDeploymentPort()); + + final CarrierTechnologyParameters prodCT0 = + parameters.getEventOutputParameters().get("SyncProducer0").getCarrierTechnologyParameters(); + final EventProtocolParameters prodEP0 = + parameters.getEventOutputParameters().get("SyncProducer0").getEventProtocolParameters(); + final CarrierTechnologyParameters consCT0 = + parameters.getEventInputParameters().get("SyncConsumer0").getCarrierTechnologyParameters(); + final EventProtocolParameters consEP0 = + parameters.getEventInputParameters().get("SyncConsumer0").getEventProtocolParameters(); + final CarrierTechnologyParameters prodCT1 = + parameters.getEventOutputParameters().get("SyncProducer1").getCarrierTechnologyParameters(); + final EventProtocolParameters prodEP1 = + parameters.getEventOutputParameters().get("SyncProducer1").getEventProtocolParameters(); + final CarrierTechnologyParameters consCT1 = + parameters.getEventInputParameters().get("SyncConsumer1").getCarrierTechnologyParameters(); + final EventProtocolParameters consEP1 = + parameters.getEventInputParameters().get("SyncConsumer1").getEventProtocolParameters(); + + assertEquals("FILE", prodCT0.getLabel()); + assertEquals("JSON", prodEP0.getLabel()); + assertEquals("FILE", consCT0.getLabel()); + assertEquals("JSON", consEP0.getLabel()); + assertEquals("FILE", prodCT1.getLabel()); + assertEquals("JSON", prodEP1.getLabel()); + assertEquals("SUPER_DOOPER", consCT1.getLabel()); + assertEquals("SUPER_TOK_DEL", consEP1.getLabel()); + + assertTrue(consCT1 instanceof SuperDooperCarrierTechnologyParameters); + assertTrue(consEP1 instanceof SuperTokenDelimitedEventProtocolParameters); + + final SuperDooperCarrierTechnologyParameters superDooperParameters = + (SuperDooperCarrierTechnologyParameters) consCT1; + assertEquals("localhost:9092", superDooperParameters.getBootstrapServers()); + assertEquals("all", superDooperParameters.getAcks()); + assertEquals(0, superDooperParameters.getRetries()); + assertEquals(16384, superDooperParameters.getBatchSize()); + assertEquals(1, superDooperParameters.getLingerTime()); + assertEquals(33554432, superDooperParameters.getBufferMemory()); + assertEquals("default-group-id", superDooperParameters.getGroupId()); + assertTrue(superDooperParameters.isEnableAutoCommit()); + assertEquals(1000, superDooperParameters.getAutoCommitTime()); + assertEquals(30000, superDooperParameters.getSessionTimeout()); + assertEquals("apex-out", superDooperParameters.getProducerTopic()); + assertEquals(100, superDooperParameters.getConsumerPollTime()); + assertEquals("org.apache.superDooper.common.serialization.StringSerializer", + superDooperParameters.getKeySerializer()); + assertEquals("org.apache.superDooper.common.serialization.StringSerializer", + superDooperParameters.getValueSerializer()); + assertEquals("org.apache.superDooper.common.serialization.StringDeserializer", + superDooperParameters.getKeyDeserializer()); + assertEquals("org.apache.superDooper.common.serialization.StringDeserializer", + superDooperParameters.getValueDeserializer()); + + final String[] consumerTopics = {"apex-in"}; + assertEquals(Arrays.asList(consumerTopics), superDooperParameters.getConsumerTopicList()); + } catch (final ApexParameterException e) { + fail("This test should not throw an exception"); + } + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperCarrierTechnologyParameters.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperCarrierTechnologyParameters.java new file mode 100644 index 000000000..ffbd1c0e5 --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperCarrierTechnologyParameters.java @@ -0,0 +1,392 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.parameters.dummyclasses; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Properties; + +import org.onap.policy.apex.model.basicmodel.service.ParameterService; +import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters; + +/** + * Apex parameters for SuperDooper as an event carrier technology. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class SuperDooperCarrierTechnologyParameters extends CarrierTechnologyParameters { + // Default parameter values + private static final String DEFAULT_ACKS = "all"; + private static final String DEFAULT_BOOTSTRAP_SERVERS = "localhost:9092"; + private static final int DEFAULT_RETRIES = 0; + private static final int DEFAULT_BATCH_SIZE = 16384; + private static final int DEFAULT_LINGER_TIME = 1; + private static final long DEFAULT_BUFFER_MEMORY = 33554432; + private static final String DEFAULT_GROUP_ID = "default-group-id"; + private static final boolean DEFAULT_ENABLE_AUTO_COMMIT = true; + private static final int DEFAULT_AUTO_COMMIT_TIME = 1000; + private static final int DEFAULT_SESSION_TIMEOUT = 30000; + private static final String DEFAULT_PRODUCER_TOPIC = "apex-out"; + private static final int DEFAULT_CONSUMER_POLL_TIME = 100; + private static final String[] DEFAULT_CONSUMER_TOPIC_LIST = {"apex-in"}; + private static final String DEFAULT_KEY_SERIALIZER = "org.apache.superDooper.common.serialization.StringSerializer"; + private static final String DEFAULT_VALUE_SERIALIZER = + "org.apache.superDooper.common.serialization.StringSerializer"; + private static final String DEFAULT_KEY_DESERIALIZER = + "org.apache.superDooper.common.serialization.StringDeserializer"; + private static final String DEFAULT_VALUE_DESERIALIZER = + "org.apache.superDooper.common.serialization.StringDeserializer"; + + // Parameter property map tokens + private static final String PROPERTY_BOOTSTRAP_SERVERS = "bootstrap.servers"; + private static final String PROPERTY_ACKS = "acks"; + private static final String PROPERTY_RETRIES = "retries"; + private static final String PROPERTY_BATCH_SIZE = "batch.size"; + private static final String PROPERTY_LINGER_TIME = "linger.ms"; + private static final String PROPERTY_BUFFER_MEMORY = "buffer.memory"; + private static final String PROPERTY_GROUP_ID = "group.id"; + private static final String PROPERTY_ENABLE_AUTO_COMMIT = "enable.auto.commit"; + private static final String PROPERTY_AUTO_COMMIT_TIME = "auto.commit.interval.ms"; + private static final String PROPERTY_SESSION_TIMEOUT = "session.timeout.ms"; + private static final String PROPERTY_KEY_SERIALIZER = "key.serializer"; + private static final String PROPERTY_VALUE_SERIALIZER = "value.serializer"; + private static final String PROPERTY_KEY_DESERIALIZER = "key.deserializer"; + private static final String PROPERTY_VALUE_DESERIALIZER = "value.deserializer"; + + // superDooper carrier parameters + private final String bootstrapServers = DEFAULT_BOOTSTRAP_SERVERS; + private final String acks = DEFAULT_ACKS; + private final int retries = DEFAULT_RETRIES; + private final int batchSize = DEFAULT_BATCH_SIZE; + private final int lingerTime = DEFAULT_LINGER_TIME; + private final long bufferMemory = DEFAULT_BUFFER_MEMORY; + private final String groupId = DEFAULT_GROUP_ID; + private final boolean enableAutoCommit = DEFAULT_ENABLE_AUTO_COMMIT; + private final int autoCommitTime = DEFAULT_AUTO_COMMIT_TIME; + private final int sessionTimeout = DEFAULT_SESSION_TIMEOUT; + private final String producerTopic = DEFAULT_PRODUCER_TOPIC; + private final int consumerPollTime = DEFAULT_CONSUMER_POLL_TIME; + private final String[] consumerTopicList = DEFAULT_CONSUMER_TOPIC_LIST; + private final String keySerializer = DEFAULT_KEY_SERIALIZER; + private final String valueSerializer = DEFAULT_VALUE_SERIALIZER; + private final String keyDeserializer = DEFAULT_KEY_DESERIALIZER; + private final String valueDeserializer = DEFAULT_VALUE_DESERIALIZER; + + /** + * Constructor to create a file carrier technology parameters instance and register the instance + * with the parameter service. + */ + public SuperDooperCarrierTechnologyParameters() { + super(SuperDooperCarrierTechnologyParameters.class.getCanonicalName()); + ParameterService.registerParameters(SuperDooperCarrierTechnologyParameters.class, this); + + // Set the carrier technology properties for the FILE carrier technology + this.setLabel("SUPER_DOOPER"); + this.setEventProducerPluginClass( + "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperEventProducer"); + this.setEventConsumerPluginClass( + "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperEventSubscriber"); + } + + /** + * Gets the superDooper producer properties. + * + * @return the superDooper producer properties + */ + public Properties getSuperDooperProducerProperties() { + final Properties superDooperProperties = new Properties(); + + superDooperProperties.put(PROPERTY_BOOTSTRAP_SERVERS, bootstrapServers); + superDooperProperties.put(PROPERTY_ACKS, acks); + superDooperProperties.put(PROPERTY_RETRIES, retries); + superDooperProperties.put(PROPERTY_BATCH_SIZE, batchSize); + superDooperProperties.put(PROPERTY_LINGER_TIME, lingerTime); + superDooperProperties.put(PROPERTY_BUFFER_MEMORY, bufferMemory); + superDooperProperties.put(PROPERTY_KEY_SERIALIZER, keySerializer); + superDooperProperties.put(PROPERTY_VALUE_SERIALIZER, valueSerializer); + + return superDooperProperties; + } + + /** + * Gets the superDooper consumer properties. + * + * @return the superDooper consumer properties + */ + public Properties getSuperDooperConsumerProperties() { + final Properties superDooperProperties = new Properties(); + + superDooperProperties.put(PROPERTY_BOOTSTRAP_SERVERS, bootstrapServers); + superDooperProperties.put(PROPERTY_GROUP_ID, groupId); + superDooperProperties.put(PROPERTY_ENABLE_AUTO_COMMIT, enableAutoCommit); + superDooperProperties.put(PROPERTY_AUTO_COMMIT_TIME, autoCommitTime); + superDooperProperties.put(PROPERTY_SESSION_TIMEOUT, sessionTimeout); + superDooperProperties.put(PROPERTY_KEY_DESERIALIZER, keyDeserializer); + superDooperProperties.put(PROPERTY_VALUE_DESERIALIZER, valueDeserializer); + + return superDooperProperties; + } + + /** + * Gets the bootstrap servers. + * + * @return the bootstrap servers + */ + public String getBootstrapServers() { + return bootstrapServers; + } + + /** + * Gets the acks. + * + * @return the acks + */ + public String getAcks() { + return acks; + } + + /** + * Gets the retries. + * + * @return the retries + */ + public int getRetries() { + return retries; + } + + /** + * Gets the batch size. + * + * @return the batch size + */ + public int getBatchSize() { + return batchSize; + } + + /** + * Gets the linger time. + * + * @return the linger time + */ + public int getLingerTime() { + return lingerTime; + } + + /** + * Gets the buffer memory. + * + * @return the buffer memory + */ + public long getBufferMemory() { + return bufferMemory; + } + + /** + * Gets the group id. + * + * @return the group id + */ + public String getGroupId() { + return groupId; + } + + /** + * Checks if is enable auto commit. + * + * @return true, if checks if is enable auto commit + */ + public boolean isEnableAutoCommit() { + return enableAutoCommit; + } + + /** + * Gets the auto commit time. + * + * @return the auto commit time + */ + public int getAutoCommitTime() { + return autoCommitTime; + } + + /** + * Gets the session timeout. + * + * @return the session timeout + */ + public int getSessionTimeout() { + return sessionTimeout; + } + + /** + * Gets the producer topic. + * + * @return the producer topic + */ + public String getProducerTopic() { + return producerTopic; + } + + /** + * Gets the consumer poll time. + * + * @return the consumer poll time + */ + public long getConsumerPollTime() { + return consumerPollTime; + } + + /** + * Gets the consumer topic list. + * + * @return the consumer topic list + */ + public Collection<String> getConsumerTopicList() { + return Arrays.asList(consumerTopicList); + } + + /** + * Gets the key serializer. + * + * @return the key serializer + */ + public String getKeySerializer() { + return keySerializer; + } + + /** + * Gets the value serializer. + * + * @return the value serializer + */ + public String getValueSerializer() { + return valueSerializer; + } + + /** + * Gets the key deserializer. + * + * @return the key deserializer + */ + public String getKeyDeserializer() { + return keyDeserializer; + } + + /** + * Gets the value deserializer. + * + * @return the value deserializer + */ + public String getValueDeserializer() { + return valueDeserializer; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.apps.uservice.parameters.ApexParameterValidator#validate() + */ + @Override + public String validate() { + final StringBuilder errorMessageBuilder = new StringBuilder(); + + errorMessageBuilder.append(super.validate()); + + if (bootstrapServers == null || bootstrapServers.trim().length() == 0) { + errorMessageBuilder + .append(" bootstrapServers not specified, must be specified as a string of form host:port\n"); + } + + if (acks == null || acks.trim().length() == 0) { + errorMessageBuilder.append(" acks not specified, must be specified as a string with values [0|1|all]\n"); + } + + if (retries < 0) { + errorMessageBuilder.append(" retries [" + retries + "] invalid, must be specified as retries >= 0\n"); + } + + if (batchSize < 0) { + errorMessageBuilder + .append(" batchSize [" + batchSize + "] invalid, must be specified as batchSize >= 0\n"); + } + + if (lingerTime < 0) { + errorMessageBuilder + .append(" lingerTime [" + lingerTime + "] invalid, must be specified as lingerTime >= 0\n"); + } + + if (bufferMemory < 0) { + errorMessageBuilder + .append(" bufferMemory [" + bufferMemory + "] invalid, must be specified as bufferMemory >= 0\n"); + } + + if (groupId == null || groupId.trim().length() == 0) { + errorMessageBuilder.append(" groupId not specified, must be specified as a string\n"); + } + + if (autoCommitTime < 0) { + errorMessageBuilder.append( + " autoCommitTime [" + autoCommitTime + "] invalid, must be specified as autoCommitTime >= 0\n"); + } + + if (sessionTimeout < 0) { + errorMessageBuilder.append( + " sessionTimeout [" + sessionTimeout + "] invalid, must be specified as sessionTimeout >= 0\n"); + } + + if (producerTopic == null || producerTopic.trim().length() == 0) { + errorMessageBuilder.append(" producerTopic not specified, must be specified as a string\n"); + } + + if (consumerPollTime < 0) { + errorMessageBuilder.append(" consumerPollTime [" + consumerPollTime + + "] invalid, must be specified as consumerPollTime >= 0\n"); + } + + if (consumerTopicList == null || consumerTopicList.length == 0) { + errorMessageBuilder.append(" consumerTopicList not specified, must be specified as a list of strings\n"); + } + + for (final String consumerTopic : consumerTopicList) { + if (consumerTopic == null || consumerTopic.trim().length() == 0) { + errorMessageBuilder.append(" invalid consumer topic \"" + consumerTopic + + "\" specified on consumerTopicList, consumer topics must be specified as strings\n"); + } + } + + if (keySerializer == null || keySerializer.trim().length() == 0) { + errorMessageBuilder.append(" keySerializer not specified, must be specified as a string\n"); + } + + if (valueSerializer == null || valueSerializer.trim().length() == 0) { + errorMessageBuilder.append(" valueSerializer not specified, must be specified as a string\n"); + } + + if (keyDeserializer == null || keyDeserializer.trim().length() == 0) { + errorMessageBuilder.append(" keyDeserializer not specified, must be specified as a string\n"); + } + + if (valueDeserializer == null || valueDeserializer.trim().length() == 0) { + errorMessageBuilder.append(" valueDeserializer not specified, must be specified as a string\n"); + } + + return errorMessageBuilder.toString(); + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperDistributorParameters.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperDistributorParameters.java new file mode 100644 index 000000000..6d7c6ff7e --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperDistributorParameters.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.parameters.dummyclasses; + +import org.onap.policy.apex.context.parameters.DistributorParameters; +import org.onap.policy.apex.model.basicmodel.service.ParameterService; + +/** + * Distributor parameters for the Super Dooper Distributor + * + * @author Liam Fallon (liam.fallon@ericsson.com) + * @version + */ +public class SuperDooperDistributorParameters extends DistributorParameters { + // Constants for SuperDooper configuration file locations + public static final String DEFAULT_SUPER_DOOPER_DISTRIBUTION_CONFIG_FILE = "superDooper/superDooper.xml"; + public static final String DEFAULT_SUPER_DOOPER_DISTRIBUTION_JGROUPS_FILE = + "superDooper/jgroups-superDooper-apex.xml"; + public static final boolean DEFAULT_SUPER_DOOPER_JAVA_NET_PREFER_IPV4_STACK = true; + public static final String DEFAULT_INFINSPAN_JGROUPS_BIND_ADDRESS = "localhost"; + + // SuperDooper configuration file names + private String configFile = DEFAULT_SUPER_DOOPER_DISTRIBUTION_CONFIG_FILE; + private String jgroupsFile = DEFAULT_SUPER_DOOPER_DISTRIBUTION_JGROUPS_FILE; + private boolean preferIPv4Stack = DEFAULT_SUPER_DOOPER_JAVA_NET_PREFER_IPV4_STACK; + private String jGroupsBindAddress = DEFAULT_INFINSPAN_JGROUPS_BIND_ADDRESS; + + public SuperDooperDistributorParameters() { + super(SuperDooperDistributorParameters.class.getCanonicalName()); + ParameterService.registerParameters(SuperDooperDistributorParameters.class, this); + ParameterService.registerParameters(DistributorParameters.class, this); + } + + public String getConfigFile() { + return configFile; + } + + public void setConfigFile(final String configFile) { + this.configFile = configFile; + } + + public String getJgroupsFile() { + return jgroupsFile; + } + + public void setJgroupsFile(final String jgroupsFile) { + this.jgroupsFile = jgroupsFile; + } + + public boolean preferIPv4Stack() { + return preferIPv4Stack; + } + + public void setPreferIPv4Stack(final boolean preferIPv4Stack) { + this.preferIPv4Stack = preferIPv4Stack; + } + + public String getjGroupsBindAddress() { + return jGroupsBindAddress; + } + + public void setjGroupsBindAddress(final String jGroupsBindAddress) { + this.jGroupsBindAddress = jGroupsBindAddress; + } + + @Override + public String toString() { + return "SuperDooperDistributorParameters [configFile=" + configFile + ", jgroupsFile=" + jgroupsFile + + ", preferIPv4Stack=" + preferIPv4Stack + ", jGroupsBindAddress=" + jGroupsBindAddress + "]"; + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperEventProducer.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperEventProducer.java new file mode 100644 index 000000000..e405107f0 --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperEventProducer.java @@ -0,0 +1,106 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.parameters.dummyclasses; + +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.engine.event.ApexEventProducer; +import org.onap.policy.apex.service.engine.event.PeeredReference; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * @author John Keeney (john.keeney@ericsson.com) + */ +public class SuperDooperEventProducer implements ApexEventProducer { + + private static final XLogger LOGGER = XLoggerFactory.getXLogger(SuperDooperEventProducer.class); + + private String name; + + public SuperDooperEventProducer() {} + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.event.ApexEventProducer#init(java.lang.String, + * com.ericsson.apex.service.parameters.producer.ProducerParameters) + */ + @Override + public void init(final String name, final EventHandlerParameters producerParameters) throws ApexEventException { + this.name = name; + } + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.event.ApexEventProducer#getName() + */ + @Override + public String getName() { + return name; + } + + /* + * (non-Javadoc) + * + * @see + * com.ericsson.apex.service.engine.event.ApexEventProducer#getPeeredReference(com.ericsson.apex + * .service.parameters.eventhandler.EventHandlerPeeredMode) + */ + @Override + public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) { + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.ericsson.apex.service.engine.event.ApexEventProducer#setPeeredReference(com.ericsson.apex + * .service.parameters.eventhandler.EventHandlerPeeredMode, + * com.ericsson.apex.service.engine.event.PeeredReference) + */ + @Override + public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {} + + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.event.ApexEventProducer#sendEvent(long, + * java.lang.String, java.lang.Object) + */ + @Override + public void sendEvent(final long executionId, final String eventName, final Object event) { + LOGGER.info("Sending Event: " + this.getClass().getCanonicalName() + ":" + this.name + " ... event (" + + eventName + ") : " + event); + } + + /* + * (non-Javadoc) + * + * @see com.ericsson.apex.service.engine.event.ApexEventProducer#stop() + */ + @Override + public void stop() {} +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperEventSubscriber.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperEventSubscriber.java new file mode 100644 index 000000000..c791d31e1 --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperEventSubscriber.java @@ -0,0 +1,82 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.parameters.dummyclasses; + +import org.onap.policy.apex.service.engine.event.ApexEventConsumer; +import org.onap.policy.apex.service.engine.event.ApexEventException; +import org.onap.policy.apex.service.engine.event.ApexEventReceiver; +import org.onap.policy.apex.service.engine.event.PeeredReference; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters; +import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +public class SuperDooperEventSubscriber implements ApexEventConsumer { + + private static final XLogger LOGGER = XLoggerFactory.getXLogger(SuperDooperEventSubscriber.class); + + private String name; + + public SuperDooperEventSubscriber() {} + + @Override + public void init(final String name, final EventHandlerParameters consumerParameters, + final ApexEventReceiver apexEventReceiver) throws ApexEventException { + this.name = name; + LOGGER.info("Initialising Apex Consumer: " + this.getClass().getCanonicalName() + ":" + this.name); + } + + @Override + public String getName() { + return name; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#getPeeredReference(org.onap. + * policy.apex .service.parameters.eventhandler.EventHandlerPeeredMode) + */ + @Override + public PeeredReference getPeeredReference(final EventHandlerPeeredMode peeredMode) { + return null; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.service.engine.event.ApexEventConsumer#setPeeredReference(org.onap. + * policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode, + * org.onap.policy.apex.service.engine.event.PeeredReference) + */ + @Override + public void setPeeredReference(final EventHandlerPeeredMode peeredMode, final PeeredReference peeredReference) {} + + @Override + public void start() { + // TODO Auto-generated method stub + + } + + @Override + public void stop() {} + +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperExecutorParameters.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperExecutorParameters.java new file mode 100644 index 000000000..3af772985 --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperDooperExecutorParameters.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.parameters.dummyclasses; + +import org.onap.policy.apex.core.engine.ExecutorParameters; + +/** + * Default Executor parameters for MVEL + * + * @author Liam Fallon (liam.fallon@ericsson.com) + * @version + */ +public class SuperDooperExecutorParameters extends ExecutorParameters { + public SuperDooperExecutorParameters() { + this.setTaskExecutorPluginClass( + "org.onap.policy.apex.service.engine.parameters.dummyclasses.DummyTaskExecutor"); + this.setTaskSelectionExecutorPluginClass( + "org.onap.policy.apex.service.engine.parameters.dummyclasses.DummyTaskSelectExecutor"); + this.setStateFinalizerExecutorPluginClass( + "org.onap.policy.apex.service.engine.parameters.dummyclasses.DummyStateFinalizerExecutor"); + } +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperTokenDelimitedEventConverter.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperTokenDelimitedEventConverter.java new file mode 100644 index 000000000..e807f7fb5 --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperTokenDelimitedEventConverter.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.parameters.dummyclasses; + +import java.util.List; + +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; +import org.onap.policy.apex.service.engine.event.ApexEvent; +import org.onap.policy.apex.service.engine.event.ApexEventProtocolConverter; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolParameters; + +public final class SuperTokenDelimitedEventConverter implements ApexEventProtocolConverter { + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.ApexEventConverter#toApexEvent(java.lang.String, + * java.lang.Object) + */ + @Override + public List<ApexEvent> toApexEvent(final String eventName, final Object eventOfOtherType) throws ApexException { + return null; + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.apex.service.engine.event.ApexEventConverter#fromApexEvent(org.onap.policy. + * apex.service.engine.event.ApexEvent) + */ + @Override + public String fromApexEvent(final ApexEvent apexEvent) throws ApexException { + return null; + } + + @Override + public void init(final EventProtocolParameters parameters) {} +} diff --git a/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperTokenDelimitedEventProtocolParameters.java b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperTokenDelimitedEventProtocolParameters.java new file mode 100644 index 000000000..99f938e10 --- /dev/null +++ b/services/services-engine/src/test/java/org/onap/policy/apex/service/engine/parameters/dummyclasses/SuperTokenDelimitedEventProtocolParameters.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2016-2018 Ericsson. 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.apex.service.engine.parameters.dummyclasses; + +import org.onap.policy.apex.model.basicmodel.service.ParameterService; +import org.onap.policy.apex.service.engine.event.impl.jsonprotocolplugin.JSONEventProtocolParameters; +import org.onap.policy.apex.service.parameters.eventprotocol.EventProtocolTextTokenDelimitedParameters; + +/** + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class SuperTokenDelimitedEventProtocolParameters extends EventProtocolTextTokenDelimitedParameters { + /** The label of this carrier technology. */ + public static final String SUPER_TOKEN_EVENT_PROTOCOL_LABEL = "SUPER_TOK_DEL"; + + // Constants for text delimiter tokeb + private static final String SUPER_TOKEN_DELIMITER = "SuperToken"; + + /** + * Constructor to create a JSON event protocol parameter instance and register the instance with + * the parameter service. + */ + public SuperTokenDelimitedEventProtocolParameters() { + super(JSONEventProtocolParameters.class.getCanonicalName()); + ParameterService.registerParameters(SuperTokenDelimitedEventProtocolParameters.class, this); + + // Set the event protocol properties for the JSON carrier technology + this.setLabel(SUPER_TOKEN_EVENT_PROTOCOL_LABEL); + + // Set the starting and ending delimiters for text blocks of JSON events + this.setDelimiterToken(SUPER_TOKEN_DELIMITER); + + // Set the event protocol plugin class + this.setEventProtocolPluginClass(SuperTokenDelimitedEventConverter.class.getCanonicalName()); + } +} diff --git a/services/services-engine/src/test/resources/logback-test.xml b/services/services-engine/src/test/resources/logback-test.xml new file mode 100644 index 000000000..bb9d0c788 --- /dev/null +++ b/services/services-engine/src/test/resources/logback-test.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + Copyright (C) 2016-2018 Ericsson. 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. + + SPDX-License-Identifier: Apache-2.0 + ============LICENSE_END========================================================= +--> + +<configuration> + + <contextName>Apex</contextName> + <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /> + <property name="LOG_DIR" value="${java.io.tmpdir}/apex_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.onap.policy.apex.service.engine.event" level="info" additivity="false"> + <appender-ref ref="STDOUT" /> + </logger> +</configuration> diff --git a/services/services-engine/src/test/resources/main/DummyModelFile.json b/services/services-engine/src/test/resources/main/DummyModelFile.json new file mode 100644 index 000000000..b6cf5bd08 --- /dev/null +++ b/services/services-engine/src/test/resources/main/DummyModelFile.json @@ -0,0 +1,3 @@ +{ + "name": "value" +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/badParams.json b/services/services-engine/src/test/resources/parameters/badParams.json new file mode 100644 index 000000000..c3b96c7ba --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/badParams.json @@ -0,0 +1,31 @@ +{ + "engineServiceParameters": { + "name": "hello there", + "version": "PA1", + "id": -45, + "instanceCount": -345, + "deploymentPort": 65536, + "policyModelFileName": "/some/file/name.xml" + }, + "eventOutputParameters": { + "FirstProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE" + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "TheFileConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/blankParams.json b/services/services-engine/src/test/resources/parameters/blankParams.json new file mode 100644 index 000000000..d874ae98b --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/blankParams.json @@ -0,0 +1,11 @@ +{ + "engineServiceParameters": { + + }, + "eventInputParameters": { + + }, + "eventOutputParameters": { + + } +} diff --git a/services/services-engine/src/test/resources/parameters/empty.json b/services/services-engine/src/test/resources/parameters/empty.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/empty.json @@ -0,0 +1 @@ +{}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/factoryGoodParams.json b/services/services-engine/src/test/resources/parameters/factoryGoodParams.json new file mode 100644 index 000000000..54b58ce00 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/factoryGoodParams.json @@ -0,0 +1,64 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "FirstProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + }, + "MyOtherProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "TheFileConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + }, + "MySuperDooperConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/goodParams.json b/services/services-engine/src/test/resources/parameters/goodParams.json new file mode 100644 index 000000000..c470f3eea --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/goodParams.json @@ -0,0 +1,64 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "FirstProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + }, + "MyOtherProducer": { + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + } + } + }, + "eventInputParameters": { + "TheFileConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + }, + "MySuperDooperConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/noParams.json b/services/services-engine/src/test/resources/parameters/noParams.json new file mode 100644 index 000000000..7a73a41bf --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/noParams.json @@ -0,0 +1,2 @@ +{ +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/prodConsBadCTParClass.json b/services/services-engine/src/test/resources/parameters/prodConsBadCTParClass.json new file mode 100644 index 000000000..217946956 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/prodConsBadCTParClass.json @@ -0,0 +1,42 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "aProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "aConsumer": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.FILECarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/prodConsBadEPParClass.json b/services/services-engine/src/test/resources/parameters/prodConsBadEPParClass.json new file mode 100644 index 000000000..0900d5bee --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/prodConsBadEPParClass.json @@ -0,0 +1,42 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "aProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "aConsumer": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.event.impl.jsonprotocolplugin.JSONEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/prodConsBadFileName.json b/services/services-engine/src/test/resources/parameters/prodConsBadFileName.json new file mode 100644 index 000000000..2dc506561 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/prodConsBadFileName.json @@ -0,0 +1,42 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "aProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": null + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "aConsumer": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/prodConsMismatchCTParClass.json b/services/services-engine/src/test/resources/parameters/prodConsMismatchCTParClass.json new file mode 100644 index 000000000..e8d1a9632 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/prodConsMismatchCTParClass.json @@ -0,0 +1,42 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "aProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "aConsumer": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_LOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/prodConsMismatchEPParClass.json b/services/services-engine/src/test/resources/parameters/prodConsMismatchEPParClass.json new file mode 100644 index 000000000..89e905c3a --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/prodConsMismatchEPParClass.json @@ -0,0 +1,42 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "aProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "aConsumer": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_BEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/prodConsNoCT.json b/services/services-engine/src/test/resources/parameters/prodConsNoCT.json new file mode 100644 index 000000000..7bf3024ba --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/prodConsNoCT.json @@ -0,0 +1,42 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "aProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "aConsumer": { + "carrierParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.FILECarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/prodConsNoCTParClass.json b/services/services-engine/src/test/resources/parameters/prodConsNoCTParClass.json new file mode 100644 index 000000000..9c8723a81 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/prodConsNoCTParClass.json @@ -0,0 +1,41 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "aProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "aConsumer": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/prodConsNoEP.json b/services/services-engine/src/test/resources/parameters/prodConsNoEP.json new file mode 100644 index 000000000..122680dbe --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/prodConsNoEP.json @@ -0,0 +1,42 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "aProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "aConsumer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameterClassName": "org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.FILECarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/prodConsNoEPParClass.json b/services/services-engine/src/test/resources/parameters/prodConsNoEPParClass.json new file mode 100644 index 000000000..8aea0ea3e --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/prodConsNoEPParClass.json @@ -0,0 +1,41 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "aProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "aConsumer": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/prodConsOKFileName.json b/services/services-engine/src/test/resources/parameters/prodConsOKFileName.json new file mode 100644 index 000000000..b2424043e --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/prodConsOKFileName.json @@ -0,0 +1,42 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "aProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "aConsumer": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/prodConsWrongTypeCTParClass.json b/services/services-engine/src/test/resources/parameters/prodConsWrongTypeCTParClass.json new file mode 100644 index 000000000..6bfab6a99 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/prodConsWrongTypeCTParClass.json @@ -0,0 +1,42 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "aProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "aConsumer": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/prodConsWrongTypeEPParClass.json b/services/services-engine/src/test/resources/parameters/prodConsWrongTypeEPParClass.json new file mode 100644 index 000000000..d72139de8 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/prodConsWrongTypeEPParClass.json @@ -0,0 +1,42 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "aProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "aConsumer": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceContextBadClassDistParams.json b/services/services-engine/src/test/resources/parameters/serviceContextBadClassDistParams.json new file mode 100644 index 000000000..6468e10a4 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceContextBadClassDistParams.json @@ -0,0 +1,23 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "contextParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.ContextParameters", + "distributorParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.ContextParameters" + } + }, + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceContextBadClassLockParams.json b/services/services-engine/src/test/resources/parameters/serviceContextBadClassLockParams.json new file mode 100644 index 000000000..57a38024d --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceContextBadClassLockParams.json @@ -0,0 +1,23 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "contextParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.ContextParameters", + "lockManagerParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.ContextParameters" + } + }, + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceContextBadClassParams.json b/services/services-engine/src/test/resources/parameters/serviceContextBadClassParams.json new file mode 100644 index 000000000..a2920303a --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceContextBadClassParams.json @@ -0,0 +1,15 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "contextParameters": { + "parameterClassName": "java.lang.Integer" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceContextBadClassPersistParams.json b/services/services-engine/src/test/resources/parameters/serviceContextBadClassPersistParams.json new file mode 100644 index 000000000..598c20bd7 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceContextBadClassPersistParams.json @@ -0,0 +1,23 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "contextParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.ContextParameters", + "persistorParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.ContextParameters" + } + }, + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceContextBadParams.json b/services/services-engine/src/test/resources/parameters/serviceContextBadParams.json new file mode 100644 index 000000000..d850ba290 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceContextBadParams.json @@ -0,0 +1,15 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "contextParameters": { + "parameterClassName": "hello" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceContextBadPluginClassParams.json b/services/services-engine/src/test/resources/parameters/serviceContextBadPluginClassParams.json new file mode 100644 index 000000000..beb049069 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceContextBadPluginClassParams.json @@ -0,0 +1,15 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "contextParameters": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceContextBadPluginNameParams.json b/services/services-engine/src/test/resources/parameters/serviceContextBadPluginNameParams.json new file mode 100644 index 000000000..d152809fa --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceContextBadPluginNameParams.json @@ -0,0 +1,15 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "contextParameters": { + "parameterClassNamelooby": "" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceContextNoParams.json b/services/services-engine/src/test/resources/parameters/serviceContextNoParams.json new file mode 100644 index 000000000..2d6cb4d85 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceContextNoParams.json @@ -0,0 +1,15 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "contextParameters": { + + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceContextOKDefaultParams.json b/services/services-engine/src/test/resources/parameters/serviceContextOKDefaultParams.json new file mode 100644 index 000000000..56294a3c7 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceContextOKDefaultParams.json @@ -0,0 +1,45 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "contextParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.ContextParameters" + }, + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "FirstProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "MySuperDooperConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceContextOKDistParams.json b/services/services-engine/src/test/resources/parameters/serviceContextOKDistParams.json new file mode 100644 index 000000000..1aa2abb0b --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceContextOKDistParams.json @@ -0,0 +1,48 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "contextParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.ContextParameters", + "contextParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.DistributorParameters" + } + }, + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "FirstProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "MySuperDooperConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceContextOKFlushParams.json b/services/services-engine/src/test/resources/parameters/serviceContextOKFlushParams.json new file mode 100644 index 000000000..7d9eb6f2e --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceContextOKFlushParams.json @@ -0,0 +1,49 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "contextParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.ContextParameters", + "persistorParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.PersistorParameters", + "flushPeriod": 123456 + } + }, + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "FirstProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "MySuperDooperConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceContextOKFullParams.json b/services/services-engine/src/test/resources/parameters/serviceContextOKFullParams.json new file mode 100644 index 000000000..22991054a --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceContextOKFullParams.json @@ -0,0 +1,59 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "contextParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.ContextParameters", + "distributorParameters": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperDistributorParameters", + "configFile": "my/lovely/configFile.xml", + "jgroupsFile": "holy/stone.xml", + "preferIPv4Stack": false, + "jGroupsBindAddress": "fatherted" + }, + "lockManagerParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.LockManagerParameters" + }, + "persistorParameters": { + "parameterClassName": "org.onap.policy.apex.context.parameters.PersistorParameters", + "flushPeriod": 123456 + } + }, + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "FirstProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "MySuperDooperConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceExecutorBadParams.json b/services/services-engine/src/test/resources/parameters/serviceExecutorBadParams.json new file mode 100644 index 000000000..839694af3 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceExecutorBadParams.json @@ -0,0 +1,18 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + }, + "ZOOBY": "hello" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceExecutorBadPluginNameParams.json b/services/services-engine/src/test/resources/parameters/serviceExecutorBadPluginNameParams.json new file mode 100644 index 000000000..5a28d8985 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceExecutorBadPluginNameParams.json @@ -0,0 +1,23 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + }, + "ZOOBY": { + "parameterClassNamelooby": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + }, + "LOOBY": { + "parameterClassNamelooby": "" + } + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceExecutorBadPluginValueBlankParams.json b/services/services-engine/src/test/resources/parameters/serviceExecutorBadPluginValueBlankParams.json new file mode 100644 index 000000000..c70fa4c8b --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceExecutorBadPluginValueBlankParams.json @@ -0,0 +1,23 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + }, + "ZOOBY": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + }, + "LOOBY": { + "parameterClassName": " " + } + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceExecutorBadPluginValueObjectParams.json b/services/services-engine/src/test/resources/parameters/serviceExecutorBadPluginValueObjectParams.json new file mode 100644 index 000000000..200d8f1a5 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceExecutorBadPluginValueObjectParams.json @@ -0,0 +1,25 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + }, + "ZOOBY": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + }, + "LOOBY": { + "parameterClassName": { + + } + } + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceExecutorBadPluginValueParams.json b/services/services-engine/src/test/resources/parameters/serviceExecutorBadPluginValueParams.json new file mode 100644 index 000000000..b96a27409 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceExecutorBadPluginValueParams.json @@ -0,0 +1,23 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + }, + "ZOOBY": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + }, + "LOOBY": { + "parameterClassName": "helloworld" + } + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceExecutorEmptyParams.json b/services/services-engine/src/test/resources/parameters/serviceExecutorEmptyParams.json new file mode 100644 index 000000000..f07eaff9d --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceExecutorEmptyParams.json @@ -0,0 +1,20 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + }, + "ZOOBY": { + + } + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceExecutorNoExecutorParams.json b/services/services-engine/src/test/resources/parameters/serviceExecutorNoExecutorParams.json new file mode 100644 index 000000000..44d643cd2 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceExecutorNoExecutorParams.json @@ -0,0 +1,13 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "someParameter": "someValue" + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/serviceExecutorNoParams.json b/services/services-engine/src/test/resources/parameters/serviceExecutorNoParams.json new file mode 100644 index 000000000..751ac2171 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/serviceExecutorNoParams.json @@ -0,0 +1,40 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + + } + } + }, + "eventOutputParameters": { + "FirstProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + }, + "eventInputParameters": { + "MySuperDooperConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/superDooperParams.json b/services/services-engine/src/test/resources/parameters/superDooperParams.json new file mode 100644 index 000000000..75820ebaf --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/superDooperParams.json @@ -0,0 +1,55 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 345, + "deploymentPort": 65522 + }, + "eventOutputParameters": { + "FirstProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters", + "parameters": { + "bootstrapServers": "somehost:12345", + "acks": 0, + "retries": 25, + "batchSize": 98765, + "lingerTime": 21, + "bufferMemory": 50505050, + "groupId": "first-group-id", + "enableAutoCommit": false, + "autoCommitTime": 441, + "sessionTimeout": 987, + "producerTopic": "producer-out", + "consumerPollTime": 101, + "consumerTopicList": [ + "consumer-out-0", + "consumer-out-1", + "consumer-out-2" + ], + "keySerializer": "some.key.serailizer", + "valueSerializer": "some.value.serailizer", + "keyDeserializer": "some.key.deserailizer", + "valueDeserializer": "some.value.deserailizer" + } + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + }, + "eventInputParameters": { + "MySuperDooperConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + } + } +} diff --git a/services/services-engine/src/test/resources/parameters/syncBadParamsBadPeers.json b/services/services-engine/src/test/resources/parameters/syncBadParamsBadPeers.json new file mode 100644 index 000000000..6393d4864 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/syncBadParamsBadPeers.json @@ -0,0 +1,72 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "SyncProducer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncProducer1" + }, + "SyncProducer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncProducer0" + } + }, + "eventInputParameters": { + "SyncConsumer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncConsumer1" + }, + "SyncConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + }, + "synchronousMode": true, + "synchronousPeer": "SyncConsumer0" + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/syncBadParamsBadTimeout.json b/services/services-engine/src/test/resources/parameters/syncBadParamsBadTimeout.json new file mode 100644 index 000000000..a6de63f30 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/syncBadParamsBadTimeout.json @@ -0,0 +1,65 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "FirstProducer": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + }, + "MyOtherProducer": { + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "synchronousTimeout": 12345 + } + }, + "eventInputParameters": { + "TheFileConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + } + }, + "MySuperDooperConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + } + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/syncBadParamsInvalidTimeout.json b/services/services-engine/src/test/resources/parameters/syncBadParamsInvalidTimeout.json new file mode 100644 index 000000000..ac24c8231 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/syncBadParamsInvalidTimeout.json @@ -0,0 +1,76 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "SyncProducer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousTimeout": -10, + "synchronousPeer": "SyncConsumer0" + }, + "SyncProducer1": { + "synchronousMode": true, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousTimeout": -3, + "synchronousPeer": "SyncConsumer1" + } + }, + "eventInputParameters": { + "SyncConsumer0": { + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncProducer0", + "synchronousTimeout": -1, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + } + }, + "SyncConsumer1": { + "synchronousPeer": "SyncProducer1", + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + }, + "synchronousMode": true, + "synchronousTimeout": -99999999 + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/syncBadParamsNoSyncWithPeer.json b/services/services-engine/src/test/resources/parameters/syncBadParamsNoSyncWithPeer.json new file mode 100644 index 000000000..98840912f --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/syncBadParamsNoSyncWithPeer.json @@ -0,0 +1,71 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "SyncProducer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousPeer": "SyncConsumer0" + }, + "SyncProducer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncConsumer1" + } + }, + "eventInputParameters": { + "SyncConsumer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncProducer0" + }, + "SyncConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + }, + "synchronousMode": true, + "synchronousPeer": "SyncProducer1" + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/syncBadParamsNotSyncWithPeer.json b/services/services-engine/src/test/resources/parameters/syncBadParamsNotSyncWithPeer.json new file mode 100644 index 000000000..477bf8639 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/syncBadParamsNotSyncWithPeer.json @@ -0,0 +1,72 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "SyncProducer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": false, + "synchronousPeer": "SyncConsumer0" + }, + "SyncProducer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncConsumer1" + } + }, + "eventInputParameters": { + "SyncConsumer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncProducer0" + }, + "SyncConsumer1": { + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + }, + "synchronousMode": true, + "synchronousPeer": "SyncProducer1" + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/syncBadParamsUnpairedTimeout.json b/services/services-engine/src/test/resources/parameters/syncBadParamsUnpairedTimeout.json new file mode 100644 index 000000000..93c998b29 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/syncBadParamsUnpairedTimeout.json @@ -0,0 +1,76 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "SyncProducer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousTimeout": 10, + "synchronousPeer": "SyncConsumer0" + }, + "SyncProducer1": { + "synchronousMode": true, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousTimeout": 3, + "synchronousPeer": "SyncConsumer1" + } + }, + "eventInputParameters": { + "SyncConsumer0": { + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncProducer0", + "synchronousTimeout": 1, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + } + }, + "SyncConsumer1": { + "synchronousPeer": "SyncProducer1", + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + }, + "synchronousMode": true, + "synchronousTimeout": 99999999 + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/syncGoodParams.json b/services/services-engine/src/test/resources/parameters/syncGoodParams.json new file mode 100644 index 000000000..b2980aaed --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/syncGoodParams.json @@ -0,0 +1,72 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "SyncProducer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncConsumer0" + }, + "SyncProducer1": { + "synchronousMode": true, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousPeer": "SyncConsumer1" + } + }, + "eventInputParameters": { + "SyncConsumer0": { + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncProducer0", + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + } + }, + "SyncConsumer1": { + "synchronousPeer": "SyncProducer1", + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + }, + "synchronousMode": true + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/syncGoodParamsBothTimeout.json b/services/services-engine/src/test/resources/parameters/syncGoodParamsBothTimeout.json new file mode 100644 index 000000000..68626958d --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/syncGoodParamsBothTimeout.json @@ -0,0 +1,76 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "SyncProducer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "synchronousTimeout": 12345, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncConsumer0" + }, + "SyncProducer1": { + "synchronousTimeout": 1, + "synchronousMode": true, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousPeer": "SyncConsumer1" + } + }, + "eventInputParameters": { + "SyncConsumer0": { + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousTimeout": 12345, + "synchronousMode": true, + "synchronousPeer": "SyncProducer0", + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + } + }, + "SyncConsumer1": { + "synchronousPeer": "SyncProducer1", + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "synchronousTimeout": 1, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + }, + "synchronousMode": true + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/syncGoodParamsConsumerTimeout.json b/services/services-engine/src/test/resources/parameters/syncGoodParamsConsumerTimeout.json new file mode 100644 index 000000000..d849040ac --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/syncGoodParamsConsumerTimeout.json @@ -0,0 +1,74 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "SyncProducer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncConsumer0" + }, + "SyncProducer1": { + "synchronousMode": true, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousPeer": "SyncConsumer1" + } + }, + "eventInputParameters": { + "SyncConsumer0": { + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousTimeout": 12345, + "synchronousMode": true, + "synchronousPeer": "SyncProducer0", + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + } + }, + "SyncConsumer1": { + "synchronousPeer": "SyncProducer1", + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "synchronousTimeout": 1, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + }, + "synchronousMode": true + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/syncGoodParamsProducerTimeout.json b/services/services-engine/src/test/resources/parameters/syncGoodParamsProducerTimeout.json new file mode 100644 index 000000000..b248259a4 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/syncGoodParamsProducerTimeout.json @@ -0,0 +1,74 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "SyncProducer0": { + "synchronousTimeout": 12345, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncConsumer0" + }, + "SyncProducer1": { + "synchronousMode": true, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousPeer": "SyncConsumer1", + "synchronousTimeout": 1 + } + }, + "eventInputParameters": { + "SyncConsumer0": { + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncProducer0", + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + } + }, + "SyncConsumer1": { + "synchronousPeer": "SyncProducer1", + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + }, + "synchronousMode": true + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/syncMismatchedPeers.json b/services/services-engine/src/test/resources/parameters/syncMismatchedPeers.json new file mode 100644 index 000000000..9e5399d4f --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/syncMismatchedPeers.json @@ -0,0 +1,72 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "SyncProducer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncConsumer1" + }, + "SyncProducer1": { + "synchronousMode": true, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousPeer": "SyncConsumer0" + } + }, + "eventInputParameters": { + "SyncConsumer0": { + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncProducer0", + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + } + }, + "SyncConsumer1": { + "synchronousPeer": "SyncProducer1", + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + }, + "synchronousMode": true + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/syncUnusedConsumerPeers.json b/services/services-engine/src/test/resources/parameters/syncUnusedConsumerPeers.json new file mode 100644 index 000000000..71337f340 --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/syncUnusedConsumerPeers.json @@ -0,0 +1,72 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "SyncProducer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncConsumer0" + }, + "SyncProducer1": { + "synchronousMode": true, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousPeer": "SyncConsumer0" + } + }, + "eventInputParameters": { + "SyncConsumer0": { + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncProducer0", + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + } + }, + "SyncConsumer1": { + "synchronousPeer": "SyncProducer1", + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + }, + "synchronousMode": true + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/parameters/syncUnusedProducerPeers.json b/services/services-engine/src/test/resources/parameters/syncUnusedProducerPeers.json new file mode 100644 index 000000000..4fe58bacc --- /dev/null +++ b/services/services-engine/src/test/resources/parameters/syncUnusedProducerPeers.json @@ -0,0 +1,72 @@ +{ + "engineServiceParameters": { + "name": "MyApexEngine", + "version": "0.0.1", + "id": 45, + "instanceCount": 19, + "deploymentPort": 65522, + "policyModelFileName": "src/test/resources/policymodels/SamplePolicyModelMVEL.json", + "engineParameters": { + "executorParameters": { + "MVEL": { + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperExecutorParameters" + } + } + } + }, + "eventOutputParameters": { + "SyncProducer0": { + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncConsumer0" + }, + "SyncProducer1": { + "synchronousMode": true, + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/aaa.json" + } + }, + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousPeer": "SyncConsumer1" + } + }, + "eventInputParameters": { + "SyncConsumer0": { + "eventProtocolParameters": { + "eventProtocol": "JSON" + }, + "synchronousMode": true, + "synchronousPeer": "SyncProducer1", + "carrierTechnologyParameters": { + "carrierTechnology": "FILE", + "parameters": { + "fileName": "/tmp/bbb.json" + } + } + }, + "SyncConsumer1": { + "synchronousPeer": "SyncProducer1", + "carrierTechnologyParameters": { + "carrierTechnology": "SUPER_DOOPER", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperDooperCarrierTechnologyParameters" + }, + "eventProtocolParameters": { + "eventProtocol": "SUPER_TOK_DEL", + "parameterClassName": "org.onap.policy.apex.service.engine.parameters.dummyclasses.SuperTokenDelimitedEventProtocolParameters" + }, + "synchronousMode": true + } + } +}
\ No newline at end of file diff --git a/services/services-engine/src/test/resources/policymodels/SamplePolicyModelMVEL.json b/services/services-engine/src/test/resources/policymodels/SamplePolicyModelMVEL.json new file mode 100644 index 000000000..95ea511b1 --- /dev/null +++ b/services/services-engine/src/test/resources/policymodels/SamplePolicyModelMVEL.json @@ -0,0 +1,7372 @@ +{ + "apexPolicyModel": { + "key": { + "name": "SamplePolicyModelMVEL", + "version": "0.0.1" + }, + "keyInformation": { + "key": { + "name": "KeyInformation", + "version": "0.0.1" + }, + "keyInfoMap": { + "entry": [ + { + "key": { + "name": "Context", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Context", + "version": "0.0.1" + }, + "UUID": "ca36bfd8-6042-3633-8c85-89c66507c3bf", + "description": "Generated description for concept referred to by key \"Context:0.0.1\"" + } + }, + { + "key": { + "name": "Event0000", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0000", + "version": "0.0.1" + }, + "UUID": "465a81cc-885f-3a4d-bc4e-1508da92b236", + "description": "Generated description for concept referred to by key \"Event0000:0.0.1\"" + } + }, + { + "key": { + "name": "Event0001", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0001", + "version": "0.0.1" + }, + "UUID": "36b2d570-fff7-3a4b-bab2-6bf492f5129a", + "description": "Generated description for concept referred to by key \"Event0001:0.0.1\"" + } + }, + { + "key": { + "name": "Event0002", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0002", + "version": "0.0.1" + }, + "UUID": "ff6160a7-fb5e-379c-a6d2-2cd28053eacf", + "description": "Generated description for concept referred to by key \"Event0002:0.0.1\"" + } + }, + { + "key": { + "name": "Event0003", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0003", + "version": "0.0.1" + }, + "UUID": "5899e216-2abf-3781-abc4-2c257b92721e", + "description": "Generated description for concept referred to by key \"Event0003:0.0.1\"" + } + }, + { + "key": { + "name": "Event0004", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0004", + "version": "0.0.1" + }, + "UUID": "7c2692a7-4587-3d09-abf9-d96b339a316f", + "description": "Generated description for concept referred to by key \"Event0004:0.0.1\"" + } + }, + { + "key": { + "name": "Event0100", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0100", + "version": "0.0.1" + }, + "UUID": "b696048c-c0b0-34c1-8dbe-32ab6c8bc0c7", + "description": "Generated description for concept referred to by key \"Event0100:0.0.1\"" + } + }, + { + "key": { + "name": "Event0101", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0101", + "version": "0.0.1" + }, + "UUID": "edbfa868-2ab2-30fd-8078-4c7f67ca6122", + "description": "Generated description for concept referred to by key \"Event0101:0.0.1\"" + } + }, + { + "key": { + "name": "Event0102", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0102", + "version": "0.0.1" + }, + "UUID": "6b6ad2ff-ef63-3f7b-aabb-fba44f8de9d4", + "description": "Generated description for concept referred to by key \"Event0102:0.0.1\"" + } + }, + { + "key": { + "name": "Event0103", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0103", + "version": "0.0.1" + }, + "UUID": "c2550912-10d9-3000-8826-377288cd6cb1", + "description": "Generated description for concept referred to by key \"Event0103:0.0.1\"" + } + }, + { + "key": { + "name": "Event0104", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0104", + "version": "0.0.1" + }, + "UUID": "f6d75b71-c8a7-3337-a121-88d68c389f5a", + "description": "Generated description for concept referred to by key \"Event0104:0.0.1\"" + } + }, + { + "key": { + "name": "Events", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Events", + "version": "0.0.1" + }, + "UUID": "0215644c-4531-375c-8335-d558b4de8c03", + "description": "Generated description for concept referred to by key \"Events:0.0.1\"" + } + }, + { + "key": { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + "UUID": "976a79e7-5c80-3c03-9503-da3f41fec395", + "description": "Generated description for concept referred to by key \"ExternalContextAlbum:0.0.1\"" + } + }, + { + "key": { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + "UUID": "c95e9e5f-d2c7-3ac7-a205-ea3574530cb7", + "description": "Generated description for concept referred to by key \"GlobalContextAlbum:0.0.1\"" + } + }, + { + "key": { + "name": "KeyInformation", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "KeyInformation", + "version": "0.0.1" + }, + "UUID": "1ff2f905-685c-3caf-95bc-0bbc90345888", + "description": "Generated description for concept referred to by key \"KeyInformation:0.0.1\"" + } + }, + { + "key": { + "name": "Policies", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Policies", + "version": "0.0.1" + }, + "UUID": "f54c3b2b-be76-31c4-adfc-87c494c06808", + "description": "Generated description for concept referred to by key \"Policies:0.0.1\"" + } + }, + { + "key": { + "name": "Policy0", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Policy0", + "version": "0.0.1" + }, + "UUID": "3410e939-30ca-32c4-a2d8-c30b6fee6eec", + "description": "Generated description for concept referred to by key \"Policy0:0.0.1\"" + } + }, + { + "key": { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + }, + "UUID": "e27564c4-3cbf-3db2-9bf3-83ae80a2f907", + "description": "Generated description for concept referred to by key \"Policy0ContextAlbum:0.0.1\"" + } + }, + { + "key": { + "name": "Policy1", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Policy1", + "version": "0.0.1" + }, + "UUID": "d0b2b585-f344-33b8-af9e-250e7f4cfbce", + "description": "Generated description for concept referred to by key \"Policy1:0.0.1\"" + } + }, + { + "key": { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + }, + "UUID": "815d74ae-6fc0-3221-87b9-2bb1dfdfa7f0", + "description": "Generated description for concept referred to by key \"Policy1ContextAlbum:0.0.1\"" + } + }, + { + "key": { + "name": "SamplePolicyModelMVEL", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "SamplePolicyModelMVEL", + "version": "0.0.1" + }, + "UUID": "a4cc4860-0bbc-389c-b270-e1bf7daffbe2", + "description": "Generated description for concept referred to by key \"SamplePolicyModelMVEL:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Act0", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Act0", + "version": "0.0.1" + }, + "UUID": "0589ff20-adcc-3ce5-95fe-8d7978ed54ed", + "description": "Generated description for concept referred to by key \"Task_Act0:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Act1", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Act1", + "version": "0.0.1" + }, + "UUID": "095b126d-ca8b-32c9-ad52-d744e817a79c", + "description": "Generated description for concept referred to by key \"Task_Act1:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Act2", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Act2", + "version": "0.0.1" + }, + "UUID": "3d786b4c-d9ee-3367-ab71-c67271a4ea2f", + "description": "Generated description for concept referred to by key \"Task_Act2:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Act3", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Act3", + "version": "0.0.1" + }, + "UUID": "9231753e-20c5-3436-982f-9100340cc570", + "description": "Generated description for concept referred to by key \"Task_Act3:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Decide0", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Decide0", + "version": "0.0.1" + }, + "UUID": "502383d3-483f-3a56-a426-2f0406674c8d", + "description": "Generated description for concept referred to by key \"Task_Decide0:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Decide1", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Decide1", + "version": "0.0.1" + }, + "UUID": "16598106-41c8-3b5a-99c6-5fcf6d1a5ddf", + "description": "Generated description for concept referred to by key \"Task_Decide1:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Decide2", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Decide2", + "version": "0.0.1" + }, + "UUID": "ad3a89f5-e369-3c66-b22c-669f7b3653b8", + "description": "Generated description for concept referred to by key \"Task_Decide2:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Decide3", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Decide3", + "version": "0.0.1" + }, + "UUID": "56815939-1164-3867-9ed1-0a27ff8aafb3", + "description": "Generated description for concept referred to by key \"Task_Decide3:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Establish0", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Establish0", + "version": "0.0.1" + }, + "UUID": "0db0c566-ecd7-3e27-9865-4b82c893abdb", + "description": "Generated description for concept referred to by key \"Task_Establish0:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Establish1", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Establish1", + "version": "0.0.1" + }, + "UUID": "6944a4c1-6201-317c-8d7e-eaa7f2ee0ea0", + "description": "Generated description for concept referred to by key \"Task_Establish1:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Establish2", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Establish2", + "version": "0.0.1" + }, + "UUID": "0f766ea9-11cd-3e7d-a8c8-28c8dee6a85a", + "description": "Generated description for concept referred to by key \"Task_Establish2:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Establish3", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Establish3", + "version": "0.0.1" + }, + "UUID": "c3237a38-cc6d-3418-b1e1-0dc8b4bdcc66", + "description": "Generated description for concept referred to by key \"Task_Establish3:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Match0", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Match0", + "version": "0.0.1" + }, + "UUID": "051bcfd5-cf73-3c89-8ee7-ea6e005ec059", + "description": "Generated description for concept referred to by key \"Task_Match0:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Match1", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Match1", + "version": "0.0.1" + }, + "UUID": "3754fe19-98f2-34a1-9f45-db31052208d8", + "description": "Generated description for concept referred to by key \"Task_Match1:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Match2", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Match2", + "version": "0.0.1" + }, + "UUID": "8c200709-a180-3c8b-916f-275ff49ce194", + "description": "Generated description for concept referred to by key \"Task_Match2:0.0.1\"" + } + }, + { + "key": { + "name": "Task_Match3", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Match3", + "version": "0.0.1" + }, + "UUID": "a1a879c6-4510-33b0-bbd0-ad6256189a37", + "description": "Generated description for concept referred to by key \"Task_Match3:0.0.1\"" + } + }, + { + "key": { + "name": "Tasks", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Tasks", + "version": "0.0.1" + }, + "UUID": "a7fab96b-ce1c-37ce-bbb2-556b6db524a5", + "description": "Generated description for concept referred to by key \"Tasks:0.0.1\"" + } + }, + { + "key": { + "name": "TestCase", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestCase", + "version": "0.0.1" + }, + "UUID": "0a652886-c88d-3f8c-8994-ae9161e7c963", + "description": "Generated description for concept referred to by key \"TestCase:0.0.1\"" + } + }, + { + "key": { + "name": "TestContextItem000", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem000", + "version": "0.0.1" + }, + "UUID": "8efba9fa-371e-33df-a7d6-88b0284e7fd0", + "description": "Generated description for concept referred to by key \"TestContextItem000:0.0.1\"" + } + }, + { + "key": { + "name": "TestContextItem001", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem001", + "version": "0.0.1" + }, + "UUID": "3740077c-a2b3-356b-81dc-5ded2118a951", + "description": "Generated description for concept referred to by key \"TestContextItem001:0.0.1\"" + } + }, + { + "key": { + "name": "TestContextItem002", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem002", + "version": "0.0.1" + }, + "UUID": "b5c7df95-9af5-322f-9ea8-eb440a2bf926", + "description": "Generated description for concept referred to by key \"TestContextItem002:0.0.1\"" + } + }, + { + "key": { + "name": "TestContextItem003", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem003", + "version": "0.0.1" + }, + "UUID": "b36f0aa5-0fb9-3e2c-8fa2-fddb7fd05f4b", + "description": "Generated description for concept referred to by key \"TestContextItem003:0.0.1\"" + } + }, + { + "key": { + "name": "TestContextItem004", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem004", + "version": "0.0.1" + }, + "UUID": "093cda11-eaeb-3a46-a5b6-d5e30c00935b", + "description": "Generated description for concept referred to by key \"TestContextItem004:0.0.1\"" + } + }, + { + "key": { + "name": "TestContextItem005", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem005", + "version": "0.0.1" + }, + "UUID": "569a758d-ba40-37c0-aebb-7ad138df25ac", + "description": "Generated description for concept referred to by key \"TestContextItem005:0.0.1\"" + } + }, + { + "key": { + "name": "TestContextItem006", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem006", + "version": "0.0.1" + }, + "UUID": "252818d9-b61f-3962-a905-8865fb00fb04", + "description": "Generated description for concept referred to by key \"TestContextItem006:0.0.1\"" + } + }, + { + "key": { + "name": "TestContextItem007", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem007", + "version": "0.0.1" + }, + "UUID": "fe1a5f7c-c083-377b-a797-752b01fc6c73", + "description": "Generated description for concept referred to by key \"TestContextItem007:0.0.1\"" + } + }, + { + "key": { + "name": "TestContextItem008", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem008", + "version": "0.0.1" + }, + "UUID": "aa87d007-d07e-3f67-8c6d-0ebc3d85479d", + "description": "Generated description for concept referred to by key \"TestContextItem008:0.0.1\"" + } + }, + { + "key": { + "name": "TestContextItem009", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem009", + "version": "0.0.1" + }, + "UUID": "126e7a3a-11b6-3f88-9397-c21d8819f859", + "description": "Generated description for concept referred to by key \"TestContextItem009:0.0.1\"" + } + }, + { + "key": { + "name": "TestContextItem00A", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem00A", + "version": "0.0.1" + }, + "UUID": "0e0e3dec-e03d-3379-a87b-1ecd4aa3d8cc", + "description": "Generated description for concept referred to by key \"TestContextItem00A:0.0.1\"" + } + }, + { + "key": { + "name": "TestContextItem00B", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem00B", + "version": "0.0.1" + }, + "UUID": "dbdc98df-3ff4-360c-b8d3-a7a836ac3de6", + "description": "Generated description for concept referred to by key \"TestContextItem00B:0.0.1\"" + } + }, + { + "key": { + "name": "TestContextItem00C", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem00C", + "version": "0.0.1" + }, + "UUID": "32a2f355-77f3-3b25-ace6-7a9c5763a5ad", + "description": "Generated description for concept referred to by key \"TestContextItem00C:0.0.1\"" + } + }, + { + "key": { + "name": "TestDatatypes", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestDatatypes", + "version": "0.0.1" + }, + "UUID": "3f95472c-973e-30e2-95f1-bf00cbef909a", + "description": "Generated description for concept referred to by key \"TestDatatypes:0.0.1\"" + } + }, + { + "key": { + "name": "TestExternalContextItem", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestExternalContextItem", + "version": "0.0.1" + }, + "UUID": "610dbbd4-9149-3b3c-9af4-819056f0e169", + "description": "Generated description for concept referred to by key \"TestExternalContextItem:0.0.1\"" + } + }, + { + "key": { + "name": "TestGlobalContextItem", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestGlobalContextItem", + "version": "0.0.1" + }, + "UUID": "07fa8f68-55f1-3fd0-81c1-749a379753a7", + "description": "Generated description for concept referred to by key \"TestGlobalContextItem:0.0.1\"" + } + }, + { + "key": { + "name": "TestPolicyContextItem", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestPolicyContextItem", + "version": "0.0.1" + }, + "UUID": "d9c93cd1-539e-35c5-aaec-bb711ceb1251", + "description": "Generated description for concept referred to by key \"TestPolicyContextItem:0.0.1\"" + } + }, + { + "key": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "UUID": "683fe492-7eae-3ac7-9924-bb7850208d05", + "description": "Generated description for concept referred to by key \"TestSlogan:0.0.1\"" + } + }, + { + "key": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "UUID": "bba25b6f-e3cd-3060-9022-4ef3a79f8eb0", + "description": "Generated description for concept referred to by key \"TestTemperature:0.0.1\"" + } + }, + { + "key": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "UUID": "97b73937-c344-33c0-924c-4d26b6449564", + "description": "Generated description for concept referred to by key \"TestTimestamp:0.0.1\"" + } + } + ] + } + }, + "policies": { + "key": { + "name": "Policies", + "version": "0.0.1" + }, + "policyMap": { + "entry": [ + { + "key": { + "name": "Policy0", + "version": "0.0.1" + }, + "value": { + "policyKey": { + "name": "Policy0", + "version": "0.0.1" + }, + "template": "MEDA", + "state": { + "entry": [ + { + "key": "Act", + "value": { + "stateKey": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Act" + }, + "trigger": { + "name": "Event0003", + "version": "0.0.1" + }, + "stateOutputs": { + "entry": [ + { + "key": "Act_NULL", + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Act_NULL" + }, + "outgoingEvent": { + "name": "Event0004", + "version": "0.0.1" + }, + "nextState": { + "parentKeyName": "NULL", + "parentKeyVersion": "0.0.0", + "parentLocalName": "NULL", + "localName": "NULL" + } + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + } + ], + "taskSelectionLogic": { + "key": "TaskSelectionLigic", + "logicFlavour": "MVEL", + "logic": "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;" + }, + "stateFinalizerLogicMap": { + "entry": [] + }, + "defaultTask": { + "name": "Task_Act1", + "version": "0.0.1" + }, + "taskReferences": { + "entry": [ + { + "key": { + "name": "Task_Act0", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Task_Act0_DIRECT_Act_NULL" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Act_NULL" + } + } + }, + { + "key": { + "name": "Task_Act1", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Task_Act1_DIRECT_Act_NULL" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Act_NULL" + } + } + }, + { + "key": { + "name": "Task_Act2", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Task_Act2_DIRECT_Act_NULL" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Act_NULL" + } + } + }, + { + "key": { + "name": "Task_Act3", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Task_Act3_DIRECT_Act_NULL" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Act_NULL" + } + } + } + ] + } + } + }, + { + "key": "Decide", + "value": { + "stateKey": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Decide" + }, + "trigger": { + "name": "Event0002", + "version": "0.0.1" + }, + "stateOutputs": { + "entry": [ + { + "key": "Decide_Act", + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Decide_Act" + }, + "outgoingEvent": { + "name": "Event0003", + "version": "0.0.1" + }, + "nextState": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Act" + } + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + } + ], + "taskSelectionLogic": { + "key": "TaskSelectionLigic", + "logicFlavour": "MVEL", + "logic": "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;" + }, + "stateFinalizerLogicMap": { + "entry": [] + }, + "defaultTask": { + "name": "Task_Decide3", + "version": "0.0.1" + }, + "taskReferences": { + "entry": [ + { + "key": { + "name": "Task_Decide0", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Task_Decide0_DIRECT_Decide_Act" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Decide_Act" + } + } + }, + { + "key": { + "name": "Task_Decide1", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Task_Decide1_DIRECT_Decide_Act" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Decide_Act" + } + } + }, + { + "key": { + "name": "Task_Decide2", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Task_Decide2_DIRECT_Decide_Act" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Decide_Act" + } + } + }, + { + "key": { + "name": "Task_Decide3", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Task_Decide3_DIRECT_Decide_Act" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Decide_Act" + } + } + } + ] + } + } + }, + { + "key": "Establish", + "value": { + "stateKey": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Establish" + }, + "trigger": { + "name": "Event0001", + "version": "0.0.1" + }, + "stateOutputs": { + "entry": [ + { + "key": "Establish_Decide", + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Establish_Decide" + }, + "outgoingEvent": { + "name": "Event0002", + "version": "0.0.1" + }, + "nextState": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Decide" + } + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + } + ], + "taskSelectionLogic": { + "key": "TaskSelectionLigic", + "logicFlavour": "MVEL", + "logic": "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;" + }, + "stateFinalizerLogicMap": { + "entry": [] + }, + "defaultTask": { + "name": "Task_Establish2", + "version": "0.0.1" + }, + "taskReferences": { + "entry": [ + { + "key": { + "name": "Task_Establish0", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Task_Establish0_DIRECT_Establish_Decide" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Establish_Decide" + } + } + }, + { + "key": { + "name": "Task_Establish1", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Task_Establish1_DIRECT_Establish_Decide" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Establish_Decide" + } + } + }, + { + "key": { + "name": "Task_Establish2", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Task_Establish2_DIRECT_Establish_Decide" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Establish_Decide" + } + } + }, + { + "key": { + "name": "Task_Establish3", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Task_Establish3_DIRECT_Establish_Decide" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Establish_Decide" + } + } + } + ] + } + } + }, + { + "key": "Match", + "value": { + "stateKey": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Match" + }, + "trigger": { + "name": "Event0000", + "version": "0.0.1" + }, + "stateOutputs": { + "entry": [ + { + "key": "Match_Establish", + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Match_Establish" + }, + "outgoingEvent": { + "name": "Event0001", + "version": "0.0.1" + }, + "nextState": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Establish" + } + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + } + ], + "taskSelectionLogic": { + "key": "TaskSelectionLigic", + "logicFlavour": "MVEL", + "logic": "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;" + }, + "stateFinalizerLogicMap": { + "entry": [] + }, + "defaultTask": { + "name": "Task_Match0", + "version": "0.0.1" + }, + "taskReferences": { + "entry": [ + { + "key": { + "name": "Task_Match0", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Task_Match0_DIRECT_Match_Establish" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Match_Establish" + } + } + }, + { + "key": { + "name": "Task_Match1", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Task_Match1_DIRECT_Match_Establish" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Match_Establish" + } + } + }, + { + "key": { + "name": "Task_Match2", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Task_Match2_DIRECT_Match_Establish" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Match_Establish" + } + } + }, + { + "key": { + "name": "Task_Match3", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Task_Match3_DIRECT_Match_Establish" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Match_Establish" + } + } + } + ] + } + } + } + ] + }, + "firstState": "Match" + } + }, + { + "key": { + "name": "Policy1", + "version": "0.0.1" + }, + "value": { + "policyKey": { + "name": "Policy1", + "version": "0.0.1" + }, + "template": "MEDA", + "state": { + "entry": [ + { + "key": "Act", + "value": { + "stateKey": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Act" + }, + "trigger": { + "name": "Event0103", + "version": "0.0.1" + }, + "stateOutputs": { + "entry": [ + { + "key": "Act_NULL", + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Act_NULL" + }, + "outgoingEvent": { + "name": "Event0104", + "version": "0.0.1" + }, + "nextState": { + "parentKeyName": "NULL", + "parentKeyVersion": "0.0.0", + "parentLocalName": "NULL", + "localName": "NULL" + } + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + } + ], + "taskSelectionLogic": { + "key": "TaskSelectionLigic", + "logicFlavour": "MVEL", + "logic": "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;" + }, + "stateFinalizerLogicMap": { + "entry": [] + }, + "defaultTask": { + "name": "Task_Act0", + "version": "0.0.1" + }, + "taskReferences": { + "entry": [ + { + "key": { + "name": "Task_Act0", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Task_Act0_DIRECT_Act_NULL" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Act_NULL" + } + } + }, + { + "key": { + "name": "Task_Act1", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Task_Act1_DIRECT_Act_NULL" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Act_NULL" + } + } + }, + { + "key": { + "name": "Task_Act2", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Task_Act2_DIRECT_Act_NULL" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Act_NULL" + } + } + }, + { + "key": { + "name": "Task_Act3", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Task_Act3_DIRECT_Act_NULL" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Act", + "localName": "Act_NULL" + } + } + } + ] + } + } + }, + { + "key": "Decide", + "value": { + "stateKey": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Decide" + }, + "trigger": { + "name": "Event0102", + "version": "0.0.1" + }, + "stateOutputs": { + "entry": [ + { + "key": "Decide_Act", + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Decide_Act" + }, + "outgoingEvent": { + "name": "Event0103", + "version": "0.0.1" + }, + "nextState": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Act" + } + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + } + ], + "taskSelectionLogic": { + "key": "TaskSelectionLigic", + "logicFlavour": "MVEL", + "logic": "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;" + }, + "stateFinalizerLogicMap": { + "entry": [] + }, + "defaultTask": { + "name": "Task_Decide3", + "version": "0.0.1" + }, + "taskReferences": { + "entry": [ + { + "key": { + "name": "Task_Decide0", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Task_Decide0_DIRECT_Decide_Act" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Decide_Act" + } + } + }, + { + "key": { + "name": "Task_Decide1", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Task_Decide1_DIRECT_Decide_Act" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Decide_Act" + } + } + }, + { + "key": { + "name": "Task_Decide2", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Task_Decide2_DIRECT_Decide_Act" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Decide_Act" + } + } + }, + { + "key": { + "name": "Task_Decide3", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Task_Decide3_DIRECT_Decide_Act" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Decide", + "localName": "Decide_Act" + } + } + } + ] + } + } + }, + { + "key": "Establish", + "value": { + "stateKey": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Establish" + }, + "trigger": { + "name": "Event0101", + "version": "0.0.1" + }, + "stateOutputs": { + "entry": [ + { + "key": "Establish_Decide", + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Establish_Decide" + }, + "outgoingEvent": { + "name": "Event0102", + "version": "0.0.1" + }, + "nextState": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Decide" + } + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + } + ], + "taskSelectionLogic": { + "key": "TaskSelectionLigic", + "logicFlavour": "MVEL", + "logic": "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;" + }, + "stateFinalizerLogicMap": { + "entry": [] + }, + "defaultTask": { + "name": "Task_Establish1", + "version": "0.0.1" + }, + "taskReferences": { + "entry": [ + { + "key": { + "name": "Task_Establish0", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Task_Establish0_DIRECT_Establish_Decide" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Establish_Decide" + } + } + }, + { + "key": { + "name": "Task_Establish1", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Task_Establish1_DIRECT_Establish_Decide" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Establish_Decide" + } + } + }, + { + "key": { + "name": "Task_Establish2", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Task_Establish2_DIRECT_Establish_Decide" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Establish_Decide" + } + } + }, + { + "key": { + "name": "Task_Establish3", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Task_Establish3_DIRECT_Establish_Decide" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Establish", + "localName": "Establish_Decide" + } + } + } + ] + } + } + }, + { + "key": "Match", + "value": { + "stateKey": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Match" + }, + "trigger": { + "name": "Event0100", + "version": "0.0.1" + }, + "stateOutputs": { + "entry": [ + { + "key": "Match_Establish", + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Match_Establish" + }, + "outgoingEvent": { + "name": "Event0101", + "version": "0.0.1" + }, + "nextState": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Establish" + } + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + } + ], + "taskSelectionLogic": { + "key": "TaskSelectionLigic", + "logicFlavour": "MVEL", + "logic": "logger.debug(subject.id + \":\" + subject.stateName);\nsubject.defaultTaskKey.copyTo(selectedTask);\nreturn true;" + }, + "stateFinalizerLogicMap": { + "entry": [] + }, + "defaultTask": { + "name": "Task_Match3", + "version": "0.0.1" + }, + "taskReferences": { + "entry": [ + { + "key": { + "name": "Task_Match0", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Task_Match0_DIRECT_Match_Establish" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Match_Establish" + } + } + }, + { + "key": { + "name": "Task_Match1", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Task_Match1_DIRECT_Match_Establish" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Match_Establish" + } + } + }, + { + "key": { + "name": "Task_Match2", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Task_Match2_DIRECT_Match_Establish" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Match_Establish" + } + } + }, + { + "key": { + "name": "Task_Match3", + "version": "0.0.1" + }, + "value": { + "key": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Task_Match3_DIRECT_Match_Establish" + }, + "outputType": "DIRECT", + "output": { + "parentKeyName": "Policy1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "Match", + "localName": "Match_Establish" + } + } + } + ] + } + } + } + ] + }, + "firstState": "Match" + } + } + ] + } + }, + "tasks": { + "key": { + "name": "Tasks", + "version": "0.0.1" + }, + "taskMap": { + "entry": [ + { + "key": { + "name": "Task_Act0", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Act0", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestActCaseSelected", + "value": { + "key": "TestActCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestActStateTime", + "value": { + "key": "TestActStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Act0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + }, + { + "key": "Parameter1", + "value": { + "key": { + "parentKeyName": "Task_Act0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter1" + }, + "defaultValue": "DefaultValue1" + } + }, + { + "key": "Parameter2", + "value": { + "key": { + "parentKeyName": "Task_Act0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter2" + }, + "defaultValue": "DefaultValue2" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestActCaseSelected\"] = (byte)2;\ntimeNow = new Date();\noutFields[\"TestActStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Act1", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Act1", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestActCaseSelected", + "value": { + "key": "TestActCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestActStateTime", + "value": { + "key": "TestActStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Act1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + }, + { + "key": "Parameter1", + "value": { + "key": { + "parentKeyName": "Task_Act1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter1" + }, + "defaultValue": "DefaultValue1" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestActCaseSelected\"] = (byte)3;\ntimeNow = new Date();\noutFields[\"TestActStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Act2", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Act2", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestActCaseSelected", + "value": { + "key": "TestActCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestActStateTime", + "value": { + "key": "TestActStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Act2", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestActCaseSelected\"] = (byte)0;\ntimeNow = new Date();\noutFields[\"TestActStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Act3", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Act3", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestActCaseSelected", + "value": { + "key": "TestActCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestActStateTime", + "value": { + "key": "TestActStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Act3", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestActCaseSelected\"] = (byte)1;\ntimeNow = new Date();\noutFields[\"TestActStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Decide0", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Decide0", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Decide0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + }, + { + "key": "Parameter1", + "value": { + "key": { + "parentKeyName": "Task_Decide0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter1" + }, + "defaultValue": "DefaultValue1" + } + }, + { + "key": "Parameter2", + "value": { + "key": { + "parentKeyName": "Task_Decide0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter2" + }, + "defaultValue": "DefaultValue2" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestDecideCaseSelected\"] = (byte)2;\ntimeNow = new Date();\noutFields[\"TestDecideStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Decide1", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Decide1", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Decide1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + }, + { + "key": "Parameter1", + "value": { + "key": { + "parentKeyName": "Task_Decide1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter1" + }, + "defaultValue": "DefaultValue1" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestDecideCaseSelected\"] = (byte)3;\ntimeNow = new Date();\noutFields[\"TestDecideStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Decide2", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Decide2", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Decide2", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestDecideCaseSelected\"] = (byte)0;\ntimeNow = new Date();\noutFields[\"TestDecideStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Decide3", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Decide3", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Decide3", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestDecideCaseSelected\"] = (byte)1;\ntimeNow = new Date();\noutFields[\"TestDecideStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Establish0", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Establish0", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Establish0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + }, + { + "key": "Parameter1", + "value": { + "key": { + "parentKeyName": "Task_Establish0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter1" + }, + "defaultValue": "DefaultValue1" + } + }, + { + "key": "Parameter2", + "value": { + "key": { + "parentKeyName": "Task_Establish0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter2" + }, + "defaultValue": "DefaultValue2" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestEstablishCaseSelected\"] = (byte)2;\ntimeNow = new Date();\noutFields[\"TestEstablishStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Establish1", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Establish1", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Establish1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + }, + { + "key": "Parameter1", + "value": { + "key": { + "parentKeyName": "Task_Establish1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter1" + }, + "defaultValue": "DefaultValue1" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestEstablishCaseSelected\"] = (byte)3;\ntimeNow = new Date();\noutFields[\"TestEstablishStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Establish2", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Establish2", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Establish2", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestEstablishCaseSelected\"] = (byte)0;\ntimeNow = new Date();\noutFields[\"TestEstablishStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Establish3", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Establish3", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Establish3", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestEstablishCaseSelected\"] = (byte)1;\ntimeNow = new Date();\noutFields[\"TestEstablishStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Match0", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Match0", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Match0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + }, + { + "key": "Parameter1", + "value": { + "key": { + "parentKeyName": "Task_Match0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter1" + }, + "defaultValue": "DefaultValue1" + } + }, + { + "key": "Parameter2", + "value": { + "key": { + "parentKeyName": "Task_Match0", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter2" + }, + "defaultValue": "DefaultValue2" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestMatchCaseSelected\"] = (byte)2;\ntimeNow = new Date();\noutFields[\"TestMatchStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Match1", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Match1", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Match1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + }, + { + "key": "Parameter1", + "value": { + "key": { + "parentKeyName": "Task_Match1", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter1" + }, + "defaultValue": "DefaultValue1" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestMatchCaseSelected\"] = (byte)3;\ntimeNow = new Date();\noutFields[\"TestMatchStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Match2", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Match2", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Match2", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestMatchCaseSelected\"] = (byte)0;\ntimeNow = new Date();\noutFields[\"TestMatchStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + }, + { + "key": { + "name": "Task_Match3", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Task_Match3", + "version": "0.0.1" + }, + "inputFields": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "outputFields": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + }, + "taskParameters": { + "entry": [ + { + "key": "Parameter0", + "value": { + "key": { + "parentKeyName": "Task_Match3", + "parentKeyVersion": "0.0.1", + "parentLocalName": "NULL", + "localName": "Parameter0" + }, + "defaultValue": "DefaultValue0" + } + } + ] + }, + "contextAlbumReference": [ + { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + { + "name": "GlobalContextAlbum", + "version": "0.0.1" + } + ], + "taskLogic": { + "key": "_TaskLogic", + "logicFlavour": "MVEL", + "logic": "import java.util.Date;\nlogger.debug(subject.id);\ngc = getContextAlbum(\"GlobalContextAlbum\");\nlogger.debug(gc);\nlogger.debug(inFields);\noutFields[\"TestMatchCaseSelected\"] = (byte)1;\ntimeNow = new Date();\noutFields[\"TestMatchStateTime\"] = timeNow.getTime();\nlogger.debug(outFields);\nreturn true;" + } + } + } + ] + } + }, + "events": { + "key": { + "name": "Events", + "version": "0.0.1" + }, + "eventMap": { + "entry": [ + { + "key": { + "name": "Event0000", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0000", + "version": "0.0.1" + }, + "nameSpace": "org.onap.policy.apex.sample.events", + "source": "Outside", + "target": "Match", + "parameter": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + } + } + }, + { + "key": { + "name": "Event0001", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0001", + "version": "0.0.1" + }, + "nameSpace": "org.onap.policy.apex.sample.events", + "source": "Match", + "target": "Establish", + "parameter": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + } + } + }, + { + "key": { + "name": "Event0002", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0002", + "version": "0.0.1" + }, + "nameSpace": "org.onap.policy.apex.sample.events", + "source": "Establish", + "target": "Decide", + "parameter": { + "entry": [ + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + } + } + }, + { + "key": { + "name": "Event0003", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0003", + "version": "0.0.1" + }, + "nameSpace": "org.onap.policy.apex.sample.events", + "source": "Decide", + "target": "Act", + "parameter": { + "entry": [ + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + } + } + }, + { + "key": { + "name": "Event0004", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0004", + "version": "0.0.1" + }, + "nameSpace": "org.onap.policy.apex.sample.events", + "source": "Act", + "target": "Outside", + "parameter": { + "entry": [ + { + "key": "TestActCaseSelected", + "value": { + "key": "TestActCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestActStateTime", + "value": { + "key": "TestActStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + } + } + }, + { + "key": { + "name": "Event0100", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0100", + "version": "0.0.1" + }, + "nameSpace": "org.onap.policy.apex.sample.events", + "source": "Outside", + "target": "Match", + "parameter": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + } + } + }, + { + "key": { + "name": "Event0101", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0101", + "version": "0.0.1" + }, + "nameSpace": "org.onap.policy.apex.sample.events", + "source": "Match", + "target": "Establish", + "parameter": { + "entry": [ + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + } + } + }, + { + "key": { + "name": "Event0102", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0102", + "version": "0.0.1" + }, + "nameSpace": "org.onap.policy.apex.sample.events", + "source": "Establish", + "target": "Decide", + "parameter": { + "entry": [ + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + } + } + }, + { + "key": { + "name": "Event0103", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0103", + "version": "0.0.1" + }, + "nameSpace": "org.onap.policy.apex.sample.events", + "source": "Decide", + "target": "Act", + "parameter": { + "entry": [ + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + } + } + }, + { + "key": { + "name": "Event0104", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Event0104", + "version": "0.0.1" + }, + "nameSpace": "org.onap.policy.apex.sample.events", + "source": "Act", + "target": "Outside", + "parameter": { + "entry": [ + { + "key": "TestActCaseSelected", + "value": { + "key": "TestActCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestActStateTime", + "value": { + "key": "TestActStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideCaseSelected", + "value": { + "key": "TestDecideCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestDecideStateTime", + "value": { + "key": "TestDecideStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishCaseSelected", + "value": { + "key": "TestEstablishCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestEstablishStateTime", + "value": { + "key": "TestEstablishStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCase", + "value": { + "key": "TestMatchCase", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchCaseSelected", + "value": { + "key": "TestMatchCaseSelected", + "fieldSchemaKey": { + "name": "TestCase", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestMatchStateTime", + "value": { + "key": "TestMatchStateTime", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestSlogan", + "value": { + "key": "TestSlogan", + "fieldSchemaKey": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTemperature", + "value": { + "key": "TestTemperature", + "fieldSchemaKey": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "optional": false + } + }, + { + "key": "TestTimestamp", + "value": { + "key": "TestTimestamp", + "fieldSchemaKey": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "optional": false + } + } + ] + } + } + } + ] + } + }, + "albums": { + "key": { + "name": "Context", + "version": "0.0.1" + }, + "albums": { + "entry": [ + { + "key": { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "ExternalContextAlbum", + "version": "0.0.1" + }, + "scope": "EXTERNAL", + "isWritable": false, + "itemSchema": { + "name": "TestExternalContextItem", + "version": "0.0.1" + } + } + }, + { + "key": { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "GlobalContextAlbum", + "version": "0.0.1" + }, + "scope": "GLOBAL", + "isWritable": true, + "itemSchema": { + "name": "TestGlobalContextItem", + "version": "0.0.1" + } + } + }, + { + "key": { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Policy0ContextAlbum", + "version": "0.0.1" + }, + "scope": "APPLICATION", + "isWritable": true, + "itemSchema": { + "name": "TestPolicyContextItem", + "version": "0.0.1" + } + } + }, + { + "key": { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "Policy1ContextAlbum", + "version": "0.0.1" + }, + "scope": "APPLICATION", + "isWritable": true, + "itemSchema": { + "name": "TestPolicyContextItem", + "version": "0.0.1" + } + } + } + ] + } + }, + "schemas": { + "key": { + "name": "TestDatatypes", + "version": "0.0.1" + }, + "schemas": { + "entry": [ + { + "key": { + "name": "TestCase", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestCase", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "java.lang.Byte" + } + }, + { + "key": { + "name": "TestContextItem000", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem000", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestContextItem000" + } + }, + { + "key": { + "name": "TestContextItem001", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem001", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestContextItem001" + } + }, + { + "key": { + "name": "TestContextItem002", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem002", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestContextItem002" + } + }, + { + "key": { + "name": "TestContextItem003", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem003", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestContextItem003" + } + }, + { + "key": { + "name": "TestContextItem004", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem004", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestContextItem004" + } + }, + { + "key": { + "name": "TestContextItem005", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem005", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestContextItem005" + } + }, + { + "key": { + "name": "TestContextItem006", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem006", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestContextItem006" + } + }, + { + "key": { + "name": "TestContextItem007", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem007", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestContextItem007" + } + }, + { + "key": { + "name": "TestContextItem008", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem008", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestContextItem008" + } + }, + { + "key": { + "name": "TestContextItem009", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem009", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestContextItem009" + } + }, + { + "key": { + "name": "TestContextItem00A", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem00A", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestContextItem00A" + } + }, + { + "key": { + "name": "TestContextItem00B", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem00B", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestContextItem00B" + } + }, + { + "key": { + "name": "TestContextItem00C", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestContextItem00C", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestContextItem00C" + } + }, + { + "key": { + "name": "TestExternalContextItem", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestExternalContextItem", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestExternalContextItem" + } + }, + { + "key": { + "name": "TestGlobalContextItem", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestGlobalContextItem", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestGlobalContextItem" + } + }, + { + "key": { + "name": "TestPolicyContextItem", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestPolicyContextItem", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "org.onap.policy.apex.context.test.concepts.TestPolicyContextItem" + } + }, + { + "key": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestSlogan", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "java.lang.String" + } + }, + { + "key": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestTemperature", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "java.lang.Double" + } + }, + { + "key": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "value": { + "key": { + "name": "TestTimestamp", + "version": "0.0.1" + }, + "schemaFlavour": "Java", + "schemaDefinition": "java.lang.Long" + } + } + ] + } + } + } +} |