github.com/Financial-Times/publish-availability-monitor@v1.12.0/content/content.go (about) 1 package content 2 3 import ( 4 "bytes" 5 "io" 6 "net/http" 7 8 "github.com/Financial-Times/go-logger/v2" 9 "github.com/Financial-Times/publish-availability-monitor/httpcaller" 10 ) 11 12 // Content is the interface for different type of contents from different CMSs. 13 type Content interface { 14 Initialize(binaryContent []byte) Content 15 Validate(externalValidationEndpoint, tid, username, password string, log *logger.UPPLogger) ValidationResponse 16 GetType() string 17 GetUUID() string 18 } 19 20 type ValidationResponse struct { 21 IsValid bool 22 IsMarkedDeleted bool 23 } 24 25 type validationParam struct { 26 binaryContent []byte 27 validationURL string 28 username string 29 password string 30 tid string 31 uuid string 32 contentType string 33 isGenericPublish bool 34 } 35 36 var httpCaller httpcaller.Caller 37 38 func init() { 39 httpCaller = httpcaller.NewCaller(10) 40 } 41 42 func doExternalValidation(p validationParam, validCheck func(int) bool, deletedCheck func(...int) bool, log *logger.UPPLogger) ValidationResponse { 43 logEntry := log.WithUUID(p.uuid).WithTransactionID(p.tid) 44 45 if p.validationURL == "" { 46 logEntry.Warnf("External validation for content. Validation endpoint URL is missing for content type=[%s]", p.contentType) 47 return ValidationResponse{false, deletedCheck()} 48 } 49 50 logEntry = logEntry.WithField("validation_url", p.validationURL) 51 52 contentType := "application/json" 53 if p.isGenericPublish { 54 contentType = p.contentType 55 } 56 57 resp, err := httpCaller.DoCall(httpcaller.Config{ 58 HTTPMethod: "POST", 59 URL: p.validationURL, 60 Username: p.username, 61 Password: p.password, 62 TID: httpcaller.ConstructPamTID(p.tid), 63 ContentType: contentType, 64 Entity: bytes.NewReader(p.binaryContent), 65 }) 66 67 if err != nil { 68 logEntry.WithError(err).Warn("External validation for content failed while creating validation request. Skipping external validation.") 69 return ValidationResponse{true, deletedCheck()} 70 } 71 defer resp.Body.Close() 72 73 logEntry.Infof("External validation received statusCode [%d]", resp.StatusCode) 74 75 bs, err := io.ReadAll(resp.Body) 76 if err != nil { 77 logEntry.WithError(err).Warn("External validation reading response body error") 78 } 79 80 if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNotFound { 81 logEntry.Infof("External validation received statusCode [%d], received error: [%v]", resp.StatusCode, string(bs)) 82 } 83 84 if resp.StatusCode == http.StatusNotFound { 85 logEntry.Infof("External validation received statusCode [%d], content is marked as deleted.", resp.StatusCode) 86 } 87 88 return ValidationResponse{validCheck(resp.StatusCode), deletedCheck(resp.StatusCode)} 89 }