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

🐙 octavia-cli: use model serialization #12133

Merged
merged 17 commits into from
May 6, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
2 changes: 2 additions & 0 deletions airbyte-api/src/main/openapi/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3597,6 +3597,7 @@ components:
sourceDefinedCursor:
description: If the source defines the cursor field, then any other cursor field inputs will be ignored. If it does not, either the user_provided one is used, or the default one is used as a backup.
type: boolean
nullable: true
defaultCursorField:
description: Path to the field that will be used to determine if a record is new or modified since the last sync. If not provided by the source, the end user will have to specify the comparable themselves.
type: array
Expand All @@ -3611,6 +3612,7 @@ components:
type: string
namespace:
type: string
nullable: true
description: Optional Source-defined namespace. Airbyte streams from the same sources should have the same namespace. Currently only used by JDBC destinations to determine what schema to write to.
StreamJsonSchema:
type: object
Expand Down
11 changes: 6 additions & 5 deletions octavia-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,9 @@ You can disable telemetry by setting the `OCTAVIA_ENABLE_TELEMETRY` environment

## Changelog

| Version | Date | Description | PR |
|---------|------------|-------------------|----------------------------------------------------------|
| 0.36.2 | 2022-04-15 | Improve telemetry | [#12072](https://github.com/airbytehq/airbyte/issues/11896)|
| 0.35.68 | 2022-04-12 | Add telemetry | [#11896](https://github.com/airbytehq/airbyte/issues/11896)|
| 0.35.61 | 2022-04-07 | Alpha release | [EPIC](https://github.com/airbytehq/airbyte/issues/10704)|
| Version | Date | Description | PR |
|---------|------------|-------------------------------------|----------------------------------------------------------|
| 0.36.7 | 2022-05-03 | Use camel case in connection fields | [#12133](https://github.com/airbytehq/airbyte/pull/12133)|
alafanechere marked this conversation as resolved.
Show resolved Hide resolved
| 0.36.2 | 2022-04-15 | Improve telemetry | [#12072](https://github.com/airbytehq/airbyte/issues/11896)|
| 0.35.68 | 2022-04-12 | Add telemetry | [#11896](https://github.com/airbytehq/airbyte/issues/11896)|
| 0.35.61 | 2022-04-07 | Alpha release | [EPIC](https://github.com/airbytehq/airbyte/issues/10704)|
Original file line number Diff line number Diff line change
@@ -1,38 +1,35 @@
# Configuration for connection poke_to_g
# Configuration for connection poke_to_pg
definition_type: connection
resource_name: poke_to_g
resource_name: poke_to_pg
source_id: TO_UPDATE_FROM_TEST
destination_id: TO_UPDATE_FROM_TEST

# EDIT THE CONFIGURATION BELOW!
configuration:
sourceId: TO_UPDATE_FROM_TEST # REQUIRED | string
destinationId: TO_UPDATE_FROM_TEST # REQUIRED | string
status: active # REQUIRED | string | Allowed values: active, inactive, deprecated
name: poke_to_g # OPTIONAL | string | Optional name of the connection
namespaceDefinition: source # OPTIONAL | string | Allowed values: source, destination, customformat
namespaceFormat: "${SOURCE_NAMESPACE}" # OPTIONAL | string | Used when namespaceDefinition is 'customformat'. If blank then behaves like namespaceDefinition = 'destination'. If "${SOURCE_NAMESPACE}" then behaves like namespaceDefinition = 'source'.
namespace_definition: source # OPTIONAL | string | Allowed values: source, destination, customformat
namespace_format: "${SOURCE_NAMESPACE}" # OPTIONAL | string | Used when namespaceDefinition is 'customformat'. If blank then behaves like namespaceDefinition = 'destination'. If "${SOURCE_NAMESPACE}" then behaves like namespaceDefinition = 'source'.
prefix: "" # REQUIRED | Prefix that will be prepended to the name of each stream when it is written to the destination
resourceRequirements: # OPTIONAL | object | Resource requirements to run workers (blank for unbounded allocations)
resource_requirements: # OPTIONAL | object | Resource requirements to run workers (blank for unbounded allocations)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to catch api exception or validate existing configs to provide a understandable error message to the user directing them to switch to snake_case, or re-generate the files.

cpu_limit: "" # OPTIONAL
cpu_request: "" # OPTIONAL
memory_limit: "" # OPTIONAL
memory_request: "" # OPTIONAL
schedule: # OPTIONAL | object
timeUnit: hours # REQUIRED | string | Allowed values: minutes, hours, days, weeks, months
time_unit: hours # REQUIRED | string | Allowed values: minutes, hours, days, weeks, months
units: 1 # REQUIRED | integer
syncCatalog: # OPTIONAL | object | 🚨 ONLY edit streams.config, streams.stream should not be edited as schema cannot be changed.
sync_catalog: # OPTIONAL | object | 🚨 ONLY edit streams.config, streams.stream should not be edited as schema cannot be changed.
streams:
- config:
aliasName: pokemon
cursorField: []
destinationSyncMode: append
primaryKey: []
alias_name: pokemon
cursor_field: []
destination_sync_mode: append
primary_key: []
selected: true
syncMode: full_refresh
sync_mode: full_refresh
stream:
defaultCursorField: []
jsonSchema:
default_cursor_field: []
json_schema:
$schema: http://json-schema.org/draft-07/schema#
properties:
abilities:
Expand Down Expand Up @@ -358,7 +355,7 @@ configuration:
type: object
name: pokemon
namespace: null
sourceDefinedCursor: null
sourceDefinedPrimaryKey: []
supportedSyncModes:
source_defined_cursor: null
source_defined_primary_key: []
supported_sync_modes:
- full_refresh
4 changes: 1 addition & 3 deletions octavia-cli/integration_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,13 @@ def updated_connection_configuration_and_path(octavia_test_project_directory, so
local_configuration = yaml.safe_load(dumb_local_configuration_file)
local_configuration["source_id"] = source.resource_id
local_configuration["destination_id"] = destination.resource_id
local_configuration["configuration"]["sourceId"] = source.resource_id
local_configuration["configuration"]["destinationId"] = destination.resource_id
with open(edited_path, "w") as updated_configuration_file:
yaml.dump(local_configuration, updated_configuration_file)
return local_configuration, edited_path


@pytest.fixture(scope="session")
def connection(api_client, workspace_id, octavia_test_project_directory, source, destination):
def connection(api_client, workspace_id, octavia_test_project_directory, source, destination, connection_state_path):
configuration, configuration_path = updated_connection_configuration_and_path(octavia_test_project_directory, source, destination)
connection = Connection(api_client, workspace_id, configuration, configuration_path)
yield connection
Expand Down
18 changes: 11 additions & 7 deletions octavia-cli/integration_tests/test_apply/test_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Copyright (c) 2021 Airbyte, Inc., all rights reserved.
#


import pytest

pytestmark = pytest.mark.integration
Expand All @@ -10,23 +11,25 @@
def test_source_lifecycle(source):
assert not source.was_created
source.create()
source.state = source._get_state_from_file()
source.state = source._get_state_from_file(source.configuration_path)
assert source.was_created
assert not source.get_diff_with_remote_resource()
source.local_configuration["configuration"]["pokemon_name"] = "snorlax"
source.raw_configuration["configuration"]["pokemon_name"] = "snorlax"
source.configuration = source._deserialize_raw_configuration()
assert 'changed from "ditto" to "snorlax"' in source.get_diff_with_remote_resource()
source.update()
assert not source.get_diff_with_remote_resource()
assert source.catalog["streams"][0]["config"]["aliasName"] == "pokemon"
assert source.catalog["streams"][0]["config"]["alias_name"] == "pokemon"


def test_destination_lifecycle(destination):
assert not destination.was_created
destination.create()
destination.state = destination._get_state_from_file()
destination.state = destination._get_state_from_file(destination.configuration_path)
assert destination.was_created
assert not destination.get_diff_with_remote_resource()
destination.local_configuration["configuration"]["host"] = "foo"
destination.raw_configuration["configuration"]["host"] = "foo"
destination.configuration = destination._deserialize_raw_configuration()
assert 'changed from "localhost" to "foo"' in destination.get_diff_with_remote_resource()
destination.update()
assert not destination.get_diff_with_remote_resource()
Expand All @@ -37,10 +40,11 @@ def test_connection_lifecycle(source, destination, connection):
assert destination.was_created
assert not connection.was_created
connection.create()
connection.state = connection._get_state_from_file()
connection.state = connection._get_state_from_file(connection.configuration_path)
assert connection.was_created
assert not connection.get_diff_with_remote_resource()
connection.local_configuration["configuration"]["status"] = "inactive"
connection.raw_configuration["configuration"]["status"] = "inactive"
connection.configuration = connection._deserialize_raw_configuration()
assert 'changed from "active" to "inactive"' in connection.get_diff_with_remote_resource()
connection.update()
assert not connection.get_diff_with_remote_resource()
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,19 @@ destination_id: my_destination_id

# EDIT THE CONFIGURATION BELOW!
configuration:
sourceId: my_source_id # REQUIRED | string
destinationId: my_destination_id # REQUIRED | string
status: active # REQUIRED | string | Allowed values: active, inactive, deprecated
name: my_new_connection # OPTIONAL | string | Optional name of the connection
namespaceDefinition: source # OPTIONAL | string | Allowed values: source, destination, customformat
namespaceFormat: "${SOURCE_NAMESPACE}" # OPTIONAL | string | Used when namespaceDefinition is 'customformat'. If blank then behaves like namespaceDefinition = 'destination'. If "${SOURCE_NAMESPACE}" then behaves like namespaceDefinition = 'source'.
namespace_definition: source # OPTIONAL | string | Allowed values: source, destination, customformat
namespace_format: "${SOURCE_NAMESPACE}" # OPTIONAL | string | Used when namespaceDefinition is 'customformat'. If blank then behaves like namespaceDefinition = 'destination'. If "${SOURCE_NAMESPACE}" then behaves like namespaceDefinition = 'source'.
prefix: "" # REQUIRED | Prefix that will be prepended to the name of each stream when it is written to the destination
resourceRequirements: # OPTIONAL | object | Resource requirements to run workers (blank for unbounded allocations)
resource_requirements: # OPTIONAL | object | Resource requirements to run workers (blank for unbounded allocations)
cpu_limit: "" # OPTIONAL
cpu_request: "" # OPTIONAL
memory_limit: "" # OPTIONAL
memory_request: "" # OPTIONAL
schedule: # OPTIONAL | object
timeUnit: hours # REQUIRED | string | Allowed values: minutes, hours, days, weeks, months
time_unit: hours # REQUIRED | string | Allowed values: minutes, hours, days, weeks, months
units: 1 # REQUIRED | integer
syncCatalog: # OPTIONAL | object | 🚨 ONLY edit streams.config, streams.stream should not be edited as schema cannot be changed.
sync_catalog: # OPTIONAL | object | 🚨 ONLY edit streams.config, streams.stream should not be edited as schema cannot be changed.
streams:
- config:
aliasName: aliasMock
Expand Down
Loading