Merge pull request #48 from 30x/oss

G OSS policy
diff --git a/apigee_sync_test.go b/apigee_sync_test.go
index a705f86..94fa16e 100644
--- a/apigee_sync_test.go
+++ b/apigee_sync_test.go
@@ -310,7 +310,7 @@
 
 			scopes := []string{apidInfo.ClusterID}
 			snapshot := &common.Snapshot{}
-			apidSnapshotManager.downloadSnapshot(scopes, snapshot)
+			apidSnapshotManager.downloadSnapshot(true, scopes, snapshot)
 			apidSnapshotManager.storeBootSnapshot(snapshot)
 			apidSnapshotManager.storeDataSnapshot(snapshot)
 			restoreContext()
diff --git a/change_test.go b/change_test.go
index 1619bc6..4a1981b 100644
--- a/change_test.go
+++ b/change_test.go
@@ -211,6 +211,6 @@
 
 }
 
-func (s *dummySnapshotManager) downloadSnapshot(scopes []string, snapshot *common.Snapshot) error {
+func (s *dummySnapshotManager) downloadSnapshot(isBoot bool, scopes []string, snapshot *common.Snapshot) error {
 	return nil
 }
diff --git a/managerInterfaces.go b/managerInterfaces.go
index 7205613..ae80cec 100644
--- a/managerInterfaces.go
+++ b/managerInterfaces.go
@@ -34,7 +34,7 @@
 	storeBootSnapshot(snapshot *common.Snapshot)
 	downloadDataSnapshot()
 	storeDataSnapshot(snapshot *common.Snapshot)
-	downloadSnapshot(scopes []string, snapshot *common.Snapshot) error
+	downloadSnapshot(isBoot bool, scopes []string, snapshot *common.Snapshot) error
 }
 
 type changeManager interface {
diff --git a/snapshot.go b/snapshot.go
index f390cfb..b7a089d 100644
--- a/snapshot.go
+++ b/snapshot.go
@@ -94,7 +94,7 @@
 	scopes := []string{apidInfo.ClusterID}
 	snapshot := &common.Snapshot{}
 
-	err := s.downloadSnapshot(scopes, snapshot)
+	err := s.downloadSnapshot(true, scopes, snapshot)
 	if err != nil {
 		// this may happen during shutdown
 		if _, ok := err.(quitSignalError); ok {
@@ -135,7 +135,7 @@
 	scopes := findScopesForId(apidInfo.ClusterID)
 	scopes = append(scopes, apidInfo.ClusterID)
 	snapshot := &common.Snapshot{}
-	err := s.downloadSnapshot(scopes, snapshot)
+	err := s.downloadSnapshot(false, scopes, snapshot)
 	if err != nil {
 		// this may happen during shutdown
 		if _, ok := err.(quitSignalError); ok {
@@ -246,7 +246,7 @@
 // a blocking method
 // will keep retrying with backoff until success
 
-func (s *simpleSnapShotManager) downloadSnapshot(scopes []string, snapshot *common.Snapshot) error {
+func (s *simpleSnapShotManager) downloadSnapshot(isBoot bool, scopes []string, snapshot *common.Snapshot) error {
 	// if closed
 	if atomic.LoadInt32(s.isClosed) == int32(1) {
 		log.Warn("Trying to download snapshot with a closed snapShotManager")
@@ -272,13 +272,15 @@
 
 	//pollWithBackoff only accepts function that accept a single quit channel
 	//to accommodate functions which need more parameters, wrap them in closures
-	attemptDownload := getAttemptDownloadClosure(snapshot, uri)
+	attemptDownload := getAttemptDownloadClosure(isBoot, snapshot, uri)
 	pollWithBackoff(s.quitChan, attemptDownload, handleSnapshotServerError)
 	return nil
 }
 
-func getAttemptDownloadClosure(snapshot *common.Snapshot, uri string) func(chan bool) error {
+func getAttemptDownloadClosure(isBoot bool, snapshot *common.Snapshot, uri string) func(chan bool) error {
 	return func(_ chan bool) error {
+
+		var tid string
 		req, err := http.NewRequest("GET", uri, nil)
 		if err != nil {
 			// should never happen, but if it does, it's unrecoverable anyway
@@ -310,8 +312,16 @@
 			return expected200Error{}
 		}
 
+		// Bootstrap scope is a special case, that can occur only once. The tid is
+		// hardcoded to "bootstrap" to ensure there can be no clash of tid between
+		// bootstrap and subsequent data scopes.
+		if isBoot {
+			tid = "bootstrap"
+		} else {
+			tid = r.Header.Get("Transicator-Snapshot-TXID")
+		}
 		// Decode the Snapshot server response
-		err = processSnapshotResponse(r.Header.Get("Transicator-Snapshot-TXID"), r.Body, snapshot)
+		err = processSnapshotResponse(tid, r.Body, snapshot)
 		if err != nil {
 			log.Errorf("Snapshot server response Data not parsable: %v", err)
 			return err