content: //
  // Licensed to the Apache Software Foundation (ASF) under one
  // or more contributor license agreements.  See the NOTICE file
  // distributed with this work for additional information
  // regarding copyright ownership.  The ASF licenses this file
  // to you under the Apache License, Version 2.0 (the
  // "License"); you may not use this file except in compliance
  // with the License.  You may obtain a copy of the License at
  //
  //   http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing,
  // software distributed under the License is distributed on an
  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  // KIND, either express or implied.  See the License for the
  // specific language governing permissions and limitations
  // under the License.
  //
  
  package com.cloud.network.nicira;
  
  import static org.junit.Assert.assertEquals;
  import static org.junit.Assert.assertTrue;
  import static org.junit.Assert.fail;
  
  import java.util.ArrayList;
  import java.util.List;
  import java.util.UUID;
  
  import org.junit.Before;
  import org.junit.Test;
  
  import com.cloud.utils.PropertiesUtil;
  import com.cloud.utils.rest.HttpClientHelper;
  
  public class NiciraNvpApiIT {
  
      protected NiciraNvpApi api;
  
      protected long timestamp = System.currentTimeMillis();
  
      @Before
      public void setup() throws Exception {
          PropertiesUtil.loadFromFile(PropertiesUtil.findConfigFile("config.properties"));
          final String host = System.getProperty("nvp.host");
          final String user = System.getProperty("nvp.admin.user");
          final String pass = System.getProperty("nvp.admin.pwd");
          api = NiciraNvpApi.create()
                  .host(host)
                  .username(user)
                  .password(pass)
                  .httpClient(HttpClientHelper.createHttpClient(5))
                  .build();
      }
  
      @Test
      public void testCRUDSecurityProfile() {
          SecurityProfile sProfile = new SecurityProfile();
          sProfile.setDisplayName("SecProfile" + timestamp);
  
          final List<SecurityRule> egressRules = new ArrayList<SecurityRule>();
          sProfile.setLogicalPortEgressRules(egressRules);
          egressRules.add(new SecurityRule(SecurityRule.ETHERTYPE_IPV4, "1.10.10.0", null, 80, 88, 6));
          egressRules.add(new SecurityRule(SecurityRule.ETHERTYPE_IPV6, "2a80:34ac::1", null, 90, 98, 6));
  
          final List<SecurityRule> ingressRules = new ArrayList<SecurityRule>();
          sProfile.setLogicalPortIngressRules(ingressRules);
          ingressRules.add(new SecurityRule(SecurityRule.ETHERTYPE_IPV4, "1.10.10.0", null, 50, 58, 6));
          ingressRules.add(new SecurityRule(SecurityRule.ETHERTYPE_IPV6, "280a:3ac4::1", null, 60, 68, 6));
  
          final List<NiciraNvpTag> tags = new ArrayList<NiciraNvpTag>();
          sProfile.setTags(tags);
          tags.add(new NiciraNvpTag("nvp", "MyTag1"));
          tags.add(new NiciraNvpTag("nicira", "MyTag2"));
          // In the creation we don't get to specify UUID, href or schema: they don't exist yet
  
          try {
              sProfile = api.createSecurityProfile(sProfile);
  
              // We can now update the new entity
              sProfile.setDisplayName("UpdatedSecProfile" + timestamp);
              api.updateSecurityProfile(sProfile, sProfile.getUuid());
  
              // Read them all
              List<SecurityProfile> profiles = api.findSecurityProfile();
              SecurityProfile scInList = null;
              for (final SecurityProfile iProfile : profiles) {
                  if (iProfile.getUuid().equalsIgnoreCase(sProfile.getUuid())) {
                      scInList = iProfile;
                  }
              }
              assertEquals("Read a Security Profile different from the one just created and updated", sProfile, scInList);
  
              // Read them filtered by uuid (get one)
              profiles = api.findSecurityProfile(sProfile.getUuid());
              assertEquals("Read a Security Profile different from the one just created and updated", sProfile, profiles.get(0));
              assertEquals("Read a Security Profile filtered by unique id (UUID) with more than one item", 1, profiles.size());
  
              // We can now delete the new entity
              api.deleteSecurityProfile(sProfile.getUuid());
          } catch (final NiciraNvpApiException e) {
              e.printStackTrace();
              assertTrue("Errors in Security Profile CRUD", false);
          }
      }
  
      @Test
      public void testCRUDAclReadAll() {
          try {
              Acl acl = setupAcl();
  
              acl = api.createAcl(acl);
              acl.setDisplayName("UpdatedAcl" + timestamp);
              api.updateAcl(acl, acl.getUuid());
  
              List<Acl> acls = api.findAcl();
              Acl scInList = null;
              for (final Acl iAcl : acls) {
                  if (iAcl.getUuid().equalsIgnoreCase(acl.getUuid())) {
                      scInList = iAcl;
                  }
              }
              assertEquals("Read a ACL different from the one just created and updated", acl, scInList);
  
              api.deleteAcl(acl.getUuid());
          } catch (final NiciraNvpApiException e) {
              e.printStackTrace();
              fail("Errors in ACL CRUD");
          }
      }
  
      @Test
      public void testCRUDAclReadOne() {
          try {
              Acl acl = setupAcl();
  
              acl = api.createAcl(acl);
              acl.setDisplayName("UpdatedAcl" + timestamp);
              api.updateAcl(acl, acl.getUuid());
  
              List<Acl> acls = api.findAcl(acl.getUuid());
              assertEquals("Read a ACL different from the one just created and updated", acl, acls.get(0));
              assertEquals("Read a ACL filtered by unique id (UUID) with more than one item", 1, acls.size());
  
              api.deleteAcl(acl.getUuid());
          } catch (final NiciraNvpApiException e) {
              e.printStackTrace();
              fail("Errors in ACL CRUD");
          }
      }
  
      @Test
      public void testCRUDLogicalSwitch() throws Exception {
          LogicalSwitch logicalSwitch = new LogicalSwitch();
          logicalSwitch.setDisplayName("LogicalSwitch" + timestamp);
          logicalSwitch.setPortIsolationEnabled(true);
          logicalSwitch.setReplicationMode("service");
          logicalSwitch.setTags(new ArrayList<NiciraNvpTag>());
          logicalSwitch.getTags().add(new NiciraNvpTag("anto", "hugo"));
  
          // In the creation we don't get to specify UUID, href or schema: they don't exist yet
  
          logicalSwitch = api.createLogicalSwitch(logicalSwitch);
  
          // We can now update the new entity
          logicalSwitch.setDisplayName("UpdatedLogicalSwitch" + timestamp);
          api.updateLogicalSwitch(logicalSwitch, logicalSwitch.getUuid());
  
          // Read them all
          List<LogicalSwitch> logicalSwitches = api.findLogicalSwitch();
          for (final LogicalSwitch iLogicalSwitch : logicalSwitches) {
              if (iLogicalSwitch.getUuid().equalsIgnoreCase(logicalSwitch.getUuid())) {
                  assertEquals("Read a LogicalSwitch different from the one just created and updated", logicalSwitch, iLogicalSwitch);
              }
          }
  
          // Read them filtered by uuid (get one)
          logicalSwitches = api.findLogicalSwitch(logicalSwitch.getUuid());
          assertEquals("Read a LogicalSwitch different from the one just created and updated", logicalSwitch, logicalSwitches.get(0));
          assertEquals("Read a LogicalSwitch filtered by unique id (UUID) with more than one item", 1, logicalSwitches.size());
  
          // Before deleting the test LogicalSwitch, test its ports
          final List<NiciraNvpTag> tags = new ArrayList<NiciraNvpTag>();
          tags.add(new NiciraNvpTag("cs_account", "OwnerName"));
  
          LogicalSwitchPort logicalSwitchPort = new LogicalSwitchPort("LSwitchPort" + timestamp, tags, true);
          logicalSwitchPort = api.createLogicalSwitchPort(logicalSwitch.getUuid(), logicalSwitchPort);
  
          logicalSwitchPort.setDisplayName("UpdatedLSwitchPort" + timestamp);
          api.updateLogicalSwitchPort(logicalSwitch.getUuid(), logicalSwitchPort);
  
          final List<LogicalSwitchPort> logicalSwitchePorts = api.findLogicalSwitchPortsByUuid(logicalSwitch.getUuid(), logicalSwitchPort.getUuid());
          for (final LogicalSwitchPort iLSwitchPort : logicalSwitchePorts) {
              if (iLSwitchPort.getUuid().equalsIgnoreCase(logicalSwitchPort.getUuid())) {
                  assertEquals("Read a LogicalSwitchPort different from the one just created and updated", logicalSwitchPort, iLSwitchPort);
              }
          }
  
          // And finally test attachments
          final String attachmentUuid = UUID.randomUUID().toString();
          final VifAttachment vifAttachment = new VifAttachment(attachmentUuid);
          api.updateLogicalSwitchPortAttachment(logicalSwitch.getUuid(), logicalSwitchPort.getUuid(), vifAttachment);
  
          assertEquals("Read a LogicalSwitchPort by vifAttachment different than expected",
                  api.findLogicalSwitchPortUuidByVifAttachmentUuid(logicalSwitch.getUuid(), vifAttachment.getVifUuid()), logicalSwitchPort.getUuid());
  
          api.deleteLogicalSwitchPort(logicalSwitch.getUuid(), logicalSwitchPort.getUuid());
  
          // We can now delete the new entity
          api.deleteLogicalSwitch(logicalSwitch.getUuid());
      }
  
      @Test
      public void testCRUDLogicalRouter() {
          LogicalRouter logicalRouter = new LogicalRouter();
          logicalRouter.setDisplayName("LogicalRouter" + timestamp);
          logicalRouter.setDistributed(true);
          logicalRouter.setNatSynchronizationEnabled(true);
          logicalRouter.setReplicationMode(LogicalRouter.REPLICATION_MODE_SERVICE);
          final RoutingConfig routingConfig = new SingleDefaultRouteImplicitRoutingConfig(
                  new RouterNextHop("192.168.10.20"));
          logicalRouter.setRoutingConfig(routingConfig);
  
          // In the creation we don't get to specify UUID, href or schema: they don't exist yet
  
          try {
              logicalRouter = api.createLogicalRouter(logicalRouter);
  
              // We can now update the new entity
              logicalRouter.setDisplayName("UpdatedLogicalSwitch" + timestamp);
              api.updateLogicalRouter(logicalRouter, logicalRouter.getUuid());
  
              // Read them all
              List<LogicalRouter> logicalRouters = api.findLogicalRouter();
              LogicalRouter lsInList = null;
              for (final LogicalRouter iLogicalRouter : logicalRouters) {
                  if (iLogicalRouter.getUuid().equalsIgnoreCase(logicalRouter.getUuid())) {
                      lsInList = iLogicalRouter;
                  }
              }
              assertEquals("Read a LogicalRouter different from the one just created and updated", logicalRouter, lsInList);
  
              // Read them filtered by uuid (get one)
              logicalRouters = api.findLogicalRouter(logicalRouter.getUuid());
              assertEquals("Read a LogicalRouter different from the one just created and updated", logicalRouter, logicalRouters.get(0));
              assertEquals("Read a LogicalRouter filtered by unique id (UUID) with more than one item", 1, logicalRouters.size());
  
              assertEquals(logicalRouters.get(0), api.findOneLogicalRouterByUuid(logicalRouter.getUuid()));
  
              // Before deleting the test LogicalRouter, test its ports
              final List<NiciraNvpTag> tags = new ArrayList<NiciraNvpTag>();
              tags.add(new NiciraNvpTag("cs_account", "OwnerName"));
  
              LogicalRouterPort logicalRouterPort = new LogicalRouterPort();
              logicalRouterPort.setDisplayName("LRouterPort" + timestamp);
              logicalRouterPort.setTags(tags);
              logicalRouterPort.setAdminStatusEnabled(true);
              logicalRouterPort.setPortno(1024);
              logicalRouterPort.setMacAddress("00:00:00:00:00:00");
  
              final List<String> ipAddresses = new ArrayList<String>();
              // Add some ips to this list
              logicalRouterPort.setIpAddresses(ipAddresses);
              logicalRouterPort = api.createLogicalRouterPort(logicalRouter.getUuid(), logicalRouterPort);
  
              logicalRouterPort.setDisplayName("UpdatedLRouterPort" + timestamp);
              api.updateLogicalRouterPort(logicalRouter.getUuid(), logicalRouterPort);
  
              final List<LogicalRouterPort> logicalRouterePorts = api.findLogicalRouterPortsByUuid(logicalRouter.getUuid(), logicalRouterPort.getUuid());
              for (final LogicalRouterPort iLRouterPort : logicalRouterePorts) {
                  if (iLRouterPort.getUuid().equalsIgnoreCase(logicalRouterPort.getUuid())) {
                      assertEquals("Read a LogicalRouterPort different from the one just created and updated", logicalRouterPort, iLRouterPort);
                  }
              }
  
              UUID.randomUUID().toString();
  
              // Test CRUD for Nat Rules
              SourceNatRule snr = new SourceNatRule();
              snr.setToSourceIpAddressMin("192.168.10.10");
              snr.setToSourceIpAddressMax("192.168.10.20");
              snr.setOrder(200);
              final Match match = new Match();
              match.setSourceIpAddresses("192.168.150.150");
              snr.setMatch(match);
              snr = (SourceNatRule) api.createLogicalRouterNatRule(logicalRouter.getUuid(), snr);
              snr.setToSourceIpAddressMax("192.168.10.30");
              api.updateLogicalRouterNatRule(logicalRouter.getUuid(), snr);
  
              api.findNatRulesByLogicalRouterUuid(logicalRouter.getUuid());
              api.deleteLogicalRouterNatRule(logicalRouter.getUuid(), snr.getUuid());
  
              api.deleteLogicalRouterPort(logicalRouter.getUuid(), logicalRouterPort.getUuid());
  
              // We can now delete the new entity
              api.deleteLogicalRouter(logicalRouter.getUuid());
          } catch (final NiciraNvpApiException e) {
              e.printStackTrace();
              assertTrue("Errors in LogicalRouter CRUD", false);
          }
      }
  
      @Test
      public void testGetControlClusterStatus() throws NiciraNvpApiException {
          final ControlClusterStatus controlClusterStatus = api.getControlClusterStatus();
          final String clusterStatus = controlClusterStatus.getClusterStatus();
          final boolean correctStatus = clusterStatus.equalsIgnoreCase("stable") ||
                  clusterStatus.equalsIgnoreCase("joining") || clusterStatus.equalsIgnoreCase("unstable");
          assertTrue("Not recognizable cluster status", correctStatus);
      }
  
      private Acl setupAcl() {
          Acl acl = new Acl();
          acl.setDisplayName("Acl" + timestamp);
  
          // Note that if the protocol is 6 (TCP) then you cannot put ICMP code and type
          // Note that if the protocol is 1 (ICMP) then you cannot put ports
          final List<AclRule> egressRules = new ArrayList<>();
          acl.setLogicalPortEgressRules(egressRules);
          egressRules.add(new AclRule(AclRule.ETHERTYPE_IPV4, 1, "allow", null, null, "1.10.10.0", "1.10.10.1", null, null, null, null, 0, 0, 5));
          egressRules.add(new AclRule(AclRule.ETHERTYPE_IPV4, 6, "allow", null, null, "1.10.10.6", "1.10.10.7", 80, 80, 80, 80, 1, null, null));
  
          final List<AclRule> ingressRules = new ArrayList<>();
          acl.setLogicalPortIngressRules(ingressRules);
          ingressRules.add(new AclRule(AclRule.ETHERTYPE_IPV4, 1, "allow", null, null, "1.10.10.0", "1.10.10.1", null, null, null, null, 0, 0, 5));
          ingressRules.add(new AclRule(AclRule.ETHERTYPE_IPV4, 6, "allow", null, null, "1.10.10.6", "1.10.10.7", 80, 80, 80, 80, 1, null, null));
  
          final List<NiciraNvpTag> tags = new ArrayList<>();
          acl.setTags(tags);
          tags.add(new NiciraNvpTag("nvp", "MyTag1"));
          tags.add(new NiciraNvpTag("nicira", "MyTag2"));
          // In the creation we don't get to specify UUID, href or schema: they don't exist yet
  
          return acl;
      }
  
  }
  