Replaced all tabs with spaces in java and pom.xml
[so.git] / adapters / mso-adapter-utils / src / main / java / org / onap / so / openstack / utils / MsoNeutronUtils.java
index 850f16f..78db27f 100644 (file)
@@ -27,7 +27,6 @@ import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.List;
 import java.util.Optional;
-
 import org.onap.so.cloud.CloudConfig;
 import org.onap.so.cloud.authentication.AuthenticationMethodFactory;
 import org.onap.so.cloud.authentication.KeystoneAuthHolder;
@@ -51,7 +50,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
-
 import com.woorea.openstack.base.client.OpenStackBaseException;
 import com.woorea.openstack.base.client.OpenStackConnectException;
 import com.woorea.openstack.base.client.OpenStackRequest;
@@ -67,519 +65,495 @@ import com.woorea.openstack.quantum.model.Port;
 import com.woorea.openstack.quantum.model.Segment;
 
 @Component
-public class MsoNeutronUtils extends MsoCommonUtils
-{
+public class MsoNeutronUtils extends MsoCommonUtils {
 
-       // Fetch cloud configuration each time (may be cached in CloudConfig class)
-       @Autowired
-       private CloudConfig cloudConfig;
+    // Fetch cloud configuration each time (may be cached in CloudConfig class)
+    @Autowired
+    private CloudConfig cloudConfig;
 
-       @Autowired
+    @Autowired
     private AuthenticationMethodFactory authenticationMethodFactory;
-       
-       @Autowired
-       private MsoTenantUtilsFactory tenantUtilsFactory;
 
-       @Autowired
-       private KeystoneV3Authentication keystoneV3Authentication;
+    @Autowired
+    private MsoTenantUtilsFactory tenantUtilsFactory;
+
+    @Autowired
+    private KeystoneV3Authentication keystoneV3Authentication;
 
     private static Logger logger = LoggerFactory.getLogger(MsoNeutronUtils.class);
 
     public enum NetworkType {
-               BASIC, PROVIDER, MULTI_PROVIDER
-       };
-
-       /**
-        * Create a network with the specified parameters in the given cloud/tenant.
-        *
-        * If a network already exists with the same name, an exception will be thrown.  Note that
-        * this is an MSO-imposed restriction.  Openstack does not require uniqueness on network names.
-        * <p>
-        * @param cloudSiteId The cloud identifier (may be a region) in which to create the network.
-        * @param tenantId The tenant in which to create the network
-        * @param type The type of network to create (Basic, Provider, Multi-Provider)
-        * @param networkName The network name to create
-        * @param provider The provider network name (for Provider or Multi-Provider networks)
-        * @param vlans A list of VLAN segments for the network (for Provider or Multi-Provider networks)
-        * @return a NetworkInfo object which describes the newly created network
-        * @throws MsoNetworkAlreadyExists Thrown if a network with the same name already exists
-        * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception
-        * @throws MsoCloudSiteNotFound Thrown if the cloudSite is invalid or unknown
-        */
-       public NetworkInfo createNetwork (String cloudSiteId, String tenantId, NetworkType type, String networkName, String provider, List<Integer> vlans)
-            throws MsoException
-       {
-               // Obtain the cloud site information where we will create the stack
-        CloudSite cloudSite = cloudConfig.getCloudSite(cloudSiteId).orElseThrow(
-                () -> new MsoCloudSiteNotFound(cloudSiteId));
-
-               Quantum neutronClient = getNeutronClient (cloudSite, tenantId);
-
-               // Check if a network already exists with this name
-               // Openstack will allow duplicate name, so require explicit check
-               Network network = findNetworkByName (neutronClient, networkName);
-
-               if (network != null) {
-                       // Network already exists.  Throw an exception
-        logger.error("{} Network {} on Cloud site {} for tenant {} already exists {}",
-            MessageEnum.RA_NETWORK_ALREADY_EXIST, networkName, cloudSiteId, tenantId,
-            ErrorCode.DataError.getValue());
-        throw new MsoNetworkAlreadyExists (networkName, tenantId, cloudSiteId);
-               }
-
-               // Does not exist, create a new one
-               network = new Network();
-               network.setName(networkName);
-               network.setAdminStateUp(true);
-
-               if (type == NetworkType.PROVIDER) {
-                       if (provider != null && vlans != null && vlans.size() > 0) {
-                               network.setProviderPhysicalNetwork (provider);
-                               network.setProviderNetworkType("vlan");
-                               network.setProviderSegmentationId (vlans.get(0));
-                       }
-               } else if (type == NetworkType.MULTI_PROVIDER) {
-                       if (provider != null && vlans != null && vlans.size() > 0) {
-                               List<Segment> segments = new ArrayList<>(vlans.size());
-                               for (int vlan : vlans) {
-                                       Segment segment = new Segment();
-                                       segment.setProviderPhysicalNetwork (provider);
-                                       segment.setProviderNetworkType("vlan");
-                                       segment.setProviderSegmentationId (vlan);
-
-                                       segments.add(segment);
-                               }
-                               network.setSegments(segments);
-                       }
-               }
-
-               try {
-                       OpenStackRequest<Network> request = neutronClient.networks().create(network);
-                       Network newNetwork = executeAndRecordOpenstackRequest(request);
-                       return new NetworkInfoMapper(newNetwork).map();
-               }
-               catch (OpenStackBaseException e) {
-                       // Convert Neutron exception to an MsoOpenstackException
-                       MsoException me = neutronExceptionToMsoException (e, "CreateNetwork");
-                       throw me;
-               }
-               catch (RuntimeException e) {
-                       // Catch-all
-                       MsoException me = runtimeExceptionToMsoException(e, "CreateNetwork");
-                       throw me;
-               }
-       }
-
-
-       /**
-        * Query for a network with the specified name or ID in the given cloud.  If the network exists,
-        * return an NetworkInfo object.  If not, return null.
-        * <p>
-        * Whenever possible, the network ID should be used as it is much more efficient.  Query by
-        * name requires retrieval of all networks for the tenant and search for matching name.
-        * <p>
-        * @param networkNameOrId The network to query
-        * @param tenantId The Openstack tenant to look in for the network
-        * @param cloudSiteId The cloud identifier (may be a region) in which to query the network.
-        * @return a NetworkInfo object describing the queried network, or null if not found
-        * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception
-        * @throws MsoCloudSiteNotFound
-        */
-    public NetworkInfo queryNetwork(String networkNameOrId, String tenantId, String cloudSiteId) throws MsoException
-       {
-      logger.debug("In queryNetwork");
-
-               // Obtain the cloud site information
-        CloudSite cloudSite = cloudConfig.getCloudSite(cloudSiteId).orElseThrow(
-                () -> new MsoCloudSiteNotFound(cloudSiteId));
-
-               Quantum neutronClient = getNeutronClient (cloudSite, tenantId);
-
-               // Check if the network exists and return its info
-               try {
-                       Network network = findNetworkByNameOrId (neutronClient, networkNameOrId);
-                       if (network == null) {
-          logger.debug("Query Network: {} not found in tenant {}", networkNameOrId, tenantId);
-          return null;
-                       }
-                       return new NetworkInfoMapper(network).map();
-               }
-               catch (OpenStackBaseException e) {
-                       // Convert Neutron exception to an MsoOpenstackException
-                       MsoException me = neutronExceptionToMsoException (e, "QueryNetwork");
-                       throw me;
-               }
-               catch (RuntimeException e) {
-                       // Catch-all
-                       MsoException me = runtimeExceptionToMsoException(e, "QueryNetwork");
-                       throw me;
-               }
-       }
-    
-    public Optional<Port> getNeutronPort(String neutronPortId, String tenantId, String cloudSiteId)
-       {
-               try {
-                       logger.debug("Finding Neutron port:" + neutronPortId);
-                         CloudSite cloudSite = cloudConfig.getCloudSite(cloudSiteId).orElseThrow(
-                               () -> new MsoCloudSiteNotFound(cloudSiteId));
-                               Quantum neutronClient = getNeutronClient (cloudSite, tenantId);
-                       Port port = findPortById (neutronClient, neutronPortId);
-                       if (port == null) {                             
-                               return Optional.empty();
-                       }
-                       return Optional.of(port);
-               }
-               catch (RuntimeException | MsoException e) {
-                       logger.error("Error retrieving neutron port", e);
-                       return Optional.empty();
-               }
-       }
-
-       /**
-        * Delete the specified Network (by ID) in the given cloud.
-        * If the network does not exist, success is returned.
-        * <p>
-        * @param networkId Openstack ID of the network to delete
-        * @param tenantId The Openstack tenant.
-        * @param cloudSiteId The cloud identifier (may be a region) from which to delete the network.
-        * @return true if the network was deleted, false if the network did not exist
-        * @throws MsoOpenstackException If the Openstack API call returns an exception, this local
-        * exception will be thrown.
-        * @throws MsoCloudSiteNotFound
-        */
-    public boolean deleteNetwork(String networkId, String tenantId, String cloudSiteId) throws MsoException
-       {
-               // Obtain the cloud site information where we will create the stack
-        CloudSite cloudSite = cloudConfig.getCloudSite(cloudSiteId).orElseThrow(
-                () -> new MsoCloudSiteNotFound(cloudSiteId));
-               Quantum neutronClient = getNeutronClient (cloudSite, tenantId);
-
-               try {
-                       // Check that the network exists.
-                       Network network = findNetworkById (neutronClient, networkId);
-                       if (network == null) {
-          logger.info("{} Network not found! Network id: {} Cloud site: {} Tenant: {} ",
-              MessageEnum.RA_DELETE_NETWORK_EXC, networkId, cloudSiteId, tenantId);
-          return false;
-                       }
-
-                       OpenStackRequest<Void> request = neutronClient.networks().delete(network.getId());
-                       executeAndRecordOpenstackRequest(request);
-
-        logger.debug("Deleted Network {} ({})", network.getId(), network.getName());
+        BASIC, PROVIDER, MULTI_PROVIDER
+    };
+
+    /**
+     * Create a network with the specified parameters in the given cloud/tenant.
+     *
+     * If a network already exists with the same name, an exception will be thrown. Note that this is an MSO-imposed
+     * restriction. Openstack does not require uniqueness on network names.
+     * <p>
+     * 
+     * @param cloudSiteId The cloud identifier (may be a region) in which to create the network.
+     * @param tenantId The tenant in which to create the network
+     * @param type The type of network to create (Basic, Provider, Multi-Provider)
+     * @param networkName The network name to create
+     * @param provider The provider network name (for Provider or Multi-Provider networks)
+     * @param vlans A list of VLAN segments for the network (for Provider or Multi-Provider networks)
+     * @return a NetworkInfo object which describes the newly created network
+     * @throws MsoNetworkAlreadyExists Thrown if a network with the same name already exists
+     * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception
+     * @throws MsoCloudSiteNotFound Thrown if the cloudSite is invalid or unknown
+     */
+    public NetworkInfo createNetwork(String cloudSiteId, String tenantId, NetworkType type, String networkName,
+            String provider, List<Integer> vlans) throws MsoException {
+        // Obtain the cloud site information where we will create the stack
+        CloudSite cloudSite =
+                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
+
+        Quantum neutronClient = getNeutronClient(cloudSite, tenantId);
+
+        // Check if a network already exists with this name
+        // Openstack will allow duplicate name, so require explicit check
+        Network network = findNetworkByName(neutronClient, networkName);
+
+        if (network != null) {
+            // Network already exists. Throw an exception
+            logger.error("{} Network {} on Cloud site {} for tenant {} already exists {}",
+                    MessageEnum.RA_NETWORK_ALREADY_EXIST, networkName, cloudSiteId, tenantId,
+                    ErrorCode.DataError.getValue());
+            throw new MsoNetworkAlreadyExists(networkName, tenantId, cloudSiteId);
+        }
+
+        // Does not exist, create a new one
+        network = new Network();
+        network.setName(networkName);
+        network.setAdminStateUp(true);
+
+        if (type == NetworkType.PROVIDER) {
+            if (provider != null && vlans != null && vlans.size() > 0) {
+                network.setProviderPhysicalNetwork(provider);
+                network.setProviderNetworkType("vlan");
+                network.setProviderSegmentationId(vlans.get(0));
+            }
+        } else if (type == NetworkType.MULTI_PROVIDER) {
+            if (provider != null && vlans != null && vlans.size() > 0) {
+                List<Segment> segments = new ArrayList<>(vlans.size());
+                for (int vlan : vlans) {
+                    Segment segment = new Segment();
+                    segment.setProviderPhysicalNetwork(provider);
+                    segment.setProviderNetworkType("vlan");
+                    segment.setProviderSegmentationId(vlan);
+
+                    segments.add(segment);
+                }
+                network.setSegments(segments);
+            }
+        }
+
+        try {
+            OpenStackRequest<Network> request = neutronClient.networks().create(network);
+            Network newNetwork = executeAndRecordOpenstackRequest(request);
+            return new NetworkInfoMapper(newNetwork).map();
+        } catch (OpenStackBaseException e) {
+            // Convert Neutron exception to an MsoOpenstackException
+            MsoException me = neutronExceptionToMsoException(e, "CreateNetwork");
+            throw me;
+        } catch (RuntimeException e) {
+            // Catch-all
+            MsoException me = runtimeExceptionToMsoException(e, "CreateNetwork");
+            throw me;
+        }
+    }
+
+
+    /**
+     * Query for a network with the specified name or ID in the given cloud. If the network exists, return an
+     * NetworkInfo object. If not, return null.
+     * <p>
+     * Whenever possible, the network ID should be used as it is much more efficient. Query by name requires retrieval
+     * of all networks for the tenant and search for matching name.
+     * <p>
+     * 
+     * @param networkNameOrId The network to query
+     * @param tenantId The Openstack tenant to look in for the network
+     * @param cloudSiteId The cloud identifier (may be a region) in which to query the network.
+     * @return a NetworkInfo object describing the queried network, or null if not found
+     * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception
+     * @throws MsoCloudSiteNotFound
+     */
+    public NetworkInfo queryNetwork(String networkNameOrId, String tenantId, String cloudSiteId) throws MsoException {
+        logger.debug("In queryNetwork");
+
+        // Obtain the cloud site information
+        CloudSite cloudSite =
+                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
+
+        Quantum neutronClient = getNeutronClient(cloudSite, tenantId);
+
+        // Check if the network exists and return its info
+        try {
+            Network network = findNetworkByNameOrId(neutronClient, networkNameOrId);
+            if (network == null) {
+                logger.debug("Query Network: {} not found in tenant {}", networkNameOrId, tenantId);
+                return null;
+            }
+            return new NetworkInfoMapper(network).map();
+        } catch (OpenStackBaseException e) {
+            // Convert Neutron exception to an MsoOpenstackException
+            MsoException me = neutronExceptionToMsoException(e, "QueryNetwork");
+            throw me;
+        } catch (RuntimeException e) {
+            // Catch-all
+            MsoException me = runtimeExceptionToMsoException(e, "QueryNetwork");
+            throw me;
+        }
     }
-               catch (OpenStackBaseException e) {
-                       // Convert Neutron exception to an MsoOpenstackException
-                       MsoException me = neutronExceptionToMsoException (e, "Delete Network");
-                       throw me;
-               }
-               catch (RuntimeException e) {
-                       // Catch-all
-                       MsoException me = runtimeExceptionToMsoException(e, "DeleteNetwork");
-                       throw me;
-               }
-
-               return true;
-       }
-
-
-       /**
-        * Update a network with the specified parameters in the given cloud/tenant.
-        *
-        * Specifically, this call is intended to update the VLAN segments on a
-        * multi-provider network.  The provider segments will be replaced with the
-        * supplied list of VLANs.
-        * <p>
-        * Note that updating the 'segments' array is not normally supported by Neutron.
-        * This method relies on a Platform Orchestration extension (using SDN controller
-        * to manage the virtual networking).
-        *
-        * @param cloudSiteId The cloud site ID (may be a region) in which to update the network.
-        * @param tenantId Openstack ID of the tenant in which to update the network
-        * @param networkId The unique Openstack ID of the network to be updated
-        * @param type The network type (Basic, Provider, Multi-Provider)
-        * @param provider The provider network name.  This should not change.
-        * @param vlans The list of VLAN segments to replace
-        * @return a NetworkInfo object which describes the updated network
-        * @throws MsoNetworkNotFound Thrown if the requested network does not exist
-        * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception
-        * @throws MsoCloudSiteNotFound
-        */
-       public NetworkInfo updateNetwork (String cloudSiteId, String tenantId, String networkId, NetworkType type, String provider, List<Integer> vlans)
-            throws MsoException
-       {
-               // Obtain the cloud site information where we will create the stack
-        CloudSite cloudSite = cloudConfig.getCloudSite(cloudSiteId).orElseThrow(
-                () -> new MsoCloudSiteNotFound(cloudSiteId));
-               Quantum neutronClient = getNeutronClient (cloudSite, tenantId);
-
-               // Check that the network exists
-               Network network = findNetworkById (neutronClient, networkId);
-
-               if (network == null) {
-                       // Network not found.  Throw an exception
-        logger.error("{} Network {} on Cloud site {} for Tenant {} not found {}", MessageEnum.RA_NETWORK_NOT_FOUND,
-            networkId, cloudSiteId, tenantId, ErrorCode.DataError.getValue());
-                       throw new MsoNetworkNotFound (networkId, tenantId, cloudSiteId);
-               }
-
-               // Overwrite the properties to be updated
-               if (type == NetworkType.PROVIDER) {
-                       if (provider != null && vlans != null && vlans.size() > 0) {
-                               network.setProviderPhysicalNetwork (provider);
-                               network.setProviderNetworkType("vlan");
-                               network.setProviderSegmentationId (vlans.get(0));
-                       }
-               } else if (type == NetworkType.MULTI_PROVIDER) {
-                       if (provider != null && vlans != null && vlans.size() > 0) {
-                               List<Segment> segments = new ArrayList<>(vlans.size());
-                               for (int vlan : vlans) {
-                                       Segment segment = new Segment();
-                                       segment.setProviderPhysicalNetwork (provider);
-                                       segment.setProviderNetworkType("vlan");
-                                       segment.setProviderSegmentationId (vlan);
-
-                                       segments.add(segment);
-                               }
-                               network.setSegments(segments);
-                       }
-               }
-
-               try {
-                       OpenStackRequest<Network> request = neutronClient.networks().update(network);
-                       Network newNetwork = executeAndRecordOpenstackRequest(request);
-                       return new NetworkInfoMapper(newNetwork).map();
-               }
-               catch (OpenStackBaseException e) {
-                       // Convert Neutron exception to an MsoOpenstackException
-                       MsoException me = neutronExceptionToMsoException (e, "UpdateNetwork");
-                       throw me;
-               }
-               catch (RuntimeException e) {
-                       // Catch-all
-                       MsoException me = runtimeExceptionToMsoException(e, "UpdateNetwork");
-                       throw me;
-               }
-       }
-
-
-       // -------------------------------------------------------------------
-       // PRIVATE UTILITY FUNCTIONS FOR USE WITHIN THIS CLASS
-
-       /**
-        * Get a Neutron (Quantum) client for the Openstack Network service.
-        * This requires a 'member'-level userId + password, which will be retrieved from
-        * properties based on the specified cloud Id.  The tenant in which to operate
-        * must also be provided.
-        * <p>
-        * On successful authentication, the Quantum object will be cached for the
-        * tenantID + cloudId so that it can be reused without reauthenticating with
-        *  Openstack every time.
-        *
-        * @param cloudSite - a cloud site definition
-        * @param tenantId - Openstack tenant ID
-        * @return an authenticated Quantum object
-        */
-    private Quantum getNeutronClient(CloudSite cloudSite, String tenantId) throws MsoException
-       {
-               String cloudId = cloudSite.getId();
-               String region = cloudSite.getRegionId();        
-
-
-               // Obtain an MSO token for the tenant from the identity service
-               CloudIdentity cloudIdentity = cloudSite.getIdentityService();
-               MsoTenantUtils tenantUtils = tenantUtilsFactory.getTenantUtilsByServerType(cloudIdentity.getIdentityServerType());
+
+    public Optional<Port> getNeutronPort(String neutronPortId, String tenantId, String cloudSiteId) {
+        try {
+            logger.debug("Finding Neutron port:" + neutronPortId);
+            CloudSite cloudSite =
+                    cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
+            Quantum neutronClient = getNeutronClient(cloudSite, tenantId);
+            Port port = findPortById(neutronClient, neutronPortId);
+            if (port == null) {
+                return Optional.empty();
+            }
+            return Optional.of(port);
+        } catch (RuntimeException | MsoException e) {
+            logger.error("Error retrieving neutron port", e);
+            return Optional.empty();
+        }
+    }
+
+    /**
+     * Delete the specified Network (by ID) in the given cloud. If the network does not exist, success is returned.
+     * <p>
+     * 
+     * @param networkId Openstack ID of the network to delete
+     * @param tenantId The Openstack tenant.
+     * @param cloudSiteId The cloud identifier (may be a region) from which to delete the network.
+     * @return true if the network was deleted, false if the network did not exist
+     * @throws MsoOpenstackException If the Openstack API call returns an exception, this local exception will be
+     *         thrown.
+     * @throws MsoCloudSiteNotFound
+     */
+    public boolean deleteNetwork(String networkId, String tenantId, String cloudSiteId) throws MsoException {
+        // Obtain the cloud site information where we will create the stack
+        CloudSite cloudSite =
+                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
+        Quantum neutronClient = getNeutronClient(cloudSite, tenantId);
+
+        try {
+            // Check that the network exists.
+            Network network = findNetworkById(neutronClient, networkId);
+            if (network == null) {
+                logger.info("{} Network not found! Network id: {} Cloud site: {} Tenant: {} ",
+                        MessageEnum.RA_DELETE_NETWORK_EXC, networkId, cloudSiteId, tenantId);
+                return false;
+            }
+
+            OpenStackRequest<Void> request = neutronClient.networks().delete(network.getId());
+            executeAndRecordOpenstackRequest(request);
+
+            logger.debug("Deleted Network {} ({})", network.getId(), network.getName());
+        } catch (OpenStackBaseException e) {
+            // Convert Neutron exception to an MsoOpenstackException
+            MsoException me = neutronExceptionToMsoException(e, "Delete Network");
+            throw me;
+        } catch (RuntimeException e) {
+            // Catch-all
+            MsoException me = runtimeExceptionToMsoException(e, "DeleteNetwork");
+            throw me;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Update a network with the specified parameters in the given cloud/tenant.
+     *
+     * Specifically, this call is intended to update the VLAN segments on a multi-provider network. The provider
+     * segments will be replaced with the supplied list of VLANs.
+     * <p>
+     * Note that updating the 'segments' array is not normally supported by Neutron. This method relies on a Platform
+     * Orchestration extension (using SDN controller to manage the virtual networking).
+     *
+     * @param cloudSiteId The cloud site ID (may be a region) in which to update the network.
+     * @param tenantId Openstack ID of the tenant in which to update the network
+     * @param networkId The unique Openstack ID of the network to be updated
+     * @param type The network type (Basic, Provider, Multi-Provider)
+     * @param provider The provider network name. This should not change.
+     * @param vlans The list of VLAN segments to replace
+     * @return a NetworkInfo object which describes the updated network
+     * @throws MsoNetworkNotFound Thrown if the requested network does not exist
+     * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception
+     * @throws MsoCloudSiteNotFound
+     */
+    public NetworkInfo updateNetwork(String cloudSiteId, String tenantId, String networkId, NetworkType type,
+            String provider, List<Integer> vlans) throws MsoException {
+        // Obtain the cloud site information where we will create the stack
+        CloudSite cloudSite =
+                cloudConfig.getCloudSite(cloudSiteId).orElseThrow(() -> new MsoCloudSiteNotFound(cloudSiteId));
+        Quantum neutronClient = getNeutronClient(cloudSite, tenantId);
+
+        // Check that the network exists
+        Network network = findNetworkById(neutronClient, networkId);
+
+        if (network == null) {
+            // Network not found. Throw an exception
+            logger.error("{} Network {} on Cloud site {} for Tenant {} not found {}", MessageEnum.RA_NETWORK_NOT_FOUND,
+                    networkId, cloudSiteId, tenantId, ErrorCode.DataError.getValue());
+            throw new MsoNetworkNotFound(networkId, tenantId, cloudSiteId);
+        }
+
+        // Overwrite the properties to be updated
+        if (type == NetworkType.PROVIDER) {
+            if (provider != null && vlans != null && vlans.size() > 0) {
+                network.setProviderPhysicalNetwork(provider);
+                network.setProviderNetworkType("vlan");
+                network.setProviderSegmentationId(vlans.get(0));
+            }
+        } else if (type == NetworkType.MULTI_PROVIDER) {
+            if (provider != null && vlans != null && vlans.size() > 0) {
+                List<Segment> segments = new ArrayList<>(vlans.size());
+                for (int vlan : vlans) {
+                    Segment segment = new Segment();
+                    segment.setProviderPhysicalNetwork(provider);
+                    segment.setProviderNetworkType("vlan");
+                    segment.setProviderSegmentationId(vlan);
+
+                    segments.add(segment);
+                }
+                network.setSegments(segments);
+            }
+        }
+
+        try {
+            OpenStackRequest<Network> request = neutronClient.networks().update(network);
+            Network newNetwork = executeAndRecordOpenstackRequest(request);
+            return new NetworkInfoMapper(newNetwork).map();
+        } catch (OpenStackBaseException e) {
+            // Convert Neutron exception to an MsoOpenstackException
+            MsoException me = neutronExceptionToMsoException(e, "UpdateNetwork");
+            throw me;
+        } catch (RuntimeException e) {
+            // Catch-all
+            MsoException me = runtimeExceptionToMsoException(e, "UpdateNetwork");
+            throw me;
+        }
+    }
+
+
+    // -------------------------------------------------------------------
+    // PRIVATE UTILITY FUNCTIONS FOR USE WITHIN THIS CLASS
+
+    /**
+     * Get a Neutron (Quantum) client for the Openstack Network service. This requires a 'member'-level userId +
+     * password, which will be retrieved from properties based on the specified cloud Id. The tenant in which to operate
+     * must also be provided.
+     * <p>
+     * On successful authentication, the Quantum object will be cached for the tenantID + cloudId so that it can be
+     * reused without reauthenticating with Openstack every time.
+     *
+     * @param cloudSite - a cloud site definition
+     * @param tenantId - Openstack tenant ID
+     * @return an authenticated Quantum object
+     */
+    private Quantum getNeutronClient(CloudSite cloudSite, String tenantId) throws MsoException {
+        String cloudId = cloudSite.getId();
+        String region = cloudSite.getRegionId();
+
+
+        // Obtain an MSO token for the tenant from the identity service
+        CloudIdentity cloudIdentity = cloudSite.getIdentityService();
+        MsoTenantUtils tenantUtils =
+                tenantUtilsFactory.getTenantUtilsByServerType(cloudIdentity.getIdentityServerType());
         final String keystoneUrl = tenantUtils.getKeystoneUrl(cloudId, cloudIdentity);
-               String neutronUrl = null;
-               String tokenId = null;
-               Calendar expiration = null;
-               try {
-               if (ServerType.KEYSTONE.equals(cloudIdentity.getIdentityServerType())) {
-                               Keystone keystoneTenantClient = new Keystone(keystoneUrl);
-                               Access access = null;
-                               
-                               Authentication credentials = authenticationMethodFactory.getAuthenticationFor(cloudIdentity);
-                               OpenStackRequest<Access> request = keystoneTenantClient.tokens().authenticate(credentials).withTenantId(tenantId);
-                               access = executeAndRecordOpenstackRequest(request);
-                               
-                               
-                               try {
-                                       neutronUrl = KeystoneUtils.findEndpointURL(access.getServiceCatalog(), "network", region, "public");
-                                       if (! neutronUrl.endsWith("/")) {
-                               neutronUrl += "/v2.0/";
-                           }
-                               } catch (RuntimeException e) {
-                                       // This comes back for not found (probably an incorrect region ID)
-                                       String error = "Network service not found: region=" + region + ",cloud=" + cloudIdentity.getId();
-                                       throw new MsoAdapterException (error, e);
-                               }
-                               tokenId = access.getToken().getId();
-                               expiration = access.getToken().getExpires();
-               } else if (ServerType.KEYSTONE_V3.equals(cloudIdentity.getIdentityServerType())) {
-                       try {
-                               KeystoneAuthHolder holder = keystoneV3Authentication.getToken(cloudSite, tenantId, "network");
-                               tokenId = holder.getId();
-                               expiration = holder.getexpiration();
-                               neutronUrl = holder.getServiceUrl();
-                               if (! neutronUrl.endsWith("/")) {
-                               neutronUrl += "/v2.0/";
-                           }
-                       } catch (ServiceEndpointNotFoundException e) {
-                               // This comes back for not found (probably an incorrect region ID)
-                                       String error = "Network service not found: region=" + region + ",cloud=" + cloudIdentity.getId();
-                                       throw new MsoAdapterException (error, e);
-                       }
-               }
-               }
-               catch (OpenStackResponseException e) {
-                       if (e.getStatus() == 401) {
-                               // Authentication error.
-                               String error = "Authentication Failure: tenant=" + tenantId + ",cloud=" + cloudIdentity.getId();
-
-                               throw new MsoAdapterException(error);
-                       }
-                       else {
-                               MsoException me = keystoneErrorToMsoException(e, "TokenAuth");
-                               throw me;
-                       }
-               }
-               catch (OpenStackConnectException e) {
-                       // Connection to Openstack failed
-                       MsoIOException me = new MsoIOException (e.getMessage(), e);
-                       me.addContext("TokenAuth");
-                       throw me;
-               }
-               catch (RuntimeException e) {
-                       // Catch-all
-                       MsoException me = runtimeExceptionToMsoException(e, "TokenAuth");
-                       throw me;
-               }
-
-               Quantum neutronClient = new Quantum(neutronUrl);
-               neutronClient.token(tokenId);
-               return neutronClient;
-       }
-
-       /*
-        * Find a tenant (or query its existence) by its Name or Id.  Check first against the
-        * ID.  If that fails, then try by name.
-        *
-        * @param adminClient an authenticated Keystone object
-        * @param tenantName the tenant name or ID to query
-        * @return a Tenant object or null if not found
-        */
-       public Network findNetworkByNameOrId (Quantum neutronClient, String networkNameOrId)
-       {
-               if (networkNameOrId == null) {
+        String neutronUrl = null;
+        String tokenId = null;
+        Calendar expiration = null;
+        try {
+            if (ServerType.KEYSTONE.equals(cloudIdentity.getIdentityServerType())) {
+                Keystone keystoneTenantClient = new Keystone(keystoneUrl);
+                Access access = null;
+
+                Authentication credentials = authenticationMethodFactory.getAuthenticationFor(cloudIdentity);
+                OpenStackRequest<Access> request =
+                        keystoneTenantClient.tokens().authenticate(credentials).withTenantId(tenantId);
+                access = executeAndRecordOpenstackRequest(request);
+
+
+                try {
+                    neutronUrl = KeystoneUtils.findEndpointURL(access.getServiceCatalog(), "network", region, "public");
+                    if (!neutronUrl.endsWith("/")) {
+                        neutronUrl += "/v2.0/";
+                    }
+                } catch (RuntimeException e) {
+                    // This comes back for not found (probably an incorrect region ID)
+                    String error = "Network service not found: region=" + region + ",cloud=" + cloudIdentity.getId();
+                    throw new MsoAdapterException(error, e);
+                }
+                tokenId = access.getToken().getId();
+                expiration = access.getToken().getExpires();
+            } else if (ServerType.KEYSTONE_V3.equals(cloudIdentity.getIdentityServerType())) {
+                try {
+                    KeystoneAuthHolder holder = keystoneV3Authentication.getToken(cloudSite, tenantId, "network");
+                    tokenId = holder.getId();
+                    expiration = holder.getexpiration();
+                    neutronUrl = holder.getServiceUrl();
+                    if (!neutronUrl.endsWith("/")) {
+                        neutronUrl += "/v2.0/";
+                    }
+                } catch (ServiceEndpointNotFoundException e) {
+                    // This comes back for not found (probably an incorrect region ID)
+                    String error = "Network service not found: region=" + region + ",cloud=" + cloudIdentity.getId();
+                    throw new MsoAdapterException(error, e);
+                }
+            }
+        } catch (OpenStackResponseException e) {
+            if (e.getStatus() == 401) {
+                // Authentication error.
+                String error = "Authentication Failure: tenant=" + tenantId + ",cloud=" + cloudIdentity.getId();
+
+                throw new MsoAdapterException(error);
+            } else {
+                MsoException me = keystoneErrorToMsoException(e, "TokenAuth");
+                throw me;
+            }
+        } catch (OpenStackConnectException e) {
+            // Connection to Openstack failed
+            MsoIOException me = new MsoIOException(e.getMessage(), e);
+            me.addContext("TokenAuth");
+            throw me;
+        } catch (RuntimeException e) {
+            // Catch-all
+            MsoException me = runtimeExceptionToMsoException(e, "TokenAuth");
+            throw me;
+        }
+
+        Quantum neutronClient = new Quantum(neutronUrl);
+        neutronClient.token(tokenId);
+        return neutronClient;
+    }
+
+    /*
+     * Find a tenant (or query its existence) by its Name or Id. Check first against the ID. If that fails, then try by
+     * name.
+     *
+     * @param adminClient an authenticated Keystone object
+     * 
+     * @param tenantName the tenant name or ID to query
+     * 
+     * @return a Tenant object or null if not found
+     */
+    public Network findNetworkByNameOrId(Quantum neutronClient, String networkNameOrId) {
+        if (networkNameOrId == null) {
             return null;
         }
 
-               Network network = findNetworkById(neutronClient, networkNameOrId);
+        Network network = findNetworkById(neutronClient, networkNameOrId);
 
-               if (network == null) {
+        if (network == null) {
             network = findNetworkByName(neutronClient, networkNameOrId);
         }
 
-               return network;
-       }
-
-       /*
-        * Find a network (or query its existence) by its Id.
-        *
-        * @param neutronClient an authenticated Quantum object
-        * @param networkId the network ID to query
-        * @return a Network object or null if not found
-        */
-       private Network findNetworkById (Quantum neutronClient, String networkId)
-       {
-               if (networkId == null) {
+        return network;
+    }
+
+    /*
+     * Find a network (or query its existence) by its Id.
+     *
+     * @param neutronClient an authenticated Quantum object
+     * 
+     * @param networkId the network ID to query
+     * 
+     * @return a Network object or null if not found
+     */
+    private Network findNetworkById(Quantum neutronClient, String networkId) {
+        if (networkId == null) {
             return null;
         }
 
-               try {
-                       OpenStackRequest<Network> request = neutronClient.networks().show(networkId);
-                       Network network = executeAndRecordOpenstackRequest(request);
-                       return network;
-               }
-               catch (OpenStackResponseException e) {
-                       if (e.getStatus() == 404) {
-                               return null;
-                       } else {
-          logger.error("{} {} Openstack Error, GET Network By ID ({}): ", MessageEnum.RA_CONNECTION_EXCEPTION,
-              ErrorCode.DataError.getValue(), networkId, e);
-          throw e;
-                       }
-               }
-       }
-       
-       
-       private Port findPortById (Quantum neutronClient, String neutronPortId)
-       {
-               if (neutronPortId == null) {
+        try {
+            OpenStackRequest<Network> request = neutronClient.networks().show(networkId);
+            Network network = executeAndRecordOpenstackRequest(request);
+            return network;
+        } catch (OpenStackResponseException e) {
+            if (e.getStatus() == 404) {
+                return null;
+            } else {
+                logger.error("{} {} Openstack Error, GET Network By ID ({}): ", MessageEnum.RA_CONNECTION_EXCEPTION,
+                        ErrorCode.DataError.getValue(), networkId, e);
+                throw e;
+            }
+        }
+    }
+
+
+    private Port findPortById(Quantum neutronClient, String neutronPortId) {
+        if (neutronPortId == null) {
             return null;
         }
 
-               try {
-                       OpenStackRequest<Port> request = neutronClient.ports().show(neutronPortId);
-                       Port port = executeAndRecordOpenstackRequest(request);
-                       return port;
-               }
-               catch (OpenStackResponseException e) {
-                       if (e.getStatus() == 404) {
-                               logger.warn("Neutron port not found: " + neutronPortId,"Neutron port not found: " + neutronPortId);
-                               return null;
-                       } else {
-                               logger.error("{} {} Openstack Error, GET Neutron Port By ID ({}): ", MessageEnum.RA_CONNECTION_EXCEPTION,
-                                       ErrorCode.DataError.getValue(), neutronPortId, e);
-                               throw e;
-                       }
-               }
-       }
-
-       /*
-        * Find a network (or query its existence) by its Name.  This method avoids an
-        * initial lookup by ID when it's known that we have the network Name.
-        *
-        * Neutron does not support 'name=*' query parameter for Network query (show).
-        * The only way to query by name is to retrieve all networks and look for the
-        * match.  While inefficient, this capability will be provided as it is needed
-        * by MSO, but should be avoided in favor of ID whenever possible.
-        *
-        * TODO:
-        * Network names are not required to be unique, though MSO will attempt to enforce
-        * uniqueness.  This call probably needs to return an error (instead of returning
-        * the first match).
-        *
-        * @param neutronClient an authenticated Quantum object
-        * @param networkName the network name to query
-        * @return a Network object or null if not found
-        */
-       public Network findNetworkByName (Quantum neutronClient, String networkName)
-       {
-               if (networkName == null) {
+        try {
+            OpenStackRequest<Port> request = neutronClient.ports().show(neutronPortId);
+            Port port = executeAndRecordOpenstackRequest(request);
+            return port;
+        } catch (OpenStackResponseException e) {
+            if (e.getStatus() == 404) {
+                logger.warn("Neutron port not found: " + neutronPortId, "Neutron port not found: " + neutronPortId);
+                return null;
+            } else {
+                logger.error("{} {} Openstack Error, GET Neutron Port By ID ({}): ",
+                        MessageEnum.RA_CONNECTION_EXCEPTION, ErrorCode.DataError.getValue(), neutronPortId, e);
+                throw e;
+            }
+        }
+    }
+
+    /*
+     * Find a network (or query its existence) by its Name. This method avoids an initial lookup by ID when it's known
+     * that we have the network Name.
+     *
+     * Neutron does not support 'name=*' query parameter for Network query (show). The only way to query by name is to
+     * retrieve all networks and look for the match. While inefficient, this capability will be provided as it is needed
+     * by MSO, but should be avoided in favor of ID whenever possible.
+     *
+     * TODO: Network names are not required to be unique, though MSO will attempt to enforce uniqueness. This call
+     * probably needs to return an error (instead of returning the first match).
+     *
+     * @param neutronClient an authenticated Quantum object
+     * 
+     * @param networkName the network name to query
+     * 
+     * @return a Network object or null if not found
+     */
+    public Network findNetworkByName(Quantum neutronClient, String networkName) {
+        if (networkName == null) {
             return null;
         }
 
-               try {
-                       OpenStackRequest<Networks> request = neutronClient.networks().list();
-                       Networks networks = executeAndRecordOpenstackRequest(request);
-                       for (Network network : networks.getList()) {
-                               if (network.getName().equals(networkName)) {
-            logger.debug("Found match on network name: {}", networkName);
-            return network;
-                               }
-                       }
-        logger.debug("findNetworkByName - no match found for {}", networkName);
-        return null;
-               }
-               catch (OpenStackResponseException e) {
-                       if (e.getStatus() == 404) {
-                               return null;
-                       } else {
-          logger.error("{} {} Openstack Error, GET Network By Name ({}): ", MessageEnum.RA_CONNECTION_EXCEPTION,
-              ErrorCode.DataError.getValue(), networkName, e);
-          throw e;
-                       }
-               }
-       }
+        try {
+            OpenStackRequest<Networks> request = neutronClient.networks().list();
+            Networks networks = executeAndRecordOpenstackRequest(request);
+            for (Network network : networks.getList()) {
+                if (network.getName().equals(networkName)) {
+                    logger.debug("Found match on network name: {}", networkName);
+                    return network;
+                }
+            }
+            logger.debug("findNetworkByName - no match found for {}", networkName);
+            return null;
+        } catch (OpenStackResponseException e) {
+            if (e.getStatus() == 404) {
+                return null;
+            } else {
+                logger.error("{} {} Openstack Error, GET Network By Name ({}): ", MessageEnum.RA_CONNECTION_EXCEPTION,
+                        ErrorCode.DataError.getValue(), networkName, e);
+                throw e;
+            }
+        }
+    }
 }