Flows API
  • Globus Flows
  • Overview
  • Getting Started
    • How to Run a Flow
    • How to Monitor a Flow Run
    • How to Create a Flow
  • Authoring Flows
    • Introduction
    • Actions
    • Expressions
    • Choice States
    • Wait States
    • Fail States
    • Pass States
    • Protecting Secrets
    • Handling Exceptions
    • Performing Actions as Different Users
    • Run Context
    • Validating Flow Definitions
  • Authoring Input Schemas
  • Authentication and Authorization
  • Consents and Resuming Runs
  • Permissions
  • Limits
  • Hosted Action Providers
    • Hello World
    • Globus Search - Ingest Task
    • Globus Search - Delete Task
    • Send Notification Email
    • Wait For User Selection
    • Expression Evaluation
    • DataCite Mint
    • Transfer APs
    • Compute AP
  • Example Flows
    • Simple Transfer
    • Move (copy and delete) files
    • Transfer and Share Files
    • Two Stage Globus Transfer
    • Transfer After Approval
    • Looping Batched Move
    • Tar and Transfer with Globus Compute
Skip to main content
Globus Docs
  • APIs
    Auth Flows Groups Search Timers Transfer Globus Connect Server Compute Helper Pages
  • Applications
    Globus Connect Personal Globus Connect Server Premium Storage Connectors Compute Command Line Interface Python SDK JavaScript SDK
  • Guides
  • Support
    FAQs Mailing Lists Contact Us Check Support Tickets
  1. Home
  2. Globus Services
  3. Globus Flows
  4. Example Flows
  5. Move (copy and delete) files

Move (copy and delete) files

Description

Perform a 'move' operation on a directory by first transferring from a source to a destination and then deleting from the source. The entire directory’s contents, including files and subdirectories, will be copied to the destination and then deleted from the source.

Note

This example differs from the Move (copy and delete) files Globus-provided flow available in the Globus Web App.

The example is simplified and may exhibit slightly different behaviors.

Highlights

In the example definition, the IdentifyPathTypes state uses expression evaluators to prepare several boolean values.

These boolean values are used by the TestPathConstraints state to conditionally modify the destination path used by the Transfer state.

Source code

{
  "Comment": "A Flow for performing a logical 'move' operation by first transferring from a source to a destination and then deleting from the source",
  "StartAt": "GetSourcePathInfo",
  "States": {
    "GetSourcePathInfo": {
      "Type": "Action",
      "Comment": "Lookup the source path to determine its type (file/dir) to decide if transfer should be recursive",
      "ActionUrl": "https://transfer.actions.globus.org/stat",
      "Parameters": {
        "path.$": "$.source.path",
        "endpoint_id.$": "$.source.id"
      },
      "ResultPath": "$.SourceStat",
      "Next": "GetDestinationPathInfo"
    },
    "GetDestinationPathInfo": {
      "Type": "Action",
      "Comment": "Lookup the destination path to determine its type (file/dir)",
      "ActionUrl": "https://transfer.actions.globus.org/stat",
      "Parameters": {
        "path.$": "$.destination.path",
        "endpoint_id.$": "$.destination.id"
      },
      "ResultPath": "$.DestinationStat",
      "Next": "IdentifyPathTypes"
    },
    "IdentifyPathTypes": {
      "Comment": "Check the paths to see if they are directories or files",
      "Type": "ExpressionEval",
      "Parameters": {
        "source_is_dir.=": "SourceStat.details.type == 'dir'",
        "dest_is_dir.=": "'type' in DestinationStat.details and DestinationStat.details.type == 'dir'",
        "dest_exists.=": "'code' not in DestinationStat.details or DestinationStat.details.code != 'NotFound'"
      },
      "ResultPath": "$.PathTypes",
      "Next": "TestPathConstraints"
    },
    "TestPathConstraints": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.PathTypes.dest_exists",
          "BooleanEquals": false,
          "Next": "ComputeDestPathNoOp"
        },
        {
          "And": [
            {
              "Variable": "$.PathTypes.source_is_dir",
              "BooleanEquals": true
            },
            {
              "Variable": "$.PathTypes.dest_is_dir",
              "BooleanEquals": false
            }
          ],
          "Next": "FailDirOntoFile"
        },
        {
          "And": [
            {
              "Variable": "$.PathTypes.source_is_dir",
              "BooleanEquals": false
            },
            {
              "Variable": "$.PathTypes.dest_is_dir",
              "BooleanEquals": true
            }
          ],
          "Next": "ComputeDestPathFileUnderDir"
        }
      ],
      "Default": "ComputeDestPathNoOp"
    },
    "ComputeDestPathFileUnderDir": {
      "Comment": "Compute the destination path for file-to-dir transfers.",
      "Type": "ExpressionEval",
      "Parameters": {
        "path.=": "destination.path + source.path.rpartition('/')[2]"
      },
      "ResultPath": "$.ComputedDest",
      "Next": "Transfer"
    },
    "ComputeDestPathNoOp": {
      "Comment": "\"Compute\" the destination path for file-to-file and dir-to-dir transfers. This is a no-op used to match the output format of ComputeDestPathFileUnderDir.",
      "Type": "ExpressionEval",
      "Parameters": {
        "path.$": "$.destination.path"
      },
      "ResultPath": "$.ComputedDest",
      "Next": "Transfer"
    },
    "Transfer": {
      "Type": "Action",
      "Comment": "Run the initial transfer operation from the source to the destination",
      "ActionUrl": "https://transfer.actions.globus.org/transfer",
      "WaitTime": 172800,
      "Parameters": {
        "DATA": [
          {
            "source_path.$": "$.source.path",
            "destination_path.$": "$.ComputedDest.path"
          }
        ],
        "source_endpoint.$": "$.source.id",
        "destination_endpoint.$": "$.destination.id"
      },
      "ResultPath": "$.TransferResult",
      "Next": "Delete"
    },
    "Delete": {
      "Type": "Action",
      "Comment": "Delete the source path.",
      "ActionUrl": "https://transfer.actions.globus.org/delete",
      "WaitTime": 172800,
      "Parameters": {
        "DATA": [
          {
            "path.$": "$.source.path"
          }
        ],
        "recursive": true,
        "endpoint.$": "$.source.id"
      },
      "ResultPath": "$.DeleteResult",
      "Next": "Success"
    },
    "FailDirOntoFile": {
      "Comment": "Report failure due to a transfer of a directory to a file",
      "Type": "Fail",
      "Cause": "DirectoryOntoFile",
      "Error": "If the source path is a directory, the destination path must also be a directory. Moving a directory to a file is not possible."
    },
    "Success": {
      "Comment": "Normal completion, so report success and exit",
      "Type": "Pass",
      "Parameters": {
        "message": "Move operation complete"
      },
      "ResultPath": "$.FlowResult",
      "End": true
    }
  }
}
{
  "type": "object",
  "required": [
    "source",
    "destination"
  ],
  "properties": {
    "source": {
      "type": "object",
      "title": "Source",
      "format": "globus-collection",
      "required": [
        "id",
        "path"
      ],
      "properties": {
        "id": {
          "type": "string",
          "title": "Source Collection ID",
          "format": "uuid",
          "description": "The UUID for the collection which serves as the source of the Move"
        },
        "path": {
          "type": "string",
          "title": "Source Collection Path",
          "description": "The path on the source collection for the data"
        }
      },
      "description": "The data's origin.",
      "additionalProperties": false
    },
    "destination": {
      "type": "object",
      "title": "Destination",
      "format": "globus-collection",
      "required": [
        "id",
        "path"
      ],
      "properties": {
        "id": {
          "type": "string",
          "title": "Destination Collection ID",
          "format": "uuid",
          "description": "The UUID for the collection which serves as the destination for the Move"
        },
        "path": {
          "type": "string",
          "title": "Destination Collection Path",
          "description": "The path on the destination collection where the data will be stored"
        }
      },
      "description": "The destination for the data.",
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}
{
  "source": {
    "id": "6c54cade-bde5-45c1-bdea-f4bd71dba2cc",
    "path": "/~/source-directory"
  },
  "destination": {
    "id": "31ce9ba0-176d-45a5-add3-f37d233ba47d",
    "path": "/~/destination-directory"
  }
}
  • Globus Flows
  • Overview
  • Getting Started
    • How to Run a Flow
    • How to Monitor a Flow Run
    • How to Create a Flow
  • Authoring Flows
    • Introduction
    • Actions
    • Expressions
    • Choice States
    • Wait States
    • Fail States
    • Pass States
    • Protecting Secrets
    • Handling Exceptions
    • Performing Actions as Different Users
    • Run Context
    • Validating Flow Definitions
  • Authoring Input Schemas
  • Authentication and Authorization
  • Consents and Resuming Runs
  • Permissions
  • Limits
  • Hosted Action Providers
    • Hello World
    • Globus Search - Ingest Task
    • Globus Search - Delete Task
    • Send Notification Email
    • Wait For User Selection
    • Expression Evaluation
    • DataCite Mint
    • Transfer APs
    • Compute AP
  • Example Flows
    • Simple Transfer
    • Move (copy and delete) files
    • Transfer and Share Files
    • Two Stage Globus Transfer
    • Transfer After Approval
    • Looping Batched Move
    • Tar and Transfer with Globus Compute
© 2010- The University of Chicago Legal Privacy Accessibility