func()

in internal/pkg/file/uploader/upload.go [58:148]


func (u *Uploader) Begin(ctx context.Context, namespaces []string, data JSDict) (file.Info, error) {
	vSpan, _ := apm.StartSpan(ctx, "validateFileInfo", "validate")
	if data == nil {
		vSpan.End()
		return file.Info{}, ErrPayloadRequired
	}

	/*
		Validation and Input parsing
	*/

	// make sure all required fields are present and non-empty
	if err := validateUploadPayload(data); err != nil {
		vSpan.End()
		return file.Info{}, err
	}

	size, _ := data.Int64("file", "size")
	if size > u.sizeLimit {
		vSpan.End()
		return file.Info{}, ErrFileSizeTooLarge
	}

	uid, err := uuid.NewV4()
	vSpan.End()
	if err != nil {
		return file.Info{}, fmt.Errorf("unable to generate upload operation ID: %w", err)
	}
	id := uid.String()

	// grab required fields that were checked already in validation step
	agentID, _ := data.Str("agent_id")
	actionID, _ := data.Str("action_id")
	source, _ := data.Str("src")
	docID := fmt.Sprintf("%s.%s", actionID, agentID)

	info := file.Info{
		ID:         id,
		DocID:      docID,
		AgentID:    agentID,
		ActionID:   actionID,
		Namespaces: namespaces,
		ChunkSize:  file.MaxChunkSize,
		Source:     source,
		Total:      size,
		Status:     file.StatusAwaiting,
		Start:      time.Now(),
	}
	chunkCount := info.Total / info.ChunkSize
	if info.Total%info.ChunkSize > 0 {
		chunkCount += 1
	}
	info.Count = int(chunkCount)

	/*
		Enrich document with additional server-side fields
	*/

	if err := data.Put(info.ChunkSize, "file", "ChunkSize"); err != nil {
		return file.Info{}, err
	}
	if err := data.Put(info.Status, "file", "Status"); err != nil {
		return file.Info{}, err
	}
	if err := data.Put(id, "upload_id"); err != nil {
		return file.Info{}, err
	}
	if err := data.Put(info.Start.UnixMilli(), "upload_start"); err != nil {
		return file.Info{}, err
	}
	if err := data.Put(info.Start.UnixMilli(), "@timestamp"); err != nil {
		return file.Info{}, err
	}
	if err := data.Put(info.Namespaces, "namespaces"); err != nil {
		return file.Info{}, err
	}

	/*
		Write to storage
	*/
	doc, err := json.Marshal(data)
	if err != nil {
		return file.Info{}, err
	}
	_, err = CreateFileDoc(ctx, u.bulker, doc, source, docID)
	if err != nil {
		return file.Info{}, err
	}

	return info, nil
}