From 1ea1074ca347645f4cb511d9f6eb4e00e3408406 Mon Sep 17 00:00:00 2001 From: anuchan Date: Wed, 20 Jul 2016 22:46:29 -0700 Subject: [PATCH 01/13] Simplifying the task group logic --- .../implementation/AvailabilitySetImpl.java | 8 ++- .../implementation/VirtualMachineImpl.java | 12 ++-- .../implementation/LoadBalancerImpl.java | 31 ++++---- .../network/implementation/NetworkImpl.java | 18 +++-- .../implementation/NetworkInterfaceImpl.java | 9 ++- .../NetworkSecurityGroupImpl.java | 55 +++++++------- .../implementation/PublicIpAddressImpl.java | 8 ++- .../models/implementation/ResourceImpl.java | 2 +- .../model/implementation/CreatableImpl.java | 71 +++++------------- .../implementation/CreatableTaskGroup.java | 65 ++++++++--------- .../implementation/CreatableTaskItem.java | 27 ++++--- .../CreatableUpdatableImpl.java | 5 +- .../resources/fluentcore/utils/Utils.java | 2 +- .../implementation/DeploymentImpl.java | 7 +- .../implementation/StorageAccountImpl.java | 72 ++++++++++--------- .../java/com/microsoft/azure/DAGNode.java | 4 +- .../java/com/microsoft/azure/DAGraph.java | 26 ++++--- .../com/microsoft/azure/TaskGroupBase.java | 37 +--------- 18 files changed, 207 insertions(+), 252 deletions(-) diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/AvailabilitySetImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/AvailabilitySetImpl.java index eb90fcea6a981..a89fc7c2ac7f1 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/AvailabilitySetImpl.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/AvailabilitySetImpl.java @@ -8,6 +8,7 @@ import com.microsoft.azure.SubResource; import com.microsoft.azure.management.compute.AvailabilitySet; import com.microsoft.azure.management.compute.InstanceViewStatus; +import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.rest.ServiceCall; @@ -101,16 +102,19 @@ public ServiceCall applyAsync(ServiceCallback callback) { return this.createAsync(callback); } + // CreatableTaskGroup.ResourceCreator implementation + @Override - protected void createResource() throws Exception { + public Resource createResource() throws Exception { ServiceResponse response = this.client.createOrUpdate(this.resourceGroupName(), this.name(), this.inner()); AvailabilitySetInner availabilitySetInner = response.getBody(); this.setInner(availabilitySetInner); this.idOfVMsInSet = null; + return this; } @Override - protected ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { return this.client.createOrUpdateAsync(this.resourceGroupName(), this.name(), this.inner(), Utils.fromVoidCallback(this, new ServiceCallback() { @Override diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java index 40c67d882ca0a..53711354ad5bb 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java @@ -41,6 +41,7 @@ import com.microsoft.azure.management.network.PublicIpAddress; import com.microsoft.azure.management.network.implementation.NetworkManager; import com.microsoft.azure.management.resources.fluentcore.arm.ResourceUtils; +import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; import com.microsoft.azure.management.resources.fluentcore.model.Creatable; import com.microsoft.azure.management.resources.fluentcore.utils.PagedListConverter; @@ -854,13 +855,11 @@ public PowerState powerState() { return null; } - /************************************************** - * . - * CreatableImpl::createResource - **************************************************/ + + // CreatableTaskGroup.ResourceCreator implementation @Override - protected void createResource() throws Exception { + public Resource createResource() throws Exception { if (isInCreateMode()) { setOSDiskAndOSProfileDefaults(); setHardwareProfileDefaults(); @@ -875,10 +874,11 @@ protected void createResource() throws Exception { this.setInner(serviceResponse.getBody()); clearCachedRelatedResources(); initializeDataDisks(); + return this; } @Override - protected ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { if (isInCreateMode()) { setOSDiskAndOSProfileDefaults(); setHardwareProfileDefaults(); diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/LoadBalancerImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/LoadBalancerImpl.java index 07d750e11dbb7..23f27d72e42e9 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/LoadBalancerImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/LoadBalancerImpl.java @@ -18,6 +18,7 @@ import com.microsoft.azure.management.network.PublicIpAddress; import com.microsoft.azure.management.network.PublicIpAddress.DefinitionStages.WithGroup; import com.microsoft.azure.management.network.SupportsNetworkInterfaces; +import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; import com.microsoft.azure.management.resources.fluentcore.model.Creatable; import com.microsoft.azure.management.resources.fluentcore.utils.Utils; @@ -203,7 +204,20 @@ public LoadBalancerImpl withExistingVirtualMachines(SupportsNetworkInterfaces... // Getters @Override - protected void createResource() throws Exception { + public List publicIpAddressIds() { + List publicIpAddressIds = new ArrayList<>(); + if (this.inner().frontendIPConfigurations() != null) { + for (FrontendIPConfiguration frontEndIpConfig : this.inner().frontendIPConfigurations()) { + publicIpAddressIds.add(frontEndIpConfig.publicIPAddress().id()); + } + } + return Collections.unmodifiableList(publicIpAddressIds); + } + + // CreatableTaskGroup.ResourceCreator implementation + + @Override + public Resource createResource() throws Exception { ensureCreationPrerequisites(); ServiceResponse response = @@ -211,10 +225,11 @@ protected void createResource() throws Exception { this.setInner(response.getBody()); runPostCreationTasks(); + return this; } @Override - protected ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { ensureCreationPrerequisites(); return this.innerCollection.createOrUpdateAsync(this.resourceGroupName(), this.name(), this.inner(), Utils.fromVoidCallback(this, new ServiceCallback() { @@ -235,16 +250,4 @@ public void success(ServiceResponse result) { } })); } - - @Override - public List publicIpAddressIds() { - List publicIpAddressIds = new ArrayList<>(); - if (this.inner().frontendIPConfigurations() != null) { - for (FrontendIPConfiguration frontEndIpConfig : this.inner().frontendIPConfigurations()) { - publicIpAddressIds.add(frontEndIpConfig.publicIPAddress().id()); - } - } - return Collections.unmodifiableList(publicIpAddressIds); - } - } \ No newline at end of file diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkImpl.java index 84fa28307cd35..689c3e9489935 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkImpl.java @@ -7,6 +7,7 @@ import com.microsoft.azure.management.network.Network; import com.microsoft.azure.management.network.Subnet; +import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.rest.ServiceCall; @@ -175,17 +176,25 @@ private void ensureCreationPrerequisites() { } @Override - protected void createResource() throws Exception { + public SubnetImpl updateSubnet(String name) { + return (SubnetImpl) this.subnets.get(name); + } + + // CreatableTaskGroup.ResourceCreator implementation + + @Override + public Resource createResource() throws Exception { ensureCreationPrerequisites(); ServiceResponse response = this.innerCollection.createOrUpdate(this.resourceGroupName(), this.name(), this.inner()); this.setInner(response.getBody()); initializeSubnetsFromInner(); + return this; } @Override - protected ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { ensureCreationPrerequisites(); return this.innerCollection.createOrUpdateAsync(this.resourceGroupName(), this.name(), this.inner(), @@ -202,9 +211,4 @@ public void success(ServiceResponse result) { } })); } - - @Override - public SubnetImpl updateSubnet(String name) { - return (SubnetImpl) this.subnets.get(name); - } } \ No newline at end of file diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkInterfaceImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkInterfaceImpl.java index b1eb382692b71..f3aa05c2bd330 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkInterfaceImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkInterfaceImpl.java @@ -347,12 +347,10 @@ public NicIpConfigurationImpl primaryIpConfiguration() { } - /**************************************************. - * CreatableImpl::createResource - **************************************************/ + // CreatableTaskGroup.ResourceCreator implementation @Override - protected void createResource() throws Exception { + public Resource createResource() throws Exception { NetworkSecurityGroup networkSecurityGroup = null; if (creatableNetworkSecurityGroupKey != null) { networkSecurityGroup = (NetworkSecurityGroup) this.createdResource(creatableNetworkSecurityGroupKey); @@ -371,10 +369,11 @@ protected void createResource() throws Exception { this.setInner(response.getBody()); clearCachedRelatedResources(); initializeNicIpConfigurations(); + return this; } @Override - protected ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { NicIpConfigurationImpl.ensureConfigurations(this.nicIpConfigurations); return this.client.createOrUpdateAsync(this.resourceGroupName(), this.nicName, diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkSecurityGroupImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkSecurityGroupImpl.java index bd0c4370e2c50..684f39f9d53a8 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkSecurityGroupImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkSecurityGroupImpl.java @@ -7,6 +7,7 @@ import com.microsoft.azure.management.network.NetworkSecurityGroup; import com.microsoft.azure.management.network.NetworkSecurityRule; +import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.rest.ServiceCall; @@ -101,32 +102,6 @@ public ServiceCall applyAsync(ServiceCallback callback) { return createAsync(callback); } - @Override - protected void createResource() throws Exception { - ServiceResponse response = - this.innerCollection.createOrUpdate(this.resourceGroupName(), this.name(), this.inner()); - this.setInner(response.getBody()); - initializeRulesFromInner(); - } - - @Override - protected ServiceCall createResourceAsync(final ServiceCallback callback) { - return this.innerCollection.createOrUpdateAsync(this.resourceGroupName(), this.name(), this.inner(), - Utils.fromVoidCallback(this, new ServiceCallback() { - @Override - public void failure(Throwable t) { - callback.failure(t); - } - - @Override - public void success(ServiceResponse result) { - initializeRulesFromInner(); - callback.success(result); - } - })); - } - - // Setters (fluent) @Override @@ -175,4 +150,32 @@ public List networkInterfaceIds() { } return Collections.unmodifiableList(ids); } + + // CreatableTaskGroup.ResourceCreator implementation + + @Override + public Resource createResource() throws Exception { + ServiceResponse response = + this.innerCollection.createOrUpdate(this.resourceGroupName(), this.name(), this.inner()); + this.setInner(response.getBody()); + initializeRulesFromInner(); + return this; + } + + @Override + public ServiceCall createResourceAsync(final ServiceCallback callback) { + return this.innerCollection.createOrUpdateAsync(this.resourceGroupName(), this.name(), this.inner(), + Utils.fromVoidCallback(this, new ServiceCallback() { + @Override + public void failure(Throwable t) { + callback.failure(t); + } + + @Override + public void success(ServiceResponse result) { + initializeRulesFromInner(); + callback.success(result); + } + })); + } } \ No newline at end of file diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/PublicIpAddressImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/PublicIpAddressImpl.java index 6f19250d85907..1b8d83d4b0322 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/PublicIpAddressImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/PublicIpAddressImpl.java @@ -8,6 +8,7 @@ import com.microsoft.azure.management.network.PublicIpAddress; import com.microsoft.azure.management.network.IPAllocationMethod; import com.microsoft.azure.management.network.PublicIPAddressDnsSettings; +import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.rest.ServiceCall; @@ -138,8 +139,10 @@ public String leafDomainLabel() { } } + // CreatableTaskGroup.ResourceCreator implementation + @Override - protected void createResource() throws Exception { + public Resource createResource() throws Exception { // Clean up empty DNS settings final PublicIPAddressDnsSettings dnsSettings = this.inner().dnsSettings(); if (dnsSettings != null) { @@ -153,10 +156,11 @@ protected void createResource() throws Exception { ServiceResponse response = this.client.createOrUpdate(this.resourceGroupName(), this.name(), this.inner()); this.setInner(response.getBody()); + return this; } @Override - protected ServiceCall createResourceAsync(ServiceCallback callback) { + public ServiceCall createResourceAsync(ServiceCallback callback) { // Clean up empty DNS settings final PublicIPAddressDnsSettings dnsSettings = this.inner().dnsSettings(); if (dnsSettings != null) { diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/arm/models/implementation/ResourceImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/arm/models/implementation/ResourceImpl.java index 3cfecebd100ef..516968a7215b8 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/arm/models/implementation/ResourceImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/arm/models/implementation/ResourceImpl.java @@ -29,7 +29,7 @@ public abstract class ResourceImpl< InnerModelT extends com.microsoft.azure.Resource, FluentModelImplT extends ResourceImpl> extends - CreatableUpdatableImpl + CreatableUpdatableImpl implements Resource { diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java index 19ca9ca7db0aa..0ef127ca21662 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java @@ -5,8 +5,6 @@ */ package com.microsoft.azure.management.resources.fluentcore.model.implementation; - -import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.model.Creatable; import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.rest.ServiceCall; @@ -18,18 +16,20 @@ * @param the fluent model type representing the creatable resource * @param the model inner type that the fluent model type wraps * @param the fluent model implementation type + * @param the fluent model or one of the base interface of fluent model */ -public abstract class CreatableImpl +public abstract class CreatableImpl extends IndexableRefreshableWrapperImpl - implements CreatableTaskGroup.RootResourceCreator { + implements CreatableTaskGroup.ResourceCreator +{ /** - * The group of tasks to create this resource and creatable it depends on. + * The group of tasks to create this resource and it's dependencies. */ - private CreatableTaskGroup creatableTaskGroup; + private CreatableTaskGroup creatableTaskGroup; protected CreatableImpl(String name, InnerModelT innerObject) { super(name, innerObject); - creatableTaskGroup = new CreatableTaskGroup(name, (Creatable) this, this); + creatableTaskGroup = new CreatableTaskGroup<>(name, this); } /** @@ -38,21 +38,11 @@ protected CreatableImpl(String name, InnerModelT innerObject) { * @param creatableResource the creatable dependency. */ protected void addCreatableDependency(Creatable creatableResource) { - CreatableTaskGroup childGroup = ((CreatableImpl) creatableResource).creatableTaskGroup; + CreatableTaskGroup childGroup = ((CreatableTaskGroup.ResourceCreator) creatableResource).creatableTaskGroup(); childGroup.merge(this.creatableTaskGroup); } - @Override - public void createRootResource() throws Exception { - this.createResource(); - } - - @Override - public ServiceCall createRootResourceAsync(ServiceCallback callback) { - return this.createResourceAsync(callback); - } - - protected Resource createdResource(String key) { + protected ResourceT createdResource(String key) { return this.creatableTaskGroup.taskResult(key); } @@ -64,33 +54,12 @@ protected Resource createdResource(String key) { */ @SuppressWarnings("unchecked") public FluentModelImplT create() throws Exception { - // This method get's called in two ways: - // 1. User explicitly call Creatable::create requesting creation of the resource. - // 2. Gets called as a part of creating dependent resources for the resource user requested to create in #1. - // - // The creatableTaskGroup of the 'Creatable' on which user called 'create' (#1) is known as the preparer. - // Preparer is the one responsible for preparing the underlying DAG for traversal. - // - // Initially creatableTaskGroup of all creatables as preparer, but as soon as user calls Create in one of - // them (say A::Create) all other creatables that A depends on will be marked as non-preparer. - // - // This achieve two goals: - // - // a. When #2 happens we know group is already prepared and all left is to create the currently requested resource. - // b. User can call 'Create' on any of the creatables not just the ROOT creatable. [ROOT is the one who does not - // have any dependent] - // - // After the creation of each resource in the creatableTaskGroup owned by the user chosen Creatable (#1), each - // sub-creatableTaskGroup of the created resource will be marked back as preparer. Hence user can again call - // Update on any of these resources [which is nothing but equivalent to calling create again] - // if (creatableTaskGroup.isPreparer()) { creatableTaskGroup.prepare(); creatableTaskGroup.execute(); - } else { - createResource(); + return (FluentModelImplT) this; } - return (FluentModelImplT) this; + throw new IllegalStateException("Internal Error: create can be called only on preparer"); } /** @@ -104,22 +73,14 @@ public ServiceCall createAsync(ServiceCallback callback) { if (creatableTaskGroup.isPreparer()) { creatableTaskGroup.prepare(); return creatableTaskGroup.executeAsync(Utils.toVoidCallback((FluentModelT) this, callback)); - } else { - return createResourceAsync(Utils.toVoidCallback((FluentModelT) this, callback)); } + throw new IllegalStateException("Internal Error: createAsync can be called only on preparer"); } /** - * Creates this resource. - * - * @throws Exception when anything goes wrong + * @return the task group associated with this creatable. */ - protected abstract void createResource() throws Exception; - - /** - * Creates this resource asynchronously. - * - * @throws Exception when anything goes wrong - */ - protected abstract ServiceCall createResourceAsync(ServiceCallback callback); + public CreatableTaskGroup creatableTaskGroup() { + return this.creatableTaskGroup; + } } diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskGroup.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskGroup.java index 980a03a113683..c0b1ccecdbebc 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskGroup.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskGroup.java @@ -1,41 +1,51 @@ package com.microsoft.azure.management.resources.fluentcore.model.implementation; import com.microsoft.azure.TaskGroupBase; -import com.microsoft.azure.TaskItem; -import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; -import com.microsoft.azure.management.resources.fluentcore.model.Creatable; import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; /** - * Type representing a group of creatable tasks and the dependency between them. + * Type representing a group of tasks that can create resources that are dependents on each other. + * + * @param the type of the resource this group creates */ -public class CreatableTaskGroup extends TaskGroupBase { - +public class CreatableTaskGroup extends TaskGroupBase { /** - * Represents a type that know how to create the root resource in a CreatableTaskGroup. + * Represents a type that know how to create resource. + * + * @param the type of the resource that this creator creates */ - interface RootResourceCreator { + interface ResourceCreator { /** - * Creates the root resource. + * Creates the resource asynchronously. + * + * @param serviceCallback the callback to be invoked after the creation of resource + * @return the service call reference */ - void createRootResource() throws Exception; + ServiceCall createResourceAsync(ServiceCallback serviceCallback); - ServiceCall createRootResourceAsync(ServiceCallback serviceCallback); - } + /** + * Creates the resource synchronously. + * + * @return the created resource + * @throws Exception + */ + ResourceT createResource() throws Exception; - private final RootResourceCreator rootCreate; + /** + * @return Gets the task group. + */ + CreatableTaskGroup creatableTaskGroup(); + } /** * Creates CreatableTaskGroup. * * @param rootCreatableId the id of the root creatable - * @param rootCreatable represents the root resource creatable that this group want to create ultimately - * @param rootCreate {@link RootResourceCreator} that know how to create the rootCreatable once all the - * dependencies are available + * @param resourceCreator represents the resource creator that this group want to create ultimately */ - public CreatableTaskGroup(String rootCreatableId, Creatable rootCreatable, RootResourceCreator rootCreate) { - this(rootCreatableId, new CreatableTaskItem(rootCreatable), rootCreate); + public CreatableTaskGroup(String rootCreatableId, ResourceCreator resourceCreator) { + this(rootCreatableId, new CreatableTaskItem(resourceCreator)); } /** @@ -43,16 +53,13 @@ public CreatableTaskGroup(String rootCreatableId, Creatable * * @param key the key of the root task * @param rootTask represents the root task that this group want to executes ultimately - * @param rootCreate {@link RootResourceCreator} that know how to create the rootCreatable once all the - * dependencies are available */ - public CreatableTaskGroup(String key, CreatableTaskItem rootTask, RootResourceCreator rootCreate) { + public CreatableTaskGroup(String key, CreatableTaskItem rootTask) { super(key, rootTask); - this.rootCreate = rootCreate; } /** - * Gets a resource created by a creatable task in this group. + * Gets a resource created by a creator task in this group. *

* This method can return null if the resource has not yet created that happens if the responsible task * is not yet selected for execution or it's it progress @@ -60,17 +67,7 @@ public CreatableTaskGroup(String key, CreatableTaskItem rootTask, RootResourceCr * @param key the resource id * @return the created resource */ - public Resource createdResource(String key) { + public ResourceT createdResource(String key) { return super.taskResult(key); } - - @Override - public void executeRootTask(TaskItem task) throws Exception { - this.rootCreate.createRootResource(); - } - - @Override - public ServiceCall executeRootTaskAsync(TaskItem task, ServiceCallback callback) { - return this.rootCreate.createRootResourceAsync(callback); - } } diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskItem.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskItem.java index 5b73c47e6b41a..9d538f6099d5f 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskItem.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskItem.java @@ -2,9 +2,7 @@ import com.microsoft.azure.DAGNode; import com.microsoft.azure.TaskGroup; -import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.TaskItem; -import com.microsoft.azure.management.resources.fluentcore.model.Creatable; import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; import com.microsoft.rest.ServiceResponse; @@ -12,31 +10,30 @@ /** * Represents a task that creates a resource when executed. */ -public class CreatableTaskItem implements TaskItem { - private Creatable creatable; - private DAGNode> node; - private Resource created; +public class CreatableTaskItem implements TaskItem { + private CreatableTaskGroup.ResourceCreator resourceCreator; + private ResourceT created; /** * Creates CreatableTaskItem. * - * @param creatable the creatable + * @param resourceCreator the resource creator */ - public CreatableTaskItem(Creatable creatable) { - this.creatable = creatable; + public CreatableTaskItem(CreatableTaskGroup.ResourceCreator resourceCreator) { + this.resourceCreator = resourceCreator; } @Override - public Resource result() { + public ResourceT result() { return created; } @Override - public void execute(TaskGroup> taskGroup, DAGNode> node) throws Exception { + public void execute(TaskGroup> taskGroup, DAGNode> node) throws Exception { if (this.created == null) { // execute will be called both in update and create scenarios, // so run the task only if it not not executed already. - this.created = this.creatable.create(); + this.created = this.resourceCreator.createResource(); } taskGroup.dag().reportedCompleted(node); @@ -44,16 +41,16 @@ public void execute(TaskGroup> taskGroup, DAGNode> taskGroup, final DAGNode> node, final ServiceCallback callback) { + public ServiceCall executeAsync(final TaskGroup> taskGroup, final DAGNode> node, final ServiceCallback callback) { final CreatableTaskItem self = this; - return ((Creatable) this.creatable).createAsync(new ServiceCallback() { + return (this.resourceCreator).createResourceAsync(new ServiceCallback() { @Override public void failure(Throwable t) { callback.failure(t); } @Override - public void success(ServiceResponse result) { + public void success(ServiceResponse result) { self.created = result.getBody(); taskGroup.dag().reportedCompleted(node); taskGroup.executeAsync(callback); diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableUpdatableImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableUpdatableImpl.java index 64e8c797c7f52..13a779c652bf3 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableUpdatableImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableUpdatableImpl.java @@ -14,9 +14,10 @@ * @param the fluent model type representing the resource * @param the model inner type that the fluent model type wraps * @param the implementation type of the fluent model + * @param the fluent model or one of the base interface of fluent model */ -public abstract class CreatableUpdatableImpl - extends CreatableImpl { +public abstract class CreatableUpdatableImpl + extends CreatableImpl { protected CreatableUpdatableImpl(String name, InnerModelT innerObject) { super(name, innerObject); diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java index 379c3a031e263..c4207aaf3c2d9 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java @@ -62,7 +62,7 @@ public void success(ServiceResponse result) { * @param the implementation for the fuent resource type * @return the inner callback */ - public static > ServiceCallback + public static > ServiceCallback fromVoidCallback(final FluentImplT modelImpl, final ServiceCallback callback) { return new ServiceCallback() { @Override diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/DeploymentImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/DeploymentImpl.java index b2759e9ac2f63..6ede192210d5c 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/DeploymentImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/DeploymentImpl.java @@ -36,7 +36,7 @@ * The implementation of {@link Deployment} and its nested interfaces. */ final class DeploymentImpl extends - CreatableUpdatableImpl + CreatableUpdatableImpl implements Deployment, Deployment.Definition, @@ -334,7 +334,7 @@ public Deployment refresh() throws Exception { } @Override - protected void createResource() throws Exception { + public Deployment createResource() throws Exception { DeploymentInner inner = new DeploymentInner() .withProperties(new DeploymentProperties()); inner.properties().withMode(mode()); @@ -343,10 +343,11 @@ protected void createResource() throws Exception { inner.properties().withParameters(parameters()); inner.properties().withParametersLink(parametersLink()); client.createOrUpdate(resourceGroupName(), name(), inner); + return this; } @Override - protected ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { DeploymentInner inner = new DeploymentInner() .withProperties(new DeploymentProperties()); inner.properties().withMode(mode()); diff --git a/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java b/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java index 4c940ee56da3b..26e974d5c33d5 100644 --- a/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java +++ b/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java @@ -7,6 +7,7 @@ package com.microsoft.azure.management.storage.implementation; import com.microsoft.azure.CloudException; +import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.azure.management.storage.PublicEndpoints; @@ -194,40 +195,6 @@ private void clearWrapperProperties() { publicEndpoints = null; } - @Override - protected void createResource() throws Exception { - createParameters.withLocation(this.regionName()); - createParameters.withTags(this.inner().getTags()); - this.client.create(this.resourceGroupName(), this.name(), createParameters); - // create response does not seems including the endpoints so fetching it again. - StorageAccountInner storageAccountInner = this.client - .getProperties(this.resourceGroupName(), this.name()) - .getBody(); - this.setInner(storageAccountInner); - clearWrapperProperties(); - } - - @Override - protected ServiceCall createResourceAsync(final ServiceCallback callback) { - createParameters.withLocation(this.regionName()); - createParameters.withTags(this.inner().getTags()); - final StorageAccountImpl self = this; - return this.client.createAsync(this.resourceGroupName(), this.name(), createParameters, - new ServiceCallback() { - @Override - public void failure(Throwable t) { - callback.failure(t); - } - - @Override - public void success(ServiceResponse result) { - client.getPropertiesAsync(resourceGroupName(), name(), - Utils.fromVoidCallback(self, callback)); - clearWrapperProperties(); - } - }); - } - @Override public StorageAccountImpl update() { updateParameters = new StorageAccountUpdateParametersInner(); @@ -294,4 +261,41 @@ public StorageAccountImpl withAccessTier(AccessTier accessTier) { } return this; } + + // CreatableTaskGroup.ResourceCreator implementation + + @Override + public Resource createResource() throws Exception { + createParameters.withLocation(this.regionName()); + createParameters.withTags(this.inner().getTags()); + this.client.create(this.resourceGroupName(), this.name(), createParameters); + // create response does not seems including the endpoints so fetching it again. + StorageAccountInner storageAccountInner = this.client + .getProperties(this.resourceGroupName(), this.name()) + .getBody(); + this.setInner(storageAccountInner); + clearWrapperProperties(); + return this; + } + + @Override + public ServiceCall createResourceAsync(final ServiceCallback callback) { + createParameters.withLocation(this.regionName()); + createParameters.withTags(this.inner().getTags()); + final StorageAccountImpl self = this; + return this.client.createAsync(this.resourceGroupName(), this.name(), createParameters, + new ServiceCallback() { + @Override + public void failure(Throwable t) { + callback.failure(t); + } + + @Override + public void success(ServiceResponse result) { + client.getPropertiesAsync(resourceGroupName(), name(), + Utils.fromVoidCallback(self, callback)); + clearWrapperProperties(); + } + }); + } } diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java index 112130413fd87..c340314f1f161 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.concurrent.locks.ReentrantLock; /** * The type representing node in a {@link DAGraph}. @@ -20,7 +21,7 @@ public class DAGNode extends Node { private List dependentKeys; private int toBeResolved; private boolean isPreparer; - + public ReentrantLock lock; /** * Creates a DAG node. * @@ -30,6 +31,7 @@ public class DAGNode extends Node { public DAGNode(String key, T data) { super(key, data); dependentKeys = new ArrayList<>(); + lock = new ReentrantLock(); } /** diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java index 58179e0152ed4..b9c9ec291db46 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java @@ -7,9 +7,8 @@ package com.microsoft.azure; -import java.util.ArrayDeque; import java.util.Map; -import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; /** * Type representing a DAG (directed acyclic graph). @@ -20,7 +19,7 @@ * @param the type of the nodes in the graph */ public class DAGraph> extends Graph { - private Queue queue; + private ConcurrentLinkedQueue queue; private boolean hasParent; private U rootNode; @@ -31,7 +30,7 @@ public class DAGraph> extends Graph { */ public DAGraph(U rootNode) { this.rootNode = rootNode; - this.queue = new ArrayDeque<>(); + this.queue = new ConcurrentLinkedQueue<>(); this.rootNode.setPreparer(true); this.addNode(rootNode); } @@ -103,10 +102,14 @@ public void prepare() { * Gets next node in the DAG which has no dependency or all of it's dependencies are resolved and * ready to be consumed. * - * @return next node or null if all the nodes have been explored + * @return next node or null if all the nodes have been explored or no node is available at this moment. */ public U getNext() { - return graph.get(queue.poll()); + String nextItemKey = queue.poll(); + if (nextItemKey == null) { + return null; + } + return graph.get(nextItemKey); } /** @@ -129,9 +132,14 @@ public void reportedCompleted(U completed) { String dependency = completed.key(); for (String dependentKey : graph.get(dependency).dependentKeys()) { DAGNode dependent = graph.get(dependentKey); - dependent.reportResolved(dependency); - if (dependent.hasAllResolved()) { - queue.add(dependent.key()); + dependent.lock.lock(); + try { + dependent.reportResolved(dependency); + if (dependent.hasAllResolved()) { + queue.add(dependent.key()); + } + } finally { + dependent.lock.lock(); } } } diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java index efc8d30e491bc..faedbb7d1cd08 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java @@ -58,11 +58,7 @@ public void execute() throws Exception { return; } - if (dag.isRootNode(nextNode)) { - executeRootTask(nextNode.data()); - } else { - nextNode.data().execute(this, nextNode); - } + nextNode.data().execute(this, nextNode); } @Override @@ -72,40 +68,11 @@ public ServiceCall executeAsync(final ServiceCallback callback) { return null; } - if (dag.isRootNode(nextNode)) { - return executeRootTaskAsync(nextNode.data(), callback); - } else { - return nextNode.data().executeAsync(this, nextNode, callback); - } + return nextNode.data().executeAsync(this, nextNode, callback); } @Override public T taskResult(String taskId) { return dag.getNodeData(taskId).result(); } - - /** - * Executes the root task in this group. - *

- * This method will be invoked when all the task dependencies of the root task are finished - * executing, at this point root task can be executed by consuming the result of tasks it - * depends on. - * - * @param task the root task in this group - * @throws Exception the exception - */ - public abstract void executeRootTask(TaskItem task) throws Exception; - - /** - * Executes the root task in this group asynchronously. - *

- * This method will be invoked when all the task dependencies of the root task are finished - * executing, at this point root task can be executed by consuming the result of tasks it - * depends on. - * - * @param task the root task in this group - * @param callback the callback when the task fails or succeeds - * @return the handle to the REST call - */ - public abstract ServiceCall executeRootTaskAsync(TaskItem task, ServiceCallback callback); } From c97038f212241a29a740626539c342a233a3915b Mon Sep 17 00:00:00 2001 From: anuchan Date: Thu, 21 Jul 2016 15:51:04 -0700 Subject: [PATCH 02/13] Restructuring and inital parallization work --- .../implementation/AvailabilitySetImpl.java | 15 ++-- .../implementation/VirtualMachineImpl.java | 11 +-- .../implementation/LoadBalancerImpl.java | 13 +-- .../network/implementation/NetworkImpl.java | 13 +-- .../implementation/NetworkInterfaceImpl.java | 14 +-- .../NetworkSecurityGroupImpl.java | 12 +-- .../implementation/PublicIpAddressImpl.java | 16 +++- .../model/implementation/CreatableImpl.java | 8 +- .../implementation/CreatableTaskGroup.java | 14 +-- .../implementation/CreatableTaskItem.java | 8 +- .../implementation/DeploymentImpl.java | 21 ++--- .../implementation/GenericResourceImpl.java | 29 +++++- .../implementation/ResourceGroupImpl.java | 21 ++++- .../implementation/StorageAccountImpl.java | 18 +++- .../com/microsoft/azure/TaskGroupBase.java | 88 +++++++++++++++++-- 15 files changed, 224 insertions(+), 77 deletions(-) diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/AvailabilitySetImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/AvailabilitySetImpl.java index a89fc7c2ac7f1..825a70d44f702 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/AvailabilitySetImpl.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/AvailabilitySetImpl.java @@ -107,26 +107,27 @@ public ServiceCall applyAsync(ServiceCallback callback) { @Override public Resource createResource() throws Exception { ServiceResponse response = this.client.createOrUpdate(this.resourceGroupName(), this.name(), this.inner()); - AvailabilitySetInner availabilitySetInner = response.getBody(); - this.setInner(availabilitySetInner); + this.setInner(response.getBody()); this.idOfVMsInSet = null; return this; } @Override - public ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { + final AvailabilitySetImpl self = this; return this.client.createOrUpdateAsync(this.resourceGroupName(), this.name(), this.inner(), - Utils.fromVoidCallback(this, new ServiceCallback() { + new ServiceCallback() { @Override public void failure(Throwable t) { callback.failure(t); } @Override - public void success(ServiceResponse result) { + public void success(ServiceResponse response) { + self.setInner(response.getBody()); idOfVMsInSet = null; - callback.success(result); + callback.success(new ServiceResponse(self, response.getResponse())); } - })); + }); } } diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java index d6b78c432c428..61ca9580f243d 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java @@ -877,7 +877,7 @@ public Resource createResource() throws Exception { } @Override - public ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { if (isInCreateMode()) { setOSDiskAndOSProfileDefaults(); setHardwareProfileDefaults(); @@ -896,19 +896,20 @@ public void success(ServiceResponse result) { handleNetworkSettings(); handleAvailabilitySettings(); call.newCall(client.createOrUpdateAsync(resourceGroupName(), vmName, inner(), - Utils.fromVoidCallback(self, new ServiceCallback() { + new ServiceCallback() { @Override public void failure(Throwable t) { callback.failure(t); } @Override - public void success(ServiceResponse result) { + public void success(ServiceResponse response) { + self.setInner(response.getBody()); clearCachedRelatedResources(); initializeDataDisks(); - callback.success(result); + callback.success(new ServiceResponse(self, response.getResponse())); } - })).getCall()); + }).getCall()); } }); return call; diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/LoadBalancerImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/LoadBalancerImpl.java index ce83e8cdaf064..7573f4ec86a66 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/LoadBalancerImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/LoadBalancerImpl.java @@ -221,24 +221,25 @@ public Resource createResource() throws Exception { ServiceResponse response = this.innerCollection.createOrUpdate(this.resourceGroupName(), this.name(), this.inner()); this.setInner(response.getBody()); - runPostCreationTasks(); return this; } @Override - public ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { + final LoadBalancerImpl self = this; ensureCreationPrerequisites(); return this.innerCollection.createOrUpdateAsync(this.resourceGroupName(), this.name(), this.inner(), - Utils.fromVoidCallback(this, new ServiceCallback() { + new ServiceCallback() { @Override public void failure(Throwable t) { callback.failure(t); } @Override - public void success(ServiceResponse result) { - callback.success(result); + public void success(ServiceResponse response) { + self.setInner(response.getBody()); + callback.success(new ServiceResponse(self, response.getResponse())); try { runPostCreationTasks(); } catch (Exception e) { @@ -246,6 +247,6 @@ public void success(ServiceResponse result) { e.printStackTrace(); } } - })); + }); } } \ No newline at end of file diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkImpl.java index 689c3e9489935..2e0dc39dbfd86 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkImpl.java @@ -194,21 +194,22 @@ public Resource createResource() throws Exception { } @Override - public ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { + final NetworkImpl self = this; ensureCreationPrerequisites(); - return this.innerCollection.createOrUpdateAsync(this.resourceGroupName(), this.name(), this.inner(), - Utils.fromVoidCallback(this, new ServiceCallback() { + new ServiceCallback() { @Override public void failure(Throwable t) { callback.failure(t); } @Override - public void success(ServiceResponse result) { + public void success(ServiceResponse response) { + self.setInner(response.getBody()); initializeSubnetsFromInner(); - callback.success(result); + callback.success(new ServiceResponse(self, response.getResponse())); } - })); + }); } } \ No newline at end of file diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkInterfaceImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkInterfaceImpl.java index 531f5878178f6..94c857cc5e6a4 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkInterfaceImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkInterfaceImpl.java @@ -372,24 +372,26 @@ public Resource createResource() throws Exception { } @Override - public ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { + final NetworkInterfaceImpl self = this; NicIpConfigurationImpl.ensureConfigurations(this.nicIpConfigurations); return this.client.createOrUpdateAsync(this.resourceGroupName(), this.nicName, this.inner(), - Utils.fromVoidCallback(this, new ServiceCallback() { + new ServiceCallback() { @Override public void failure(Throwable t) { callback.failure(t); } @Override - public void success(ServiceResponse result) { + public void success(ServiceResponse response) { + self.setInner(response.getBody()); clearCachedRelatedResources(); initializeNicIpConfigurations(); - callback.success(result); + callback.success(new ServiceResponse(self, response.getResponse())); } - })); + }); } /**************************************************. @@ -453,7 +455,7 @@ NetworkInterfaceImpl withIpConfiguration(NicIpConfigurationImpl nicIpConfigurati return this; } - void addToCreatableDependencies(Creatable creatableResource) { + void addToCreatableDependencies(Creatable creatableResource) { super.addCreatableDependency(creatableResource); } diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkSecurityGroupImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkSecurityGroupImpl.java index 0b50fab9c9936..9ff5370405c78 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkSecurityGroupImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkSecurityGroupImpl.java @@ -162,19 +162,21 @@ public Resource createResource() throws Exception { } @Override - public ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { + final NetworkSecurityGroupImpl self = this; return this.innerCollection.createOrUpdateAsync(this.resourceGroupName(), this.name(), this.inner(), - Utils.fromVoidCallback(this, new ServiceCallback() { + new ServiceCallback() { @Override public void failure(Throwable t) { callback.failure(t); } @Override - public void success(ServiceResponse result) { + public void success(ServiceResponse response) { + self.setInner(response.getBody()); initializeRulesFromInner(); - callback.success(result); + callback.success(new ServiceResponse(self, response.getResponse())); } - })); + }); } } \ No newline at end of file diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/PublicIpAddressImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/PublicIpAddressImpl.java index 1b8d83d4b0322..f352355d35923 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/PublicIpAddressImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/PublicIpAddressImpl.java @@ -160,7 +160,8 @@ public Resource createResource() throws Exception { } @Override - public ServiceCall createResourceAsync(ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { + final PublicIpAddressImpl self = this; // Clean up empty DNS settings final PublicIPAddressDnsSettings dnsSettings = this.inner().dnsSettings(); if (dnsSettings != null) { @@ -172,6 +173,17 @@ public ServiceCall createResourceAsync(ServiceCallback callback) { } return this.client.createOrUpdateAsync(this.resourceGroupName(), this.name(), this.inner(), - Utils.fromVoidCallback(this, callback)); + new ServiceCallback() { + @Override + public void failure(Throwable t) { + callback.failure(t); + } + + @Override + public void success(ServiceResponse response) { + self.setInner(response.getBody()); + callback.success(new ServiceResponse(self, response.getResponse())); + } + }); } } \ No newline at end of file diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java index 0ef127ca21662..90a7a54268c78 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java @@ -37,8 +37,9 @@ protected CreatableImpl(String name, InnerModelT innerObject) { * * @param creatableResource the creatable dependency. */ - protected void addCreatableDependency(Creatable creatableResource) { - CreatableTaskGroup childGroup = ((CreatableTaskGroup.ResourceCreator) creatableResource).creatableTaskGroup(); + protected void addCreatableDependency(Creatable creatableResource) { + CreatableTaskGroup childGroup = + ((CreatableTaskGroup.ResourceCreator) creatableResource).creatableTaskGroup(); childGroup.merge(this.creatableTaskGroup); } @@ -72,7 +73,8 @@ public FluentModelImplT create() throws Exception { public ServiceCall createAsync(ServiceCallback callback) { if (creatableTaskGroup.isPreparer()) { creatableTaskGroup.prepare(); - return creatableTaskGroup.executeAsync(Utils.toVoidCallback((FluentModelT) this, callback)); + creatableTaskGroup.executeAsync(Utils.toVoidCallback((FluentModelT) this, callback)); + return creatableTaskGroup.parallelServiceCall; } throw new IllegalStateException("Internal Error: createAsync can be called only on preparer"); } diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskGroup.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskGroup.java index c0b1ccecdbebc..a8425d779585e 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskGroup.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskGroup.java @@ -13,16 +13,16 @@ public class CreatableTaskGroup extends TaskGroupBase { /** * Represents a type that know how to create resource. * - * @param the type of the resource that this creator creates + * @param the type of the resource that this creator creates */ - interface ResourceCreator { + interface ResourceCreator { /** * Creates the resource asynchronously. * * @param serviceCallback the callback to be invoked after the creation of resource * @return the service call reference */ - ServiceCall createResourceAsync(ServiceCallback serviceCallback); + ServiceCall createResourceAsync(ServiceCallback serviceCallback); /** * Creates the resource synchronously. @@ -30,7 +30,7 @@ interface ResourceCreator { * @return the created resource * @throws Exception */ - ResourceT createResource() throws Exception; + T createResource() throws Exception; /** * @return Gets the task group. @@ -44,8 +44,8 @@ interface ResourceCreator { * @param rootCreatableId the id of the root creatable * @param resourceCreator represents the resource creator that this group want to create ultimately */ - public CreatableTaskGroup(String rootCreatableId, ResourceCreator resourceCreator) { - this(rootCreatableId, new CreatableTaskItem(resourceCreator)); + public CreatableTaskGroup(String rootCreatableId, ResourceCreator resourceCreator) { + this(rootCreatableId, new CreatableTaskItem<>(resourceCreator)); } /** @@ -54,7 +54,7 @@ public CreatableTaskGroup(String rootCreatableId, ResourceCreator resourceCreato * @param key the key of the root task * @param rootTask represents the root task that this group want to executes ultimately */ - public CreatableTaskGroup(String key, CreatableTaskItem rootTask) { + public CreatableTaskGroup(String key, CreatableTaskItem rootTask) { super(key, rootTask); } diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskItem.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskItem.java index 7c92271bdf7cb..63a8f5541cd65 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskItem.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskItem.java @@ -19,7 +19,7 @@ public class CreatableTaskItem implements TaskItem { * * @param resourceCreator the resource creator */ - public CreatableTaskItem(CreatableTaskGroup.ResourceCreator resourceCreator) { + public CreatableTaskItem(CreatableTaskGroup.ResourceCreator resourceCreator) { this.resourceCreator = resourceCreator; } @@ -42,15 +42,15 @@ public void execute(TaskGroup> taskGroup, DAGNode @Override public ServiceCall executeAsync(final TaskGroup> taskGroup, final DAGNode> node, final ServiceCallback callback) { - final CreatableTaskItem self = this; - return (this.resourceCreator).createResourceAsync(new ServiceCallback() { + final CreatableTaskItem self = this; + return (this.resourceCreator).createResourceAsync(new ServiceCallback() { @Override public void failure(Throwable t) { callback.failure(t); } @Override - public void success(ServiceResponse result) { + public void success(ServiceResponse result) { self.created = result.getBody(); taskGroup.dag().reportedCompleted(node); taskGroup.executeAsync(callback); diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/DeploymentImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/DeploymentImpl.java index 6ede192210d5c..75efbdf35aeee 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/DeploymentImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/DeploymentImpl.java @@ -182,7 +182,9 @@ public DeploymentExportResult exportTemplate() throws CloudException, IOExceptio @Override public DeploymentImpl withNewResourceGroup(String resourceGroupName, Region region) { - this.creatableResourceGroup = this.resourceManager.resourceGroups().define(resourceGroupName).withRegion(region); + this.creatableResourceGroup = this.resourceManager.resourceGroups() + .define(resourceGroupName) + .withRegion(region); this.resourceGroupName = resourceGroupName; return this; } @@ -190,9 +192,8 @@ public DeploymentImpl withNewResourceGroup(String resourceGroupName, Region regi @Override public DeploymentImpl withNewResourceGroup(Creatable resourceGroupDefinition) { this.resourceGroupName = resourceGroupDefinition.key(); - addCreatableDependency(resourceGroupDefinition); + this.creatableResourceGroup = resourceGroupDefinition; return this; - } @Override @@ -300,28 +301,28 @@ public void failure(Throwable t) { @Override public void success(ServiceResponse result) { - createResourceAsync(new ServiceCallback() { + createResourceAsync(new ServiceCallback() { @Override public void failure(Throwable t) { callback.failure(t); } @Override - public void success(ServiceResponse result) { + public void success(ServiceResponse result) { callback.success(new ServiceResponse<>(self, result.getResponse())); } }); } }); } else { - return createResourceAsync(new ServiceCallback() { + return createResourceAsync(new ServiceCallback() { @Override public void failure(Throwable t) { callback.failure(t); } @Override - public void success(ServiceResponse result) { + public void success(ServiceResponse result) { callback.success(new ServiceResponse<>(self, result.getResponse())); } }); @@ -347,7 +348,7 @@ public Deployment createResource() throws Exception { } @Override - public ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { DeploymentInner inner = new DeploymentInner() .withProperties(new DeploymentProperties()); inner.properties().withMode(mode()); @@ -362,8 +363,8 @@ public void failure(Throwable t) { } @Override - public void success(ServiceResponse result) { - callback.success(new ServiceResponse(result.getHeadResponse())); + public void success(ServiceResponse response) { + callback.success(new ServiceResponse(response.getHeadResponse())); } }); } diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/GenericResourceImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/GenericResourceImpl.java index eeac261be9a20..7c0596e3a6c3e 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/GenericResourceImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/GenericResourceImpl.java @@ -13,6 +13,7 @@ import com.microsoft.azure.management.resources.Plan; import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; +import com.microsoft.rest.ServiceResponse; /** * The implementation for {@link GenericResource} and its nested interfaces. @@ -133,7 +134,17 @@ public GenericResourceImpl create() throws Exception { @Override public ServiceCall createAsync(final ServiceCallback callback) { - return createResourceAsync(Utils.toVoidCallback(this, callback)); + return createResourceAsync(new ServiceCallback() { + @Override + public void failure(Throwable t) { + callback.failure(t); + } + + @Override + public void success(ServiceResponse result) { + callback.success(new ServiceResponse<>( (GenericResource)result.getBody(), result.getResponse())); + } + }); } @Override @@ -164,7 +175,8 @@ public Resource createResource() throws Exception { } @Override - public ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { + final GenericResourceImpl self = this; return client.createOrUpdateAsync( resourceGroupName(), resourceProviderNamespace, @@ -173,6 +185,17 @@ public ServiceCall createResourceAsync(final ServiceCallback callback) { key(), apiVersion, inner(), - Utils.fromVoidCallback(this, callback)); + new ServiceCallback() { + @Override + public void failure(Throwable t) { + callback.failure(t); + } + + @Override + public void success(ServiceResponse response) { + self.setInner(response.getBody()); + callback.success(new ServiceResponse(self, response.getResponse())); + } + }); } } diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/ResourceGroupImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/ResourceGroupImpl.java index a73d494be3947..7bfd5a597dea6 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/ResourceGroupImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/ResourceGroupImpl.java @@ -14,9 +14,9 @@ import com.microsoft.azure.management.resources.fluentcore.arm.Region; import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.model.implementation.CreatableUpdatableImpl; -import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; +import com.microsoft.rest.ServiceResponse; import java.io.IOException; import java.util.Arrays; @@ -147,15 +147,28 @@ public Resource createResource() throws Exception { ResourceGroupInner params = new ResourceGroupInner(); params.withLocation(this.inner().location()); params.withTags(this.inner().tags()); - client.createOrUpdate(this.name(), params); + ServiceResponse response = client.createOrUpdate(this.name(), params); + this.setInner(response.getBody()); return this; } @Override - public ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { + final ResourceGroupImpl self = this; ResourceGroupInner params = new ResourceGroupInner(); params.withLocation(this.inner().location()); params.withTags(this.inner().tags()); - return client.createOrUpdateAsync(this.name(), params, Utils.fromVoidCallback(this, callback)); + return client.createOrUpdateAsync(this.name(), params, new ServiceCallback() { + @Override + public void failure(Throwable t) { + callback.failure(t); + } + + @Override + public void success(ServiceResponse response) { + self.setInner(response.getBody()); + callback.success(new ServiceResponse(self, response.getResponse())); + } + }); } } diff --git a/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java b/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java index 26e974d5c33d5..dd382b081b8f0 100644 --- a/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java +++ b/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java @@ -279,10 +279,10 @@ public Resource createResource() throws Exception { } @Override - public ServiceCall createResourceAsync(final ServiceCallback callback) { + public ServiceCall createResourceAsync(final ServiceCallback callback) { + final StorageAccountImpl self = this; createParameters.withLocation(this.regionName()); createParameters.withTags(this.inner().getTags()); - final StorageAccountImpl self = this; return this.client.createAsync(this.resourceGroupName(), this.name(), createParameters, new ServiceCallback() { @Override @@ -293,8 +293,18 @@ public void failure(Throwable t) { @Override public void success(ServiceResponse result) { client.getPropertiesAsync(resourceGroupName(), name(), - Utils.fromVoidCallback(self, callback)); - clearWrapperProperties(); + new ServiceCallback() { + @Override + public void failure(Throwable t) { + callback.failure(t); + } + + @Override + public void success(ServiceResponse response) { + self.setInner(response.getBody()); + clearWrapperProperties(); + } + }); } }); } diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java index faedbb7d1cd08..a589c7149c747 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java @@ -9,6 +9,54 @@ import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; +import com.microsoft.rest.ServiceResponse; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ConcurrentLinkedQueue; + +/** + /** + * An instance of this class provides access to the underlying REST service call running + * in parallel. + * + * @param + */ +class ParallelServiceCall extends ServiceCall { + private TaskGroupBase taskGroup; + + /** + * Creates a ParallelServiceCall + * + * @param taskGroup the task group + */ + public ParallelServiceCall(TaskGroupBase taskGroup) { + super(null); + this.taskGroup = taskGroup; + } + + /** + * Cancels all the service calls currently executing. + */ + public void cancel() { + for (ServiceCall call : this.taskGroup.calls()) { + call.cancel(); + } + } + + /** + * @return true if the call has been canceled; false otherwise. + */ + public boolean isCancelled() { + for (ServiceCall call : this.taskGroup.calls()) { + if (!call.isCanceled()) { + return false; + } + } + return true; + } +} /** * The base implementation of TaskGroup interface. @@ -18,6 +66,9 @@ public abstract class TaskGroupBase implements TaskGroup> { private DAGraph, DAGNode>> dag; + private ConcurrentLinkedQueue serviceCalls = new ConcurrentLinkedQueue<>(); + + public ParallelServiceCall parallelServiceCall; /** * Creates TaskGroupBase. @@ -27,6 +78,11 @@ public abstract class TaskGroupBase */ public TaskGroupBase(String rootTaskItemId, TaskItem rootTaskItem) { this.dag = new DAGraph<>(new DAGNode<>(rootTaskItemId, rootTaskItem)); + this.parallelServiceCall = new ParallelServiceCall<>(this); + } + + List calls() { + return Collections.unmodifiableList(Arrays.asList(serviceCalls.toArray(new ServiceCall[0]))); } @Override @@ -63,12 +119,34 @@ public void execute() throws Exception { @Override public ServiceCall executeAsync(final ServiceCallback callback) { - final DAGNode> nextNode = dag.getNext(); - if (nextNode == null) { - return null; - } + ServiceCall serviceCall = null; + DAGNode> nextNode = dag.getNext(); + while (nextNode != null) { + if (dag.isRootNode(nextNode)) { + serviceCall = nextNode.data().executeAsync(this, nextNode, new ServiceCallback() { + @Override + public void failure(Throwable t) { + callback.failure(t); + } + + @Override + public void success(ServiceResponse result) { + callback.success(result); + } + }); + } else { + serviceCall = nextNode.data().executeAsync(this, nextNode, callback); + } - return nextNode.data().executeAsync(this, nextNode, callback); + if (serviceCall != null) { + // We need to filter out the null value returned by executeAsync. This can + // happen when TaskItem::executeAsync invokes TaskGroupBase::executeAsync + // but there is no task available in the queue at the moment. + this.serviceCalls.add(serviceCall); + } + nextNode = dag.getNext(); + } + return serviceCall; } @Override From a3f379f35f4f7c9aa221e5c0b47260594ec1e616 Mon Sep 17 00:00:00 2001 From: anuchan Date: Thu, 21 Jul 2016 16:01:43 -0700 Subject: [PATCH 03/13] marking addCretableDependency as unchecked --- .../resources/fluentcore/model/implementation/CreatableImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java index 90a7a54268c78..be11ec700d42f 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java @@ -37,6 +37,7 @@ protected CreatableImpl(String name, InnerModelT innerObject) { * * @param creatableResource the creatable dependency. */ + @SuppressWarnings("unchecked") protected void addCreatableDependency(Creatable creatableResource) { CreatableTaskGroup childGroup = ((CreatableTaskGroup.ResourceCreator) creatableResource).creatableTaskGroup(); From 354a209aaddf7b2ea30e717a28878349a215f5f8 Mon Sep 17 00:00:00 2001 From: anuchan Date: Thu, 21 Jul 2016 17:14:17 -0700 Subject: [PATCH 04/13] Fixing checkstyle errors --- .../src/main/java/com/microsoft/azure/DAGNode.java | 5 +++++ .../src/main/java/com/microsoft/azure/TaskGroupBase.java | 7 +++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java index c340314f1f161..ba6676232a9c5 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java @@ -21,7 +21,12 @@ public class DAGNode extends Node { private List dependentKeys; private int toBeResolved; private boolean isPreparer; + + /** + * The lock to be used while performing thread safe operation on this node. + */ public ReentrantLock lock; + /** * Creates a DAG node. * diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java index a589c7149c747..9b5fcf16cd2ee 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java @@ -27,11 +27,11 @@ class ParallelServiceCall extends ServiceCall { private TaskGroupBase taskGroup; /** - * Creates a ParallelServiceCall + * Creates a ParallelServiceCall. * * @param taskGroup the task group */ - public ParallelServiceCall(TaskGroupBase taskGroup) { + ParallelServiceCall(TaskGroupBase taskGroup) { super(null); this.taskGroup = taskGroup; } @@ -68,6 +68,9 @@ public abstract class TaskGroupBase private DAGraph, DAGNode>> dag; private ConcurrentLinkedQueue serviceCalls = new ConcurrentLinkedQueue<>(); + /** + * Wraps the services calls running in parallel. + */ public ParallelServiceCall parallelServiceCall; /** From 4801f0dd553d75bccee8597bce6d42aeecc706be Mon Sep 17 00:00:00 2001 From: anuchan Date: Thu, 21 Jul 2016 17:32:06 -0700 Subject: [PATCH 05/13] More check-style fixes --- .../model/implementation/CreatableImpl.java | 2 +- .../src/main/java/com/microsoft/azure/DAGNode.java | 13 ++++++++----- .../src/main/java/com/microsoft/azure/DAGraph.java | 4 ++-- .../java/com/microsoft/azure/TaskGroupBase.java | 14 +++++++++----- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java index be11ec700d42f..954040db6bffc 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java @@ -75,7 +75,7 @@ public ServiceCall createAsync(ServiceCallback callback) { if (creatableTaskGroup.isPreparer()) { creatableTaskGroup.prepare(); creatableTaskGroup.executeAsync(Utils.toVoidCallback((FluentModelT) this, callback)); - return creatableTaskGroup.parallelServiceCall; + return creatableTaskGroup.parallelServiceCall(); } throw new IllegalStateException("Internal Error: createAsync can be called only on preparer"); } diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java index ba6676232a9c5..2a340b31db5c4 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java @@ -21,11 +21,7 @@ public class DAGNode extends Node { private List dependentKeys; private int toBeResolved; private boolean isPreparer; - - /** - * The lock to be used while performing thread safe operation on this node. - */ - public ReentrantLock lock; + private ReentrantLock lock; /** * Creates a DAG node. @@ -39,6 +35,13 @@ public DAGNode(String key, T data) { lock = new ReentrantLock(); } + /** + * @return the lock to be used while performing thread safe operation on this node. + */ + public ReentrantLock Lock() { + return this.lock; + } + /** * @return a list of keys of nodes in {@link DAGraph} those are dependents on this node */ diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java index b9c9ec291db46..f0f7b66298c8f 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java @@ -132,14 +132,14 @@ public void reportedCompleted(U completed) { String dependency = completed.key(); for (String dependentKey : graph.get(dependency).dependentKeys()) { DAGNode dependent = graph.get(dependentKey); - dependent.lock.lock(); + dependent.Lock().lock(); try { dependent.reportResolved(dependency); if (dependent.hasAllResolved()) { queue.add(dependent.key()); } } finally { - dependent.lock.lock(); + dependent.Lock().lock(); } } } diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java index 9b5fcf16cd2ee..5ce63987defdb 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java @@ -67,11 +67,7 @@ public abstract class TaskGroupBase implements TaskGroup> { private DAGraph, DAGNode>> dag; private ConcurrentLinkedQueue serviceCalls = new ConcurrentLinkedQueue<>(); - - /** - * Wraps the services calls running in parallel. - */ - public ParallelServiceCall parallelServiceCall; + private ParallelServiceCall parallelServiceCall; /** * Creates TaskGroupBase. @@ -98,6 +94,14 @@ public boolean isPreparer() { return dag.isPreparer(); } + /** + * @return Gets the ParallelServiceCall instance that wraps the service calls running + * in parallel. + */ + public ParallelServiceCall parallelServiceCall() { + return this.parallelServiceCall; + } + @Override public void merge(TaskGroup> parentTaskGroup) { dag.merge(parentTaskGroup.dag()); From b0d6211853450f95c71a1c0c816c3190df139b16 Mon Sep 17 00:00:00 2001 From: anuchan Date: Thu, 21 Jul 2016 17:37:29 -0700 Subject: [PATCH 06/13] last checkstyle fix --- .../src/main/java/com/microsoft/azure/DAGNode.java | 2 +- .../src/main/java/com/microsoft/azure/DAGraph.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java index 2a340b31db5c4..4e1848fd8c159 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGNode.java @@ -38,7 +38,7 @@ public DAGNode(String key, T data) { /** * @return the lock to be used while performing thread safe operation on this node. */ - public ReentrantLock Lock() { + public ReentrantLock lock() { return this.lock; } diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java index f0f7b66298c8f..2a3e41d768cb2 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java @@ -132,14 +132,14 @@ public void reportedCompleted(U completed) { String dependency = completed.key(); for (String dependentKey : graph.get(dependency).dependentKeys()) { DAGNode dependent = graph.get(dependentKey); - dependent.Lock().lock(); + dependent.lock().lock(); try { dependent.reportResolved(dependency); if (dependent.hasAllResolved()) { queue.add(dependent.key()); } } finally { - dependent.Lock().lock(); + dependent.lock().lock(); } } } From 34793e4517c26707d7385f3ee3eae247a6150c99 Mon Sep 17 00:00:00 2001 From: anuchan Date: Thu, 21 Jul 2016 18:10:31 -0700 Subject: [PATCH 07/13] Some renames --- .../implementation/AvailabilitySetImpl.java | 3 +- .../implementation/VirtualMachineImpl.java | 3 +- .../implementation/LoadBalancerImpl.java | 3 +- .../network/implementation/NetworkImpl.java | 4 +-- .../implementation/NetworkInterfaceImpl.java | 2 +- .../NetworkSecurityGroupImpl.java | 3 +- .../implementation/PublicIpAddressImpl.java | 3 +- .../model/implementation/CreatableImpl.java | 34 +++++++++---------- ...leTaskGroup.java => CreatorTaskGroup.java} | 14 ++++---- ...ableTaskItem.java => CreatorTaskItem.java} | 12 ++++--- .../resources/fluentcore/utils/Utils.java | 5 +-- .../implementation/GenericResourceImpl.java | 5 ++- .../implementation/StorageAccountImpl.java | 3 +- 13 files changed, 44 insertions(+), 50 deletions(-) rename azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/{CreatableTaskGroup.java => CreatorTaskGroup.java} (81%) rename azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/{CreatableTaskItem.java => CreatorTaskItem.java} (81%) diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/AvailabilitySetImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/AvailabilitySetImpl.java index 825a70d44f702..a5e161e544a7d 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/AvailabilitySetImpl.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/AvailabilitySetImpl.java @@ -10,7 +10,6 @@ import com.microsoft.azure.management.compute.InstanceViewStatus; import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; -import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; import com.microsoft.rest.ServiceResponse; @@ -102,7 +101,7 @@ public ServiceCall applyAsync(ServiceCallback callback) { return this.createAsync(callback); } - // CreatableTaskGroup.ResourceCreator implementation + // CreatorTaskGroup.ResourceCreator implementation @Override public Resource createResource() throws Exception { diff --git a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java index 61ca9580f243d..32732ec83a410 100644 --- a/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java +++ b/azure-mgmt-compute/src/main/java/com/microsoft/azure/management/compute/implementation/VirtualMachineImpl.java @@ -45,7 +45,6 @@ import com.microsoft.azure.management.resources.fluentcore.model.Creatable; import com.microsoft.azure.management.resources.fluentcore.utils.PagedListConverter; import com.microsoft.azure.management.resources.fluentcore.utils.ResourceNamer; -import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.azure.management.resources.implementation.PageImpl; import com.microsoft.azure.management.storage.StorageAccount; import com.microsoft.azure.management.storage.implementation.StorageManager; @@ -855,7 +854,7 @@ public PowerState powerState() { } - // CreatableTaskGroup.ResourceCreator implementation + // CreatorTaskGroup.ResourceCreator implementation @Override public Resource createResource() throws Exception { diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/LoadBalancerImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/LoadBalancerImpl.java index 7573f4ec86a66..ce9774c2c3878 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/LoadBalancerImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/LoadBalancerImpl.java @@ -19,7 +19,6 @@ import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; import com.microsoft.azure.management.resources.fluentcore.model.Creatable; -import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; import com.microsoft.rest.ServiceResponse; @@ -212,7 +211,7 @@ public List publicIpAddressIds() { return Collections.unmodifiableList(publicIpAddressIds); } - // CreatableTaskGroup.ResourceCreator implementation + // CreatorTaskGroup.ResourceCreator implementation @Override public Resource createResource() throws Exception { diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkImpl.java index 2e0dc39dbfd86..7c3aa20dcf2a0 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkImpl.java @@ -9,11 +9,9 @@ import com.microsoft.azure.management.network.Subnet; import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; -import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; import com.microsoft.rest.ServiceResponse; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -180,7 +178,7 @@ public SubnetImpl updateSubnet(String name) { return (SubnetImpl) this.subnets.get(name); } - // CreatableTaskGroup.ResourceCreator implementation + // CreatorTaskGroup.ResourceCreator implementation @Override public Resource createResource() throws Exception { diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkInterfaceImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkInterfaceImpl.java index 94c857cc5e6a4..008229cc4284a 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkInterfaceImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkInterfaceImpl.java @@ -346,7 +346,7 @@ public NicIpConfigurationImpl primaryIpConfiguration() { } - // CreatableTaskGroup.ResourceCreator implementation + // CreatorTaskGroup.ResourceCreator implementation @Override public Resource createResource() throws Exception { diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkSecurityGroupImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkSecurityGroupImpl.java index 9ff5370405c78..2376a3acc2a63 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkSecurityGroupImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/NetworkSecurityGroupImpl.java @@ -9,7 +9,6 @@ import com.microsoft.azure.management.network.NetworkSecurityRule; import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; -import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; import com.microsoft.rest.ServiceResponse; @@ -150,7 +149,7 @@ public List networkInterfaceIds() { return Collections.unmodifiableList(ids); } - // CreatableTaskGroup.ResourceCreator implementation + // CreatorTaskGroup.ResourceCreator implementation @Override public Resource createResource() throws Exception { diff --git a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/PublicIpAddressImpl.java b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/PublicIpAddressImpl.java index f352355d35923..5e7b88d7ac9a7 100644 --- a/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/PublicIpAddressImpl.java +++ b/azure-mgmt-network/src/main/java/com/microsoft/azure/management/network/implementation/PublicIpAddressImpl.java @@ -10,7 +10,6 @@ import com.microsoft.azure.management.network.PublicIPAddressDnsSettings; import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; -import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; import com.microsoft.rest.ServiceResponse; @@ -139,7 +138,7 @@ public String leafDomainLabel() { } } - // CreatableTaskGroup.ResourceCreator implementation + // CreatorTaskGroup.ResourceCreator implementation @Override public Resource createResource() throws Exception { diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java index 954040db6bffc..382a502b019c8 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java @@ -20,16 +20,16 @@ */ public abstract class CreatableImpl extends IndexableRefreshableWrapperImpl - implements CreatableTaskGroup.ResourceCreator -{ + implements CreatorTaskGroup.ResourceCreator { + /** * The group of tasks to create this resource and it's dependencies. */ - private CreatableTaskGroup creatableTaskGroup; + private CreatorTaskGroup creatorTaskGroup; protected CreatableImpl(String name, InnerModelT innerObject) { super(name, innerObject); - creatableTaskGroup = new CreatableTaskGroup<>(name, this); + creatorTaskGroup = new CreatorTaskGroup<>(name, this); } /** @@ -39,13 +39,13 @@ protected CreatableImpl(String name, InnerModelT innerObject) { */ @SuppressWarnings("unchecked") protected void addCreatableDependency(Creatable creatableResource) { - CreatableTaskGroup childGroup = - ((CreatableTaskGroup.ResourceCreator) creatableResource).creatableTaskGroup(); - childGroup.merge(this.creatableTaskGroup); + CreatorTaskGroup childGroup = + ((CreatorTaskGroup.ResourceCreator) creatableResource).creatorTaskGroup(); + childGroup.merge(this.creatorTaskGroup); } protected ResourceT createdResource(String key) { - return this.creatableTaskGroup.taskResult(key); + return this.creatorTaskGroup.taskResult(key); } /** @@ -56,9 +56,9 @@ protected ResourceT createdResource(String key) { */ @SuppressWarnings("unchecked") public FluentModelImplT create() throws Exception { - if (creatableTaskGroup.isPreparer()) { - creatableTaskGroup.prepare(); - creatableTaskGroup.execute(); + if (creatorTaskGroup.isPreparer()) { + creatorTaskGroup.prepare(); + creatorTaskGroup.execute(); return (FluentModelImplT) this; } throw new IllegalStateException("Internal Error: create can be called only on preparer"); @@ -72,10 +72,10 @@ public FluentModelImplT create() throws Exception { */ @SuppressWarnings("unchecked") public ServiceCall createAsync(ServiceCallback callback) { - if (creatableTaskGroup.isPreparer()) { - creatableTaskGroup.prepare(); - creatableTaskGroup.executeAsync(Utils.toVoidCallback((FluentModelT) this, callback)); - return creatableTaskGroup.parallelServiceCall(); + if (creatorTaskGroup.isPreparer()) { + creatorTaskGroup.prepare(); + creatorTaskGroup.executeAsync(Utils.toVoidCallback((FluentModelT) this, callback)); + return creatorTaskGroup.parallelServiceCall(); } throw new IllegalStateException("Internal Error: createAsync can be called only on preparer"); } @@ -83,7 +83,7 @@ public ServiceCall createAsync(ServiceCallback callback) { /** * @return the task group associated with this creatable. */ - public CreatableTaskGroup creatableTaskGroup() { - return this.creatableTaskGroup; + public CreatorTaskGroup creatorTaskGroup() { + return this.creatorTaskGroup; } } diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskGroup.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskGroup.java similarity index 81% rename from azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskGroup.java rename to azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskGroup.java index a8425d779585e..a2fe11547ffdd 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskGroup.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskGroup.java @@ -9,7 +9,7 @@ * * @param the type of the resource this group creates */ -public class CreatableTaskGroup extends TaskGroupBase { +public class CreatorTaskGroup extends TaskGroupBase { /** * Represents a type that know how to create resource. * @@ -35,26 +35,26 @@ interface ResourceCreator { /** * @return Gets the task group. */ - CreatableTaskGroup creatableTaskGroup(); + CreatorTaskGroup creatorTaskGroup(); } /** - * Creates CreatableTaskGroup. + * Creates CreatorTaskGroup. * * @param rootCreatableId the id of the root creatable * @param resourceCreator represents the resource creator that this group want to create ultimately */ - public CreatableTaskGroup(String rootCreatableId, ResourceCreator resourceCreator) { - this(rootCreatableId, new CreatableTaskItem<>(resourceCreator)); + public CreatorTaskGroup(String rootCreatableId, ResourceCreator resourceCreator) { + this(rootCreatableId, new CreatorTaskItem<>(resourceCreator)); } /** - * Creates CreatableTaskGroup. + * Creates CreatorTaskGroup. * * @param key the key of the root task * @param rootTask represents the root task that this group want to executes ultimately */ - public CreatableTaskGroup(String key, CreatableTaskItem rootTask) { + public CreatorTaskGroup(String key, CreatorTaskItem rootTask) { super(key, rootTask); } diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskItem.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java similarity index 81% rename from azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskItem.java rename to azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java index 63a8f5541cd65..20bda3a58fa14 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableTaskItem.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java @@ -9,17 +9,19 @@ /** * Represents a task that creates a resource when executed. + * + * @param the type of the resource that this task creates */ -public class CreatableTaskItem implements TaskItem { - private CreatableTaskGroup.ResourceCreator resourceCreator; +public class CreatorTaskItem implements TaskItem { + private CreatorTaskGroup.ResourceCreator resourceCreator; private ResourceT created; /** - * Creates CreatableTaskItem. + * Creates CreatorTaskItem. * * @param resourceCreator the resource creator */ - public CreatableTaskItem(CreatableTaskGroup.ResourceCreator resourceCreator) { + public CreatorTaskItem(CreatorTaskGroup.ResourceCreator resourceCreator) { this.resourceCreator = resourceCreator; } @@ -42,7 +44,7 @@ public void execute(TaskGroup> taskGroup, DAGNode @Override public ServiceCall executeAsync(final TaskGroup> taskGroup, final DAGNode> node, final ServiceCallback callback) { - final CreatableTaskItem self = this; + final CreatorTaskItem self = this; return (this.resourceCreator).createResourceAsync(new ServiceCallback() { @Override public void failure(Throwable t) { diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java index c4207aaf3c2d9..bfe3b0cc44723 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java @@ -59,8 +59,9 @@ public void success(ServiceResponse result) { * @param callback the void callback * @param the inner resource type * @param the fluent resource type - * @param the implementation for the fuent resource type - * @return the inner callback + * @param the fluent model base type that all fluent models in the same task group derive from + * @param the implementation for the fluent resource type + * @return */ public static > ServiceCallback fromVoidCallback(final FluentImplT modelImpl, final ServiceCallback callback) { diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/GenericResourceImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/GenericResourceImpl.java index 7c0596e3a6c3e..3c7172c00a4cf 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/GenericResourceImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/implementation/GenericResourceImpl.java @@ -9,7 +9,6 @@ import com.microsoft.azure.management.resources.GenericResource; import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; -import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.azure.management.resources.Plan; import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; @@ -142,7 +141,7 @@ public void failure(Throwable t) { @Override public void success(ServiceResponse result) { - callback.success(new ServiceResponse<>( (GenericResource)result.getBody(), result.getResponse())); + callback.success(new ServiceResponse<>((GenericResource) result.getBody(), result.getResponse())); } }); } @@ -157,7 +156,7 @@ public ServiceCall applyAsync(ServiceCallback callback) { return createAsync(callback); } - // CreatableTaskGroup.ResourceCreator implementation + // CreatorTaskGroup.ResourceCreator implementation @Override public Resource createResource() throws Exception { diff --git a/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java b/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java index dd382b081b8f0..7fd64a7cb3d6e 100644 --- a/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java +++ b/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java @@ -9,7 +9,6 @@ import com.microsoft.azure.CloudException; import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.arm.models.implementation.GroupableResourceImpl; -import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.azure.management.storage.PublicEndpoints; import com.microsoft.azure.management.storage.StorageAccount; import com.microsoft.azure.management.storage.AccessTier; @@ -262,7 +261,7 @@ public StorageAccountImpl withAccessTier(AccessTier accessTier) { return this; } - // CreatableTaskGroup.ResourceCreator implementation + // CreatorTaskGroup.ResourceCreator implementation @Override public Resource createResource() throws Exception { From 2fdef41308c9aca8eebc655d5803217de2be30b1 Mon Sep 17 00:00:00 2001 From: anuchan Date: Thu, 21 Jul 2016 18:18:51 -0700 Subject: [PATCH 08/13] checkstyle fix --- .../azure/management/resources/fluentcore/utils/Utils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java index bfe3b0cc44723..fdff20947133c 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java @@ -61,7 +61,8 @@ public void success(ServiceResponse result) { * @param the fluent resource type * @param the fluent model base type that all fluent models in the same task group derive from * @param the implementation for the fluent resource type - * @return + * + * @return new callback from the void callback */ public static > ServiceCallback fromVoidCallback(final FluentImplT modelImpl, final ServiceCallback callback) { From 5e43c82198d33edf252814f198e9be5b185ee9e4 Mon Sep 17 00:00:00 2001 From: anuchan Date: Fri, 22 Jul 2016 14:47:46 -0700 Subject: [PATCH 09/13] Updated runtime sync script, Fixing the bug of not calling callback on stg create success, fixing the bug of not unlocking node --- .../storage/implementation/StorageAccountImpl.java | 1 + .../src/main/java/com/microsoft/azure/DAGraph.java | 2 +- tools/sync_runtimes.sh | 5 +---- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java b/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java index 7fd64a7cb3d6e..f15ca28e4072c 100644 --- a/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java +++ b/azure-mgmt-storage/src/main/java/com/microsoft/azure/management/storage/implementation/StorageAccountImpl.java @@ -302,6 +302,7 @@ public void failure(Throwable t) { public void success(ServiceResponse response) { self.setInner(response.getBody()); clearWrapperProperties(); + callback.success(new ServiceResponse(self, response.getResponse())); } }); } diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java index 2a3e41d768cb2..01917a77cf72a 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java @@ -139,7 +139,7 @@ public void reportedCompleted(U completed) { queue.add(dependent.key()); } } finally { - dependent.lock().lock(); + dependent.lock().unlock(); } } } diff --git a/tools/sync_runtimes.sh b/tools/sync_runtimes.sh index 4bc0c4da9121f..fa87a20ed4538 100755 --- a/tools/sync_runtimes.sh +++ b/tools/sync_runtimes.sh @@ -1,6 +1,4 @@ #!/bin/bash -# Exit on error -set -e # A previous commit may have created the branch, use that branch=master @@ -9,8 +7,7 @@ if [[ `curl https://api.github.com/repos/Azure/autorest-clientruntime-for-java/b fi # Pull and push the subtree -pull_subtree=`git subtree pull --squash --prefix runtimes https://${GH_TOKEN}@github.com/Azure/autorest-clientruntime-for-java.git $branch 2>&1` -echo $pull_subtree +git subtree pull --squash --prefix runtimes https://github.com/Azure/autorest-clientruntime-for-java.git $branch git subtree push --prefix runtimes https://${GH_TOKEN}@github.com/Azure/autorest-clientruntime-for-java.git sdk_${TRAVIS_PULL_REQUEST} > /dev/null 2>&1 # Create a pull request. This only applies when first time creating the branch From 734baf4437ac314494fd46c235c01dbc5d8ee414 Mon Sep 17 00:00:00 2001 From: anuchan Date: Fri, 22 Jul 2016 15:05:11 -0700 Subject: [PATCH 10/13] rollback sync script --- tools/sync_runtimes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/sync_runtimes.sh b/tools/sync_runtimes.sh index fa87a20ed4538..54dd12405e6ab 100755 --- a/tools/sync_runtimes.sh +++ b/tools/sync_runtimes.sh @@ -7,7 +7,7 @@ if [[ `curl https://api.github.com/repos/Azure/autorest-clientruntime-for-java/b fi # Pull and push the subtree -git subtree pull --squash --prefix runtimes https://github.com/Azure/autorest-clientruntime-for-java.git $branch +git subtree pull --squash --prefix runtimes https://${GH_TOKEN}@github.com/Azure/autorest-clientruntime-for-java.git $branch git subtree push --prefix runtimes https://${GH_TOKEN}@github.com/Azure/autorest-clientruntime-for-java.git sdk_${TRAVIS_PULL_REQUEST} > /dev/null 2>&1 # Create a pull request. This only applies when first time creating the branch From 543e4aaa1e49fa8a8e0e3718d3f34dc5f611e3a9 Mon Sep 17 00:00:00 2001 From: anuchan Date: Fri, 22 Jul 2016 17:23:57 -0700 Subject: [PATCH 11/13] Wiring up the final call-back correctly --- .../implementation/GroupableResourceImpl.java | 3 ++- .../models/implementation/ResourceImpl.java | 2 +- .../model/implementation/CreatableImpl.java | 5 ++-- .../CreatableUpdatableImpl.java | 2 +- .../model/implementation/CreatorTaskItem.java | 8 +++++-- .../resources/fluentcore/utils/Utils.java | 2 +- .../java/com/microsoft/azure/TaskGroup.java | 2 +- .../com/microsoft/azure/TaskGroupBase.java | 24 ++++--------------- .../java/com/microsoft/azure/TaskItem.java | 3 ++- 9 files changed, 20 insertions(+), 31 deletions(-) diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/arm/models/implementation/GroupableResourceImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/arm/models/implementation/GroupableResourceImpl.java index 11e0d2d357c4e..4c31e15b31628 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/arm/models/implementation/GroupableResourceImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/arm/models/implementation/GroupableResourceImpl.java @@ -10,6 +10,7 @@ import com.microsoft.azure.management.resources.fluentcore.arm.ResourceUtils; import com.microsoft.azure.management.resources.fluentcore.arm.implementation.ManagerBase; import com.microsoft.azure.management.resources.fluentcore.arm.models.GroupableResource; +import com.microsoft.azure.management.resources.fluentcore.arm.models.Resource; import com.microsoft.azure.management.resources.fluentcore.model.Creatable; /** @@ -22,7 +23,7 @@ * @param the service manager type */ public abstract class GroupableResourceImpl< - FluentModelT, + FluentModelT extends Resource, InnerModelT extends com.microsoft.azure.Resource, FluentModelImplT extends GroupableResourceImpl, ManagerT extends ManagerBase> diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/arm/models/implementation/ResourceImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/arm/models/implementation/ResourceImpl.java index 516968a7215b8..89ef131c7789c 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/arm/models/implementation/ResourceImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/arm/models/implementation/ResourceImpl.java @@ -25,7 +25,7 @@ * @param the implementation type of the fluent model type */ public abstract class ResourceImpl< - FluentModelT, + FluentModelT extends Resource, InnerModelT extends com.microsoft.azure.Resource, FluentModelImplT extends ResourceImpl> extends diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java index 382a502b019c8..ce5dbfcb5e944 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java @@ -6,7 +6,6 @@ package com.microsoft.azure.management.resources.fluentcore.model.implementation; import com.microsoft.azure.management.resources.fluentcore.model.Creatable; -import com.microsoft.azure.management.resources.fluentcore.utils.Utils; import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; @@ -18,7 +17,7 @@ * @param the fluent model implementation type * @param the fluent model or one of the base interface of fluent model */ -public abstract class CreatableImpl +public abstract class CreatableImpl extends IndexableRefreshableWrapperImpl implements CreatorTaskGroup.ResourceCreator { @@ -74,7 +73,7 @@ public FluentModelImplT create() throws Exception { public ServiceCall createAsync(ServiceCallback callback) { if (creatorTaskGroup.isPreparer()) { creatorTaskGroup.prepare(); - creatorTaskGroup.executeAsync(Utils.toVoidCallback((FluentModelT) this, callback)); + creatorTaskGroup.executeAsync((ServiceCallback) callback); return creatorTaskGroup.parallelServiceCall(); } throw new IllegalStateException("Internal Error: createAsync can be called only on preparer"); diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableUpdatableImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableUpdatableImpl.java index 13a779c652bf3..d63a724e44c26 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableUpdatableImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableUpdatableImpl.java @@ -16,7 +16,7 @@ * @param the implementation type of the fluent model * @param the fluent model or one of the base interface of fluent model */ -public abstract class CreatableUpdatableImpl +public abstract class CreatableUpdatableImpl extends CreatableImpl { protected CreatableUpdatableImpl(String name, InnerModelT innerObject) { diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java index 20bda3a58fa14..d8a0565338114 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java @@ -43,7 +43,7 @@ public void execute(TaskGroup> taskGroup, DAGNode } @Override - public ServiceCall executeAsync(final TaskGroup> taskGroup, final DAGNode> node, final ServiceCallback callback) { + public ServiceCall executeAsync(final TaskGroup> taskGroup, final DAGNode> node, final boolean isRootNode, final ServiceCallback callback) { final CreatorTaskItem self = this; return (this.resourceCreator).createResourceAsync(new ServiceCallback() { @Override @@ -55,7 +55,11 @@ public void failure(Throwable t) { public void success(ServiceResponse result) { self.created = result.getBody(); taskGroup.dag().reportedCompleted(node); - taskGroup.executeAsync(callback); + if (isRootNode) { + callback.success(result); + } else { + taskGroup.executeAsync(callback); + } } }); } diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java index fdff20947133c..4983c48f7733e 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/utils/Utils.java @@ -64,7 +64,7 @@ public void success(ServiceResponse result) { * * @return new callback from the void callback */ - public static > ServiceCallback + public static > ServiceCallback fromVoidCallback(final FluentImplT modelImpl, final ServiceCallback callback) { return new ServiceCallback() { @Override diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroup.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroup.java index 26bbbece2606b..3ad514d93874a 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroup.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroup.java @@ -63,7 +63,7 @@ public interface TaskGroup> { * @param callback the callback to call on failure or success * @return the handle to the REST call */ - ServiceCall executeAsync(ServiceCallback callback); + ServiceCall executeAsync(ServiceCallback callback); /** * Gets the result of execution of a task in the group. diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java index 5ce63987defdb..1cd0050e5ddb6 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java @@ -9,7 +9,6 @@ import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; -import com.microsoft.rest.ServiceResponse; import java.util.Arrays; import java.util.Collections; @@ -125,29 +124,14 @@ public void execute() throws Exception { } @Override - public ServiceCall executeAsync(final ServiceCallback callback) { + public ServiceCall executeAsync(final ServiceCallback callback) { ServiceCall serviceCall = null; DAGNode> nextNode = dag.getNext(); while (nextNode != null) { - if (dag.isRootNode(nextNode)) { - serviceCall = nextNode.data().executeAsync(this, nextNode, new ServiceCallback() { - @Override - public void failure(Throwable t) { - callback.failure(t); - } - - @Override - public void success(ServiceResponse result) { - callback.success(result); - } - }); - } else { - serviceCall = nextNode.data().executeAsync(this, nextNode, callback); - } - + serviceCall = nextNode.data().executeAsync(this, nextNode, dag.isRootNode(nextNode), callback); if (serviceCall != null) { - // We need to filter out the null value returned by executeAsync. This can - // happen when TaskItem::executeAsync invokes TaskGroupBase::executeAsync + // Filter out the null value returned by executeAsync. that happen + // when TaskItem::executeAsync invokes TaskGroupBase::executeAsync // but there is no task available in the queue at the moment. this.serviceCalls.add(serviceCall); } diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskItem.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskItem.java index fb74c23845c3b..1612ff4f835a7 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskItem.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskItem.java @@ -39,8 +39,9 @@ public interface TaskItem { * @param taskGroup the task group dispatching tasks * @param node the node the task item is associated with + * @param isRootNode true if the node is root node * @param callback callback to call on success or failure * @return the handle of the REST call */ - ServiceCall executeAsync(TaskGroup> taskGroup, DAGNode> node, ServiceCallback callback); + ServiceCall executeAsync(TaskGroup> taskGroup, DAGNode> node, final boolean isRootNode, ServiceCallback callback); } From 9bcaf0b7a8fbd7be9b4df025c5a8a73e319541ad Mon Sep 17 00:00:00 2001 From: anuchan Date: Sun, 24 Jul 2016 00:29:36 -0700 Subject: [PATCH 12/13] Simplify the parallel async logic and adding circular depedency detection logic --- .../model/implementation/CreatableImpl.java | 3 +- .../model/implementation/CreatorTaskItem.java | 16 +- .../java/com/microsoft/azure/DAGraph.java | 11 +- .../main/java/com/microsoft/azure/Graph.java | 89 ++++++++- .../com/microsoft/azure/TaskGroupBase.java | 172 ++++++++++-------- .../java/com/microsoft/azure/TaskItem.java | 11 +- 6 files changed, 194 insertions(+), 108 deletions(-) diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java index ce5dbfcb5e944..9fef29a055303 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatableImpl.java @@ -73,8 +73,7 @@ public FluentModelImplT create() throws Exception { public ServiceCall createAsync(ServiceCallback callback) { if (creatorTaskGroup.isPreparer()) { creatorTaskGroup.prepare(); - creatorTaskGroup.executeAsync((ServiceCallback) callback); - return creatorTaskGroup.parallelServiceCall(); + return creatorTaskGroup.executeAsync((ServiceCallback) callback); } throw new IllegalStateException("Internal Error: createAsync can be called only on preparer"); } diff --git a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java index d8a0565338114..495b6f4612eaa 100644 --- a/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java +++ b/azure-mgmt-resources/src/main/java/com/microsoft/azure/management/resources/fluentcore/model/implementation/CreatorTaskItem.java @@ -1,7 +1,5 @@ package com.microsoft.azure.management.resources.fluentcore.model.implementation; -import com.microsoft.azure.DAGNode; -import com.microsoft.azure.TaskGroup; import com.microsoft.azure.TaskItem; import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; @@ -31,19 +29,16 @@ public ResourceT result() { } @Override - public void execute(TaskGroup> taskGroup, DAGNode> node) throws Exception { + public void execute() throws Exception { if (this.created == null) { // execute will be called both in update and create scenarios, // so run the task only if it not not executed already. this.created = this.resourceCreator.createResource(); } - - taskGroup.dag().reportedCompleted(node); - taskGroup.execute(); } @Override - public ServiceCall executeAsync(final TaskGroup> taskGroup, final DAGNode> node, final boolean isRootNode, final ServiceCallback callback) { + public ServiceCall executeAsync(final ServiceCallback callback) { final CreatorTaskItem self = this; return (this.resourceCreator).createResourceAsync(new ServiceCallback() { @Override @@ -54,12 +49,7 @@ public void failure(Throwable t) { @Override public void success(ServiceResponse result) { self.created = result.getBody(); - taskGroup.dag().reportedCompleted(node); - if (isRootNode) { - callback.success(result); - } else { - taskGroup.executeAsync(callback); - } + callback.success(result); } }); } diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java index 01917a77cf72a..df3ba483f6787 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java @@ -153,9 +153,8 @@ public void reportedCompleted(U completed) { */ private void initializeDependentKeys() { visit(new Visitor() { - // This 'visit' will be called only once per each node. @Override - public void visit(U node) { + public void visitNode(U node) { if (node.dependencyKeys().isEmpty()) { return; } @@ -166,6 +165,14 @@ public void visit(U node) { .addDependent(dependentKey); } } + + @Override + public void visitEdge(String fromKey, String toKey, GraphEdgeType edgeType) { + System.out.println("{" + fromKey + ", " + toKey + "} " + edgeType); + if (edgeType == GraphEdgeType.BACK) { + throw new IllegalStateException("Detected circular dependency: " + findPath(fromKey, toKey)); + } + } }); } diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/Graph.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/Graph.java index 40ceebaa50b2b..17440ddbeb193 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/Graph.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/Graph.java @@ -12,6 +12,16 @@ import java.util.Map; import java.util.Set; +/** + * The edge types in a graph. + */ +enum GraphEdgeType { + TREE, + FORWARD, + BACK, + CROSS +} + /** * Type representing a directed graph data structure. *

@@ -23,6 +33,11 @@ public class Graph> { protected Map graph; private Set visited; + private Integer time; + private Map entryTime; + private Map exitTime; + private Map parent; + private Set processed; /** * Creates a directed graph. @@ -30,6 +45,11 @@ public class Graph> { public Graph() { this.graph = new HashMap<>(); this.visited = new HashSet<>(); + this.time = 0; + this.entryTime = new HashMap<>(); + this.exitTime = new HashMap<>(); + this.parent = new HashMap<>(); + this.processed = new HashSet<>(); } /** @@ -53,14 +73,23 @@ interface Visitor { * * @param node the node to visited */ - void visit(U node); + void visitNode(U node); + + /** + * visit an edge. + * + * @param fromKey key of the from node + * @param toKey key of the to node + * @param graphEdgeType the edge type + */ + void visitEdge(String fromKey, String toKey, GraphEdgeType graphEdgeType); } /** * Perform DFS visit in this graph. *

* The directed graph will be traversed in DFS order and the visitor will be notified as - * search explores each node + * search explores each node and edge. * * @param visitor the graph visitor */ @@ -71,15 +100,61 @@ public void visit(Visitor visitor) { } } visited.clear(); + time = 0; + entryTime.clear(); + exitTime.clear(); + parent.clear(); + processed.clear(); } private void dfs(Visitor visitor, Node node) { - visitor.visit(node); - visited.add(node.key()); - for (String childKey : node.children()) { - if (!visited.contains(childKey)) { - this.dfs(visitor, this.graph.get(childKey)); + visitor.visitNode(node); + + String fromKey = node.key(); + visited.add(fromKey); + time++; + entryTime.put(fromKey, time); + for (String toKey : node.children()) { + if (!visited.contains(toKey)) { + parent.put(toKey, fromKey); + visitor.visitEdge(fromKey, toKey, edgeType(fromKey, toKey)); + this.dfs(visitor, this.graph.get(toKey)); + } else { + visitor.visitEdge(fromKey, toKey, edgeType(fromKey, toKey)); } } + time++; + exitTime.put(fromKey, time); + processed.add(fromKey); + } + + private GraphEdgeType edgeType(String fromKey, String toKey) { + if (parent.containsKey(toKey) && parent.get(toKey).equals(fromKey)) { + return GraphEdgeType.TREE; + } + + if (visited.contains(toKey) && !processed.contains(toKey)) { + return GraphEdgeType.BACK; + } + + if (processed.contains(toKey) && entryTime.containsKey(toKey) && entryTime.containsKey(fromKey)) { + if (entryTime.get(toKey) > entryTime.get(fromKey)) { + return GraphEdgeType.FORWARD; + } + + if (entryTime.get(toKey) < entryTime.get(fromKey)) { + return GraphEdgeType.CROSS; + } + } + + throw new IllegalStateException("Internal Error: Unable to locate the edge type {" + fromKey + ", " + toKey + "}"); + } + + protected String findPath(String start, String end) { + if (start.equals(end)) { + return start; + } else { + return findPath(start, parent.get(end)) + " -> " + end; + } } } diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java index 1cd0050e5ddb6..b607a41f54add 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskGroupBase.java @@ -9,54 +9,10 @@ import com.microsoft.rest.ServiceCall; import com.microsoft.rest.ServiceCallback; +import com.microsoft.rest.ServiceResponse; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; import java.util.concurrent.ConcurrentLinkedQueue; -/** - /** - * An instance of this class provides access to the underlying REST service call running - * in parallel. - * - * @param - */ -class ParallelServiceCall extends ServiceCall { - private TaskGroupBase taskGroup; - - /** - * Creates a ParallelServiceCall. - * - * @param taskGroup the task group - */ - ParallelServiceCall(TaskGroupBase taskGroup) { - super(null); - this.taskGroup = taskGroup; - } - - /** - * Cancels all the service calls currently executing. - */ - public void cancel() { - for (ServiceCall call : this.taskGroup.calls()) { - call.cancel(); - } - } - - /** - * @return true if the call has been canceled; false otherwise. - */ - public boolean isCancelled() { - for (ServiceCall call : this.taskGroup.calls()) { - if (!call.isCanceled()) { - return false; - } - } - return true; - } -} - /** * The base implementation of TaskGroup interface. * @@ -65,8 +21,7 @@ public boolean isCancelled() { public abstract class TaskGroupBase implements TaskGroup> { private DAGraph, DAGNode>> dag; - private ConcurrentLinkedQueue serviceCalls = new ConcurrentLinkedQueue<>(); - private ParallelServiceCall parallelServiceCall; + private ParallelServiceCall parallelServiceCall; /** * Creates TaskGroupBase. @@ -76,11 +31,7 @@ public abstract class TaskGroupBase */ public TaskGroupBase(String rootTaskItemId, TaskItem rootTaskItem) { this.dag = new DAGraph<>(new DAGNode<>(rootTaskItemId, rootTaskItem)); - this.parallelServiceCall = new ParallelServiceCall<>(this); - } - - List calls() { - return Collections.unmodifiableList(Arrays.asList(serviceCalls.toArray(new ServiceCall[0]))); + this.parallelServiceCall = new ParallelServiceCall(); } @Override @@ -93,14 +44,6 @@ public boolean isPreparer() { return dag.isPreparer(); } - /** - * @return Gets the ParallelServiceCall instance that wraps the service calls running - * in parallel. - */ - public ParallelServiceCall parallelServiceCall() { - return this.parallelServiceCall; - } - @Override public void merge(TaskGroup> parentTaskGroup) { dag.merge(parentTaskGroup.dag()); @@ -116,32 +59,109 @@ public void prepare() { @Override public void execute() throws Exception { DAGNode> nextNode = dag.getNext(); - if (nextNode == null) { - return; + while (nextNode != null) { + nextNode.data().execute(); + this.dag().reportedCompleted(nextNode); + nextNode = dag.getNext(); } - - nextNode.data().execute(this, nextNode); } @Override public ServiceCall executeAsync(final ServiceCallback callback) { - ServiceCall serviceCall = null; + executeReadyTasksAsync(callback); + return parallelServiceCall; + } + + @Override + public T taskResult(String taskId) { + return dag.getNodeData(taskId).result(); + } + + /** + * Executes all runnable tasks, a task is runnable when all the tasks its depends + * on are finished running. + * + * @param callback the callback + */ + private void executeReadyTasksAsync(final ServiceCallback callback) { DAGNode> nextNode = dag.getNext(); while (nextNode != null) { - serviceCall = nextNode.data().executeAsync(this, nextNode, dag.isRootNode(nextNode), callback); - if (serviceCall != null) { - // Filter out the null value returned by executeAsync. that happen - // when TaskItem::executeAsync invokes TaskGroupBase::executeAsync - // but there is no task available in the queue at the moment. - this.serviceCalls.add(serviceCall); - } + ServiceCall serviceCall = nextNode.data().executeAsync(taskCallback(nextNode, callback)); + this.parallelServiceCall.addCall(serviceCall); nextNode = dag.getNext(); } - return serviceCall; } - @Override - public T taskResult(String taskId) { - return dag.getNodeData(taskId).result(); + /** + * This method create and return a callback for the runnable task stored in the given node. + * This callback wraps the given callback. + * + * @param taskNode the node containing runnable task + * @param callback the callback to wrap + * @return the task callback + */ + private ServiceCallback taskCallback(final DAGNode> taskNode, final ServiceCallback callback) { + final TaskGroupBase self = this; + return new ServiceCallback() { + @Override + public void failure(Throwable t) { + callback.failure(t); + } + + @Override + public void success(ServiceResponse result) { + self.dag().reportedCompleted(taskNode); + if (self.dag().isRootNode(taskNode)) { + callback.success(result); + } else { + self.executeReadyTasksAsync(callback); + } + } + }; + } + + /** + * Type represents a set of REST calls running possibly in parallel. + */ + private class ParallelServiceCall extends ServiceCall { + private ConcurrentLinkedQueue serviceCalls; + + /** + * Creates a ParallelServiceCall. + */ + ParallelServiceCall() { + super(null); + this.serviceCalls = new ConcurrentLinkedQueue<>(); + } + + /** + * Cancels all the service calls currently executing. + */ + public void cancel() { + for (ServiceCall call : this.serviceCalls) { + call.cancel(); + } + } + + /** + * @return true if the call has been canceled; false otherwise. + */ + public boolean isCancelled() { + for (ServiceCall call : this.serviceCalls) { + if (!call.isCanceled()) { + return false; + } + } + return true; + } + + /** + * Add a call to the list of parallel calls. + * + * @param call the call + */ + private void addCall(ServiceCall call) { + this.serviceCalls.add(call); + } } } diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskItem.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskItem.java index 1612ff4f835a7..8f0a3459a2e92 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskItem.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/TaskItem.java @@ -26,22 +26,17 @@ public interface TaskItem { *

* once executed the result will be available through result getter * - * @param taskGroup the task group dispatching tasks - * @param node the node the task item is associated with * @throws Exception exception */ - void execute(TaskGroup> taskGroup, DAGNode> node) throws Exception; + void execute() throws Exception; /** * Executes the task asynchronously. *

* once executed the result will be available through result getter - - * @param taskGroup the task group dispatching tasks - * @param node the node the task item is associated with - * @param isRootNode true if the node is root node + * * @param callback callback to call on success or failure * @return the handle of the REST call */ - ServiceCall executeAsync(TaskGroup> taskGroup, DAGNode> node, final boolean isRootNode, ServiceCallback callback); + ServiceCall executeAsync(ServiceCallback callback); } From 512f5903734d659e44fecd258485f21228d5d158 Mon Sep 17 00:00:00 2001 From: anuchan Date: Mon, 25 Jul 2016 11:22:00 -0700 Subject: [PATCH 13/13] Adding comments for EdgeType num --- .../java/com/microsoft/azure/DAGraph.java | 5 +- .../main/java/com/microsoft/azure/Graph.java | 90 +++++++++++-------- 2 files changed, 53 insertions(+), 42 deletions(-) diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java index df3ba483f6787..153c38f2592a3 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java @@ -167,9 +167,8 @@ public void visitNode(U node) { } @Override - public void visitEdge(String fromKey, String toKey, GraphEdgeType edgeType) { - System.out.println("{" + fromKey + ", " + toKey + "} " + edgeType); - if (edgeType == GraphEdgeType.BACK) { + public void visitEdge(String fromKey, String toKey, EdgeType edgeType) { + if (edgeType == EdgeType.BACK) { throw new IllegalStateException("Detected circular dependency: " + findPath(fromKey, toKey)); } } diff --git a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/Graph.java b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/Graph.java index 17440ddbeb193..89087dd6d3580 100644 --- a/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/Graph.java +++ b/runtimes/azure-client-runtime/src/main/java/com/microsoft/azure/Graph.java @@ -12,16 +12,6 @@ import java.util.Map; import java.util.Set; -/** - * The edge types in a graph. - */ -enum GraphEdgeType { - TREE, - FORWARD, - BACK, - CROSS -} - /** * Type representing a directed graph data structure. *

@@ -61,30 +51,6 @@ public void addNode(U node) { graph.put(node.key(), node); } - /** - * Represents a visitor to be implemented by the consumer who want to visit the - * graph's nodes in DFS order. - * - * @param the type of the node - */ - interface Visitor { - /** - * visit a node. - * - * @param node the node to visited - */ - void visitNode(U node); - - /** - * visit an edge. - * - * @param fromKey key of the from node - * @param toKey key of the to node - * @param graphEdgeType the edge type - */ - void visitEdge(String fromKey, String toKey, GraphEdgeType graphEdgeType); - } - /** * Perform DFS visit in this graph. *

@@ -128,22 +94,22 @@ private void dfs(Visitor visitor, Node node) { processed.add(fromKey); } - private GraphEdgeType edgeType(String fromKey, String toKey) { + private EdgeType edgeType(String fromKey, String toKey) { if (parent.containsKey(toKey) && parent.get(toKey).equals(fromKey)) { - return GraphEdgeType.TREE; + return EdgeType.TREE; } if (visited.contains(toKey) && !processed.contains(toKey)) { - return GraphEdgeType.BACK; + return EdgeType.BACK; } if (processed.contains(toKey) && entryTime.containsKey(toKey) && entryTime.containsKey(fromKey)) { if (entryTime.get(toKey) > entryTime.get(fromKey)) { - return GraphEdgeType.FORWARD; + return EdgeType.FORWARD; } if (entryTime.get(toKey) < entryTime.get(fromKey)) { - return GraphEdgeType.CROSS; + return EdgeType.CROSS; } } @@ -157,4 +123,50 @@ protected String findPath(String start, String end) { return findPath(start, parent.get(end)) + " -> " + end; } } + + /** + * The edge types in a graph. + */ + enum EdgeType { + /** + * An edge (u, v) is a tree edge if v is visited the first time. + */ + TREE, + /** + * An edge (u, v) is a forward edge if v is descendant of u. + */ + FORWARD, + /** + * An edge (u, v) is a back edge if v is ancestor of u. + */ + BACK, + /** + * An edge (u, v) is a cross edge if v is neither ancestor or descendant of u. + */ + CROSS + } + + /** + * Represents a visitor to be implemented by the consumer who want to visit the + * graph's nodes in DFS order by calling visit method. + * + * @param the type of the node + */ + interface Visitor { + /** + * visit a node. + * + * @param node the node to visited + */ + void visitNode(U node); + + /** + * visit an edge. + * + * @param fromKey key of the from node + * @param toKey key of the to node + * @param edgeType the edge type + */ + void visitEdge(String fromKey, String toKey, EdgeType edgeType); + } }