aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSébastien Determe <sebastien.determe@intl.att.com>2019-03-29 08:47:17 +0000
committerGerrit Code Review <gerrit@onap.org>2019-03-29 08:47:17 +0000
commit911167cc45c8d6fdab59674e67a8373e894c2979 (patch)
tree5e92106f94a49bbae296c7df6d2bbc729f6bcab8
parente10910d9070a80e47e81a6cd7c350a627080b6a2 (diff)
parent937c480aac2d675e70c94908febddb42aefc8dcc (diff)
Merge "Rework the deploy/undeploy method"
-rw-r--r--src/main/java/org/onap/clamp/clds/util/LoggingUtils.java31
-rw-r--r--src/main/java/org/onap/clamp/exception/OperationException.java61
-rw-r--r--src/main/java/org/onap/clamp/loop/Loop.java12
-rw-r--r--src/main/java/org/onap/clamp/loop/LoopService.java4
-rw-r--r--src/main/java/org/onap/clamp/operation/LoopOperation.java212
-rw-r--r--src/main/resources/clds/camel/rest/clamp-api-v2.xml38
6 files changed, 340 insertions, 18 deletions
diff --git a/src/main/java/org/onap/clamp/clds/util/LoggingUtils.java b/src/main/java/org/onap/clamp/clds/util/LoggingUtils.java
index 300d6066..47b4f9ab 100644
--- a/src/main/java/org/onap/clamp/clds/util/LoggingUtils.java
+++ b/src/main/java/org/onap/clamp/clds/util/LoggingUtils.java
@@ -38,6 +38,7 @@ import java.util.Date;
import java.util.TimeZone;
import java.util.UUID;
+import javax.net.ssl.HttpsURLConnection;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
@@ -259,6 +260,36 @@ public class LoggingUtils {
this.mLogger.info(ONAPLogConstants.Markers.INVOKE_SYNC + "{"+ invocationID +"}");
return con;
}
+
+ /**
+ * Report pending invocation with <tt>INVOKE</tt> marker,
+ * setting standard ONAP logging headers automatically.
+ *
+ * @param builder request builder, for setting headers.
+ * @param sync whether synchronous, nullable.
+ * @return invocation ID to be passed with invocation.
+ */
+ public HttpsURLConnection invokeHttps(final HttpsURLConnection con, String targetEntity, String targetServiceName) {
+ final String invocationID = UUID.randomUUID().toString();
+
+ // Set standard HTTP headers on (southbound request) builder.
+ con.setRequestProperty(ONAPLogConstants.Headers.REQUEST_ID,
+ defaultToEmpty(MDC.get(ONAPLogConstants.MDCs.REQUEST_ID)));
+ con.setRequestProperty(ONAPLogConstants.Headers.INVOCATION_ID,
+ invocationID);
+ con.setRequestProperty(ONAPLogConstants.Headers.PARTNER_NAME,
+ defaultToEmpty(MDC.get(ONAPLogConstants.MDCs.PARTNER_NAME)));
+
+ invokeContext(targetEntity, targetServiceName, invocationID);
+
+ // Log INVOKE*, with the invocationID as the message body.
+ // (We didn't really want this kind of behavior in the standard,
+ // but is it worse than new, single-message MDC?)
+ this.mLogger.info(ONAPLogConstants.Markers.INVOKE);
+ this.mLogger.info(ONAPLogConstants.Markers.INVOKE_SYNC + "{"+ invocationID +"}");
+ return con;
+ }
+
public void invokeReturn() {
// Add the Invoke-return marker and clear the needed MDC
this.mLogger.info(ONAPLogConstants.Markers.INVOKE_RETURN);
diff --git a/src/main/java/org/onap/clamp/exception/OperationException.java b/src/main/java/org/onap/clamp/exception/OperationException.java
new file mode 100644
index 00000000..0233b092
--- /dev/null
+++ b/src/main/java/org/onap/clamp/exception/OperationException.java
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.exception;
+
+/**
+ * New exception to CldsUser errors.
+ *
+ */
+public class OperationException extends RuntimeException {
+
+ /**
+ * The serial version ID.
+ */
+ private static final long serialVersionUID = 2788967876393519620L;
+
+ /**
+ * This constructor can be used to create a new CldsUsersException.
+ *
+ * @param message
+ * A string message detailing the problem
+ * @param e
+ * The exception sent by the code
+ */
+ public OperationException(String message, Throwable e) {
+ super(message, e);
+ }
+
+ /**
+ * This constructor can be used to create a new CldsUsersException. Use this
+ * constructor only if you are creating a new exception stack, not if an
+ * exception was already raised by another code.
+ *
+ * @param message
+ * A string message detailing the problem
+ */
+ public OperationException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/main/java/org/onap/clamp/loop/Loop.java b/src/main/java/org/onap/clamp/loop/Loop.java
index 64e0108e..6dc73e98 100644
--- a/src/main/java/org/onap/clamp/loop/Loop.java
+++ b/src/main/java/org/onap/clamp/loop/Loop.java
@@ -139,7 +139,7 @@ public class Loop implements Serializable {
return dcaeDeploymentId;
}
- void setDcaeDeploymentId(String dcaeDeploymentId) {
+ public void setDcaeDeploymentId(String dcaeDeploymentId) {
this.dcaeDeploymentId = dcaeDeploymentId;
}
@@ -147,7 +147,7 @@ public class Loop implements Serializable {
return dcaeDeploymentStatusUrl;
}
- void setDcaeDeploymentStatusUrl(String dcaeDeploymentStatusUrl) {
+ public void setDcaeDeploymentStatusUrl(String dcaeDeploymentStatusUrl) {
this.dcaeDeploymentStatusUrl = dcaeDeploymentStatusUrl;
}
@@ -167,11 +167,11 @@ public class Loop implements Serializable {
this.blueprint = blueprint;
}
- LoopState getLastComputedState() {
+ public LoopState getLastComputedState() {
return lastComputedState;
}
- void setLastComputedState(LoopState lastComputedState) {
+ public void setLastComputedState(LoopState lastComputedState) {
this.lastComputedState = lastComputedState;
}
@@ -222,7 +222,7 @@ public class Loop implements Serializable {
log.setLoop(this);
}
- String getDcaeBlueprintId() {
+ public String getDcaeBlueprintId() {
return dcaeBlueprintId;
}
@@ -230,7 +230,7 @@ public class Loop implements Serializable {
this.dcaeBlueprintId = dcaeBlueprintId;
}
- JsonObject getModelPropertiesJson() {
+ public JsonObject getModelPropertiesJson() {
return modelPropertiesJson;
}
diff --git a/src/main/java/org/onap/clamp/loop/LoopService.java b/src/main/java/org/onap/clamp/loop/LoopService.java
index b4995734..34e1b4be 100644
--- a/src/main/java/org/onap/clamp/loop/LoopService.java
+++ b/src/main/java/org/onap/clamp/loop/LoopService.java
@@ -54,7 +54,7 @@ public class LoopService {
this.operationalPolicyService = operationalPolicyService;
}
- Loop saveOrUpdateLoop(Loop loop) {
+ public Loop saveOrUpdateLoop(Loop loop) {
return loopsRepository.save(loop);
}
@@ -62,7 +62,7 @@ public class LoopService {
return loopsRepository.getAllLoopNames();
}
- Loop getLoop(String loopName) {
+ public Loop getLoop(String loopName) {
return loopsRepository
.findById(loopName)
.orElse(null);
diff --git a/src/main/java/org/onap/clamp/operation/LoopOperation.java b/src/main/java/org/onap/clamp/operation/LoopOperation.java
new file mode 100644
index 00000000..af615af1
--- /dev/null
+++ b/src/main/java/org/onap/clamp/operation/LoopOperation.java
@@ -0,0 +1,212 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights
+ * reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ *
+ */
+
+package org.onap.clamp.operation;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+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.lang.reflect.Array;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.camel.Exchange;
+import org.onap.clamp.clds.client.DcaeDispatcherServices;
+import org.onap.clamp.clds.util.LoggingUtils;
+import org.onap.clamp.clds.util.ONAPLogConstants;
+import org.onap.clamp.exception.OperationException;
+import org.onap.clamp.loop.Loop;
+import org.onap.clamp.loop.LoopService;
+import org.onap.clamp.loop.LoopState;
+import org.slf4j.event.Level;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+import org.yaml.snakeyaml.Yaml;
+
+/**
+ * Closed loop operations
+ */
+@Component
+public class LoopOperation {
+
+ protected static final EELFLogger logger = EELFManager.getInstance().getLogger(LoopOperation.class);
+ protected static final EELFLogger auditLogger = EELFManager.getInstance().getMetricsLogger();
+ private final DcaeDispatcherServices dcaeDispatcherServices;
+ private final LoopService loopService;
+ private LoggingUtils util = new LoggingUtils(logger);
+
+ @Autowired
+ private HttpServletRequest request;
+
+ @Autowired
+ public LoopOperation(LoopService loopService, DcaeDispatcherServices dcaeDispatcherServices) {
+ this.loopService = loopService;
+ this.dcaeDispatcherServices = dcaeDispatcherServices;
+ }
+
+ /**
+ * Deploy the closed loop.
+ *
+ * @param loopName the loop name
+ * @return the updated loop
+ * @throws Exceptions during the operation
+ */
+ public Loop deployLoop(Exchange camelExchange, String loopName) throws OperationException {
+ util.entering(request, "CldsService: Deploy model");
+ Date startTime = new Date();
+ Loop loop = loopService.getLoop(loopName);
+
+ if (loop == null) {
+ String msg = "Deploy loop exception: Not able to find closed loop:" + loopName;
+ util.exiting(HttpStatus.INTERNAL_SERVER_ERROR.toString(), msg, Level.INFO,
+ ONAPLogConstants.ResponseStatus.ERROR);
+ throw new OperationException(msg);
+ }
+
+ // verify the current closed loop state
+ if (loop.getLastComputedState() != LoopState.SUBMITTED) {
+ String msg = "Deploy loop exception: This closed loop is in state:" + loop.getLastComputedState()
+ + ". It could be deployed only when it is in SUBMITTED state.";
+ util.exiting(HttpStatus.CONFLICT.toString(), msg, Level.INFO,
+ ONAPLogConstants.ResponseStatus.ERROR);
+ throw new OperationException(msg);
+ }
+
+ // Set the deploymentId if not present yet
+ String deploymentId = "";
+ // If model is already deployed then pass same deployment id
+ if (loop.getDcaeDeploymentId() != null && !loop.getDcaeDeploymentId().isEmpty()) {
+ deploymentId = loop.getDcaeDeploymentId();
+ } else {
+ loop.setDcaeDeploymentId(deploymentId = "closedLoop_" + loopName + "_deploymentId");
+ }
+
+ Yaml yaml = new Yaml();
+ Map<String, Object> yamlMap = yaml.load(loop.getBlueprint());
+ JsonObject bluePrint = wrapSnakeObject(yamlMap).getAsJsonObject();
+
+ loop.setDcaeDeploymentStatusUrl(dcaeDispatcherServices.createNewDeployment(deploymentId, loop.getDcaeBlueprintId(), bluePrint));
+ loop.setLastComputedState(LoopState.DEPLOYED);
+ // save the updated loop
+ loopService.saveOrUpdateLoop (loop);
+
+ // audit log
+ LoggingUtils.setTimeContext(startTime, new Date());
+ auditLogger.info("Deploy model completed");
+ util.exiting(HttpStatus.OK.toString(), "Successful", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED);
+ return loop;
+ }
+
+ /**
+ * Un deploy closed loop.
+ *
+ * @param loopName the loop name
+ * @return the updated loop
+ */
+ public Loop unDeployLoop(String loopName) throws OperationException {
+ util.entering(request, "LoopOperation: Undeploy the closed loop");
+ Date startTime = new Date();
+ Loop loop = loopService.getLoop(loopName);
+
+ if (loop == null) {
+ String msg = "Undeploy loop exception: Not able to find closed loop:" + loopName;
+ util.exiting(HttpStatus.INTERNAL_SERVER_ERROR.toString(), msg, Level.INFO,
+ ONAPLogConstants.ResponseStatus.ERROR);
+ throw new OperationException(msg);
+ }
+
+ // verify the current closed loop state
+ if (loop.getLastComputedState() != LoopState.DEPLOYED) {
+ String msg = "Unploy loop exception: This closed loop is in state:" + loop.getLastComputedState()
+ + ". It could be undeployed only when it is in DEPLOYED state.";
+ util.exiting(HttpStatus.CONFLICT.toString(), msg, Level.INFO,
+ ONAPLogConstants.ResponseStatus.ERROR);
+ throw new OperationException(msg);
+ }
+
+ loop.setDcaeDeploymentStatusUrl(
+ dcaeDispatcherServices.deleteExistingDeployment(loop.getDcaeDeploymentId(), loop.getDcaeBlueprintId()));
+
+ // clean the deployment ID
+ loop.setDcaeDeploymentId(null);
+ loop.setLastComputedState(LoopState.SUBMITTED);
+
+ // save the updated loop
+ loopService.saveOrUpdateLoop (loop);
+
+ // audit log
+ LoggingUtils.setTimeContext(startTime, new Date());
+ auditLogger.info("Undeploy model completed");
+ util.exiting(HttpStatus.OK.toString(), "Successful", Level.INFO, ONAPLogConstants.ResponseStatus.COMPLETED);
+ return loop;
+ }
+
+ private JsonElement wrapSnakeObject(Object o) {
+ //NULL => JsonNull
+ if (o == null)
+ return JsonNull.INSTANCE;
+
+ // Collection => JsonArray
+ if (o instanceof Collection) {
+ JsonArray array = new JsonArray();
+ for (Object childObj : (Collection<?>)o)
+ array.add(wrapSnakeObject(childObj));
+ return array;
+ }
+
+ // Array => JsonArray
+ if (o.getClass().isArray()) {
+ JsonArray array = new JsonArray();
+
+ int length = Array.getLength(array);
+ for (int i=0; i<length; i++)
+ array.add(wrapSnakeObject(Array.get(array, i)));
+ return array;
+ }
+
+ // Map => JsonObject
+ if (o instanceof Map) {
+ Map<?, ?> map = (Map<?, ?>)o;
+
+ JsonObject jsonObject = new JsonObject();
+ for (final Map.Entry<?, ?> entry : map.entrySet()) {
+ final String name = String.valueOf(entry.getKey());
+ final Object value = entry.getValue();
+ jsonObject.add(name, wrapSnakeObject(value));
+ }
+ return jsonObject;
+ }
+
+ // otherwise take it as a string
+ return new JsonPrimitive(String.valueOf(o));
+ }
+}
diff --git a/src/main/resources/clds/camel/rest/clamp-api-v2.xml b/src/main/resources/clds/camel/rest/clamp-api-v2.xml
index d4872ef4..c5828b28 100644
--- a/src/main/resources/clds/camel/rest/clamp-api-v2.xml
+++ b/src/main/resources/clds/camel/rest/clamp-api-v2.xml
@@ -10,7 +10,6 @@
</get>
<get uri="/v2/loop/{loopName}"
outType="org.onap.clamp.loop.Loop"
-
produces="application/json">
<route>
<to uri="bean:org.onap.clamp.authorization.AuthorizationController?method=authorize(*,'cl','','read')" />
@@ -19,19 +18,22 @@
</get>
<get uri="/v2/loop/svgRepresentation/{loopName}"
outType="java.lang.String"
-
produces="application/xml">
- <to
- uri="bean:org.onap.clamp.loop.LoopController?method=getSVGRepresentation(${header.loopName})" />
+ <route>
+ <to uri="bean:org.onap.clamp.authorization.AuthorizationController?method=authorize(*,'cl','','read')" />
+ <to uri="bean:org.onap.clamp.loop.LoopController?method=getSVGRepresentation(${header.loopName})" />
+ </route>
</get>
<post uri="/v2/loop/updateGlobalProperties/{loopName}"
- type="com.google.gson.JsonObject"
- consumes="application/json"
- outType="org.onap.clamp.loop.Loop"
- produces="application/json">
- <to
- uri="bean:org.onap.clamp.loop.LoopController?method=updateGlobalPropertiesJson(${header.loopName},${body})" />
+ type="com.google.gson.JsonObject"
+ consumes="application/json"
+ outType="org.onap.clamp.loop.Loop"
+ produces="application/json">
+ <route>
+ <to uri="bean:org.onap.clamp.authorization.AuthorizationController?method=authorize(*,'cl','','update')" />
+ <to uri="bean:org.onap.clamp.loop.LoopController?method=updateGlobalPropertiesJson(${header.loopName},${body})" />
+ </route>
</post>
<post uri="/v2/loop/updateOperationalPolicies/{loopName}"
type="com.google.gson.JsonArray"
@@ -53,6 +55,22 @@
<to uri="bean:org.onap.clamp.loop.LoopController?method=updateMicroservicePolicy(${header.loopName},${body})" />
</route>
</post>
+ <put uri="/v2/loop/deployLoop/{loopName}"
+ outType="org.onap.clamp.loop.Loop"
+ produces="application/json">
+ <route>
+ <to uri="bean:org.onap.clamp.authorization.AuthorizationController?method=authorize(*,'cl','','update')" />
+ <to uri="bean:org.onap.clamp.operation.LoopOperation?method=deployLoop(*,${header.loopName})" />
+ </route>
+ </put>
+ <put uri="/v2/loop/undeployLoop/{loopName}"
+ outType="org.onap.clamp.loop.Loop"
+ produces="application/json">
+ <route>
+ <to uri="bean:org.onap.clamp.authorization.AuthorizationController?method=authorize(*,'cl','','update')" />
+ <to uri="bean:org.onap.clamp.operation.LoopOperation?method=unDeployLoop(${header.loopName})" />
+ </route>
+ </put>
</rest>
</rests>