github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/abap/aakaas/targetVector.go (about) 1 package aakaas 2 3 import ( 4 "encoding/json" 5 "net/http" 6 "net/url" 7 "time" 8 9 abapbuild "github.com/SAP/jenkins-library/pkg/abap/build" 10 "github.com/SAP/jenkins-library/pkg/abaputils" 11 "github.com/pkg/errors" 12 ) 13 14 // TargetVectorStatus : Status of TargetVector in AAKaaS 15 type TargetVectorStatus string 16 17 const ( 18 // TargetVectorStatusGenerated : TargetVector is Generated (not published yet) 19 TargetVectorStatusGenerated TargetVectorStatus = "G" 20 // TargetVectorStatusTest : TargetVector is published for testing 21 TargetVectorStatusTest TargetVectorStatus = "T" 22 // TargetVectorStatusProductive : TargetVector is published for productive use 23 TargetVectorStatusProductive TargetVectorStatus = "P" 24 25 TargetVectorPublishStatusRunning TargetVectorStatus = "R" 26 TargetVectorPublishStatusSuccess TargetVectorStatus = "S" 27 TargetVectorPublishStatusError TargetVectorStatus = "E" 28 ) 29 30 // internal usage : Json Structure for AAKaaS Odata Service 31 type jsonTargetVector struct { 32 Tv *TargetVector `json:"d"` 33 } 34 35 // TargetVector : TargetVector desribes a deployble state of an ABAP product version 36 type TargetVector struct { 37 ID string `json:"Id"` 38 ProductName string `json:"ProductName"` 39 ProductVersion string `json:"ProductVersion"` 40 SpsLevel string `json:"SpsLevel"` 41 PatchLevel string `json:"PatchLevel"` 42 Status string `json:"Status"` 43 PublishStatus string `json:"PublishStatus"` 44 Content TargetVectorCVs `json:"Content"` 45 } 46 47 // TargetVectorCV : deployable state of an software Component Version as part of an TargetVector 48 type TargetVectorCV struct { 49 ID string `json:"Id"` 50 ScName string `json:"ScName"` 51 ScVersion string `json:"ScVersion"` 52 DeliveryPackage string `json:"DeliveryPackage"` 53 SpLevel string `json:"SpLevel"` 54 PatchLevel string `json:"PatchLevel"` 55 } 56 57 // TargetVectorCVs : deployable states of the software Component Versions of the product version 58 type TargetVectorCVs struct { 59 TargetVectorCVs []TargetVectorCV `json:"results"` 60 } 61 62 // Init : Initialize TargetVector for Creation in AAKaaS 63 func (tv *TargetVector) InitNew(addonDescriptor *abaputils.AddonDescriptor) error { 64 if addonDescriptor.AddonProduct == "" || addonDescriptor.AddonVersion == "" || addonDescriptor.AddonSpsLevel == "" || addonDescriptor.AddonPatchLevel == "" { 65 return errors.New("Parameters missing. Please provide product name, version, spslevel and patchlevel") 66 } 67 tv.ProductName = addonDescriptor.AddonProduct 68 tv.ProductVersion = addonDescriptor.AddonVersion 69 tv.SpsLevel = addonDescriptor.AddonSpsLevel 70 tv.PatchLevel = addonDescriptor.AddonPatchLevel 71 72 var tvCVs []TargetVectorCV 73 var tvCV TargetVectorCV 74 for i := range addonDescriptor.Repositories { 75 if addonDescriptor.Repositories[i].Name == "" || addonDescriptor.Repositories[i].Version == "" || addonDescriptor.Repositories[i].SpLevel == "" || 76 addonDescriptor.Repositories[i].PatchLevel == "" || addonDescriptor.Repositories[i].PackageName == "" { 77 return errors.New("Parameters missing. Please provide software component name, version, splevel, patchlevel and packagename") 78 } 79 tvCV.ScName = addonDescriptor.Repositories[i].Name 80 tvCV.ScVersion = addonDescriptor.Repositories[i].Version 81 tvCV.DeliveryPackage = addonDescriptor.Repositories[i].PackageName 82 tvCV.SpLevel = addonDescriptor.Repositories[i].SpLevel 83 tvCV.PatchLevel = addonDescriptor.Repositories[i].PatchLevel 84 tvCVs = append(tvCVs, tvCV) 85 } 86 tv.Content.TargetVectorCVs = tvCVs 87 return nil 88 } 89 90 // InitExisting : Initialize an already in AAKaaS existing TargetVector 91 func (tv *TargetVector) InitExisting(ID string) { 92 tv.ID = ID 93 } 94 95 // CreateTargetVector : Initial Creation of an TargetVector 96 func (tv *TargetVector) CreateTargetVector(conn *abapbuild.Connector) error { 97 conn.GetToken("/odata/aas_ocs_package") 98 tvJSON, err := json.Marshal(tv) 99 if err != nil { 100 return errors.Wrap(err, "Generating Request Data for Create Target Vector failed") 101 } 102 appendum := "/odata/aas_ocs_package/TargetVectorSet" 103 body, err := conn.Post(appendum, string(tvJSON)) 104 if err != nil { 105 return errors.Wrap(err, "Creating Target Vector in AAKaaS failed") 106 } 107 var jTV jsonTargetVector 108 if err := json.Unmarshal(body, &jTV); err != nil { 109 return errors.Wrap(err, "Unexpected AAKaaS response for create target vector: "+string(body)) 110 } 111 tv.ID = jTV.Tv.ID 112 tv.Status = jTV.Tv.Status 113 return nil 114 } 115 116 func (tv *TargetVector) PublishTargetVector(conn *abapbuild.Connector, targetVectorScope TargetVectorStatus) error { 117 conn.GetToken("/odata/aas_ocs_package") 118 appendum := "/odata/aas_ocs_package/PublishTargetVector?Id='" + url.QueryEscape(tv.ID) + "'&Scope='" + url.QueryEscape(string(targetVectorScope)) + "'" 119 body, err := conn.Post(appendum, "") 120 if err != nil { 121 return errors.Wrap(err, "Publish Target Vector in AAKaaS failed") 122 } 123 124 var jTV jsonTargetVector 125 if err := json.Unmarshal(body, &jTV); err != nil { 126 return errors.Wrap(err, "Unexpected AAKaaS response for publish target vector: "+string(body)) 127 } 128 129 tv.Status = jTV.Tv.Status 130 tv.PublishStatus = jTV.Tv.PublishStatus 131 return nil 132 } 133 134 // GetTargetVector : Read details of the TargetVector 135 func (tv *TargetVector) GetTargetVector(conn *abapbuild.Connector) error { 136 if tv.ID == "" { 137 return errors.New("Without ID no details of a targetVector can be obtained from AAKaaS") 138 } 139 appendum := "/odata/aas_ocs_package/TargetVectorSet('" + url.QueryEscape(tv.ID) + "')" 140 body, err := conn.Get(appendum) 141 if err != nil { 142 return errors.Wrap(err, "Getting Target Vector details from AAKaaS failed") 143 } 144 145 var jTV jsonTargetVector 146 if err := json.Unmarshal(body, &jTV); err != nil { 147 return errors.Wrap(err, "Unexpected AAKaaS response for getting target vector details: "+string(body)) 148 } 149 150 tv.Status = jTV.Tv.Status 151 tv.PublishStatus = jTV.Tv.PublishStatus 152 //other fields not needed atm 153 return nil 154 } 155 156 // PollForStatus : Poll AAKaaS until final PublishStatus reached and check if desired Status was reached 157 func (tv *TargetVector) PollForStatus(conn *abapbuild.Connector, targetStatus TargetVectorStatus) error { 158 timeout := time.After(conn.MaxRuntime) 159 ticker := time.Tick(conn.PollingInterval) 160 for { 161 select { 162 case <-timeout: 163 return errors.New("Timed out (AAKaaS target Vector Status change)") 164 case <-ticker: 165 if err := tv.GetTargetVector(conn); err != nil { 166 return errors.Wrap(err, "Getting TargetVector status during polling resulted in an error") 167 } 168 switch TargetVectorStatus(tv.PublishStatus) { 169 case TargetVectorPublishStatusRunning: 170 continue 171 case TargetVectorPublishStatusSuccess: 172 if TargetVectorStatus(tv.Status) == targetStatus { 173 return nil 174 } else { 175 return errors.New("Publishing of Targetvector " + tv.ID + " resulted in state " + string(tv.Status) + "instead of expected state " + string(targetStatus)) 176 } 177 case TargetVectorPublishStatusError: 178 return errors.New("Publishing of Targetvector " + tv.ID + " failed in AAKaaS") 179 default: 180 return errors.New("Polling returned invalid TargetVectorPublishStatus: " + string(tv.PublishStatus)) 181 } 182 } 183 } 184 } 185 186 /**************** 187 Mock Client Data 188 ****************/ 189 190 var AAKaaSHead = abapbuild.MockData{ 191 Method: `HEAD`, 192 Url: `/odata/aas_ocs_package`, 193 Body: `<?xml version="1.0"?> 194 <HTTP_BODY/>`, 195 StatusCode: 200, 196 Header: http.Header{"x-csrf-token": {"HRfJP0OhB9C9mHs2RRqUzw=="}}, 197 } 198 199 var AAKaaSTVPublishTestPost = abapbuild.MockData{ 200 Method: `POST`, 201 Url: `/odata/aas_ocs_package/PublishTargetVector?Id='W7Q00207512600000353'&Scope='T'`, 202 Body: `{ 203 "d": { 204 "Id": "W7Q00207512600000353", 205 "Vendor": "0000029218", 206 "ProductName": "/DRNMSPC/PRD01", 207 "ProductVersion": "0001", 208 "SpsLevel": "0000", 209 "PatchLevel": "0000", 210 "Status": "G", 211 "PublishStatus": "R" 212 } 213 }`, 214 StatusCode: 200, 215 } 216 217 var AAKaaSTVPublishProdPost = abapbuild.MockData{ 218 Method: `POST`, 219 Url: `/odata/aas_ocs_package/PublishTargetVector?Id='W7Q00207512600000353'&Scope='P'`, 220 Body: `{ 221 "d": { 222 "Id": "W7Q00207512600000353", 223 "Vendor": "0000029218", 224 "ProductName": "/DRNMSPC/PRD01", 225 "ProductVersion": "0001", 226 "SpsLevel": "0000", 227 "PatchLevel": "0000", 228 "Status": "G", 229 "PublishStatus": "R" 230 } 231 }`, 232 StatusCode: 200, 233 } 234 235 var AAKaaSGetTVPublishRunning = abapbuild.MockData{ 236 Method: `GET`, 237 Url: `/odata/aas_ocs_package/TargetVectorSet('W7Q00207512600000353')`, 238 Body: `{ 239 "d": { 240 "Id": "W7Q00207512600000353", 241 "Vendor": "0000029218", 242 "ProductName": "/DRNMSPC/PRD01", 243 "ProductVersion": "0001", 244 "SpsLevel": "0000", 245 "PatchLevel": "0000", 246 "Status": "G", 247 "PublishStatus": "R" 248 } 249 }`, 250 StatusCode: 200, 251 } 252 253 var AAKaaSGetTVPublishTestSuccess = abapbuild.MockData{ 254 Method: `GET`, 255 Url: `/odata/aas_ocs_package/TargetVectorSet('W7Q00207512600000353')`, 256 Body: `{ 257 "d": { 258 "Id": "W7Q00207512600000353", 259 "Vendor": "0000029218", 260 "ProductName": "/DRNMSPC/PRD01", 261 "ProductVersion": "0001", 262 "SpsLevel": "0000", 263 "PatchLevel": "0000", 264 "Status": "T", 265 "PublishStatus": "S" 266 } 267 }`, 268 StatusCode: 200, 269 } 270 271 var AAKaaSGetTVPublishProdSuccess = abapbuild.MockData{ 272 Method: `GET`, 273 Url: `/odata/aas_ocs_package/TargetVectorSet('W7Q00207512600000353')`, 274 Body: `{ 275 "d": { 276 "Id": "W7Q00207512600000353", 277 "Vendor": "0000029218", 278 "ProductName": "/DRNMSPC/PRD01", 279 "ProductVersion": "0001", 280 "SpsLevel": "0000", 281 "PatchLevel": "0000", 282 "Status": "P", 283 "PublishStatus": "S" 284 } 285 }`, 286 StatusCode: 200, 287 } 288 289 var AAKaaSTVCreatePost = abapbuild.MockData{ 290 Method: `POST`, 291 Url: `/odata/aas_ocs_package/TargetVectorSet`, 292 Body: `{ 293 "d": { 294 "Id": "W7Q00207512600000262", 295 "Vendor": "0000203069", 296 "ProductName": "/DRNMSPC/PRD01", 297 "ProductVersion": "0001", 298 "SpsLevel": "0000", 299 "PatchLevel": "0000", 300 "Status": "G", 301 "Content": { 302 "results": [ 303 { 304 "Id": "W7Q00207512600000262", 305 "ScName": "/DRNMSPC/COMP01", 306 "ScVersion": "0001", 307 "DeliveryPackage": "SAPK-001AAINDRNMSPC", 308 "SpLevel": "0000", 309 "PatchLevel": "0000" 310 } 311 ] 312 } 313 } 314 }`, 315 StatusCode: 200, 316 } 317 318 var templateMockData = abapbuild.MockData{ 319 Method: `GET`, 320 Url: ``, 321 Body: ``, 322 StatusCode: 200, 323 }