package mapping import ( "bytes" "encoding/json" "errors" "io" "io/ioutil" "net/http" "os" log "github.com/sirupsen/logrus" "github.com/spf13/viper" "iwarma.ru/console/correlator/config" ) type Component struct { Version int `json:"version"` Template map[string]interface{} `json:"template"` } type ComponentTemplate struct { Name string `json:"name"` Value Component `json:"component_template"` } type ComponentResponse struct { Templates []ComponentTemplate `json:"component_templates"` } type UpdateResponse struct { Acknowledged bool `json:"acknowledged"` } func ReadComponent(reader io.Reader) (Component, error) { byteValue, err := ioutil.ReadAll(reader) if err != nil { log.Errorf("Can't read component: %v", err) return Component{}, err } var result Component err = json.Unmarshal(byteValue, &result) if err != nil { log.Errorf("Can't unmarshall component: %v", err) return Component{}, err } return result, nil } func ReadComponentFromFile(fileName string) (Component, error) { file, err := os.Open(fileName) if err != nil { log.Errorf("Can't open file: %v", err) return Component{}, err } defer file.Close() return ReadComponent(file) } func ReadComponentResponse(reader io.Reader) (ComponentResponse, error) { byteValue, err := ioutil.ReadAll(reader) if err != nil { log.Errorf("Can't read component response: %v", err) return ComponentResponse{}, err } var result ComponentResponse err = json.Unmarshal(byteValue, &result) if err != nil { log.Errorf("Can't unmarshall component response: %v", err) return ComponentResponse{}, err } return result, nil } func ReadUpdateResponse(reader io.Reader) (UpdateResponse, error) { byteValue, err := ioutil.ReadAll(reader) if err != nil { log.Errorf("Can't read response: %v", err) return UpdateResponse{}, err } log.Debugf("Got server response: %v", string(byteValue)) var result UpdateResponse err = json.Unmarshal(byteValue, &result) if err != nil { log.Errorf("Can't unmarshall update response: %v", err) return UpdateResponse{}, err } return result, nil } func CheckComponentUpdate(url string, component Component) (bool, error) { // Get current mapping for component http_client := &http.Client{} req, err := http.NewRequest("GET", url, nil) if err != nil { log.Errorf("Can't create request to obtain component mapping version from server: %v", err) return false, err } // Set auth req.SetBasicAuth(viper.GetString(config.ElasticUsername), viper.GetString(config.ElasticPassword)) resp, err := http_client.Do(req) if err != nil { log.Errorf("Can't send request, to check component mapping on server: %v", err) return false, err } defer resp.Body.Close() responseComponent, err := ReadComponentResponse(resp.Body) if err != nil { log.Errorf("Can't parse component mapping response from server: %v", err) return false, err } // Now, check version max_version := 0 for _, cur := range responseComponent.Templates { if cur.Value.Version > max_version { max_version = cur.Value.Version } } log.Debugf("After checking %v versions, found max version %v, component version is %v", len(responseComponent.Templates), max_version, component.Version) return component.Version > max_version, nil } func UpdateComponent(url string, component Component) error { byteValue, err := json.Marshal(component) if err != nil { log.Errorf("Can't marshall component: %v", err) return err } buffer := bytes.NewBuffer(byteValue) req, err := http.NewRequest("PUT", url, buffer) if err != nil { log.Errorf("Can't create copmonent update request: %v", err) return err } req.SetBasicAuth(viper.GetString(config.ElasticUsername), viper.GetString(config.ElasticPassword)) req.Header.Add("Content-Type", "application/json") http_client := &http.Client{} resp, err := http_client.Do(req) if err != nil { log.Errorf("Can't send component update request: %v", err) return err } defer resp.Body.Close() response, err := ReadUpdateResponse(resp.Body) if err != nil { log.Errorf("Can't read server response: %v", err) return err } if response.Acknowledged != true { return errors.New("Server didn't accept component") } return nil }