-
Notifications
You must be signed in to change notification settings - Fork 582
/
commonUtils.go
221 lines (193 loc) · 7.8 KB
/
commonUtils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
package cpi
import (
"encoding/json"
"fmt"
"io"
"mime"
"net/http"
"os"
"path/filepath"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/Jeffail/gabs/v2"
piperhttp "github.com/SAP/jenkins-library/pkg/http"
"github.com/pkg/errors"
)
// CommonUtils for CPI
type CommonUtils interface {
GetBearerToken() (string, error)
}
// HttpCPIUtils for CPI
type HttpCPIUtils interface {
HandleHTTPFileDownloadResponse() error
}
// HTTPUploadUtils for CPI
type HTTPUploadUtils interface {
HandleHTTPFileUploadResponse() error
HandleHTTPGetRequestResponse() (string, error)
}
// TokenParameters struct
type TokenParameters struct {
TokenURL, Username, Password string
Client piperhttp.Sender
}
// HttpParameters struct
type HttpFileDownloadRequestParameters struct {
ErrMessage, FileDownloadPath string
Response *http.Response
}
// HTTPFileUploadRequestParameters struct
type HttpFileUploadRequestParameters struct {
ErrMessage, FilePath, HTTPMethod, HTTPURL, SuccessMessage string
Response *http.Response
HTTPErr error
}
// ServiceKey contains information about a CPI service key
type ServiceKey struct {
OAuth OAuth `json:"oauth"`
}
// OAuth is inside a CPI service key and contains more needed information
type OAuth struct {
Host string `json:"url"`
OAuthTokenProviderURL string `json:"tokenurl"`
ClientID string `json:"clientid"`
ClientSecret string `json:"clientsecret"`
}
// ReadCpiServiceKey unmarshalls the give json service key string.
func ReadCpiServiceKey(serviceKeyJSON string) (cpiServiceKey ServiceKey, err error) {
// parse
err = json.Unmarshal([]byte(serviceKeyJSON), &cpiServiceKey)
if err != nil {
err = errors.Wrap(err, "error unmarshalling serviceKey")
return
}
log.Entry().Info("CPI serviceKey read successfully")
return
}
// GetBearerToken -Provides the bearer token for making CPI OData calls
func (tokenParameters TokenParameters) GetBearerToken() (string, error) {
httpClient := tokenParameters.Client
clientOptions := piperhttp.ClientOptions{
Username: tokenParameters.Username,
Password: tokenParameters.Password,
}
httpClient.SetOptions(clientOptions)
header := make(http.Header)
header.Add("Accept", "application/json")
tokenFinalURL := fmt.Sprintf("%s?grant_type=client_credentials", tokenParameters.TokenURL)
method := "POST"
resp, httpErr := httpClient.SendRequest(method, tokenFinalURL, nil, header, nil)
if httpErr != nil {
return "", errors.Wrapf(httpErr, "HTTP %v request to %v failed with error", method, tokenFinalURL)
}
if resp != nil && resp.Body != nil {
defer resp.Body.Close()
}
if resp == nil {
return "", errors.Errorf("did not retrieve a HTTP response")
}
if resp.StatusCode != 200 {
return "", errors.Errorf("did not retrieve a valid HTTP response code: %v", httpErr)
}
bodyText, readErr := io.ReadAll(resp.Body)
if readErr != nil {
return "", errors.Wrap(readErr, "HTTP response body could not be read")
}
jsonResponse, parsingErr := gabs.ParseJSON([]byte(bodyText))
if parsingErr != nil {
return "", errors.Wrapf(parsingErr, "HTTP response body could not be parsed as JSON: %v", string(bodyText))
}
token := jsonResponse.Path("access_token").Data().(string)
return token, nil
}
// HandleHTTPFileDownloadResponse - Handle the file download response for http multipart response
func (httpFileDownloadRequestParameters HttpFileDownloadRequestParameters) HandleHTTPFileDownloadResponse() error {
response := httpFileDownloadRequestParameters.Response
contentDisposition := response.Header.Get("Content-Disposition")
disposition, params, err := mime.ParseMediaType(contentDisposition)
if err != nil {
return errors.Wrapf(err, "failed to read filename from http response headers, Content-Disposition %s", disposition)
}
filename := params["filename"]
if response != nil && response.Body != nil {
defer response.Body.Close()
}
if response.StatusCode == 200 {
workspaceRelativePath := httpFileDownloadRequestParameters.FileDownloadPath
err = os.MkdirAll(workspaceRelativePath, 0755)
// handling error while creating a workspce directoy for file download, if one not exist already!
if err != nil {
return errors.Wrapf(err, "Failed to create workspace directory")
}
zipFileName := filepath.Join(workspaceRelativePath, filename)
file, err := os.Create(zipFileName)
// handling error while creating a file in the filesystem
if err != nil {
return errors.Wrap(err, "failed to create zip archive of api proxy")
}
_, err = io.Copy(file, response.Body)
if err != nil {
return err
}
return nil
}
responseBody, readErr := io.ReadAll(response.Body)
if readErr != nil {
return errors.Wrapf(readErr, "HTTP response body could not be read, Response status code: %v", response.StatusCode)
}
log.Entry().Errorf("a HTTP error occurred! Response body: %v, Response status code : %v", responseBody, response.StatusCode)
return errors.Errorf("%s, Response Status code: %v", httpFileDownloadRequestParameters.ErrMessage, response.StatusCode)
}
// HandleHTTPFileUploadResponse - Handle the file upload response
func (httpFileUploadRequestParameters HttpFileUploadRequestParameters) HandleHTTPFileUploadResponse() error {
response := httpFileUploadRequestParameters.Response
httpErr := httpFileUploadRequestParameters.HTTPErr
if response != nil && response.Body != nil {
defer response.Body.Close()
}
if response == nil {
return errors.Errorf("did not retrieve a HTTP response: %v", httpErr)
}
responseCode := response.StatusCode
if (responseCode == http.StatusOK) || (responseCode == http.StatusCreated) {
log.Entry().
WithField("Created Artifact", httpFileUploadRequestParameters.FilePath).
Info(httpFileUploadRequestParameters.SuccessMessage)
return nil
}
if httpErr != nil {
responseBody, readErr := io.ReadAll(response.Body)
if readErr != nil {
return errors.Wrapf(readErr, "HTTP response body could not be read, Response status code: %v", response.StatusCode)
}
log.Entry().Errorf("a HTTP error occurred! Response body: %v, Response status code: %v", string(responseBody), response.StatusCode)
return errors.Wrapf(httpErr, "HTTP %v request to %v failed with error: %v", httpFileUploadRequestParameters.HTTPMethod, httpFileUploadRequestParameters.HTTPURL, string(responseBody))
}
return errors.Errorf("%s, Response Status code: %v", httpFileUploadRequestParameters.ErrMessage, response.StatusCode)
}
// HandleHTTPGetRequestResponse - Handle the GET Request response data
func (httpGetRequestParameters HttpFileUploadRequestParameters) HandleHTTPGetRequestResponse() (string, error) {
response := httpGetRequestParameters.Response
httpErr := httpGetRequestParameters.HTTPErr
if response != nil && response.Body != nil {
defer response.Body.Close()
}
if response == nil {
return "", errors.Errorf("did not retrieve a HTTP response: %v", httpErr)
}
if response.StatusCode == http.StatusOK {
responseBody, readErr := io.ReadAll(response.Body)
if readErr != nil {
return "", errors.Wrapf(readErr, "HTTP response body could not be read, response status code: %v", response.StatusCode)
}
return string(responseBody), nil
}
if httpErr != nil {
responseBody, readErr := io.ReadAll(response.Body)
if readErr != nil {
return "", errors.Wrapf(readErr, "HTTP response body could not be read, Response status code: %v", response.StatusCode)
}
log.Entry().Errorf("a HTTP error occurred! Response body: %v, Response status code: %v", string(responseBody), response.StatusCode)
return "", errors.Wrapf(httpErr, "HTTP %v request to %v failed with error: %v", httpGetRequestParameters.HTTPMethod, httpGetRequestParameters.HTTPURL, string(responseBody))
}
return "", errors.Errorf("%s, Response Status code: %v", httpGetRequestParameters.ErrMessage, response.StatusCode)
}