bugfix for error handling while detaching volumes 87/36887/3
authorModaboina, Kusumakumari (km583p) <km583p@us.att.com>
Tue, 20 Mar 2018 02:09:28 +0000 (22:09 -0400)
committerTakamune Cho <tc012c@att.com>
Wed, 21 Mar 2018 17:28:59 +0000 (17:28 +0000)
Change-Id: I96f7d017a63b0741d87666f4608356567932ff77
Issue-ID: APPC-762
Signed-off-by: Modaboina, Kusumakumari (km583p) <km583p@us.att.com>
appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/onap/appc/adapter/iaas/provider/operation/impl/DettachVolumeServer.java
appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/onap/appc/adapter/iaas/provider/operation/impl/MigrateServer.java
appc-adapters/appc-iaas-adapter/appc-iaas-adapter-bundle/src/main/java/org/onap/appc/adapter/iaas/provider/operation/impl/base/ProviderOperation.java

index d9b30cb..5874939 100644 (file)
@@ -37,21 +37,29 @@ import com.att.eelf.configuration.EELFManager;
 import com.att.eelf.i18n.EELFResourceManager;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Iterator;
 import org.glassfish.grizzly.http.util.HttpStatus;
 import org.onap.appc.Constants;
 import org.onap.appc.adapter.iaas.ProviderAdapter;
 import org.onap.appc.adapter.iaas.impl.IdentityURL;
 import org.onap.appc.adapter.iaas.impl.RequestContext;
 import org.onap.appc.adapter.iaas.impl.RequestFailedException;
+import org.onap.appc.configuration.Configuration;
+import org.onap.appc.configuration.ConfigurationFactory;
 import org.onap.appc.adapter.iaas.impl.VMURL;
 import org.onap.appc.adapter.iaas.provider.operation.common.enums.Operation;
 import org.onap.appc.adapter.iaas.provider.operation.impl.base.ProviderServerOperation;
 import org.onap.appc.exceptions.APPCException;
+import com.att.cdp.exceptions.TimeoutException;
+import com.att.cdp.openstack.util.ExceptionMapper;
 import org.onap.appc.i18n.Msg;
+import com.woorea.openstack.base.client.OpenStackBaseException;
 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
 
 public class DettachVolumeServer extends ProviderServerOperation {
     private final EELFLogger logger = EELFManager.getInstance().getLogger(DettachVolumeServer.class);
+    private static final Configuration config = ConfigurationFactory.getConfiguration();
 
     @Override
     protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
@@ -87,31 +95,32 @@ public class DettachVolumeServer extends ProviderServerOperation {
                 logger.debug(Msg.SERVER_FOUND, vmUrl, context.getTenantName(), server.getStatus().toString());
                 Context contx = server.getContext();
                 ComputeService service = contx.getComputeService();
-                VolumeService volumeService = contx.getVolumeService();
-                logger.info("collecting volume status for volume -id: " + volumeId);
-                List<Volume> volumes = volumeService.getVolumes();
                 Volume volume = new Volume();
-                logger.info("Size of volume list: " + volumes.size());
-                if (volumes != null && !volumes.isEmpty()) {
-                    if (volumes.contains(volumeId)) {
-                        volume.setId(volumeId);
-                        logger.info("Ready to Detach Volume from the server: " + Volume.Status.DETACHING);
-                        service.detachVolume(server, volume);
-                        logger.info("Volume status after performing detach: " + volume.getStatus());
-                        if (validateDetach(volumeService, volumeId)) {
-                            doSuccess(requestContext);
-                        } else {
-                            String msg = "Volume with volume id " + volumeId + " cannot be detached ";
-                            ctx.setAttribute("VOLUME_STATUS", "FAILURE");
-                            doFailure(requestContext, HttpStatus.NOT_IMPLEMENTED_501, msg);
-                            logger.info("unable to detach volume  from the server");
-                        }
-                    } else {
-                        String msg = "Volume with volume id " + volumeId + " cannot be detached as it doesn't exists";
+                VolumeService vs = contx.getVolumeService();
+                Volume s = vs.getVolume(volumeId);
+                boolean flag = false;
+                if (validateDetach(service, vm.getServerId(), volumeId)) {
+                    volume.setId(volumeId);
+                    logger.info("Ready to Detach Volume from the server:");
+                    service.detachVolume(server, volume);
+                    flag = true;
+                } else {
+                    String msg = "Volume with volume id " + volumeId + " cannot be detached as it does not exists";
+                    logger.info("Volume doesnot exists:");
+                    ctx.setAttribute("VOLUME_STATUS", "FAILURE");
+                    doFailure(requestContext, HttpStatus.METHOD_NOT_ALLOWED_405, msg);
+                    flag = false;
+                }
+                if (flag) {
+                    if (validateDetach(requestContext, service, vm.getServerId(), volumeId)) {
+                        String msg = "Volume with volume id " + volumeId + " cannot be detached ";
                         ctx.setAttribute("VOLUME_STATUS", "FAILURE");
-                        doFailure(requestContext, HttpStatus.NOT_IMPLEMENTED_501, msg);
+                        doFailure(requestContext, HttpStatus.CONFLICT_409, msg);
+                    } else {
+                        logger.info("status of detaching volume");
+                        ctx.setAttribute("VOLUME_STATUS", "SUCCESS");
+                        doSuccess(requestContext);
                     }
-                    logger.info("volumestatus:" + ctx.getAttribute("VOLUME_STATUS"));
                 }
                 context.close();
             } else {
@@ -125,24 +134,85 @@ public class DettachVolumeServer extends ProviderServerOperation {
             logger.error("An error occurred when processing the request", e);
             doFailure(requestContext, e.getStatus(), e.getMessage());
         } catch (Exception e) {
-            String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e, e.getClass().getSimpleName(),
+            String msg = EELFResourceManager.format(Msg.DETTACHINGVOLUME_SERVER, e, e.getClass().getSimpleName(),
                     DETACHVOLUME_SERVICE.toString(), vmUrl, tenantName);
             logger.error(msg, e);
+            try {
+                ExceptionMapper.mapException((OpenStackBaseException) e);
+            } catch (ZoneException e1) {
+                logger.error(e1.getMessage());
+            }
+
             doFailure(requestContext, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
         }
         return server;
     }
 
-    protected boolean validateDetach(VolumeService volumeService, String volId)
+    protected boolean validateDetach(ComputeService ser, String vm, String volumeId)
+            throws RequestFailedException, ZoneException {
+        boolean flag = false;
+        Map<String, String> map = ser.getAttachments(vm);
+        if (map != null && !(map.isEmpty())) {
+            Iterator<Entry<String, String>> it = map.entrySet().iterator();
+            while (it.hasNext()) {
+                Map.Entry volumes = (Map.Entry) it.next();
+                logger.info("volumes available in before detach");
+                logger.info("device" + volumes.getKey() + "volume" + volumes.getValue());
+                if (volumes.getValue().equals(volumeId)) {
+                    flag = true;
+                }
+            }
+        }
+        logger.info("DettachVolume  Flag" + flag);
+        return flag;
+    }
+
+    protected boolean validateDetach(RequestContext rc, ComputeService ser, String vm, String volumeId)
             throws RequestFailedException, ZoneException {
         boolean flag = false;
-        List<Volume> volumes = volumeService.getVolumes();
-        if (!volumes.contains(volId)) {
-            flag = true;
-        } else {
-            flag = false;
+        String msg = null;
+        config.setProperty(Constants.PROPERTY_RETRY_DELAY, "10");
+        config.setProperty(Constants.PROPERTY_RETRY_LIMIT, "30");
+        while (rc.attempt()) {
+            Map<String, String> map = ser.getAttachments(vm);
+            if (map != null && !(map.isEmpty())) {
+            Iterator<Entry<String, String>> it = map.entrySet().iterator();
+            logger.info("volumes available after  detach ");
+            while (it.hasNext()) {
+                Map.Entry volumes = (Map.Entry) it.next();
+                logger.info(" devices " + volumes.getKey() + " volumes" + volumes.getValue());
+                if (volumes.getValue().equals(volumeId)) {
+                    logger.info("Device" + volumes.getKey() + "Volume" + volumes.getValue());
+                    flag = true;
+                    break;
+                } else {
+                    flag = false;
+                }
+                logger.info("Dettachvolume flag-->" + flag+"Attempts"+rc.getAttempts());
+            }
+            if (flag) {
+                rc.delay();
+            } else {
+                flag = false;
+                break;
+            }
         }
-        logger.info("validateDetach flag-->" + flag);
+            else
+            {
+                flag = false;
+                logger.info( rc.getAttempts() + "No.of attempts");
+                break;
+            }
+        }
+        if ((rc.getAttempts() == 30) && (!flag)) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, Long.toString(rc.getRetryDelay()),
+                    Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit()));
+            logger.error(msg);
+            logger.info(msg);
+            throw new TimeoutException(msg);
+        }
+        logger.info("DettachVolume Flag -->" + flag);
         return flag;
     }
+
 }
index 2a48e27..87d2872 100644 (file)
-/*-
- * ============LICENSE_START=======================================================
- * ONAP : APPC
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Copyright (C) 2017 Amdocs
- * =============================================================================
- * 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.
- * 
- * ECOMP is a trademark and service mark of AT&T Intellectual Property.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.appc.adapter.iaas.provider.operation.impl.base;
-
-import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
-import static org.onap.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_ADAPTER;
-import static org.onap.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_SERVICE;
-
-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 java.net.URI;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.regex.Pattern;
-import org.glassfish.grizzly.http.util.HttpStatus;
-import org.onap.appc.adapter.iaas.ProviderAdapter;
-import org.onap.appc.adapter.iaas.impl.IdentityURL;
-import org.onap.appc.adapter.iaas.impl.ProviderCache;
-import org.onap.appc.adapter.iaas.impl.RequestContext;
-import org.onap.appc.adapter.iaas.impl.RequestFailedException;
-import org.onap.appc.adapter.iaas.impl.TenantCache;
-import org.onap.appc.adapter.iaas.impl.VMURL;
-import org.onap.appc.adapter.iaas.provider.operation.api.IProviderOperation;
-import org.onap.appc.adapter.iaas.provider.operation.common.constants.Constants;
-import org.onap.appc.adapter.iaas.provider.operation.common.enums.Outcome;
-import org.onap.appc.configuration.Configuration;
-import org.onap.appc.configuration.ConfigurationFactory;
-import org.onap.appc.exceptions.APPCException;
-import org.onap.appc.i18n.Msg;
-import org.onap.appc.pool.Pool;
-import org.onap.appc.pool.PoolExtensionException;
-import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
-import org.slf4j.MDC;
-
-public abstract class ProviderOperation implements IProviderOperation {
-
-    private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderOperation.class);
-    protected static final Configuration configuration = ConfigurationFactory.getConfiguration();
-
-
-    /**
-     * A cache of providers that are predefined.
-     */
-    private Map<String /* provider name */, ProviderCache> providerCache;
-
-    /**
-     * The username and password to use for dynamically created connections
-     */
-    private String defaultUser;
-    private String defaultPassword;
-    private String defaultDomain;
-
-    @Override
-    public void setDefaultUser(String defaultUser) {
-        this.defaultUser = defaultUser;
-    }
-
-    @Override
-    public void setDefaultPassword(String defaultPassword) {
-        this.defaultPassword = defaultPassword;
-    }
-
-    @Override
-    public void setProviderCache(Map<String, ProviderCache> providerCache) {
-        this.providerCache = providerCache;
-    }
-
-    @Override
-    public void setDefaultDomain(String defaultDomain) {
-        this.defaultDomain = defaultDomain;
-    }
-
-    /**
-     * set MDC props
-     */
-    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
-     */
-    protected void logOperation(Msg msg, Map<String, String> params, SvcLogicContext context) {
-
-        String appName = configuration.getProperty(org.onap.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 (Entry<String, String> entry : parameters.entrySet()) {
-            logger.debug(Msg.PROPERTY_VALUE, entry.getKey(), entry.getValue());
-        }
-    }
-
-    /**
-     * 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.
-     */
-    protected void doFailure(RequestContext rc, HttpStatus code, String message) {
-        try {
-            doFailure(rc, code, message, null);
-        } catch (APPCException e) {
-            logger.error("An APPC exception caught. Should never happen", e);
-        }
-    }
-
-    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) {
-            logger.error("Error when parsing status code", e);
-            status = "500";
-        }
-        svcLogic.setStatus(Outcome.FAILURE.toString());
-        svcLogic.setAttribute(org.onap.appc.Constants.ATTRIBUTE_ERROR_CODE, status);
-        svcLogic.setAttribute(org.onap.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.onap.appc.Constants.ATTRIBUTE_ERROR_CODE,
-            Integer.toString(HttpStatus.OK_200.getStatusCode()));
-    }
-
-    protected boolean validateVM(RequestContext rc, String appName, String vmUrl, VMURL vm)
-        throws RequestFailedException {
-        String msg;
-        if (vm == null) {
-            msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vmUrl);
-            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) {
-            logger.error("An error occurred when validating vm url", 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());
-
-            TenantCache tenant = cache.addTenant(vm.getTenantId(), null, defaultUser, defaultPassword, defaultDomain);
-
-            // 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.onap.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, defaultUser, defaultPassword, defaultDomain);
-            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.
-                     */
-                    reloginIfNeeded(context);
-                    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;
-    }
-
-    private void reloginIfNeeded(Context context) throws ZoneException {
-        if (context.isStale()) {
-            context.relogin();
-        }
-    }
-
-    protected Context resolveContext(RequestContext rc, Map<String, String> params, String appName, String vmUrl)
-        throws RequestFailedException {
-
-        VMURL vm = VMURL.parseURL(vmUrl);
-        if (vm == null) {
-            String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vmUrl);
-            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, vmUrl, 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);
-    }
-}
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ * ONAP : APPC\r
+ * ================================================================================\r
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Copyright (C) 2017 Amdocs\r
+ * =============================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * \r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * \r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * \r
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.appc.adapter.iaas.provider.operation.impl.base;\r
+\r
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;\r
+import static org.onap.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_ADAPTER;\r
+import static org.onap.appc.adapter.iaas.provider.operation.common.constants.Constants.MDC_SERVICE;\r
+\r
+import com.att.cdp.exceptions.ZoneException;\r
+import com.att.cdp.zones.Context;\r
+import com.att.cdp.zones.model.ModelObject;\r
+import com.att.cdp.zones.model.Server;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import com.att.eelf.i18n.EELFResourceManager;\r
+import java.net.URI;\r
+import java.util.Map;\r
+import java.util.Map.Entry;\r
+import java.util.Set;\r
+import java.util.regex.Pattern;\r
+import org.glassfish.grizzly.http.util.HttpStatus;\r
+import org.onap.appc.adapter.iaas.ProviderAdapter;\r
+import org.onap.appc.adapter.iaas.impl.IdentityURL;\r
+import org.onap.appc.adapter.iaas.impl.ProviderCache;\r
+import org.onap.appc.adapter.iaas.impl.RequestContext;\r
+import org.onap.appc.adapter.iaas.impl.RequestFailedException;\r
+import org.onap.appc.adapter.iaas.impl.TenantCache;\r
+import org.onap.appc.adapter.iaas.impl.VMURL;\r
+import org.onap.appc.adapter.iaas.provider.operation.api.IProviderOperation;\r
+import org.onap.appc.adapter.iaas.provider.operation.common.constants.Constants;\r
+import org.onap.appc.adapter.iaas.provider.operation.common.enums.Outcome;\r
+import org.onap.appc.configuration.Configuration;\r
+import org.onap.appc.configuration.ConfigurationFactory;\r
+import org.onap.appc.exceptions.APPCException;\r
+import org.onap.appc.i18n.Msg;\r
+import org.onap.appc.pool.Pool;\r
+import org.onap.appc.pool.PoolExtensionException;\r
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;\r
+import org.slf4j.MDC;\r
+\r
+public abstract class ProviderOperation implements IProviderOperation {\r
+\r
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderOperation.class);\r
+    protected static final Configuration configuration = ConfigurationFactory.getConfiguration();\r
+\r
+\r
+    /**\r
+     * A cache of providers that are predefined.\r
+     */\r
+    private Map<String /* provider name */, ProviderCache> providerCache;\r
+\r
+    /**\r
+     * The username and password to use for dynamically created connections\r
+     */\r
+    private String defaultUser;\r
+    private String defaultPassword;\r
+    private String defaultDomain;\r
+\r
+    @Override\r
+    public void setDefaultUser(String defaultUser) {\r
+        this.defaultUser = defaultUser;\r
+    }\r
+\r
+    @Override\r
+    public void setDefaultPassword(String defaultPassword) {\r
+        this.defaultPassword = defaultPassword;\r
+    }\r
+\r
+    @Override\r
+    public void setProviderCache(Map<String, ProviderCache> providerCache) {\r
+        this.providerCache = providerCache;\r
+    }\r
+\r
+    @Override\r
+    public void setDefaultDomain(String defaultDomain) {\r
+        this.defaultDomain = defaultDomain;\r
+    }\r
+\r
+    /**\r
+     * set MDC props\r
+     */\r
+    protected void setMDC(String service, String serviceName, String adapterName) {\r
+        MDC.put(MDC_ADAPTER, adapterName);\r
+        MDC.put(MDC_SERVICE, service);\r
+        MDC.put(MDC_SERVICE_NAME, serviceName);\r
+    }\r
+\r
+    /**\r
+     * initial log of the operation\r
+     */\r
+    protected void logOperation(Msg msg, Map<String, String> params, SvcLogicContext context) {\r
+\r
+        String appName = configuration.getProperty(org.onap.appc.Constants.PROPERTY_APPLICATION_NAME);\r
+        logger.info(msg, appName);\r
+\r
+        debugParameters(params);\r
+        debugContext(context);\r
+    }\r
+    /**\r
+     * This method is used to dump the value of the parameters to the log for debugging purposes.\r
+     *\r
+     * @param parameters The parameters to be printed to the log\r
+     */\r
+    private void debugParameters(Map<String, String> parameters) {\r
+        for (Entry<String, String> entry : parameters.entrySet()) {\r
+            logger.debug(Msg.PROPERTY_VALUE, entry.getKey(), entry.getValue());\r
+        }\r
+    }\r
+    /**\r
+     * This method is used to create a diagnostic dump of the context for the log\r
+     *\r
+     * @param context The context to be dumped\r
+     */\r
+    @SuppressWarnings({"nls", "static-method"})\r
+    private void debugContext(SvcLogicContext context) {\r
+        Set<String> keys = context.getAttributeKeySet();\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("Service Logic Context: Status ");\r
+        builder.append(Constants.LPAREN);\r
+        builder.append(context.getStatus());\r
+        builder.append(Constants.RPAREN);\r
+        builder.append(", Attribute count ");\r
+        builder.append(Constants.LPAREN);\r
+        builder.append(keys == null ? "none" : Integer.toString(keys.size()));\r
+        builder.append(Constants.RPAREN);\r
+        if (keys != null && !keys.isEmpty()) {\r
+            builder.append(Constants.NL);\r
+            for (String key : keys) {\r
+                String value = context.getAttribute(key);\r
+                builder.append("Attribute ");\r
+                builder.append(Constants.LPAREN);\r
+                builder.append(key);\r
+                builder.append(Constants.RPAREN);\r
+                builder.append(", value ");\r
+                builder.append(Constants.LPAREN);\r
+                builder.append(value == null ? "" : value);\r
+                builder.append(Constants.RPAREN);\r
+                builder.append(Constants.NL);\r
+            }\r
+        }\r
+        logger.debug(builder.toString());\r
+    }\r
+\r
+\r
+    /**\r
+     * This method is used to validate that the parameters contain all required property names, and that the values are\r
+     * non-null and non-empty strings. We are still not ensured that the value is valid, but at least it exists.\r
+     *\r
+     * @param parameters The parameters to be checked\r
+     * @param propertyNames The list of property names that are required to be present.\r
+     * @throws RequestFailedException If the parameters are not valid\r
+     */\r
+    protected void validateParametersExist(Map<String, String> parameters, String... propertyNames)\r
+        throws RequestFailedException {\r
+        boolean success = true;\r
+        StringBuilder msg =\r
+            new StringBuilder(EELFResourceManager.format(Msg.MISSING_REQUIRED_PROPERTIES, MDC.get(MDC_SERVICE)));\r
+        msg.append(Constants.NL);\r
+        for (String propertyName : propertyNames) {\r
+            String value = parameters.get(propertyName);\r
+            if (value == null || value.trim().length() == 0) {\r
+                success = false;\r
+                msg.append(Constants.QUOTE);\r
+                msg.append(propertyName);\r
+                msg.append(Constants.QUOTE);\r
+                msg.append(Constants.SPACE);\r
+            }\r
+        }\r
+\r
+        if (!success) {\r
+            logger.error(msg.toString());\r
+            throw new RequestFailedException("Check Parameters", msg.toString(), HttpStatus.BAD_REQUEST_400,\r
+                (Server) null);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.\r
+     */\r
+    protected void doFailure(RequestContext rc, HttpStatus code, String message) {\r
+        try {\r
+            doFailure(rc, code, message, null);\r
+        } catch (APPCException e) {\r
+            logger.error("An APPC exception caught. Should never happen", e);\r
+        }\r
+    }\r
+\r
+    protected void doFailure(RequestContext rc, HttpStatus code, String message, Throwable cause) throws APPCException {\r
+        SvcLogicContext svcLogic = rc.getSvcLogicContext();\r
+        String msg = (message == null) ? code.getReasonPhrase() : message;\r
+        if ((msg.contains("PALOS"))) {\r
+             msg = msg.substring(msg.indexOf("PALOS"), msg.length());\r
+         msg = msg.substring(msg.indexOf("PALOS"), msg.indexOf("\n"));\r
+         } else {\r
+        if (msg.contains("\n")) {\r
+            msg = msg.substring(0, msg.indexOf('\n'));\r
+            }\r
+           }\r
+        String status;\r
+        try {\r
+            status = Integer.toString(code.getStatusCode());\r
+        } catch (Exception e) {\r
+            logger.error("Error when parsing status code", e);\r
+            status = "500";\r
+        }\r
+        svcLogic.setStatus(Outcome.FAILURE.toString());\r
+        svcLogic.setAttribute(org.onap.appc.Constants.ATTRIBUTE_ERROR_CODE, status);\r
+        svcLogic.setAttribute(org.onap.appc.Constants.ATTRIBUTE_ERROR_MESSAGE, msg);\r
+        if (null != cause) {\r
+            throw new APPCException(cause);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.\r
+     */\r
+    @SuppressWarnings("static-method")\r
+    protected void doSuccess(RequestContext rc) {\r
+        SvcLogicContext svcLogic = rc.getSvcLogicContext();\r
+        svcLogic.setStatus(Outcome.SUCCESS.toString());\r
+        svcLogic.setAttribute(org.onap.appc.Constants.ATTRIBUTE_ERROR_CODE,\r
+            Integer.toString(HttpStatus.OK_200.getStatusCode()));\r
+    }\r
+\r
+    protected boolean validateVM(RequestContext rc, String appName, String vmUrl, VMURL vm)\r
+        throws RequestFailedException {\r
+        String msg;\r
+        if (vm == null) {\r
+            msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vmUrl);\r
+            logger.error(msg);\r
+            doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);\r
+            return true;\r
+        }\r
+        validateVMURL(vm);\r
+        return false;\r
+    }\r
+\r
+    protected void validateVMURL(VMURL vm) throws RequestFailedException {\r
+        String name = "vm-id";\r
+        if (vm == null) {\r
+            throw new RequestFailedException(String.format("The value %s cannot be null.", name));\r
+        }\r
+        // Check that its a good uri\r
+        // This will probably never get hit bc of an earlier check while parsing\r
+        // the string to a VMURL\r
+        try {\r
+            // noinspection ResultOfMethodCallIgnored\r
+            URI.create(vm.toString());\r
+        } catch (Exception e) {\r
+            logger.error("An error occurred when validating vm url", e);\r
+            throw new RequestFailedException(\r
+                String.format("The value %s is not well formed [%s].", name, vm.toString()));\r
+        }\r
+        // Check the tenant and vmid segments\r
+        String patternRegex = "([0-9a-f]{8}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{12})";\r
+        Pattern pattern = Pattern.compile(patternRegex, Pattern.CASE_INSENSITIVE);\r
+        if (!pattern.matcher(vm.getTenantId()).matches()) {\r
+            throw new RequestFailedException(\r
+                String.format("The value %s has an invalid tenantId [%s].", name, vm.getTenantId()));\r
+        }\r
+        if (!pattern.matcher(vm.getServerId()).matches()) {\r
+            throw new RequestFailedException(\r
+                String.format("The value %s has an invalid serverId [%s].", name, vm.getServerId()));\r
+        }\r
+    }\r
+\r
+    private ProviderCache createProviderCache(VMURL vm, IdentityURL ident) {\r
+        if (vm != null && ident != null) {\r
+            ProviderCache cache = new ProviderCache();\r
+            cache.setIdentityURL(ident.toString());\r
+            cache.setProviderName(ident.toString());\r
+            TenantCache tenant = cache.addTenant(vm.getTenantId(), null, defaultUser, defaultPassword, defaultDomain);\r
+            // Make sure we could initialize the the cache otherwise return null\r
+            if (tenant != null && tenant.isInitialized()) {\r
+                return cache;\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+    /**\r
+     * This method is a general helper method used to locate a server given its fully-qualified self-link URL on a\r
+     * supported provider, regardless of region(s), and to return an opened context that can be used to access that\r
+     * server.\r
+     *\r
+     * @param rc The request context that wraps and manages the state of the request\r
+     * @param selfLinkURL The fully-qualified self-link URL of the server\r
+     * @param providerName The name of the provider to be searched\r
+     * @return The context that can be used to access the server, or null if not found.\r
+     */\r
+    @SuppressWarnings("nls")\r
+    protected Context getContext(RequestContext rc, String selfLinkURL, String providerName) {\r
+        VMURL vm = VMURL.parseURL(selfLinkURL);\r
+        IdentityURL ident = IdentityURL.parseURL(providerName);\r
+        String appName = configuration.getProperty(org.onap.appc.Constants.PROPERTY_APPLICATION_NAME);\r
+        if (vm == null) {\r
+            String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, selfLinkURL);\r
+            logger.error(msg);\r
+            doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);\r
+            return null;\r
+        }\r
+        /*\r
+         * Get the cache of tenants and contexts for the named provider, if one exists\r
+         */\r
+        ProviderCache cache = providerCache.get(providerName);\r
+        /*\r
+         * If one doesn't exist, try and create it. If we have enough information to create it successfully, add it to\r
+         * the cache and continue, otherwise fail the request.\r
+         */\r
+        if (cache == null) {\r
+            if (ident != null) {\r
+                cache = createProviderCache(vm, ident);\r
+            }\r
+            if (cache != null) {\r
+                providerCache.put(cache.getProviderName(), cache);\r
+            } else {\r
+                String msg = EELFResourceManager.format(Msg.UNKNOWN_PROVIDER, providerName,\r
+                    providerCache.keySet().toString());\r
+                logger.error(msg);\r
+                doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);\r
+                return null;\r
+            }\r
+        }\r
+        if (providerName == null) {\r
+            logger.debug(\r
+                String.format("Using the default provider cache [%s] since no valid identity url was passed in.",\r
+                    cache.getIdentityURL()));\r
+        }\r
+        // get the tenant cache for the vm\r
+        String identityURL = cache.getIdentityURL();\r
+        TenantCache tenantCache = cache.getTenant(vm.getTenantId());\r
+        if (tenantCache == null) {\r
+            // no tenantCache matching tenant, add tenant to the provider cache\r
+            tenantCache = cache.addTenant(vm.getTenantId(), null, defaultUser, defaultPassword, defaultDomain);\r
+            if (tenantCache == null) {\r
+                // tenant not found\r
+                String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL);\r
+                logger.error(msg);\r
+                doFailure(rc, HttpStatus.NOT_FOUND_404, msg);\r
+                return null;\r
+            }\r
+        }\r
+        // reserve the context\r
+        String tenantName = tenantCache.getTenantName();\r
+        String tenantId = tenantCache.getTenantId();\r
+        String region = tenantCache.determineRegion(vm);\r
+\r
+        if (region != null) {\r
+            Pool<Context> pool = tenantCache.getPools().get(region);\r
+            while (rc.attempt()) {\r
+                try {\r
+                    Context context = pool.reserve();\r
+                    /*\r
+                     * Insert logic here to test the context for connectivity because we may have gotten one from the\r
+                     * pool that was previously created.\r
+                     */\r
+                    reloginIfNeeded(context);\r
+                    return context;\r
+                } catch (PoolExtensionException e) {\r
+                    String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, providerName, identityURL,\r
+                        tenantName, tenantId, e.getMessage(), Long.toString(rc.getRetryDelay()),\r
+                        Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit()));\r
+                    logger.error(msg, e);\r
+                    rc.delay();\r
+                } catch (Exception e) {\r
+                    String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e,\r
+                        e.getClass().getSimpleName(), "find", selfLinkURL, tenantCache.getTenantName());\r
+                    logger.error(msg, e);\r
+                    doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);\r
+                    return null;\r
+                }\r
+            }\r
+            String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, providerName, identityURL);\r
+            logger.error(msg);\r
+            doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg);\r
+            return null;\r
+        }\r
+        String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL);\r
+        logger.error(msg);\r
+        doFailure(rc, HttpStatus.NOT_FOUND_404, msg);\r
+        return null;\r
+    }\r
+\r
+    private void reloginIfNeeded(Context context) throws ZoneException {\r
+        if (context.isStale()) {\r
+            context.relogin();\r
+        }\r
+    }\r
+\r
+    protected Context resolveContext(RequestContext rc, Map<String, String> params, String appName, String vmUrl)\r
+        throws RequestFailedException {\r
+        VMURL vm = VMURL.parseURL(vmUrl);\r
+        if (vm == null) {\r
+            String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vmUrl);\r
+            doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);\r
+            logger.error(msg);\r
+            return null;\r
+        }\r
+        validateVMURL(vm);\r
+        IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));\r
+        String identStr = (ident == null) ? null : ident.toString();\r
+        return getContext(rc, vmUrl, identStr);\r
+    }\r
+\r
+    protected abstract ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)\r
+        throws APPCException;\r
+    @Override\r
+    public ModelObject doOperation(Map<String, String> params, SvcLogicContext context) throws APPCException {\r
+        return executeProviderOperation(params, context);\r
+    }\r
+}\r