github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/sys/workspace/impl_buildws.go (about) 1 /* 2 * Copyright (c) 2022-present unTill Pro, Ltd. 3 */ 4 5 package workspace 6 7 import ( 8 "fmt" 9 10 "github.com/voedger/voedger/pkg/appdef" 11 "github.com/voedger/voedger/pkg/extensionpoints" 12 "github.com/voedger/voedger/pkg/goutils/logger" 13 "github.com/voedger/voedger/pkg/istructs" 14 "github.com/voedger/voedger/pkg/sys/blobber" 15 coreutils "github.com/voedger/voedger/pkg/utils" 16 "github.com/voedger/voedger/pkg/utils/federation" 17 ) 18 19 // everything is validated already 20 func buildWorkspace(templateName string, ep extensionpoints.IExtensionPoint, wsKind appdef.QName, federation federation.IFederation, newWSID int64, 21 targetAppQName istructs.AppQName, wsName string, systemPrincipalToken string) (err error) { 22 wsTemplateBLOBs, wsTemplateData, err := ValidateTemplate(templateName, ep, wsKind) 23 if err != nil { 24 return fmt.Errorf("template validation failed: %w", err) 25 } 26 if len(wsTemplateData) == 0 { 27 return nil 28 } 29 30 // upload blobs 31 blobsMap, err := uploadBLOBs(wsTemplateBLOBs, federation, targetAppQName, newWSID, systemPrincipalToken) 32 if err != nil { 33 return fmt.Errorf("blobs uploading failed: %w", err) 34 } 35 36 // update IDs in workspace template data with new blobs IDs 37 updateBLOBsIDsMap(wsTemplateData, blobsMap) 38 39 cudBody := coreutils.JSONMapToCUDBody(wsTemplateData) 40 cudURL := fmt.Sprintf("api/%s/%d/c.sys.CUD", targetAppQName.String(), newWSID) 41 if _, err := federation.Func(cudURL, cudBody, coreutils.WithAuthorizeBy(systemPrincipalToken), coreutils.WithDiscardResponse()); err != nil { 42 return fmt.Errorf("c.sys.CUD failed: %w", err) 43 } 44 logger.Info(fmt.Sprintf("workspace %s build completed", wsName)) 45 return nil 46 } 47 48 func updateBLOBsIDsMap(wsData []map[string]interface{}, blobsMap map[int64]map[string]int64) { 49 for _, record := range wsData { 50 recordIDIntf := record[appdef.SystemField_ID] // record id existence is checked on validation stage 51 recordID := int64(recordIDIntf.(float64)) 52 if fieldsBlobIDs, ok := blobsMap[recordID]; ok { 53 for fieldName, blobIDToSet := range fieldsBlobIDs { 54 // blob fields existence is checked on validation stage 55 record[fieldName] = blobIDToSet 56 } 57 } 58 } 59 } 60 61 func uploadBLOBs(blobs []blobber.StoredBLOB, federation federation.IFederation, appQName istructs.AppQName, wsid int64, principalToken string) (blobsMap, error) { 62 res := blobsMap{} 63 for _, blob := range blobs { 64 logger.Info("workspace build: uploading blob", blob.Name) 65 newBLOBID, err := federation.UploadBLOB(appQName, istructs.WSID(wsid), blob.Name, blob.MimeType, blob.Content, coreutils.WithAuthorizeBy(principalToken)) 66 if err != nil { 67 return nil, fmt.Errorf("blob %s: %w", blob.Name, err) 68 } 69 70 fieldBlobID, ok := res[int64(blob.RecordID)] 71 if !ok { 72 fieldBlobID = map[string]int64{} 73 res[int64(blob.RecordID)] = fieldBlobID 74 } 75 fieldBlobID[blob.FieldName] = int64(newBLOBID) 76 logger.Info(fmt.Sprintf("workspace build: blob %s uploaded and set: [%d][%s]=%d", blob.Name, blob.RecordID, blob.FieldName, newBLOBID)) 77 } 78 return res, nil 79 }