Skip to content

Commit

Permalink
Merge pull request Azure#22 from jianghaolu/master
Browse files Browse the repository at this point in the history
Updates from Java SDK
  • Loading branch information
jianghaolu authored Jul 14, 2016
2 parents 53ae9e7 + cf2fdb5 commit 3fa32be
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 3fa32be

Please sign in to comment.