@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 TaskEntity prepareNetworkDelete(String id) throws ExternalException {
    NetworkEntity network = convertToEntity(getById(id));
    if (SubnetState.PENDING_DELETE.equals(network.getState())) {
      throw new InvalidNetworkStateException(
          String.format(
              "Invalid operation to delete network %s in state PENDING_DELETE", network.getId()));
    }

    NetworkService.State networkState = new NetworkService.State();
    networkState.state = SubnetState.PENDING_DELETE;
    networkState.deleteRequestTime = System.currentTimeMillis();
    this.patchNetworkService(id, networkState);
    this.tombstone(network);

    return taskBackend.createCompletedTask(network, Operation.DELETE_NETWORK);
  }
  private NetworkEntity convertToEntity(NetworkService.State network) {
    NetworkEntity networkEntity = new NetworkEntity();
    networkEntity.setName(network.name);
    networkEntity.setDescription(network.description);
    networkEntity.setState(network.state);
    networkEntity.setPortGroups(getPortGroupsJSONString(network.portGroups));
    networkEntity.setIsDefault(network.isDefault);
    networkEntity.setId(ServiceUtils.getIDFromDocumentSelfLink(network.documentSelfLink));

    return networkEntity;
  }
  @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);
  }
  private Subnet toApiRepresentation(NetworkEntity entity) {
    Subnet subnet = new Subnet();
    subnet.setId(entity.getId());
    subnet.setName(entity.getName());
    subnet.setState(entity.getState());
    subnet.setDescription(entity.getDescription());
    subnet.setPortGroups(getPortGroupsFromJSONString(entity.getPortGroups()));
    subnet.setIsDefault(entity.getIsDefault());

    return subnet;
  }