github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/cmd/integrationArtifactGetMplStatus.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 "io" 6 "net/http" 7 "net/url" 8 9 "github.com/Jeffail/gabs/v2" 10 "github.com/ouraigua/jenkins-library/pkg/cpi" 11 piperhttp "github.com/ouraigua/jenkins-library/pkg/http" 12 "github.com/ouraigua/jenkins-library/pkg/log" 13 "github.com/ouraigua/jenkins-library/pkg/telemetry" 14 "github.com/pkg/errors" 15 ) 16 17 func integrationArtifactGetMplStatus(config integrationArtifactGetMplStatusOptions, telemetryData *telemetry.CustomData, commonPipelineEnvironment *integrationArtifactGetMplStatusCommonPipelineEnvironment) { 18 // Utils can be used wherever the command.ExecRunner interface is expected. 19 // It can also be used for example as a mavenExecRunner. 20 httpClient := &piperhttp.Client{} 21 // For HTTP calls import piperhttp "github.com/SAP/jenkins-library/pkg/http" 22 // and use a &piperhttp.Client{} in a custom system 23 // Example: step checkmarxExecuteScan.go 24 25 // Error situations should be bubbled up until they reach the line below which will then stop execution 26 // through the log.Entry().Fatal() call leading to an os.Exit(1) in the end. 27 err := runIntegrationArtifactGetMplStatus(&config, telemetryData, httpClient, commonPipelineEnvironment) 28 if err != nil { 29 log.Entry().WithError(err).Fatal("step execution failed") 30 } 31 } 32 33 func runIntegrationArtifactGetMplStatus( 34 config *integrationArtifactGetMplStatusOptions, 35 telemetryData *telemetry.CustomData, 36 httpClient piperhttp.Sender, 37 commonPipelineEnvironment *integrationArtifactGetMplStatusCommonPipelineEnvironment) error { 38 39 serviceKey, err := cpi.ReadCpiServiceKey(config.APIServiceKey) 40 if err != nil { 41 return err 42 } 43 44 clientOptions := piperhttp.ClientOptions{} 45 httpClient.SetOptions(clientOptions) 46 header := make(http.Header) 47 header.Add("Accept", "application/json") 48 mplStatusEncodedURL := fmt.Sprintf("%s/api/v1/MessageProcessingLogs?$filter=IntegrationArtifact/Id"+url.QueryEscape(" eq ")+"'%s'"+ 49 url.QueryEscape(" and Status ne ")+"'DISCARDED'"+"&$orderby="+url.QueryEscape("LogEnd desc")+"&$top=1", serviceKey.OAuth.Host, config.IntegrationFlowID) 50 tokenParameters := cpi.TokenParameters{TokenURL: serviceKey.OAuth.OAuthTokenProviderURL, Username: serviceKey.OAuth.ClientID, Password: serviceKey.OAuth.ClientSecret, Client: httpClient} 51 token, err := cpi.CommonUtils.GetBearerToken(tokenParameters) 52 if err != nil { 53 return errors.Wrap(err, "failed to fetch Bearer Token") 54 } 55 clientOptions.Token = fmt.Sprintf("Bearer %s", token) 56 httpClient.SetOptions(clientOptions) 57 httpMethod := "GET" 58 mplStatusResp, httpErr := httpClient.SendRequest(httpMethod, mplStatusEncodedURL, nil, header, nil) 59 if httpErr != nil { 60 return errors.Wrapf(httpErr, "HTTP %v request to %v failed with error", httpMethod, mplStatusEncodedURL) 61 } 62 63 if mplStatusResp != nil && mplStatusResp.Body != nil { 64 defer mplStatusResp.Body.Close() 65 } 66 67 if mplStatusResp == nil { 68 return errors.Errorf("did not retrieve a HTTP response: %v", httpErr) 69 } 70 71 if mplStatusResp.StatusCode == 200 { 72 bodyText, readErr := io.ReadAll(mplStatusResp.Body) 73 if readErr != nil { 74 return errors.Wrap(readErr, "HTTP response body could not be read") 75 } 76 jsonResponse, parsingErr := gabs.ParseJSON([]byte(bodyText)) 77 if parsingErr != nil { 78 return errors.Wrapf(parsingErr, "HTTP response body could not be parsed as JSON: %v", string(bodyText)) 79 } 80 if jsonResponse == nil { 81 return errors.Errorf("Empty json response: %v", string(bodyText)) 82 } 83 if jsonResponse.Exists("d", "results", "0") { 84 mplStatus := jsonResponse.Path("d.results.0.Status").Data().(string) 85 commonPipelineEnvironment.custom.integrationFlowMplStatus = mplStatus 86 87 //if error, then return immediately with the error details 88 if mplStatus == "FAILED" { 89 mplID := jsonResponse.Path("d.results.0.MessageGuid").Data().(string) 90 resp, err := getIntegrationArtifactMPLError(commonPipelineEnvironment, mplID, httpClient, serviceKey.OAuth.Host) 91 if err != nil { 92 return err 93 } 94 return errors.New(resp) 95 } 96 } 97 return nil 98 } 99 responseBody, readErr := io.ReadAll(mplStatusResp.Body) 100 101 if readErr != nil { 102 return errors.Wrapf(readErr, "HTTP response body could not be read, Response status code: %v", mplStatusResp.StatusCode) 103 } 104 105 log.Entry().Errorf("a HTTP error occurred! Response body: %v, Response status code: %v", string(responseBody), mplStatusResp.StatusCode) 106 return errors.Errorf("Unable to get integration flow MPL status, Response Status code: %v", mplStatusResp.StatusCode) 107 } 108 109 // getIntegrationArtifactMPLError - Get integration artifact MPL error details 110 func getIntegrationArtifactMPLError(commonPipelineEnvironment *integrationArtifactGetMplStatusCommonPipelineEnvironment, mplID string, httpClient piperhttp.Sender, apiHost string) (string, error) { 111 httpMethod := "GET" 112 header := make(http.Header) 113 header.Add("content-type", "application/json") 114 errorStatusURL := fmt.Sprintf("%s/api/v1/MessageProcessingLogs('%s')/ErrorInformation/$value", apiHost, mplID) 115 errorStatusResp, httpErr := httpClient.SendRequest(httpMethod, errorStatusURL, nil, header, nil) 116 117 if errorStatusResp != nil && errorStatusResp.Body != nil { 118 defer errorStatusResp.Body.Close() 119 } 120 121 if errorStatusResp == nil { 122 return "", errors.Errorf("did not retrieve a HTTP response: %v", httpErr) 123 } 124 125 if errorStatusResp.StatusCode == http.StatusOK { 126 log.Entry(). 127 WithField("MPLID", mplID). 128 Info("Successfully retrieved Integration Flow artefact message processing error") 129 responseBody, readErr := io.ReadAll(errorStatusResp.Body) 130 if readErr != nil { 131 return "", errors.Wrapf(readErr, "HTTP response body could not be read, response status code: %v", errorStatusResp.StatusCode) 132 } 133 mplErrorDetails := string(responseBody) 134 commonPipelineEnvironment.custom.integrationFlowMplError = mplErrorDetails 135 return mplErrorDetails, nil 136 } 137 if httpErr != nil { 138 return getHTTPErrorMessage(httpErr, errorStatusResp, httpMethod, errorStatusURL) 139 } 140 return "", errors.Errorf("failed to get Integration Flow artefact message processing error, response Status code: %v", errorStatusResp.StatusCode) 141 }