Java and the Nuage VSPK - Part 2 - Creating VSD Objects

February 16, 2018 - Leonard Paquette

Setup

In part 1 of this series, we discussed how to set up your Java development environment to use the VSPK library. If you have not completed the setup, do that now. Part 1 can be found here.

There are 2 small Java programs listed (CreateHelloEnterprise.java and DeleteHelloEnterprise.java) in Part 1 that create and remove a VSD enterprise entity object named “HelloEnterprise”. Confirm that your Java environment is operational by running both of these programs and verifying that you can observe the actions of these programs visually in VSA (Virtualized Services Architect).

Nuage VSD Object Model

The VSD employs well-known design patterns to model its objects. The overall object design is a tree structure with Parent-Child associations between pairs of objects that have a “one-to-many” relationship. At the top-level, we have an Enterprise object, which serves as the parent for 1 or more Domains. In turn, a Domain object will become the parent for 1 or more Zones. Likewise, a Zone object will become the parent for 1 or more Subnets. This pattern will become evident as we start to construct our network and use the VSA to visualize its object graph. Let’s also review the 4 key object types that we will be managing.

The Enterprise object is the top-level object that represents a company or organization. It could also represent a customer in a case where one company manages network services for multiple customers using the same VSD instance. Names of enterprise objects will typically follow patterns such “My Company”, or “Customer ABC”. This is where we will start our network design.

The Domain object is the child of an enterprise object. It is the first level from which we can start to customize different types of network environments within the same enterprise. For example, we can provide a DHCP Server address for a domain that will be inherited by all virtual machines that are later attached to that domain. For another domain in the same enterprise, we might provide a different DHCP server address.

In order to create a domain object, you must first generate a Domain Template whose policies (e.g., encryption, DPI) are inherited by all domain objects that are instantiated from it. Domain objects will often be named by release environment or functional purpose, such as {“Prod”, “Test”, “Dev”} or {“Web Servers”, “DB Servers”, “App Servers”}.

The Zone object is the child of a domain object. It serves mainly as a mechanism to allow grouping of its child subnet objects by policies or rules for security, ingress, egress, etc. Zone objects will often be grouped by a network constraint {“DMZ Zone”, “Non DMZ Zone”}, or functional purpose {“Web Tier”, “DB Tier”, “App Tier”}.

The Subnet object is the child of a zone object. As its related networking term implies, a VSD subnet object specifies the IP address range that is available for all virtual machines that are attached to it. The address range for one subnet cannot overlap the address range covered by another subnet within the same domain or zone. Subnet objects will often have names based on functional purpose, such as {“Customer Support Apps”, “Sales Apps”, “Accounting Apps”} or by the IP address range itself, such as {“Subnet 10.75.55.0-24”, “Subnet 10.75.56.0-24”}.

Our First Little Network - Overview

Let’s design a small network from the top down. We will create a new enterprise called “MyLittleEnterprise”, and then instantiate a domain under MyLittleEnterprise using a simple domain template. Once we have a domain, we will add 2 zones, one for web servers and one for database servers. Finally, we will configure 2 subnets for each zone.

In a more realistic environment, your first Nuage network would likely undergo an initial deployment with a static configuration followed by one or more bulk migrations of existing virtual machines into that initial Nuage environment. Afterwards, new virtual machines would be provisioned, old virtual machines would be decommissioned or migrated from subnet to subnet, and new domains, zones and subnets would be added. With that in mind, we will construct our network one object at a time and assume that parts of the network might already exist as we add new objects into it. We will develop 3 modules to help us construct our network.

The NetworkDescriptor class offers a record definition for a new Subnet object. Recall that a Subnet object is a child of a Zone object, which means that we need to create a parent Zone object before we can create a Subnet under it. Similarly, we need a parent Domain object and a parent Enterprise object. Therefore, if we want to create a new Subnet object, we need to provide references to all parent nodes above it in the VSD object tree.

The NetworkRepository class provides a layout of the network which needs to be constructed. Although for simplicity we just hard-coded a few values for instances of the NetworkDescriptor class, a service like this could source its data from a company database or system that manages network configuration, subnet usage and availablity, IP address assignment, etc.

The NetworkBuilder class requests a network layout from the NetworkRepository service and verifies all of the references to VSD objects. It operates as an idempotent service, creating objects only when needed. If no objects exist, then all are created. If all objects exist, then none are created.

The NetworkDescriptor Class

This is a very simple class that provides a set of attributes that describe a VSD object in our network. Within our current scope, we are only concerned with top-level items from Enterprise to Subnet. For brevity, all attributes are assigned public access modifiers. Other classes in our project will use this class to reference subnet details of our network.

Here is a sample version of NetworkDescriptor.java :

public class NetworkDescriptor {
    public String enterpriseName;
    public String domainTemplateName;
    public String domainName;
    public String zoneName;
    public String subnetName;
    public String subnetAddress;
    public String subnetNetmask;
        
    public NetworkDescriptor(String enterpriseName, String domainTemplateName,
                             String domainName, String zoneName, String subnetName,
                             String subnetAddress, String subnetNetmask) {

        this.enterpriseName = enterpriseName;
        this.domainTemplateName = domainTemplateName;
        this.domainName = domainName;
        this.zoneName = zoneName;
        this.subnetName = subnetName;
        this.subnetAddress = subnetAddress;
        this.subnetNetmask = subnetNetmask;
    }
}

The NetworkRepository Class

This class maintains the names of the VSD objects that comprise our network. We use a Java ArrayList to maintain a list of NetworkDescriptor instances that can referenced by other services that need to view the network as a whole. To kick things off, we will start with one branch of the network, from an Enterprise object down to a single Subnet object.

Consider this version of NetworkRepository.java :

import java.util.ArrayList;
import java.util.List;

public class NetworkRepository {
    public List<NetworkDescriptor> networkLayout = new ArrayList<NetworkDescriptor>() {
        {
           add(new NetworkDescriptor("MyLittleEnterprise", "MyLittleDomainTemplate",
                                     "MyLittleDomain", "MyLittleWebTierZone",
                                     "MyLittleWebSubnet1",
                                     "10.117.18.0", "255.255.255.0"));
        }
    };
}

In this example, we specify that our Enterprise is to be named “My Little Enterprise”. Below the enterprise, we would like a Domain to be named “My Little Domain” based on a template named “My Little Domain Template”. A Zone named “My Little Web Tier Zone” should be created for the Domain and the Zone should be the parent for a Subnet named “My Little Web Subnet 1”. The network specific attributes indicate that our subnet should have an IP Address range of 10.117.18.0 to 10.117.18.255.

The NetworkBuilder Class - Introduction

This class will be responsible for analyzing our network layout and ensuring that its components are represented by objects in VSD. It will iterate a list of NetworkDescriptor records from the NetworkRepository class, and for each record, it will verify that corresponding VSD objects exist with matching names. If an appropriate object does not exist, then it will be created and returned so that it can serve as the parent for a new child object. If our entire network layout exists, then the class will simply list all of the objects in our network.

Here is a simple version of NetworkBuilder.java that just reads in our network layout and displays the names of key objects :

import java.util.List;

public class NetworkBuilder {
  public static void main(String[] args) {
    NetworkBuilder instance = new NetworkBuilder();
    NetworkRepository networkRepository = new NetworkRepository(); // 1

    List<NetworkDescriptor> networkLayout = networkRepository.networkLayout; // 2

    instance.verifyNetwork(networkLayout); // 3

  }
    
  private void verifyNetwork(List<NetworkDescriptor> networkLayout) {
    for (NetworkDescriptor descriptor : networkLayout)  { // 4

      System.out.println("Network requires Enterprise: " + descriptor.enterpriseName);
      System.out.println("Network requires Template: " + descriptor.domainTemplateName);
      System.out.println("Network requires Domain: " + descriptor.domainName);
      System.out.println("Network requires Zone: " + descriptor.zoneName);
      System.out.println("Network requires Subnet: " + descriptor.subnetName);
      this.verifyNetworkObjects(descriptor); // 5

    }
  }

  private void verifyNetworkObjects(NetworkDescriptor descriptor) {}

}

In the main method at Lines 1 and 2, we instantiate the NetworkRepository class and fetch a List of NetworkDescriptor objects to represent our network layout. Then in Line 3, we call the verifyNetwork method, passing in the List.

Inside the verifyNetwork method, at line 4, we iterate the list of network descriptors and then display the names of the key objects to the console. Then, in line 5 we call the verifyNetworkObjects method, which for now does nothing, but will be expanded as we add more functionality.

Run the main method of NetworkBuilder in your Java environment. If it executes properly, you should see the following results in your console :

Network layout requires Enterprise: MyLittleEnterprise
Network layout requires Template: MyLittleDomainTemplate
Network layout requires Domain: MyLittleDomain
Network layout requires Zone: MyLittleWebTierZone
Network layout requires Subnet: MyLittleWebSubnet1

From this skeletal version of NetworkBuilder, we will develop additional functionality to handle our various types of VSD objects. Our first task will be to write a handler for a VSD Enterprise object. We will then write additional handlers for Domains, Zones and Subnets.

The NetworkEnterpriseHandler Class

Let’s expand the functionality of NetworkBuilder by invoking methods of a new class called NetworkEnterpriseHandler that will handle all functionality for VSD Enterprise objects. For now, we need some basic behavior to verify that an Enterprise exists with a given name. If the enterprise exists, it should be returned. If the enterprise does not exist, it should be created and returned.

Here is an implementation of the NetworkEnterpriseHandler class :

import net.nuagenetworks.bambou.RestException;
import net.nuagenetworks.vspk.v5_0.Enterprise;
import net.nuagenetworks.vspk.v5_0.Me;
import net.nuagenetworks.vspk.v5_0.VSDSession;
import net.nuagenetworks.vspk.v5_0.fetchers.EnterprisesFetcher;

public class NetworkEnterpriseHandler {
    private VSDSession session;
    
    public NetworkEnterpriseHandler(VSDSession session) { // 1

        this.session = session;
    }
    
    public Enterprise verifyEnterprise(NetworkDescriptor descriptor) {
        String enterpriseName = descriptor.enterpriseName;
        Enterprise enterprise = this.fetchEnterprise(enterpriseName); // 2


        if (enterprise == null) {
            System.out.println("Enterprise " + enterpriseName + " not found.  Create one");
            enterprise = this.createEnterprise(enterpriseName); // 3

        } else {
            System.out.println("Enterprise " + enterpriseName + " already exists");
        }

        return enterprise;
    }
    
    public Enterprise fetchEnterprise(String enterpriseName) {
        Me me = this.session.getMe(); // 4

        String filter = String.format("name == '%s'", enterpriseName); // 5

        EnterprisesFetcher fetcher = me.getEnterprises(); // 6

        Enterprise enterprise = null;

        try {
            enterprise = fetcher.getFirst(filter, null, null, null, null, null, true); // 7

        } catch (RestException e) {
            e.printStackTrace();
        }
        
        return enterprise;
    }
    
    public Enterprise createEnterprise(String enterpriseName) {
        Me me = this.session.getMe(); // 8

        Enterprise enterprise = null;

        try {
            enterprise = new Enterprise(); // 9

            enterprise.setName(enterpriseName); // 10

            me.createChild(enterprise); // 11

        } catch (RestException e) {
            e.printStackTrace();
        }
        
        return enterprise;
    }
    
    public void deleteEnterprise(Enterprise enterprise) { // 12

        if (enterprise == null) {
            System.out.println("Enterprise does not exist");
        } else {
            System.out.println("Enterprise " + enterprise.getName() + " will be deleted");
            try {
                enterprise.delete(); // 13

            } catch (RestException e) {
                e.printStackTrace();
            }
        }
    }
}

Note that in the constructor at Line 1, there is a VSDSession argument. A VSDSession object establishes a secure HTTP connection to a VSD instance. It is similar to how you would create a connection to a database before running SQL queries. Before calling methods in this class, we will assume that a VSD session has already been established and started by NetworkBuilder.

In Line 2 of the verifyEnterprise method, we perform a search for an existing VSD Enterprise object that matches the name for our enterprise that is passed in via NetworkDescriptor. If the Enterprise already exists, then we return that Enterprise object. If the Enterprise does not exist, then in Line 3 we call the createEnterprise method to create and return a new Enterprise object.

In the fetchEnterprise method at Line 4, we instantiate a Me object to serve as the root for all of our enterprise specific network objects. Line 5 sets up a search filter based on the name of our enterprise. In Line 6, we create an instance of EnterprisesFetcher. The VSPK provides “Fetchers” for all entity types in the VSD to offer convenience methods for operating on collections of VSD objects. Line 7 calls the getFirst method of the Fetcher to retrieve the Enterprise object matching the name in the search filter.

Line 8 of the createEnterprise method is similar to Line 4 of the fetchEnterprise method. It provides us with a Me root object onto which we can attach a new Enterprise object. In Line 9, we call the constructor of the VSPK Enterprise class to create a brand new Enterprise object and then in Line 10 we assign our enterprise name. Finally, in Line 11, we create a new child Enterprise object.

The method deleteEnterprise will be covered later when we discuss how to remove our network layout from the VSD.

Adding the Enterprise to our Network

Here is the updated version of the NetworkBuilder class that integrates with NetworkEnterpriseHandler.

import java.util.List;
import net.nuagenetworks.bambou.RestException;
import net.nuagenetworks.vspk.v5_0.Enterprise;
import net.nuagenetworks.vspk.v5_0.VSDSession;

public class NetworkBuilder {
    private String url = "https://198.51.100.108:8443"; // 1

    private VSDSession session = new VSDSession("csproot", "csproot", "csp", url); // 2

    private NetworkEnterpriseHandler enterpriseHandler = 
                                             new NetworkEnterpriseHandler(session);

    public static void main(String[] args) {
      NetworkBuilder instance = new NetworkBuilder();
      NetworkRepository networkRepository = new NetworkRepository();
      List<NetworkDescriptor> networkLayout = networkRepository.networkLayout;
      instance.verifyNetwork(networkLayout);
    }
    
    private void verifyNetwork(List<NetworkDescriptor> networkLayout) {
      this.startSession(); // 3

      for (NetworkDescriptor descriptor : networkLayout)  {
        System.out.println("Network requires Enterprise: " + descriptor.enterpriseName);
        System.out.println("Network requires Template: " + descriptor.domainTemplateName);
        System.out.println("Network requires Domain: " + descriptor.domainName);
        System.out.println("Network requires Zone: " + descriptor.zoneName);
        System.out.println("Network requires Subnet: " + descriptor.subnetName);
        this.verifyNetworkObjects(descriptor);
      }
    }

    private void verifyNetworkObjects(NetworkDescriptor descriptor) {
        Enterprise enterprise = enterpriseHandler.verifyEnterprise(descriptor); // 4

    }

    private void startSession() {
        System.out.println("Starting a new VSD session");
        try {
            session.start();
        } catch (RestException e) {
            e.printStackTrace();
        }
    }

}

In Lines 1 and 2, we provide a valid set of username/password credentials and the location of the VSD. You will need to provide an appropriate address for your VSD.

We need to connect to the VSD before issuing calls to it. At Line 3 of the verifyNetwork method, we make a call to the private startSession method to establish a VSD session.

We now have a handler that can deal with Enterprise objects. In Line 4 of the verifyNetworkObjects method, we call the verifyEnterprise method of NetworkEnterpriseHandler.

You should now have 4 Java classes in your environment, namely NetworkBuilder, NetworkDescriptor, NetworkRepository and NetworkEnterpriseHandler. Ensure that they compile and then run the main method from NetworkBuilder in your Java environment. If it executes properly, you should see the following results in your console :

Starting a new VSD session
Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet1
Enterprise MyLittleEnterprise not found.  Create one

If your environment is working, and if the code completed successfully, you will see our new Enterprise object in VSA.

VSA home page with enterprise

Recall that NetworkEnterpriseHandler is designed to check whether a VSD Enterprise object exists with a given name before creating a new object. Let’s test this out now. Run the main method from NetworkBuilder again. You should see the following results in your console :

Starting a new VSD session
Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet1
Enterprise MyLittleEnterprise already exists

The NetworkDomainTemplateHandler Class

Let’s continue with the first of 2 handler classes to manage our VSD Domain objects. We now begin to see dependencies among our various VSD objects. For example, in order for a VSD Domain object to be created, there must be an existing VSD Domain Template. Similarly, for a VSD Domain Template to be created, we need an existing VSD Enterprise object.

Here is an implementation of the NetworkDomainTemplateHandler class providing similar methods to the Enterprise handler.

import java.util.ArrayList;
import java.util.List;
import net.nuagenetworks.bambou.RestException;
import net.nuagenetworks.vspk.v5_0.DomainTemplate;
import net.nuagenetworks.vspk.v5_0.Enterprise;
import net.nuagenetworks.vspk.v5_0.fetchers.DomainTemplatesFetcher;

public class NetworkDomainTemplateHandler {
    public DomainTemplate verifyTemplate(Enterprise enterprise,
                                         NetworkDescriptor descriptor) {
        String templateName = descriptor.domainTemplateName;
        DomainTemplate template = this.fetchTemplate(enterprise, templateName); // 1


        if (template == null) {
            System.out.println("Template " + templateName + " not found.  Create one");
            template = this.createTemplate(enterprise, templateName); // 2

        } else {
            System.out.println("Template " + templateName + " already exists");
        }

        return template;
    }
    
    public DomainTemplate fetchTemplate(Enterprise enterprise, String templateName) {
        String filter = String.format("name == '%s'", templateName); // 3

        DomainTemplatesFetcher fetcher = enterprise.getDomainTemplates(); // 4

        DomainTemplate template = null;

        try {
            template = fetcher.getFirst(filter, null, null, null, null, null, true); // 5

        } catch (RestException e) {
            e.printStackTrace();
        }
        
        return template;
    }
    
    public DomainTemplate createTemplate(Enterprise enterprise, String templateName) {
        DomainTemplate template = null;

        try {
            template = new DomainTemplate(); // 6

            template.setName(templateName); // 7

            enterprise.createChild(template); // 8

        } catch (RestException e) {
            e.printStackTrace();
        }
        
        return template;
    }
    
    public List<DomainTemplate> fetchAllTemplatesForEnterprise(Enterprise enterprise) {
        DomainTemplatesFetcher fetcher = enterprise.getDomainTemplates(); // 9

        List<DomainTemplate> list = new ArrayList<>();

        try {
            if (fetcher.count() > 0) { // 10

                list = fetcher.get(); // 11

            }
        } catch (RestException e) {
            e.printStackTrace();
        }

        return list;
    }
    
    public void deleteTemplate(DomainTemplate template) { // 12

        if (template == null) {
            System.out.println("Template does not exist");
        } else {
            System.out.println("Template " + template.getName() + " will be deleted");
            try {
                template.delete(); // 13

            } catch (RestException e) {
                e.printStackTrace();
            }
        }
    }
}

In Line 1 of the verifyTemplate method, we perform a search of an existing Enterprise object for a VSD Domain Template object that matches the name for our domain template that is passed in via NetworkDescriptor. If the Domain Template already exists, then we return that Domain Template object. If the Domain Template does not exist, then in Line 2 we call the createTemplate method to create and return a new Domain Template object.

Line 3 of the fetchTemplate method sets up a search filter based on the name of our domain template. In Line 4, we create an instance of DomainTemplatesFetcher. Then Line 5 retrieves the Domain Template object matching the name in the search filter.

In Line 6 of the createTemplate method, we call the constructor of the VSPK DomainTemplate class to create a brand new Domain Template object and then in Line 7 we assign our template name. Finally, in Line 8, we attach our new Domain Template object to the already existing Enterprise object.

Lines 9 to 13 of methods fetchAllTemplatesForEnterprise and deleteTemplate will be covered later when we discuss how to remove our network layout from the VSD.

Adding the Domain Template to our Network

Here is the updated version of the NetworkBuilder class that integrates with NetworkDomainTemplateHandler. There are 2 minor changes as shown below. At Line 1, we instantiate the new handler and at Line 2, we call its verifyTemplate method with our existing Enterprise object and the NetworkDescriptor object which contains the name of our domain template.

import java.util.List;
import net.nuagenetworks.bambou.RestException;
import net.nuagenetworks.vspk.v5_0.DomainTemplate;
import net.nuagenetworks.vspk.v5_0.Enterprise;
import net.nuagenetworks.vspk.v5_0.VSDSession;

public class NetworkBuilder {
    private String url = "https://198.51.100.108:8443";
    private VSDSession session = new VSDSession("csproot", "csproot", "csp", url);
    private NetworkEnterpriseHandler enterpriseHandler =
                                     new NetworkEnterpriseHandler(session);
    private NetworkDomainTemplateHandler templateHandler =
                                     new NetworkDomainTemplateHandler(); // 1


    public static void main(String[] args) {
      NetworkBuilder instance = new NetworkBuilder();
      NetworkRepository networkRepository = new NetworkRepository();
      List<NetworkDescriptor> networkLayout = networkRepository.networkLayout;
      instance.verifyNetwork(networkLayout);
    }
    
    private void verifyNetwork(List<NetworkDescriptor> networkLayout) {
      this.startSession();
      for (NetworkDescriptor descriptor : networkLayout)  {
        System.out.println("Network requires Enterprise: " + descriptor.enterpriseName);
        System.out.println("Network requires Template: " + descriptor.domainTemplateName);
        System.out.println("Network requires Domain: " + descriptor.domainName);
        System.out.println("Network requires Zone: " + descriptor.zoneName);
        System.out.println("Network requires Subnet: " + descriptor.subnetName);
        this.verifyNetworkObjects(descriptor);
      }
    }

    private void verifyNetworkObjects(NetworkDescriptor descriptor) {
        Enterprise enterprise = enterpriseHandler.verifyEnterprise(descriptor);
        DomainTemplate template =
                            templateHandler.verifyTemplate(enterprise, descriptor); // 2

    }

    private void startSession() {
        System.out.println("Starting a new VSD session");
        try {
            session.start();
        } catch (RestException e) {
            e.printStackTrace();
        }
    }

}

Run the main method from NetworkBuilder in your Java environment. You should see the following results in your console :

Starting a new VSD session
Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet1
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate not found.  Create one

If the code completed successfully, you will see our new Enterprise object along with its Domain Template child object in VSA. From the left hand side of the main VSA screen, click the Enterprise object showing the name “MyLittleEnterprise” and then click the menu option ‘Networks’ at the top of the screen. Ensure that the “Layer 3 Domains” item is selected on the left hand side of the Networks screen. For now, the only Level 3 Domain related object is our newly created Domain Template.

VSA Enterprise and Template

Recall that NetworkDomainTemplateHandler checks whether a VSD Domain Template object exists before creating a new one. Confirm this by running NetworkBuilder again. You should see the following results in your console :

Starting a new VSD session
Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet1
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists

The NetworkDomainHandler Class

The NetworkDomainHandler class is the second of 2 handler classes to manage our VSD Domain objects. At this point in our network, we have created an Enterprise object and a Domain Template object. Our new Domain object will become the child of that Enterprise object and will be linked to our existing Domain Template object.

Here is an implementation of the NetworkDomainHandler class with similar methods to our other handlers.

import java.util.ArrayList;
import java.util.List;
import net.nuagenetworks.bambou.RestException;
import net.nuagenetworks.vspk.v5_0.Domain;
import net.nuagenetworks.vspk.v5_0.DomainTemplate;
import net.nuagenetworks.vspk.v5_0.Enterprise;
import net.nuagenetworks.vspk.v5_0.fetchers.DomainsFetcher;

public class NetworkDomainHandler {
    public Domain verifyDomain(Enterprise enterprise, DomainTemplate template,
                               NetworkDescriptor descriptor) { // 1

        String domainName = descriptor.domainName;
        
        Domain domain = this.fetchDomain(enterprise, domainName); // 2


        if (domain == null) {
            System.out.println("Domain " + domainName + " not found.  Create one");
            domain = this.createDomain(enterprise, template, domainName); // 3

        } else {
            System.out.println("Domain " + domainName + " already exists");
        }

        return domain;
    }
    
    public Domain fetchDomain(Enterprise enterprise, String domainName) {
        String filter = String.format("name == '%s'", domainName); // 4

        DomainsFetcher fetcher = enterprise.getDomains(); // 5

        Domain domain = null;

        try {
            domain = fetcher.getFirst(filter, null, null, null, null, null, true); // 6

        } catch (RestException e) {
            e.printStackTrace();
        }
        
        return domain;
    }
    
    public Domain createDomain(Enterprise enterprise, DomainTemplate template,
                               String domainName) {
        Domain domain = null;

        try {
            domain = new Domain(); // 7

            domain.setName(domainName); // 8

            domain.setTemplateID(template.getId()); // 9

            enterprise.createChild(domain); // 10

        } catch (RestException e) {
            e.printStackTrace();
        }
        
        return domain;
    }
    
    public List<Domain> fetchAllDomainsForEnterprise(Enterprise enterprise) {
        DomainsFetcher fetcher = enterprise.getDomains(); // 11

        List<Domain> list = new ArrayList<>();

        try {
            if (fetcher.count() > 0) { // 12

                list = fetcher.get(); // 13

            }
        } catch (RestException e) {
            e.printStackTrace();
        }

        return list;
    }
    
    public void deleteDomain(Domain domain) { // 14

        if (domain == null) {
            System.out.println("Domain does not exist");
        } else {
            System.out.println("Domain " + domain.getName() + " will be deleted");
            try {
                domain.delete(); // 15

            } catch (RestException e) {
                e.printStackTrace();
            }
        }
    }
}

In Line 1 of the verifyDomain method, we have 3 arguments to supply the Enterprise parent object, related Domain Template object and the Network Descriptor holding the Domain name.

Similar to other handlers, Line 2 determines whether there is an existing Domain object whose name matches the name that is passed in via NetworkDescriptor. If the Domain already exists, then we return that Domain object. If the Domain does not exist, then in Line 3 we call the createDomain method to create and return a new Domain object.

Line 4 of the fetchDomain method sets up a search filter based on the name of our domain. In Line 5, we create an instance of DomainsFetcher. Then Line 6 retrieves the Domain object matching the name in the search filter.

In Line 7 of the createDomain method, we call the constructor of the VSPK Domain class to create a brand new Domain object and then in Lines 8 and 9 we assign our domain name and ID of our existing domain template. Finally, in Line 10, we attach our new Domain object to the already existing Enterprise object.

Lines 11 to 15 of methods fetchAllDomainsForEnterprise and deleteDomain will be covered later when we discuss how to remove our network layout from the VSD.

Adding the Domain to our Network

Here is the updated version of the NetworkBuilder class that integrates with NetworkDomainHandler. There are 2 minor changes as shown below. At Line 1, we instantiate the new handler and at Line 2, we call its verifyDomain method and pass it our existing Enterprise object, Domain Template object and the NetworkDescriptor object which contains the name of our domain.

import java.util.List;
import net.nuagenetworks.bambou.RestException;
import net.nuagenetworks.vspk.v5_0.Domain;
import net.nuagenetworks.vspk.v5_0.DomainTemplate;
import net.nuagenetworks.vspk.v5_0.Enterprise;
import net.nuagenetworks.vspk.v5_0.VSDSession;

public class NetworkBuilder {
    private String url = "https://198.51.100.108:8443";
    private VSDSession session = new VSDSession("csproot", "csproot", "csp", url);
    private NetworkEnterpriseHandler enterpriseHandler =
                                     new NetworkEnterpriseHandler(session);
    private NetworkDomainTemplateHandler templateHandler =
                                     new NetworkDomainTemplateHandler();
    private NetworkDomainHandler domainHandler =
                                     new NetworkDomainHandler(); // 1


    public static void main(String[] args) {
      NetworkBuilder instance = new NetworkBuilder();
      NetworkRepository networkRepository = new NetworkRepository();
      List<NetworkDescriptor> networkLayout = networkRepository.networkLayout;
      instance.verifyNetwork(networkLayout);
    }
    
    private void verifyNetwork(List<NetworkDescriptor> networkLayout) {
      this.startSession();
      for (NetworkDescriptor descriptor : networkLayout)  {
        System.out.println("Network requires Enterprise: " + descriptor.enterpriseName);
        System.out.println("Network requires Template: " + descriptor.domainTemplateName);
        System.out.println("Network requires Domain: " + descriptor.domainName);
        System.out.println("Network requires Zone: " + descriptor.zoneName);
        System.out.println("Network requires Subnet: " + descriptor.subnetName);
        this.verifyNetworkObjects(descriptor);
      }
    }

    private void verifyNetworkObjects(NetworkDescriptor descriptor) {
        Enterprise enterprise = enterpriseHandler.verifyEnterprise(descriptor);
        DomainTemplate template = templateHandler.verifyTemplate(enterprise, descriptor);
        Domain domain = domainHandler.verifyDomain(enterprise, template, descriptor); // 2

    }

    private void startSession() {
        System.out.println("Starting a new VSD session");
        try {
            session.start();
        } catch (RestException e) {
            e.printStackTrace();
        }
    }

}

Run the main method from NetworkBuilder in your Java environment. You should see the following results in your console :

Starting a new VSD session
Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet1
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists
Domain MyLittleDomain not found.  Create one

If the code completed successfully, you will see our new Enterprise object along with its Domain Template and Domain child objects in VSA. From the left hand side of the main VSA screen, click the Enterprise object showing the name “MyLittleEnterprise” and then click the menu option ‘Networks’ at the top of the screen. Ensure that the “Layer 3 Domains” item is selected on the left hand side of the Networks screen.

VSA Enterprise and Domain

The NetworkDomainHandler checks whether a VSD Domain object exists before creating a new one. You can test this by running NetworkBuilder again. You should see the following results in your console :

Starting a new VSD session
Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet1
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists
Domain MyLittleDomain already exists

The NetworkZoneHandler Class

The NetworkZoneHandler class will manage our VSD Zone objects. We already have an existing Domain object that will serve as the parent for our Zone. It is very similar to our other handlers.

Here is an implementation of the NetworkZoneHandler class.

import java.util.ArrayList;
import java.util.List;
import net.nuagenetworks.bambou.RestException;
import net.nuagenetworks.vspk.v5_0.Domain;
import net.nuagenetworks.vspk.v5_0.Zone;
import net.nuagenetworks.vspk.v5_0.fetchers.ZonesFetcher;

public class NetworkZoneHandler {
    public Zone verifyZone(Domain domain, NetworkDescriptor descriptor) { // 1

        String zoneName = descriptor.zoneName;
        
        Zone zone = this.fetchZone(domain, zoneName); // 2


        if (zone == null) {
            System.out.println("Zone " + zoneName + " not found.  Create one");
            zone = this.createZone(domain, zoneName); // 3

        } else {
            System.out.println("Zone " + zoneName + " already exists");
        }

        return zone;
    }
    
    public Zone fetchZone(Domain domain, String zoneName) {
        String filter = String.format("name == '%s'", zoneName); // 4

        ZonesFetcher fetcher = domain.getZones(); // 5

        Zone zone = null;

        try {
            zone = fetcher.getFirst(filter, null, null, null, null, null, true); // 6

        } catch (RestException e) {
            e.printStackTrace();
        }
        
        return zone;
    }
    
    public Zone createZone(Domain domain, String zoneName) {
        Zone zone = null;

        try {
            zone = new Zone(); // 7

            zone.setName(zoneName); // 8

            domain.createChild(zone); // 9

        } catch (RestException e) {
            e.printStackTrace();
        }
        
        return zone;
    }
    
    public List<Zone> fetchAllZonesForDomain(Domain domain) {
        ZonesFetcher fetcher = domain.getZones(); // 10

        List<Zone> list = new ArrayList<>();

        try {
            if (fetcher.count() > 0) { // 11

                list = fetcher.get(); // 12

            }
        } catch (RestException e) {
            e.printStackTrace();
        }

        return list;
    }
    
    public void deleteZone(Zone zone) { // 13

        if (zone == null) {
            System.out.println("Zone does not exist");
        } else {
            System.out.println("Zone " + zone.getName() + " will be deleted");
            try {
                zone.delete(); // 14

            } catch (RestException e) {
                e.printStackTrace();
            }
        }
    }
}

In Line 1 of the verifyZone method, we supply arguments for the parent Domain object and the Zone name.

Line 2 checks whether an existing Zone object matches the name that is passed in via NetworkDescriptor. If the Zone already exists, then we return that Zone object. If the Zone does not exist, then in Line 3 we call the createZone method to create and return a new Zone object.

Line 4 of the fetchZone method sets up a search filter based on the name of our zone. In Line 5, we create an instance of ZonesFetcher. Then Line 6 retrieves the Zone object matching the name in the search filter.

In Line 7 of the createZone method, we call the constructor of the VSPK Zone class to create a brand new Zone object and then in Line 8 we assign our zone name. Finally, in Line 9, we attach our new Zone object to the already existing Domain object.

Lines 10 to 14 of methods fetchAllZonesForDomain and deleteZone will be covered later when we discuss how to remove our network layout from the VSD.

Adding the Zone to our Network

Here is the updated version of the NetworkBuilder class that integrates with NetworkZoneHandler. There are 2 minor changes as shown below. At Line 1, we instantiate the new handler and at Line 2, we call its verifyZone method and pass it our existing Domain object and the NetworkDescriptor object which contains the name of our zone.

import java.util.List;
import net.nuagenetworks.bambou.RestException;
import net.nuagenetworks.vspk.v5_0.Zone;
import net.nuagenetworks.vspk.v5_0.Domain;
import net.nuagenetworks.vspk.v5_0.DomainTemplate;
import net.nuagenetworks.vspk.v5_0.Enterprise;
import net.nuagenetworks.vspk.v5_0.VSDSession;

public class NetworkBuilder {
    private String url = "https://198.51.100.108:8443";
    private VSDSession session = new VSDSession("csproot", "csproot", "csp", url);
    private NetworkEnterpriseHandler enterpriseHandler =
                                     new NetworkEnterpriseHandler(session);
    private NetworkDomainTemplateHandler templateHandler =
                                     new NetworkDomainTemplateHandler();
    private NetworkDomainHandler domainHandler =
                                     new NetworkDomainHandler();
    private NetworkZoneHandler zoneHandler = new NetworkZoneHandler(); // 1


    public static void main(String[] args) {
      NetworkBuilder instance = new NetworkBuilder();
      NetworkRepository networkRepository = new NetworkRepository();
      List<NetworkDescriptor> networkLayout = networkRepository.networkLayout;
      instance.verifyNetwork(networkLayout);
    }
    
    private void verifyNetwork(List<NetworkDescriptor> networkLayout) {
      this.startSession();
      for (NetworkDescriptor descriptor : networkLayout)  {
        System.out.println("Network requires Enterprise: " + descriptor.enterpriseName);
        System.out.println("Network requires Template: " + descriptor.domainTemplateName);
        System.out.println("Network requires Domain: " + descriptor.domainName);
        System.out.println("Network requires Zone: " + descriptor.zoneName);
        System.out.println("Network requires Subnet: " + descriptor.subnetName);
        this.verifyNetworkObjects(descriptor);
      }
    }

    private void verifyNetworkObjects(NetworkDescriptor descriptor) {
        Enterprise enterprise = enterpriseHandler.verifyEnterprise(descriptor);
        DomainTemplate template = templateHandler.verifyTemplate(enterprise, descriptor);
        Domain domain = domainHandler.verifyDomain(enterprise, template, descriptor);
        Zone zone = zoneHandler.verifyZone(domain, descriptor); // 2

    }

    private void startSession() {
        System.out.println("Starting a new VSD session");
        try {
            session.start();
        } catch (RestException e) {
            e.printStackTrace();
        }
    }

}

Run the main method from NetworkBuilder in your Java environment. You should see the following results in your console :

Starting a new VSD session
Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet1
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists
Domain MyLittleDomain already exists
Zone MyLittleWebTierZone not found.  Create one

If the code completed successfully, then in VSA you will see our network taking shape, with the Enterprise, Domain Template, Domain and Zone child objects now displayed. From the left hand side of the main VSA screen, click the Enterprise object showing the name “MyLittleEnterprise” and then click the menu option ‘Networks’ at the top of the screen. Ensure that the “Layer 3 Domains” item is selected on the left hand side of the Networks screen.

VSA Enterprise and Zone

The NetworkZoneHandler checks whether a VSD Zone object exists before creating a new one. You can test this by running NetworkBuilder again. You should see the following results in your console :

Starting a new VSD session
Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet1
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists
Domain MyLittleDomain already exists
Zone MyLittleWebTierZone already exists

The NetworkSubnetHandler Class

The NetworkSUbnetHandler class is the last of the handler classes and will be used to manage our VSD Subnet objects. We already have an existing Zone object that will serve as the parent for our Subnet.

Here is an implementation of the NetworkSubnetHandler class.

import java.util.ArrayList;
import java.util.List;
import net.nuagenetworks.bambou.RestException;
import net.nuagenetworks.vspk.v5_0.Subnet;
import net.nuagenetworks.vspk.v5_0.Zone;
import net.nuagenetworks.vspk.v5_0.fetchers.SubnetsFetcher;

public class NetworkSubnetHandler {
    public Subnet verifySubnet(Zone zone, NetworkDescriptor descriptor) { // 1

        String subnetName = descriptor.subnetName;
        
        Subnet subnet = this.fetchSubnet(zone, subnetName); // 2


        if (subnet == null) {
            System.out.println("Subnet " + subnetName + " not found.  Create one");
            subnet = this.createSubnet(zone, descriptor); // 3

        } else {
            System.out.println("Subnet " + subnetName + " already exists");
        }

        return subnet;
    }
    
    public Subnet fetchSubnet(Zone zone, String subnetName) {
        String filter = String.format("name == '%s'", subnetName); // 4

        SubnetsFetcher fetcher = zone.getSubnets(); // 5

        Subnet subnet = null;

        try {
            subnet = fetcher.getFirst(filter, null, null, null, null, null, true); // 6

        } catch (RestException e) {
            e.printStackTrace();
        }
        
        return subnet;
    }
    
    public Subnet createSubnet(Zone zone, NetworkDescriptor descriptor) {
        Subnet subnet = null;

        try {
            subnet = new Subnet(); // 7

            subnet.setName(descriptor.subnetName); // 8

            subnet.setAddress(descriptor.subnetAddress); // 9

            subnet.setNetmask(descriptor.subnetNetmask); // 10

            zone.createChild(subnet); // 11

        } catch (RestException e) {
            e.printStackTrace();
        }
        
        return subnet;
    }
    
    public List<Subnet> fetchAllSubnetsForZone(Zone zone) {
        SubnetsFetcher fetcher = zone.getSubnets(); // 12

        List<Subnet> list = new ArrayList<>();

        try {
            if (fetcher.count() > 0) { // 13

                list = fetcher.get(); // 14

            }
        } catch (RestException e) {
            e.printStackTrace();
        }

        return list;
    }
    
    public void deleteSubnet(Subnet subnet) { // 15

        if (subnet == null) {
            System.out.println("Subnet does not exist");
        } else {
            System.out.println("Subnet " + subnet.getName() + " will be deleted");
            try {
                subnet.delete(); // 16

            } catch (RestException e) {
                e.printStackTrace();
            }
        }
    }
}

In Line 1 of the verifySubnet method, we supply arguments for the parent Zone object and the Subnet attributes.

Line 2 checks whether an existing Subnet object matches the name that is passed in via NetworkDescriptor. If the Subnet already exists, then we return that Subnet object. If the Subnet does not exist, then in Line 3 we call the createSubnet method to create and return a new SUbnet object.

Line 4 of the fetchSubnet method sets up a search filter based on the name of our subnet. In Line 5, we create an instance of SubnetsFetcher. Then Line 6 retrieves the Subnet object matching the name in the search filter.

In Line 7 of the createSubnet method, we call the constructor of the VSPK Subnet class to create a brand new Zone object and then in Lines 8 through 10 we assign a few attributes for our new subnet. Finally, in Line 11, we attach our new Subnet object to the already existing Zone object.

Lines 12 to 16 of methods fetchAllSubnetsForZone and deleteSubnet will be covered later when we discuss how to remove our network layout from the VSD.

Adding the Subnet to our Network

Here is the updated version of the NetworkBuilder class that integrates with NetworkSubnetHandler. There are 2 minor changes as shown below. At Line 1, we instantiate the new handler and at Line 2, we call its verifySubnet method and pass it our existing Zone object and the NetworkDescriptor object which contains the name and IP attributes of our subnet.

import java.util.List;
import net.nuagenetworks.bambou.RestException;
import net.nuagenetworks.vspk.v5_0.Subnet;
import net.nuagenetworks.vspk.v5_0.Zone;
import net.nuagenetworks.vspk.v5_0.Domain;
import net.nuagenetworks.vspk.v5_0.DomainTemplate;
import net.nuagenetworks.vspk.v5_0.Enterprise;
import net.nuagenetworks.vspk.v5_0.VSDSession;

public class NetworkBuilder {
    private String url = "https://198.51.100.108:8443";
    private VSDSession session = new VSDSession("csproot", "csproot", "csp", url);
    private NetworkEnterpriseHandler enterpriseHandler =
                                     new NetworkEnterpriseHandler(session);
    private NetworkDomainTemplateHandler templateHandler =
                                     new NetworkDomainTemplateHandler();
    private NetworkDomainHandler domainHandler =
                                     new NetworkDomainHandler();
    private NetworkZoneHandler zoneHandler = new NetworkZoneHandler();
    private NetworkSubnetHandler subnetHandler = new NetworkSubnetHandler(); // 1


    public static void main(String[] args) {
      NetworkBuilder instance = new NetworkBuilder();
      NetworkRepository networkRepository = new NetworkRepository();
      List<NetworkDescriptor> networkLayout = networkRepository.networkLayout;
      instance.verifyNetwork(networkLayout);
    }
    
    private void verifyNetwork(List<NetworkDescriptor> networkLayout) {
      this.startSession();
      for (NetworkDescriptor descriptor : networkLayout)  {
        System.out.println("Network requires Enterprise: " + descriptor.enterpriseName);
        System.out.println("Network requires Template: " + descriptor.domainTemplateName);
        System.out.println("Network requires Domain: " + descriptor.domainName);
        System.out.println("Network requires Zone: " + descriptor.zoneName);
        System.out.println("Network requires Subnet: " + descriptor.subnetName);
        this.verifyNetworkObjects(descriptor);
      }
    }

    private void verifyNetworkObjects(NetworkDescriptor descriptor) {
        Enterprise enterprise = enterpriseHandler.verifyEnterprise(descriptor);
        DomainTemplate template = templateHandler.verifyTemplate(enterprise, descriptor);
        Domain domain = domainHandler.verifyDomain(enterprise, template, descriptor);
        Zone zone = zoneHandler.verifyZone(domain, descriptor);
        Subnet subnet = subnetHandler.verifySubnet(zone, descriptor); // 2

    }

    private void startSession() {
        System.out.println("Starting a new VSD session");
        try {
            session.start();
        } catch (RestException e) {
            e.printStackTrace();
        }
    }

}

Run the main method from NetworkBuilder in your Java environment. You should see the following results in your console :

Starting a new VSD session
Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet1
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists
Domain MyLittleDomain already exists
Zone MyLittleWebTierZone already exists
Subnet MyLittleWebSubnet1 not found.  Create one

If the code completed successfully, then in VSA you will see our complete network layout, with the Enterprise, Domain Template, Domain, Zone and Subnet objects now displayed. From the left hand side of the main VSA screen, click the Enterprise object showing the name “MyLittleEnterprise” and then click the menu option ‘Networks’ at the top of the screen. Ensure that the “Layer 3 Domains” item is selected on the left hand side of the Networks screen. You may need to highlight the Zone icon to make the new Subnet appear.

VSA Enterprise and Subnet

The NetworkSubnetHandler checks whether a VSD Subnet object exists before creating a new one. You can test this by running NetworkBuilder again. You should see the following results in your console :

Starting a new VSD session
Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet1
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists
Domain MyLittleDomain already exists
Zone MyLittleWebTierZone already exists
Subnet MyLittleWebSubnet1 already exists

Removing VSD Objects

In order to remove VSD objects, there are dependency rules that must be followed, based on parent-child relationships within the object tree. For example, to remove a Zone object, there must not be any Subnet child objects attached. Likewise, to remove a Domain object, you must first remove its Zone objects. We also want to handle cases where we have more than one child object for a parent. For simplicity, we will assume for this exercise that our network falls under a single common enterprise.

Therefore, our basic algorithm will be to locate and remove the lowest level objects first, and then work backwards, removing each parent object until we reach the top-level Enterprise object.

Here is the pseudo-code to remove our network:

1. Delete all children of enterprise ...
   - fetch all domains for enterprise
   - for each domain ...
     - fetch all zones for domain
     - for each zone ...
         - fetch all subnets for zone
         - for each subnet ...
             - delete subnet
         - delete zone
     - delete domain
     - delete domain template
2. Delete enterprise

Removing a Subnet

Recall that we already have code in our NetworkSubnetHandler class that can fetch all sibling Subnet objects that belong to the same Zone, along with code to delete a specific Subnet instance. Here are the relevant code snippets from that class:

public class NetworkSubnetHandler {
    ...
    public List<Subnet> fetchAllSubnetsForZone(Zone zone) {
        SubnetsFetcher fetcher = zone.getSubnets(); // 12

        List<Subnet> list = new ArrayList<>();

        try {
            if (fetcher.count() > 0) { // 13

                list = fetcher.get(); // 14

            }
        } catch (RestException e) {
            e.printStackTrace();
        }

        return list;
    }
    
    public void deleteSubnet(Subnet subnet) { // 15

        if (subnet == null) {
            System.out.println("Subnet does not exist");
        } else {
            System.out.println("Subnet " + subnet.getName() + " will be deleted");
            try {
                subnet.delete(); // 16

            } catch (RestException e) {
                e.printStackTrace();
            }
        }
    }

In Line 12 of the fetchAllSubnetsForZone method, we gather all Subnet children for a given Zone into a Fetcher. Then in Lines 13 and 14, we check whether there are any subnets and when any are found, they are added to a Java list.

Line 15 presents the deleteSubnet method which performs the actual deletion of a Subnet object from VSD. If the Subnet object is not initialized, then the method simply prints a message. Otherwise, at Line 16, the Subnet will be deleted.

Removing a Zone

The NetworkZoneHandler class can fetch all sibling Zone objects that belong to the same Domain, and can delete a specific Zone instance. Here are the relevant code snippets from that class:

public class NetworkZoneHandler {
    ...
    public List<Zone> fetchAllZonesForDomain(Domain domain) {
        ZonesFetcher fetcher = domain.getZones(); // 10

        List<Zone> list = new ArrayList<>();

        try {
            if (fetcher.count() > 0) { // 11

                list = fetcher.get(); // 12

            }
        } catch (RestException e) {
            e.printStackTrace();
        }

        return list;
    }
    
    public void deleteZone(Zone zone) { // 13

        if (zone == null) {
            System.out.println("Zone does not exist");
        } else {
            System.out.println("Zone " + zone.getName() + " will be deleted");
            try {
                zone.delete(); // 14

            } catch (RestException e) {
                e.printStackTrace();
            }
        }
    }

In Line 10 of the fetchAllZonesForDomain method, we gather all Zone children for a given Domain into a Fetcher. Then in Lines 11 and 12, we check whether there are any zones and when any are found, they are added to a Java list.

Line 13 presents the deleteZone method which performs the actual deletion of a Zone object from VSD. If the Zone object is not initialized, then the method simply prints a message. Otherwise, at Line 14, the Zone will be deleted.

Removing a Domain

The NetworkDomainHandler class can fetch all sibling Domain objects that belong to the same Enterprise, and can delete a specific Domain instance. Here are the relevant code snippets from that class:

public class NetworkDomainHandler {
    ...
    public List<Domain> fetchAllDomainsForEnterprise(Enterprise enterprise) {
        DomainsFetcher fetcher = enterprise.getDomains(); // 11

        List<Domain> list = new ArrayList<>();

        try {
            if (fetcher.count() > 0) { // 12

                list = fetcher.get(); // 13

            }
        } catch (RestException e) {
            e.printStackTrace();
        }

        return list;
    }
    
    public void deleteDomain(Domain domain) { // 14

        if (domain == null) {
            System.out.println("Domain does not exist");
        } else {
            System.out.println("Domain " + domain.getName() + " will be deleted");
            try {
                domain.delete(); // 15

            } catch (RestException e) {
                e.printStackTrace();
            }
        }
    }

In Line 11 of the fetchAllDomainsForEnterprise method, we gather all Domain children for a given Enterprise into a Fetcher. Then in Lines 12 and 13, we check whether there are any domains and when any are found, they are added to a Java list.

Line 14 presents the deleteDomain method which performs the actual deletion of a Domain object from VSD. If the Domain object is not initialized, then the method simply prints a message. Otherwise, at Line 15, the Domain will be deleted.

Removing a Domain Template

The NetworkDomainTemplateHandler class can fetch all sibling Domain Template objects that belong to the same Enterprise, and can delete a specific Domain Template instance. Here are the relevant code snippets from that class:

public class NetworkDomainTemplateHandler {
    ...
    public List<DomainTemplate> fetchAllTemplatesForEnterprise(Enterprise enterprise) {
        DomainTemplatesFetcher fetcher = enterprise.getDomainTemplates(); // 9

        List<DomainTemplate> list = new ArrayList<>();

        try {
            if (fetcher.count() > 0) { // 10

                list = fetcher.get(); // 11

            }
        } catch (RestException e) {
            e.printStackTrace();
        }

        return list;
    }
    
    public void deleteTemplate(DomainTemplate template) { // 12

        if (template == null) {
            System.out.println("Template does not exist");
        } else {
            System.out.println("Template " + template.getName() + " will be deleted");
            try {
                template.delete(); // 13

            } catch (RestException e) {
                e.printStackTrace();
            }
        }
    }

In Line 9 of the fetchAllTemplatesForEnterprise method, we gather all Domain Template children for a given Enterprise into a Fetcher. Then in Lines 10 and 11, we check whether there are any templates and when any are found, they are added to a Java list.

Line 12 presents the deleteTemplate method which performs the actual deletion of a Domain Template object from VSD. If the Domain Template object is not initialized, then the method simply prints a message. Otherwise, at Line 13, the Domain Template is deleted.

Removing an Enterprise

The NetworkEnterpriseHandler class already contains code that can delete a specific Enterprise instance. Here is the relevant code snippet from that class:

public class NetworkEnterpriseHandler {
    ...
    public void deleteEnterprise(Enterprise enterprise) { // 12

        if (enterprise == null) {
            System.out.println("Enterprise does not exist");
        } else {
            System.out.println("Enterprise " + enterprise.getName() + " will be deleted");
            try {
                enterprise.delete(); // 13

            } catch (RestException e) {
                e.printStackTrace();
            }
        }
    }

Line 12 presents the deleteEnterprise method which performs the actual deletion of an Enterprise object from VSD. If the Enterprise object is not initialized, then the method simply prints a message. Otherwise, at Line 13, the Enterprise is deleted.

Removing our Little Network

Rather than adding more complexity to the NetworkBuilder class, we will construct a separate class called NetworkRemover that will handle the removal of all of our VSD objects.

import java.util.List;
import net.nuagenetworks.bambou.RestException;
import net.nuagenetworks.vspk.v5_0.Domain;
import net.nuagenetworks.vspk.v5_0.DomainTemplate;
import net.nuagenetworks.vspk.v5_0.Enterprise;
import net.nuagenetworks.vspk.v5_0.Subnet;
import net.nuagenetworks.vspk.v5_0.VSDSession;
import net.nuagenetworks.vspk.v5_0.Zone;

public class NetworkRemover {
    private String enterpriseName = "MyLittleEnterprise"; // 1

    private String url = "https://198.51.100.108:8443";
    private VSDSession session = new VSDSession("csproot", "csproot", "csp", url);
    private NetworkEnterpriseHandler enterpriseHandler =
                                     new NetworkEnterpriseHandler(session);
    private NetworkDomainTemplateHandler templateHandler =
                                     new NetworkDomainTemplateHandler();
    private NetworkDomainHandler domainHandler =
                                     new NetworkDomainHandler();
    private NetworkZoneHandler zoneHandler = new NetworkZoneHandler();
    private NetworkSubnetHandler subnetHandler = new NetworkSubnetHandler();

    public static void main(String[] args) {
      NetworkRemover instance = new NetworkRemover();
      instance.removeNetwork();
    }
    
    private void removeNetwork() {
        this.startSession();
        Enterprise enterprise = enterpriseHandler.fetchEnterprise(enterpriseName);
        this.removeAllChildrenOfEnterprise(enterprise); // 2

        enterpriseHandler.deleteEnterprise(enterprise); // 3

    }

    private void removeAllChildrenOfEnterprise(Enterprise enterprise) {
        List<Domain> list = domainHandler.fetchAllDomainsForEnterprise(enterprise); // 4

        for (Domain domain : list) { // 5

            this.deleteAllZonesForDomain(domain); // 6

            domainHandler.deleteDomain(domain); // 7

            this.deleteAllTemplatesForEnterprise(enterprise); // 8

       }
    }
    
    private void deleteAllZonesForDomain(Domain domain) {
        List<Zone> list = zoneHandler.fetchAllZonesForDomain(domain); // 9

        for (Zone zone : list) { // 10

            this.deleteAllSubnetsForZone(zone); // 11

            zoneHandler.deleteZone(zone); // 12

        }
    }
    
    private void deleteAllSubnetsForZone(Zone zone) {
        List<Subnet> list = subnetHandler.fetchAllSubnetsForZone(zone); // 13

        for (Subnet subnet : list) { // 14

            subnetHandler.deleteSubnet(subnet);
        }
    }
    
    private void deleteAllTemplatesForEnterprise(Enterprise enterprise) {
        List<DomainTemplate> list =
             templateHandler.fetchAllTemplatesForEnterprise(enterprise); // 15

        for (DomainTemplate template : list) { // 16

            templateHandler.deleteTemplate(template);
        }
    }
    
    private void startSession() {
        System.out.println("Starting a new VSD session");
        try {
            session.start();
        } catch (RestException e) {
            e.printStackTrace();
        }
    }

}

At Line 1 of the NetworkRemover class we have hard-coded the name of the enterprise to be deleted, “MyLittleEnterprise”.

We kick off the removal process at Line 2 of the removeNetwork method where we call a private method to remove all of the children for our enterprise. Then at Line 3 we delete the enterprise itself.

In Line 4 of the removeAllChildrenOfEnterprise method, we generate a list of all domains in the enterprise. We then iterate the list of domains at Line 5. For each domain in the list, we call a local method at Line 6 to delete all of its zones and subnets. Once all child objects of the domain have been removed, at Line 7 we call the deleteDomain method of our domain handler class. Then at Line 8 we call a local method to remove all domain templates.

In Line 9 of the deleteAllZonesForDomain method, we generate a list of all zones for a given domain. We then iterate the list of zones at Line 10. For each zone in the list, we call a local method at Line 11 to delete all of its subnets. Once all child subnet objects of the zone have been removed, we call the deleteZone method of our zone handler class at Line 12.

In Line 13 of the deleteAllSubnetsForZone method, we generate a list of all subnets for a given zone. We then iterate the list of subnets at Line 14. For each subnet in the list, we call the deleteSubnet method of the subnet handler class at Line 14.

In Line 15 of the deleteAllTemplatesForEnterprise method, we generate a list of all domain templates in the enterprise. We then iterate the list of templates at Line 16. For each template in the list, we call the deleteTemplate method of the domain template handler class.

Run the main method from NetworkRemover in your Java environment. You should see the following results in your console :

Starting a new VSD session
Subnet MyLittleWebSubnet1 will be deleted
Zone MyLittleWebTierZone will be deleted
Domain MyLittleDomain will be deleted
Template MyLittleDomainTemplate will be deleted
Enterprise MyLittleEnterprise will be deleted

If the code completed successfully, you will no longer see the Enterprise in VSA.

VSA home page without enterprise

Expanding our Little Network

So far we have had to deal with just a handful of VSD objects in our network. Let’s ensure that our code works properly by expanding the size of our network. Let’s add another zone to our domain and define 2 subnets for each zone.

Here is a revised version of the NetworkRepository class:

import java.util.ArrayList;
import java.util.List;

public class NetworkRepository {
    public List<NetworkDescriptor> networkLayout = new ArrayList<NetworkDescriptor>() {
        {
         add(new NetworkDescriptor("MyLittleEnterprise", "MyLittleDomainTemplate",
                                   "MyLittleDomain", "MyLittleWebTierZone",
                                   "MyLittleWebSubnet1",
                                   "10.117.18.0", "255.255.255.0"));

        add(new NetworkDescriptor("MyLittleEnterprise", "MyLittleDomainTemplate",
                                  "MyLittleDomain", "MyLittleWebTierZone",
                                  "MyLittleWebSubnet2",
                                  "10.117.19.0", "255.255.255.0"));

        add(new NetworkDescriptor("MyLittleEnterprise", "MyLittleDomainTemplate",
                                  "MyLittleDomain", "MyLittleDBTierZone",
                                  "MyLittleDBSubnet1",
                                  "10.117.21.0", "255.255.255.0"));

        add(new NetworkDescriptor("MyLittleEnterprise", "MyLittleDomainTemplate",
                                  "MyLittleDomain", "MyLittleDBTierZone",
                                  "MyLittleDBSubnet2",
                                  "10.117.22.0", "255.255.255.0"));
       }
    };
}

We now configure 2 different zones called MyLittleWebTierZone and MyLittleDBTierZone. Within the Web Tier Zone, we want two subnets called MyLittleWebSubnet1 and MyLittleWebSubnet2. Likewise, within the DB Tier Zone, we want two subnets called MyLittleDBSubnet1 and MyLittleDBSubnet2. Each subnet will be assigned its own IP address range.

Run the main method from NetworkBuilder class. You should see the following results in your console (events triggering VSD objects creation have been marked with arrows) :

Starting a new VSD session

Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet1
Enterprise MyLittleEnterprise not found.  Create one     <-----
Template MyLittleDomainTemplate not found.  Create one     <-----
Domain MyLittleDomain not found.  Create one     <-----
Zone MyLittleWebTierZone not found.  Create one     <-----
Subnet MyLittleWebSubnet1 not found.  Create one     <-----

Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet2
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists
Domain MyLittleDomain already exists
Zone MyLittleWebTierZone already exists
Subnet MyLittleWebSubnet2 not found.  Create one     <-----

Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleDBTierZone
Network requires Subnet: MyLittleDBSubnet1
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists
Domain MyLittleDomain already exists
Zone MyLittleDBTierZone not found.  Create one     <-----
Subnet MyLittleDBSubnet1 not found.  Create one     <-----

Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleDBTierZone
Network requires Subnet: MyLittleDBSubnet2
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists
Domain MyLittleDomain already exists
Zone MyLittleDBTierZone already exists
Subnet MyLittleDBSubnet2 not found.  Create one     <-----

If the code completed successfully, then in VSA you will see the larger network layout, with the Enterprise, Domain Template, Domain, 2 Zones and 4 Subnet objects now displayed.

VSA Enterprise and Double Zone

The NetworkBuilder class and its related handlers check whether VSD objects exist before creating new ones. This strategy should still apply for our larger network. You can test this by running NetworkBuilder again. You should see the following results in your console :

Starting a new VSD session

Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet1
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists
Domain MyLittleDomain already exists
Zone MyLittleWebTierZone already exists
Subnet MyLittleWebSubnet1 already exists

Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleWebTierZone
Network requires Subnet: MyLittleWebSubnet2
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists
Domain MyLittleDomain already exists
Zone MyLittleWebTierZone already exists
Subnet MyLittleWebSubnet2 already exists

Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleDBTierZone
Network requires Subnet: MyLittleDBSubnet1
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists
Domain MyLittleDomain already exists
Zone MyLittleDBTierZone already exists
Subnet MyLittleDBSubnet1 already exists

Network requires Enterprise: MyLittleEnterprise
Network requires Template: MyLittleDomainTemplate
Network requires Domain: MyLittleDomain
Network requires Zone: MyLittleDBTierZone
Network requires Subnet: MyLittleDBSubnet2
Enterprise MyLittleEnterprise already exists
Template MyLittleDomainTemplate already exists
Domain MyLittleDomain already exists
Zone MyLittleDBTierZone already exists
Subnet MyLittleDBSubnet2 already exists

Final Cleanup

When we constructed our NetworkRemover class, we included loops and logic to handle the case where a VSD object in our network has multiple child objects below it. Our revised network layout has 2 Subnets in a Zone and 2 Zones in a Domain.

Our code should still work properly. Run the main method of the NetworkRemover class. You should see the following results in your console :

Subnet MyLittleDBSubnet1 will be deleted
Subnet MyLittleDBSubnet2 will be deleted
Zone MyLittleDBTierZone will be deleted
Subnet MyLittleWebSubnet1 will be deleted
Subnet MyLittleWebSubnet2 will be deleted
Zone MyLittleWebTierZone will be deleted
Domain MyLittleDomain will be deleted
Template MyLittleDomainTemplate will be deleted
Enterprise MyLittleEnterprise will be deleted

If the code completed successfully, you will no longer see the Enterprise in VSA.

VSA home page without enterprise

Conclusion

In Parts 1 and 2 of this series, we introduced the VSPK-Java library and provided many Java code samples that you can use and expand upon in your own environment. There are many more VSD object types that you will encounter in your SDN design, including policies, templates and gateways. Nuage Networks offers several other software tools for network management based on Python, Go, Objective-J, and Ansible.

For additional Java examples, please check here.