Sonar code smell fixes
[appc.git] / appc-adapters / appc-iaas-adapter / appc-iaas-adapter-bundle / src / main / java / org / onap / appc / adapter / iaas / provider / operation / impl / AttachVolumeServer.java
index 3d3b9b7..e21105d 100644 (file)
@@ -2,9 +2,11 @@
  * ============LICENSE_START=======================================================
  * ONAP : APPC
  * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
  * =============================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * 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;
+
+import static org.onap.appc.adapter.iaas.provider.operation.common.enums.Operation.ATTACHVOLUME_SERVICE;
 import static org.onap.appc.adapter.utils.Constants.ADAPTER_NAME;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import org.glassfish.grizzly.http.util.HttpStatus;
 import org.onap.appc.Constants;
 import org.onap.appc.adapter.iaas.ProviderAdapter;
@@ -33,10 +39,15 @@ import org.onap.appc.adapter.iaas.impl.RequestFailedException;
 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.configuration.Configuration;
+import org.onap.appc.configuration.ConfigurationFactory;
 import org.onap.appc.exceptions.APPCException;
 import org.onap.appc.i18n.Msg;
 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import com.att.cdp.exceptions.TimeoutException;
 import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.util.ExceptionMapper;
+import com.att.cdp.zones.ComputeService;
 import com.att.cdp.zones.Context;
 import com.att.cdp.zones.VolumeService;
 import com.att.cdp.zones.model.ModelObject;
@@ -45,73 +56,116 @@ import com.att.cdp.zones.model.Volume;
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
 import com.att.eelf.i18n.EELFResourceManager;
-import static org.onap.appc.adapter.iaas.provider.operation.common.enums.Operation.ATTACHVOLUME_SERVICE;;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import org.apache.commons.lang.StringUtils;
+import org.onap.appc.adapter.iaas.provider.operation.common.constants.Property;
 
 public class AttachVolumeServer extends ProviderServerOperation {
+
     private final EELFLogger logger = EELFManager.getInstance().getLogger(AttachVolumeServer.class);
-    private Server attachVolume(Map<String, String> params, SvcLogicContext ctx) throws APPCException {
+    private static final Configuration config = ConfigurationFactory.getConfiguration();
+
+    private Server attachVolume(Map<String, String> params, SvcLogicContext ctx) {
         Server server = null;
-        RequestContext rc = new RequestContext(ctx);
-        rc.isAlive();
+        RequestContext requestContext = new RequestContext(ctx);
+        requestContext.isAlive();
         String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
-        String vm_url = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
-        String volumeid = params.get(ProviderAdapter.VOLUME_ID);
+        String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+        String volumeId = params.get(ProviderAdapter.VOLUME_ID);
         String device = params.get(ProviderAdapter.DEVICE);
-        VMURL vm = VMURL.parseURL(vm_url);
-        Context context = null;
-        String tenantName = "Unknown";//to be used also in case of exception
+        if (StringUtils.isBlank(device)) {
+            logger.info("Setting device to null");
+            device = null;
+        }
+        VMURL vm = VMURL.parseURL(vmUrl);
+        Context context;
+        final String volumeStatus = "VOLUME_STATUS";
+        final String statusFail = "FAILURE";
+        final String statusSuccess = "SUCCESS";
+        final String statusNotFound = "CONTEXT_NOT_FOUND";
+        String tenantName = "Unknown";// to be used also in case of exception
         try {
-            if (validateVM(rc, appName, vm_url, vm))
+            if (validateVM(requestContext, appName, vmUrl, vm)) {
                 return null;
+            }
             IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
             String identStr = (ident == null) ? null : ident.toString();
-            String vol_id = (volumeid == null) ? null : volumeid.toString();
-            String msg;
-            context = getContext(rc, vm_url, identStr);
+            context = getContext(requestContext, vmUrl, identStr);
+            String skipHypervisorCheck = configuration.getProperty(Property.SKIP_HYPERVISOR_CHECK);
+            if (skipHypervisorCheck == null && ctx != null) {
+                skipHypervisorCheck = ctx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK);
+            }
             if (context != null) {
-                tenantName = context.getTenantName();//this varaible also is used in case of exception
-                rc.reset();
-                server = lookupServer(rc, context, vm.getServerId());
-                logger.debug(Msg.SERVER_FOUND, vm_url, tenantName, server.getStatus().toString());
-                    VolumeService vs = context.getVolumeService();
-                    vs.getVolumes(server);;
-                    Volume vol = new Volume();
-                    vol.setId(vol_id);
-                    logger.info("Server status: "+server.getStatus());
-                    Map volms = server.getVolumes();
-                    logger.info("list of attachments");
-                    logger.info(volms.size()+"initial volumes");
-                    logger.info(vol.getId());
-                    if(server.getVolumes().containsValue(vol_id))
-                    {
-                        logger.info("Alreday volumes exists:");
-                         logger.info( volms.size()+"volumes size if exists");
-                    }
-                    else
-                    {
-                    server.attachVolume(vol, device);
-                    logger.info( volms.size()+"volumes size after attaching volume");
+                tenantName = context.getTenantName();// this variable also is
+                                                        // used in case of
+                                                        // exception
+                requestContext.reset();
+                server = lookupServer(requestContext, context, vm.getServerId());
+                logger.debug(Msg.SERVER_FOUND, vmUrl, context.getTenantName(), server.getStatus().toString());
+                Context contx = server.getContext();
+                if (!"true".equalsIgnoreCase(skipHypervisorCheck)) {
+                    // Check of the Hypervisor for the VM Server is UP and reachable
+                    checkHypervisor(server);
+                }
+                ComputeService service = contx.getComputeService();
+                if ((volumeId == null || volumeId.isEmpty()) || (device == null || device.isEmpty())) {
+                    ctx.setAttribute(volumeStatus, statusFail);
+                    doFailure(requestContext, HttpStatus.BAD_REQUEST_400, "Both Device or Volumeid are mandatory");
+                }
+                VolumeService volumeService = contx.getVolumeService();
+                logger.info("collecting volume status for volume -id:" + volumeId);
+                //List<Volume> volumes = volumeService.getVolumes();
+                Volume volume = new Volume();
+                boolean isAttached = false;
+                if (validateAttach(service, vm.getServerId(), volumeId, device)) {
+                    String msg = "Volume with volume id " + volumeId + " cannot be attached as it already exists";
+                    logger.info("Already volumes exists:");
+                    ctx.setAttribute(volumeStatus, statusFail);
+                    doFailure(requestContext, HttpStatus.METHOD_NOT_ALLOWED_405, msg);
+                    isAttached = false;
+                } else {
+                    volume.setId(volumeId);
+                    logger.info("Ready to Attach Volume to the server:");
+                    service.attachVolume(server, volume, device);
+                    isAttached = true;
+                }
+                if (isAttached) {
+                    if (validateAttach(requestContext, service, vm.getServerId(), volumeId, device)) {
+                        ctx.setAttribute(volumeStatus, statusSuccess);
+                        doSuccess(requestContext);
+                    } else {
+                        String msg = "Volume with " + volumeId + " unable  to attach";
+                        logger.info("Volume with " + volumeId + " unable to attach");
+                        ctx.setAttribute(volumeStatus, statusFail);
+                        doFailure(requestContext, HttpStatus.CONFLICT_409, msg);
                     }
+                }
                 context.close();
-                doSuccess(rc);
-                ctx.setAttribute("VOLUME_STATUS", "SUCCESS");
             } else {
-                ctx.setAttribute("VOLUME_STATUS", "CONTEXT_NOT_FOUND");
+                ctx.setAttribute(volumeStatus, statusNotFound);
             }
         } catch (ZoneException e) {
-            String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vm_url);
+            String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vmUrl);
             logger.error(msg);
-            doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+            ctx.setAttribute(volumeStatus, statusFail);
+            doFailure(requestContext, HttpStatus.NOT_FOUND_404, msg);
         } catch (RequestFailedException e) {
-            doFailure(rc, e.getStatus(), e.getMessage());
+            ctx.setAttribute(volumeStatus, statusFail);
+            doFailure(requestContext, e.getStatus(), e.getMessage());
         } catch (Exception ex) {
             String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, ex, ex.getClass().getSimpleName(),
-                    ATTACHVOLUME_SERVICE.toString(), vm_url, tenantName);
-            logger.error(msg, ex);
-            doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+                    ATTACHVOLUME_SERVICE.toString(), vmUrl, tenantName);
+            ctx.setAttribute(volumeStatus, statusFail);
+            try {
+                ExceptionMapper.mapException((OpenStackBaseException) ex);
+            } catch (ZoneException e1) {
+                logger.error(e1.getMessage());
+            }
+            doFailure(requestContext, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
         }
         return server;
     }
+
     @Override
     protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
             throws APPCException {
@@ -119,4 +173,69 @@ public class AttachVolumeServer extends ProviderServerOperation {
         logOperation(Msg.ATTACHINGVOLUME_SERVER, params, context);
         return attachVolume(params, context);
     }
+
+    protected boolean validateAttach(ComputeService ser, String vm, String volumeId, String device)
+            throws ZoneException {
+        boolean isValid = false;
+        Map<String, String> map = ser.getAttachments(vm);
+        Iterator<Entry<String, String>> it = map.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry<String, String> volumes = it.next();
+            logger.info("volumes available before attach");
+            logger.info("device" + volumes.getKey() + " Values " + volumes.getValue());
+            if (StringUtils.isBlank(device)) {
+                if (volumes.getValue().equals(volumeId)) {
+                    logger.info("Device " + volumes.getKey() + " Volumes " + volumes.getValue());
+                    isValid = true;
+                }
+            } else if (volumes.getKey().equals(device) && (volumes.getValue().equals(volumeId))) {
+                logger.info("Device " + volumes.getKey() + " Volumes " + volumes.getValue());
+                isValid = true;
+            }
+        }
+        logger.info("AttachVolumeFlag " + isValid);
+        return isValid;
+    }
+
+    protected boolean validateAttach(RequestContext rc, ComputeService ser, String vm, String volumeId, String device)
+            throws ZoneException {
+        boolean isValid = 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 attach ");
+                while (it.hasNext()) {
+                    Map.Entry<String, String> volumes = it.next();
+                    logger.info(" devices " + volumes.getKey() + " volumes " + volumes.getValue());
+                    if (StringUtils.isBlank(device) && (volumes.getValue().equals(volumeId))) {
+                        logger.info("Device " + volumes.getKey() + "Volumes " + volumes.getValue());
+                        isValid = true;
+                        break;
+                    } else if (volumes.getKey().equals(device) && (volumes.getValue().equals(volumeId))) {
+                        logger.info("Device " + volumes.getKey() + " Volume " + volumes.getValue());
+                        isValid = true;
+                        break;
+                    }
+                }
+                if (isValid) {
+                    logger.info("AttachVolume " + rc.getAttempts() + " No.of attempts ");
+                    break;
+                } else {
+                    rc.delay();
+                }
+            }
+        }
+        if ((rc.getAttempts() == 30) && (!isValid)) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, Long.toString(rc.getRetryDelay()),
+                    Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit()));
+            logger.error(msg);
+            throw new TimeoutException(msg);
+        }
+        logger.info("AttachVolume Flag -->" + isValid);
+        return isValid;
+    }
 }