summaryrefslogtreecommitdiffstats
path: root/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation
diff options
context:
space:
mode:
Diffstat (limited to 'appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation')
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/IProviderOperation.java61
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/ProviderOperationFactory.java119
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Constants.java58
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Property.java36
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Operation.java93
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Outcome.java38
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/CreateSnapshot.java291
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/EvacuateServer.java378
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/LookupServer.java124
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/MigrateServer.java284
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RebuildServer.java503
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestartServer.java320
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestoreStack.java152
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/SnapshotStack.java237
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StartServer.java186
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StopServer.java198
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateServer.java248
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateStack.java128
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/VmStatuschecker.java160
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderOperation.java457
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderServerOperation.java573
-rw-r--r--appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderStackOperation.java186
22 files changed, 4830 insertions, 0 deletions
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/IProviderOperation.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/IProviderOperation.java
new file mode 100644
index 000000000..0bdc7669f
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/IProviderOperation.java
@@ -0,0 +1,61 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.api;
+
+import org.openecomp.appc.adapter.iaas.impl.ProviderCache;
+import org.openecomp.appc.exceptions.APPCException;
+import com.att.cdp.zones.model.ModelObject;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+
+import java.util.Map;
+
+/**
+ * @since September 26, 2016
+ */
+public interface IProviderOperation {
+
+ /**
+ * perform specific provider operation
+ * @param params
+ * @param context
+ * @return Object represents Stack, Server Or Image
+ */
+ ModelObject doOperation(Map<String,String> params, SvcLogicContext context) throws APPCException;
+
+ /**
+ * sets a cache of providers that are predefined.
+ * @param providerCache
+ */
+ void setProviderCache(Map<String /* provider name */, ProviderCache> providerCache);
+
+ /**
+ * should be initialized by user
+ * @param defaultUser
+ */
+ void setDefaultUser(String defaultUser);
+
+ /**
+ * should be initialized by user
+ * @param defaultPass
+ */
+ void setDefaultPass(String defaultPass);
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/ProviderOperationFactory.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/ProviderOperationFactory.java
new file mode 100644
index 000000000..dd604a555
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/api/ProviderOperationFactory.java
@@ -0,0 +1,119 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.api;
+
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.*;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation;
+import org.openecomp.appc.exceptions.APPCException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Singleton factory of provider operations objects with cache
+ * @since September 26, 2016
+ */
+public class ProviderOperationFactory {
+
+ /**
+ * holds instance of the class
+ */
+ private static ProviderOperationFactory instance;
+
+ /**
+ * holds concrete operations objects
+ */
+ private Map<Operation, IProviderOperation> operations;
+
+ /**
+ * private constructor
+ */
+ private ProviderOperationFactory() {
+ this.operations = new HashMap<>();
+ }
+
+ /**
+ * @return instance of the factory
+ */
+ public static ProviderOperationFactory getInstance() {
+ if (instance == null) {
+ instance = new ProviderOperationFactory();
+ }
+ return instance;
+ }
+
+ /**
+ * @param op
+ * @return concrete operation impl
+ */
+ public IProviderOperation getOperationObject(Operation op) throws APPCException {
+
+ IProviderOperation opObject = operations.get(op);
+ if (opObject == null) {
+ switch (op) {
+ case EVACUATE_SERVICE:
+ opObject = new EvacuateServer();
+ break;
+ case MIGRATE_SERVICE:
+ opObject = new MigrateServer();
+ break;
+ case REBUILD_SERVICE:
+ opObject = new RebuildServer();
+ break;
+ case RESTART_SERVICE:
+ opObject = new RestartServer();
+ break;
+ case VMSTATUSCHECK_SERVICE:
+ opObject = new VmStatuschecker();
+ break;
+ case SNAPSHOT_SERVICE:
+ opObject = new CreateSnapshot();
+ break;
+ case TERMINATE_STACK:
+ opObject = new TerminateStack();
+ break;
+ case SNAPSHOT_STACK:
+ opObject = new SnapshotStack();
+ break;
+ case RESTORE_STACK:
+ opObject = new RestoreStack();
+ break;
+ case START_SERVICE:
+ opObject = new StartServer();
+ break;
+ case STOP_SERVICE:
+ opObject = new StopServer();
+ break;
+ case TERMINATE_SERVICE:
+ opObject = new TerminateServer();
+ break;
+ case LOOKUP_SERVICE:
+ opObject = new LookupServer();
+ break;
+ default:
+ throw new APPCException("Unsupported provider operation.");
+ }
+ operations.put(op,opObject);
+ }
+ return opObject;
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Constants.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Constants.java
new file mode 100644
index 000000000..e3c592c89
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Constants.java
@@ -0,0 +1,58 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.common.constants;
+
+/**
+ * @since September 26, 2016
+ */
+public class Constants {
+
+ public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
+
+ public static final String MDC_SERVICE = "service";
+ public static final String MDC_ADAPTER = "adapter";
+
+ /**
+ * The constant for a left parenthesis
+ */
+ public static final char LPAREN = '(';
+
+ /**
+ * The constant for a new line control code
+ */
+ public static final char NL = '\n';
+
+ /**
+ * The constant for a single quote
+ */
+ public static final char QUOTE = '\'';
+
+ /**
+ * The constant for a right parenthesis
+ */
+ public static final char RPAREN = ')';
+
+ /**
+ * The constant for a space
+ */
+ public static final char SPACE = ' ';
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Property.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Property.java
new file mode 100644
index 000000000..702c469cb
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/constants/Property.java
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.common.constants;
+
+/**
+ * @since September 26, 2016
+ */
+public class Property {
+
+ public static final String PROVIDER = "provider";
+ public static final String PROVIDER_IDENTITY = "identity";
+ public static final String PROVIDER_TENANT = "tenant";
+ public static final String PROVIDER_TENANT_NAME = "name";
+ public static final String PROVIDER_TENANT_PASSWORD = "password";
+ public static final String PROVIDER_TENANT_USERID = "userid";
+ public static final String PROVIDER_TYPE = "type";
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Operation.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Operation.java
new file mode 100644
index 000000000..768ccc0c0
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Operation.java
@@ -0,0 +1,93 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.common.enums;
+
+/**
+ * @since September 26, 2016
+ */
+public enum Operation {
+ EVACUATE_SERVICE {
+ public String toString(){
+ return "evacuateServer";
+ }
+ },
+ MIGRATE_SERVICE {
+ public String toString(){
+ return "migrateServer";
+ }
+ },
+ REBUILD_SERVICE {
+ public String toString(){
+ return "rebuildServer";
+ }
+ },
+ RESTART_SERVICE {
+ public String toString(){
+ return "restartServer";
+ }
+ },
+ VMSTATUSCHECK_SERVICE {
+ public String toString(){
+ return "vmStatuschecker";
+ }
+ },
+ SNAPSHOT_SERVICE {
+ public String toString(){
+ return "createSnapshot";
+ }
+ },
+ TERMINATE_STACK {
+ public String toString(){
+ return "terminateStack";
+ }
+ },
+ SNAPSHOT_STACK {
+ public String toString(){
+ return "snapshotStack";
+ }
+ },
+ START_SERVICE {
+ public String toString(){
+ return "startServer";
+ }
+ },
+ STOP_SERVICE {
+ public String toString(){
+ return "stopServer";
+ }
+ },
+ TERMINATE_SERVICE {
+ public String toString(){
+ return "terminateServer";
+ }
+ },
+ LOOKUP_SERVICE {
+ public String toString(){
+ return "lookupServer";
+ }
+ },
+ RESTORE_STACK{
+ public String toString(){
+ return "restoreStack";
+ }
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Outcome.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Outcome.java
new file mode 100644
index 000000000..017c69879
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/common/enums/Outcome.java
@@ -0,0 +1,38 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.common.enums;
+
+/**
+ * @since September 26, 2016
+ */
+public enum Outcome {
+ FAILURE {
+ public String toString(){
+ return "failure";
+ }
+ },
+ SUCCESS {
+ public String toString(){
+ return "success";
+ }
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/CreateSnapshot.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/CreateSnapshot.java
new file mode 100644
index 000000000..c96dc6e84
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/CreateSnapshot.java
@@ -0,0 +1,291 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.IdentityURL;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.iaas.impl.VMURL;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.ImageService;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.glassfish.grizzly.http.util.HttpStatus;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants.DATE_FORMAT;
+import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME;
+
+import org.slf4j.MDC;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+
+public class CreateSnapshot extends ProviderServerOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(CreateSnapshot.class);
+ private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+ private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+
+ private String generateSnapshotName(String server) {
+ SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df2.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "create snapshot");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.CreateSnapshot");
+
+ metricsLogger.info("Snapshot Name Generated: Snapshot of %s at %s", server, df.format(new Date()));
+
+ return String.format("Snapshot of %s at %s", server, df.format(new Date()));
+ }
+
+ private Image createSnapshot(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+ Context context = server.getContext();
+ Provider provider = context.getProvider();
+ ImageService service = context.getImageService(); // Already checked access by this point
+
+ String snapshotName = generateSnapshotName(server.getName());
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "create snapshot");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.CreateSnapshot");
+
+ logger.info(String.format("Creating snapshot of server %s (%s) with name %s", server.getName(), server.getId(),
+ snapshotName));
+ metricsLogger.info(String.format("Creating snapshot of server %s (%s) with name %s", server.getName(), server.getId(),
+ snapshotName));
+
+ // Request Snapshot
+ String msg;
+ while (rc.attempt()) {
+ try {
+ server.createSnapshot(snapshotName);
+ break;
+ } catch (ContextConnectionException e) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+ context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ metricsLogger.error(msg, e);
+ rc.delay();
+ }
+ }
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+ rc.reset();
+
+ // Locate snapshot image
+ Image snapshot = null;
+ while (rc.attempt()) {
+ try {
+ snapshot = service.getImageByName(snapshotName);
+ if (snapshot != null) {
+ break;
+ }
+ } catch (ContextConnectionException e) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+ context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ metricsLogger.error(msg, e);
+ rc.delay();
+ }
+ }
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+ rc.reset();
+
+ // Wait for it to be ready
+ waitForStateChange(rc, snapshot, Image.Status.ACTIVE);
+
+ return snapshot;
+ }
+
+ private Image createSnapshot(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
+
+ Image snapshot = null;
+ RequestContext rc = new RequestContext(ctx);
+ rc.isAlive();
+
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+ String msg;
+
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "create snapshot");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.CreateSnapshot");
+
+ try {
+ validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+ ProviderAdapter.PROPERTY_PROVIDER_NAME);
+ String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+
+ VMURL vm = VMURL.parseURL(vm_url);
+ if (validateVM(rc, appName, vm_url, vm)) return null;
+
+ IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+ String identStr = (ident == null) ? null : ident.toString();
+
+ Context context = null;
+ try {
+ context = getContext(rc, vm_url, identStr);
+ if (context != null) {
+ Server server = lookupServer(rc, context, vm.getServerId());
+ logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString());
+
+ if (hasImageAccess(rc, context)) {
+ snapshot = createSnapshot(rc, server);
+ doSuccess(rc);
+ } else {
+ msg = EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(),
+ "Accessing Image Service Failed");
+ logger.error(msg);
+ metricsLogger.error(msg);
+ doFailure(rc, HttpStatus.FORBIDDEN_403, msg);
+ }
+ context.close();
+ }
+ } catch (ResourceNotFoundException e) {
+ msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url);
+ logger.error(msg);
+ metricsLogger.error(msg, e);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ } catch (Throwable t) {
+ msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(),
+ Operation.SNAPSHOT_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName());
+ logger.error(msg, t);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ }
+ } catch (RequestFailedException e) {
+ doFailure(rc, e.getStatus(), e.getMessage());
+ }
+ return snapshot;
+ }
+
+ @Override
+ protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException {
+
+ setMDC(Operation.SNAPSHOT_SERVICE.toString(), "App-C IaaS Adapter:Snapshot", ADAPTER_NAME);
+ logOperation(Msg.SNAPSHOTING_SERVER, params, context);
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "create snapshot");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.CreateSnapshot");
+
+ metricsLogger.info("Executing Provider Operation: Create Snapshot");
+
+ return createSnapshot(params, context);
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/EvacuateServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/EvacuateServer.java
new file mode 100644
index 000000000..d749fc225
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/EvacuateServer.java
@@ -0,0 +1,378 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.IdentityURL;
+import org.openecomp.appc.adapter.iaas.impl.ProviderAdapterImpl;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.iaas.impl.VMURL;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.model.Hypervisor;
+import com.att.cdp.zones.model.Hypervisor.Status;
+import com.att.cdp.zones.model.Hypervisor.State;
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.slf4j.MDC;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME;
+
+public class EvacuateServer extends ProviderServerOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(EvacuateServer.class);
+ private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+ private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+ private ProviderAdapterImpl paImpl = null;
+
+
+ private void evacuateServer(RequestContext rc, @SuppressWarnings("unused") Server server, String target_host) throws ZoneException, RequestFailedException {
+
+ String msg;
+ Context ctx = server.getContext();
+ Provider provider = ctx.getProvider();
+ ComputeService service = ctx.getComputeService();
+
+ /*
+ * Pending is a bit of a special case. If we find the server is in a pending state, then the provider is in the
+ * process of changing state of the server. So, lets try to wait a little bit and see if the state settles down
+ * to one we can deal with. If not, then we have to fail the request.
+ */
+ try {
+ if (server.getStatus().equals(Server.Status.PENDING)) {
+ waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR, Server.Status.SUSPENDED, Server.Status.PAUSED);
+ }
+ } catch (RequestFailedException e) {
+ // evacuate is a special case. If the server is still in a Pending state, we want to continue with evacuate
+ logger.info("Evacuate server - ignore RequestFailedException from waitForStateChange() ...");
+ }
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "evacuate server");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.EvacuteServer");
+
+
+ try {
+ while (rc.attempt()) {
+ try {
+ logger.debug("Calling CDP moveServer - server id = " + server.getId());
+ service.moveServer(server.getId(), target_host);
+ // Wait for completion, expecting the server to go to a non pending state
+ waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR, Server.Status.SUSPENDED, Server.Status.PAUSED);
+ break;
+ } catch (ContextConnectionException e) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+ ctx.getTenant().getName(), ctx.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ metricsLogger.error(msg,e);
+ rc.delay();
+ }
+ }
+
+ } catch (ZoneException e) {
+ msg =
+ EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, server.getName(), server.getId(), e.getMessage());
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Evacute Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Evacuate Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+ rc.reset();
+ }
+
+
+ /**
+ * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#evacuateServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext)
+ */
+ private Server evacuateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
+ Server server = null;
+ RequestContext rc = new RequestContext(ctx);
+ rc.isAlive();
+
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+ String msg;
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "evacuate server");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.EvacuateServer");
+
+ ctx.setAttribute("EVACUATE_STATUS", "ERROR");
+ try {
+ validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+ ProviderAdapter.PROPERTY_PROVIDER_NAME);
+ String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+
+ VMURL vm = VMURL.parseURL(vm_url);
+ if (validateVM(rc, appName, vm_url, vm)) return null;
+
+ IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+ String identStr = (ident == null) ? null : ident.toString();
+
+ // retrieve the optional parameters
+ String rebuild_vm = params.get(ProviderAdapter.PROPERTY_REBUILD_VM);
+ String targethost_id = params.get(ProviderAdapter.PROPERTY_TARGETHOST_ID);
+
+ Context context = null;
+ try {
+ context = getContext(rc, vm_url, identStr);
+ if (context != null) {
+
+ server = lookupServer(rc, context, vm.getServerId());
+ logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString());
+
+ // check target host status
+ if (isComputeNodeDown(context, targethost_id)) {
+ msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, server.getName(), server.getId(),
+ "Target host " + targethost_id +" status is not UP/ENABLED");
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Evacuate Server", msg, HttpStatus.BAD_REQUEST_400, server);
+ }
+
+ // save hypervisor name before evacuate
+ String hypervisor = server.getHypervisor().getHostName();
+
+ evacuateServer(rc, server, targethost_id);
+
+ server.refreshAll();
+ String hypervisor_after_evacuate = server.getHypervisor().getHostName();
+ logger.debug("Hostname before evacuate: " + hypervisor + ", After evacuate: " + hypervisor_after_evacuate);
+
+ // check hypervisor host name after evacuate. If it is unchanged, the evacuate failed.
+ if ((hypervisor != null) && (hypervisor.equals(hypervisor_after_evacuate))) {
+ msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, server.getName(), server.getId(),
+ "Hypervisor host " + hypervisor + " after evacuate is the same as before evacuate. Provider (ex. Openstack) recovery actions may be needed.");
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Evacuate Server", msg, HttpStatus.INTERNAL_SERVER_ERROR_500, server);
+
+ }
+
+ // check VM status after evacuate
+ if (server.getStatus() == Server.Status.ERROR) {
+ msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, server.getName(), server.getId(),
+ "VM is in ERROR state after evacuate. Provider (ex. Openstack) recovery actions may be needed.");
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Evacuate Server", msg, HttpStatus.INTERNAL_SERVER_ERROR_500, server);
+ }
+
+ context.close();
+ doSuccess(rc);
+ ctx.setAttribute("EVACUATE_STATUS", "SUCCESS");
+
+ // If a snapshot exists, do a rebuild to apply the latest snapshot to the evacuated server.
+ // This is the default behavior unless the optional parameter is set to FALSE.
+ if ((rebuild_vm == null) || !(rebuild_vm.equalsIgnoreCase("false"))) {
+ List<Image> snapshots = server.getSnapshots();
+ if (snapshots == null || snapshots.isEmpty()) {
+ logger.debug("No snapshots available - skipping rebuild after evacuate");
+ } else if (paImpl != null) {
+ logger.debug("Executing a rebuild after evacuate");
+ paImpl.rebuildServer(params, ctx);
+ // Check error code for rebuild errors. Evacuate had set it to 200 after
+ // a successful evacuate. Rebuild updates the error code.
+ String rebuildErrorCode = ctx.getAttribute(org.openecomp.appc.Constants.ATTRIBUTE_ERROR_CODE);
+ if (rebuildErrorCode != null) {
+ try {
+ int error_code = Integer.parseInt(rebuildErrorCode);
+ if (error_code != HttpStatus.OK_200.getStatusCode()) {
+ logger.debug("Rebuild after evacuate failed - error code=" + error_code
+ + ", message=" + ctx.getAttribute(org.openecomp.appc.Constants.ATTRIBUTE_ERROR_MESSAGE));
+ msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_REBUILD_FAILED, server.getName(), hypervisor,
+ hypervisor_after_evacuate, ctx.getAttribute(org.openecomp.appc.Constants.ATTRIBUTE_ERROR_MESSAGE));
+ logger.error(msg);
+ metricsLogger.error(msg);
+ ctx.setAttribute("EVACUATE_STATUS", "ERROR");
+ // update error message while keeping the error code the same as before
+ doFailure(rc, HttpStatus.getHttpStatus(error_code), msg);
+ }
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ }
+ } catch (ResourceNotFoundException e) {
+ msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ } catch (RequestFailedException e) {
+ doFailure(rc, e.getStatus(), e.getMessage());
+ } catch (Throwable t) {
+ msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(),
+ Operation.EVACUATE_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName());
+ logger.error(msg, t);
+ metricsLogger.error(msg, t);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ }
+ } catch (RequestFailedException e) {
+ msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, "n/a", "n/a", e.getMessage());
+ logger.error(msg);
+ metricsLogger.error(msg);
+ doFailure(rc, e.getStatus(), e.getMessage());
+ }
+
+ return server;
+ }
+
+ /*
+ * Check if a Compute node is down.
+ *
+ * This method attempts to find a given host in the list of hypervisors for a given
+ * context. The only case where a node is considered down is if a matching hypervisor
+ * is found and it's state and status are not UP/ENABLED.
+ *
+ * @param context
+ * The current context
+ * @param host
+ * The host name (short or fully qualified) of a compute node
+ * @return true if the node is determined as down, false for all other cases
+ */
+ private boolean isComputeNodeDown(Context context, String host) throws ZoneException {
+ ComputeService service = context.getComputeService();
+ boolean node_down = false;
+
+ // Check host status. A node is considered down only if a matching target host is
+ // found and it's state/status is not UP/ENABLED.
+ if ((host != null) && !(host.isEmpty())) {
+ List<Hypervisor> hypervisors = service.getHypervisors();
+ logger.debug("List of Hypervisors retrieved: " + Arrays.toString(hypervisors.toArray()));
+ for (Hypervisor h : hypervisors) {
+ if (h.getHostName().startsWith(host)) {
+ // host matches one of the hypervisors
+ State hstate = h.getState();
+ Status hstatus = h.getStatus();
+ logger.debug("Host matching hypervisor: " + h.getHostName() + ", State/Status: "
+ + hstate.toString() + "/" + hstatus.toString());
+ if ((hstate != null) && (hstatus != null)) {
+ if (!(hstate.equals(State.UP)) || !(hstatus.equals(Status.ENABLED))) {
+ node_down = true;
+ }
+ }
+ }
+ }
+ }
+ return node_down;
+ }
+
+ @Override
+ protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException {
+
+ setMDC(Operation.EVACUATE_SERVICE.toString(), "App-C IaaS Adapter:Evacuate", ADAPTER_NAME);
+ logOperation(Msg.EVACUATING_SERVER, params, context);
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "evacuate server");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.EvacuateServer");
+
+
+ metricsLogger.info("Executing Provider Operation: Evacuate");
+ return evacuateServer(params, context);
+ }
+
+ public void setProvideAdapterRef(ProviderAdapterImpl pai) {
+ paImpl = pai;
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/LookupServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/LookupServer.java
new file mode 100644
index 000000000..03a76cb8b
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/LookupServer.java
@@ -0,0 +1,124 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.iaas.impl.VMURL;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.glassfish.grizzly.http.util.HttpStatus;
+
+import java.io.IOException;
+import java.util.Map;
+
+import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME;
+
+/**
+ * @since September 26, 2016
+ */
+public class LookupServer extends ProviderServerOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(EvacuateServer.class);
+ private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+
+ public Server lookupServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
+ Server server = null;
+ RequestContext rc = new RequestContext(ctx);
+ rc.isAlive(); //should we test the return and fail if false?
+
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+
+ String vm_url = null;
+ VMURL vm = null;
+ try {
+
+ //process vm_url
+ validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+ ProviderAdapter.PROPERTY_PROVIDER_NAME);
+ vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+ vm = VMURL.parseURL(vm_url);
+ if (validateVM(rc, appName, vm_url, vm)) return null;
+
+
+ //use try with resource to ensure context is closed (returned to pool)
+ try(Context context = resolveContext(rc, params, appName, vm_url)){
+ //resloveContext & getContext call doFailure and log errors before returning null
+ if (context != null){
+ rc.reset();
+ server = lookupServer(rc, context, vm.getServerId());
+ logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString());
+ ctx.setAttribute("serverFound", "success");
+ String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "LookupServer", vm_url);
+ ctx.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg);
+ doSuccess(rc);
+ }
+ } catch (ZoneException e) {
+ //server not found
+ String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ ctx.setAttribute("serverFound", "failure");
+ } catch (IOException e) {
+ //exception closing context
+ String msg = EELFResourceManager.format(Msg.CLOSE_CONTEXT_FAILED, e, vm_url);
+ logger.error(msg);
+ } catch (Throwable t) {
+ String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(),
+ Operation.LOOKUP_SERVICE.toString(), vm_url, "Unknown" );
+ logger.error(msg, t);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ }
+
+ } catch (RequestFailedException e) {
+ // parameters not valid, unable to connect to provider
+ String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ ctx.setAttribute("serverFound", "failure");
+ }
+ return server;
+ }
+
+ @Override
+ protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException {
+
+ setMDC(Operation.LOOKUP_SERVICE.toString(), "App-C IaaS Adapter:LookupServer", ADAPTER_NAME);
+ logOperation(Msg.LOOKING_SERVER_UP, params, context);
+ return lookupServer(params, context);
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/MigrateServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/MigrateServer.java
new file mode 100644
index 000000000..1b17d1c5c
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/MigrateServer.java
@@ -0,0 +1,284 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.IdentityURL;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.iaas.impl.VMURL;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.glassfish.grizzly.http.util.HttpStatus;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_SERVICE;
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.MIGRATE_SERVICE;
+import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME;
+
+import org.slf4j.MDC;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+
+/**
+ * @since September 26, 2016
+ */
+public class MigrateServer extends ProviderServerOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(EvacuateServer.class);
+ private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+ private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+ /**
+ * A list of valid initial VM statuses for a migrate operations
+ */
+ private final Collection<Server.Status> migratableStatuses = Arrays.asList(Server.Status.READY, Server.Status.RUNNING, Server.Status.SUSPENDED);
+
+
+ private String getConnectionExceptionMessage(RequestContext rc, Context ctx, ContextConnectionException e)
+ throws ZoneException {
+ return EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, ctx.getProvider().getName(),
+ ctx.getComputeService().getURL(), ctx.getTenant().getName(), ctx.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ }
+
+ private void migrateServer(RequestContext rc, Server server, SvcLogicContext svcCtx)
+ throws ZoneException, RequestFailedException {
+ String msg;
+ Context ctx = server.getContext();
+ ComputeService service = ctx.getComputeService();
+
+ // Init status will equal final status
+ Server.Status initialStatus = server.getStatus();
+
+ if (initialStatus == null) {
+ throw new ZoneException("Failed to determine server's starting status");
+ }
+
+ // We can only migrate certain statuses
+ if (!migratableStatuses.contains(initialStatus)) {
+ throw new ZoneException(String.format("Cannot migrate server that is in %s state. Must be in one of [%s]",
+ initialStatus, migratableStatuses));
+ }
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "migrate server");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.MigrateServer");
+ // Is the skip Hypervisor check attribute populated?
+ String skipHypervisorCheck = null;
+ if (svcCtx != null) {
+ skipHypervisorCheck = svcCtx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK);
+
+ }
+
+ // // Always perform Hypervisor check
+ // unless the skip is set to true
+
+ if (skipHypervisorCheck == null || (!skipHypervisorCheck.equalsIgnoreCase("true"))) {
+
+ // Check of the Hypervisor for the VM Server is UP and reachable
+
+ checkHypervisor(server);
+
+ }
+
+ boolean inConfirmPhase = false;
+ try {
+ while (rc.attempt()) {
+ try {
+ if (!inConfirmPhase) {
+ // Initial migrate request
+ service.migrateServer(server.getId());
+ // Wait for change to verify resize
+ waitForStateChange(rc, server, Server.Status.READY);
+ inConfirmPhase = true;
+ }
+
+ // Verify resize
+ service.processResize(server);
+ // Wait for complete. will go back to init status
+ waitForStateChange(rc, server, initialStatus);
+ logger.info("Completed migrate request successfully");
+ metricsLogger.info("Completed migrate request successfully");
+ return;
+ } catch (ContextConnectionException e) {
+ msg = getConnectionExceptionMessage(rc, ctx, e);
+ logger.error(msg, e);
+ metricsLogger.error(msg, e);
+ rc.delay();
+ }
+ }
+ } catch (ZoneException e) {
+ String phase = inConfirmPhase ? "VERIFY MIGRATE" : "REQUEST MIGRATE";
+ msg = EELFResourceManager.format(Msg.MIGRATE_SERVER_FAILED, server.getName(), server.getId(), phase,
+ e.getMessage());
+ generateEvent(rc, false, msg);
+ logger.error(msg, e);
+ metricsLogger.error(msg, e);
+ throw new RequestFailedException("Migrate Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+ }
+
+ }
+
+ /**
+ * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#migrateServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext)
+ */
+ private Server migrateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
+ Server server = null;
+ RequestContext rc = new RequestContext(ctx);
+ rc.isAlive();
+
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+ String msg;
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "migrate server");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.MigrateServer");
+
+ try {
+ validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+ ProviderAdapter.PROPERTY_PROVIDER_NAME);
+ String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+
+ VMURL vm = VMURL.parseURL(vm_url);
+ if (validateVM(rc, appName, vm_url, vm)) return null;
+
+ IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+ String identStr = (ident == null) ? null : ident.toString();
+
+ Context context = null;
+ try {
+ context = getContext(rc, vm_url, identStr);
+ if (context != null) {
+ server = lookupServer(rc, context, vm.getServerId());
+ logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString());
+ migrateServer(rc, server, ctx);
+ server.refreshStatus();
+ context.close();
+ doSuccess(rc);
+ }
+ } catch (RequestFailedException e) {
+ doFailure(rc, e.getStatus(), e.getMessage());
+ }
+ catch (ResourceNotFoundException e) {
+ msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ } catch (Throwable t) {
+ msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(),
+ MIGRATE_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName());
+ logger.error(msg, t);
+ metricsLogger.error(msg);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ }
+ } catch (RequestFailedException e) {
+ doFailure(rc, e.getStatus(), e.getMessage());
+ }
+
+ return server;
+ }
+
+ @Override
+ protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException {
+
+ setMDC(Operation.MIGRATE_SERVICE.toString(), "App-C IaaS Adapter:Migrate", ADAPTER_NAME);
+ logOperation(Msg.MIGRATING_SERVER, params, context);
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "migrate server");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.MigrateServer");
+
+
+ metricsLogger.info("Executing Provider Operation: Migrate");
+
+ return migrateServer(params,context);
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RebuildServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RebuildServer.java
new file mode 100644
index 000000000..959c1ad41
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RebuildServer.java
@@ -0,0 +1,503 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.IdentityURL;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.iaas.impl.VMURL;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Outcome;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.ImageService;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.ServerBootSource;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.glassfish.grizzly.http.util.HttpStatus;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_SERVICE;
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.STOP_SERVICE;
+import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME;
+
+import org.slf4j.MDC;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * @since September 26, 2016
+ */
+public class RebuildServer extends ProviderServerOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(RebuildServer.class);
+ private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+ private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+ /**
+ * Rebuild the indicated server with the indicated image. This method assumes the server has been determined to be
+ * in the correct state to do the rebuild.
+ *
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param server
+ * the server to be rebuilt
+ * @param image
+ * The image to be used (or snapshot)
+ * @throws RequestFailedException
+ * if the server does not change state in the allotted time
+ */
+ @SuppressWarnings("nls")
+ private void rebuildServer(RequestContext rc, Server server, String image) throws RequestFailedException {
+ logger.debug(Msg.REBUILD_SERVER, server.getId());
+
+ String msg;
+ Context context = server.getContext();
+ Provider provider = context.getProvider();
+ ComputeService service = context.getComputeService();
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "rebuild server");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RebuildServer");
+
+ try {
+ while (rc.attempt()) {
+ try {
+ server.rebuild(image);
+ break;
+ } catch (ContextConnectionException e) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+ context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ metricsLogger.error(msg,e);
+ rc.delay();
+ }
+ }
+
+ /*
+ * We need to provide some time for OpenStack to start processing the request.
+ */
+ try {
+ Thread.sleep(10L * 1000L);
+ } catch (InterruptedException e) {
+ logger.trace("Sleep threw interrupted exception, should never occur");
+ metricsLogger.trace("Sleep threw interrupted exception, should never occur");
+ }
+ } catch (ZoneException e) {
+ msg =
+ EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(), e.getMessage());
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+
+ rc.reset();
+ /*
+ * Once we have started the process, now we wait for the final state of stopped. This should be the final state
+ * (since we started the rebuild with the server stopped).
+ */
+ waitForStateChange(rc, server, Server.Status.READY);
+
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+ rc.reset();
+ }
+
+ /**
+ * This method is called to rebuild the provided server.
+ * <p>
+ * If the server was booted from a volume, then the request is failed immediately and no action is taken. Rebuilding
+ * a VM from a bootable volume, where the bootable volume itself is not rebuilt, serves no purpose.
+ * </p>
+ *
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param server
+ * @throws ZoneException
+ * @throws RequestFailedException
+ */
+ @SuppressWarnings("nls")
+ private void rebuildServer(RequestContext rc, Server server, SvcLogicContext ctx)
+ throws ZoneException, RequestFailedException {
+
+ ServerBootSource builtFrom = server.getBootSource();
+ String msg;
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "rebuild server");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RebuildServer");
+
+ // Throw exception for non image/snap boot source
+ if (ServerBootSource.VOLUME.equals(builtFrom)) {
+ msg = String.format("Rebuilding is currently not supported for servers built from bootable volumes [%s]",
+ server.getId());
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Rebuild Server", msg, HttpStatus.FORBIDDEN_403, server);
+ }
+
+ /*
+ * Pending is a bit of a special case. If we find the server is in a
+ * pending state, then the provider is in the process of changing state
+ * of the server. So, lets try to wait a little bit and see if the state
+ * settles down to one we can deal with. If not, then we have to fail
+ * the request.
+ */
+ Context context = server.getContext();
+ Provider provider = context.getProvider();
+ ComputeService service = context.getComputeService();
+ if (server.getStatus().equals(Server.Status.PENDING)) {
+ rc.reset();
+ waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR,
+ Server.Status.SUSPENDED, Server.Status.PAUSED);
+ }
+
+ // Is the skip Hypervisor check attribute populated?
+ String skipHypervisorCheck = null;
+ if (ctx != null) {
+ skipHypervisorCheck = ctx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK);
+
+ }
+
+ // Always perform Hypervisor Status checks
+ // unless the skip is set to true
+ if (skipHypervisorCheck == null || (!skipHypervisorCheck.equalsIgnoreCase("true"))) {
+
+ // Check of the Hypervisor for the VM Server is UP and reachable
+ checkHypervisor(server);
+ }
+
+ /*
+ * Get the image to use. This is determined by the presence or
+ * absence of snapshot images. If any snapshots exist, then the
+ * latest snapshot is used, otherwise the image used to construct
+ * the VM is used.
+ */
+ List<Image> snapshots = server.getSnapshots();
+ String imageToUse;
+ if (snapshots != null && !snapshots.isEmpty()) {
+ imageToUse = snapshots.get(0).getId();
+ } else {
+ imageToUse = server.getImage();
+ ImageService imageService = server.getContext().getImageService();
+ rc.reset();
+ try {
+ while (rc.attempt()) {
+ try {
+ /*
+ * We are just trying to make sure that the image
+ * exists. We arent interested in the details at
+ * this point.
+ */
+ imageService.getImage(imageToUse);
+ break;
+ } catch (ContextConnectionException e) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(),
+ imageService.getURL(), context.getTenant().getName(), context.getTenant().getId(),
+ e.getMessage(), Long.toString(rc.getRetryDelay()),
+ Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ metricsLogger.error(msg);
+ rc.delay();
+ }
+ }
+ } catch (ZoneException e) {
+ msg = EELFResourceManager.format(Msg.IMAGE_NOT_FOUND, imageToUse, "rebuild");
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+ }
+ }
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+ rc.reset();
+
+ /*
+ * We determine what to do based on the current state of the server
+ */
+ switch (server.getStatus()) {
+ case DELETED:
+ // Nothing to do, the server is gone
+ msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(),
+ server.getTenantId(), "rebuilt");
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+
+ case RUNNING:
+ // Attempt to stop the server, then rebuild it
+ stopServer(rc, server);
+ rc.reset();
+ rebuildServer(rc, server, imageToUse);
+ rc.reset();
+ startServer(rc, server);
+ generateEvent(rc, true, Outcome.SUCCESS.toString());
+ metricsLogger.info("Server status: RUNNING");
+ break;
+
+ case ERROR:
+ msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(),
+ server.getTenantId(), "rebuild");
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+
+ case READY:
+ // Attempt to rebuild the server
+ rebuildServer(rc, server, imageToUse);
+ rc.reset();
+ startServer(rc, server);
+ generateEvent(rc, true, Outcome.SUCCESS.toString());
+ metricsLogger.info("Server status: READY");
+ break;
+
+ case PAUSED:
+ // if paused, un-pause it, stop it, and rebuild it
+ unpauseServer(rc, server);
+ rc.reset();
+ stopServer(rc, server);
+ rc.reset();
+ rebuildServer(rc, server, imageToUse);
+ rc.reset();
+ startServer(rc, server);
+ generateEvent(rc, true, Outcome.SUCCESS.toString());
+ metricsLogger.info("Server status: PAUSED");
+ break;
+
+ case SUSPENDED:
+ // Attempt to resume the suspended server, stop it, and rebuild it
+ resumeServer(rc, server);
+ rc.reset();
+ stopServer(rc, server);
+ rc.reset();
+ rebuildServer(rc, server, imageToUse);
+ rc.reset();
+ startServer(rc, server);
+ generateEvent(rc, true, Outcome.SUCCESS.toString());
+ metricsLogger.info("Server status: SUSPENDED");
+ break;
+
+ default:
+ // Hmmm, unknown status, should never occur
+ msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(),
+ server.getTenantId(), server.getStatus().name());
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+ }
+
+
+ }
+
+ /**
+ * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#rebuildServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext)
+ */
+ @SuppressWarnings("nls")
+ public Server rebuildServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
+ Server server = null;
+ RequestContext rc = new RequestContext(ctx);
+ rc.isAlive();
+
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+ String msg;
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "rebuild server");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RebuildServer");
+
+ try {
+ validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+ ProviderAdapter.PROPERTY_PROVIDER_NAME);
+ String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+
+ VMURL vm = VMURL.parseURL(vm_url);
+ if (validateVM(rc, appName, vm_url, vm)) return null;
+
+ IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+ String identStr = (ident == null) ? null : ident.toString();
+ ctx.setAttribute("REBUILD_STATUS", "ERROR");
+
+ Context context = null;
+ try {
+ context = getContext(rc, vm_url, identStr);
+ if (context != null) {
+ rc.reset();
+ server = lookupServer(rc, context, vm.getServerId());
+ logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString());
+
+ // Manually checking image service until new PAL release
+ if (hasImageAccess(rc, context)) {
+ rebuildServer(rc, server, ctx);
+ doSuccess(rc);
+ ctx.setAttribute("REBUILD_STATUS", "SUCCESS");
+ } else {
+ msg = EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(),
+ "Accessing Image Service Failed");
+ logger.error(msg);
+ metricsLogger.error(msg);
+ doFailure(rc, HttpStatus.FORBIDDEN_403, msg);
+ }
+ context.close();
+ }
+ else
+ {
+ ctx.setAttribute("REBUILD_STATUS", "CONTEXT_NOT_FOUND");
+ }
+ }
+ catch (RequestFailedException e) {
+ doFailure(rc, e.getStatus(), e.getMessage());
+ ctx.setAttribute("REBUILD_STATUS", "ERROR");
+ }
+ catch (ResourceNotFoundException e) {
+ msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url);
+ ctx.setAttribute("REBUILD_STATUS", "ERROR");
+ logger.error(msg);
+ metricsLogger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ } catch (Throwable t) {
+ msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(),
+ STOP_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName());
+ ctx.setAttribute("REBUILD_STATUS", "ERROR");
+ logger.error(msg, t);
+ metricsLogger.error(msg);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ }
+ } catch (RequestFailedException e) {
+ doFailure(rc, e.getStatus(), e.getMessage());
+ ctx.setAttribute("REBUILD_STATUS", "ERROR");
+ }
+
+ return server;
+ }
+
+ @Override
+ protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException {
+
+ setMDC(Operation.REBUILD_SERVICE.toString(), "App-C IaaS Adapter:Rebuild", ADAPTER_NAME);
+ logOperation(Msg.REBUILDING_SERVER, params, context);
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "rebuild server");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RebuildServer");
+
+
+ metricsLogger.info("Executing Provider Operation: Rebuild");
+
+
+ return rebuildServer(params, context);
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestartServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestartServer.java
new file mode 100644
index 000000000..45e8f469f
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestartServer.java
@@ -0,0 +1,320 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.IdentityURL;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.iaas.impl.VMURL;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Outcome;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.openecomp.appc.exceptions.UnknownProviderException;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.NetworkService;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Network;
+import com.att.cdp.zones.model.Port;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Subnet;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.slf4j.MDC;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_SERVICE;
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.RESTART_SERVICE;
+import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME;
+
+
+public class RestartServer extends ProviderServerOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(RestartServer.class);
+ private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+
+
+ /**
+ * This method handles the case of restarting a server once we have found the server and have obtained the abstract
+ * representation of the server via the context (i.e., the "Server" object from the CDP-Zones abstraction).
+ *
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param server
+ * The server object representing the server we want to operate on
+ * @throws ZoneException
+ */
+ @SuppressWarnings("nls")
+ private void restartServer(RequestContext rc, Server server, SvcLogicContext ctx)
+ throws ZoneException, RequestFailedException {
+
+ /*
+ * Pending is a bit of a special case. If we find the server is in a
+ * pending state, then the provider is in the process of changing state
+ * of the server. So, lets try to wait a little bit and see if the state
+ * settles down to one we can deal with. If not, then we have to fail
+ * the request.
+ */
+ String msg;
+ if (server.getStatus().equals(Server.Status.PENDING)) {
+ waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR,
+ Server.Status.SUSPENDED, Server.Status.PAUSED);
+ }
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "restart server");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RestartServer");
+
+ String skipHypervisorCheck = null;
+ if (ctx != null) {
+ skipHypervisorCheck = ctx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK);
+
+ }
+
+ // Always perform Virtual Machine/Hypervisor Status/Network checks
+ // unless the skip is set to true
+ if (skipHypervisorCheck == null || (!skipHypervisorCheck.equalsIgnoreCase("true"))) {
+
+ // Check of the Hypervisor for the VM Server is UP and reachable
+
+ checkHypervisor(server);
+
+ }
+
+ /*
+ * We determine what to do based on the current state of the server
+ */
+
+ switch (server.getStatus()) {
+ case DELETED:
+ // Nothing to do, the server is gone
+ msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(),
+ server.getTenantId(), "restarted");
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ break;
+
+ case RUNNING:
+ // Attempt to stop and start the server
+ stopServer(rc, server);
+ startServer(rc, server);
+ generateEvent(rc, true, Outcome.SUCCESS.toString());
+ metricsLogger.info("Server status: RUNNING");
+ break;
+
+ case ERROR:
+ msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(),
+ server.getTenantId(), "rebuild");
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+
+ case READY:
+ // Attempt to start the server
+ startServer(rc, server);
+ generateEvent(rc, true, Outcome.SUCCESS.toString());
+ metricsLogger.info("Server status: READY");
+ break;
+
+ case PAUSED:
+ // if paused, un-pause it
+ unpauseServer(rc, server);
+ generateEvent(rc, true, Outcome.SUCCESS.toString());
+ metricsLogger.info("Server status: PAUSED");
+ break;
+
+ case SUSPENDED:
+ // Attempt to resume the suspended server
+ resumeServer(rc, server);
+ generateEvent(rc, true, Outcome.SUCCESS.toString());
+ metricsLogger.info("Server status: SUSPENDED");
+ break;
+
+ default:
+ // Hmmm, unknown status, should never occur
+ msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(),
+ server.getTenantId(), server.getStatus().name());
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ break;
+ }
+
+
+ }
+
+ /**
+ * This method is used to restart an existing virtual machine given the fully qualified URL of the machine.
+ * <p>
+ * The fully qualified URL contains enough information to locate the appropriate server. The URL is of the form
+ * <pre>
+ * [scheme]://[host[:port]] / [path] / [tenant_id] / servers / [vm_id]
+ * </pre> Where the various parts of the URL can be parsed and extracted and used to locate the appropriate service
+ * in the provider service catalog. This then allows us to open a context using the CDP abstraction, obtain the
+ * server by its UUID, and then perform the restart.
+ * </p>
+ *
+ * @throws UnknownProviderException
+ * If the provider cannot be found
+ * @throws IllegalArgumentException
+ * if the expected argument(s) are not defined or are invalid
+ * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#restartServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext)
+ */
+ @SuppressWarnings("nls")
+ private Server restartServer(Map<String, String> params, SvcLogicContext ctx)
+ throws UnknownProviderException, IllegalArgumentException {
+ Server server = null;
+ RequestContext rc = new RequestContext(ctx);
+ rc.isAlive();
+
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "GET server status");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RestartServer");
+
+ ctx.setAttribute("RESTART_STATUS", "ERROR");
+ try {
+ validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+ ProviderAdapter.PROPERTY_PROVIDER_NAME);
+
+ String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+
+ VMURL vm = VMURL.parseURL(vm_url);
+ if (validateVM(rc, appName, vm_url, vm)) return null;
+
+ IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+ String identStr = (ident == null) ? null : ident.toString();
+
+ Context context = null;
+ try {
+ context = getContext(rc, vm_url, identStr);
+ if (context != null) {
+ rc.reset();
+ server = lookupServer(rc, context, vm.getServerId());
+ logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString());
+ rc.reset();
+ restartServer(rc, server, ctx);
+ context.close();
+ doSuccess(rc);
+ ctx.setAttribute("RESTART_STATUS", "SUCCESS");
+ String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "RestartServer", vm_url);
+ ctx.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg);
+ }
+ } catch (RequestFailedException e) {
+ doFailure(rc, e.getStatus(), e.getMessage());
+ }
+ catch (ResourceNotFoundException e) {
+ String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ } catch (Throwable t) {
+ String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(),
+ RESTART_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName());
+ logger.error(msg, t);
+ metricsLogger.error(msg, t);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ }
+ } catch (RequestFailedException e) {
+ doFailure(rc, e.getStatus(), e.getMessage());
+ }
+
+ return server;
+ }
+
+ @Override
+ protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws UnknownProviderException {
+
+ setMDC(RESTART_SERVICE.toString(), "App-C IaaS Adapter:Restart", ADAPTER_NAME);
+ logOperation(Msg.RESTARTING_SERVER, params, context);
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "execute restart");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.RestartServer");
+
+ metricsLogger.info("Executing Provider Operation: Restart");
+
+
+ return restartServer(params, context);
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestoreStack.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestoreStack.java
new file mode 100644
index 000000000..018c8e2e6
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/RestoreStack.java
@@ -0,0 +1,152 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderStackOperation;
+import org.openecomp.appc.adapter.openstack.heat.SnapshotResource;
+import org.openecomp.appc.adapter.openstack.heat.StackResource;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.exceptions.UnknownProviderException;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.OpenStackContext;
+import com.att.cdp.openstack.connectors.HeatConnector;
+import com.att.cdp.openstack.util.ExceptionMapper;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Stack;
+import com.att.cdp.zones.spi.RequestState;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import com.woorea.openstack.heat.Heat;
+import org.glassfish.grizzly.http.util.HttpStatus;
+
+import java.util.Map;
+
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.RESTART_SERVICE;
+import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME;
+
+
+public class RestoreStack extends ProviderStackOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(RestoreStack.class);
+
+ private void restoreStack(Stack stack, String snapshotId) throws ZoneException, RequestFailedException {
+ Context context = stack.getContext();
+
+ OpenStackContext osContext = (OpenStackContext)context;
+
+ final HeatConnector heatConnector = osContext.getHeatConnector();
+ ((OpenStackContext)context).refreshIfStale(heatConnector);
+
+ trackRequest(context);
+ RequestState.put("SERVICE", "Orchestration");
+ RequestState.put("SERVICE_URL", heatConnector.getEndpoint());
+
+ Heat heat = heatConnector.getClient();
+
+ SnapshotResource snapshotResource = new SnapshotResource(heat);
+
+ try {
+
+ snapshotResource.restore(stack.getName(), stack.getId(), snapshotId).execute();
+
+ // wait for the snapshot restore
+ StackResource stackResource = new StackResource(heat);
+ if (!waitForStack(stack, stackResource, "RESTORE_COMPLETE")) {
+ throw new RequestFailedException("Snapshot restore failed.");
+ }
+
+ } catch (OpenStackBaseException e) {
+ ExceptionMapper.mapException(e);
+ }
+
+ }
+
+ public Stack restoreStack(Map<String, String> params, SvcLogicContext ctx) throws IllegalArgumentException, APPCException {
+ Stack stack = null;
+ RequestContext rc = new RequestContext(ctx);
+ rc.isAlive();
+
+ ctx.setAttribute("SNAPSHOT_STATUS", "STACK_NOT_FOUND");
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+
+ String vm_url = null;
+ Context context = null;
+
+ try {
+
+ validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL, ProviderAdapter.PROPERTY_PROVIDER_NAME,
+ ProviderAdapter.PROPERTY_STACK_ID, ProviderAdapter.PROPERTY_INPUT_SNAPSHOT_ID);
+
+ String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID);
+ vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+ String snapshotId = params.get(ProviderAdapter.PROPERTY_INPUT_SNAPSHOT_ID);
+
+ context = resolveContext(rc, params, appName, vm_url);
+
+
+ if (context != null) {
+ stack = lookupStack(rc, context, stackId);
+ logger.debug(Msg.STACK_FOUND, vm_url, context.getTenantName(), stack.getStatus().toString());
+ logger.info(EELFResourceManager.format(Msg.TERMINATING_STACK, stack.getName()));
+ restoreStack(stack, snapshotId);
+ logger.info(EELFResourceManager.format(Msg.TERMINATE_STACK, stack.getName()));
+ context.close();
+ doSuccess(rc);
+ }else {
+ ctx.setAttribute(Constants.DG_ATTRIBUTE_STATUS, "failure");
+ }
+
+ } catch (ResourceNotFoundException e) {
+ String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vm_url);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg, e);
+ } catch (RequestFailedException e) {
+ logger.error(EELFResourceManager.format(Msg.MISSING_PARAMETER_IN_REQUEST, e.getReason(), "restoreStack"));
+ doFailure(rc, e.getStatus(), e.getMessage(), e);
+ } catch (Throwable t) {
+ String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(),
+ "restoreStack", vm_url, null == context ? "n/a" : context.getTenantName());
+ logger.error(msg, t);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg, t);
+ }
+ return stack;
+ }
+
+ @Override
+ protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException {
+
+ setMDC(Operation.RESTORE_STACK.toString(), "App-C IaaS Adapter:Restore-Stack", ADAPTER_NAME);
+ logOperation(Msg.RESTORING_STACK, params, context);
+ return restoreStack(params, context);
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/SnapshotStack.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/SnapshotStack.java
new file mode 100644
index 000000000..5014e759f
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/SnapshotStack.java
@@ -0,0 +1,237 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderOperation;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderStackOperation;
+import org.openecomp.appc.adapter.openstack.heat.SnapshotResource;
+import org.openecomp.appc.adapter.openstack.heat.StackResource;
+import org.openecomp.appc.adapter.openstack.heat.model.CreateSnapshotParams;
+import org.openecomp.appc.adapter.openstack.heat.model.Snapshot;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.OpenStackContext;
+import com.att.cdp.openstack.connectors.HeatConnector;
+import com.att.cdp.openstack.util.ExceptionMapper;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Stack;
+import com.att.cdp.zones.spi.RequestState;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import com.woorea.openstack.heat.Heat;
+import org.glassfish.grizzly.http.util.HttpStatus;
+
+import java.util.Map;
+
+import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME;
+
+import org.slf4j.MDC;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+
+/**
+ * @since September 26, 2016
+ */
+public class SnapshotStack extends ProviderStackOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(SnapshotStack.class);
+ private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+
+
+ private Snapshot snapshotStack(@SuppressWarnings("unused") RequestContext rc, Stack stack) throws ZoneException, RequestFailedException {
+ Snapshot snapshot = new Snapshot();
+ Context context = stack.getContext();
+
+ OpenStackContext osContext = (OpenStackContext)context;
+
+ final HeatConnector heatConnector = osContext.getHeatConnector();
+ ((OpenStackContext)context).refreshIfStale(heatConnector);
+
+ trackRequest(context);
+ RequestState.put("SERVICE", "Orchestration");
+ RequestState.put("SERVICE_URL", heatConnector.getEndpoint());
+
+ Heat heat = heatConnector.getClient();
+
+ SnapshotResource snapshotResource = new SnapshotResource(heat);
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "snapshot stack");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.SnapshotStack");
+
+ try {
+
+ snapshot = snapshotResource.create(stack.getName(), stack.getId(), new CreateSnapshotParams()).execute();
+
+ // wait for the stack deletion
+ StackResource stackResource = new StackResource(heat);
+ if (!waitForStack(stack, stackResource, "SNAPSHOT_COMPLETE")) {
+ throw new RequestFailedException("Stack Snapshot failed.");
+ }
+
+ } catch (OpenStackBaseException e) {
+ ExceptionMapper.mapException(e);
+ }
+
+ return snapshot;
+ }
+
+
+ public Stack snapshotStack(Map<String, String> params, SvcLogicContext ctx) throws IllegalArgumentException, APPCException {
+ Stack stack = null;
+ RequestContext rc = new RequestContext(ctx);
+ rc.isAlive();
+
+ ctx.setAttribute("SNAPSHOT_STATUS", "STACK_NOT_FOUND");
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+
+ String vm_url = null;
+ Context context = null;
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "snapshot stack");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.SnapshotStack");
+
+
+ try {
+
+ validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+ ProviderAdapter.PROPERTY_PROVIDER_NAME, ProviderAdapter.PROPERTY_STACK_ID);
+
+ String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID);
+ vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+
+ context = resolveContext(rc, params, appName, vm_url);
+
+ if (context != null) {
+ stack = lookupStack(rc, context, stackId);
+ logger.debug(Msg.STACK_FOUND, vm_url, context.getTenantName(), stack.getStatus().toString());
+ logger.info(EELFResourceManager.format(Msg.SNAPSHOTING_STACK, stack.getName()));
+ metricsLogger.info(EELFResourceManager.format(Msg.SNAPSHOTING_STACK, stack.getName()));
+
+ Snapshot snapshot = snapshotStack(rc, stack);
+
+ ctx.setAttribute(ProviderAdapter.DG_OUTPUT_PARAM_NAMESPACE +
+ ProviderAdapter.PROPERTY_SNAPSHOT_ID, snapshot.getId());
+
+ logger.info(EELFResourceManager.format(Msg.STACK_SNAPSHOTED, stack.getName(), snapshot.getId()));
+ metricsLogger.info(EELFResourceManager.format(Msg.STACK_SNAPSHOTED, stack.getName(), snapshot.getId()));
+ context.close();
+ doSuccess(rc);
+ } else {
+ ctx.setAttribute(Constants.DG_ATTRIBUTE_STATUS, "failure");
+ }
+
+ } catch (ResourceNotFoundException e) {
+ String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vm_url);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg, e);
+ } catch (RequestFailedException e) {
+ logger.error(EELFResourceManager.format(Msg.MISSING_PARAMETER_IN_REQUEST, e.getReason(), "snapshotStack"));
+ metricsLogger.error(EELFResourceManager.format(Msg.MISSING_PARAMETER_IN_REQUEST, e.getReason(), "snapshotStack"));
+ doFailure(rc, e.getStatus(), e.getMessage(), e);
+ } catch (Throwable t) {
+ String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(),
+ "snapshotStack", vm_url, null == context ? "n/a" : context.getTenantName());
+ logger.error(msg, t);
+ metricsLogger.error(msg);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg, t);
+ }
+ return stack;
+ }
+
+ @Override
+ protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException {
+ setMDC(Operation.SNAPSHOT_STACK.toString(), "App-C IaaS Adapter:Snapshot-Stack", ADAPTER_NAME);
+ logOperation(Msg.SNAPSHOTING_STACK, params, context);
+
+ /*
+ * Set Time for Metrics Logger
+ */
+ long startTime = System.currentTimeMillis();
+ TimeZone tz = TimeZone.getTimeZone("UTC");
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ df.setTimeZone(tz);
+ String startTimeStr = df.format(new Date());
+ long endTime = System.currentTimeMillis();
+ long duration = endTime - startTime;
+ String endTimeStr = String.valueOf(endTime);
+ String durationStr = String.valueOf(duration);
+ String endTimeStrUTC = df.format(new Date());
+ MDC.put("EndTimestamp", endTimeStrUTC);
+ MDC.put("ElapsedTime", durationStr);
+ MDC.put("TargetEntity", "cdp");
+ MDC.put("TargetServiceName", "snapshot stack");
+ MDC.put("ClassName", "org.openecomp.appc.adapter.iaas.provider.operation.impl.SnapshotStack");
+
+ metricsLogger.info("Executing Provider Operation: Snapshot Stack");
+
+ return snapshotStack(params, context);
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StartServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StartServer.java
new file mode 100644
index 000000000..41b0afd69
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StartServer.java
@@ -0,0 +1,186 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.IdentityURL;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.iaas.impl.VMURL;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.glassfish.grizzly.http.util.HttpStatus;
+
+import java.util.Map;
+
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.START_SERVICE;
+import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME;
+
+public class StartServer extends ProviderServerOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(StartServer.class);
+
+ /**
+ * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#startServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext)
+ */
+ @SuppressWarnings("nls")
+ public Server startServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
+ Server server = null;
+ RequestContext rc = new RequestContext(ctx);
+ rc.isAlive();
+
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+
+ try {
+ validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+ ProviderAdapter.PROPERTY_PROVIDER_NAME);
+
+ String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+
+ VMURL vm = VMURL.parseURL(vm_url);
+ if (validateVM(rc, appName, vm_url, vm)) return null;
+
+ IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+ String identStr = (ident == null) ? null : ident.toString();
+
+ Context context = null;
+ ctx.setAttribute("START_STATUS", "ERROR");
+ try {
+ context = getContext(rc, vm_url, identStr);
+ if (context != null) {
+ rc.reset();
+ server = lookupServer(rc, context, vm.getServerId());
+ logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString());
+ String msg;
+
+ /*
+ * We determine what to do based on the current state of the server
+ */
+
+ /*
+ * Pending is a bit of a special case. If we find the server is in a
+ * pending state, then the provider is in the process of changing state
+ * of the server. So, lets try to wait a little bit and see if the state
+ * settles down to one we can deal with. If not, then we have to fail
+ * the request.
+ */
+
+ if (server.getStatus().equals(Server.Status.PENDING)) {
+ waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR,
+ Server.Status.SUSPENDED, Server.Status.PAUSED, Server.Status.DELETED);
+ }
+
+ switch (server.getStatus()) {
+ case DELETED:
+ // Nothing to do, the server is gone
+ msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(),
+ server.getTenantId(), "started");
+ logger.error(msg);
+ // metricsLogger.error(msg);
+ throw new RequestFailedException("Start Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+
+ case RUNNING:
+ // Nothing to do, the server is already running
+ logger.info("Server was already running");
+ break;
+
+ case ERROR:
+ // Server is in error state
+ msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(),
+ server.getTenantId(), "start");
+ logger.error(msg);
+ // metricsLogger.error(msg);
+ throw new RequestFailedException("Start Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+
+ case READY:
+ // Server is stopped attempt to start the server
+ rc.reset();
+ startServer(rc, server);
+ break;
+
+ case PAUSED:
+ // if paused, un-pause it
+ rc.reset();
+ unpauseServer(rc, server);
+ // metricsLogger.info("Server status: PAUSED");
+ break;
+
+ case SUSPENDED:
+ // Attempt to resume the suspended server
+ rc.reset();
+ resumeServer(rc, server);
+ // metricsLogger.info("Server status: SUSPENDED");
+ break;
+
+ default:
+ // Hmmm, unknown status, should never occur
+ msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(),
+ server.getTenantId(), server.getStatus().name());
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ // metricsLogger.error(msg);
+ throw new RequestFailedException("Start Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+ }
+ context.close();
+ doSuccess(rc);
+ ctx.setAttribute("START_STATUS", "SUCCESS");
+ }
+ else
+ {
+ ctx.setAttribute("START_STATUS", "CONTEXT_NOT_FOUND");
+ }
+ } catch (ResourceNotFoundException e) {
+ String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ } catch (Throwable t) {
+ String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(),
+ START_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName());
+ logger.error(msg, t);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ }
+ } catch (RequestFailedException e) {
+ doFailure(rc, e.getStatus(), e.getMessage());
+ }
+
+ return server;
+ }
+
+ @Override
+ protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException {
+
+ setMDC(Operation.START_SERVICE.toString(), "App-C IaaS Adapter:Start", ADAPTER_NAME);
+ logOperation(Msg.STARTING_SERVER, params, context);
+ return startServer(params, context);
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StopServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StopServer.java
new file mode 100644
index 000000000..9429d5654
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/StopServer.java
@@ -0,0 +1,198 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.IdentityURL;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.iaas.impl.VMURL;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Outcome;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.glassfish.grizzly.http.util.HttpStatus;
+
+import java.util.Map;
+
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.STOP_SERVICE;
+import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME;
+
+
+public class StopServer extends ProviderServerOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(StopServer.class);
+ private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+
+ /**
+ * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#stopServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext)
+ */
+ @SuppressWarnings("nls")
+ public Server stopServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
+ Server server = null;
+ RequestContext rc = new RequestContext(ctx);
+ rc.isAlive();
+
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+
+ try {
+ validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+ ProviderAdapter.PROPERTY_PROVIDER_NAME);
+
+ String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+ ctx.setAttribute("STOP_STATUS", "SUCCESS");
+
+ VMURL vm = VMURL.parseURL(vm_url);
+ if (validateVM(rc, appName, vm_url, vm)) return null;
+
+ IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+ String identStr = (ident == null) ? null : ident.toString();
+
+ Context context = null;
+ ctx.setAttribute("STOP_STATUS", "ERROR");
+ try {
+ context = getContext(rc, vm_url, identStr);
+ if (context != null) {
+ rc.reset();
+ server = lookupServer(rc, context, vm.getServerId());
+ logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString());
+
+ String msg;
+ /*
+ * We determine what to do based on the current state of the server
+ */
+
+ /*
+ * Pending is a bit of a special case. If we find the server is in a
+ * pending state, then the provider is in the process of changing state
+ * of the server. So, lets try to wait a little bit and see if the state
+ * settles down to one we can deal with. If not, then we have to fail
+ * the request.
+ */
+
+ if (server.getStatus().equals(Server.Status.PENDING)) {
+ waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR,
+ Server.Status.SUSPENDED, Server.Status.PAUSED, Server.Status.DELETED);
+ }
+
+ switch (server.getStatus()) {
+ case DELETED:
+ // Nothing to do, the server is gone
+ msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(),
+ server.getTenantId(), "stopped");
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Stop Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+
+ case RUNNING:
+ // Attempt to stop the server
+ rc.reset();
+ stopServer(rc, server);
+ generateEvent(rc, true, Outcome.SUCCESS.toString());
+ break;
+
+ case ERROR:
+ // Server is in error state
+ msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(),
+ server.getTenantId(), "stop");
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Stop Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+
+ case READY:
+ // Nothing to do, the server was already stopped
+ logger.info("Server was already stopped");
+ break;
+
+ case PAUSED:
+ // if paused, un-pause it and then stop it
+ rc.reset();
+ unpauseServer(rc, server);
+ rc.reset();
+ stopServer(rc, server);
+ generateEvent(rc, true, Outcome.SUCCESS.toString());
+ break;
+
+ case SUSPENDED:
+ // Attempt to resume the suspended server and after that stop it
+ rc.reset();
+ resumeServer(rc, server);
+ rc.reset();
+ stopServer(rc, server);
+ generateEvent(rc, true, Outcome.SUCCESS.toString());
+ break;
+
+ default:
+ // Hmmm, unknown status, should never occur
+ msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(),
+ server.getTenantId(), server.getStatus().name());
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ metricsLogger.error(msg);
+ throw new RequestFailedException("Stop Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+ }
+ context.close();
+ doSuccess(rc);
+ ctx.setAttribute("STOP_STATUS", "SUCCESS");
+ msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "StopServer", vm_url);
+ ctx.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg);
+
+ }else{
+ ctx.setAttribute("STOP_STATUS", "CONTEXT_NOT_FOUND");
+ }
+ } catch (ResourceNotFoundException e) {
+ String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ } catch (Throwable t) {
+ String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(),
+ STOP_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName());
+ logger.error(msg, t);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ }
+ } catch (RequestFailedException e) {
+ logger.error(EELFResourceManager.format(Msg.STOP_SERVER_FAILED, appName, "n/a", "n/a", e.getMessage()));
+ doFailure(rc, e.getStatus(), e.getMessage());
+ }
+
+ return server;
+ }
+
+ @Override
+ protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException {
+
+ setMDC(STOP_SERVICE.toString(), "App-C IaaS Adapter:Stop", ADAPTER_NAME);
+ logOperation(Msg.STOPPING_SERVER, params, context);
+ return stopServer(params, context);
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateServer.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateServer.java
new file mode 100644
index 000000000..d0deda741
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateServer.java
@@ -0,0 +1,248 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.IdentityURL;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.iaas.impl.VMURL;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Outcome;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderOperation;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.exceptions.UnknownProviderException;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.slf4j.MDC;
+
+import java.util.Map;
+
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.RESTART_SERVICE;
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.STOP_SERVICE;
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.TERMINATE_SERVICE;
+import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME;
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
+
+public class TerminateServer extends ProviderServerOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(EvacuateServer.class);
+
+ /**
+ * Start the server and wait for it to enter a running state
+ *
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param server
+ * The server to be started
+ * @throws ZoneException
+ * @throws RequestFailedException
+ */
+ @SuppressWarnings("nls")
+ private void deleteServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+ String msg;
+ Context context = server.getContext();
+ Provider provider = context.getProvider();
+ ComputeService service = context.getComputeService();
+ while (rc.attempt()) {
+ try {
+ logger.info("deleting SERVER");
+ server.delete();
+ break;
+ } catch (ContextConnectionException e) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+ context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ rc.delay();
+ }
+ }
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+ logger.error(msg);
+ throw new RequestFailedException("Delete Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+ rc.reset();
+ }
+
+ /**
+ * This method handles the case of restarting a server once we have found the server and have obtained the abstract
+ * representation of the server via the context (i.e., the "Server" object from the CDP-Zones abstraction).
+ *
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param server
+ * The server object representing the server we want to operate on
+ * @throws ZoneException
+ */
+ @SuppressWarnings("nls")
+ private void terminateServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+ /*
+ * Pending is a bit of a special case. If we find the server is in a pending state, then the provider is in the
+ * process of changing state of the server. So, lets try to wait a little bit and see if the state settles down
+ * to one we can deal with. If not, then we have to fail the request.
+ */
+ String msg;
+ if (server.getStatus().equals(Server.Status.PENDING)) {
+ waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR, Server.Status.SUSPENDED, Server.Status.PAUSED);
+ }
+
+ /*
+ * We determine what to do based on the current state of the server
+ */
+ switch (server.getStatus()) {
+ case DELETED:
+ // Nothing to do, the server is gone
+ msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(),
+ server.getTenantId(), "restarted");
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ break;
+
+ case RUNNING:
+ // Attempt to stop and start the server
+ logger.info("stopping SERVER");
+ stopServer(rc, server);
+ deleteServer(rc, server);
+ logger.info("after delete SERVER");
+ generateEvent(rc, true, Outcome.SUCCESS.toString());
+ break;
+
+ case ERROR:
+
+ case READY:
+
+ case PAUSED:
+
+ case SUSPENDED:
+ // Attempt to delete the suspended server
+ deleteServer(rc, server);
+ generateEvent(rc, true, Outcome.SUCCESS.toString());
+ break;
+
+ default:
+ // Hmmm, unknown status, should never occur
+ msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(),
+ server.getTenantId(), server.getStatus().name());
+ generateEvent(rc, false, msg);
+ logger.error(msg);
+ break;
+ }
+
+ }
+
+ /**
+ * This method is used to delete an existing virtual machine given the fully qualified URL of the machine.
+ * <p>
+ * The fully qualified URL contains enough information to locate the appropriate server. The URL is of the form
+ * <pre>
+ * [scheme]://[host[:port]] / [path] / [tenant_id] / servers / [vm_id]
+ * </pre> Where the various parts of the URL can be parsed and extracted and used to locate the appropriate service
+ * in the provider service catalog. This then allows us to open a context using the CDP abstraction, obtain the
+ * server by its UUID, and then perform the restart.
+ * </p>
+ *
+ * @throws UnknownProviderException
+ * If the provider cannot be found
+ * @throws IllegalArgumentException
+ * if the expected argument(s) are not defined or are invalid
+ * @see org.openecomp.appc.adapter.iaas.ProviderAdapter#terminateServer(java.util.Map, org.openecomp.sdnc.sli.SvcLogicContext)
+ */
+ @SuppressWarnings("nls")
+ public Server terminateServer(Map<String, String> params, SvcLogicContext ctx)
+ throws UnknownProviderException, IllegalArgumentException {
+ Server server = null;
+ RequestContext rc = new RequestContext(ctx);
+ rc.isAlive();
+
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+
+ try {
+ validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+ ProviderAdapter.PROPERTY_PROVIDER_NAME);
+
+ String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+ ctx.setAttribute("TERMINATE_STATUS", "SUCCESS");
+
+ VMURL vm = VMURL.parseURL(vm_url);
+ if (validateVM(rc, appName, vm_url, vm)) return null;
+
+ IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+ String identStr = (ident == null) ? null : ident.toString();
+
+ Context context = null;
+ try {
+ context = getContext(rc, vm_url, identStr);
+ if (context != null) {
+ server = lookupServer(rc, context, vm.getServerId());
+ logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString());
+ logger.info(EELFResourceManager.format(Msg.TERMINATING_SERVER, server.getName()));
+ terminateServer(rc, server);
+ logger.info(EELFResourceManager.format(Msg.TERMINATE_SERVER, server.getName()));
+ context.close();
+ doSuccess(rc);
+ }else{
+ ctx.setAttribute("TERMINATE_STATUS", "SERVER_NOT_FOUND");
+ }
+ } catch (ResourceNotFoundException e) {
+ String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ ctx.setAttribute("TERMINATE_STATUS", "SERVER_NOT_FOUND");
+ } catch (Throwable t) {
+ String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(),
+ RESTART_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName());
+ logger.error(msg, t);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ }
+ } catch (RequestFailedException e) {
+ logger.error(EELFResourceManager.format(Msg.TERMINATE_SERVER_FAILED, appName, "n/a", "n/a", e.getMessage()));
+ doFailure(rc, e.getStatus(), e.getMessage());
+ ctx.setAttribute("TERMINATE_STATUS", "ERROR");
+ }
+
+ return server;
+ }
+
+ @Override
+ protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws UnknownProviderException {
+
+ setMDC(TERMINATE_SERVICE.toString(), "App-C IaaS Adapter:Terminate", ADAPTER_NAME);
+ logOperation(Msg.TERMINATING_SERVER, params, context);
+ return terminateServer(params,context);
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateStack.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateStack.java
new file mode 100644
index 000000000..220c00d8c
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/TerminateStack.java
@@ -0,0 +1,128 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderStackOperation;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.StackService;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Stack;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.glassfish.grizzly.http.util.HttpStatus;
+
+import java.util.Map;
+
+import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME;
+
+/**
+ * @since September 26, 2016
+ */
+public class TerminateStack extends ProviderStackOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(EvacuateServer.class);
+
+ private void deleteStack(RequestContext rc, Stack stack) throws ZoneException, RequestFailedException {
+ SvcLogicContext ctx = rc.getSvcLogicContext();
+ Context context = stack.getContext();
+ StackService stackService = context.getStackService();
+ logger.debug("Deleting Stack: " + "id:{ " + stack.getId() + "}");
+ stackService.deleteStack(stack);
+
+ // wait for the stack deletion
+ boolean success = waitForStackStatus(rc, stack, Stack.Status.DELETED);
+ if (success) {
+ ctx.setAttribute("TERMINATE_STATUS", "SUCCESS");
+ } else {
+ ctx.setAttribute("TERMINATE_STATUS", "ERROR");
+ throw new RequestFailedException("Delete Stack failure : " + Msg.STACK_OPERATION_EXCEPTION.toString());
+ }
+ }
+
+ @SuppressWarnings("nls")
+ public Stack terminateStack(Map<String, String> params, SvcLogicContext ctx) throws IllegalArgumentException, APPCException {
+ Stack stack = null;
+ RequestContext rc = new RequestContext(ctx);
+ rc.isAlive();
+
+ ctx.setAttribute("TERMINATE_STATUS", "STACK_NOT_FOUND");
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+
+ try {
+
+ validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+ ProviderAdapter.PROPERTY_PROVIDER_NAME, ProviderAdapter.PROPERTY_STACK_ID);
+
+ String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID);
+ String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+
+ Context context = resolveContext(rc, params, appName, vm_url);
+
+ try {
+ if (context != null) {
+ rc.reset();
+ stack = lookupStack(rc, context, stackId);
+ logger.debug(Msg.STACK_FOUND, vm_url, context.getTenantName(), stack.getStatus().toString());
+ logger.info(EELFResourceManager.format(Msg.TERMINATING_STACK, stack.getName()));
+ deleteStack(rc, stack);
+ logger.info(EELFResourceManager.format(Msg.TERMINATE_STACK, stack.getName()));
+ context.close();
+ doSuccess(rc);
+ String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "TerminateStack", vm_url);
+ ctx.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg);
+ }
+ } catch (ResourceNotFoundException e) {
+ String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vm_url);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ } catch (Throwable t) {
+ String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(),
+ Operation.TERMINATE_STACK.toString(), vm_url, context.getTenantName());
+ logger.error(msg, t);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ }
+ } catch (RequestFailedException e) {
+ logger.error(EELFResourceManager.format(Msg.TERMINATE_STACK_FAILED, appName, "n/a", "n/a"));
+ doFailure(rc, e.getStatus(), e.getMessage());
+ }
+ return stack;
+ }
+
+ @Override
+ protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException {
+
+ setMDC(Operation.TERMINATE_STACK.toString(), "App-C IaaS Adapter:Terminate-Stack", ADAPTER_NAME);
+ logOperation(Msg.TERMINATING_STACK, params, context);
+ return terminateStack(params, context);
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/VmStatuschecker.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/VmStatuschecker.java
new file mode 100644
index 000000000..0df17caa4
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/VmStatuschecker.java
@@ -0,0 +1,160 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.IdentityURL;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.iaas.impl.VMURL;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Outcome;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderOperation;
+import org.openecomp.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.exceptions.UnknownProviderException;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.slf4j.MDC;
+
+import java.util.Map;
+
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Operation.RESTART_SERVICE;
+import static org.openecomp.appc.adapter.utils.Constants.ADAPTER_NAME;
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
+
+
+public class VmStatuschecker extends ProviderServerOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(VmStatuschecker.class);
+ private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+ /* *********************************************************************************/
+ /* DEVEN PANCHAL: This method is used to check the status of the VM */
+ /**********************************************************************************/
+ public Server vmStatuschecker(Map<String, String> params, SvcLogicContext ctx) throws UnknownProviderException, IllegalArgumentException {
+ Server server = null;
+ RequestContext rc = new RequestContext(ctx);
+ rc.isAlive();
+
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+
+ try {
+ validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+ ProviderAdapter.PROPERTY_PROVIDER_NAME);
+
+ String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+
+ VMURL vm = VMURL.parseURL(vm_url);
+ if (validateVM(rc, appName, vm_url, vm)) return null;
+
+ IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+ String identStr = (ident == null) ? null : ident.toString();
+
+ Context context = null;
+ try {
+ context = getContext(rc, vm_url, identStr);
+ if (context != null) {
+ server = lookupServer(rc, context, vm.getServerId());
+ logger.debug(Msg.SERVER_FOUND, vm_url, context.getTenantName(), server.getStatus().toString());
+
+ String statusvm;
+ switch (server.getStatus()) {
+ case DELETED:
+ statusvm = "deleted";
+ break;
+
+ case RUNNING:
+ statusvm = "running";
+ break;
+
+ case ERROR:
+ statusvm = "error";
+ break;
+
+ case READY:
+ statusvm = "ready";
+ break;
+
+ case PAUSED:
+ statusvm = "paused";
+ break;
+
+ case SUSPENDED:
+ statusvm = "suspended";
+ break;
+
+ case PENDING:
+ statusvm = "pending";
+ break;
+
+ default:
+ statusvm = "default-unknown state-should never occur";
+ break;
+ }
+
+
+ String statusofVM = statusvm;
+ context.close();
+ SvcLogicContext svcLogic = rc.getSvcLogicContext();
+ svcLogic.setStatus(Outcome.SUCCESS.toString());
+ svcLogic.setAttribute("org.openecomp.statusofvm", statusofVM);
+ svcLogic.setAttribute(Constants.STATUS_OF_VM, statusofVM);
+ svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE, Integer.toString(HttpStatus.OK_200.getStatusCode()));
+ }
+ } catch (ResourceNotFoundException e) {
+ String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ } catch (Throwable t) {
+ String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, t, t.getClass().getSimpleName(),
+ RESTART_SERVICE.toString(), vm_url, context == null ? "Unknown" : context.getTenantName());
+ logger.error(msg, t);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ }
+ } catch (RequestFailedException e) {
+ doFailure(rc, e.getStatus(), e.getMessage());
+ }
+
+ return server;
+ }
+
+ /* *********************************************************************************/
+
+ @Override
+ protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws UnknownProviderException {
+
+ setMDC(Operation.VMSTATUSCHECK_SERVICE.toString(), "App-C IaaS Adapter:VmStatusCheck", ADAPTER_NAME);
+ logOperation(Msg.CHECKING_SERVER, params, context);
+ return vmStatuschecker(params, context);
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderOperation.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderOperation.java
new file mode 100644
index 000000000..58753f527
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderOperation.java
@@ -0,0 +1,457 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl.base;
+
+import org.openecomp.appc.adapter.iaas.ProviderAdapter;
+import org.openecomp.appc.adapter.iaas.impl.*;
+import org.openecomp.appc.adapter.iaas.provider.operation.api.IProviderOperation;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants;
+import org.openecomp.appc.adapter.iaas.provider.operation.common.enums.Outcome;
+import org.openecomp.appc.configuration.Configuration;
+import org.openecomp.appc.configuration.ConfigurationFactory;
+import org.openecomp.appc.exceptions.APPCException;
+import org.openecomp.appc.i18n.Msg;
+import org.openecomp.appc.pool.Pool;
+import org.openecomp.appc.pool.PoolExtensionException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.slf4j.MDC;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_ADAPTER;
+import static org.openecomp.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_SERVICE;
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
+
+/**
+ * @since September 26, 2016
+ */
+public abstract class ProviderOperation implements IProviderOperation {
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderOperation.class);
+ protected static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+ public void setProviderCache(Map<String, ProviderCache> providerCache) {
+ this.providerCache = providerCache;
+ }
+
+ /**
+ * A cache of providers that are predefined.
+ */
+ private Map<String /* provider name */, ProviderCache> providerCache;
+
+
+ public void setDefaultUser(String defaultUser) {
+ DEFAULT_USER = defaultUser;
+ }
+
+ public void setDefaultPass(String defaultPass) {
+ DEFAULT_PASS = defaultPass;
+ }
+
+ /**
+ * The username and password to use for dynamically created connections
+ */
+ private static String DEFAULT_USER;
+ private static String DEFAULT_PASS;
+
+
+ /**
+ * set MDC props
+ * @param service
+ * @param serviceName
+ * @param adapterName
+ */
+ protected void setMDC(String service, String serviceName, String adapterName){
+ MDC.put(MDC_ADAPTER, adapterName);
+ MDC.put(MDC_SERVICE, service);
+ MDC.put(MDC_SERVICE_NAME, serviceName);
+ }
+
+ /**
+ * initial log of the operation
+ * @param msg
+ * @param params
+ * @param context
+ */
+ protected void logOperation(Msg msg, Map<String, String> params, SvcLogicContext context){
+
+ String appName = configuration.getProperty(org.openecomp.appc.Constants.PROPERTY_APPLICATION_NAME);
+ logger.info(msg, appName);
+
+ debugParameters(params);
+ debugContext(context);
+ }
+
+ /**
+ * This method is used to dump the value of the parameters to the log for debugging purposes.
+ *
+ * @param parameters
+ * The parameters to be printed to the log
+ */
+ private void debugParameters(Map<String, String> parameters) {
+ for (String key : parameters.keySet()) {
+ logger.debug(Msg.PROPERTY_VALUE, key, parameters.get(key));
+ }
+ }
+
+ /**
+ * This method is used to create a diagnostic dump of the context for the log
+ *
+ * @param context
+ * The context to be dumped
+ */
+ @SuppressWarnings({
+ "nls", "static-method"
+ })
+ private void debugContext(SvcLogicContext context) {
+ Set<String> keys = context.getAttributeKeySet();
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("Service Logic Context: Status ");
+ builder.append(Constants.LPAREN);
+ builder.append(context.getStatus());
+ builder.append(Constants.RPAREN);
+ builder.append(", Attribute count ");
+ builder.append(Constants.LPAREN);
+ builder.append(keys == null ? "none" : Integer.toString(keys.size()));
+ builder.append(Constants.RPAREN);
+ if (keys != null && !keys.isEmpty()) {
+ builder.append(Constants.NL);
+ for (String key : keys) {
+ String value = context.getAttribute(key);
+ builder.append("Attribute ");
+ builder.append(Constants.LPAREN);
+ builder.append(key);
+ builder.append(Constants.RPAREN);
+ builder.append(", value ");
+ builder.append(Constants.LPAREN);
+ builder.append(value == null ? "" : value);
+ builder.append(Constants.RPAREN);
+ builder.append(Constants.NL);
+ }
+ }
+
+ logger.debug(builder.toString());
+ }
+
+
+ /**
+ * This method is used to validate that the parameters contain all required property names, and that the values are
+ * non-null and non-empty strings. We are still not ensured that the value is valid, but at least it exists.
+ *
+ * @param parameters
+ * The parameters to be checked
+ * @param propertyNames
+ * The list of property names that are required to be present.
+ * @throws RequestFailedException
+ * If the parameters are not valid
+ */
+ protected void validateParametersExist(Map<String, String> parameters, String... propertyNames)
+ throws RequestFailedException {
+ boolean success = true;
+ StringBuilder msg = new StringBuilder(EELFResourceManager.format(Msg.MISSING_REQUIRED_PROPERTIES, MDC.get(MDC_SERVICE)));
+ msg.append(Constants.NL);
+ for (String propertyName : propertyNames) {
+ String value = parameters.get(propertyName);
+ if (value == null || value.trim().length() == 0) {
+ success = false;
+ msg.append(Constants.QUOTE);
+ msg.append(propertyName);
+ msg.append(Constants.QUOTE);
+ msg.append(Constants.SPACE);
+ }
+ }
+
+ if (!success) {
+ logger.error(msg.toString());
+ throw new RequestFailedException("Check Parameters", msg.toString(), HttpStatus.BAD_REQUEST_400, (Server)null);
+ }
+ }
+
+ /**
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param code
+ * @param message
+ */
+ protected void doFailure(RequestContext rc, HttpStatus code, String message) {
+ try {
+ doFailure(rc, code, message, null);
+ } catch (APPCException ignored) {/* never happens */}
+ }
+
+ protected void doFailure(RequestContext rc, HttpStatus code, String message, Throwable cause) throws APPCException {
+ SvcLogicContext svcLogic = rc.getSvcLogicContext();
+ String msg = (message == null) ? code.getReasonPhrase() : message;
+ if (msg.contains("\n")) {
+ msg = msg.substring(0, msg.indexOf("\n"));
+ }
+ String status;
+ try {
+ status = Integer.toString(code.getStatusCode());
+ } catch (Exception e) {
+ status = "500";
+ }
+ svcLogic.setStatus(Outcome.FAILURE.toString());
+ svcLogic.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_ERROR_CODE, status);
+ svcLogic.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_ERROR_MESSAGE, msg);
+
+ if (null != cause) throw new APPCException(cause);
+ }
+
+ /**
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ */
+ @SuppressWarnings("static-method")
+ protected void doSuccess(RequestContext rc) {
+ SvcLogicContext svcLogic = rc.getSvcLogicContext();
+ svcLogic.setStatus(Outcome.SUCCESS.toString());
+ svcLogic.setAttribute(org.openecomp.appc.Constants.ATTRIBUTE_ERROR_CODE, Integer.toString(HttpStatus.OK_200.getStatusCode()));
+ }
+
+ protected boolean validateVM(RequestContext rc, String appName, String vm_url, VMURL vm)
+ throws RequestFailedException {
+ String msg;
+ if (vm == null) {
+ msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vm_url);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ return true;
+ }
+ validateVMURL(vm);
+ return false;
+ }
+
+ protected void validateVMURL(VMURL vm) throws RequestFailedException {
+ String name = "vm-id";
+ if (vm == null) {
+ throw new RequestFailedException(String.format("The value %s cannot be null.", name));
+ }
+
+ // Check that its a good uri
+ // This will probably never get hit bc of an earlier check while parsing
+ // the string to a VMURL
+ try {
+ //noinspection ResultOfMethodCallIgnored
+ URI.create(vm.toString());
+ } catch (Exception e) {
+ throw new RequestFailedException(
+ String.format("The value %s is not well formed [%s].", name, vm.toString()));
+ }
+
+ // Check the tenant and vmid segments
+ String patternRegex = "([0-9a-f]{8}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{12})";
+ Pattern pattern = Pattern.compile(patternRegex, Pattern.CASE_INSENSITIVE);
+
+ if (!pattern.matcher(vm.getTenantId()).matches()) {
+ throw new RequestFailedException(
+ String.format("The value %s has an invalid tenantId [%s].", name, vm.getTenantId()));
+ }
+ if (!pattern.matcher(vm.getServerId()).matches()) {
+ throw new RequestFailedException(
+ String.format("The value %s has an invalid serverId [%s].", name, vm.getServerId()));
+ }
+ }
+
+ private ProviderCache createProviderCache(VMURL vm, IdentityURL ident) {
+ if (vm != null && ident != null) {
+ ProviderCache cache = new ProviderCache();
+
+ cache.setIdentityURL(ident.toString());
+ cache.setProviderName(ident.toString());
+ // cache.setProviderType("OpenStack");
+
+ TenantCache tenant = cache.addTenant(vm.getTenantId(),null, DEFAULT_USER, DEFAULT_PASS);
+
+ // Make sure we could initialize the the cache otherwise return null
+ if (tenant != null && tenant.isInitialized()) {
+ return cache;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * This method is a general helper method used to locate a server given its fully-qualified self-link URL on a
+ * supported provider, regardless of region(s), and to return an opened context that can be used to access that
+ * server.
+ *
+ * @param rc
+ * The request context that wraps and manages the state of the request
+ * @param selfLinkURL
+ * The fully-qualified self-link URL of the server
+ * @param providerName
+ * The name of the provider to be searched
+ * @return The context that can be used to access the server, or null if not found.
+ */
+ @SuppressWarnings("nls")
+ protected Context getContext(RequestContext rc, String selfLinkURL, String providerName) {
+ VMURL vm = VMURL.parseURL(selfLinkURL);
+ IdentityURL ident = IdentityURL.parseURL(providerName);
+ String appName = configuration.getProperty(org.openecomp.appc.Constants.PROPERTY_APPLICATION_NAME);
+
+ if (vm == null) {
+ String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, selfLinkURL);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ return null;
+ }
+
+ /*
+ * Get the cache of tenants and contexts for the named provider, if one exists
+ */
+ ProviderCache cache = providerCache.get(providerName);
+
+ /*
+ * If one doesn't exist, try and create it. If we have enough information to create it successfully, add it to
+ * the cache and continue, otherwise fail the request.
+ */
+ if (cache == null) {
+ if (ident != null) {
+ cache = createProviderCache(vm, ident);
+ }
+ if (cache != null) {
+ providerCache.put(cache.getProviderName(), cache);
+ } else {
+ String msg =
+ EELFResourceManager.format(Msg.UNKNOWN_PROVIDER, providerName, providerCache.keySet().toString());
+ logger.error(msg);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ return null;
+ }
+ }
+
+ if (providerName == null) {
+ logger
+ .debug(String.format("Using the default provider cache [%s] since no valid identity url was passed in.",
+ cache.getIdentityURL()));
+ }
+
+ // get the tenant cache for the vm
+ String identityURL = cache.getIdentityURL();
+ TenantCache tenantCache = cache.getTenant(vm.getTenantId());
+
+ if(tenantCache == null){
+ //no tenantCache matching tenant, add tenant to the provider cache
+ tenantCache = cache.addTenant(vm.getTenantId(),null,DEFAULT_USER, DEFAULT_PASS);
+
+ if(tenantCache == null){
+ //tenant not found
+ String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ return null;
+ }
+ }
+
+ //reserve the context
+ String tenantName = tenantCache.getTenantName();
+ String tenantId = tenantCache.getTenantId();
+ String region = tenantCache.determineRegion(vm);
+
+ if (region != null) {
+ Pool<Context> pool = tenantCache.getPools().get(region);
+
+ while (rc.attempt()) {
+ try {
+ Context context = pool.reserve();
+
+ /*
+ * Insert logic here to test the context for connectivity because we may have gotten one from
+ * the pool that was previously created.
+ */
+ if (context.isStale()) {
+ context.relogin();
+ }
+ return context;
+ } catch (PoolExtensionException e) {
+ String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, providerName, identityURL,
+ tenantName, tenantId, e.getMessage(), Long.toString(rc.getRetryDelay()),
+ Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ rc.delay();
+ } catch (Exception e) {
+ String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e,
+ e.getClass().getSimpleName(), "find", selfLinkURL, tenantCache.getTenantName());
+
+ logger.error(msg, e);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ return null;
+ }
+ }
+
+ String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, providerName, identityURL);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg);
+ return null;
+ }
+
+
+ String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ return null;
+ }
+
+ protected Context resolveContext(RequestContext rc, Map<String, String> params, String appName, String vm_url)
+ throws RequestFailedException {
+
+ VMURL vm = VMURL.parseURL(vm_url);
+ if (vm == null) {
+ String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vm_url);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ logger.error(msg);
+ return null;
+ }
+ validateVMURL(vm);
+ IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+ String identStr = (ident == null) ? null : ident.toString();
+
+ return getContext(rc, vm_url, identStr);
+
+ }
+
+
+
+
+
+
+
+ protected abstract ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context) throws APPCException;
+
+ @Override
+ public ModelObject doOperation(Map<String, String> params, SvcLogicContext context) throws APPCException {
+
+ return executeProviderOperation(params,context);
+ }
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderServerOperation.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderServerOperation.java
new file mode 100644
index 000000000..0a27a7ac9
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderServerOperation.java
@@ -0,0 +1,573 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl.base;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.impl.*;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.NotLoggedInException;
+import com.att.cdp.exceptions.TimeoutException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.pal.util.StringHelper;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.ImageService;
+import com.att.cdp.zones.NetworkService;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.model.Hypervisor;
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.Network;
+import com.att.cdp.zones.model.Port;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @since September 29, 2016
+ */
+public abstract class ProviderServerOperation extends ProviderOperation{
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderServerOperation.class);
+
+ /**
+ * Looks up the indicated server using the provided context and returns the server to the caller
+ *
+ * @param rc
+ * The request context
+ * @param context
+ * The provider context
+ * @param id
+ * The id of the server
+ * @return The server, or null if there is a problem
+ * @throws ZoneException
+ * If the server cannot be found
+ * @throws RequestFailedException
+ * If the server cannot be found because we cant connect to the provider
+ */
+ @SuppressWarnings("nls")
+ protected Server lookupServer(RequestContext rc, Context context, String id)
+ throws ZoneException, RequestFailedException {
+ ComputeService service = context.getComputeService();
+ Server server = null;
+ String msg;
+ Provider provider = context.getProvider();
+
+ while (rc.attempt()) {
+ try {
+ server = service.getServer(id);
+ break;
+ } catch (ContextConnectionException e) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+ context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ rc.delay();
+ }
+ }
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+ logger.error(msg);
+ doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg);
+ throw new RequestFailedException("Lookup Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+ return server;
+ }
+
+
+
+ /**
+ * Resume a suspended server and wait for it to enter a running state
+ *
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param server
+ * The server to be resumed
+ * @throws ZoneException
+ * @throws RequestFailedException
+ */
+ @SuppressWarnings("nls")
+ protected void resumeServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+ logger.debug(Msg.RESUME_SERVER, server.getId());
+
+ Context context = server.getContext();
+ String msg;
+ Provider provider = context.getProvider();
+ ComputeService service = context.getComputeService();
+ while (rc.attempt()) {
+ try {
+ server.resume();
+ break;
+ } catch (ContextConnectionException e) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+ context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ rc.delay();
+ }
+ }
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+ logger.error(msg);
+ throw new RequestFailedException("Resume Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+ rc.reset();
+ waitForStateChange(rc, server, Server.Status.RUNNING);
+ }
+
+
+ protected boolean hasImageAccess(@SuppressWarnings("unused") RequestContext rc, Context context) {
+ logger.info("Checking permissions for image service.");
+ try {
+ ImageService service = context.getImageService();
+ service.getImageByName("CHECK_IMAGE_ACCESS");
+ logger.info("Image service is accessible.");
+ return true;
+ } catch (ZoneException e) {
+ logger.warn("Image service could not be accessed. Some operations may fail.", e);
+ return false;
+ }
+ }
+
+
+ /**
+ * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not.
+ * <p>
+ * This method checks the state of the server periodically for one of the desired states. When the server enters one
+ * of the desired states, the method returns a successful indication (true). If the server never enters one of the
+ * desired states within the allocated timeout period, then the method returns a failed response (false). No
+ * exceptions are thrown from this method.
+ * </p>
+ *
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param image
+ * The server to wait on
+ * @param desiredStates
+ * A variable list of desired states, any one of which is allowed.
+ * @throws RequestFailedException
+ * If the request times out or fails for some reason
+ * @throws NotLoggedInException
+ */
+ @SuppressWarnings("nls")
+ protected void waitForStateChange(RequestContext rc, Image image, Image.Status... desiredStates)
+ throws RequestFailedException, NotLoggedInException {
+ int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL);
+ int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT);
+ Context context = image.getContext();
+ Provider provider = context.getProvider();
+ ImageService service = context.getImageService();
+ String msg;
+
+ long endTime = System.currentTimeMillis() + (timeout * 1000); //
+
+ while (rc.attempt()) {
+ try {
+ try {
+ image.waitForStateChange(pollInterval, timeout, desiredStates);
+ break;
+ } catch (TimeoutException e) {
+ @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
+ List<String> list = new ArrayList<>();
+ for (Image.Status desiredState : desiredStates) {
+ list.add(desiredState.name());
+ }
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+ context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ rc.delay();
+ }
+ } catch (ZoneException e) {
+ List<String> list = new ArrayList<>();
+ for (Image.Status desiredState : desiredStates) {
+ list.add(desiredState.name());
+ }
+ String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(),
+ "server", image.getName(), image.getId(), StringHelper.asList(list), image.getStatus().name(),
+ e.getMessage());
+ logger.error(reason);
+ logger.error(EELFResourceManager.format(e));
+
+ // Instead of failing we are going to wait and try again.
+ // Timeout is reduced by delay time
+ logger.info(String.format("Retrying in %ds", rc.getRetryDelay()));
+ rc.delay();
+ timeout = (int) (endTime - System.currentTimeMillis()) / 1000;
+ // throw new RequestFailedException(e, operation, reason,
+ // HttpStatus.BAD_GATEWAY_502, server);
+ }
+ }
+
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+ logger.error(msg);
+ throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, new Server());
+ }
+ rc.reset();
+ }
+
+
+ /**
+ * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not.
+ * <p>
+ * This method checks the state of the server periodically for one of the desired states. When the server enters one
+ * of the desired states, the method returns a successful indication (true). If the server never enters one of the
+ * desired states within the allocated timeout period, then the method returns a failed response (false). No
+ * exceptions are thrown from this method.
+ * </p>
+ *
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param server
+ * The server to wait on
+ * @param desiredStates
+ * A variable list of desired states, any one of which is allowed.
+ * @throws RequestFailedException
+ * If the request times out or fails for some reason
+ */
+ @SuppressWarnings("nls")
+ protected void waitForStateChange(RequestContext rc, Server server, Server.Status... desiredStates)
+ throws RequestFailedException {
+ int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL);
+ int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT);
+ Context context = server.getContext();
+ Provider provider = context.getProvider();
+ ComputeService service = context.getComputeService();
+ String msg;
+
+ long endTime = System.currentTimeMillis() + (timeout * 1000); //
+
+ while (rc.attempt()) {
+ try {
+ try {
+ server.waitForStateChange(pollInterval, timeout, desiredStates);
+ break;
+ } catch (TimeoutException e) {
+ @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
+ List<String> list = new ArrayList<>();
+ for (Server.Status desiredState : desiredStates) {
+ list.add(desiredState.name());
+ }
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+ context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ rc.delay();
+ }
+ } catch (ZoneException e) {
+ List<String> list = new ArrayList<>();
+ for (Server.Status desiredState : desiredStates) {
+ list.add(desiredState.name());
+ }
+ String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(),
+ "server", server.getName(), server.getId(), StringHelper.asList(list), server.getStatus().name(),
+ e.getMessage());
+ logger.error(reason);
+ logger.error(EELFResourceManager.format(e));
+
+ // Instead of failing we are going to wait and try again.
+ // Timeout is reduced by delay time
+ logger.info(String.format("Retrying in %ds", rc.getRetryDelay()));
+ rc.delay();
+ timeout = (int) (endTime - System.currentTimeMillis()) / 1000;
+ // throw new RequestFailedException(e, operation, reason,
+ // HttpStatus.BAD_GATEWAY_502, server);
+ }
+ }
+
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+ logger.error(msg);
+ throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+ rc.reset();
+ }
+
+ /**
+ * Stop the specified server and wait for it to stop
+ *
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param server
+ * The server to be stopped
+ * @throws ZoneException
+ * @throws RequestFailedException
+ */
+ @SuppressWarnings("nls")
+ protected void stopServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+ logger.debug(Msg.STOP_SERVER, server.getId());
+
+ String msg;
+ Context context = server.getContext();
+ Provider provider = context.getProvider();
+ ComputeService service = context.getComputeService();
+ while (rc.attempt()) {
+ try {
+ server.stop();
+ break;
+ } catch (ContextConnectionException e) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+ context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ rc.delay();
+ }
+ }
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+ logger.error(msg);
+ throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+ rc.reset();
+ waitForStateChange(rc, server, Server.Status.READY, Server.Status.ERROR);
+ }
+
+ /**
+ * Start the server and wait for it to enter a running state
+ *
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param server
+ * The server to be started
+ * @throws ZoneException
+ * @throws RequestFailedException
+ */
+ @SuppressWarnings("nls")
+ protected void startServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+ logger.debug(Msg.START_SERVER, server.getId());
+ String msg;
+ Context context = server.getContext();
+ Provider provider = context.getProvider();
+ ComputeService service = context.getComputeService();
+ while (rc.attempt()) {
+ try {
+ server.start();
+ break;
+ } catch (ContextConnectionException e) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+ context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ rc.delay();
+ }
+ }
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+ logger.error(msg);
+ throw new RequestFailedException("Start Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+ rc.reset();
+ waitForStateChange(rc, server, Server.Status.RUNNING);
+ }
+
+
+ /**
+ * Un-Pause a paused server and wait for it to enter a running state
+ *
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param server
+ * The server to be un-paused
+ * @throws ZoneException
+ * @throws RequestFailedException
+ */
+ @SuppressWarnings("nls")
+ protected void unpauseServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+ logger.debug(Msg.UNPAUSE_SERVER, server.getId());
+
+ String msg;
+ Context context = server.getContext();
+ Provider provider = context.getProvider();
+ ComputeService service = context.getComputeService();
+ while (rc.attempt()) {
+ try {
+ server.unpause();
+ break;
+ } catch (ContextConnectionException e) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+ context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ rc.delay();
+ }
+ }
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+ logger.error(msg);
+ throw new RequestFailedException("Unpause Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+ }
+ rc.reset();
+ waitForStateChange(rc, server, Server.Status.RUNNING, Server.Status.READY);
+ }
+
+
+ /**
+ * Generates the event indicating what happened
+ *
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param success
+ * True if the event represents a successful outcome
+ * @param msg
+ * The detailed message
+ */
+ protected void generateEvent(@SuppressWarnings("unused") RequestContext rc, @SuppressWarnings("unused") boolean success, @SuppressWarnings("unused") String msg) {
+ // indication to the DG to generate the event?
+ }
+
+ /**
+ * Checks if the VM is connected to the Virtual Network and reachable
+ *
+ * @param rc
+ * The request context that manages the state and recovery of the request for the life of its processing.
+ * @param server
+ * The server object representing the server we want to operate on
+ * @param context
+ * The interface cloud service provider to access services or the object model, or both
+
+ */
+ protected void checkVirtualMachineNetworkStatus(RequestContext rc, Server server, Context context)
+ throws ZoneException, RequestFailedException {
+
+ logger.info("Performing the VM Server networking status checks...");
+ List<Port> ports = server.getPorts();
+
+ NetworkService netSvc = context.getNetworkService();
+
+ String msg;
+ for (Port port : ports) {
+
+ switch (port.getPortState().toString().toUpperCase()) {
+ /**
+ * The port is connected, configured, and usable for communication
+ */
+ case "ONLINE":
+ Network network = netSvc.getNetworkById(port.getNetwork());
+ // Subnet subnet = netSvc.getSubnetById(port.getSubnetId());
+ if (!network.getStatus().equals(Network.Status.ACTIVE.toString())) {
+ msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId());
+ logger.error(msg);
+ doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
+ throw new RequestFailedException("VM Server Network is DOWN", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
+ server);
+ }
+ break;
+
+ /**
+ * The port is disconnected or powered-off and cannot be used for
+ * communication
+ */
+ case "OFFLINE":
+ msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId());
+ logger.error(msg);
+ doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
+ throw new RequestFailedException("VM Server Port status is OFFLINE", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
+ server);
+
+ /**
+ * The port's status is changing because of some event or operation.
+ * The final state is yet to be determined.
+ */
+ case "PENDING":
+ msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId());
+ logger.error(msg);
+ doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
+ throw new RequestFailedException("VM Server Port status is PENDING", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
+ server);
+
+ /**
+ * The port is in an unknown state and cannot be used.
+ */
+ case "UNKNOWN":
+ msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId());
+ logger.error(msg);
+ doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
+ throw new RequestFailedException("VM Server Port status is UNKNOWN", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
+ server);
+ }
+
+ }
+ logger.info("Passed the VM Server the Hypervisor status checks..");
+
+ }
+
+ /**
+ * Checks if the VM is connected to the Virtual Network and reachable
+ *
+ * @param server
+ * The server object representing the server we want to operate on
+ */
+ protected void checkHypervisor(Server server)
+ throws ZoneException, RequestFailedException {
+
+ logger.info("Performing the Hypervisor status checks..");
+ String status = null, state = null, msg = null;
+
+ status = server.getHypervisor().getStatus().toString();
+ state = server.getHypervisor().getState().toString();
+
+ if (!status.equals(Hypervisor.Status.ENABLED.toString()) || !state.equals(Hypervisor.State.UP.toString())) {
+ msg = EELFResourceManager.format(Msg.HYPERVISOR_DOWN_ERROR, server.getHypervisor().getHostName(), server.getName());
+ logger.error(msg.toString());
+
+ //doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
+ throw new RequestFailedException("Hypervisor status DOWN or NOT ENABLED", msg.toString(), HttpStatus.PRECONDITION_FAILED_412,
+ server);
+
+ }
+
+ logger.info("Passed the Hypervisor status checks..");
+
+ }
+
+ /**
+ * Checks if a Host machine is reachable
+ *
+ * @param ipAddress
+ * IP Address of the Host Machine.
+ * @param server
+ * The server object representing the Virtual Machine server
+ * @return boolean
+ *
+ */
+ /*private boolean isHostReachable(String ipAddress) throws IOException {
+
+ InetAddress address = InetAddress.getByName(ipAddress);
+
+ return address.isReachable(15000);
+
+
+ }*/
+
+}
diff --git a/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderStackOperation.java b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderStackOperation.java
new file mode 100644
index 000000000..2eb2b69cf
--- /dev/null
+++ b/appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/openecomp/appc/adapter/iaas/provider/operation/impl/base/ProviderStackOperation.java
@@ -0,0 +1,186 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * openECOMP : APP-C
+ * ================================================================================
+ * 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.openecomp.appc.adapter.iaas.provider.operation.impl.base;
+
+import org.openecomp.appc.Constants;
+import org.openecomp.appc.adapter.iaas.impl.RequestContext;
+import org.openecomp.appc.adapter.iaas.impl.RequestFailedException;
+import org.openecomp.appc.adapter.openstack.heat.StackResource;
+import org.openecomp.appc.i18n.Msg;
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.TimeoutException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.StackService;
+import com.att.cdp.zones.model.Stack;
+import com.att.cdp.zones.spi.AbstractService;
+import com.att.cdp.zones.spi.RequestState;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import org.openecomp.sdnc.sli.SvcLogicContext;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import org.glassfish.grizzly.http.util.HttpStatus;
+
+import java.util.List;
+
+/**
+ * @since September 29, 2016
+ */
+public abstract class ProviderStackOperation extends ProviderOperation{
+
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderStackOperation.class);
+
+
+ protected void trackRequest(Context context, AbstractService.State... states) {
+ RequestState.clear();
+
+ if (null == states) return;
+ for (AbstractService.State state : states) {
+ RequestState.put(state.getName(), state.getValue());
+ }
+
+ Thread currentThread = Thread.currentThread();
+ StackTraceElement[] stack = currentThread.getStackTrace();
+ if (stack != null && stack.length > 0) {
+ int index = 0;
+ StackTraceElement element;
+ for (; index < stack.length; index++) {
+ element = stack[index];
+ if ("trackRequest".equals(element.getMethodName())) { //$NON-NLS-1$
+ break;
+ }
+ }
+ index++;
+
+ if (index < stack.length) {
+ element = stack[index];
+ RequestState.put(RequestState.METHOD, element.getMethodName());
+ RequestState.put(RequestState.CLASS, element.getClassName());
+ RequestState.put(RequestState.LINE_NUMBER, Integer.toString(element.getLineNumber()));
+ RequestState.put(RequestState.THREAD, currentThread.getName());
+ RequestState.put(RequestState.PROVIDER, context.getProvider().getName());
+ RequestState.put(RequestState.TENANT, context.getTenantName());
+ RequestState.put(RequestState.PRINCIPAL, context.getPrincipal());
+ }
+ }
+ }
+
+ private boolean checkStatus(String expectedStatus, int pollInterval, String actualStatus) {
+ if (actualStatus.toUpperCase().equals(expectedStatus)) {
+ return true;
+ } else {
+ try {
+ Thread.sleep(pollInterval * 1000);
+ } catch (InterruptedException ignored) {
+ }
+ }
+ return false;
+ }
+
+ protected boolean waitForStack(Stack stack, StackResource stackResource, String expectedStatus)
+ throws OpenStackBaseException, TimeoutException {
+ int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL);
+ int timeout = configuration.getIntegerProperty(Constants.PROPERTY_STACK_STATE_CHANGE_TIMEOUT);
+ long maxTimeToWait = System.currentTimeMillis() + (long) timeout * 1000;
+
+ while (System.currentTimeMillis() < maxTimeToWait) {
+ String stackStatus = stackResource.show(stack.getName(), stack.getId()).execute().getStackStatus();
+ logger.debug("Stack status : " + stackStatus);
+ if (stackStatus.toUpperCase().contains("FAILED")) return false;
+ if(checkStatus(expectedStatus, pollInterval, stackStatus)) return true;
+ }
+ throw new TimeoutException("Timeout waiting for stack status change");
+ }
+
+ protected Stack lookupStack(RequestContext rc, Context context, String id)
+ throws ZoneException, RequestFailedException {
+ StackService stackService = context.getStackService();
+ Stack stack = null;
+ String msg;
+ Provider provider = context.getProvider();
+ while (rc.attempt()) {
+ try {
+ List<Stack> stackList = stackService.getStacks();
+ for (Stack stackObj : stackList) {
+ if (stackObj.getId().equals(id)) {
+ stack = stackObj;
+ break;
+ }
+ }
+ break;
+ } catch (ContextConnectionException e) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), stackService.getURL(),
+ context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+ Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+ Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ rc.delay();
+ }
+
+ }
+ if (rc.isFailed()) {
+ msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), stackService.getURL());
+ logger.error(msg);
+ doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg);
+ throw new RequestFailedException("Lookup Stack", msg, HttpStatus.BAD_GATEWAY_502, stack);
+ }
+
+ if (stack == null) {
+ throw new ResourceNotFoundException("Stack not found with Id : {" + id + "}");
+ }
+ return stack;
+ }
+
+
+ protected boolean waitForStackStatus(RequestContext rc, Stack stack, Stack.Status expectedStatus) throws ZoneException, RequestFailedException {
+ SvcLogicContext ctx = rc.getSvcLogicContext();
+ Context context = stack.getContext();
+ StackService stackService = context.getStackService();
+
+ int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL);
+ int timeout = configuration.getIntegerProperty(Constants.PROPERTY_STACK_STATE_CHANGE_TIMEOUT);
+ long maxTimeToWait = System.currentTimeMillis() + (long) timeout * 1000;
+ Stack.Status stackStatus;
+ while (System.currentTimeMillis() < maxTimeToWait) {
+ stackStatus = stackService.getStack(stack.getName(), stack.getId()).getStatus();
+ logger.debug("Stack status : " + stackStatus.toString());
+ if (stackStatus == expectedStatus) {
+ return true;
+ } else if (stackStatus == Stack.Status.FAILED) {
+ return false;
+ } else {
+ try {
+ Thread.sleep(pollInterval * 1000);
+ } catch (InterruptedException e) {
+ logger.trace("Sleep threw interrupted exception, should never occur");
+ }
+ }
+ }
+
+ ctx.setAttribute("TERMINATE_STATUS", "ERROR");
+ throw new TimeoutException("Timeout waiting for stack status change");
+
+ }
+}