diff options
Diffstat (limited to 'client/client-editor/src/main/java/org')
24 files changed, 4273 insertions, 0 deletions
diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditor.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditor.java new file mode 100644 index 000000000..cb5e8f6b6 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditor.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.client.editor.rest; + +import org.glassfish.grizzly.http.server.HttpServer; +import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; +import org.glassfish.jersey.server.ResourceConfig; +import org.onap.policy.apex.model.utilities.Assertions; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * This class is used to launch the editor. It creates a Grizzly embedded web server and runs the editor. + */ +public class ApexEditor { + // Logger for this class + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexEditor.class); + + // The HTTP server exposing JAX-RS resources defined in this application. + private final HttpServer server; + + /** + * Starts the HTTP server for the Apex editor on the default base URI and with the default REST packages. + */ + public ApexEditor() { + this(new ApexEditorParameters()); + } + + /** + * Starts the HTTP server for the Apex editor. + * + * @param parameters the parameters + */ + public ApexEditor(final ApexEditorParameters parameters) { + Assertions.argumentNotNull(parameters, "parameters may not be null"); + + LOGGER.debug("Apex RESTful editor starting . . ."); + + // Create a resource configuration that scans for JAX-RS resources and providers + // in org.onap.policy.apex.client.editor.rest package + final ResourceConfig rc = new ResourceConfig().packages(parameters.getRESTPackages()); + + // create and start a new instance of grizzly http server + // exposing the Jersey application at BASE_URI + server = GrizzlyHttpServerFactory.createHttpServer(parameters.getBaseURI(), rc); + + // Add static content + server.getServerConfiguration().addHttpHandler(new org.glassfish.grizzly.http.server.CLStaticHttpHandler( + ApexEditorMain.class.getClassLoader(), "/webapp/"), parameters.getStaticPath()); + + LOGGER.debug("Apex RESTful editor started"); + } + + /** + * Shut down the web server. + */ + public void shutdown() { + LOGGER.debug("Apex RESTful editor shutting down . . ."); + server.shutdown(); + LOGGER.debug("Apex RESTful editor shut down"); + } +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorException.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorException.java new file mode 100644 index 000000000..b674e6021 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorException.java @@ -0,0 +1,73 @@ +/*- + * ============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.client.editor.rest; + +import org.onap.policy.apex.model.basicmodel.concepts.ApexException; + +/** + * Exceptions from the Apex editor. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexEditorException extends ApexException { + private static final long serialVersionUID = 4867385591967018254L; + + /** + * Instantiates a new apex editor exception. + * + * @param message the message on the exception + */ + public ApexEditorException(final String message) { + super(message); + } + + /** + * Instantiates a new apex editor exception. + * + * @param message the message on the exception + * @param object the object that the exception was thrown on + */ + public ApexEditorException(final String message, final Object object) { + super(message, object); + } + + /** + * Instantiates a new apex editor exception. + * + * @param message the message on the exception + * @param e the exception that caused this Apex exception + */ + public ApexEditorException(final String message, final Exception e) { + super(message, e); + } + + /** + * Instantiates a new apex editor exception. + * + * @param message the message on the exception + * @param e the exception that caused this Apex exception + * @param object the object that the exception was thrown on + */ + public ApexEditorException(final String message, final Exception e, final Object object) { + super(message, e, object); + } + +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorMain.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorMain.java new file mode 100644 index 000000000..ee7199fda --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorMain.java @@ -0,0 +1,207 @@ +/*- + * ============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.client.editor.rest; + +import java.io.PrintStream; + +/** + * This class is the main class that is used to launch the Apex editor from the command line. + * + */ +public class ApexEditorMain { + /** + * The Enum EditorState holds the current state of the editor. + */ + // Editor state + public enum EditorState { + /** The editor is stopped. */ + STOPPED, + /** The editor is ready to run. */ + READY, + /** The editor is getting ready to run. */ + INITIALIZING, + /** The editor is running. */ + RUNNING + }; + + private static final int EDITOR_RNNING_CHECK_TIMEOUT = 1000; + + private EditorState state = EditorState.STOPPED; + + // The Apex editor this class is running + private ApexEditor apexEditor = null; + + // The parameters for the editor + private ApexEditorParameters parameters = null; + + // Output and error streams for messages + private final PrintStream outStream; + + /** + * Main method, main entry point for command. + * + * @param args The command line arguments for the editor + */ + public static void main(final String[] args) { + try { + final ApexEditorMain editorMain = new ApexEditorMain(args, System.out); + editorMain.init(); + } catch (final Exception e) { + System.err.println(e.getMessage()); + } + } + + /** + * Constructor, kicks off the editor. + * + * @param args The command line arguments for the editor + * @param outStream The stream for output messages + */ + public ApexEditorMain(final String[] args, final PrintStream outStream) { + // Save the streams for output and error + this.outStream = outStream; + + // Editor parameter parsing + final ApexEditorParameterParser parser = new ApexEditorParameterParser(); + + try { + // Get and check the parameters + parameters = parser.parse(args); + } catch (final ApexEditorParameterException e) { + throw new ApexEditorParameterException( + "Apex Editor REST endpoint (" + this.toString() + ") parameter error, " + e.getMessage() + '\n' + + parser.getHelp(ApexEditorMain.class.getCanonicalName())); + } + + if (parameters.isHelpSet()) { + throw new ApexEditorParameterException(parser.getHelp(ApexEditorMain.class.getCanonicalName())); + } + + // Validate the parameters + final String validationMessage = parameters.validate(); + if (validationMessage.length() > 0) { + throw new ApexEditorParameterException( + "Apex Editor REST endpoint (" + this.toString() + ") parameters invalid, " + validationMessage + + '\n' + parser.getHelp(ApexEditorMain.class.getCanonicalName())); + } + + state = EditorState.READY; + } + + /** + * Initialize the Apex editor. + */ + public void init() { + outStream.println("Apex Editor REST endpoint (" + this.toString() + ") starting at " + + parameters.getBaseURI().toString() + " . . ."); + + try { + state = EditorState.INITIALIZING; + + // Start the editor + apexEditor = new ApexEditor(parameters); + + // Add a shutdown hook to shut down the editor when the process is exiting + Runtime.getRuntime().addShutdownHook(new Thread(new ApexEditorShutdownHook())); + + state = EditorState.RUNNING; + + if (parameters.getTimeToLive() == ApexEditorParameters.INFINITY_TIME_TO_LIVE) { + outStream.println("Apex Editor REST endpoint (" + this.toString() + ") started at " + + parameters.getBaseURI().toString()); + } else { + outStream.println("Apex Editor REST endpoint (" + this.toString() + ") started"); + } + + // Find out how long is left to wait + long timeRemaining = parameters.getTimeToLive(); + while (timeRemaining == ApexEditorParameters.INFINITY_TIME_TO_LIVE || timeRemaining > 0) { + // decrement the time to live in the non-infinity case + if (timeRemaining > 0) { + timeRemaining--; + } + + // Wait for a second + Thread.sleep(EDITOR_RNNING_CHECK_TIMEOUT); + } + } catch (final Exception e) { + outStream.println( + "Apex Editor REST endpoint (" + this.toString() + ") failed at with error: " + e.getMessage()); + } finally { + if (apexEditor != null) { + apexEditor.shutdown(); + apexEditor = null; + } + state = EditorState.STOPPED; + } + } + + /** + * Get the editor state. + * + * @return the state + */ + public EditorState getState() { + return state; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + final StringBuilder ret = new StringBuilder(); + ret.append(this.getClass().getSimpleName()).append(": Config=[").append(parameters).append("], State=") + .append(this.getState()); + return ret.toString(); + } + + /** + * Explicitly shut down the editor. + */ + public void shutdown() { + if (apexEditor != null) { + outStream.println("Apex Editor REST endpoint (" + this.toString() + ") shutting down"); + apexEditor.shutdown(); + } + state = EditorState.STOPPED; + outStream.println("Apex Editor REST endpoint (" + this.toString() + ") shut down"); + } + + /** + * This class is a shutdown hook for the Apex editor command. + */ + private class ApexEditorShutdownHook implements Runnable { + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + if (apexEditor != null) { + apexEditor.shutdown(); + } + } + } +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorParameterException.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorParameterException.java new file mode 100644 index 000000000..921b4c068 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorParameterException.java @@ -0,0 +1,49 @@ +/*- + * ============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.client.editor.rest; + +/** + * A run time exception used to report parsing and parameter input errors. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexEditorParameterException extends IllegalArgumentException { + private static final long serialVersionUID = 6520231162404452427L; + + /** + * Create an ApexEditorParameterException with a message. + * + * @param message the message + */ + public ApexEditorParameterException(final String message) { + super(message); + } + + /** + * Create an ApexEditorParameterException with a message and an exception. + * + * @param message the message + * @param t the t + */ + public ApexEditorParameterException(final String message, final Throwable t) { + super(message, t); + } +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorParameterParser.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorParameterParser.java new file mode 100644 index 000000000..32ebfba9a --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorParameterParser.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.client.editor.rest; + +import java.io.PrintWriter; +import java.io.StringWriter; +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; + +/** + * This class reads and handles command line parameters to the Apex CLI editor. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexEditorParameterParser { + // Apache Commons CLI options + private Options options; + + private static final int COMMAND_HELP_MAX_LINE_WIDTH = 120; + + /** + * Construct the options for the CLI editor. + */ + public ApexEditorParameterParser() { + options = new Options(); + options.addOption("h", "help", false, "outputs the usage of this command"); + options.addOption( + Option.builder("p").longOpt("port").desc("port to use for the Apex RESTful editor REST calls.").hasArg() + .argName("PORT").required(false).type(Number.class).build()); + options.addOption(Option.builder("t").longOpt("time-to-live") + .desc("the amount of time in seconds that the server will run for before terminating. " + + "Default value is " + ApexEditorParameters.INFINITY_TIME_TO_LIVE + " to run indefinitely.") + .hasArg().argName("TIME_TO_LIVE").required(false).type(Number.class).build()); + options.addOption(Option.builder("l").longOpt("listen").desc("the IP address to listen on. Default value is " + + ApexEditorParameters.DEFAULT_SERVER_URI_ROOT + " " + + "to listen on all available addresses. Use value 'localhost' to restrict access to the local machine only.") + .hasArg().argName("ADDRESS").required(false).type(String.class).build()); + } + + /** + * Parse the command line options. + * + * @param args The arguments + * @return the apex editor parameters + */ + public ApexEditorParameters parse(final String[] args) { + CommandLine commandLine = null; + try { + commandLine = new DefaultParser().parse(options, args); + } catch (final ParseException e) { + throw new ApexEditorParameterException("invalid command line arguments specified : " + e.getMessage()); + } + + final ApexEditorParameters parameters = new ApexEditorParameters(); + final String[] remainingArgs = commandLine.getArgs(); + + if (commandLine.getArgs().length > 0) { + throw new ApexEditorParameterException( + "too many command line arguments specified : " + Arrays.toString(remainingArgs)); + } + + if (commandLine.hasOption('h')) { + parameters.setHelp(true); + } + try { + if (commandLine.hasOption('p')) { + parameters.setRESTPort(((Number) commandLine.getParsedOptionValue("port")).intValue()); + } + } catch (final ParseException e) { + throw new ApexEditorParameterException("error parsing argument \"port\" :" + e.getMessage(), e); + } + try { + if (commandLine.hasOption('t')) { + parameters.setTimeToLive(((Number) commandLine.getParsedOptionValue("time-to-live")).longValue()); + } + } catch (final ParseException e) { + throw new ApexEditorParameterException("error parsing argument \"time-to-live\" :" + e.getMessage(), e); + } + try { + if (commandLine.hasOption('l')) { + parameters.setListenAddress(commandLine.getParsedOptionValue("listen").toString()); + } + } catch (final ParseException e) { + throw new ApexEditorParameterException("error parsing argument \"listen-address\" :" + e.getMessage(), e); + } + + return parameters; + } + + /** + * Get help information. + * + * @param mainClassName the main class name + * @return the help + */ + public String getHelp(final String mainClassName) { + final StringWriter stringWriter = new StringWriter(); + final PrintWriter stringPrintWriter = new PrintWriter(stringWriter); + + final HelpFormatter helpFormatter = new HelpFormatter(); + helpFormatter.printHelp(stringPrintWriter, COMMAND_HELP_MAX_LINE_WIDTH, mainClassName + " [options...] ", null, + options, 0, 1, ""); + + return stringWriter.toString(); + } +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorParameters.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorParameters.java new file mode 100644 index 000000000..16afcd161 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorParameters.java @@ -0,0 +1,224 @@ +/*- + * ============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.client.editor.rest; + +import java.net.URI; +import java.net.URISyntaxException; + +/** + * This class reads and handles command line parameters to the Apex CLI editor. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public class ApexEditorParameters { + /** The default port for connecting to the Web editor on. */ + public static final int DEFAULT_REST_PORT = 18989; + + /** The connection is held up until killed on demand. */ + public static final int INFINITY_TIME_TO_LIVE = -1; + + // Base URI the HTTP server will listen on + private static final String DEFAULT_SERVER_URI_PREFIX = "http://"; + /** The server listens on all available interfaces/addresses. */ + public static final String DEFAULT_SERVER_URI_ROOT = "0.0.0.0"; + private static final String DEFAULT_REST_PATH = "/apexservices/"; + private static final String DEFAULT_STATIC_PATH = "/"; + + // Constants for port checks + private static final int MIN_USER_PORT = 1024; + private static final int MAX_USER_PORT = 65535; + + + // Package that will field REST requests + private static final String[] DEFAULT_PACKAGES = new String[] { "org.onap.policy.apex.client.editor.rest" }; + + // The editor parameters + private boolean helpSet = false; + private int restPort = DEFAULT_REST_PORT; + private long timeToLive = INFINITY_TIME_TO_LIVE; + private String listenAddress = DEFAULT_SERVER_URI_ROOT; + + /** + * Validate. + * + * @return the string + */ + public String validate() { + String validationMessage = ""; + validationMessage += validatePort(); + validationMessage += validateTimeToLive(); + validationMessage += validateUrl(); + + return validationMessage; + } + + /** + * Gets the base URI. + * + * @return the base URI + */ + public URI getBaseURI() { + return URI.create(DEFAULT_SERVER_URI_PREFIX + listenAddress + ':' + restPort + DEFAULT_REST_PATH); + } + + /** + * Gets the REST packages. + * + * @return the REST packages + */ + public String[] getRESTPackages() { + return DEFAULT_PACKAGES; + } + + /** + * Gets the static path. + * + * @return the static path + */ + public String getStaticPath() { + return DEFAULT_STATIC_PATH; + } + + /** + * Validate port. + * + * @return a warning string, or an empty string + */ + private String validatePort() { + if (restPort < MIN_USER_PORT || restPort > MAX_USER_PORT) { + return "port must be between " + MIN_USER_PORT + " and " + MAX_USER_PORT + "\n"; + } else { + return ""; + } + } + + /** + * Validate URL. + * + * @return a warning string, or an empty string + */ + private String validateUrl() { + try { + new URI(getBaseURI().toString()).parseServerAuthority(); + return ""; + } catch (final URISyntaxException e) { + return "listen address is not valid. " + e.getMessage() + "\n"; + } + } + + /** + * Validate time to live. + * + * @return the string + */ + private String validateTimeToLive() { + if (timeToLive < -1) { + return "time to live must be greater than -1 (set to -1 to wait forever)\n"; + } else { + return ""; + } + } + + /** + * Checks if is help set. + * + * @return true, if checks if is help set + */ + public boolean isHelpSet() { + return helpSet; + } + + /** + * Sets the help. + * + * @param help the help + */ + public void setHelp(final boolean help) { + this.helpSet = help; + } + + /** + * Gets the REST port. + * + * @return the REST port + */ + public int getRESTPort() { + return restPort; + } + + /** + * Sets the REST port. + * + * @param incomingRestPort the REST port + */ + public void setRESTPort(final int incomingRestPort) { + this.restPort = incomingRestPort; + } + + /** + * Gets the time to live. + * + * @return the time to live + */ + public long getTimeToLive() { + return timeToLive; + } + + /** + * Sets the time to live. + * + * @param timeToLive the time to live + */ + public void setTimeToLive(final long timeToLive) { + this.timeToLive = timeToLive; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + final StringBuilder ret = new StringBuilder(); + ret.append(this.getClass().getSimpleName()).append(": URI=").append(this.getBaseURI()).append(", TTL=") + .append(this.getTimeToLive()).append("sec"); + return ret.toString(); + } + + /** + * Gets the base address to listen on. + * + * @return the listenAddress + */ + public String getListenAddress() { + return listenAddress; + } + + /** + * Sets the base address to listen on. + * + * @param listenAddress the new listenAddress + */ + public void setListenAddress(final String listenAddress) { + this.listenAddress = listenAddress; + } +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorRestResource.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorRestResource.java new file mode 100644 index 000000000..08b869256 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/ApexEditorRestResource.java @@ -0,0 +1,2019 @@ +/*- + * ============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.client.editor.rest; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.onap.policy.apex.client.editor.rest.bean.BeanContextAlbum; +import org.onap.policy.apex.client.editor.rest.bean.BeanContextSchema; +import org.onap.policy.apex.client.editor.rest.bean.BeanEvent; +import org.onap.policy.apex.client.editor.rest.bean.BeanField; +import org.onap.policy.apex.client.editor.rest.bean.BeanKeyRef; +import org.onap.policy.apex.client.editor.rest.bean.BeanLogic; +import org.onap.policy.apex.client.editor.rest.bean.BeanModel; +import org.onap.policy.apex.client.editor.rest.bean.BeanPolicy; +import org.onap.policy.apex.client.editor.rest.bean.BeanState; +import org.onap.policy.apex.client.editor.rest.bean.BeanStateOutput; +import org.onap.policy.apex.client.editor.rest.bean.BeanStateTaskRef; +import org.onap.policy.apex.client.editor.rest.bean.BeanTask; +import org.onap.policy.apex.client.editor.rest.bean.BeanTaskParameter; +import org.onap.policy.apex.model.basicmodel.concepts.AxKey; +import org.onap.policy.apex.model.basicmodel.concepts.AxKeyInfo; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum; +import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema; +import org.onap.policy.apex.model.eventmodel.concepts.AxEvent; +import org.onap.policy.apex.model.modelapi.ApexAPIResult; +import org.onap.policy.apex.model.modelapi.ApexAPIResult.RESULT; +import org.onap.policy.apex.model.modelapi.ApexModel; +import org.onap.policy.apex.model.modelapi.ApexModelFactory; +import org.onap.policy.apex.model.policymodel.concepts.AxPolicy; +import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel; +import org.onap.policy.apex.model.policymodel.concepts.AxTask; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * The class represents the root resource exposed at the base URL<br> + * The url to access this resource would be in the form {@code <baseURL>/rest/<session>/....} <br> + * For example: a PUT request to the following URL {@code http://localhost:8080/apex/rest/109/ContextSchema/Update}, + * with a JSON string payload containing the new {@code Schema} in the body, can be explained as: + * <ul> + * <li>The server or servlet is running at the base URL {@code http://localhost:8080/apex} + * <li>This resource {@code ApexRestEditorResource} is used because the path {@code rest/109} matches the {@code Path} + * filter specification for this Resource ({@code @Path("rest/{session}")}), where the {@code int} path parameter + * {@code session} is assigned the {@code int} value {@code 109} + * <li>The path {@code ContextSchema/Update} redirects this call to the method {@link #updateContextSchema(String)}, + * which should be a {@link javax.ws.rs.PUT}, with a single String in the body/payload which gets mapped to the single + * String parameter for the method. + * <li>So, in summary, the REST request updates a {@code ContextSchema} as specified in the payload for {@code session} + * number {@code 109} + * </ul> + * + * <b>Note:</b> An allocated {@code Session} identifier must be included in (almost) all requests. Models for different + * {@code Session} identifiers are completely isolated from one another. + * + * <b>Note:</b> To create a new {@code Session}, and have a new session ID allocated use {@link javax.ws.rs.GET} request + * to {@code <baseURL>/rest/-1/Session/Create} (for example: {@code http://localhost:8080/apex/rest/-1/Session/Create} ) + * + */ +@Path("editor/{session}") +@Produces({ MediaType.APPLICATION_JSON }) +@Consumes({ MediaType.APPLICATION_JSON }) + +public class ApexEditorRestResource { + // Get a reference to the logger + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexEditorRestResource.class); + + // The next session will have this number, stating at 0 + private static int nextSession = 0; + + // All REST editor sessions being handled by the server + private static final Map<Integer, ApexModel> SESSIONMODELMAP = new TreeMap<>(); + + // The ID of this session. This gets injected from the URL. + @PathParam("session") + private int sessionID = -1; + + // The Apex model for the session + private ApexModel sessionApexModel = null; + + /** + * This method sets the Apex model for the current editor session. Don't forget to call {@link #commitChanges()} + * when finished! This makes requests atomic. + * + * @return the result of finding the session Apex model and setting it + */ + private ApexAPIResult initialiseSessionForChanges() { + if (sessionID < 0) { + return new ApexAPIResult(RESULT.FAILED, "Session ID \"" + sessionID + "\" is negative"); + } + + if (!SESSIONMODELMAP.containsKey(sessionID)) { + return new ApexAPIResult(RESULT.FAILED, "A session with session ID \"" + sessionID + "\" does not exist"); + } + + if (sessionApexModel == null) { + sessionApexModel = SESSIONMODELMAP.get(sessionID).clone(); + } + return new ApexAPIResult(); + } + + /** + * This method sets the Apex model for the current editor session. Don't make any changes to the model. + * + * @return the result of finding the session Apex model and setting it + */ + private ApexAPIResult initialiseSessionForReadOnly() { + if (sessionID < 0) { + return new ApexAPIResult(RESULT.FAILED, "Session ID \"" + sessionID + "\" is negative"); + } + + if (!SESSIONMODELMAP.containsKey(sessionID)) { + return new ApexAPIResult(RESULT.FAILED, "A session with session ID \"" + sessionID + "\" does not exist"); + } + + if (sessionApexModel == null) { + sessionApexModel = SESSIONMODELMAP.get(sessionID); + } + return new ApexAPIResult(); + } + + /** + * This method commits changes to the Apex model for the current editor session. This should only be called once, at + * the end of a successful change to the model for this session + * + * @return the result of committing the session Apex model + */ + private ApexAPIResult commitChanges() { + + if (sessionApexModel == null) { + return new ApexAPIResult(RESULT.FAILED, "Cannot commit a changes for Session ID \"" + sessionID + + "\", because it has not been initialised / started"); + } + + SESSIONMODELMAP.put(sessionID, sessionApexModel); + + return new ApexAPIResult(); + } + + /** + * Creates a new session. Always call this method with sessionID -1, whereby a new sessionID will be allocated. If + * successful the new sessionID will be available in the first message in the result. + * + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()}. This includes the session id + * for this session. + */ + @GET + @Path("Session/Create") + public ApexAPIResult createSession() { + ApexAPIResult ret = null; + LOGGER.entry(); + try { + if (sessionID != -1) { + ret = new ApexAPIResult(RESULT.FAILED, "Session ID must be set to -1 to create sessions: " + sessionID); + return ret; + } + + final int newSessionID = nextSession; + + if (SESSIONMODELMAP.containsKey(newSessionID)) { + ret = new ApexAPIResult(RESULT.FAILED, "Session already exists for session: " + newSessionID); + return ret; + } + + SESSIONMODELMAP.put(newSessionID, new ApexModelFactory().createApexModel(null, true)); + nextSession++; + + ret = new ApexAPIResult(RESULT.SUCCESS, Integer.toString(newSessionID)); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Session/Create" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Load the model from a JSON string for this session. + * + * @param jsonString the JSON string to be parsed. The returned value(s) will be similar to {@link AxPolicyModel}, + * with merged {@linkplain AxKeyInfo} for the root object. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @PUT + @Path("/Model/Load") + public ApexAPIResult loadFromString(final String jsonString) { + ApexAPIResult ret = null; + LOGGER.entry(jsonString); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + ret = sessionApexModel.loadFromString(jsonString); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Model/Load" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Analyse the model and return analysis results. If successful the analysis results will be available in the + * messages in the result. + * + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("Model/Analyse") + public ApexAPIResult analyse() { + ApexAPIResult ret = null; + LOGGER.entry(); + try { + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + ret = sessionApexModel.analyse(); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Model/Analyse" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Validate the model and return validation results. If successful the validation results will be available in the + * messages in the result. + * + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("Model/Validate") + public ApexAPIResult validate() { + ApexAPIResult ret = null; + LOGGER.entry(); + try { + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + ret = sessionApexModel.validate(); + + ret = addKeyInfo2Messages(ret); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Model/Validate" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Creates the new model model for this session. + * + * @param jsonString the JSON string to be parsed containing the new model. See {@linkplain BeanModel} + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @POST + @Path("Model/Create") + public ApexAPIResult createModel(final String jsonString) { + ApexAPIResult ret = null; + LOGGER.entry(jsonString); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + final BeanModel jsonbean = RestUtils.getJSONParameters(jsonString, BeanModel.class); + ret = sessionApexModel.createModel(jsonbean.getName(), jsonbean.getVersion(), jsonbean.getUuid(), + jsonbean.getDescription()); + + if (ret.isOK()) { + ret = addKeyInfo2Messages(ret); + } + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Model/Create" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Update the model for this session. + * + * @param jsonString the JSON string to be parsed containing the updated model. See {@linkplain BeanModel} + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @PUT + @Path("Model/Update") + public ApexAPIResult updateModel(final String jsonString) { + ApexAPIResult ret = null; + LOGGER.entry(jsonString); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + final BeanModel jsonbean = RestUtils.getJSONParameters(jsonString, BeanModel.class); + ret = sessionApexModel.updateModel(jsonbean.getName(), jsonbean.getVersion(), jsonbean.getUuid(), + jsonbean.getDescription()); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Model/Update" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Gets the key for the model for this session. If successful the model key will be available in the first message + * in the result. See {@linkplain AxKey} + * + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("Model/GetKey") + public ApexAPIResult getModelKey() { + ApexAPIResult ret = null; + LOGGER.entry(); + try { + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + ret = sessionApexModel.getModelKey(); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Model/GetKey" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Retrieve the model for this session. If successful the model will be available in the first message in the + * result. The returned value will be similar to a {@link AxPolicyModel}, with merged {@linkplain AxKeyInfo} for the + * root object. + * + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("Model/Get") + public ApexAPIResult listModel() { + ApexAPIResult ret = null; + LOGGER.entry(); + try { + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + ret = sessionApexModel.listModel(); + if (ret.isNOK()) { + return ret; + } + + ret = addKeyInfo2Messages(ret); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Model/Get" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Download the model for this session as a String. + * + * @return the model represented as a JSON string. See {@linkplain AxPolicyModel} + */ + @GET + @Path("Model/Download") + public String downloadModel() { + ApexAPIResult ret = null; + LOGGER.entry(); + try { + + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + throw new IllegalStateException("Cannot download file: " + ret.getMessage()); + } + + ret = sessionApexModel.listModel(); + if (ret.isNOK()) { + throw new IllegalStateException("Cannot download file: " + ret.getMessage()); + } + + return ret.getMessage(); + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit(ret.isOK()); + LOGGER.info("Model/Download" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Delete the model for this session. + * + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @DELETE + @Path("Model/Delete") + public ApexAPIResult deleteModel() { + ApexAPIResult ret = null; + LOGGER.entry(); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + ret = sessionApexModel.deleteModel(); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Model/Delete" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * List key information with the given key names/versions. If successful the result(s) will be available in the + * result messages. See {@linkplain AxKeyInfo} + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("KeyInformation/Get") + public ApexAPIResult listKeyInformation(@QueryParam("name") final String name, + @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + ret = sessionApexModel.listKeyInformation(name1, version1); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("KeyInformation/Get" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Creates a context schema with the information in the JSON string passed. + * + * @param jsonString the JSON string to be parsed. See {@linkplain BeanContextSchema} + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @POST + @Path("ContextSchema/Create") + public ApexAPIResult createContextSchema(final String jsonString) { + ApexAPIResult ret = null; + LOGGER.entry(jsonString); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + final BeanContextSchema jsonbean = RestUtils.getJSONParameters(jsonString, BeanContextSchema.class); + ret = sessionApexModel.createContextSchema(jsonbean.getName(), jsonbean.getVersion(), + jsonbean.getSchemaFlavour(), jsonbean.getSchemaDefinition(), jsonbean.getUuid(), + jsonbean.getDescription()); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("ContextSchema/Create" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Update a context schema with the information in the JSON string passed. + * + * @param jsonString the JSON string to be parsed. See {@linkplain BeanContextSchema} + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @PUT + @Path("ContextSchema/Update") + public ApexAPIResult updateContextSchema(final String jsonString) { + ApexAPIResult ret = null; + LOGGER.entry(jsonString); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + final BeanContextSchema jsonbean = RestUtils.getJSONParameters(jsonString, BeanContextSchema.class); + + ret = sessionApexModel.updateContextSchema(jsonbean.getName(), jsonbean.getVersion(), + jsonbean.getSchemaFlavour(), jsonbean.getSchemaDefinition(), jsonbean.getUuid(), + jsonbean.getDescription()); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("ContextSchema/Update" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * List context schemas with the given key names/versions. If successful the result(s) will be available in the + * result messages. The returned value(s) will be similar to {@link AxContextSchema}, with merged + * {@linkplain AxKeyInfo} for the root object. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("ContextSchema/Get") + public ApexAPIResult listContextSchemas(@QueryParam("name") final String name, + @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + ret = sessionApexModel.listContextSchemas(name1, version1); + if (ret.isNOK()) { + return ret; + } + + ret = addKeyInfo2Messages(ret); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("ContextSchema/Get" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Delete context schemas with the given key names/versions. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @DELETE + @Path("ContextSchema/Delete") + public ApexAPIResult deleteContextSchema(@QueryParam("name") final String name, + @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + ret = sessionApexModel.deleteContextSchema(name1, version1); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("ContextSchema/Delete" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Validate context schemas with the given key names/versions. The result(s) will be available in the result + * messages. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("Validate/ContextSchema") + public ApexAPIResult validateContextSchemas(@QueryParam("name") final String name, + @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + ret = sessionApexModel.validateContextSchemas(name1, version1); + if (ret.isNOK()) { + return ret; + } + + ret = addKeyInfo2Messages(ret); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Validate/ContextSchema" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Creates a context album with the information in the JSON string passed. + * + * @param jsonString the JSON string to be parsed. See {@linkplain BeanContextAlbum} + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @POST + @Path("ContextAlbum/Create") + public ApexAPIResult createContextAlbum(final String jsonString) { + ApexAPIResult ret = null; + LOGGER.entry(jsonString); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + final BeanContextAlbum jsonbean = RestUtils.getJSONParameters(jsonString, BeanContextAlbum.class); + + ret = sessionApexModel.createContextAlbum(jsonbean.getName(), jsonbean.getVersion(), jsonbean.getScope(), + Boolean.toString(jsonbean.getWriteable()), jsonbean.getItemSchema().getName(), + jsonbean.getItemSchema().getVersion(), jsonbean.getUuid(), jsonbean.getDescription()); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("ContextAlbum/Create" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Update a context album with the information in the JSON string passed. + * + * @param jsonString the JSON string to be parsed. See {@linkplain BeanContextAlbum} + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @PUT + @Path("ContextAlbum/Update") + public ApexAPIResult updateContextAlbum(final String jsonString) { + ApexAPIResult ret = null; + LOGGER.entry(jsonString); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + final BeanContextAlbum jsonbean = RestUtils.getJSONParameters(jsonString, BeanContextAlbum.class); + + ret = sessionApexModel.updateContextAlbum(jsonbean.getName(), jsonbean.getVersion(), jsonbean.getScope(), + Boolean.toString(jsonbean.getWriteable()), jsonbean.getItemSchema().getName(), + jsonbean.getItemSchema().getVersion(), jsonbean.getUuid(), jsonbean.getDescription()); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("ContextAlbum/Update" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * List context albums with the given key names/versions. If successful the result(s) will be available in the + * result messages. The returned value(s) will be similar to {@link AxContextAlbum}, with merged + * {@linkplain AxKeyInfo} for the root object. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("ContextAlbum/Get") + public ApexAPIResult listContextAlbums(@QueryParam("name") final String name, + @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + ret = sessionApexModel.listContextAlbum(name1, version1); + if (ret.isNOK()) { + return ret; + } + + ret = addKeyInfo2Messages(ret); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("ContextAlbum/Get" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Delete context albums with the given key names/versions. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @DELETE + @Path("ContextAlbum/Delete") + public ApexAPIResult deleteContextAlbum(@QueryParam("name") final String name, + @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + ret = sessionApexModel.deleteContextAlbum(name1, version1); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("ContextAlbum/Delete" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Validate context albums with the given key names/versions. The result(s) will be available in the result + * messages. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("Validate/ContextAlbum") + public ApexAPIResult validateContextAlbums(@QueryParam("name") final String name, + @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + ret = sessionApexModel.listContextAlbum(name1, version1); + if (ret.isNOK()) { + return ret; + } + + ret = addKeyInfo2Messages(ret); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Validate/ContextAlbum" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Creates an event with the information in the JSON string passed. + * + * @param jsonString the JSON string to be parsed. See {@linkplain BeanEvent} + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @POST + @Path("Event/Create") + public ApexAPIResult createEvent(final String jsonString) { + ApexAPIResult ret = null; + LOGGER.entry(jsonString); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + final BeanEvent jsonbean = RestUtils.getJSONParameters(jsonString, BeanEvent.class); + + ret = sessionApexModel.createEvent(jsonbean.getName(), jsonbean.getVersion(), jsonbean.getNameSpace(), + jsonbean.getSource(), jsonbean.getTarget(), jsonbean.getUuid(), jsonbean.getDescription()); + if (ret.isNOK()) { + return ret; + } + if (jsonbean.getParameters() != null) { + for (final Entry<String, BeanField> p : jsonbean.getParameters().entrySet()) { + if (p.getValue() == null) { + ret = new ApexAPIResult(RESULT.FAILED, "Null event parameter information for parameter \"" + + p.getKey() + "\" in event " + jsonbean.getName() + ":" + jsonbean.getVersion() + + ". The event was created, but there was an error adding the event parameters. The event has only been partially defined."); + return ret; + } + final ApexAPIResult rettmp = + sessionApexModel.createEventPar(jsonbean.getName(), jsonbean.getVersion(), p.getKey(), + p.getValue().getName(), p.getValue().getVersion(), p.getValue().getOptional()); + if (rettmp.isNOK()) { + rettmp.addMessage("Failed to add event parameter information for parameter \"" + p.getKey() + + "\" in event " + jsonbean.getName() + ":" + jsonbean.getVersion() + + ". The event was created, but there was an error adding the event parameters. The event has only been partially defined."); + ret = rettmp; + return ret; + } + } + } + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Event/Create" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Update an event with the information in the JSON string passed. + * + * @param jsonString the JSON string to be parsed. See {@linkplain BeanEvent} + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @PUT + @Path("Event/Update") + public ApexAPIResult updateEvent(final String jsonString) { + ApexAPIResult ret = null; + LOGGER.entry(jsonString); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + final BeanEvent jsonbean = RestUtils.getJSONParameters(jsonString, BeanEvent.class); + + if (jsonbean.getName() == null || jsonbean.getName().equals("") || jsonbean.getVersion() == null + || jsonbean.getVersion().equals("")) { + ret = new ApexAPIResult(RESULT.FAILED, "Null/Empty event name/version (\"" + jsonbean.getName() + ":" + + jsonbean.getVersion() + "\" passed to UpdateEvent"); + return ret; + } + + ret = sessionApexModel.deleteEvent(jsonbean.getName(), jsonbean.getVersion()); + if (ret.isNOK()) { + return ret; + } + + ret = createEvent(jsonString); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Event/Update" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * List events with the given key names/versions. If successful the result(s) will be available in the result + * messages. The returned value(s) will be similar to {@link AxEvent}, with merged {@linkplain AxKeyInfo} for the + * root object. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("Event/Get") + public ApexAPIResult listEvent(@QueryParam("name") final String name, @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + ret = sessionApexModel.listEvent(name1, version1); + if (ret.isNOK()) { + return ret; + } + + ret = addKeyInfo2Messages(ret); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Event/Get" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Delete events with the given key names/versions. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @DELETE + @Path("Event/Delete") + public ApexAPIResult deleteEvent(@QueryParam("name") final String name, + @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + ret = sessionApexModel.deleteEvent(name1, version1); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Event/Delete" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Validate events with the given key names/versions. The result(s) will be available in the result messages. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("Validate/Event") + public ApexAPIResult validateEvent(@QueryParam("name") final String name, + @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + ret = sessionApexModel.listEvent(name1, version1); + if (ret.isNOK()) { + return ret; + } + + ret = addKeyInfo2Messages(ret); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Validate/Event" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Creates a task with the information in the JSON string passed. + * + * @param jsonString the JSON string to be parsed. See {@linkplain BeanTask} + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @POST + @Path("Task/Create") + public ApexAPIResult createTask(final String jsonString) { + ApexAPIResult ret = null; + ApexAPIResult tempres = null; + LOGGER.entry(jsonString); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + final BeanTask jsonbean = RestUtils.getJSONParameters(jsonString, BeanTask.class); + + ret = sessionApexModel.createTask(jsonbean.getName(), jsonbean.getVersion(), jsonbean.getUuid(), + jsonbean.getDescription()); + if (ret.isNOK()) { + return ret; + } + if (jsonbean.getInputFields() != null) { + for (final Entry<String, BeanField> fin : jsonbean.getInputFields().entrySet()) { + if (fin.getValue() == null) { + ret = new ApexAPIResult(RESULT.FAILED, "Null task input field information for field \"" + + fin.getKey() + "\" in task " + jsonbean.getName() + ":" + jsonbean.getVersion() + + ". The task was created, but there was an error adding the input fields. The task has only been partially defined."); + return ret; + } + if (fin.getKey() == null || !fin.getKey().equals(fin.getValue().getLocalName())) { + ret = new ApexAPIResult(RESULT.FAILED, "Invalid task input field information for field \"" + + fin.getKey() + "\" in task " + jsonbean.getName() + ":" + jsonbean.getVersion() + + ". The localName of the field (\"" + fin.getValue().getLocalName() + + "\") is not the same as the field name. " + + "The task was created, but there was an error adding the input fields. The task has only been partially defined."); + return ret; + } + tempres = sessionApexModel.createTaskInputField(jsonbean.getName(), jsonbean.getVersion(), + fin.getKey(), fin.getValue().getName(), fin.getValue().getVersion(), + fin.getValue().getOptional()); + if (tempres.isNOK()) { + tempres.addMessage("Failed to add task input field information for field \"" + fin.getKey() + + "\" in task " + jsonbean.getName() + ":" + jsonbean.getVersion() + + ". The task was created, but there was an error adding the input fields. The task has only been partially defined."); + ret = tempres; + return ret; + } + } + } + if (jsonbean.getOutputFields() != null) { + for (final Entry<String, BeanField> fout : jsonbean.getOutputFields().entrySet()) { + if (fout.getValue() == null) { + ret = new ApexAPIResult(RESULT.FAILED, "Null task output field information for field \"" + + fout.getKey() + "\" in task " + jsonbean.getName() + ":" + jsonbean.getVersion() + + ". The task was created, but there was an error adding the output fields. The task has only been partially defined."); + return ret; + } + if (fout.getKey() == null || !fout.getKey().equals(fout.getValue().getLocalName())) { + ret = new ApexAPIResult(RESULT.FAILED, "Invalid task output field information for field \"" + + fout.getKey() + "\" in task " + jsonbean.getName() + ":" + jsonbean.getVersion() + + ". The localName of the field (\"" + fout.getValue().getLocalName() + + "\") is not the same as the field name. " + + "The task was created, but there was an error adding the output fields. The task has only been partially defined."); + return ret; + } + tempres = sessionApexModel.createTaskOutputField(jsonbean.getName(), jsonbean.getVersion(), + fout.getKey(), fout.getValue().getName(), fout.getValue().getVersion(), + fout.getValue().getOptional()); + if (tempres.isNOK()) { + tempres.addMessage("Failed to add task output field information for field \"" + fout.getKey() + + "\" in task " + jsonbean.getName() + ":" + jsonbean.getVersion() + + ". The task was created, but there was an error adding the output fields. The task has only been partially defined."); + ret = tempres; + return ret; + } + } + } + if (jsonbean.getTaskLogic() != null) { + final BeanLogic logic = jsonbean.getTaskLogic(); + tempres = sessionApexModel.createTaskLogic(jsonbean.getName(), jsonbean.getVersion(), + logic.getLogicFlavour(), logic.getLogic()); + if (tempres.isNOK()) { + tempres.addMessage("Failed to add task logic in task " + jsonbean.getName() + ":" + + jsonbean.getVersion() + + ". The task was created, but there was an error adding the logic. The task has only been partially defined."); + ret = tempres; + return ret; + } + } + if (jsonbean.getParameters() != null) { + for (final Entry<String, BeanTaskParameter> param : jsonbean.getParameters().entrySet()) { + if (param.getKey() == null || param.getValue() == null + || !param.getKey().equals(param.getValue().getParameterName())) { + ret = new ApexAPIResult(RESULT.FAILED, + "Null or invalid task parameter information for parameter \"" + param.getKey() + + "\" in task " + jsonbean.getName() + ":" + jsonbean.getVersion() + + ". The task was created, but there was an error adding the parameters. The task has only been partially defined."); + return ret; + } + tempres = sessionApexModel.createTaskParameter(jsonbean.getName(), jsonbean.getVersion(), + param.getValue().getParameterName(), param.getValue().getDefaultValue()); + if (tempres.isNOK()) { + tempres.addMessage("Failed to add task parameter \"" + param.getKey() + "\" in task " + + jsonbean.getName() + ":" + jsonbean.getVersion() + + ". The task was created, but there was an error adding the parameters. The task has only been partially defined."); + ret = tempres; + return ret; + } + } + } + if (jsonbean.getContexts() != null) { + for (final BeanKeyRef contextalbum : jsonbean.getContexts()) { + if (contextalbum.getName() == null || contextalbum.getVersion() == null) { + ret = new ApexAPIResult(RESULT.FAILED, + "Null or invalid context album reference information in task " + jsonbean.getName() + + ":" + jsonbean.getVersion() + + ". The task was created, but there was an error adding the" + + " context album reference. The task has only been partially defined."); + return ret; + } + tempres = sessionApexModel.createTaskContextRef(jsonbean.getName(), jsonbean.getVersion(), + contextalbum.getName(), contextalbum.getVersion()); + if (tempres.isNOK()) { + ret = new ApexAPIResult(RESULT.FAILED, + "Failed to add context album reference information in task " + jsonbean.getName() + ":" + + jsonbean.getVersion() + + ". The task was created, but there was an error adding the" + + " context album reference. The task has only been partially defined."); + return ret; + } + } + } + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Task/Create" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Update a task with the information in the JSON string passed. + * + * @param jsonString the JSON string to be parsed. See {@linkplain BeanTask} + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @PUT + @Path("Task/Update") + public ApexAPIResult updateTask(final String jsonString) { + ApexAPIResult ret = null; + LOGGER.entry(jsonString); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + final BeanTask jsonbean = RestUtils.getJSONParameters(jsonString, BeanTask.class); + + if (jsonbean.getName() == null || jsonbean.getName().equals("") || jsonbean.getVersion() == null + || jsonbean.getVersion().equals("")) { + ret = new ApexAPIResult(RESULT.FAILED, "Null/Empty task name/version (\"" + jsonbean.getName() + ":" + + jsonbean.getVersion() + "\" passed to UpdateTask"); + return ret; + } + + ret = sessionApexModel.deleteTask(jsonbean.getName(), jsonbean.getVersion()); + if (ret.isNOK()) { + return ret; + } + + ret = createTask(jsonString); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Task/Update" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * List tasks with the given key names/versions. If successful the result(s) will be available in the result + * messages. The returned value(s) will be similar to {@link AxTask}, with merged {@linkplain AxKeyInfo} for the + * root object. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("Task/Get") + public ApexAPIResult listTask(@QueryParam("name") final String name, @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + ret = sessionApexModel.listTask(name1, version1); + if (ret.isNOK()) { + return ret; + } + + ret = addKeyInfo2Messages(ret); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Task/Get" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Delete tasks with the given key names/versions. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @DELETE + @Path("Task/Delete") + public ApexAPIResult deleteTask(@QueryParam("name") final String name, + @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + // all input/output fields, parameters, logic, context references is "owned"/contained in the task, so + // deleting the task removes all of these + ret = sessionApexModel.deleteTask(name1, version1); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Task/Delete" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Validate tasks with the given key names/versions. The result(s) will be available in the result messages. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("Validate/Task") + public ApexAPIResult validateTask(@QueryParam("name") final String name, + @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + ret = sessionApexModel.listTask(name1, version1); + if (ret.isNOK()) { + return ret; + } + + ret = addKeyInfo2Messages(ret); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Validate/Task" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + // CHECKSTYLE:OFF: MethodLength + /** + * Creates a policy with the information in the JSON string passed. + * + * @param jsonString the JSON string to be parsed See {@linkplain BeanPolicy} + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @POST + @Path("Policy/Create") + public ApexAPIResult createPolicy(final String jsonString) { + + ApexAPIResult ret = null; + ApexAPIResult tempres = null; + LOGGER.entry(jsonString); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + final BeanPolicy jsonbean = RestUtils.getJSONParameters(jsonString, BeanPolicy.class); + final String policyname = jsonbean.getName(); + final String policyversion = jsonbean.getVersion(); + + ret = sessionApexModel.createPolicy(policyname, policyversion, jsonbean.getTemplate(), + jsonbean.getFirstState(), jsonbean.getUuid(), jsonbean.getDescription()); + if (ret.isNOK()) { + return ret; + } + + if (jsonbean.getStates() == null || jsonbean.getStates().isEmpty()) { + ret = new ApexAPIResult(RESULT.FAILED, "Null or empty state map; no states defined for policy \"" + + policyname + ":" + policyversion + + "\". The policy was created, but there was an error adding states. The policy has only been partially defined."); + return ret; + } + + final Map<String, BeanState> statemap = jsonbean.getStates(); + // need to create all the states first, before populating them + for (final Map.Entry<String, BeanState> e : statemap.entrySet()) { + final String statename = e.getKey(); + final BeanState state = e.getValue(); + if (state == null) { + ret = new ApexAPIResult(RESULT.FAILED, "Null or invalid state information for state \"" + statename + + "\" for policy \"" + policyname + ":" + policyversion + + "\". The policy was created, but there was an error adding the state. The policy has only been partially defined."); + return ret; + } + if (state.getTrigger() == null) { + ret = new ApexAPIResult(RESULT.FAILED, "Null or invalid state trigger for state \"" + statename + + "\" for policy \"" + policyname + ":" + policyversion + + "\". The policy was created, but there was an error adding the state. The policy has only been partially defined."); + return ret; + } + if (state.getDefaultTask() == null) { + ret = new ApexAPIResult(RESULT.FAILED, "Null or invalid default task for state \"" + statename + + "\" for policy \"" + policyname + ":" + policyversion + + "\". The policy was created, but there was an error adding the state. The policy has only been partially defined."); + return ret; + } + tempres = sessionApexModel.createPolicyState(policyname, policyversion, statename, + state.getTrigger().getName(), state.getTrigger().getVersion(), state.getDefaultTask().getName(), + state.getDefaultTask().getVersion()); + if (tempres.isNOK()) { + ret = tempres; + return ret; + } + } + + for (final Map.Entry<String, BeanState> e : statemap.entrySet()) { + final String statename = e.getKey(); + final BeanState state = e.getValue(); + + final BeanLogic tsl = state.getTaskSelectionLogic(); + if (tsl != null) { + tempres = sessionApexModel.createPolicyStateTaskSelectionLogic(policyname, policyversion, statename, + tsl.getLogicFlavour(), tsl.getLogic()); + if (tempres.isNOK()) { + tempres.addMessage("Failed to add task selection logic for state \"" + statename + "\" for" + + " policy \"" + policyname + ":" + policyversion + + "\". The policy was created, but there was an error adding the task selection logic for " + + "the state. The policy has only been partially defined."); + ret = tempres; + return ret; + } + } + + final BeanKeyRef[] contexts = state.getContexts(); + if (contexts != null) { + for (final BeanKeyRef c : contexts) { + if (c == null) { + ret = new ApexAPIResult(RESULT.FAILED, "Null or invalid context reference \"" + c + "\" for" + + " state \"" + statename + "\" for policy \"" + policyname + ":" + policyversion + + "\". The policy was created, but there was an error adding the context reference for the state." + + " The policy has only been partially defined."); + return ret; + } + tempres = sessionApexModel.createPolicyStateContextRef(policyname, policyversion, statename, + c.getName(), c.getVersion()); + if (tempres.isNOK()) { + tempres.addMessage("Failed to add context reference \"" + c + "\" for state \"" + statename + + "\" for policy \"" + policyname + ":" + policyversion + + "\". The policy was created, but there was an error adding the context reference for the state." + + " The policy has only been partially defined."); + ret = tempres; + return ret; + } + } + } + + final Map<String, BeanLogic> finalizers = state.getFinalizers(); + if (finalizers != null) { + for (final Map.Entry<String, BeanLogic> f : finalizers.entrySet()) { + final String finalizername = f.getKey(); + final BeanLogic finalizer = f.getValue(); + if (finalizername == null || finalizer == null) { + ret = new ApexAPIResult(RESULT.FAILED, + "Null or invalid finalizer information for finalizer " + "named \"" + finalizername + + "\" in state \"" + statename + "\" for policy \"" + policyname + ":" + + policyversion + + "\". The policy and state were created, but there was an error adding the finalizer." + + " The policy has only been partially defined."); + return ret; + } + tempres = sessionApexModel.createPolicyStateFinalizerLogic(policyname, policyversion, statename, + finalizername, finalizer.getLogicFlavour(), finalizer.getLogic()); + if (tempres.isNOK()) { + tempres.addMessage("Failed to add finalizer information for finalizer named \"" + + finalizername + "\" in" + " state \"" + statename + "\" for policy \"" + + policyname + ":" + policyversion + + "\". The policy and state were created, but there was an error adding the finalizer." + + " The policy has only been partially defined."); + ret = tempres; + return ret; + } + } + } + final Map<String, BeanStateOutput> outputs = state.getStateOutputs(); + if (outputs == null || outputs.isEmpty()) { + ret = new ApexAPIResult(RESULT.FAILED, "No state outputs have been defined in state \"" + statename + + "\" for policy \"" + policyname + ":" + policyversion + + "\". The policy and state were created, but there was an error adding state outputs." + + " The policy has only been partially defined."); + return ret; + } + for (final Map.Entry<String, BeanStateOutput> o : outputs.entrySet()) { + final String outputname = o.getKey(); + final BeanStateOutput output = o.getValue(); + if (outputname == null || output == null || output.getEvent() == null) { + ret = new ApexAPIResult(RESULT.FAILED, "Null or invalid output information for output named \"" + + outputname + "\" in state \"" + statename + "\" for policy \"" + policyname + ":" + + policyversion + + "\". The policy and state were created, but there was an error adding the output." + + " The policy has only been partially defined."); + return ret; + } + tempres = sessionApexModel.createPolicyStateOutput(policyname, policyversion, statename, outputname, + output.getEvent().getName(), output.getEvent().getVersion(), output.getNextState()); + if (tempres.isNOK()) { + tempres.addMessage("Failed to add output information for output named \"" + outputname + + "\" in state \"" + statename + "\" for policy \"" + policyname + ":" + policyversion + + "\". The policy and state were created, but there was an error adding the output." + + " The policy has only been partially defined."); + ret = tempres; + return ret; + } + } + + final Map<String, BeanStateTaskRef> taskmap = state.getTasks(); + if (taskmap == null || taskmap.isEmpty()) { + ret = new ApexAPIResult(RESULT.FAILED, + "No tasks have been defined in state \"" + statename + "\" for policy \"" + policyname + ":" + + policyversion + + "\". The policy and state were created, but there was an error adding tasks." + + " The policy has only been partially defined."); + return ret; + } + for (final Map.Entry<String, BeanStateTaskRef> t : taskmap.entrySet()) { + final String tasklocalname = t.getKey(); + final BeanStateTaskRef taskref = t.getValue(); + if (tasklocalname == null || taskref == null || taskref.getTask() == null) { + ret = new ApexAPIResult(RESULT.FAILED, "Null or invalid task information for task named \"" + + tasklocalname + "\" in state \"" + statename + "\" for for policy \"" + policyname + + ":" + policyversion + + "\". The policy and state were created, but there was an error adding the task. " + + "The policy has only been partially defined."); + return ret; + } + tempres = sessionApexModel.createPolicyStateTaskRef(policyname, policyversion, statename, + tasklocalname, taskref.getTask().getName(), taskref.getTask().getVersion(), + taskref.getOutputType(), taskref.getOutputName()); + if (tempres.isNOK()) { + tempres.addMessage("Failed to add task reference \"" + t + "\" for state \"" + statename + + "\" for policy \"" + policyname + ":" + policyversion + + "\". The policy was created, but there was an error adding the task reference for the state." + + " The policy has only been partially defined."); + ret = tempres; + return ret; + } + } + + } + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Policy/Create" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + // CHECKSTYLE:ON: MethodLength + + /** + * Update a policy with the information in the JSON string passed. + * + * @param firstStatePeriodic indicates if periodic event should be created and added to model + * @param jsonString the JSON string to be parsed. See {@linkplain BeanPolicy} + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @PUT + @Path("Policy/Update") + public ApexAPIResult updatePolicy(@QueryParam("firstStatePeriodic") final boolean firstStatePeriodic, + final String jsonString) { + ApexAPIResult ret = null; + LOGGER.entry(jsonString); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + final BeanPolicy jsonbean = RestUtils.getJSONParameters(jsonString, BeanPolicy.class); + + if (jsonbean.getName() == null || jsonbean.getName().equals("") || jsonbean.getVersion() == null + || jsonbean.getVersion().equals("")) { + ret = new ApexAPIResult(RESULT.FAILED, "Null/Empty Policy name/version (\"" + jsonbean.getName() + ":" + + jsonbean.getVersion() + "\" passed to UpdatePolicy"); + return ret; + } + + ret = sessionApexModel.deletePolicy(jsonbean.getName(), jsonbean.getVersion()); + if (ret.isNOK()) { + return ret; + } + if (firstStatePeriodic) { + final ApexAPIResult existingPeriodicEvent = sessionApexModel.listEvent("PeriodicEvent", null); + if (existingPeriodicEvent.isNOK()) { + final String periodicEventString = + "{\"name\":\"PeriodicEvent\",\"version\":\"0.0.1\",\"uuid\":\"44236da1-3d47-4988-8033-b6fee9d6a0f4\",\"description\":\"Generated description for concept referred to by key 'PeriodicEvent:0.0.1'\",\"source\":\"System\",\"target\":\"Apex\",\"nameSpace\":\"org.onap.policy.apex.domains.aadm.events\",\"parameters\":{}}"; + ret = createEvent(periodicEventString); + if (ret.isNOK()) { + return ret; + } + } + } + ret = createPolicy(jsonString); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Policy/Update" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * List policies with the given key names/versions. If successful the result(s) will be available in the result + * messages. The returned value(s) will be similar to {@link AxPolicy}, with merged {@linkplain AxKey Info} for the + * root object. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @GET + @Path("Policy/Get") + public ApexAPIResult listPolicy(@QueryParam("name") final String name, + @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + ret = initialiseSessionForReadOnly(); + if (ret.isNOK()) { + return ret; + } + + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + ret = sessionApexModel.listPolicy(name1, version1); + + if (ret.isNOK()) { + return ret; + } + + ret = addKeyInfo2Messages(ret); + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Policy/Get" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * Delete policies with the given key names/versions. + * + * @param name the name to search for. If null or empty, then all names will be queried + * @param version the version to search for. If null then all versions will be searched for. + * @return an ApexAPIResult object. If successful then {@link ApexAPIResult#isOK()} will return true. Any + * messages/errors can be retrieved using {@link ApexAPIResult#getMessages()} + */ + @DELETE + @Path("Policy/Delete") + public ApexAPIResult deletePolicy(@QueryParam("name") final String name, + @QueryParam("version") final String version) { + ApexAPIResult ret = null; + String name1 = name; + String version1 = version; + LOGGER.entry(name1, version1); + try { + ret = initialiseSessionForChanges(); + if (ret.isNOK()) { + return ret; + } + + if (name1 == null || name1.equals("")) { + name1 = null; + } + if (version1 == null || version1.equals("")) { + version1 = null; + } + + // all input/output fields, parameters, logic, context references is "owned"/contained in the task, so + // deleting the task removes all of these + ret = sessionApexModel.deletePolicy(name1, version1); + if (ret.isOK()) { + commitChanges(); + } + return ret; + } catch (final Exception e) { + LOGGER.catching(e); + throw e; + } finally { + LOGGER.exit((ret == null ? false : ret.isOK())); + LOGGER.info("Policy/Delete" + (ret != null && ret.isOK() ? ": OK" : ": Not OK")); + } + } + + /** + * The json strings representing the objects listed, stored in result.messages[], does not contain the + * AxKeyInformation for that object. This utility method retrieves the AxKeyInfo for each object and adds it to the + * json for the object. + * + * @param result The list result, containing json representations of objects stored in its "messages" array + * @return The list result, containing json augmented representations of objects stored in its "messages" array + */ + private ApexAPIResult addKeyInfo2Messages(final ApexAPIResult result) { + if (result.isNOK()) { + return result; + } + + final ApexAPIResult ret = new ApexAPIResult(result.getResult()); + ret.setMessages(result.getMessages()); + + final List<String> messages = result.getMessages(); + final List<String> augmessages = new ArrayList<>(messages.size()); + final GsonBuilder gb = new GsonBuilder(); + gb.serializeNulls().enableComplexMapKeySerialization(); + final Gson gson = gb.create(); + for (final String message : messages) { + try { + final JsonObject jsonObject = gson.fromJson(message, JsonObject.class); + JsonObject objecttochange = jsonObject; + String name = null; + if (jsonObject != null && jsonObject.get("key") != null && jsonObject.get("key").isJsonObject() + && jsonObject.getAsJsonObject("key").get("name") != null) { + name = jsonObject.getAsJsonObject("key").get("name").getAsString(); + } else if (jsonObject != null && jsonObject.get("policyKey") != null + && jsonObject.get("policyKey").isJsonObject() + && jsonObject.getAsJsonObject("policyKey").get("name") != null) { + name = jsonObject.getAsJsonObject("policyKey").get("name").getAsString(); + } + String version = null; + if (jsonObject != null && jsonObject.get("key") != null && jsonObject.get("key").isJsonObject() + && jsonObject.getAsJsonObject("key").get("version") != null) { + version = jsonObject.getAsJsonObject("key").get("version").getAsString(); + } else if (jsonObject != null && jsonObject.get("policyKey") != null + && jsonObject.get("policyKey").isJsonObject() + && jsonObject.getAsJsonObject("policyKey").get("version") != null) { + version = jsonObject.getAsJsonObject("policyKey").get("version").getAsString(); + } + + if (name == null && version == null && jsonObject.entrySet() != null + && jsonObject.entrySet().size() > 0) { + objecttochange = (JsonObject) jsonObject.entrySet().iterator().next().getValue(); + if (objecttochange != null && objecttochange.get("key") != null + && objecttochange.get("key").isJsonObject() + && objecttochange.getAsJsonObject("key").get("name") != null) { + name = objecttochange.getAsJsonObject("key").get("name").getAsString(); + } else if (objecttochange != null && objecttochange.get("policyKey") != null + && objecttochange.get("policyKey").isJsonObject() + && objecttochange.getAsJsonObject("policyKey").get("name") != null) { + name = objecttochange.getAsJsonObject("policyKey").get("name").getAsString(); + } + if (objecttochange != null && objecttochange.get("key") != null + && objecttochange.get("key").isJsonObject() + && objecttochange.getAsJsonObject("key").get("version") != null) { + version = objecttochange.getAsJsonObject("key").get("version").getAsString(); + } else if (objecttochange != null && objecttochange.get("policyKey") != null + && objecttochange.get("policyKey").isJsonObject() + && objecttochange.getAsJsonObject("policyKey").get("version") != null) { + version = objecttochange.getAsJsonObject("policyKey").get("version").getAsString(); + } + } + + String uuid = null; + String desc = null; + + if (name != null && version != null) { + final ApexAPIResult keyInfoResult = sessionApexModel.listKeyInformation(name, version); + final List<String> keyInfoMessages = keyInfoResult.getMessages(); + if (keyInfoResult.isOK() && keyInfoMessages != null && keyInfoMessages.size() > 0) { + final String keyInfoJson = keyInfoMessages.get(0); + final JsonObject keyInfoJsonObject = gson.fromJson(keyInfoJson, JsonObject.class); + if (keyInfoJsonObject != null && keyInfoJsonObject.get("apexKeyInfo") != null + && keyInfoJsonObject.get("apexKeyInfo").getAsJsonObject().get("UUID") != null) { + uuid = keyInfoJsonObject.get("apexKeyInfo").getAsJsonObject().get("UUID").getAsString(); + } + if (keyInfoJsonObject != null && keyInfoJsonObject.get("apexKeyInfo") != null + && keyInfoJsonObject.get("apexKeyInfo").getAsJsonObject().get("description") != null) { + desc = keyInfoJsonObject.get("apexKeyInfo").getAsJsonObject().get("description") + .getAsString(); + } + } + } + objecttochange.addProperty("uuid", uuid); + objecttochange.addProperty("description", desc); + augmessages.add(gson.toJson(jsonObject)); + } catch (final Exception e) { + augmessages.add(message); + } + } + ret.setMessages(augmessages); + + if (messages.size() != augmessages.size()) { + ret.setResult(RESULT.OTHER_ERROR); + ret.addMessage("Failed to add KeyInfo to all results. Results are not complete"); + } + + return ret; + } + + /* + * This method is used only for testing and is used to cause an exception on calls from unit test to test exception + * handling. + */ + protected static int createCorruptSession() { + final ApexEditorRestResource apexEditorRestResource = new ApexEditorRestResource(); + final ApexAPIResult result = apexEditorRestResource.createSession(); + final int corruptSessionId = new Integer(result.getMessages().get(0)); + + SESSIONMODELMAP.put(corruptSessionId, null); + + return corruptSessionId; + } +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/RestUtils.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/RestUtils.java new file mode 100644 index 000000000..2c5b6e89a --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/RestUtils.java @@ -0,0 +1,190 @@ +/*- + * ============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.client.editor.rest; + +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; + +import java.io.StringReader; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import javax.ws.rs.core.MediaType; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.transform.stream.StreamSource; + +import org.eclipse.persistence.jaxb.MarshallerProperties; +import org.onap.policy.apex.client.editor.rest.bean.BeanBase; +import org.onap.policy.apex.model.basicmodel.concepts.AxConcept; + +/** + * Utilities for handling RESTful communication for Apex. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public abstract class RestUtils { + + /** + * Constructor, block inheritance. + */ + private RestUtils() {} + + /** + * HTTP POST requests can't send nulls so we interpret blanks as nulls. + * + * @param parameter the parameter to convert from blank to null + * @return null if the parameter us blank, otherwise the original parameter + */ + private static String blank2null(final String parameter) { + return (parameter.length() == 0 ? null : parameter); + } + + /** + * HTTP POST requests can't send nulls so we interpret blanks as nulls. + * + * @param val the val + * @return null if the parameter us blank, otherwise the original parameter + */ + private static JsonElement blank2null(final JsonElement val) { + if (val == null) { + return JsonNull.INSTANCE; + } + if (val.isJsonPrimitive() && ((JsonPrimitive) val).isString()) { + final String v = ((JsonPrimitive) val).getAsString(); + if (v == null || v.equals("")) { + return JsonNull.INSTANCE; + } + } + if (val.isJsonArray()) { + final JsonArray arr = val.getAsJsonArray(); + for (int i = 0; i < arr.size(); i++) { + arr.set(i, blank2null(arr.get(i))); + } + } + if (val.isJsonObject()) { + final JsonObject o = val.getAsJsonObject(); + for (final Entry<String, JsonElement> e : o.entrySet()) { + e.setValue(blank2null(e.getValue())); + } + } + return val; + } + + /** + * Apex HTTP PUT requests send simple single level JSON strings, this method reads those strings into a map. + * + * @param jsonString the incoming JSON string + * @return a map of the JSON strings + */ + public static Map<String, String> getJSONParameters(final String jsonString) { + final GsonBuilder gb = new GsonBuilder(); + gb.serializeNulls().enableComplexMapKeySerialization(); + final JsonObject jsonObject = gb.create().fromJson(jsonString, JsonObject.class); + + final Map<String, String> jsonMap = new TreeMap<>(); + for (final Entry<String, JsonElement> jsonEntry : jsonObject.entrySet()) { + jsonMap.put(jsonEntry.getKey(), (jsonEntry.getValue() == JsonNull.INSTANCE ? null + : blank2null(jsonEntry.getValue().getAsString()))); + } + return jsonMap; + } + + /** + * Apex HTTP PUT requests send simple single level JSON strings, this method reads those strings into a map. + * + * @param <CLZ> the generic type + * @param jsonString the incoming JSON string + * @param clz the clz + * @return a map of the JSON strings + */ + public static <CLZ extends BeanBase> CLZ getJSONParameters(final String jsonString, final Class<CLZ> clz) { + final GsonBuilder gb = new GsonBuilder(); + gb.serializeNulls().enableComplexMapKeySerialization(); + final JsonObject jsonObject = gb.create().fromJson(jsonString, JsonObject.class); + + for (final Entry<String, JsonElement> jsonEntry : jsonObject.entrySet()) { + final JsonElement val = jsonEntry.getValue(); + jsonEntry.setValue(blank2null(val)); + } + final CLZ ret = gb.create().fromJson(jsonObject, clz); + return ret; + } + + // Regular expressions for checking input types + private static final String XML_INPUT_TYPE_REGEXP = "^\\s*<\\?xml.*>\\s*"; // (starts with <?xml...> + private static final String JSON_INPUT_TYPE_REGEXP = "^\\s*[\\(\\{\\[][\\s+\\S]*[\\)\\}\\]]"; // starts with some + // kind of bracket [ + // or ( or {, then has + // something, then has + // and has a close + // bracket + + /** + * Gets the concept from JSON. + * + * @param <CLZ> the generic type + * @param jsonString the json string + * @param clz the clz + * @return the concept from JSON + * @throws JAXBException the JAXB exception + */ + public static <CLZ extends AxConcept> CLZ getConceptFromJSON(final String jsonString, final Class<CLZ> clz) + throws JAXBException { + Unmarshaller unmarshaller = null; + final JAXBContext jaxbContext = JAXBContext.newInstance(clz); + unmarshaller = jaxbContext.createUnmarshaller(); + if (jsonString.matches(JSON_INPUT_TYPE_REGEXP)) { + unmarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON); + unmarshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, true); + } else if (jsonString.matches(XML_INPUT_TYPE_REGEXP)) { + unmarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_XML); + } else { + return null; + } + final StreamSource source = new StreamSource(new StringReader(jsonString)); + final JAXBElement<CLZ> rootElement = unmarshaller.unmarshal(source, clz); + final CLZ apexConcept = rootElement.getValue(); + return apexConcept; + + } + + /** + * Gets the JSO nfrom concept. + * + * @param object the object + * @return the JSO nfrom concept + */ + public static String getJSONfromConcept(final Object object) { + final GsonBuilder gb = new GsonBuilder(); + gb.serializeNulls().enableComplexMapKeySerialization(); + final String jsonObject = gb.create().toJson(object); + return jsonObject; + } + +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanBase.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanBase.java new file mode 100644 index 000000000..b2222f827 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanBase.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.client.editor.rest.bean; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +/** + * The base class for Beans. + */ +public abstract class BeanBase { + + /** + * Gets a named field from the bean. + * + * @param field the field name + * @return the value for the field + */ + public String get(final String field) { + // CHECKSTYLE:OFF: MagicNumber + // use getter preferably + for (final Method method : this.getClass().getMethods()) { + if ((method.getName().startsWith("get")) && (method.getName().length() == (field.length() + 3))) { + if (method.getName().toLowerCase().endsWith(field.toLowerCase())) { + try { + return (String) method.invoke(this); + } catch (final Exception e) { + throw new IllegalArgumentException( + "Problem retrieving field called ('" + field + "') from JSON bean " + this, e); + } + } + } + } + // Use field approach + if (field != null) { + try { + final Field f = this.getClass().getDeclaredField(field); + if (f != null) { + f.setAccessible(true); + return (String) (f.get(this)); + } + } catch (final Exception e) { + throw new IllegalArgumentException( + "Problem retrieving field called ('" + field + "') from JSON bean " + this, e); + } + } + throw new IllegalArgumentException("Problem retrieving field called ('" + field + "') from JSON bean " + this); + } +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanContextAlbum.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanContextAlbum.java new file mode 100644 index 000000000..848665a0f --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanContextAlbum.java @@ -0,0 +1,109 @@ +/*- + * ============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.client.editor.rest.bean; + +import javax.xml.bind.annotation.XmlType; + +/** + * The ContextAlbum Bean. + */ +@XmlType +public class BeanContextAlbum extends BeanBase { + + private String name = null, version = null, scope = null, uuid = null, description = null; + private BeanKeyRef itemSchema = null; + private boolean writeable; + + /** + * Gets the name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * Gets the version. + * + * @return the version + */ + public String getVersion() { + return version; + } + + /** + * Gets the scope. + * + * @return the scope + */ + public String getScope() { + return scope; + } + + /** + * Gets the uuid. + * + * @return the uuid + */ + public String getUuid() { + return uuid; + } + + /** + * Gets the description. + * + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * Gets the item schema. + * + * @return the item schema + */ + public BeanKeyRef getItemSchema() { + return itemSchema; + } + + /** + * Gets the writeable. + * + * @return the writeable + */ + public boolean getWriteable() { + return writeable; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "ContextAlbum [name=" + name + ", version=" + version + ", scope=" + scope + ", uuid=" + uuid + + ", description=" + description + ", itemSchema=" + itemSchema + ", writeable=" + writeable + "]"; + } + +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanContextSchema.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanContextSchema.java new file mode 100644 index 000000000..0d86c2791 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanContextSchema.java @@ -0,0 +1,98 @@ +/*- + * ============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.client.editor.rest.bean; + +import javax.xml.bind.annotation.XmlType; + +/** + * The ContextSchema Bean. + */ +@XmlType +public class BeanContextSchema extends BeanBase { + + private String name = null, version = null, schemaFlavour = null, schemaDefinition = null, uuid = null, + description = null; + + /** + * Gets the name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * Gets the version. + * + * @return the version + */ + public String getVersion() { + return version; + } + + /** + * Gets the uuid. + * + * @return the uuid + */ + public String getUuid() { + return uuid; + } + + /** + * Gets the description. + * + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * Gets the schema flavour. + * + * @return the schema flavour + */ + public String getSchemaFlavour() { + return schemaFlavour; + } + + /** + * Gets the schema definition. + * + * @return the schema definition + */ + public String getSchemaDefinition() { + return schemaDefinition; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "ContextSchema [name=" + name + ", version=" + version + ", schemaFlavour=" + schemaFlavour + + ", schemaDefinition=" + schemaDefinition + ", uuid=" + uuid + ", description=" + description + "]"; + } +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanEvent.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanEvent.java new file mode 100644 index 000000000..8b7c6bce2 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanEvent.java @@ -0,0 +1,134 @@ +/*- + * ============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.client.editor.rest.bean; + +import java.util.Map; + +import javax.xml.bind.annotation.XmlType; + +/** + * The Event Bean. + */ +@XmlType +public class BeanEvent extends BeanBase { + + private String name = null, version = null, nameSpace = null, source = null, target = null, uuid = null, + description = null; + private Map<String, BeanField> parameters = null; + + /** + * 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 uuid. + * + * @return the uuid + */ + public String getUuid() { + return uuid; + } + + /** + * Gets the description. + * + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * Gets the parameters. + * + * @return the parameters + */ + public Map<String, BeanField> getParameters() { + return parameters; + } + + /** + * Gets the parameter. + * + * @param p the p + * @return the parameter + */ + public BeanField getParameter(final String p) { + if (parameters != null) { + return parameters.get(p); + } + return null; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "Event [name=" + name + ", version=" + version + ", nameSpace=" + nameSpace + ", source=" + source + + ", target=" + target + ", uuid=" + uuid + ", description=" + description + ", parameters=" + + getParameters() + "]"; + } + +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanField.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanField.java new file mode 100644 index 000000000..d606c4d8d --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanField.java @@ -0,0 +1,63 @@ +/*- + * ============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.client.editor.rest.bean; + +import javax.xml.bind.annotation.XmlType; + +/** + * The Field Bean. + */ +@XmlType +public class BeanField extends BeanKeyRef { + + private boolean optional = true; + private String localName = null; + + /** + * Gets the local name for this field. + * + * @return the local name for this field. + */ + public String getLocalName() { + return localName; + } + + /** + * Gets the optional flag. + * + * @return the optional flag + */ + public boolean getOptional() { + return optional; + } + + /* + * (non-Javadoc) + * + * @see org.onap.policy.apex.client.editor.rest.bean.Bean_KeyRef#toString() + */ + @Override + public String toString() { + return "Field [localName=" + getLocalName() + ", name=" + getName() + ", version=" + getVersion() + + ", optional=" + getOptional() + "]"; + } + +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanKeyRef.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanKeyRef.java new file mode 100644 index 000000000..a498b9467 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanKeyRef.java @@ -0,0 +1,61 @@ +/*- + * ============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.client.editor.rest.bean; + +import javax.xml.bind.annotation.XmlType; + +/** + * The Key Reference Bean. + */ +@XmlType +public class BeanKeyRef extends BeanBase { + + private String name = null, version = null; + + /** + * Gets the name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * Gets the version. + * + * @return the version + */ + public String getVersion() { + return version; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "KeyRef [name=" + name + ", version=" + version + "]"; + } + +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanLogic.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanLogic.java new file mode 100644 index 000000000..48fba16a8 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanLogic.java @@ -0,0 +1,61 @@ +/*- + * ============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.client.editor.rest.bean; + +import javax.xml.bind.annotation.XmlType; + +/** + * The Logic Bean. + */ +@XmlType +public class BeanLogic extends BeanBase { + + private String logic = null, logicFlavour = null; + + /** + * Gets the logic flavour. + * + * @return the logic flavour + */ + public String getLogicFlavour() { + return logicFlavour; + } + + /** + * Gets the logic. + * + * @return the logic + */ + public String getLogic() { + return logic; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "Logic [logicFlavour=" + logicFlavour + ", logic=" + logic + "]"; + } + +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanModel.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanModel.java new file mode 100644 index 000000000..3170ea303 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanModel.java @@ -0,0 +1,79 @@ +/*- + * ============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.client.editor.rest.bean; + +import javax.xml.bind.annotation.XmlType; + +/** + * The Model Bean. + */ +@XmlType +public class BeanModel extends BeanBase { + + private String name = null, version = null, uuid = null, description = null; + + /** + * Gets the name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * Gets the version. + * + * @return the version + */ + public String getVersion() { + return version; + } + + /** + * Gets the uuid. + * + * @return the uuid + */ + public String getUuid() { + return uuid; + } + + /** + * Gets the description. + * + * @return the description + */ + public String getDescription() { + return description; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "Model [name=" + name + ", version=" + version + ", uuid=" + uuid + ", description=" + description + "]"; + } + +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanPolicy.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanPolicy.java new file mode 100644 index 000000000..bdbfb6dea --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanPolicy.java @@ -0,0 +1,110 @@ +/*- + * ============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.client.editor.rest.bean; + +import java.util.Map; + +import javax.xml.bind.annotation.XmlType; + +/** + * The Policy Bean. + */ +@XmlType +public class BeanPolicy extends BeanBase { + + private String name = null, version = null, uuid = null, description = null, firstState = null, template = null; + private Map<String, BeanState> states = null; + + /** + * Gets the name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * Gets the version. + * + * @return the version + */ + public String getVersion() { + return version; + } + + /** + * Gets the uuid. + * + * @return the uuid + */ + public String getUuid() { + return uuid; + } + + /** + * Gets the description. + * + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * Gets the first state. + * + * @return the first state + */ + public String getFirstState() { + return firstState; + } + + /** + * Gets the template. + * + * @return the template + */ + public String getTemplate() { + return template; + } + + /** + * Gets the states. + * + * @return the states + */ + public Map<String, BeanState> getStates() { + return states; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "Policy [name=" + name + ", version=" + version + ", uuid=" + uuid + ", description=" + description + + ", firstState=" + firstState + ", template=" + template + ", states=" + states + "]"; + } + +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanState.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanState.java new file mode 100644 index 000000000..f404d79a4 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanState.java @@ -0,0 +1,136 @@ +/*- + * ============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.client.editor.rest.bean; + +import java.util.Arrays; +import java.util.Map; + +import javax.xml.bind.annotation.XmlType; + +/** + * The State Bean. + */ +@XmlType +public class BeanState extends BeanBase { + + private String name = null; + private BeanKeyRef trigger = null; + private BeanKeyRef defaultTask = null; + private BeanKeyRef[] contexts = null; + private BeanLogic taskSelectionLogic = null; + private Map<String, BeanStateTaskRef> tasks = null; + private Map<String, BeanLogic> finalizers = null; + private Map<String, BeanStateOutput> stateOutputs = null; + + /** + * Gets the name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * Gets the trigger. + * + * @return the trigger + */ + public BeanKeyRef getTrigger() { + return trigger; + } + + /** + * Gets the contexts. + * + * @return the contexts + */ + public BeanKeyRef[] getContexts() { + return contexts; + } + + /** + * Gets the task selection logic. + * + * @return the task selection logic + */ + public BeanLogic getTaskSelectionLogic() { + return taskSelectionLogic; + } + + /** + * Gets the tasks. + * + * @return the tasks + */ + public Map<String, BeanStateTaskRef> getTasks() { + return tasks; + } + + /** + * Gets the finalizers. + * + * @return the finalizers + */ + public Map<String, BeanLogic> getFinalizers() { + return finalizers; + } + + /** + * Gets the state outputs. + * + * @return the state outputs + */ + public Map<String, BeanStateOutput> getStateOutputs() { + return stateOutputs; + } + + /** + * Gets the default task. + * + * @return the default task + */ + public BeanKeyRef getDefaultTask() { + return defaultTask; + } + + /** + * Sets the default task. + * + * @param defaultTask the new default task + */ + public void setDefaultTask(final BeanKeyRef defaultTask) { + this.defaultTask = defaultTask; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "State [name=" + name + ", trigger=" + trigger + ", defaultTask=" + defaultTask + ", contexts=" + + Arrays.toString(contexts) + ", taskSelectionLogic=" + taskSelectionLogic + ", tasks=" + tasks + + ", finalizers=" + finalizers + ", stateOutputs=" + stateOutputs + "]"; + } + +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanStateOutput.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanStateOutput.java new file mode 100644 index 000000000..f29f7d322 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanStateOutput.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.client.editor.rest.bean; + +import javax.xml.bind.annotation.XmlType; + +/** + * The StateOutput Bean. + */ +@XmlType +public class BeanStateOutput extends BeanBase { + + private BeanKeyRef event = null; + private String nextState = null; + + /** + * Gets the event. + * + * @return the event + */ + public BeanKeyRef getEvent() { + return event; + } + + /** + * Gets the next state. + * + * @return the next state + */ + public String getNextState() { + return nextState; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "StateOutput [event=" + event + ", nextState=" + nextState + "]"; + } + +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanStateTaskRef.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanStateTaskRef.java new file mode 100644 index 000000000..9d446e7c7 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanStateTaskRef.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.client.editor.rest.bean; + +import javax.xml.bind.annotation.XmlType; + +/** + * The State Task Reference Bean. + */ +@XmlType +public class BeanStateTaskRef extends BeanBase { + + private BeanKeyRef task = null; + private String outputType = null, outputName = null; + + /** + * Gets the task. + * + * @return the task + */ + public BeanKeyRef getTask() { + return task; + } + + /** + * Gets the output type. + * + * @return the output type + */ + public String getOutputType() { + return outputType; + } + + /** + * Gets the output name. + * + * @return the output name + */ + public String getOutputName() { + return outputName; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "StateTaskRef [task=" + task + ", outputType=" + outputType + ", outputName=" + outputName + "]"; + } + +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanTask.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanTask.java new file mode 100644 index 000000000..0df810caf --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanTask.java @@ -0,0 +1,133 @@ +/*- + * ============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.client.editor.rest.bean; + +import java.util.Arrays; +import java.util.Map; + +import javax.xml.bind.annotation.XmlType; + +/** + * The Task Bean. + */ +@XmlType +public class BeanTask extends BeanBase { + + private String name = null, version = null, uuid = null, description = null; + private BeanLogic taskLogic = null; + private Map<String, BeanField> inputFields = null; + private Map<String, BeanField> outputFields = null; + private Map<String, BeanTaskParameter> parameters = null; + private BeanKeyRef[] contexts = null; + + /** + * Gets the name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * Gets the version. + * + * @return the version + */ + public String getVersion() { + return version; + } + + /** + * Gets the uuid. + * + * @return the uuid + */ + public String getUuid() { + return uuid; + } + + /** + * Gets the description. + * + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * Gets the task logic. + * + * @return the task logic + */ + public BeanLogic getTaskLogic() { + return taskLogic; + } + + /** + * Gets the input fields. + * + * @return the input fields + */ + public Map<String, BeanField> getInputFields() { + return inputFields; + } + + /** + * Gets the output fields. + * + * @return the output fields + */ + public Map<String, BeanField> getOutputFields() { + return outputFields; + } + + /** + * Gets the parameters. + * + * @return the parameters + */ + public Map<String, BeanTaskParameter> getParameters() { + return parameters; + } + + /** + * Gets the contexts. + * + * @return the contexts + */ + public BeanKeyRef[] getContexts() { + return contexts; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "BeanTask [name=" + name + ", version=" + version + ", uuid=" + uuid + ", description=" + description + + ", taskLogic=" + taskLogic + ", inputFields=" + inputFields + ", outputFields=" + outputFields + + ", parameters=" + parameters + ", contexts=" + Arrays.toString(contexts) + "]"; + } +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanTaskParameter.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanTaskParameter.java new file mode 100644 index 000000000..2de1c7a28 --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/BeanTaskParameter.java @@ -0,0 +1,61 @@ +/*- + * ============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.client.editor.rest.bean; + +import javax.xml.bind.annotation.XmlType; + +/** + * The Task Parameter Bean. + */ +@XmlType +public class BeanTaskParameter extends BeanBase { + + private String parameterName = null, defaultValue = null; + + /** + * Gets the parameter name. + * + * @return the parameter name + */ + public String getParameterName() { + return parameterName; + } + + /** + * Gets the default value. + * + * @return the default value + */ + public String getDefaultValue() { + return defaultValue; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "TaskParameter [parameterName=" + parameterName + ", defaultValue=" + defaultValue + "]"; + } + +} diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/package-info.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/package-info.java new file mode 100644 index 000000000..0c286afba --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/bean/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 JSON/XML serializable beans for use with the REST interface. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ + +package org.onap.policy.apex.client.editor.rest.bean; diff --git a/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/package-info.java b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/package-info.java new file mode 100644 index 000000000..e9bf636cf --- /dev/null +++ b/client/client-editor/src/main/java/org/onap/policy/apex/client/editor/rest/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 the RESTful editor for Apex. It implements a RESTful service towards the + * {@link org.onap.policy.apex.model.modelapi.ApexEditorAPI} Java interface for use by clients over REST. It also + * provides a web-based client written in Javascript. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ + +package org.onap.policy.apex.client.editor.rest; |