# How to Port Buffers between Orgs

**URL:** <https://community.synatic.com/t/how-to-port-buffers-between-orgs/418>\
**Category:** Buffers\
**Tags:** flows, buffer\
**Created:** [April 18, 2024, 2:12pm UTC](https://community.synatic.com/t/how-to-port-buffers-between-orgs/418 "2024-04-18T14:12:12Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Faizel](https://yyz2.discourse-cdn.com/flex032/user_avatar/community.synatic.com/faizel/32/918_2.png) [@Faizel](https://community.synatic.com/u/Faizel)\
**Post date:** [April 18, 2024, 2:12pm UTC](https://community.synatic.com/t/how-to-port-buffers-between-orgs/418/1 "2024-04-18T14:12:12Z")

</div>

If required to transfer Buffers with data and indexes for particular solutions between Orgs, please follow the instructions below:

Illustrated below is an overview of the process, We have two orgs, source and target or dev and prod orgs, In the source we create two flows, one to populate a list of buffers to create and a second to create the buffers in the target org. In the source org, we have a flow that will get the data and POST to an API to ingest records in the buffer. The API sits on the target org and works as an interface to add the records into the buffer that is generated.

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/1/119f6e187197a750d4ec99eda39780b4c2efe709.png)

# Populate List of Buffers

In Target org (OrgB). Create a flow to Populate a list of the buffers we want to create. Illustrated below is an example of a flow that uses a Record generator to store the list of buffers to generate, sets default values then prepares the buffer list and saves the records to a buffer (Buffer List) that we will use in the next step to create the buffer.

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/b/baf4b66c5587e46a9e05a86bbd5c5ef444302f0d.png)

In the Record Generator, we specify the Name of the buffer (TableName), indexes (OtherKeys) to create on the buffer, and the solution where the buffer should be saved.

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/b/b66e8a090c8d455ec57c33f3eccf10f46010a98e.png)

In the Filter step, `return !!input.record.TableName`; is a way of checking if the `TableName` property exists within the record object

![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/4/40c14ab7de9b405f2e76da7c81642debdb11bb7d.png)

Add a Calculator step to set the defaults.

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/4/46ff6b7a6c278ee3af58cd21892e246733ffdea8.png)

Code:

```auto
let inputRecord = input.record;

function getBufferName(SolutionName, TableName) {
    // cast TableName to lowercase & remove underscores
    let tableNameString = stringHelper.replaceAll(stringHelper.clean(TableName).toLowerCase(), "_", "", true);
    // replace spaces with dashes
    tableNameString = stringHelper.replaceAll(tableNameString, " ", "-", true);
    // attach buffername to solution name in kebab case to get object id
    return stringHelper.clean(SolutionName) + '-' + tableNameString;
}

// define default values and ensure all keys exist in output record
inputRecord.SolutionName = !!inputRecord.SolutionName ? inputRecord.SolutionName : "global";
inputRecord.BufferDescription = !!inputRecord.BufferDescription ? inputRecord.BufferDescription : "Raw table buffer";
inputRecord.OtherKeys = !!inputRecord.OtherKeys ? inputRecord.OtherKeys : [];
inputRecord.BufferName = !!inputRecord.BufferName ? stringHelper.clean(inputRecord.BufferName) : getBufferName(inputRecord.SolutionName, inputRecord.TableName);
inputRecord.BufferTitle = !!inputRecord.TableName ? stringHelper.clean(inputRecord.TableName) : stringHelper.clean(inputRecord.TableName);

//If Required to put buffer into a subsolution, Uncomment the below
// let SubCategoryPath = "SubCategory > "; //Specify Name of Category
// inputRecord.BufferTitle = SubCategoryPath + inputRecord.BufferTitle;

return inputRecord;

```

Below is an example of what the data looks like going into the buffer

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/8/81752e6355b9b4cb1cbdb282b821305b0d206750.png)

Add a Buffer destination to save the records for the list of buffers to be generated.

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/2/2b0770760e831987538d6aaa8499c2199a96c372.png)

Note: If you have a large number of buffers to create, On the Source org (OrgA), Step up a flow that will use the Synatic Admin to get a list of buffers from a solution with the indexes, then use a Calculator step to prepare the data as per the Record Generator sample above and write the records to a JSON file then consume the JSON file in the above flow to populate the list of buffers

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/4/49490490a96e38ec4740a291a5e8a833567a5ef9.png)

# Create Buffers

In Target org (OrgB). Create a flow to generate the buffers based on the list we created in the above steps. Illustrated below is an example of a flow that queries the buffer list then prepares data and uses the Synatic Admin destination step to create the buffers.

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/a/ac999be2aa2bbb82f94195acd71d40f5cd460e42.png)

Add a buffer query to get the data from the buffer list

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/1/1376c04659b2efed0a8c6dd0cb73d86bdff66826.png)

In the Filter step, `return !!input.record.TableName`; is a way of checking if the `TableName` property exists within the record object. Add a default calculator after to see the results from the filter step

![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/4/40c14ab7de9b405f2e76da7c81642debdb11bb7d.png)

Add a Subflow control step after the Filter step and default calculator to send each record to the Synatic Admin destination to generate the buffer. In the Subflow Add a Start flow step, Ensure Set Parent Record is checked

![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/5/51f2694c5a23f1022cb701a9d700db2be4a4fc41.png)

After the Start flow and Pass Through step, Add a Calculator step to define the buffer

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/f/f34162b365acbea99a3418569d76bf4d378c11ea.png)

Code:

```auto
let inputRecord=input.record;

// create automatic indexes for key fields
indexes = [];

inputRecord.OtherKeys.forEach((item) => {
    indexes.push({"key": [[stringHelper.clean(item),1]],"unique": false});
})

// a maximum of 10 indexes may be used
indexes = indexes.slice(0, 10);

// define buffer record
inputRecord = {
    "name": inputRecord.BufferName,
    "title": inputRecord.BufferTitle,
    "description": inputRecord.BufferDescription,
    "indexes": indexes,
    "solution": {
        "name": inputRecord.SolutionName
    }
}

return inputRecord;

```

Below is an example of a record that will go into the Synatic Admin step to create the Buffer

![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/d/d2a9c4ab8112f697a66e817673e384ecd3ad78aa.png)

Add a Synatic Admin destination step, Choose Buffers as the Resource and Insert as the Operation

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/5/501183987013f8d70dacfe6c15f1a85b69d8bbfb.png)

When the flows are executed, The buffers will be created in the specified solution with the indexes set up

![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/d/d73d3201e908ae422c34c22d3e52f819a8d33fa2.png)

# Ingest Records from API

In the Target Org (Org B) - Create a flow that will be used by the API (Gateway) to get records and add to the buffer. Illustrated below is an example of a flow that takes in JSON, looks up a buffer and add records to a Buffer destination

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/9/9902f344c10060482f214a58bf144b0c48f8aa79.png)

Add a flow Input Parameter, Call it TableName and set it to be Required

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/5/5a0cbd9de51aa8c644983fd2b111f9102504a19b.png)

After the JSON reader step, Add a calculator to format the record data and set the bufferName

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/d/d6334fc92c9e4b6e1d3ba257c64abbb9ccb43fe4.png)

Code:

```auto
let inputRecord=input.record;

inputRecord={
    "_recordData": JSON.parse(JSON.stringify(input.record))
}
input.parameters.BufferName = input.parameters.TableName.toString().replace(" ","-").replace("_","").toLowerCase();
inputRecord._bufferName=input.parameters.BufferName;

return inputRecord;

```

Use the Synatic Admin Lookup step to take in the bufferName and return the details of the buffer to a field called \_buffer

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/3/3099321a79c93a30fec09070e5f5b820a4a99bee.png)

After the Synatic Lookup, Add a Calculator step that will create a parameter for the buffer and prepare the record data

Note: \_recordData field name is required to pass the values to the buffer destination

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/2/29bbc261da4961b18f8489dfba8bfd4c91044502.png)

Add a Subflow control step to send each record to the Buffer destination. In the Subflow, Add a Start flow step, Ensure Set Parent Record is checked

![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/5/51f2694c5a23f1022cb701a9d700db2be4a4fc41.png)

Before the Buffer destination, Add a Calculator step to set the bufferid as a parameter

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/7/7c69bdb1c509f38b74787ae41bdcabd14e040863.png)

In the buffer destination, Reference the parameter created in the previous step called bufferid to add the records into the Buffer destination

![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/3/395af070d76be1e67aaa3ef166f8a0ea167f945f.png)

# API (Gateway) Setup

In the Target org (OrgB) Create a REST gateway to ingest records and add them to the Buffer, The API will act as an interface between the two orgs.

Choose the HTTP method as POST, specify a path name and TableName parameter which will be used to get the buffer we want to add records to. Select the flow created in the previous step and select the From Path parameters mapping. Choose the Processing Mode as Async and Input Content Type as JSON

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/5/5019e107aa85669de18e48ca010616e626f3b8e1.png)

* * *

# Push Records to Buffer API

On the Source Org (OrgA), Create a flow that will get the records from our source buffer and POST them to the API endpoint to add the records into the buffer. Illustrated below is an example of a flow sets the source buffer and target buffer in a Record Generator then queries the records from the source and sends each record to the API endpoint to ingest records into the new target Buffer.

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/9/9ad91a4e4026a96591896745135031831709dcda.png)

In the Record Generator, Specify the Buffers that we want to get the data from and the target buffers that we want to send the data to, As per the below

![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/6/656ba162e18cb8498a126492396f3ab767f09450.png)

Before and After the Split step, A default calculator can be added to see what the data looks like. In the Split step we split on the `buffers` array which we created in the previous Record Generator.

![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/f/f1efd390ff56f57a9326c20a190baedddf68e845.png)

Add a Subflow control step to set each buffer to a parameter. In the Subflow add a Start flow step, Ensure Set Parent Record is checked

![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/5/51f2694c5a23f1022cb701a9d700db2be4a4fc41.png)

In the first Subflow control step, After the Start Flow and Pass Through, Add a calculator step to set the source buffer and target buffer as parameters

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/9/96d09405c3ffdd430df2c35476b2e1b0db91fdf4.png)

Code:

```auto
let inputRecord=input.record;
input.parameters.buffername=inputRecord.name;
input.parameters.TargetTable = inputRecord.TargetTable
inputRecord={}
return inputRecord;

```

Add a second Subflow that will pass each buffer and Target buffer to get the data and send to the API to ingest records

![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/5/54071cf814daab27aaa23b31fb7e9aa5ad839bad.png)

Include the Buffer Source step, where we pass in the source Buffername to get the records

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/f/f556c02e2aa1cf654b47863d33aafecc48d2b7e8.png)

Add a Calculator step after the Buffer source and Pass through to delete the default \_id field from the record

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/1/18481065086ca4b1829be1366f3bc8d4f816fad8.png)

Code:

```auto
let inputRecord=input.record;
delete inputRecord._id;
return inputRecord;

```

An HTTP Destination step is used to add the API info and path from the Target Org (OrgB). Specify the Content-Type to be JSON

 ![image](https://canada1.discourse-cdn.com/flex032/uploads/synatic/original/2X/f/f2b449c369e4fb10a10b9068588c0777aa369385.png)

* * *

> Order of Execution

_Target Org (OrgB)_

- Populate List of Buffer
- Generate Buffers
- Ingest Records from API
- Gateway to Point to Ingest Records from API Flow

_Source Org (OrgA)_

- Push Records to Buffer API
