vitess.io/vitess@v0.16.2/go/vt/topo/workflow.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package topo
    18  
    19  import (
    20  	"path"
    21  
    22  	"context"
    23  
    24  	"google.golang.org/protobuf/proto"
    25  
    26  	workflowpb "vitess.io/vitess/go/vt/proto/workflow"
    27  )
    28  
    29  // This file provides the utility methods to save / retrieve workflows
    30  // in the topology global cell.
    31  
    32  const (
    33  	workflowsPath    = "workflows"
    34  	workflowFilename = "Workflow"
    35  )
    36  
    37  func pathForWorkflow(uuid string) string {
    38  	return path.Join(workflowsPath, uuid, workflowFilename)
    39  }
    40  
    41  // WorkflowInfo is a meta struct that contains the version of a Workflow.
    42  type WorkflowInfo struct {
    43  	version Version
    44  	*workflowpb.Workflow
    45  }
    46  
    47  // GetWorkflowNames returns the names of the existing
    48  // workflows. They are sorted by uuid.
    49  func (ts *Server) GetWorkflowNames(ctx context.Context) ([]string, error) {
    50  	entries, err := ts.globalCell.ListDir(ctx, workflowsPath, false /*full*/)
    51  	switch {
    52  	case IsErrType(err, NoNode):
    53  		return nil, nil
    54  	case err == nil:
    55  		return DirEntriesToStringArray(entries), nil
    56  	default:
    57  		return nil, err
    58  	}
    59  }
    60  
    61  // CreateWorkflow creates the given workflow, and returns the initial
    62  // WorkflowInfo.
    63  func (ts *Server) CreateWorkflow(ctx context.Context, w *workflowpb.Workflow) (*WorkflowInfo, error) {
    64  	// Pack the content.
    65  	contents, err := proto.Marshal(w)
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	// Save it.
    71  	filePath := pathForWorkflow(w.Uuid)
    72  	version, err := ts.globalCell.Create(ctx, filePath, contents)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  	return &WorkflowInfo{
    77  		version:  version,
    78  		Workflow: w,
    79  	}, nil
    80  }
    81  
    82  // GetWorkflow reads a workflow from the global cell.
    83  func (ts *Server) GetWorkflow(ctx context.Context, uuid string) (*WorkflowInfo, error) {
    84  	// Read the file.
    85  	filePath := pathForWorkflow(uuid)
    86  	contents, version, err := ts.globalCell.Get(ctx, filePath)
    87  	if err != nil {
    88  		return nil, err
    89  	}
    90  
    91  	// Unpack the contents.
    92  	w := &workflowpb.Workflow{}
    93  	if err := proto.Unmarshal(contents, w); err != nil {
    94  		return nil, err
    95  	}
    96  
    97  	return &WorkflowInfo{
    98  		version:  version,
    99  		Workflow: w,
   100  	}, nil
   101  }
   102  
   103  // SaveWorkflow saves the WorkflowInfo object. If the version is not
   104  // good any more, ErrBadVersion is returned.
   105  func (ts *Server) SaveWorkflow(ctx context.Context, wi *WorkflowInfo) error {
   106  	// Pack the content.
   107  	contents, err := proto.Marshal(wi.Workflow)
   108  	if err != nil {
   109  		return err
   110  	}
   111  
   112  	// Save it.
   113  	filePath := pathForWorkflow(wi.Uuid)
   114  	version, err := ts.globalCell.Update(ctx, filePath, contents, wi.version)
   115  	if err != nil {
   116  		return err
   117  	}
   118  
   119  	// Remember the new version.
   120  	wi.version = version
   121  	return nil
   122  }
   123  
   124  // DeleteWorkflow deletes the specified workflow.  After this, the
   125  // WorkflowInfo object should not be used any more.
   126  func (ts *Server) DeleteWorkflow(ctx context.Context, wi *WorkflowInfo) error {
   127  	filePath := pathForWorkflow(wi.Uuid)
   128  	return ts.globalCell.Delete(ctx, filePath, wi.version)
   129  }