Merge pull request #20 from 30x/XAPID-892

Xapid 892 - make  apid get deployments return ISO8601 time format
diff --git a/api.go b/api.go
index 010e872..972b8eb 100644
--- a/api.go
+++ b/api.go
@@ -31,6 +31,11 @@
 	API_ERR_INTERNAL
 )
 
+const (
+	sqlTimeFormat = "2006-01-02 15:04:05.999 -0700 MST"
+	iso8601       = "2006-01-02T15:04:05.999Z07:00"
+)
+
 type deploymentsResult struct {
 	deployments []DataDeployment
 	err         error
@@ -246,9 +251,9 @@
 		apiDeps = append(apiDeps, ApiDeployment{
 			ID:               d.ID,
 			ScopeId:          d.DataScopeID,
-			Created:          d.Created,
+			Created:          convertTime(d.Created),
 			CreatedBy:        d.CreatedBy,
-			Updated:          d.Updated,
+			Updated:          convertTime(d.Updated),
 			UpdatedBy:        d.UpdatedBy,
 			BundleConfigJson: []byte(d.BundleConfigJSON),
 			ConfigJson:       []byte(d.ConfigJSON),
@@ -382,3 +387,18 @@
 	e := atomic.LoadInt64(&eTag)
 	return strconv.FormatInt(e, 10)
 }
+
+func convertTime(t string) string {
+	if t == "" {
+		return ""
+	}
+	formats := []string{sqlTimeFormat, iso8601, time.RFC3339}
+	for _, f := range formats {
+		timestamp, err := time.Parse(f, t)
+		if err == nil {
+			return timestamp.Format(iso8601)
+		}
+	}
+	log.Panic("convertTime: Unsupported time format: " + t)
+	return ""
+}
diff --git a/api_test.go b/api_test.go
index 665074e..c6acd5e 100644
--- a/api_test.go
+++ b/api_test.go
@@ -11,6 +11,7 @@
 
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
+	"strconv"
 )
 
 var _ = Describe("api", func() {
@@ -361,6 +362,37 @@
 
 			Expect(uploaded).To(Equal(deploymentResults))
 		})
+
+		It("should get iso8601 time", func() {
+			testTimes := []string{"", "2017-04-05 04:47:36.462 +0000 UTC", "2017-04-05 04:47:36.462 -0700 MST", "2017-04-05T04:47:36.462Z", "2017-04-05T04:47:36.462-07:00"}
+			isoTime := []string{"", "2017-04-05T04:47:36.462Z", "2017-04-05T04:47:36.462-07:00", "2017-04-05T04:47:36.462Z", "2017-04-05T04:47:36.462-07:00"}
+			for i, t := range testTimes {
+				log.Debug("insert deployment with timestamp: " + t)
+				deploymentID := "api_time_iso8601_" + strconv.Itoa(i)
+				insertTimeDeployment(testServer, deploymentID, t)
+			}
+
+			uri, err := url.Parse(testServer.URL)
+			uri.Path = deploymentsEndpoint
+
+			res, err := http.Get(uri.String())
+			Expect(err).ShouldNot(HaveOccurred())
+			defer res.Body.Close()
+
+			Expect(res.StatusCode).Should(Equal(http.StatusOK))
+
+			var depRes ApiDeploymentResponse
+			body, err := ioutil.ReadAll(res.Body)
+			Expect(err).ShouldNot(HaveOccurred())
+			json.Unmarshal(body, &depRes)
+
+			Expect(len(depRes)).To(Equal(len(testTimes)))
+
+			for i, dep := range depRes {
+				Expect(dep.Created).To(Equal(isoTime[i]))
+				Expect(dep.Updated).To(Equal(isoTime[i]))
+			}
+		})
 	})
 })
 
@@ -410,3 +442,50 @@
 	err = tx.Commit()
 	Expect(err).ShouldNot(HaveOccurred())
 }
+
+func insertTimeDeployment(testServer *httptest.Server, deploymentID string, timestamp string) {
+
+	uri, err := url.Parse(testServer.URL)
+	Expect(err).ShouldNot(HaveOccurred())
+
+	uri.Path = "/bundles/1"
+	bundleUri := uri.String()
+	bundle := bundleConfigJson{
+		Name:         uri.Path,
+		URI:          bundleUri,
+		ChecksumType: "crc32",
+	}
+	bundle.Checksum = testGetChecksum(bundle.ChecksumType, bundleUri)
+	bundleJson, err := json.Marshal(bundle)
+	Expect(err).ShouldNot(HaveOccurred())
+
+	tx, err := getDB().Begin()
+	Expect(err).ShouldNot(HaveOccurred())
+
+	dep := DataDeployment{
+		ID:                 deploymentID,
+		BundleConfigID:     deploymentID,
+		ApidClusterID:      deploymentID,
+		DataScopeID:        deploymentID,
+		BundleConfigJSON:   string(bundleJson),
+		ConfigJSON:         string(bundleJson),
+		Created:            timestamp,
+		CreatedBy:          "",
+		Updated:            timestamp,
+		UpdatedBy:          "",
+		BundleName:         deploymentID,
+		BundleURI:          bundle.URI,
+		BundleChecksum:     bundle.Checksum,
+		BundleChecksumType: bundle.ChecksumType,
+		LocalBundleURI:     "x",
+		DeployStatus:       "",
+		DeployErrorCode:    0,
+		DeployErrorMessage: "",
+	}
+
+	err = InsertDeployment(tx, dep)
+	Expect(err).ShouldNot(HaveOccurred())
+
+	err = tx.Commit()
+	Expect(err).ShouldNot(HaveOccurred())
+}