kudu git commit: KUDU-2540: Authorization failures on exactly-once RPCs cause FATAL

2018-08-14 Thread danburkert
Repository: kudu
Updated Branches:
  refs/heads/branch-1.7.x cd28c7553 -> b24f166e3


KUDU-2540: Authorization failures on exactly-once RPCs cause FATAL

See the associated JIRA for bug details. The fix follows a slightly
different approach than suggested by Todd, namely initialization of the
RPC tracker in the RPC context is delayed until after authorization.
This allows the error path code to remain unchanged, and allows the one
caller of the RpcContext constructor to be slightly cleaned up.

Change-Id: I9717d36e438bbe68172fa2619c9829ad5fdc779d
Reviewed-on: http://gerrit.cloudera.org:8080/11216
Reviewed-by: Alexey Serbin 
Tested-by: Kudu Jenkins
Reviewed-on: http://gerrit.cloudera.org:8080/11219
Reviewed-by: Adar Dembo 


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/b24f166e
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/b24f166e
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/b24f166e

Branch: refs/heads/branch-1.7.x
Commit: b24f166e356d7f34f6cff2efa0dcb3ff3ebe6e0b
Parents: cd28c75
Author: Dan Burkert 
Authored: Tue Aug 14 12:18:32 2018 -0700
Committer: Dan Burkert 
Committed: Tue Aug 14 22:55:34 2018 +

--
 src/kudu/rpc/rpc_context.cc   | 11 +++
 src/kudu/rpc/rpc_context.h| 10 --
 src/kudu/rpc/rpc_stub-test.cc | 36 +---
 src/kudu/rpc/service_if.cc| 12 +++-
 4 files changed, 47 insertions(+), 22 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/kudu/blob/b24f166e/src/kudu/rpc/rpc_context.cc
--
diff --git a/src/kudu/rpc/rpc_context.cc b/src/kudu/rpc/rpc_context.cc
index 123d21f..fe6fb38 100644
--- a/src/kudu/rpc/rpc_context.cc
+++ b/src/kudu/rpc/rpc_context.cc
@@ -48,12 +48,10 @@ namespace rpc {
 
 RpcContext::RpcContext(InboundCall *call,
const google::protobuf::Message *request_pb,
-   google::protobuf::Message *response_pb,
-   const scoped_refptr& result_tracker)
+   google::protobuf::Message *response_pb)
   : call_(CHECK_NOTNULL(call)),
 request_pb_(request_pb),
-response_pb_(response_pb),
-result_tracker_(result_tracker) {
+response_pb_(response_pb) {
   VLOG(4) << call_->remote_method().service_name() << ": Received RPC request 
for "
   << call_->ToString() << ":" << std::endl << 
SecureDebugString(*request_pb_);
   TRACE_EVENT_ASYNC_BEGIN2("rpc_call", "RPC", this,
@@ -64,6 +62,11 @@ RpcContext::RpcContext(InboundCall *call,
 RpcContext::~RpcContext() {
 }
 
+void RpcContext::SetResultTracker(scoped_refptr result_tracker) 
{
+  DCHECK(!result_tracker_);
+  result_tracker_ = std::move(result_tracker);
+}
+
 void RpcContext::RespondSuccess() {
   if (AreResultsTracked()) {
 result_tracker_->RecordCompletionAndRespond(call_->header().request_id(),

http://git-wip-us.apache.org/repos/asf/kudu/blob/b24f166e/src/kudu/rpc/rpc_context.h
--
diff --git a/src/kudu/rpc/rpc_context.h b/src/kudu/rpc/rpc_context.h
index a34c1a1..e27 100644
--- a/src/kudu/rpc/rpc_context.h
+++ b/src/kudu/rpc/rpc_context.h
@@ -69,11 +69,17 @@ class RpcContext {
   // and is not a public API.
   RpcContext(InboundCall *call,
  const google::protobuf::Message *request_pb,
- google::protobuf::Message *response_pb,
- const scoped_refptr& result_tracker);
+ google::protobuf::Message *response_pb);
 
   ~RpcContext();
 
+  // Initialize a result tracker for the RPC.
+  //
+  // This is delayed until after the constructor in order to allow for RPCs to
+  // be validated and used prior to initializing the tracking (primarily for
+  // authorization).
+  void SetResultTracker(scoped_refptr result_tracker);
+
   // Return the trace buffer for this call.
   Trace* trace();
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/b24f166e/src/kudu/rpc/rpc_stub-test.cc
--
diff --git a/src/kudu/rpc/rpc_stub-test.cc b/src/kudu/rpc/rpc_stub-test.cc
index d5b85d1..7e46dc9 100644
--- a/src/kudu/rpc/rpc_stub-test.cc
+++ b/src/kudu/rpc/rpc_stub-test.cc
@@ -208,13 +208,35 @@ TEST_F(RpcStubTest, TestAuthorization) {
 p.set_user_credentials(creds);
 
 // Alice is disallowed by all RPCs.
-RpcController controller;
-WhoAmIRequestPB req;
-WhoAmIResponsePB resp;
-Status s = p.WhoAmI(req, , );
-ASSERT_FALSE(s.ok());
-ASSERT_EQ(s.ToString(),
-  "Remote error: Not authorized: alice is not allowed to call this 
method");
+{
+  RpcController controller;
+  WhoAmIRequestPB req;
+  WhoAmIResponsePB resp;
+  Status s = p.WhoAmI(req, , );
+  

kudu git commit: KUDU-2540: Authorization failures on exactly-once RPCs cause FATAL

2018-08-14 Thread danburkert
Repository: kudu
Updated Branches:
  refs/heads/branch-1.6.x 6dfc10ac0 -> c50b7fe69


KUDU-2540: Authorization failures on exactly-once RPCs cause FATAL

See the associated JIRA for bug details. The fix follows a slightly
different approach than suggested by Todd, namely initialization of the
RPC tracker in the RPC context is delayed until after authorization.
This allows the error path code to remain unchanged, and allows the one
caller of the RpcContext constructor to be slightly cleaned up.

Change-Id: I9717d36e438bbe68172fa2619c9829ad5fdc779d
Reviewed-on: http://gerrit.cloudera.org:8080/11216
Reviewed-by: Alexey Serbin 
Tested-by: Kudu Jenkins
Reviewed-on: http://gerrit.cloudera.org:8080/11220
Reviewed-by: Adar Dembo 


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/c50b7fe6
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/c50b7fe6
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/c50b7fe6

Branch: refs/heads/branch-1.6.x
Commit: c50b7fe6915febcb2af480e67a1ca43a708142c0
Parents: 6dfc10a
Author: Dan Burkert 
Authored: Tue Aug 14 12:18:32 2018 -0700
Committer: Dan Burkert 
Committed: Tue Aug 14 22:55:37 2018 +

--
 src/kudu/rpc/rpc_context.cc   | 11 +++
 src/kudu/rpc/rpc_context.h| 10 --
 src/kudu/rpc/rpc_stub-test.cc | 36 +---
 src/kudu/rpc/service_if.cc| 12 +++-
 4 files changed, 47 insertions(+), 22 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/kudu/blob/c50b7fe6/src/kudu/rpc/rpc_context.cc
--
diff --git a/src/kudu/rpc/rpc_context.cc b/src/kudu/rpc/rpc_context.cc
index 9c3d154..27011b5 100644
--- a/src/kudu/rpc/rpc_context.cc
+++ b/src/kudu/rpc/rpc_context.cc
@@ -47,12 +47,10 @@ namespace rpc {
 
 RpcContext::RpcContext(InboundCall *call,
const google::protobuf::Message *request_pb,
-   google::protobuf::Message *response_pb,
-   const scoped_refptr& result_tracker)
+   google::protobuf::Message *response_pb)
   : call_(CHECK_NOTNULL(call)),
 request_pb_(request_pb),
-response_pb_(response_pb),
-result_tracker_(result_tracker) {
+response_pb_(response_pb) {
   VLOG(4) << call_->remote_method().service_name() << ": Received RPC request 
for "
   << call_->ToString() << ":" << std::endl << 
SecureDebugString(*request_pb_);
   TRACE_EVENT_ASYNC_BEGIN2("rpc_call", "RPC", this,
@@ -63,6 +61,11 @@ RpcContext::RpcContext(InboundCall *call,
 RpcContext::~RpcContext() {
 }
 
+void RpcContext::SetResultTracker(scoped_refptr result_tracker) 
{
+  DCHECK(!result_tracker_);
+  result_tracker_ = std::move(result_tracker);
+}
+
 void RpcContext::RespondSuccess() {
   if (AreResultsTracked()) {
 result_tracker_->RecordCompletionAndRespond(call_->header().request_id(),

http://git-wip-us.apache.org/repos/asf/kudu/blob/c50b7fe6/src/kudu/rpc/rpc_context.h
--
diff --git a/src/kudu/rpc/rpc_context.h b/src/kudu/rpc/rpc_context.h
index 42f096e..468e6d1 100644
--- a/src/kudu/rpc/rpc_context.h
+++ b/src/kudu/rpc/rpc_context.h
@@ -68,11 +68,17 @@ class RpcContext {
   // and is not a public API.
   RpcContext(InboundCall *call,
  const google::protobuf::Message *request_pb,
- google::protobuf::Message *response_pb,
- const scoped_refptr& result_tracker);
+ google::protobuf::Message *response_pb);
 
   ~RpcContext();
 
+  // Initialize a result tracker for the RPC.
+  //
+  // This is delayed until after the constructor in order to allow for RPCs to
+  // be validated and used prior to initializing the tracking (primarily for
+  // authorization).
+  void SetResultTracker(scoped_refptr result_tracker);
+
   // Return the trace buffer for this call.
   Trace* trace();
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/c50b7fe6/src/kudu/rpc/rpc_stub-test.cc
--
diff --git a/src/kudu/rpc/rpc_stub-test.cc b/src/kudu/rpc/rpc_stub-test.cc
index 5fe2885..cb16c02 100644
--- a/src/kudu/rpc/rpc_stub-test.cc
+++ b/src/kudu/rpc/rpc_stub-test.cc
@@ -209,13 +209,35 @@ TEST_F(RpcStubTest, TestAuthorization) {
 p.set_user_credentials(creds);
 
 // Alice is disallowed by all RPCs.
-RpcController controller;
-WhoAmIRequestPB req;
-WhoAmIResponsePB resp;
-Status s = p.WhoAmI(req, , );
-ASSERT_FALSE(s.ok());
-ASSERT_EQ(s.ToString(),
-  "Remote error: Not authorized: alice is not allowed to call this 
method");
+{
+  RpcController controller;
+  WhoAmIRequestPB req;
+  WhoAmIResponsePB resp;
+  Status s = p.WhoAmI(req, , );
+  

kudu git commit: KUDU-2540: Authorization failures on exactly-once RPCs cause FATAL

2018-08-14 Thread danburkert
Repository: kudu
Updated Branches:
  refs/heads/master 2d92370d9 -> e795d5a82


KUDU-2540: Authorization failures on exactly-once RPCs cause FATAL

See the associated JIRA for bug details. The fix follows a slightly
different approach than suggested by Todd, namely initialization of the
RPC tracker in the RPC context is delayed until after authorization.
This allows the error path code to remain unchanged, and allows the one
caller of the RpcContext constructor to be slightly cleaned up.

Change-Id: I9717d36e438bbe68172fa2619c9829ad5fdc779d
Reviewed-on: http://gerrit.cloudera.org:8080/11216
Reviewed-by: Alexey Serbin 
Tested-by: Kudu Jenkins


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/e795d5a8
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/e795d5a8
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/e795d5a8

Branch: refs/heads/master
Commit: e795d5a82c0c27c8a2ba1f82ac6695402aa42885
Parents: 2d92370
Author: Dan Burkert 
Authored: Tue Aug 14 12:18:32 2018 -0700
Committer: Dan Burkert 
Committed: Tue Aug 14 21:20:30 2018 +

--
 src/kudu/rpc/rpc_context.cc   | 11 +++
 src/kudu/rpc/rpc_context.h| 10 --
 src/kudu/rpc/rpc_stub-test.cc | 36 +---
 src/kudu/rpc/service_if.cc| 12 +++-
 4 files changed, 47 insertions(+), 22 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/kudu/blob/e795d5a8/src/kudu/rpc/rpc_context.cc
--
diff --git a/src/kudu/rpc/rpc_context.cc b/src/kudu/rpc/rpc_context.cc
index b3072ca..9f95358 100644
--- a/src/kudu/rpc/rpc_context.cc
+++ b/src/kudu/rpc/rpc_context.cc
@@ -48,12 +48,10 @@ namespace rpc {
 
 RpcContext::RpcContext(InboundCall *call,
const google::protobuf::Message *request_pb,
-   google::protobuf::Message *response_pb,
-   scoped_refptr result_tracker)
+   google::protobuf::Message *response_pb)
   : call_(CHECK_NOTNULL(call)),
 request_pb_(request_pb),
-response_pb_(response_pb),
-result_tracker_(std::move(result_tracker)) {
+response_pb_(response_pb) {
   VLOG(4) << call_->remote_method().service_name() << ": Received RPC request 
for "
   << call_->ToString() << ":" << std::endl << 
SecureDebugString(*request_pb_);
   TRACE_EVENT_ASYNC_BEGIN2("rpc_call", "RPC", this,
@@ -64,6 +62,11 @@ RpcContext::RpcContext(InboundCall *call,
 RpcContext::~RpcContext() {
 }
 
+void RpcContext::SetResultTracker(scoped_refptr result_tracker) 
{
+  DCHECK(!result_tracker_);
+  result_tracker_ = std::move(result_tracker);
+}
+
 void RpcContext::RespondSuccess() {
   if (AreResultsTracked()) {
 result_tracker_->RecordCompletionAndRespond(call_->header().request_id(),

http://git-wip-us.apache.org/repos/asf/kudu/blob/e795d5a8/src/kudu/rpc/rpc_context.h
--
diff --git a/src/kudu/rpc/rpc_context.h b/src/kudu/rpc/rpc_context.h
index 1b12023..38ce703 100644
--- a/src/kudu/rpc/rpc_context.h
+++ b/src/kudu/rpc/rpc_context.h
@@ -69,11 +69,17 @@ class RpcContext {
   // and is not a public API.
   RpcContext(InboundCall *call,
  const google::protobuf::Message *request_pb,
- google::protobuf::Message *response_pb,
- scoped_refptr result_tracker);
+ google::protobuf::Message *response_pb);
 
   ~RpcContext();
 
+  // Initialize a result tracker for the RPC.
+  //
+  // This is delayed until after the constructor in order to allow for RPCs to
+  // be validated and used prior to initializing the tracking (primarily for
+  // authorization).
+  void SetResultTracker(scoped_refptr result_tracker);
+
   // Return the trace buffer for this call.
   Trace* trace();
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/e795d5a8/src/kudu/rpc/rpc_stub-test.cc
--
diff --git a/src/kudu/rpc/rpc_stub-test.cc b/src/kudu/rpc/rpc_stub-test.cc
index e626276..dc92f2e 100644
--- a/src/kudu/rpc/rpc_stub-test.cc
+++ b/src/kudu/rpc/rpc_stub-test.cc
@@ -209,13 +209,35 @@ TEST_F(RpcStubTest, TestAuthorization) {
 p.set_user_credentials(creds);
 
 // Alice is disallowed by all RPCs.
-RpcController controller;
-WhoAmIRequestPB req;
-WhoAmIResponsePB resp;
-Status s = p.WhoAmI(req, , );
-ASSERT_FALSE(s.ok());
-ASSERT_EQ(s.ToString(),
-  "Remote error: Not authorized: alice is not allowed to call this 
method");
+{
+  RpcController controller;
+  WhoAmIRequestPB req;
+  WhoAmIResponsePB resp;
+  Status s = p.WhoAmI(req, , );
+  ASSERT_FALSE(s.ok());
+  ASSERT_EQ(s.ToString(),
+"Remote error: Not 

[1/2] kudu git commit: [Java] Upgrade Dependencies

2018-08-14 Thread granthenke
Repository: kudu
Updated Branches:
  refs/heads/master c866f4762 -> 2d92370d9


[Java] Upgrade Dependencies

Upgrades the Java dependencies and Gradle versions.

Minor version upgrades:
- Guava 25.1-android -> 26.0-android

Maintenance version upgrades:
- Protobuf 3.6.0 -> 3.6.1

Gradle upgrades:
- SpotBugs 3.1.5 -> 3.1.6

Change-Id: I42637a2466ceea5de33b44fcda2fe7086d9dd79e
Reviewed-on: http://gerrit.cloudera.org:8080/11213
Reviewed-by: Adar Dembo 
Tested-by: Kudu Jenkins


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/2cbddb3c
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/2cbddb3c
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/2cbddb3c

Branch: refs/heads/master
Commit: 2cbddb3ca4c13519e3582c1cf6c40b7a8b82913a
Parents: c866f47
Author: Grant Henke 
Authored: Tue Aug 14 12:42:44 2018 -0500
Committer: Grant Henke 
Committed: Tue Aug 14 19:53:29 2018 +

--
 java/gradle/dependencies.gradle | 6 +++---
 java/pom.xml| 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/kudu/blob/2cbddb3c/java/gradle/dependencies.gradle
--
diff --git a/java/gradle/dependencies.gradle b/java/gradle/dependencies.gradle
index d5401b9..5384599 100755
--- a/java/gradle/dependencies.gradle
+++ b/java/gradle/dependencies.gradle
@@ -35,7 +35,7 @@ versions += [
 gradle : "4.9",
 // We use the android version instead of the jre version
 // to maintain Java 1.7 compatibility.
-guava  : "25.1-android",
+guava  : "26.0-android",
 hadoop : "3.1.0",
 hamcrest   : "1.3",
 hive   : "2.3.3",
@@ -48,14 +48,14 @@ versions += [
 netty  : "3.10.6.Final",
 parquet: "1.10.0",
 pmd: "5.8.1",
-protobuf   : "3.6.0",
+protobuf   : "3.6.1",
 scala  : "2.11.12",
 scalatest  : "3.0.5",
 scopt  : "3.7.0",
 slf4j  : "1.7.25",
 spark  : "2.3.1",
 sparkAvro  : "4.0.0",
-spotBugs   : "3.1.5",
+spotBugs   : "3.1.6",
 yetus  : "0.7.0"
 ]
 

http://git-wip-us.apache.org/repos/asf/kudu/blob/2cbddb3c/java/pom.xml
--
diff --git a/java/pom.xml b/java/pom.xml
index bf5bbaf..a234e3c 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -72,7 +72,7 @@
 2.6
 1.8.0
 
-25.1-android
+26.0-android
 3.1.0
 1.3
 2.3.3
@@ -84,7 +84,7 @@
 1.0.0
 3.10.6.Final
 1.10.0
-3.6.0
+3.6.1
 3.7.0
 1.7.25
 4.0.0



[2/2] kudu git commit: [gradle] Aggressively retry downloading the gradle wrapper jar

2018-08-14 Thread granthenke
[gradle] Aggressively retry downloading the gradle wrapper jar

When downloading the Gradle wrapper jar via curl
builds could fail because we didn’t retry. This patch
adds various ways to retry:

- Adds `—retry 3` to retry transient errors.
- Adds -L to handle when the requested page has
moved to a different location
- Adds -S to show the errors.
- Adds a manual retry loop to retry errors that
curl doesn’t think are transient.
- Replaces raw.githubusercontent.com usage with
a github.com raw url.

Change-Id: I85b0f9252dbb68b4f6f67c29f9ad02f145e084ba
Reviewed-on: http://gerrit.cloudera.org:8080/11214
Reviewed-by: Adar Dembo 
Tested-by: Grant Henke 


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/2d92370d
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/2d92370d
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/2d92370d

Branch: refs/heads/master
Commit: 2d92370d984d8277f1727cf108d3e6199fcca7ea
Parents: 2cbddb3
Author: Grant Henke 
Authored: Tue Aug 14 13:27:53 2018 -0500
Committer: Grant Henke 
Committed: Tue Aug 14 19:53:33 2018 +

--
 java/gradle/wrapper.gradle | 16 
 java/gradlew   | 14 +++---
 2 files changed, 23 insertions(+), 7 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/kudu/blob/2d92370d/java/gradle/wrapper.gradle
--
diff --git a/java/gradle/wrapper.gradle b/java/gradle/wrapper.gradle
index c57eac9..56071a5 100644
--- a/java/gradle/wrapper.gradle
+++ b/java/gradle/wrapper.gradle
@@ -52,13 +52,21 @@ task bootstrapWrapper() {
 // Add a trailing zero to the version if needed.
 def fullVersion = versions.gradle.count(".") == 1 ? "${versions.gradle}.0" 
: versions.gradle
 // Leverages the wrapper jar checked into the gradle project on github 
because the jar isn't available elsewhere.
-def wrapperBaseUrl = 
"https://raw.githubusercontent.com/gradle/gradle/v$fullVersion/gradle/wrapper;
+def wrapperBaseUrl = 
"https://github.com/gradle/gradle/raw/v$fullVersion/gradle/wrapper;
 def wrapperJarUrl = wrapperBaseUrl + "/gradle-wrapper.jar"
 
 def bootstrapString = """
-  if [ ! -e $wrapperJarPath ]; then
- curl -s -o $wrapperJarPath $wrapperJarUrl
-  fi
+  # Loop in case we encounter an error.
+  for attempt in 1 2 3; do
+if [ ! -e $wrapperJarPath ]; then
+  if ! curl -s -S --retry 3 -L -o "$wrapperJarPath" "$wrapperJarUrl"; 
then
+rm -f "$wrapperJarPath"
+# Pause for a bit before looping in case the server throttled us.
+sleep 5
+continue
+  fi
+fi
+  done
   """.stripIndent()
 
 def wrapperScript = wrapper.scriptFile

http://git-wip-us.apache.org/repos/asf/kudu/blob/2d92370d/java/gradlew
--
diff --git a/java/gradlew b/java/gradlew
index 0a5d168..3807ff4 100755
--- a/java/gradlew
+++ b/java/gradlew
@@ -79,9 +79,17 @@ case "`uname`" in
 esac
 
 
-if [ ! -e $APP_HOME/gradle/wrapper/gradle-wrapper.jar ]; then
-   curl -s -o $APP_HOME/gradle/wrapper/gradle-wrapper.jar 
https://raw.githubusercontent.com/gradle/gradle/v4.9.0/gradle/wrapper/gradle-wrapper.jar
-fi
+# Loop in case we encounter an error.
+for attempt in 1 2 3; do
+  if [ ! -e $APP_HOME/gradle/wrapper/gradle-wrapper.jar ]; then
+if ! curl -s -S --retry 3 -L -o 
"$APP_HOME/gradle/wrapper/gradle-wrapper.jar" 
"https://github.com/gradle/gradle/raw/v4.9.0/gradle/wrapper/gradle-wrapper.jar;;
 then
+  rm -f "$APP_HOME/gradle/wrapper/gradle-wrapper.jar"
+  # Pause for a bit before looping in case the server throttled us.
+  sleep 5
+  continue
+fi
+  fi
+done
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar