Skip to content

Commit

Permalink
Squashed 'runtimes/' changes from 53ae9e7..3fa32be
Browse files Browse the repository at this point in the history
3fa32be Merge pull request #22 from jianghaolu/master
cf2fdb5 Adding publicIp sample, only mark sub-DAGs as non-prepare - the root DAG stay as preparer
1d5e9c1 improving comment as per review
25beef0 Addressing review comments [javadoc, simplfying the map iteration]
cfbafd0 comment corrections
ac633da Making DAG to work correctly to handle more cases
45c3d88 couple of javadoc fixes
57288f4 Merge pull request Azure#819 from jianghaolu/async
999fb18 Add retry for 404 GET
9c048fc Add a bunch of configs to RestClient
46a53cd Merge branch 'master' of github.com:Azure/azure-sdk-for-java into async
76e3ae9 Merge pull request Azure#832 from jianghaolu/restclient
7be25fe Merge commit '486acdc633c498d4335711e30817cc70faacc487' into restclient
f84d8eb making dag::prepare to work for update
bb4a917 Fixing the bug of trying to create created resources during update, adding better way to name gen resource names
738d121 use AZURE_GERMANY insteadof AZURE_GERMAN
6c8f63a ensuring trailing slash for urls
c8db8d3 correcting environment name
0261a6e Adding few more Azure environments
5aac1fa Add applyAsync()
bc57070 Basic prototyping of async in fluent

git-subtree-dir: runtimes
git-subtree-split: 3fa32be
  • Loading branch information
jianghaolu committed Jul 14, 2016
1 parent 75623b4 commit c0aa849
Show file tree
Hide file tree
Showing 13 changed files with 304 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,14 @@ public ApplicationTokenCredentials withDefaultSubscriptionId(String subscription
*
* @param credentialsFile A file with credentials, using the standard Java properties format.
* and the following keys:
* subscription=<subscription-id>
* tenant=<tenant-id>
* client=<client-id>
* key=<client-key>
* managementURI=<management-URI>
* baseURL=<base-URL>
* authURL=<authentication-URL>
* subscription=&lt;subscription-id&gt;
* tenant=&lt;tenant-id&gt;
* client=&lt;client-id&gt;
* key=&lt;client-key&gt;
* managementURI=&lt;management-URI&gt;
* baseURL=&lt;base-URL&gt;
* authURL=&lt;authentication-URL&gt;
*
* @return The credentials based on the file.
* @throws IOException exception thrown from file access errors.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,25 @@ public AzureEnvironment(
"https://login.chinacloudapi.cn/",
"https://management.core.chinacloudapi.cn/",
true,
"https://management.chinacloudapi.cn");
"https://management.chinacloudapi.cn/");

/**
* Provides the settings for authentication with Azure US Government.
*/
public static final AzureEnvironment AZURE_US_GOVERNMENT = new AzureEnvironment(
"https://login.microsoftonline.com/",
"https://management.core.usgovcloudapi.net/",
true,
"https://management.usgovcloudapi.net/");

/**
* Provides the settings for authentication with Azure Germany.
*/
public static final AzureEnvironment AZURE_GERMANY = new AzureEnvironment(
"https://login.microsoftonline.de/",
"https://management.core.cloudapi.de/",
true,
"https://management.microsoftazure.de/");

/**
* Gets the base URL of the management service.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.microsoft.azure;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
Expand All @@ -18,6 +19,7 @@
public class DAGNode<T> extends Node<T> {
private List<String> dependentKeys;
private int toBeResolved;
private boolean isPreparer;

/**
* Creates a DAG node.
Expand All @@ -34,11 +36,11 @@ public DAGNode(String key, T data) {
* @return a list of keys of nodes in {@link DAGraph} those are dependents on this node
*/
List<String> dependentKeys() {
return this.dependentKeys;
return Collections.unmodifiableList(this.dependentKeys);
}

/**
* mark the node identified by the given key as dependent of this node.
* Mark the node identified by the given key as dependent of this node.
*
* @param key the id of the dependent node
*/
Expand All @@ -54,12 +56,11 @@ public List<String> dependencyKeys() {
}

/**
* mark the node identified by the given key as this node's dependency.
* Mark the node identified by the given key as this node's dependency.
*
* @param dependencyKey the id of the dependency node
*/
public void addDependency(String dependencyKey) {
toBeResolved++;
super.addChild(dependencyKey);
}

Expand All @@ -70,6 +71,30 @@ public boolean hasDependencies() {
return this.hasChildren();
}

/**
* Mark or un-mark this node as preparer.
*
* @param isPreparer <tt>true</tt> if this node needs to be marked as preparer, <tt>false</tt> otherwise.
*/
public void setPreparer(boolean isPreparer) {
this.isPreparer = isPreparer;
}

/**
* @return <tt>true</tt> if this node is marked as preparer
*/
public boolean isPreparer() {
return isPreparer;
}

/**
* Initialize the node so that traversal can be performed on the parent DAG.
*/
public void initialize() {
this.toBeResolved = this.dependencyKeys().size();
this.dependentKeys.clear();
}

/**
* @return <tt>true</tt> if all dependencies of this node are ready to be consumed
*/
Expand Down
46 changes: 31 additions & 15 deletions azure-client-runtime/src/main/java/com/microsoft/azure/DAGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class DAGraph<T, U extends DAGNode<T>> extends Graph<T, U> {
public DAGraph(U rootNode) {
this.rootNode = rootNode;
this.queue = new ArrayDeque<>();
this.rootNode.setPreparer(true);
this.addNode(rootNode);
}

Expand All @@ -52,18 +53,25 @@ public boolean isRootNode(U node) {
return this.rootNode == node;
}

/**
* @return <tt>true</tt> if this dag is the preparer responsible for
* preparing the DAG for traversal.
*/
public boolean isPreparer() {
return this.rootNode.isPreparer();
}

/**
* Merge this DAG with another DAG.
* <p>
* this will mark this DAG as a child DAG, the dependencies of nodes in this DAG will be merged
* This will mark this DAG as a child DAG, the dependencies of nodes in this DAG will be merged
* with (copied to) the parent DAG
*
* @param parent the parent DAG
*/
public void merge(DAGraph<T, U> parent) {
this.hasParent = true;
parent.rootNode.addDependency(this.rootNode.key());
this.rootNode.addDependent(parent.rootNode.key());
for (Map.Entry<String, U> entry: graph.entrySet()) {
String key = entry.getKey();
if (!parent.graph.containsKey(key)) {
Expand All @@ -77,19 +85,25 @@ public void merge(DAGraph<T, U> parent) {
* in the DAG with no dependencies.
*/
public void prepare() {
initializeQueue();
if (queue.isEmpty()) {
throw new RuntimeException("Found circular dependency");
if (isPreparer()) {
for (U node : graph.values()) {
// Prepare each node for traversal
node.initialize();
if (!this.isRootNode(node)) {
// Mark other sub-DAGs as non-preparer
node.setPreparer(false);
}
}
initializeDependentKeys();
initializeQueue();
}
}

/**
* Gets next node in the DAG which has no dependency or all of it's dependencies are resolved and
* ready to be consumed.
* <p>
* null will be returned when all the nodes are explored
*
* @return next node
* @return next node or null if all the nodes have been explored
*/
public U getNext() {
return graph.get(queue.poll());
Expand All @@ -111,6 +125,7 @@ public T getNodeData(String key) {
* @param completed the node ready to be consumed
*/
public void reportedCompleted(U completed) {
completed.setPreparer(true);
String dependency = completed.key();
for (String dependentKey : graph.get(dependency).dependentKeys()) {
DAGNode<T> dependent = graph.get(dependentKey);
Expand All @@ -122,27 +137,25 @@ public void reportedCompleted(U completed) {
}

/**
* populate dependents of all nodes.
* Initializes dependents of all nodes.
* <p>
* the DAG will be explored in DFS order and all node's dependents will be identified,
* The DAG will be explored in DFS order and all node's dependents will be identified,
* this prepares the DAG for traversal using getNext method, each call to getNext returns next node
* in the DAG with no dependencies.
*/
public void populateDependentKeys() {
this.queue.clear();
private void initializeDependentKeys() {
visit(new Visitor<U>() {
// This 'visit' will be called only once per each node.
@Override
public void visit(U node) {
if (node.dependencyKeys().isEmpty()) {
queue.add(node.key());
return;
}

String dependentKey = node.key();
for (String dependencyKey : node.dependencyKeys()) {
graph.get(dependencyKey)
.dependentKeys()
.add(dependentKey);
.addDependent(dependentKey);
}
}
});
Expand All @@ -159,5 +172,8 @@ private void initializeQueue() {
this.queue.add(entry.getKey());
}
}
if (queue.isEmpty()) {
throw new RuntimeException("Found circular dependency");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
/**
* Type representing a directed graph data structure.
* <p>
* each node in a graph is represented by {@link Node}
* Each node in a graph is represented by {@link Node}
*
* @param <T> the type of the data stored in the graph's nodes
* @param <U> the type of the nodes in the graph
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package com.microsoft.azure;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
Expand Down Expand Up @@ -57,7 +58,7 @@ public boolean hasChildren() {
* @return children (neighbours) of this node
*/
public List<String> children() {
return this.children;
return Collections.unmodifiableList(this.children);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*
*/

package com.microsoft.azure;

import com.microsoft.rest.retry.RetryStrategy;
import okhttp3.Response;

/**
* A retry strategy with backoff parameters for calculating the exponential
* delay between retries for 404s from GET calls.
*/
public class ResourceGetExponentialBackoffRetryStrategy extends RetryStrategy {
/**
* Represents the default number of retries.
*/
private static final int DEFAULT_NUMBER_OF_ATTEMPTS = 3;

/**
* Creates an instance of the retry strategy.
*/
public ResourceGetExponentialBackoffRetryStrategy() {
this(null, DEFAULT_FIRST_FAST_RETRY);
}

/**
* Initializes a new instance of the {@link RetryStrategy} class.
*
* @param name The name of the retry strategy.
* @param firstFastRetry true to immediately retry in the first attempt; otherwise, false.
*/
private ResourceGetExponentialBackoffRetryStrategy(String name, boolean firstFastRetry) {
super(name, firstFastRetry);
}

@Override
public boolean shouldRetry(int retryCount, Response response) {
int code = response.code();
//CHECKSTYLE IGNORE MagicNumber FOR NEXT 2 LINES
return retryCount < DEFAULT_NUMBER_OF_ATTEMPTS
&& code == 404
&& response.request().method().equalsIgnoreCase("GET");
}
}
Loading

0 comments on commit c0aa849

Please sign in to comment.