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  }