Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hubspot Destination #21

Merged
merged 63 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
1a59888
implement common config
oykmnk Sep 26, 2022
6330617
provide source config
oykmnk Sep 27, 2022
c1081dc
add one more test case for the source config
oykmnk Sep 27, 2022
a97a341
Merge pull request #1 from conduitio-labs/common-config
oykmnk Sep 27, 2022
03678ba
Merge pull request #2 from conduitio-labs/source-config
oykmnk Sep 27, 2022
069c5ce
implement hubspot http client
oykmnk Sep 27, 2022
b89a466
rename test functions
oykmnk Sep 27, 2022
e7dddb3
update comment
oykmnk Sep 27, 2022
cc701dd
update dependencies
oykmnk Sep 27, 2022
799da82
enable check shadowing
oykmnk Sep 27, 2022
1db1230
capture resp body if unexpected status code is occured
oykmnk Sep 27, 2022
216f1b2
Merge pull request #3 from conduitio-labs/hubspot-client
oykmnk Sep 27, 2022
c7fc683
add `gte` and `lte` validations
oykmnk Sep 28, 2022
3597b74
implement snapshot iterator
oykmnk Sep 28, 2022
feb099d
provide the `MaxRetries` config field
oykmnk Sep 28, 2022
a21a294
add comment about hubspot's id
oykmnk Sep 28, 2022
d1d7ac1
update `poll`'s comment
oykmnk Sep 28, 2022
3de26aa
provide a consts for id and createdAt fields
oykmnk Sep 28, 2022
b552201
move iterator's errors to a separate file
oykmnk Sep 28, 2022
e3bf884
Merge pull request #4 from conduitio-labs/source-snapshot-iterator
oykmnk Sep 29, 2022
59b71ce
regenerate mocks
oykmnk Sep 29, 2022
139a897
add hubspot resource validation
oykmnk Sep 29, 2022
5ad458a
Merge pull request #5 from conduitio-labs/check-supported-resources
oykmnk Sep 29, 2022
6edae10
implement destination
oykmnk Oct 6, 2022
ec40e88
pass a resource to the writer
oykmnk Oct 6, 2022
b6dd4e1
update the objectIdPlaceholder
oykmnk Oct 6, 2022
226cd5a
add teardown log
oykmnk Oct 6, 2022
38a118d
update destination comments
oykmnk Oct 6, 2022
69de240
Merge pull request #7 from conduitio-labs/destination-implementation
oykmnk Oct 6, 2022
25279b7
Implement CDC iterator (#8)
oykmnk Oct 18, 2022
0fd3869
Merge branch 'develop' into destination
oykmnk Oct 18, 2022
fc51bb1
check for nil iterator on teardown (#9)
oykmnk Oct 20, 2022
848d864
Merge branch 'develop' into destination
oykmnk Oct 20, 2022
ce9dce4
Implement Source integration tests (#10)
oykmnk Oct 24, 2022
27753a9
Implement Destination integration tests (#12)
oykmnk Oct 24, 2022
dada5c8
add source config validation
oykmnk Oct 24, 2022
28df651
Merge branch 'develop' into destination
oykmnk Oct 24, 2022
b0163f9
Implement deletion handling in CDC iterator (#13)
BohdanMyronchuk Oct 25, 2022
a52e1f8
Merge branch 'develop' into destination
oykmnk Oct 25, 2022
8cd71b0
replace sending to channel with return
oykmnk Oct 25, 2022
bd1440d
Update CDC and fix `bufferSize` and HubSpot limit functionality (#14)
oykmnk Oct 28, 2022
5a534df
Merge branch 'develop' into destination
oykmnk Oct 28, 2022
3536873
remove unsupported resources from the destination
oykmnk Oct 28, 2022
5b8adf9
Add Source documentation (#15)
oykmnk Oct 31, 2022
c4b81d2
Merge branch 'develop' into destination
oykmnk Oct 31, 2022
562590c
Add Destination documentation (#16)
oykmnk Oct 31, 2022
2283af0
Implement acceptance tests (#17)
oykmnk Nov 2, 2022
193471f
Add `extraProperties` source config field (#19)
oykmnk Nov 3, 2022
f4ed2ed
Merge branch 'develop' into destination
oykmnk Nov 3, 2022
854c0a7
fix test after merge
oykmnk Nov 3, 2022
3f03703
update resources list, rename `insert` to `create`
oykmnk Nov 4, 2022
80f774c
Merge branch 'develop' into destination
oykmnk Nov 4, 2022
d0a7c80
Add new source config field, `snapshot` (#23)
oykmnk Nov 29, 2022
29660db
Merge branch 'develop' into destination
oykmnk Nov 29, 2022
a829fb0
Data duplication fix (#25)
BohdanMyronchuk Dec 14, 2022
548666a
Merge branch 'develop' into destination
Dec 14, 2022
d9f40c0
Make `Position.ItemID` a string (#26)
oykmnk Dec 21, 2022
38f3a74
fix itemID check
oykmnk Dec 21, 2022
c47c6a3
Merge branch 'develop' into destination
oykmnk Dec 21, 2022
57a2feb
Update connector
lovromazgon Aug 4, 2023
19b92cf
refactor tests
lovromazgon Aug 10, 2023
278bf5d
Merge branch 'main' into destination
lovromazgon Aug 10, 2023
bd6344c
fix linter
lovromazgon Aug 10, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ jobs:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v4
with:
go-version: 1.18
go-version: "1.20"

- name: Test
run: make test GOTEST_FLAGS="-v -count=1 -race"
9 changes: 5 additions & 4 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ jobs:
golangci-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v3
- uses: actions/setup-go@v4
with:
go-version: '1.18'
go-version: "1.20"
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3.3.1
uses: golangci/golangci-lint-action@v3.6.0
with:
version: v1.49.0
version: v1.53.3
args: --timeout=2m
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ jobs:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v3
uses: actions/setup-go@v4
with:
go-version: 1.18
go-version: "1.20"

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v4
Expand Down
35 changes: 30 additions & 5 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ linters-settings:
gofmt:
simplify: false
govet:
check-shadowing: false
check-shadowing: true
nolintlint:
allow-unused: false # report any unused nolint directives
require-explanation: true # require an explanation for nolint directives
Expand All @@ -25,7 +25,7 @@ linters:
disable-all: true
enable:
- bodyclose
- depguard
# - depguard
- dogsled
- durationcheck
- errcheck
Expand Down Expand Up @@ -61,10 +61,10 @@ linters:
- nakedret
- nilerr
- nilnil
- nlreturn
# - nlreturn
- noctx
- nolintlint
- paralleltest
# - paralleltest
- predeclared
- rowserrcheck
- staticcheck
Expand Down Expand Up @@ -101,4 +101,29 @@ linters:
# - prealloc
# - testpackage
# - wsl
# - cyclop # not interested in package complexities at the moment
# - cyclop # not interested in package complexities at the moment

# List of regexps of issue texts to exclude.
issues:
exclude-rules:
- path: _test
linters:
- varnamelen
- testpackage
- nonamedreturns
- funlen # it can be annoying for table-driven tests
- dupl
- goerr113
- maintidx
- wrapcheck
- forcetypeassert
- path: _integration_test
linters:
- varnamelen
- testpackage
- nonamedreturns
- funlen # it can be annoying for table-driven tests
- dupl
- goerr113
- maintidx
- paralleltest # we don't want to run the integration tests in parallel because we want deterministic results
13 changes: 7 additions & 6 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ builds:
checksum:
name_template: checksums.txt
archives:
- replacements:
darwin: Darwin
linux: Linux
windows: Windows
386: i386
amd64: x86_64
- name_template: >-
{{ .ProjectName }}_
{{- .Version }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
changelog:
sort: asc
use: github
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ VERSION=$(shell git describe --tags --dirty --always)
build:
go build -ldflags "-X 'github.com/conduitio-labs/conduit-connector-hubspot.version=${VERSION}'" -o conduit-connector-hubspot cmd/connector/main.go

# if you plan to run integration tests it's recommended to do that with -p=1 specified.
test:
go test $(GOTEST_FLAGS) ./...

lint:
golangci-lint run

mockgen:
mockgen -package mock -source source/source.go -destination source/mock/source.go
mockgen -package mock -source destination/destination.go -destination destination/mock/destination.go
92 changes: 91 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,94 @@

## General

The [HubSpot](https://hubspot.com/) connector is one of Conduit plugins. It provides both, a source and a destination HubSpot connector.
The [HubSpot](https://hubspot.com/) connector is one of Conduit plugins. It provides both, a source and a destination HubSpot connector.

### Prerequisites

- [Go](https://go.dev/) v1.20
- [HubSpot](https://www.hubspot.com/) account and a [private app](https://developers.hubspot.com/docs/api/private-apps)
- (optional) [golangci-lint](https://github.com/golangci/golangci-lint) v1.49.0

### How to build it

Run `make build`.

### Testing

Run `make test` to run all the unit and integration tests. The integration tests require the environment variable `HUBSPOT_ACCESS_TOKEN` to be set. If the environment variable is empty, the integration tests will be skipped.

## Source

The HubSpot Source Connector uses a private app access token to connect to a HubSpot account and creates records for each resource change detected in a HubSpot account.

### Snapshot capture

When the connector first starts, snapshot mode is enabled. The connector reads items of a resource that you specified. It only reads items that are created before the connector starts to run, batching them by `bufferSize`. Each new batch is processed every `pollingPeriod` duration. Once all items in that initial snapshot are read the connector switches into CDC mode.

This behavior is enabled by default, but can be turned off by adding `"snapshot": false` to the Source configuration.

### Change Data Capture

When a snapshot is captured the connector starts to listen to data changes. It can track creates, updates, and deletes that occur after the connector is started. But please note that not all resources support all operations. You can check the available resources and operations they support out [here](docs/resources.md).

### Position structure

The connector goes through two modes.

**Snapshot**. The position contains the `initialTimestamp` field that is equal to the timestamp of the first connector run. If a resource supports filtering by id, the position also contains the id of the last processed item in the `itemId` field.

Here's an example of a Snapshot position:

```json
{
"mode": "snapshot",
"itemId": "256",
"initialTimestamp": "2022-10-28T14:58:27Z"
}
```

**CDC**. The position in this mode contains the same fields as in the Snapshot mode plus a `timestamp` that is equal to the `updatedAt` of the last processed item.

Here's an example of a CDC position:

```json
{
"mode": "cdc",
"itemId": "256",
"initialTimestamp": "2022-10-28T14:58:27Z",
"timestamp": "2022-10-28T15:00:50Z"
}
```

### Configuration options

| name | description | required | default |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- |
| `accessToken` | The private app access token for accessing the HubSpot API. | **true** | |
| `resource` | The HubSpot resource that the connector will work with.<br />You can find a list of the available resources [here](docs/resources.md). | **true** | |
| `maxRetries` | The number of HubSpot API request retries attempts that will be tried before giving up if a request fails. | false | `4` |
| `pollingPeriod` | The duration that defines a period of polling new items. | false | `5s` |
| `bufferSize` | The buffer size for consumed items.<br />It will also be used as a limit when retrieving items from the HubSpot API. | false | `100` |
| `extraProperties` | The list of HubSpot resource properties to include in addition to the default.<br />If any of the specified properties are not present on the requested HubSpot resource, they will be ignored.<br />Only CRM resources support this.<br />The format of this field is the following: `prop1,prop2,prop3` | false | |
| `snapshot` | The field determines whether or not the connector will take a snapshot of the entire collection before starting CDC mode. | false | `true` |

### Known limitations

- Not all resources support all CDC operations. You can check the available resources and operations they support out [here](docs/resources.md).

## Destination

The HubSpot Destination takes a `record.Record` and sends its payload to HubSpot without any transformations. The destination is designed to handle different payloads. You can check the available resources and operations they support out [here](/docs/resources.md).

### Configuration options

| name | description | required | default |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- |
| `accessToken` | The private app access token for accessing the HubSpot API. | **true** | |
| `resource` | The HubSpot resource that the connector will work with.<br />You can find a list of the available resources [here](docs/resources.md). | **true** | |
| `maxRetries` | The number of HubSpot API request retries attempts that will be tried before giving up if a request fails. | false | `4` |

### Known limitations

- To perform the update or delete operations the destination requires the `record.Key` to be set.
- If you want to use the destination to insert records from a source containing records that were previously taken by the HubSpot source, you may need to exclude some read-only fields from their payload. When trying to insert read-only fields you'll see an appropriate error message in the logs containing the names of the read-only fields.
Loading