added state command to docs

This commit is contained in:
philip-ellis-sp
2023-06-12 13:28:35 -05:00
parent 23686aa9fa
commit a154472eab
8 changed files with 99 additions and 22 deletions

View File

@@ -77,6 +77,12 @@ IDN will throw a connection timeout error if your connector doesn't respond with
:::
:::caution Important
IDN supports [delta aggregation](#delta-aggregation-state). If your source has a large number of accounts that will be syncronized with IDN, then it is highly recommended to utilize [delta aggregation](#delta-aggregation-state) for the source.
:::
The following code snippet from [index.ts](https://github.com/sailpoint-oss/airtable-example-connector/blob/main/src/index.ts) shows how to register the account list command on the connector object:
```javascript
@@ -174,9 +180,11 @@ The result of the account list command is not an array of objects but several in
If your source can keep track of changes to the data in some way, then delta aggregation can be performed on a source. In order to implement, there are a few things that need to be configured
1. In your connector-spec.json file, in the sourceConfig section, a checkbox needs to be added to enable state with the key ```spConnEnableStatefulCommands```:
1. In your connector-spec.json file, the feature needs to be enabled by adding the following key: ```"supportsStatefulCommands": true,``` and in the sourceConfig section, a checkbox needs to be added to enable state with the key ```spConnEnableStatefulCommands```:
```
```javascript
"supportsStatefulCommands": true,
...
{
"key": "spConnEnableStatefulCommands",
"label": "Stateful",
@@ -185,9 +193,9 @@ If your source can keep track of changes to the data in some way, then delta agg
}
```
2. In the ```stdAccountList``` command, when you are done sending commands, you need to also send the state to IDN so it knows where to start the next time it sends a list request:
2. In the ```stdAccountList``` command, when you are done sending accounts, you need to also send the state to IDN so it knows where to start the next time it sends a list request:
```
```javascript
const state = {"data": Date.now().toString()}
...
res.saveState(state)
@@ -203,7 +211,7 @@ The state that you send using the ```saveState``` command MUST be a json object,
3. In the ```stdAccountList``` command, you need to properly handle the state object. Something like below checks the stateful boolean as well as the state object and fetches accounts accordingly:
```
```javascript
.stdAccountList(async (context: Context, input: StdAccountListInput, res: Response<StdAccountListOutput>) => {
let accounts = []
const state = {"data": Date.now().toString()}

View File

@@ -109,3 +109,66 @@ private buildStandardObject(): StdEntitlementReadOutput | StdEntitlementListOutp
IDN will throw a connection timeout error if your connector doesn't respond within 3 minutes, and there are memory limitations involved with aggregating data. To prevent large memory utilization or timeout errors, you should set up your connectors to send data to IDN as it's retrieved from your source system. For more details and an example, refer to [Connector Timeouts](../in-depth/connector-timeouts.md).
:::
:::caution Important
IDN supports [delta aggregation](#delta-aggregation-state). If your source has a large number of entitlements that will be syncronized with IDN, then it is highly recommended to utilize [delta aggregation](#delta-aggregation-state) for the source.
:::
## Delta Aggregation (State)
If your source can keep track of changes to the data in some way, then delta aggregation can be performed on a source. In order to implement, there are a few things that need to be configured
1. In your connector-spec.json file, the feature needs to be enabled by adding the following key: ```"supportsStatefulCommands": true,``` and in the sourceConfig section, a checkbox needs to be added to enable state with the key ```spConnEnableStatefulCommands```:
```javascript
"supportsStatefulCommands": true,
...
{
"key": "spConnEnableStatefulCommands",
"label": "Stateful",
"required": true,
"type": "checkbox"
}
```
2. In the ```stdEntitlementList``` command, when you are done sending entitlments, you need to also send the state to IDN so it knows where to start the next time it sends a list request:
```javascript
const state = {"data": Date.now().toString()}
...
res.saveState(state)
```
In the above example, I am capturing the date, but you can use any value you want to store the state
:::caution Important
The state that you send using the ```saveState``` command MUST be a json object, and it is recommend to only save strings to ensure proper serialization/deserialization of the data. You cannot send a simple string or number or it will not properly save the state.
:::
3. In the ```stdEntitlementList``` command, you need to properly handle the state object. Something like below checks the stateful boolean as well as the state object and fetches accounts accordingly:
```javascript
.stdEntitlementList(async (context: Context, input: StdEntitlementListInput, res: Response<StdEntitlementListOutput>) => {
let groups = []
const state = {"data": Date.now().toString()}
if (!input.state && input.stateful) {
logger.info(input, "No state provided, fetching all entitlements")
const groups = await airtable.getAllEntitlements()
} else if (input.state && input.stateful) {
logger.info(input ,"Current state provided, only fetching entitlements after that state")
const groups = await airtable.getAllStatefulEntitlements(new Date(Number(input.state?.data)))
} else {
logger.info(input.state ,"Source is not stateful, getting all entitlements")
const groups = await airtable.getAllEntitlements()
}
logger.info(groups, "fetched the following entitlements in Airtable")
for (const group of groups) {
res.send(group.toStdEntitlementListOutput())
}
res.saveState(state)
})
```

View File

@@ -9,13 +9,11 @@ export default function BlogBanner() {
<div>
<div className={styles.imageContainer}>
<img className={styles.headerImage} src={useBaseUrl('/blog/blog_banner_template.png')}></img>
<div className={styles.blogHeaderText}>
SailPoint Developer Blog
Blog
</div>
</div >
</div>
);
}

View File

@@ -6,8 +6,8 @@
max-width: 396px;
font-weight: bold;
line-height: 133%;
top: 21px;
left: 74px;
top: -84px;
left: 59px;
}
.background {
@@ -18,7 +18,11 @@
.imageContainer {
width: 100%;
height: 180px;
background-image: url('../../../../static/blog/blog_banner_template.png');
background-repeat: repeat;
height: 90px;
background: rgb(0,51,161);
background: linear-gradient(90deg, rgba(0,51,161,1) 0%, rgba(84,192,232,1) 100%);
}
.headerImage {
height: 90px;
}

View File

@@ -9,8 +9,9 @@ export default function MarketplaceBanner() {
<div>
<div className={styles.imageContainer}>
<img className={styles.headerImage} src={useBaseUrl('/blog/marketplace_banner_template.png')}></img>
<div className={styles.blogHeaderText}>
SailPoint Developer Marketplace
Marketplace
</div>
</div >

View File

@@ -6,8 +6,8 @@
max-width: 459px;
font-weight: bold;
line-height: 130%;
top: 29px;
left: 228px;
top: -84px;
left: 101px;
}
.background {
@@ -18,8 +18,11 @@
.imageContainer {
width: 100%;
height: 180px;
background-size: 1920px 180px;
background-image: url('../../../../static/blog/marketplace_banner_template.png');
background-repeat: repeat;
height: 90px;
background: rgb(0,51,161);
background: linear-gradient(90deg, rgba(0,51,161,1) 0%, rgba(84,192,232,1) 100%);
}
.headerImage {
height: 90px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 8.4 KiB