From 93c62ac0c3024d0262b8301fb7a2ebd171c3f4ef Mon Sep 17 00:00:00 2001
From: Renan DelValle <renanidelvalle+noreply@gmail.com>
Date: Thu, 12 Apr 2018 15:12:36 -0700
Subject: [PATCH 1/5] Removing port override as it is not needed

---
 examples/client.go |  3 ++-
 realis.go          | 36 +++++++++++++++++++++++++++++++-----
 zk.go              | 26 ++++++++++++++++++++------
 3 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/examples/client.go b/examples/client.go
index b2a57e5..01a9649 100644
--- a/examples/client.go
+++ b/examples/client.go
@@ -104,7 +104,8 @@ func main() {
 		fmt.Println("zkUrl: ", zkUrl)
 		clientOptions = append(clientOptions, realis.ZKUrl(zkUrl))
 	} else {
-		clientOptions = append(clientOptions, realis.SchedulerUrl(url))
+		clientOptions = append(clientOptions, realis.SchedulerUrl(url),
+			realis.ZookeeperOptions(realis.ZKAuroraPortOverride(2343), realis.ZKAuroraSchemeOverride("https")))
 	}
 
 	if caCertsPath != "" {
diff --git a/realis.go b/realis.go
index c9291d1..e94e1e7 100644
--- a/realis.go
+++ b/realis.go
@@ -26,6 +26,7 @@ import (
 	"net/http/cookiejar"
 	"os"
 	"path/filepath"
+	"strings"
 	"time"
 
 	"sync"
@@ -102,6 +103,7 @@ type RealisConfig struct {
 	clientkey, clientcert       string
 	options                     []ClientOption
 	debug                       bool
+	zkOptions                   []ZKOpt
 }
 
 var defaultBackoff = Backoff{
@@ -140,8 +142,15 @@ func ZKCluster(cluster *Cluster) ClientOption {
 }
 
 func ZKUrl(url string) ClientOption {
+
+	opts := []ZKOpt{ZKEndpoints(strings.Split(url, ",")...), ZKPath("/aurora/scheduler")}
+
 	return func(config *RealisConfig) {
-		config.cluster = GetDefaultClusterFromZKUrl(url)
+		if config.zkOptions == nil {
+			config.zkOptions = opts
+		} else {
+			config.zkOptions = append(config.zkOptions, opts...)
+		}
 	}
 }
 
@@ -187,6 +196,16 @@ func ClientCerts(clientKey, clientCert string) ClientOption {
 	}
 }
 
+// Use this option if you'd like to override default settings for connecting to Zookeeper.
+// For example, this can be used to override the port on which to communicate with Aurora.
+// This may be helpful if Aurora is behind another service and running on a port that is different
+// what is advertised in Zookeeper.
+func ZookeeperOptions(opts ...ZKOpt) ClientOption {
+	return func(config *RealisConfig) {
+		config.zkOptions = opts
+	}
+}
+
 // Using the word set to avoid name collision with Interface.
 func SetLogger(l Logger) ClientOption {
 	return func(config *RealisConfig) {
@@ -257,9 +276,16 @@ func NewRealisClient(options ...ClientOption) (Realis, error) {
 	var url string
 	var err error
 
-	// Determine how to get information to connect to the scheduler.
-	// Prioritize getting leader from ZK over using a direct URL.
-	if config.cluster != nil {
+	// Find the leader using custom Zookeeper options if options are provided
+	if config.zkOptions != nil {
+		url, err = LeaderFromZKOpts(config.zkOptions...)
+		if err != nil {
+			return nil, NewTemporaryError(errors.Wrap(err, "LeaderFromZK error"))
+		}
+		config.logger.Println("Scheduler URL from ZK: ", url)
+	} else if config.cluster != nil {
+		// Determine how to get information to connect to the scheduler.
+		// Prioritize getting leader from ZK over using a direct URL.
 		url, err = LeaderFromZK(*config.cluster)
 		// If ZK is configured, throw an error if the leader is unable to be determined
 		if err != nil {
@@ -270,7 +296,7 @@ func NewRealisClient(options ...ClientOption) (Realis, error) {
 		url = config.url
 		config.logger.Println("Scheduler URL: ", url)
 	} else {
-		return nil, errors.New("Incomplete Options -- url or cluster required")
+		return nil, errors.New("Incomplete Options -- url, cluster.json, or Zookeeper address required")
 	}
 
 	if config.jsonTransport {
diff --git a/zk.go b/zk.go
index dd711e0..838714c 100644
--- a/zk.go
+++ b/zk.go
@@ -36,11 +36,12 @@ type ServiceInstance struct {
 }
 
 type zkConfig struct {
-	endpoints []string
-	path      string
-	backoff   Backoff
-	timeout   time.Duration
-	logger    Logger
+	endpoints            []string
+	path                 string
+	backoff              Backoff
+	timeout              time.Duration
+	logger               Logger
+	auroraSchemeOverride *string
 }
 
 type ZKOpt func(z *zkConfig)
@@ -75,6 +76,12 @@ func ZKLogger(l Logger) ZKOpt {
 	}
 }
 
+func ZKAuroraSchemeOverride(scheme string) ZKOpt {
+	return func(z *zkConfig) {
+		z.auroraSchemeOverride = &scheme
+	}
+}
+
 // Retrieves current Aurora leader from ZK.
 func LeaderFromZK(cluster Cluster) (string, error) {
 	return LeaderFromZKOpts(ZKEndpoints(strings.Split(cluster.ZK, ",")...), ZKPath(cluster.SchedZKPath))
@@ -151,8 +158,15 @@ func LeaderFromZKOpts(options ...ZKOpt) (string, error) {
 
 				var scheme, host, port string
 				for k, v := range serviceInst.AdditionalEndpoints {
-					scheme = k
+
+					if config.auroraSchemeOverride == nil {
+						scheme = k
+					} else {
+						scheme = *config.auroraSchemeOverride
+					}
+
 					host = v.Host
+
 					port = strconv.Itoa(v.Port)
 				}
 

From 1e1b2e48b78982d08730999e70eda1ae8389952c Mon Sep 17 00:00:00 2001
From: Renan DelValle <renanidelvalle+noreply@gmail.com>
Date: Thu, 12 Apr 2018 15:22:25 -0700
Subject: [PATCH 2/5] Changing code comments to reflect getting rid of port
 override.

---
 examples/client.go | 3 +--
 realis.go          | 5 ++---
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/examples/client.go b/examples/client.go
index 01a9649..b2a57e5 100644
--- a/examples/client.go
+++ b/examples/client.go
@@ -104,8 +104,7 @@ func main() {
 		fmt.Println("zkUrl: ", zkUrl)
 		clientOptions = append(clientOptions, realis.ZKUrl(zkUrl))
 	} else {
-		clientOptions = append(clientOptions, realis.SchedulerUrl(url),
-			realis.ZookeeperOptions(realis.ZKAuroraPortOverride(2343), realis.ZKAuroraSchemeOverride("https")))
+		clientOptions = append(clientOptions, realis.SchedulerUrl(url))
 	}
 
 	if caCertsPath != "" {
diff --git a/realis.go b/realis.go
index e94e1e7..f1cb09f 100644
--- a/realis.go
+++ b/realis.go
@@ -197,9 +197,8 @@ func ClientCerts(clientKey, clientCert string) ClientOption {
 }
 
 // Use this option if you'd like to override default settings for connecting to Zookeeper.
-// For example, this can be used to override the port on which to communicate with Aurora.
-// This may be helpful if Aurora is behind another service and running on a port that is different
-// what is advertised in Zookeeper.
+// For example, this can be used to override the scheme to be used for communicating with Aurora (e.g. https).
+// See zk.go for what is possible to set as an option.
 func ZookeeperOptions(opts ...ZKOpt) ClientOption {
 	return func(config *RealisConfig) {
 		config.zkOptions = opts

From 280db21d3300644f2d6ddda5bb0663ec87dfa0e3 Mon Sep 17 00:00:00 2001
From: Renan DelValle <renanidelvalle+noreply@gmail.com>
Date: Thu, 12 Apr 2018 18:11:07 -0700
Subject: [PATCH 3/5] Adding port override back in.

---
 zk.go | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/zk.go b/zk.go
index 838714c..f930bd9 100644
--- a/zk.go
+++ b/zk.go
@@ -42,6 +42,7 @@ type zkConfig struct {
 	timeout              time.Duration
 	logger               Logger
 	auroraSchemeOverride *string
+	auroraPortOverride   *int
 }
 
 type ZKOpt func(z *zkConfig)
@@ -82,6 +83,12 @@ func ZKAuroraSchemeOverride(scheme string) ZKOpt {
 	}
 }
 
+func ZKAuroraPortOverride(port int) ZKOpt {
+	return func(z *zkConfig) {
+		z.auroraPortOverride = &port
+	}
+}
+
 // Retrieves current Aurora leader from ZK.
 func LeaderFromZK(cluster Cluster) (string, error) {
 	return LeaderFromZKOpts(ZKEndpoints(strings.Split(cluster.ZK, ",")...), ZKPath(cluster.SchedZKPath))
@@ -167,7 +174,11 @@ func LeaderFromZKOpts(options ...ZKOpt) (string, error) {
 
 					host = v.Host
 
-					port = strconv.Itoa(v.Port)
+					if config.auroraPortOverride == nil {
+						port = strconv.Itoa(v.Port)
+					} else {
+						port = strconv.Itoa(*config.auroraPortOverride)
+					}
 				}
 
 				leaderURL = scheme + "://" + host + ":" + port

From 40d832f536f6588f1f7050c191feead51e95d588 Mon Sep 17 00:00:00 2001
From: Renan DelValle <renanidelvalle+noreply@gmail.com>
Date: Wed, 30 May 2018 12:23:42 -0700
Subject: [PATCH 4/5] Removing port and schema override as these can be set
 from Aurora itself.

---
 zk.go | 39 +++++++--------------------------------
 1 file changed, 7 insertions(+), 32 deletions(-)

diff --git a/zk.go b/zk.go
index f930bd9..dd711e0 100644
--- a/zk.go
+++ b/zk.go
@@ -36,13 +36,11 @@ type ServiceInstance struct {
 }
 
 type zkConfig struct {
-	endpoints            []string
-	path                 string
-	backoff              Backoff
-	timeout              time.Duration
-	logger               Logger
-	auroraSchemeOverride *string
-	auroraPortOverride   *int
+	endpoints []string
+	path      string
+	backoff   Backoff
+	timeout   time.Duration
+	logger    Logger
 }
 
 type ZKOpt func(z *zkConfig)
@@ -77,18 +75,6 @@ func ZKLogger(l Logger) ZKOpt {
 	}
 }
 
-func ZKAuroraSchemeOverride(scheme string) ZKOpt {
-	return func(z *zkConfig) {
-		z.auroraSchemeOverride = &scheme
-	}
-}
-
-func ZKAuroraPortOverride(port int) ZKOpt {
-	return func(z *zkConfig) {
-		z.auroraPortOverride = &port
-	}
-}
-
 // Retrieves current Aurora leader from ZK.
 func LeaderFromZK(cluster Cluster) (string, error) {
 	return LeaderFromZKOpts(ZKEndpoints(strings.Split(cluster.ZK, ",")...), ZKPath(cluster.SchedZKPath))
@@ -165,20 +151,9 @@ func LeaderFromZKOpts(options ...ZKOpt) (string, error) {
 
 				var scheme, host, port string
 				for k, v := range serviceInst.AdditionalEndpoints {
-
-					if config.auroraSchemeOverride == nil {
-						scheme = k
-					} else {
-						scheme = *config.auroraSchemeOverride
-					}
-
+					scheme = k
 					host = v.Host
-
-					if config.auroraPortOverride == nil {
-						port = strconv.Itoa(v.Port)
-					} else {
-						port = strconv.Itoa(*config.auroraPortOverride)
-					}
+					port = strconv.Itoa(v.Port)
 				}
 
 				leaderURL = scheme + "://" + host + ":" + port

From 1bf341b815592176e4f949593a694fe6a4bf2f25 Mon Sep 17 00:00:00 2001
From: Renan DelValle <renanidelvalle+noreply@gmail.com>
Date: Wed, 30 May 2018 12:26:37 -0700
Subject: [PATCH 5/5] Changing comments to reflect current change.

---
 realis.go | 1 -
 1 file changed, 1 deletion(-)

diff --git a/realis.go b/realis.go
index f1cb09f..6b2c976 100644
--- a/realis.go
+++ b/realis.go
@@ -197,7 +197,6 @@ func ClientCerts(clientKey, clientCert string) ClientOption {
 }
 
 // Use this option if you'd like to override default settings for connecting to Zookeeper.
-// For example, this can be used to override the scheme to be used for communicating with Aurora (e.g. https).
 // See zk.go for what is possible to set as an option.
 func ZookeeperOptions(opts ...ZKOpt) ClientOption {
 	return func(config *RealisConfig) {