@Override
  public TaskEntity setDefault(String networkId) throws ExternalException {
    NetworkService.State currentDefaultNetwork = getDefaultNetwork();

    if (currentDefaultNetwork != null) {
      NetworkService.State currentDefaultNetworkPatch = new NetworkService.State();
      currentDefaultNetworkPatch.isDefault = false;

      try {
        xenonClient.patch(currentDefaultNetwork.documentSelfLink, currentDefaultNetworkPatch);
      } catch (DocumentNotFoundException ex) {
        throw new NetworkNotFoundException(
            "Failed to patch current default network " + currentDefaultNetwork.documentSelfLink);
      }
    }

    NetworkService.State newDefaultNetwork = getById(networkId);
    NetworkService.State newDefaultNetworkPatch = new NetworkService.State();
    newDefaultNetworkPatch.isDefault = true;
    try {
      newDefaultNetwork =
          xenonClient
              .patch(newDefaultNetwork.documentSelfLink, newDefaultNetworkPatch)
              .getBody(NetworkService.State.class);
    } catch (DocumentNotFoundException ex) {
      throw new NetworkNotFoundException(
          "Failed to patch new default network " + newDefaultNetwork.documentSelfLink);
    }

    return taskBackend.createCompletedTask(
        convertToEntity(newDefaultNetwork), Operation.SET_DEFAULT_NETWORK);
  }
 private void patchNetworkService(String id, NetworkService.State networkState)
     throws NetworkNotFoundException {
   try {
     xenonClient.patch(NetworkServiceFactory.SELF_LINK + "/" + id, networkState);
   } catch (DocumentNotFoundException e) {
     throw new NetworkNotFoundException(id);
   }
 }
 private NetworkService.State getById(String id) throws NetworkNotFoundException {
   try {
     com.vmware.xenon.common.Operation result =
         xenonClient.get(NetworkServiceFactory.SELF_LINK + "/" + id);
     return result.getBody(NetworkService.State.class);
   } catch (DocumentNotFoundException exception) {
     throw new NetworkNotFoundException(id);
   }
 }
  private NetworkService.State getDefaultNetwork() {
    ImmutableMap.Builder<String, String> termsBuilder = new ImmutableBiMap.Builder<>();
    termsBuilder.put("isDefault", Boolean.TRUE.toString());

    List<NetworkService.State> defaultNetworks =
        xenonClient.queryDocuments(NetworkService.State.class, termsBuilder.build());

    if (defaultNetworks != null && !defaultNetworks.isEmpty()) {
      return defaultNetworks.iterator().next();
    } else {
      return null;
    }
  }
  @Override
  public void tombstone(NetworkEntity network) throws ExternalException {
    List<Vm> vmsOnNetwork = vmBackend.filterByNetwork(network.getId());
    if (!vmsOnNetwork.isEmpty()) {
      logger.info("There are {} VMs still on network {}", vmsOnNetwork.size(), network.getId());
      return;
    }

    xenonClient.delete(
        NetworkServiceFactory.SELF_LINK + "/" + network.getId(), new NetworkService.State());
    tombstoneBackend.create(Subnet.KIND, network.getId());
    logger.info("network {} tombstoned", network.getId());
  }
  @Override
  public ResourceList<Subnet> getPage(String pageLink) throws ExternalException {
    ServiceDocumentQueryResult queryResult = null;
    try {
      queryResult = xenonClient.queryDocumentPage(pageLink);
    } catch (DocumentNotFoundException e) {
      throw new PageExpiredException(pageLink);
    }

    return PaginationUtils.xenonQueryResultToResourceList(
        NetworkService.State.class,
        queryResult,
        state -> toApiRepresentation(convertToEntity(state)));
  }
  private ServiceDocumentQueryResult filterServiceDocuments(
      Optional<String> name, Optional<String> portGroup, Optional<Integer> pageSize) {
    final ImmutableMap.Builder<String, String> termsBuilder = new ImmutableMap.Builder<>();
    if (name.isPresent()) {
      termsBuilder.put("name", name.get());
    }

    if (portGroup.isPresent()) {
      termsBuilder.put(
          NetworkService.State.FIELD_PORT_GROUPS_QUERY_KEY, portGroup.get().toString());
    }

    ImmutableMap<String, String> terms = termsBuilder.build();
    logger.info("Filtering networks using terms {}", terms);

    return xenonClient.queryDocuments(NetworkService.State.class, terms, pageSize, true);
  }
  @Override
  public TaskEntity createNetwork(SubnetCreateSpec network) throws ExternalException {
    checkPortGroupsExist(network.getPortGroups());
    checkPortGroupsNotAddedToAnySubnet(network.getPortGroups());

    NetworkService.State state = new NetworkService.State();
    state.name = network.getName();
    state.description = network.getDescription();
    state.portGroups = network.getPortGroups();
    state.state = SubnetState.READY;

    com.vmware.xenon.common.Operation result =
        xenonClient.post(NetworkServiceFactory.SELF_LINK, state);

    NetworkService.State createdState = result.getBody(NetworkService.State.class);

    String id = ServiceUtils.getIDFromDocumentSelfLink(createdState.documentSelfLink);

    NetworkEntity networkEntity = new NetworkEntity();
    networkEntity.setId(id);
    networkEntity.setDescription(createdState.description);
    networkEntity.setPortGroups(getPortGroupsJSONString(createdState.portGroups));
    return taskBackend.createCompletedTask(networkEntity, Operation.CREATE_NETWORK);
  }
  @BeforeMethod
  public void setUp() throws Exception, DocumentNotFoundException {
    attachedDiskIds = new ArrayList<>();
    attachedDiskEntities = new ArrayList<>();
    persistentDiskEntities = new ArrayList<>();
    baseDiskEntities = new ArrayList<>();

    FlavorEntity vmFlavorEntity = new FlavorEntity();
    vmFlavorEntity.setName("vm-100");
    vmFlavorEntity.setKind(Vm.KIND);
    FlavorEntity diskFlavorEntity = new FlavorEntity();
    diskFlavorEntity.setName("core-100");
    diskFlavorEntity.setKind(PersistentDisk.KIND);

    task = new TaskEntity();
    task.setId("task-1");

    vm = new VmEntity();
    vm.setName("vm-name-1");
    vm.setId(vmId);
    vm.setFlavorId(vmFlavorEntity.getId());
    vm.setState(VmState.STOPPED);

    disk1 = new PersistentDiskEntity();
    disk1.setName(diskName1);
    disk1.setId(diskId1);
    disk1.setFlavorId(diskFlavorEntity.getId());
    disk1.setCapacityGb(1);
    persistentDiskEntities.add(disk1);
    baseDiskEntities.add(disk1);

    disk2 = new PersistentDiskEntity();
    disk2.setName(diskName2);
    disk2.setId(diskId2);
    disk2.setFlavorId(diskFlavorEntity.getId());
    disk2.setCapacityGb(2);
    persistentDiskEntities.add(disk2);
    baseDiskEntities.add(disk2);

    // String id, String name, String kind, String flavor, String state
    attachedDisk1 =
        AttachedDisk.create(disk1.getId(), disk1.getName(), disk1.getKind(), "core-100", 1, false);
    attachedDisk2 =
        AttachedDisk.create(disk2.getId(), disk2.getName(), disk2.getKind(), "core-100", 2, false);
    attachedDiskIds.add(attachedDisk1.getId());
    attachedDiskIds.add(attachedDisk2.getId());

    attachedDiskEntity1 = new AttachedDiskEntity();
    attachedDiskEntity1.setId(attachedDiskId1);
    attachedDiskEntities.add(attachedDiskEntity1);

    attachedDiskEntity2 = new AttachedDiskEntity();
    attachedDiskEntity2.setId(attachedDiskId2);
    attachedDiskEntities.add(attachedDiskEntity2);

    Datastore datastore = new Datastore();
    datastore.setId("datastore-id");

    when(diskBackend.find(PersistentDisk.KIND, diskId1)).thenReturn(disk1);
    when(diskBackend.find(PersistentDisk.KIND, diskId2)).thenReturn(disk2);

    taskCommand =
        spy(
            new TaskCommand(
                xenonClient,
                photonControllerXenonRestClient,
                hostClient,
                housekeeperClient,
                deployerClient,
                deployerXenonClient,
                housekeeperXenonClient,
                entityLockBackend,
                task));
    when(taskCommand.getHostClient()).thenReturn(hostClient);
    when(taskCommand.getPhotonControllerXenonRestClient())
        .thenReturn(photonControllerXenonRestClient);
    when(vmBackend.findById(vmId)).thenReturn(vm);
    when(diskBackend.find(PersistentDisk.KIND, diskId1)).thenReturn(disk1);
    when(diskBackend.find(PersistentDisk.KIND, diskId2)).thenReturn(disk2);

    when(attachedDiskBackend.findAttachedDisk(disk1)).thenReturn(attachedDiskEntity1);
    when(attachedDiskBackend.findAttachedDisk(disk2)).thenReturn(attachedDiskEntity2);
    when(taskCommand.getHostClient()).thenReturn(hostClient);
    HostService.State hostServiceState = new HostService.State();
    hostServiceState.hostAddress = "host-ip";
    when(hostServiceOp.getBody(Matchers.any())).thenReturn(hostServiceState);
    when(xenonClient.get(Matchers.startsWith(HostServiceFactory.SELF_LINK)))
        .thenReturn(hostServiceOp);
  }