use of com.vmware.xenon.common.Operation.CompletionHandler in project photon-model by vmware.
the class AzureComputeEnumerationAdapterService method disassociateNics.
/**
* Deletes stale network interface states that are deleted from the remote.
*/
private DeferredResult<List<Operation>> disassociateNics(EnumerationContext ctx, List<String> remoteNicIds, List<NetworkInterfaceState> allLocalNics) {
List<DeferredResult<Operation>> updateOps = new ArrayList<>();
allLocalNics.stream().filter(localNic -> !remoteNicIds.contains(localNic.id)).forEach(localNic -> {
Operation upOp = PhotonModelUtils.createRemoveEndpointLinksOperation(this, ctx.request.endpointLink, localNic);
if (upOp != null) {
CompletionHandler completionHandler = upOp.getCompletion();
upOp.setCompletion(null);
updateOps.add(sendWithDeferredResult(upOp).whenComplete(completionHandler::handle));
}
});
return DeferredResult.allOf(updateOps);
}
use of com.vmware.xenon.common.Operation.CompletionHandler in project photon-model by vmware.
the class AzureComputeEnumerationAdapterService method disassociateOrRetireHelper.
/**
* Helper method to paginate through resources to be deleted.
*/
private void disassociateOrRetireHelper(EnumerationContext ctx, ComputeEnumerationSubStages next) {
if (ctx.deletionNextPageLink == null) {
logFine(() -> String.format("Finished %s of compute states for Azure", ctx.request.preserveMissing ? "retiring" : "deletion"));
ctx.subStage = next;
handleSubStage(ctx);
return;
}
CompletionHandler completionHandler = (o, e) -> {
if (e != null) {
handleError(ctx, e);
return;
}
QueryTask queryTask = o.getBody(QueryTask.class);
ctx.deletionNextPageLink = queryTask.results.nextPageLink;
List<Operation> operations = new ArrayList<>();
for (Object s : queryTask.results.documents.values()) {
ComputeState computeState = Utils.fromJson(s, ComputeState.class);
String vmId = computeState.id;
// present in Azure but have older timestamp in local repository.
if (ctx.vmIds.contains(vmId) || ctx.regionIds.contains(vmId)) {
continue;
}
if (ctx.request.preserveMissing) {
logFine(() -> String.format("Retiring compute state %s", computeState.documentSelfLink));
ComputeState cs = new ComputeState();
cs.powerState = PowerState.OFF;
cs.lifecycleState = LifecycleState.RETIRED;
operations.add(Operation.createPatch(this, computeState.documentSelfLink).setBody(cs));
} else {
// Deleting the localResourceState is done by disassociating the endpointLink from the
// localResourceState. If the localResourceState isn't associated with any other
// endpointLink, we issue a delete then
Operation dOp = PhotonModelUtils.createRemoveEndpointLinksOperation(this, ctx.request.endpointLink, computeState);
if (dOp != null) {
dOp.sendWith(getHost());
logFine(() -> String.format("Deleting compute state %s", computeState.documentSelfLink));
}
if (computeState.diskLinks != null && !computeState.diskLinks.isEmpty()) {
computeState.diskLinks.forEach(dl -> {
sendRequest(Operation.createGet(this, dl).setCompletion((op, ex) -> {
if (ex != null) {
logWarning(() -> String.format("Error retrieving " + "diskState: %s", ex.getMessage()));
} else {
DiskState diskState = op.getBody(DiskState.class);
Operation diskOp = PhotonModelUtils.createRemoveEndpointLinksOperation(this, ctx.request.endpointLink, diskState);
if (diskOp != null) {
diskOp.sendWith(getHost());
logFine(() -> String.format("Deleting disk state %s of machine %s", dl, computeState.documentSelfLink));
}
}
}));
});
}
if (computeState.networkInterfaceLinks != null && !computeState.networkInterfaceLinks.isEmpty()) {
computeState.networkInterfaceLinks.forEach(nil -> {
sendRequest(Operation.createGet(this, nil).setCompletion((op, ex) -> {
if (ex != null) {
logWarning(() -> String.format("Error retrieving NetworkInterface state: %s", ex.getMessage()));
} else {
NetworkInterfaceState networkInterfaceState = op.getBody(NetworkInterfaceState.class);
Operation nicOp = PhotonModelUtils.createRemoveEndpointLinksOperation(this, ctx.request.endpointLink, networkInterfaceState);
if (nicOp != null) {
nicOp.sendWith(getHost());
logFine(() -> String.format("Deleting NetworkInterface state %s of machine %s", nil, computeState.documentSelfLink));
}
}
}));
});
}
}
}
if (operations.size() == 0) {
logFine(() -> String.format("No compute/disk states to %s", ctx.request.preserveMissing ? "retire" : "delete"));
disassociateOrRetireHelper(ctx, next);
return;
}
OperationJoin.create(operations).setCompletion((ops, exs) -> {
if (exs != null) {
// We don't want to fail the whole data collection if some of the
// operation fails.
exs.values().forEach(ex -> logWarning(() -> String.format("Error: %s", ex.getMessage())));
}
disassociateOrRetireHelper(ctx, next);
}).sendWith(this);
};
logFine(() -> String.format("Querying page [%s] for resources to be %s", ctx.deletionNextPageLink, ctx.request.preserveMissing ? "retire" : "delete"));
sendRequest(Operation.createGet(createInventoryUri(this.getHost(), ctx.deletionNextPageLink)).setCompletion(completionHandler));
}
use of com.vmware.xenon.common.Operation.CompletionHandler in project photon-model by vmware.
the class AzureNetworkEnumerationAdapterService method createUpdateNetworkStates.
/**
* Create new network states or update matching network states with the actual state in Azure.
*/
private void createUpdateNetworkStates(NetworkEnumContext context, NetworkEnumStages next) {
logFine(() -> "Create or update Network States with the actual state in Azure.");
if (context.virtualNetworks.size() == 0) {
logFine(() -> "No virtual networks found to create/update.");
handleSubStage(context, next);
return;
}
Stream<Operation> operations = context.virtualNetworks.values().stream().map(virtualNetwork -> {
NetworkState existingNetworkState = context.networkStates.get(virtualNetwork.id);
NetworkState networkState = buildNetworkState(context, virtualNetwork, existingNetworkState);
setTagLinksToResourceState(networkState, virtualNetwork.tags, true);
if (existingNetworkState == null) {
// set internal tags as tagLinks for networks to be newly created.
setTagLinksToResourceState(networkState, context.networkInternalTagsMap, false);
} else {
// for already existing networks, add internal tags only if missing
if (networkState.tagLinks == null || networkState.tagLinks.isEmpty()) {
setTagLinksToResourceState(networkState, context.networkInternalTagsMap, false);
} else {
context.networkInternalTagLinksSet.stream().filter(tagLink -> !networkState.tagLinks.contains(tagLink)).map(tagLink -> networkState.tagLinks.add(tagLink)).collect(Collectors.toSet());
}
}
CompletionHandler handler = (completedOp, failure) -> {
if (failure != null) {
// Process successful operations only.
logWarning(() -> String.format("Error: %s", failure.getMessage()));
return;
}
NetworkState result;
if (completedOp.getStatusCode() == Operation.STATUS_CODE_NOT_MODIFIED) {
// Use the original networkState as result
result = networkState;
} else {
result = completedOp.getBody(NetworkState.class);
}
context.networkStates.put(result.id, result);
};
return existingNetworkState != null ? // Update case.
Operation.createPatch(this, networkState.documentSelfLink).setBody(networkState).setCompletion(handler) : // Create case.
Operation.createPost(getHost(), NetworkService.FACTORY_LINK).setBody(networkState).setCompletion(handler);
});
OperationJoin.create(operations).setCompletion((ops, failures) -> {
// We don't want to fail the whole data collection if some of the so we don't care of
// any potential operation failures. They are already logged at individual operation
// level.
logFine(() -> "Finished updating network states.");
handleSubStage(context, next);
}).sendWith(this);
}
use of com.vmware.xenon.common.Operation.CompletionHandler in project photon-model by vmware.
the class AzureStorageEnumerationAdapterService method disassociateStorageDescription.
/*
* Disassociate local storage accounts and all resources inside them that no longer exist in
* Azure
*
* The logic works by recording a timestamp when enumeration starts. This timestamp is used to
* lookup resources which haven't been touched as part of current enumeration cycle. The other
* data point this method uses is the storage accounts discovered as part of get storage
* accounts call.
*
* A disassociate on a storage description is invoked only if it meets two criteria: -
* Timestamp older
* than current enumeration cycle. - Storage account is not present on Azure.
*/
private void disassociateStorageDescription(StorageEnumContext context, StorageEnumStages next) {
Query.Builder qBuilder = Query.Builder.create().addKindFieldClause(StorageDescription.class).addRangeClause(StorageDescription.FIELD_NAME_UPDATE_TIME_MICROS, QueryTask.NumericRange.createLessThanRange(context.enumerationStartTimeInMicros));
QueryByPages<StorageDescription> queryLocalStates = new QueryByPages<>(getHost(), qBuilder.build(), StorageDescription.class, context.parentCompute.tenantLinks, context.request.endpointLink, context.parentCompute.documentSelfLink).setMaxPageSize(QueryUtils.MAX_RESULT_LIMIT).setClusterType(ServiceTypeCluster.INVENTORY_SERVICE);
List<DeferredResult<Operation>> disassociateDRs = new ArrayList<>();
queryLocalStates.queryDocuments(sd -> {
if (context.storageAccountIds.contains(sd.id)) {
return;
}
// Deleting the localResourceState is done by disassociating the
// endpointLink from the localResourceState. If the localResourceState
// isn't associated with any other endpointLink, it should be eventually
// deleted by the groomer task
Operation disassociateOp = PhotonModelUtils.createRemoveEndpointLinksOperation(this, context.request.endpointLink, sd);
if (disassociateOp == null) {
return;
}
// NOTE: The original Op is set with completion that must be executed.
// Since sendWithDeferredResult is used we must manually call it, otherwise it's
// just ignored.
CompletionHandler disassociateOpCompletion = disassociateOp.getCompletion();
DeferredResult<Operation> disassociateDR = sendWithDeferredResult(disassociateOp).whenComplete(disassociateOpCompletion::handle).whenComplete((o, e) -> {
final String message = "Disassociate stale %s state";
if (e != null) {
logWarning(message + ": FAILED with %s", sd.documentSelfLink, Utils.toString(e));
} else {
log(Level.FINEST, message + ": SUCCESS", sd.documentSelfLink);
}
});
disassociateDRs.add(disassociateDR);
}).thenCompose(ignore -> DeferredResult.allOf(disassociateDRs)).whenComplete((r, e) -> {
logFine(() -> "Finished disassociation of storage descriptions for Azure");
context.subStage = next;
handleSubStage(context);
});
}
use of com.vmware.xenon.common.Operation.CompletionHandler in project photon-model by vmware.
the class AzureStorageEnumerationAdapterService method disassociateResourceGroupStates.
/*
* Disassociate local storage containers that no longer exist in Azure
*
* The logic works by recording a timestamp when enumeration starts. This timestamp is used to
* lookup resources which haven't been touched as part of current enumeration cycle. The other
* data point this method uses is the storage accounts discovered as part of get storage
* accounts call.
*
* A disassociate on a resource group state is invoked only if it meets two criteria: -
* Timestamp
* older than current enumeration cycle. - Storage container is not present on Azure.
*/
private void disassociateResourceGroupStates(StorageEnumContext context, StorageEnumStages next) {
Query.Builder qBuilder = newResourceGroupQueryBuilder(context).addRangeClause(ResourceGroupState.FIELD_NAME_UPDATE_TIME_MICROS, QueryTask.NumericRange.createLessThanRange(context.enumerationStartTimeInMicros));
QueryByPages<ResourceGroupState> queryLocalStates = new QueryByPages<>(getHost(), qBuilder.build(), ResourceGroupState.class, context.parentCompute.tenantLinks, null, /* endpointLink */
context.parentCompute.documentSelfLink).setMaxPageSize(QueryUtils.MAX_RESULT_LIMIT).setClusterType(ServiceTypeCluster.INVENTORY_SERVICE);
List<DeferredResult<Operation>> ops = new ArrayList<>();
queryLocalStates.queryDocuments(rg -> {
// repository it means nothing has changed about it.
if (context.containerIds.contains(canonizeId(rg.id))) {
return;
}
// Deleting the localResourceState is done by disassociating the
// endpointLink from the localResourceState. If the localResourceState
// isn't associated with any other endpointLink, it should be eventually
// deleted by the groomer task
Operation disassociateOp = PhotonModelUtils.createRemoveEndpointLinksOperation(this, context.request.endpointLink, rg);
if (disassociateOp == null) {
return;
}
// NOTE: The original Op is set with completion that must be executed.
// Since sendWithDeferredResult is used we must manually call it, otherwise it's
// just ignored.
CompletionHandler disassociateOpCompletion = disassociateOp.getCompletion();
DeferredResult<Operation> disassociateDR = sendWithDeferredResult(disassociateOp).whenComplete(disassociateOpCompletion::handle).whenComplete((o, e) -> {
final String message = "Disassociate stale %s state";
if (e != null) {
logWarning(message + ": FAILED with %s", rg.documentSelfLink, Utils.toString(e));
} else {
log(Level.FINEST, message + ": SUCCESS", rg.documentSelfLink);
}
});
ops.add(disassociateDR);
}).thenCompose(r -> DeferredResult.allOf(ops)).whenComplete((r, e) -> {
logFine(() -> "Finished disassociation of storage containers for Azure");
context.subStage = next;
handleSubStage(context);
});
}
Aggregations