| // Copyright 2017 Google Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package apidAnalytics |
| |
| import ( |
| "github.com/apid/apid-core" |
| "net/http" |
| "strings" |
| ) |
| |
| var analyticsBasePath string |
| |
| type errResponse struct { |
| ErrorCode string `json:"errorCode"` |
| Reason string `json:"reason"` |
| } |
| |
| type dbError struct { |
| ErrorCode string `json:"errorCode"` |
| Reason string `json:"reason"` |
| } |
| |
| func initAPI(services apid.Services) { |
| log.Debug("initialized API's exposed by apidAnalytics plugin") |
| analyticsBasePath = config.GetString(configAnalyticsBasePath) |
| services.API().HandleFunc(analyticsBasePath+"/{bundle_scope_uuid}", |
| saveAnalyticsRecord).Methods("POST") |
| services.API().HandleFunc(analyticsBasePath, |
| processAnalyticsRecord).Methods("POST") |
| } |
| |
| func saveAnalyticsRecord(w http.ResponseWriter, r *http.Request) { |
| |
| w.Header().Set("Content-Type", "application/json; charset=UTF-8") |
| |
| db := getDB() // When database isnt initialized |
| if db == nil { |
| writeError(w, http.StatusInternalServerError, |
| "INTERNAL_SERVER_ERROR", |
| "Service is not initialized completely") |
| return |
| } |
| |
| if !strings.EqualFold(r.Header.Get("Content-Type"), "application/json") { |
| writeError(w, http.StatusBadRequest, "UNSUPPORTED_CONTENT_TYPE", |
| "Only supported content type is application/json") |
| return |
| } |
| |
| vars := apid.API().Vars(r) |
| scopeuuid := vars["bundle_scope_uuid"] |
| tenant, dbErr := getTenantForScope(scopeuuid) |
| if dbErr.ErrorCode != "" { |
| switch dbErr.ErrorCode { |
| case "INTERNAL_SEARCH_ERROR": |
| writeError(w, http.StatusInternalServerError, |
| "INTERNAL_SEARCH_ERROR", dbErr.Reason) |
| case "UNKNOWN_SCOPE": |
| writeError(w, http.StatusBadRequest, |
| "UNKNOWN_SCOPE", dbErr.Reason) |
| } |
| } else { |
| body, err := getJsonBody(r) |
| if err.ErrorCode == "" { |
| err = validateEnrichPublish(tenant, body) |
| if err.ErrorCode == "" { |
| w.WriteHeader(http.StatusOK) |
| return |
| } |
| } |
| writeError(w, http.StatusBadRequest, err.ErrorCode, err.Reason) |
| } |
| } |
| |
| func processAnalyticsRecord(w http.ResponseWriter, r *http.Request) { |
| |
| w.Header().Set("Content-Type", "application/json; charset=UTF-8") |
| |
| db := getDB() // When database isnt initialized |
| if db == nil { |
| writeError(w, http.StatusInternalServerError, |
| "INTERNAL_SERVER_ERROR", |
| "Service is not initialized completely") |
| return |
| } |
| |
| if !strings.EqualFold(r.Header.Get("Content-Type"), "application/json") { |
| writeError(w, http.StatusBadRequest, "UNSUPPORTED_CONTENT_TYPE", |
| "Only supported content type is application/json") |
| return |
| } |
| |
| body, err := getJsonBody(r) |
| if err.ErrorCode == "" { |
| tenant, e := getTenantFromPayload(body) |
| if e.ErrorCode == "" { |
| _, dbErr := validateTenant(tenant) |
| if dbErr.ErrorCode != "" { |
| switch dbErr.ErrorCode { |
| case "INTERNAL_SEARCH_ERROR": |
| writeError(w, http.StatusInternalServerError, |
| "INTERNAL_SEARCH_ERROR", dbErr.Reason) |
| case "UNKNOWN_SCOPE": |
| writeError(w, http.StatusBadRequest, |
| "UNKNOWN_SCOPE", dbErr.Reason) |
| } |
| return |
| } else { |
| err = validateEnrichPublish(tenant, body) |
| if err.ErrorCode == "" { |
| w.WriteHeader(http.StatusOK) |
| return |
| } |
| } |
| } else { |
| writeError(w, http.StatusBadRequest, |
| e.ErrorCode, e.Reason) |
| return |
| } |
| } |
| writeError(w, http.StatusBadRequest, err.ErrorCode, err.Reason) |
| } |