diff --git a/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml b/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml index a2461de6285e7..ffd6473031b24 100644 --- a/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml +++ b/.github/ISSUE_TEMPLATE/airflow_providers_bug_report.yml @@ -41,6 +41,7 @@ body: - apache-pig - apache-pinot - apache-spark + - apache-tinkerpop - apprise - arangodb - asana diff --git a/.github/boring-cyborg.yml b/.github/boring-cyborg.yml index cff760ad9dc38..cf71336c9486c 100644 --- a/.github/boring-cyborg.yml +++ b/.github/boring-cyborg.yml @@ -72,6 +72,9 @@ labelPRBasedOnFilePath: provider:apache-spark: - providers/apache/spark/** + provider:apache-tinkerpop: + - providers/apache/tinkerpop/** + provider:apprise: - providers/apprise/** diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 964ebe4aa099c..976690a898cba 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -246,6 +246,9 @@ repos: name: Check that executables have shebang - id: check-xml name: Check XML files with xmllint + exclude: > + (?x) + ^scripts/ci/docker-compose/gremlin/. - id: trailing-whitespace name: Remove trailing whitespace at end of line exclude: ^airflow-core/docs/img/.*\.dot$|^dev/breeze/doc/images/output.*$ @@ -970,6 +973,7 @@ repos: exclude: > (?x) ^scripts/ci/docker-compose/grafana/.| + ^scripts/ci/docker-compose/gremlin/.| ^scripts/ci/docker-compose/.+-config\.ya?ml$ require_serial: true additional_dependencies: ['jsonschema>=3.2.0,<5.0', 'pyyaml>=6.0.2', 'requests==2.32.3', 'rich>=12.4.4'] diff --git a/airflow-core/docs/extra-packages-ref.rst b/airflow-core/docs/extra-packages-ref.rst index 9c360209ac22c..31d15dd324977 100644 --- a/airflow-core/docs/extra-packages-ref.rst +++ b/airflow-core/docs/extra-packages-ref.rst @@ -198,6 +198,8 @@ custom bash/python providers). +---------------------+-----------------------------------------------------+------------------------------------------------+ | apache-spark | ``pip install 'apache-airflow[apache-spark]'`` | All Spark related operators & hooks | +---------------------+-----------------------------------------------------+------------------------------------------------+ +| apache-tinkerpop | ``pip install apache-airflow[apache-tinkerpop]`` | Apache-tinkerpop hooks and operators | ++---------------------+-----------------------------------------------------+------------------------------------------------+ | apache-webhdfs | ``pip install 'apache-airflow[apache-webhdfs]'`` | HDFS hooks and operators | +---------------------+-----------------------------------------------------+------------------------------------------------+ diff --git a/airflow-core/src/airflow/utils/db.py b/airflow-core/src/airflow/utils/db.py index e4919d82bfd36..c7853adfabfbf 100644 --- a/airflow-core/src/airflow/utils/db.py +++ b/airflow-core/src/airflow/utils/db.py @@ -352,6 +352,15 @@ def create_default_connections(session: Session = NEW_SESSION): ), session, ) + merge_conn( + Connection( + conn_id="gremlin_default", + conn_type="gremlin", + host="gremlin", + port=8182, + ), + session, + ) merge_conn( Connection( conn_id="hive_cli_default", diff --git a/contributing-docs/testing/integration_tests.rst b/contributing-docs/testing/integration_tests.rst index 3be9f60a17a65..bc7e9c70f1d32 100644 --- a/contributing-docs/testing/integration_tests.rst +++ b/contributing-docs/testing/integration_tests.rst @@ -64,6 +64,8 @@ core or provider type of test. +--------------+-------------------------------------------------------+ | drill | Integration required for drill operator and hook. | +--------------+-------------------------------------------------------+ +| gremlin | Integration required for gremlin operator and hook. | ++--------------+-------------------------------------------------------+ | kafka | Integration required for Kafka hooks. | +--------------+-------------------------------------------------------+ | kerberos | Integration that provides Kerberos authentication. | diff --git a/dev/breeze/doc/images/output-commands.svg b/dev/breeze/doc/images/output-commands.svg index 2d9668f5a21af..b40f3cbf9b6a4 100644 --- a/dev/breeze/doc/images/output-commands.svg +++ b/dev/breeze/doc/images/output-commands.svg @@ -323,7 +323,7 @@ --integrationCore Integrations to enable when running (can be more   than one).                                              (all | all-testable | cassandra | celery | drill |      -kafka | kerberos | keycloak | mongo | mssql |           +gremlin | kafka | kerberos | keycloak | mongo | mssql | openlineage | otel | pinot | qdrant | redis | statsd |  trino | ydb)                                            --standalone-dag-processor/--no-standalone-dag-processoRun standalone dag processor for start-airflow          diff --git a/dev/breeze/doc/images/output_build-docs.svg b/dev/breeze/doc/images/output_build-docs.svg index f433121431045..f4421e33dc256 100644 --- a/dev/breeze/doc/images/output_build-docs.svg +++ b/dev/breeze/doc/images/output_build-docs.svg @@ -194,15 +194,15 @@ breeze build-docs                                                                                                      [OPTIONS] [airbyte | alibaba | all-providers | amazon | apache-airflow | apache-airflow-providers | apache.beam |      apache.cassandra | apache.drill | apache.druid | apache.flink | apache.hdfs | apache.hive | apache.iceberg |           -apache.impala | apache.kafka | apache.kylin | apache.livy | apache.pig | apache.pinot | apache.spark | apprise |       -arangodb | asana | atlassian.jira | celery | cloudant | cncf.kubernetes | cohere | common.compat | common.io |         -common.messaging | common.sql | databricks | datadog | dbt.cloud | dingding | discord | docker | docker-stack | edge3 -elasticsearch | exasol | fab | facebook | ftp | git | github | google | grpc | hashicorp | helm-chart | http | imap -influxdb | jdbc | jenkins | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo | mysql |   -neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill | pgvector |   -pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sendgrid | sftp | singularity | slack | -smtp | snowflake | sqlite | ssh | standard | tableau | telegram | teradata | trino | vertica | weaviate | yandex | ydb -zendesk]...                                                                                                          +apache.impala | apache.kafka | apache.kylin | apache.livy | apache.pig | apache.pinot | apache.spark |                 +apache.tinkerpop | apprise | arangodb | asana | atlassian.jira | celery | cloudant | cncf.kubernetes | cohere |        +common.compat | common.io | common.messaging | common.sql | databricks | datadog | dbt.cloud | dingding | discord |    +docker | docker-stack | edge3 | elasticsearch | exasol | fab | facebook | ftp | git | github | google | grpc |         +hashicorp | helm-chart | http | imap | influxdb | jdbc | jenkins | microsoft.azure | microsoft.mssql | microsoft.psrp +microsoft.winrm | mongo | mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle |  +pagerduty | papermill | pgvector | pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment |      +sendgrid | sftp | singularity | slack | smtp | snowflake | sqlite | ssh | standard | tableau | telegram | teradata |   +trino | vertica | weaviate | yandex | ydb | zendesk]...                                                                Build documents. diff --git a/dev/breeze/doc/images/output_build-docs.txt b/dev/breeze/doc/images/output_build-docs.txt index 0af15214ce8cc..b8ce7331d5e1e 100644 --- a/dev/breeze/doc/images/output_build-docs.txt +++ b/dev/breeze/doc/images/output_build-docs.txt @@ -1 +1 @@ -23e0abc8bc26f17cd7e033a3b5654cb4 +8ae2b68e8981f5fc57c32b7e064211bd diff --git a/dev/breeze/doc/images/output_release-management_add-back-references.svg b/dev/breeze/doc/images/output_release-management_add-back-references.svg index 54d7a14e6adba..b9bf811ef24eb 100644 --- a/dev/breeze/doc/images/output_release-management_add-back-references.svg +++ b/dev/breeze/doc/images/output_release-management_add-back-references.svg @@ -142,15 +142,15 @@ breeze release-management add-back-references                                                                          [OPTIONS] [airbyte | alibaba | all-providers | amazon | apache-airflow | apache-airflow-providers | apache.beam |      apache.cassandra | apache.drill | apache.druid | apache.flink | apache.hdfs | apache.hive | apache.iceberg |           -apache.impala | apache.kafka | apache.kylin | apache.livy | apache.pig | apache.pinot | apache.spark | apprise |       -arangodb | asana | atlassian.jira | celery | cloudant | cncf.kubernetes | cohere | common.compat | common.io |         -common.messaging | common.sql | databricks | datadog | dbt.cloud | dingding | discord | docker | docker-stack | edge3 -elasticsearch | exasol | fab | facebook | ftp | git | github | google | grpc | hashicorp | helm-chart | http | imap -influxdb | jdbc | jenkins | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo | mysql |   -neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill | pgvector |   -pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sendgrid | sftp | singularity | slack | -smtp | snowflake | sqlite | ssh | standard | tableau | telegram | teradata | trino | vertica | weaviate | yandex | ydb -zendesk]...                                                                                                          +apache.impala | apache.kafka | apache.kylin | apache.livy | apache.pig | apache.pinot | apache.spark |                 +apache.tinkerpop | apprise | arangodb | asana | atlassian.jira | celery | cloudant | cncf.kubernetes | cohere |        +common.compat | common.io | common.messaging | common.sql | databricks | datadog | dbt.cloud | dingding | discord |    +docker | docker-stack | edge3 | elasticsearch | exasol | fab | facebook | ftp | git | github | google | grpc |         +hashicorp | helm-chart | http | imap | influxdb | jdbc | jenkins | microsoft.azure | microsoft.mssql | microsoft.psrp +microsoft.winrm | mongo | mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle |  +pagerduty | papermill | pgvector | pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment |      +sendgrid | sftp | singularity | slack | smtp | snowflake | sqlite | ssh | standard | tableau | telegram | teradata |   +trino | vertica | weaviate | yandex | ydb | zendesk]...                                                                Command to add back references for documentation to make it backward compatible. diff --git a/dev/breeze/doc/images/output_release-management_add-back-references.txt b/dev/breeze/doc/images/output_release-management_add-back-references.txt index b0761c9ff313b..6373b2f3555d8 100644 --- a/dev/breeze/doc/images/output_release-management_add-back-references.txt +++ b/dev/breeze/doc/images/output_release-management_add-back-references.txt @@ -1 +1 @@ -fbcb4084b1e42f4fb8be2d5a43d81019 +121c5c2424354100827502bc6a6e09c3 diff --git a/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.svg b/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.svg index e8f786ea94099..17845a419b447 100644 --- a/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.svg +++ b/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.svg @@ -143,14 +143,14 @@ breeze release-management generate-issue-content-providers                                                             [OPTIONS] [airbyte | alibaba | amazon | apache.beam | apache.cassandra | apache.drill | apache.druid | apache.flink |  apache.hdfs | apache.hive | apache.iceberg | apache.impala | apache.kafka | apache.kylin | apache.livy | apache.pig |  -apache.pinot | apache.spark | apprise | arangodb | asana | atlassian.jira | celery | cloudant | cncf.kubernetes |      -cohere | common.compat | common.io | common.messaging | common.sql | databricks | datadog | dbt.cloud | dingding |     -discord | docker | edge3 | elasticsearch | exasol | fab | facebook | ftp | git | github | google | grpc | hashicorp |  -http | imap | influxdb | jdbc | jenkins | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo -mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill |    -pgvector | pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sftp | singularity | slack | -smtp | snowflake | sqlite | ssh | standard | tableau | telegram | teradata | trino | vertica | weaviate | yandex | ydb -zendesk]...                                                                                                          +apache.pinot | apache.spark | apache.tinkerpop | apprise | arangodb | asana | atlassian.jira | celery | cloudant |     +cncf.kubernetes | cohere | common.compat | common.io | common.messaging | common.sql | databricks | datadog |          +dbt.cloud | dingding | discord | docker | edge3 | elasticsearch | exasol | fab | facebook | ftp | git | github |       +google | grpc | hashicorp | http | imap | influxdb | jdbc | jenkins | microsoft.azure | microsoft.mssql |              +microsoft.psrp | microsoft.winrm | mongo | mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch |       +opsgenie | oracle | pagerduty | papermill | pgvector | pinecone | postgres | presto | qdrant | redis | salesforce |    +samba | segment | sftp | singularity | slack | smtp | snowflake | sqlite | ssh | standard | tableau | telegram |       +teradata | trino | vertica | weaviate | yandex | ydb | zendesk]...                                                     Generates content for issue to test the release. diff --git a/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.txt b/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.txt index deb7377e876e9..482879d9ca349 100644 --- a/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.txt +++ b/dev/breeze/doc/images/output_release-management_generate-issue-content-providers.txt @@ -1 +1 @@ -8539b9fa5e6f545a226180fb2b0479bb +585e7edc334db3e051441aa73afdec7b diff --git a/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.svg b/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.svg index 9f97ecd9e2ef7..075f044461a21 100644 --- a/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.svg +++ b/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.svg @@ -197,14 +197,14 @@ breeze release-management prepare-provider-distributions                                                               [OPTIONS] [airbyte | alibaba | amazon | apache.beam | apache.cassandra | apache.drill | apache.druid | apache.flink |  apache.hdfs | apache.hive | apache.iceberg | apache.impala | apache.kafka | apache.kylin | apache.livy | apache.pig |  -apache.pinot | apache.spark | apprise | arangodb | asana | atlassian.jira | celery | cloudant | cncf.kubernetes |      -cohere | common.compat | common.io | common.messaging | common.sql | databricks | datadog | dbt.cloud | dingding |     -discord | docker | edge3 | elasticsearch | exasol | fab | facebook | ftp | git | github | google | grpc | hashicorp |  -http | imap | influxdb | jdbc | jenkins | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo -mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill |    -pgvector | pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sftp | singularity | slack | -smtp | snowflake | sqlite | ssh | standard | tableau | telegram | teradata | trino | vertica | weaviate | yandex | ydb -zendesk]...                                                                                                          +apache.pinot | apache.spark | apache.tinkerpop | apprise | arangodb | asana | atlassian.jira | celery | cloudant |     +cncf.kubernetes | cohere | common.compat | common.io | common.messaging | common.sql | databricks | datadog |          +dbt.cloud | dingding | discord | docker | edge3 | elasticsearch | exasol | fab | facebook | ftp | git | github |       +google | grpc | hashicorp | http | imap | influxdb | jdbc | jenkins | microsoft.azure | microsoft.mssql |              +microsoft.psrp | microsoft.winrm | mongo | mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch |       +opsgenie | oracle | pagerduty | papermill | pgvector | pinecone | postgres | presto | qdrant | redis | salesforce |    +samba | segment | sftp | singularity | slack | smtp | snowflake | sqlite | ssh | standard | tableau | telegram |       +teradata | trino | vertica | weaviate | yandex | ydb | zendesk]...                                                     Prepare sdist/whl distributions of Airflow Providers. diff --git a/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.txt b/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.txt index f5292cbc8cacf..6b9757d044820 100644 --- a/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.txt +++ b/dev/breeze/doc/images/output_release-management_prepare-provider-distributions.txt @@ -1 +1 @@ -b4d234fbf771ca1e4b14c92ab7d3e910 +09dd7c6e5817710841fd90c4ac05b4d2 diff --git a/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.svg b/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.svg index 3f64f75e93ce5..20ffd7ee61ce5 100644 --- a/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.svg +++ b/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.svg @@ -188,14 +188,14 @@ breeze release-management prepare-provider-documentation                                                               [OPTIONS] [airbyte | alibaba | amazon | apache.beam | apache.cassandra | apache.drill | apache.druid | apache.flink |  apache.hdfs | apache.hive | apache.iceberg | apache.impala | apache.kafka | apache.kylin | apache.livy | apache.pig |  -apache.pinot | apache.spark | apprise | arangodb | asana | atlassian.jira | celery | cloudant | cncf.kubernetes |      -cohere | common.compat | common.io | common.messaging | common.sql | databricks | datadog | dbt.cloud | dingding |     -discord | docker | edge3 | elasticsearch | exasol | fab | facebook | ftp | git | github | google | grpc | hashicorp |  -http | imap | influxdb | jdbc | jenkins | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo -mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill |    -pgvector | pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sftp | singularity | slack | -smtp | snowflake | sqlite | ssh | standard | tableau | telegram | teradata | trino | vertica | weaviate | yandex | ydb -zendesk]...                                                                                                          +apache.pinot | apache.spark | apache.tinkerpop | apprise | arangodb | asana | atlassian.jira | celery | cloudant |     +cncf.kubernetes | cohere | common.compat | common.io | common.messaging | common.sql | databricks | datadog |          +dbt.cloud | dingding | discord | docker | edge3 | elasticsearch | exasol | fab | facebook | ftp | git | github |       +google | grpc | hashicorp | http | imap | influxdb | jdbc | jenkins | microsoft.azure | microsoft.mssql |              +microsoft.psrp | microsoft.winrm | mongo | mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch |       +opsgenie | oracle | pagerduty | papermill | pgvector | pinecone | postgres | presto | qdrant | redis | salesforce |    +samba | segment | sftp | singularity | slack | smtp | snowflake | sqlite | ssh | standard | tableau | telegram |       +teradata | trino | vertica | weaviate | yandex | ydb | zendesk]...                                                     Prepare CHANGELOG, README and COMMITS information for providers. diff --git a/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.txt b/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.txt index f28c1c909ed51..b29249194c7a4 100644 --- a/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.txt +++ b/dev/breeze/doc/images/output_release-management_prepare-provider-documentation.txt @@ -1 +1 @@ -7da34b87ae2b46a281d523e28f4bbfb5 +53c659a34bafdcf7c012eb578dab893f diff --git a/dev/breeze/doc/images/output_release-management_publish-docs.svg b/dev/breeze/doc/images/output_release-management_publish-docs.svg index bd70f79c4c176..831be65d4081f 100644 --- a/dev/breeze/doc/images/output_release-management_publish-docs.svg +++ b/dev/breeze/doc/images/output_release-management_publish-docs.svg @@ -199,15 +199,15 @@ breeze release-management publish-docs                                                                                 [OPTIONS] [airbyte | alibaba | all-providers | amazon | apache-airflow | apache-airflow-providers | apache.beam |      apache.cassandra | apache.drill | apache.druid | apache.flink | apache.hdfs | apache.hive | apache.iceberg |           -apache.impala | apache.kafka | apache.kylin | apache.livy | apache.pig | apache.pinot | apache.spark | apprise |       -arangodb | asana | atlassian.jira | celery | cloudant | cncf.kubernetes | cohere | common.compat | common.io |         -common.messaging | common.sql | databricks | datadog | dbt.cloud | dingding | discord | docker | docker-stack | edge3 -elasticsearch | exasol | fab | facebook | ftp | git | github | google | grpc | hashicorp | helm-chart | http | imap -influxdb | jdbc | jenkins | microsoft.azure | microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo | mysql |   -neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill | pgvector |   -pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sendgrid | sftp | singularity | slack | -smtp | snowflake | sqlite | ssh | standard | tableau | telegram | teradata | trino | vertica | weaviate | yandex | ydb -zendesk]...                                                                                                          +apache.impala | apache.kafka | apache.kylin | apache.livy | apache.pig | apache.pinot | apache.spark |                 +apache.tinkerpop | apprise | arangodb | asana | atlassian.jira | celery | cloudant | cncf.kubernetes | cohere |        +common.compat | common.io | common.messaging | common.sql | databricks | datadog | dbt.cloud | dingding | discord |    +docker | docker-stack | edge3 | elasticsearch | exasol | fab | facebook | ftp | git | github | google | grpc |         +hashicorp | helm-chart | http | imap | influxdb | jdbc | jenkins | microsoft.azure | microsoft.mssql | microsoft.psrp +microsoft.winrm | mongo | mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle |  +pagerduty | papermill | pgvector | pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment |      +sendgrid | sftp | singularity | slack | smtp | snowflake | sqlite | ssh | standard | tableau | telegram | teradata |   +trino | vertica | weaviate | yandex | ydb | zendesk]...                                                                Command to publish generated documentation to airflow-site diff --git a/dev/breeze/doc/images/output_release-management_publish-docs.txt b/dev/breeze/doc/images/output_release-management_publish-docs.txt index fc7cd0b3bbc65..c0f2a006df77e 100644 --- a/dev/breeze/doc/images/output_release-management_publish-docs.txt +++ b/dev/breeze/doc/images/output_release-management_publish-docs.txt @@ -1 +1 @@ -f50847005b110bf0474ba730172efd8b +4051081e930cd2c899a8db9c614d0ed2 diff --git a/dev/breeze/doc/images/output_sbom_generate-providers-requirements.svg b/dev/breeze/doc/images/output_sbom_generate-providers-requirements.svg index c591c16de3aa1..d37cb29f1ccf1 100644 --- a/dev/breeze/doc/images/output_sbom_generate-providers-requirements.svg +++ b/dev/breeze/doc/images/output_sbom_generate-providers-requirements.svg @@ -188,12 +188,12 @@ --provider-idProvider id to generate the requirements for                                                   (airbyte | alibaba | amazon | apache.beam | apache.cassandra | apache.drill | apache.druid |   apache.flink | apache.hdfs | apache.hive | apache.iceberg | apache.impala | apache.kafka |     -apache.kylin | apache.livy | apache.pig | apache.pinot | apache.spark | apprise | arangodb |   -asana | atlassian.jira | celery | cloudant | cncf.kubernetes | cohere | common.compat |        -common.io | common.messaging | common.sql | databricks | datadog | dbt.cloud | dingding |      -discord | docker | edge3 | elasticsearch | exasol | fab | facebook | ftp | git | github |      -google | grpc | hashicorp | http | imap | influxdb | jdbc | jenkins | microsoft.azure |        -microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo | mysql | neo4j | odbc | openai |   +apache.kylin | apache.livy | apache.pig | apache.pinot | apache.spark | apache.tinkerpop |     +apprise | arangodb | asana | atlassian.jira | celery | cloudant | cncf.kubernetes | cohere |   +common.compat | common.io | common.messaging | common.sql | databricks | datadog | dbt.cloud | +dingding | discord | docker | edge3 | elasticsearch | exasol | fab | facebook | ftp | git |    +github | google | grpc | hashicorp | http | imap | influxdb | jdbc | jenkins | microsoft.azure +| microsoft.mssql | microsoft.psrp | microsoft.winrm | mongo | mysql | neo4j | odbc | openai | openfaas | openlineage | opensearch | opsgenie | oracle | pagerduty | papermill | pgvector |   pinecone | postgres | presto | qdrant | redis | salesforce | samba | segment | sendgrid | sftp | singularity | slack | smtp | snowflake | sqlite | ssh | standard | tableau | telegram |      diff --git a/dev/breeze/doc/images/output_sbom_generate-providers-requirements.txt b/dev/breeze/doc/images/output_sbom_generate-providers-requirements.txt index 1c70f48771cde..7799d72651b51 100644 --- a/dev/breeze/doc/images/output_sbom_generate-providers-requirements.txt +++ b/dev/breeze/doc/images/output_sbom_generate-providers-requirements.txt @@ -1 +1 @@ -9df7dccf519dc82ef16b95a8102936fd +781a886d7ccd2537dd9af7a479bb3007 diff --git a/dev/breeze/doc/images/output_shell.svg b/dev/breeze/doc/images/output_shell.svg index ff42b6fcd75ab..c33e37ad242be 100644 --- a/dev/breeze/doc/images/output_shell.svg +++ b/dev/breeze/doc/images/output_shell.svg @@ -547,7 +547,7 @@ --integrationCore Integrations to enable when running (can be more   than one).                                              (all | all-testable | cassandra | celery | drill |      -kafka | kerberos | keycloak | mongo | mssql |           +gremlin | kafka | kerberos | keycloak | mongo | mssql | openlineage | otel | pinot | qdrant | redis | statsd |  trino | ydb)                                            --load-example-dags-eEnable configuration to load example DAGs when starting diff --git a/dev/breeze/doc/images/output_shell.txt b/dev/breeze/doc/images/output_shell.txt index bc1afa16956f4..4bc4dbed2a13d 100644 --- a/dev/breeze/doc/images/output_shell.txt +++ b/dev/breeze/doc/images/output_shell.txt @@ -1 +1 @@ -19ef098d3ebe4f9a7d5a4c805600bcfd +664f71ecf40d322c88efa458a7e1a564 diff --git a/dev/breeze/doc/images/output_start-airflow.svg b/dev/breeze/doc/images/output_start-airflow.svg index 9cb6a3acdfbf1..68db41092407c 100644 --- a/dev/breeze/doc/images/output_start-airflow.svg +++ b/dev/breeze/doc/images/output_start-airflow.svg @@ -441,7 +441,7 @@ --integrationCore Integrations to enable when running (can be more   than one).                                              (all | all-testable | cassandra | celery | drill |      -kafka | kerberos | keycloak | mongo | mssql |           +gremlin | kafka | kerberos | keycloak | mongo | mssql | openlineage | otel | pinot | qdrant | redis | statsd |  trino | ydb)                                            --standalone-dag-processor/--no-standalone-dag-processoRun standalone dag processor for start-airflow          diff --git a/dev/breeze/doc/images/output_start-airflow.txt b/dev/breeze/doc/images/output_start-airflow.txt index 34e5ac548698a..12d99f7aa940b 100644 --- a/dev/breeze/doc/images/output_start-airflow.txt +++ b/dev/breeze/doc/images/output_start-airflow.txt @@ -1 +1 @@ -d17743200dad3972e3432e9c2e91ba02 +bae200412140579f690c72361f82f838 diff --git a/dev/breeze/doc/images/output_testing_providers-integration-tests.svg b/dev/breeze/doc/images/output_testing_providers-integration-tests.svg index 4f85c968d2203..71bce41db52bd 100644 --- a/dev/breeze/doc/images/output_testing_providers-integration-tests.svg +++ b/dev/breeze/doc/images/output_testing_providers-integration-tests.svg @@ -237,8 +237,8 @@ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Integration tests ──────────────────────────────────────────────────────────────────────────────────────────────────╮ --integrationProviders Integration(s) to enable when running (can be more than one).                             -(all | all-testable | cassandra | celery | drill | kafka | mongo | mssql | openlineage | pinot |    -qdrant | redis | trino | ydb)                                                                       +(all | all-testable | cassandra | celery | drill | gremlin | kafka | mongo | mssql | openlineage |  +pinot | qdrant | redis | trino | ydb)                                                               ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─ Advanced flag for tests command ────────────────────────────────────────────────────────────────────────────────────╮ --github-repository-gGitHub repository used to pull, push run images.(TEXT)[default: apache/airflow] diff --git a/dev/breeze/doc/images/output_testing_providers-integration-tests.txt b/dev/breeze/doc/images/output_testing_providers-integration-tests.txt index 4796ca1d55b1d..1b6995e16c3d1 100644 --- a/dev/breeze/doc/images/output_testing_providers-integration-tests.txt +++ b/dev/breeze/doc/images/output_testing_providers-integration-tests.txt @@ -1 +1 @@ -a384620e2acf2a0f693c742a7b1d41a5 +48aafaf7c9282ae70307e168ffefb0ab diff --git a/dev/breeze/src/airflow_breeze/global_constants.py b/dev/breeze/src/airflow_breeze/global_constants.py index d131afb86482a..5910f86ec811f 100644 --- a/dev/breeze/src/airflow_breeze/global_constants.py +++ b/dev/breeze/src/airflow_breeze/global_constants.py @@ -64,6 +64,7 @@ "celery", "cassandra", "drill", + "gremlin", "kafka", "mongo", "mssql", @@ -353,6 +354,7 @@ def get_default_platform_machine() -> str: DRILL_HOST_PORT = "28047" FLOWER_HOST_PORT = "25555" +GREMLIN_HOST_PORT = "8182" MSSQL_HOST_PORT = "21433" MYSQL_HOST_PORT = "23306" POSTGRES_HOST_PORT = "25433" diff --git a/dev/breeze/src/airflow_breeze/params/shell_params.py b/dev/breeze/src/airflow_breeze/params/shell_params.py index 363078439b5b2..947ac2c54f222 100644 --- a/dev/breeze/src/airflow_breeze/params/shell_params.py +++ b/dev/breeze/src/airflow_breeze/params/shell_params.py @@ -46,6 +46,7 @@ EDGE_EXECUTOR, FAB_AUTH_MANAGER, FLOWER_HOST_PORT, + GREMLIN_HOST_PORT, KEYCLOAK_INTEGRATION, MOUNT_ALL, MOUNT_PROVIDERS_AND_TESTS, @@ -581,6 +582,7 @@ def env_variables_for_docker_commands(self) -> dict[str, str]: _set_var(_env, "DRILL_HOST_PORT", None, DRILL_HOST_PORT) _set_var(_env, "ENABLE_COVERAGE", self.enable_coverage) _set_var(_env, "FLOWER_HOST_PORT", None, FLOWER_HOST_PORT) + _set_var(_env, "GREMLIN_HOST_PORT", None, GREMLIN_HOST_PORT) _set_var(_env, "EXCLUDED_PROVIDERS", self.excluded_providers) _set_var(_env, "FORCE_LOWEST_DEPENDENCIES", self.force_lowest_dependencies) _set_var(_env, "SQLALCHEMY_WARN_20", self.force_sa_warnings) diff --git a/dev/breeze/tests/test_pytest_args_for_test_types.py b/dev/breeze/tests/test_pytest_args_for_test_types.py index 7a1ef48f21535..fa0e48f519790 100644 --- a/dev/breeze/tests/test_pytest_args_for_test_types.py +++ b/dev/breeze/tests/test_pytest_args_for_test_types.py @@ -63,6 +63,7 @@ def _find_all_integration_folders() -> list[str]: "providers/apache/hive/tests/integration", "providers/apache/kafka/tests/integration", "providers/apache/pinot/tests/integration", + "providers/apache/tinkerpop/tests/integration", "providers/celery/tests/integration", "providers/google/tests/integration", "providers/microsoft/mssql/tests/integration", diff --git a/dev/breeze/tests/test_selective_checks.py b/dev/breeze/tests/test_selective_checks.py index 3469ee95168a9..6a87e8146b3a0 100644 --- a/dev/breeze/tests/test_selective_checks.py +++ b/dev/breeze/tests/test_selective_checks.py @@ -1123,8 +1123,8 @@ def assert_outputs_are_printed(expected_outputs: dict[str, str], stderr: str): "core-test-types-list-as-strings-in-json": ALL_CI_SELECTIVE_TEST_TYPES_AS_JSON, "providers-test-types-list-as-strings-in-json": ALL_PROVIDERS_SELECTIVE_TEST_TYPES_AS_JSON, "testable-core-integrations": "['kerberos']", - "testable-providers-integrations": "['celery', 'cassandra', 'drill', 'kafka', 'mongo', " - "'pinot', 'qdrant', 'redis', 'trino', 'ydb']", + "testable-providers-integrations": "['celery', 'cassandra', 'drill', 'gremlin', 'kafka', " + "'mongo', 'pinot', 'qdrant', 'redis', 'trino', 'ydb']", "needs-mypy": "true", "mypy-checks": ALL_MYPY_CHECKS, }, diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index 93514805fd598..b5275a37c8c69 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -1813,6 +1813,9 @@ timedeltas timeframe timespan timezones +TinkerPop +Tinkerpop +tinkerpop tis TLS tls diff --git a/providers/apache/tinkerpop/README.rst b/providers/apache/tinkerpop/README.rst new file mode 100644 index 0000000000000..5ac5a4238690e --- /dev/null +++ b/providers/apache/tinkerpop/README.rst @@ -0,0 +1,63 @@ + +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + +.. http://www.apache.org/licenses/LICENSE-2.0 + +.. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +.. NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE OVERWRITTEN! + +.. IF YOU WANT TO MODIFY TEMPLATE FOR THIS FILE, YOU SHOULD MODIFY THE TEMPLATE + ``PROVIDER_README_TEMPLATE.rst.jinja2`` IN the ``dev/breeze/src/airflow_breeze/templates`` DIRECTORY + +Package ``apache-airflow-providers-apache-tinkerpop`` + +Release: ``1.0.0`` + + +`Apache TinkerPop `__. +Apache TinkerPop is a graph computing framework for both graph databases (OLTP) and graph analytic +systems (OLAP) and Gremlin is its graph traversal language. + + +Provider package +---------------- + +This is a provider package for ``apache.tinkerpop`` provider. All classes for this provider package +are in ``airflow.providers.apache.tinkerpop`` python package. + +You can find package information and changelog for the provider +in the `documentation `_. + +Installation +------------ + +You can install this package on top of an existing Airflow 2 installation (see ``Requirements`` below +for the minimum Airflow version supported) via +``pip install apache-airflow-providers-apache-tinkerpop`` + +The package supports the following python versions: 3.9,3.10,3.11,3.12 + +Requirements +------------ + +================== ================== +PIP package Version required +================== ================== +``apache-airflow`` ``>=2.9.0`` +``gremlinpython`` ``>=3.7.0`` +================== ================== + +The changelog for the provider package can be found in the +`changelog `_. diff --git a/providers/apache/tinkerpop/docs/changelog.rst b/providers/apache/tinkerpop/docs/changelog.rst new file mode 100644 index 0000000000000..dbb7f2a36d5ae --- /dev/null +++ b/providers/apache/tinkerpop/docs/changelog.rst @@ -0,0 +1,24 @@ + .. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + .. http://www.apache.org/licenses/LICENSE-2.0 + + .. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +``apache-airflow-providers-apache-tinkerpop`` + + +1.0.0 +..... + +* ``Initial version of the provider. (#47466)`` diff --git a/providers/apache/tinkerpop/docs/commits.rst b/providers/apache/tinkerpop/docs/commits.rst new file mode 100644 index 0000000000000..b7a280ec6bdc6 --- /dev/null +++ b/providers/apache/tinkerpop/docs/commits.rst @@ -0,0 +1,35 @@ + + .. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + .. http://www.apache.org/licenses/LICENSE-2.0 + + .. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + .. NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE OVERWRITTEN! + + .. IF YOU WANT TO MODIFY THIS FILE, YOU SHOULD MODIFY THE TEMPLATE + `PROVIDER_COMMITS_TEMPLATE.rst.jinja2` IN the `dev/breeze/src/airflow_breeze/templates` DIRECTORY + + .. THE REMAINDER OF THE FILE IS AUTOMATICALLY GENERATED. IT WILL BE OVERWRITTEN! + +Package apache-airflow-providers-apache-tinkerpop +------------------------------------------------------ + +`Apache TinkerPop `__. +Apache TinkerPop is a graph computing framework for both graph databases (OLTP) and graph analytic +systems (OLAP) and Gremlin is its graph traversal language. + + +This is detailed commit list of changes for versions provider package: ``apache.tinkerpop``. +For high-level changelog, see :doc:`package information including changelog `. diff --git a/providers/apache/tinkerpop/docs/conf.py b/providers/apache/tinkerpop/docs/conf.py new file mode 100644 index 0000000000000..377a7626ba9d1 --- /dev/null +++ b/providers/apache/tinkerpop/docs/conf.py @@ -0,0 +1,27 @@ +# Disable Flake8 because of all the sphinx imports +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +"""Configuration of Providers docs building.""" + +from __future__ import annotations + +import os + +os.environ["AIRFLOW_PACKAGE_NAME"] = "apache-airflow-providers-apache-tinkerpop" + +from docs.provider_conf import * # noqa: F403 diff --git a/providers/apache/tinkerpop/docs/connections/tinkerpop.rst b/providers/apache/tinkerpop/docs/connections/tinkerpop.rst new file mode 100644 index 0000000000000..ce64ad135cd8c --- /dev/null +++ b/providers/apache/tinkerpop/docs/connections/tinkerpop.rst @@ -0,0 +1,88 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + +.. http://www.apache.org/licenses/LICENSE-2.0 + +.. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + + +.. _howto/connection:tinkerpop: + +Gremlin Connection +==================== + +The Gremlin connection type enables integrations with Gremlin Server. + +Authenticating to Gremlin +--------------------------- + +Authenticate to Gremlin using the `Germlin python client default authentication +`_. + +Default Connection IDs +---------------------- + +Hooks and operators related to Gremlin use ``gremlin_default`` by default. + +Configuring the Connection +-------------------------- + +Use the ``gremlin_conn_id`` argument to connect to your Gremlin instance where +the connection metadata is structured as follows: + +.. list-table:: Gremlin Airflow Connection Metadata + :widths: 25 25 + :header-rows: 1 + + * - Parameter + - Input + * - Host: string + - Gremlin hostname + * - Port: int + - Gremlin port + * - Username: string + - Gremlin user + * - Password: string + - Gremlin user password + * - Scheme: string + - Gremlin Scheme + * - Schema: string + - Gremlin Schema + +URI format example +^^^^^^^^^^^^^^^^^^ + +If serializing with Airflow URI: + +.. code-block:: bash + + export AIRFLOW_CONN_GREMLIN_DEFAULT='gremlin://username:password@host:port/schema' + +Note that all components of the URI should be URL-encoded. + +JSON format example +^^^^^^^^^^^^^^^^^^^ + +If serializing with JSON: + +.. code-block:: bash + + export AIRFLOW_CONN_GREMLIN_DEFAULT='{ + "conn_type": "gremlin", + "login": "username", + "host": "host", + "password": "password", + "schema": "schema", + "port": 433 + }' diff --git a/providers/apache/tinkerpop/docs/index.rst b/providers/apache/tinkerpop/docs/index.rst new file mode 100644 index 0000000000000..1205b73736495 --- /dev/null +++ b/providers/apache/tinkerpop/docs/index.rst @@ -0,0 +1,107 @@ + + .. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + .. http://www.apache.org/licenses/LICENSE-2.0 + + .. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +Package ``apache-airflow-providers-apache-tinkerpop`` +===================================================== + +.. toctree:: + :hidden: + :maxdepth: 1 + :caption: Basics + + Home + Changelog + Security + +.. toctree:: + :hidden: + :maxdepth: 1 + :caption: Guides + + Connection Types + Operators + +.. toctree:: + :hidden: + :maxdepth: 1 + :caption: References + + Python API <_api/airflow/providers/apache/tinkerpop/index> + +.. toctree:: + :hidden: + :maxdepth: 1 + :caption: System tests + + System Tests <_api/tests/system/apache/tinkerpop/index> + +.. toctree:: + :hidden: + :maxdepth: 1 + :caption: Resources + + Example DAGs + PyPI Repository + Installing from sources + +.. THE REMAINDER OF THE FILE IS AUTOMATICALLY GENERATED. IT WILL BE OVERWRITTEN AT RELEASE TIME! + + +.. toctree:: + :hidden: + :maxdepth: 1 + :caption: Commits + + Detailed list of commits + + +apache-airflow-providers-apache-tinkerpop package +------------------------------------------------------ + +`Apache TinkerPop `__. +Apache TinkerPop is a graph computing framework for both graph databases (OLTP) and graph analytic +systems (OLAP) and Gremlin is its graph traversal language. + + +Release: 1.0.0 + +Provider package +---------------- + +This package is for the ``apache.tinkerpop`` provider. +All classes for this package are included in the ``airflow.providers.apache.tinkerpop`` python package. + +Installation +------------ + +You can install this package on top of an existing Airflow 2 installation via +``pip install apache-airflow-providers-apache-tinkerpop``. +For the minimum Airflow version supported, see ``Requirements`` below. + +Requirements +------------ + +The minimum Apache Airflow version supported by this provider package is ``2.9.0``. + +================== ================== +PIP package Version required +================== ================== +``apache-airflow`` ``>=2.9.0`` +``gremlinpython`` ``>=3.7.0`` +``nest-asyncio`` ``>=1.6.0`` +================== ================== diff --git a/providers/apache/tinkerpop/docs/installing-providers-from-sources.rst b/providers/apache/tinkerpop/docs/installing-providers-from-sources.rst new file mode 100644 index 0000000000000..fdbb17d017579 --- /dev/null +++ b/providers/apache/tinkerpop/docs/installing-providers-from-sources.rst @@ -0,0 +1,18 @@ + .. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + .. http://www.apache.org/licenses/LICENSE-2.0 + + .. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +.. include:: /../../../../devel-common/src/sphinx_exts/includes/installing-providers-from-sources.rst diff --git a/providers/apache/tinkerpop/docs/operators/tinkerpop.rst b/providers/apache/tinkerpop/docs/operators/tinkerpop.rst new file mode 100644 index 0000000000000..cb1e73addb480 --- /dev/null +++ b/providers/apache/tinkerpop/docs/operators/tinkerpop.rst @@ -0,0 +1,46 @@ + .. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + .. http://www.apache.org/licenses/LICENSE-2.0 + + .. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + + +Apache TinkerPop Operators +========================== + +.. _howto/operator:`GremlinOperator`: + +GremlinOperator +--------------- + +Executes Gremlin queries on a remote Gremlin Server. + +For parameter definition take a look at :class:`~airflow.providers.apache.tinkerpop.operators.gremlin.GremlinOperator`. + +Using the operator +"""""""""""""""""" + +An example usage of the GremlinOperator to query from gremlin server is as follows: + +.. exampleinclude:: /../tests/system/apache/tinkerpop/example_gremlin_dag.py + :language: python + :dedent: 4 + :start-after: [START run_query_gremlin_operator] + :end-before: [END run_query_gremlin_operator] + + +Reference +""""""""" + +For further information, look at: https://tinkerpop.apache.org/gremlin.html diff --git a/providers/apache/tinkerpop/docs/security.rst b/providers/apache/tinkerpop/docs/security.rst new file mode 100644 index 0000000000000..351ff007ebf2f --- /dev/null +++ b/providers/apache/tinkerpop/docs/security.rst @@ -0,0 +1,18 @@ + .. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + .. http://www.apache.org/licenses/LICENSE-2.0 + + .. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +.. include:: /../../../../devel-common/src/sphinx_exts/includes/security.rst diff --git a/providers/apache/tinkerpop/provider.yaml b/providers/apache/tinkerpop/provider.yaml new file mode 100644 index 0000000000000..f61e5993e0275 --- /dev/null +++ b/providers/apache/tinkerpop/provider.yaml @@ -0,0 +1,45 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +--- +package-name: apache-airflow-providers-apache-tinkerpop +name: Apache TinkerPop +description: | + `Apache TinkerPop `__. + Apache TinkerPop is a graph computing framework for both graph databases (OLTP) and graph analytic + systems (OLAP) and Gremlin is its graph traversal language. +state: ready +source-date-epoch: 1686592800 +# note that these versions are maintained by the release manager - do not update them manually +versions: + - 1.0.0 +integrations: + - integration-name: Apache TinkerPop + external-doc-url: https://tinkerpop.apache.org/ + how-to-guide: + - /docs/apache-airflow-providers-apache-tinkerpop/operators/tinkerpop.rst + tags: [apache] +operators: + - integration-name: Apache TinkerPop + python-modules: + - airflow.providers.apache.tinkerpop.operators.gremlin +hooks: + - integration-name: Apache TinkerPop + python-modules: + - airflow.providers.apache.tinkerpop.hooks.gremlin +connection-types: + - hook-class-name: airflow.providers.apache.tinkerpop.hooks.gremlin.GremlinHook + connection-type: gremlin diff --git a/providers/apache/tinkerpop/pyproject.toml b/providers/apache/tinkerpop/pyproject.toml new file mode 100644 index 0000000000000..58a86b8d21fcd --- /dev/null +++ b/providers/apache/tinkerpop/pyproject.toml @@ -0,0 +1,110 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE OVERWRITTEN! + +# IF YOU WANT TO MODIFY THIS FILE EXCEPT DEPENDENCIES, YOU SHOULD MODIFY THE TEMPLATE +# `pyproject_TEMPLATE.toml.jinja2` IN the `dev/breeze/src/airflow_breeze/templates` DIRECTORY +[build-system] +requires = ["flit_core==3.12.0"] +build-backend = "flit_core.buildapi" + +[project] +name = "apache-airflow-providers-apache-tinkerpop" +version = "1.0.0" +description = "Provider package apache-airflow-providers-apache-tinkerpop for Apache Airflow" +readme = "README.rst" +authors = [ + {name="Apache Software Foundation", email="dev@airflow.apache.org"}, +] +maintainers = [ + {name="Apache Software Foundation", email="dev@airflow.apache.org"}, +] +keywords = [ "airflow-provider", "apache.tinkerpop", "airflow", "integration" ] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Environment :: Web Environment", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "Framework :: Apache Airflow", + "Framework :: Apache Airflow :: Provider", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: System :: Monitoring", +] +requires-python = "~=3.9" + +# The dependencies should be modified in place in the generated file. +# Any change in the dependencies is preserved when the file is regenerated +# Make sure to run ``breeze static-checks --type update-providers-dependencies --all-files`` +# After you modify the dependencies, and rebuild your Breeze CI image with ``breeze ci-image build`` +dependencies = [ + "apache-airflow>=2.9.0", + "gremlinpython>=3.7.0", +] + +[dependency-groups] +dev = [ + "apache-airflow", + "apache-airflow-task-sdk", + "apache-airflow-devel-common", + # Additional devel dependencies (do not remove this line and add extra development dependencies) +] + +# To build docs: +# +# uv run --group docs build-docs +# +# To enable auto-refreshing build with server: +# +# uv run --group docs build-docs --autobuild +# +# To see more options: +# +# uv run --group docs build-docs --help +# +docs = [ + "apache-airflow-devel-common[docs]" +] + +[tool.uv.sources] +# These names must match the names as defined in the pyproject.toml of the workspace items, +# *not* the workspace folder paths +apache-airflow = {workspace = true} +apache-airflow-devel-common = {workspace = true} +apache-airflow-task-sdk = {workspace = true} +apache-airflow-providers-common-sql = {workspace = true} +apache-airflow-providers-standard = {workspace = true} + +[project.urls] +"Documentation" = "https://airflow.apache.org/docs/apache-airflow-providers-apache-tinkerpop/1.0.0" +"Changelog" = "https://airflow.apache.org/docs/apache-airflow-providers-apache-tinkerpop/1.0.0/changelog.html" +"Bug Tracker" = "https://github.com/apache/airflow/issues" +"Source Code" = "https://github.com/apache/airflow" +"Slack Chat" = "https://s.apache.org/airflow-slack" +"Mastodon" = "https://fosstodon.org/@airflow" +"YouTube" = "https://www.youtube.com/channel/UCSXwxpWZQ7XZ1WL3wqevChA/" + +[project.entry-points."apache_airflow_provider"] +provider_info = "airflow.providers.apache.tinkerpop.get_provider_info:get_provider_info" + +[tool.flit.module] +name = "airflow.providers.apache.tinkerpop" diff --git a/providers/apache/tinkerpop/src/airflow/__init__.py b/providers/apache/tinkerpop/src/airflow/__init__.py new file mode 100644 index 0000000000000..e8fd22856438c --- /dev/null +++ b/providers/apache/tinkerpop/src/airflow/__init__.py @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/providers/apache/tinkerpop/src/airflow/providers/__init__.py b/providers/apache/tinkerpop/src/airflow/providers/__init__.py new file mode 100644 index 0000000000000..e8fd22856438c --- /dev/null +++ b/providers/apache/tinkerpop/src/airflow/providers/__init__.py @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/providers/apache/tinkerpop/src/airflow/providers/apache/__init__.py b/providers/apache/tinkerpop/src/airflow/providers/apache/__init__.py new file mode 100644 index 0000000000000..e8fd22856438c --- /dev/null +++ b/providers/apache/tinkerpop/src/airflow/providers/apache/__init__.py @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/LICENSE b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/LICENSE new file mode 100644 index 0000000000000..11069edd79019 --- /dev/null +++ b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/__init__.py b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/__init__.py new file mode 100644 index 0000000000000..58f646b31f81e --- /dev/null +++ b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/__init__.py @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE +# OVERWRITTEN WHEN PREPARING DOCUMENTATION FOR THE PACKAGES. +# +# IF YOU WANT TO MODIFY THIS FILE, YOU SHOULD MODIFY THE TEMPLATE +# `PROVIDER__INIT__PY_TEMPLATE.py.jinja2` IN the `dev/breeze/src/airflow_breeze/templates` DIRECTORY +# +from __future__ import annotations + +import packaging.version + +from airflow import __version__ as airflow_version + +__all__ = ["__version__"] + +__version__ = "1.0.0" + +if packaging.version.parse(packaging.version.parse(airflow_version).base_version) < packaging.version.parse( + "2.9.0" +): + raise RuntimeError( + f"The package `apache-airflow-providers-apache-tinkerpop:{__version__}` needs Apache Airflow 2.9.0+" + ) diff --git a/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/get_provider_info.py b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/get_provider_info.py new file mode 100644 index 0000000000000..136b01fc499cc --- /dev/null +++ b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/get_provider_info.py @@ -0,0 +1,55 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# NOTE! THIS FILE IS AUTOMATICALLY GENERATED AND WILL BE OVERWRITTEN! +# +# IF YOU WANT TO MODIFY THIS FILE, YOU SHOULD MODIFY THE TEMPLATE +# `get_provider_info_TEMPLATE.py.jinja2` IN the `dev/breeze/src/airflow_breeze/templates` DIRECTORY + + +def get_provider_info(): + return { + "package-name": "apache-airflow-providers-apache-tinkerpop", + "name": "Apache TinkerPop", + "description": "`Apache TinkerPop `__.\nApache TinkerPop is a graph computing framework for both graph databases (OLTP) and graph analytic\nsystems (OLAP) and Gremlin is its graph traversal language.\n", + "integrations": [ + { + "integration-name": "Apache TinkerPop", + "external-doc-url": "https://tinkerpop.apache.org/", + "how-to-guide": ["/docs/apache-airflow-providers-apache-tinkerpop/operators/tinkerpop.rst"], + "tags": ["apache"], + } + ], + "operators": [ + { + "integration-name": "Apache TinkerPop", + "python-modules": ["airflow.providers.apache.tinkerpop.operators.gremlin"], + } + ], + "hooks": [ + { + "integration-name": "Apache TinkerPop", + "python-modules": ["airflow.providers.apache.tinkerpop.hooks.gremlin"], + } + ], + "connection-types": [ + { + "hook-class-name": "airflow.providers.apache.tinkerpop.hooks.gremlin.GremlinHook", + "connection-type": "gremlin", + } + ], + } diff --git a/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/hooks/__init__.py b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/hooks/__init__.py new file mode 100644 index 0000000000000..217e5db960782 --- /dev/null +++ b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/hooks/__init__.py @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/hooks/gremlin.py b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/hooks/gremlin.py new file mode 100644 index 0000000000000..3c547a02c338c --- /dev/null +++ b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/hooks/gremlin.py @@ -0,0 +1,154 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +"""This module allows connecting to an Graph DB using the Gremlin Client.""" + +from __future__ import annotations + +import logging +from typing import TYPE_CHECKING, Any + +from gremlin_python.driver.client import Client + +from airflow.hooks.base import BaseHook + +if TYPE_CHECKING: + from airflow.models import Connection + + +logger = logging.getLogger(__name__) + + +class GremlinHook(BaseHook): + """ + Interact with Graph DB using the Gremlin Client. + + This hook creates a connection to Graph DB and allows you to run Gremlin queries.` + + :param gremlin_conn_id: Reference to the connection ID configured in Airflow. + """ + + conn_name_attr = "gremlin__conn_id" + default_conn_name = "gremlin_default" + conn_type = "gremlin" + hook_name = "Gremlin" + default_port = 443 + traversal_source = "g" + + def __init__(self, conn_id: str = default_conn_name, *args, **kwargs) -> None: + super().__init__(*args, **kwargs) + self.gremlin_conn_id = conn_id + self.connection = kwargs.pop("connection", None) + self.client: Client | None = None + + def get_conn(self, serializer=None) -> Client: + """ + Establish a connection to Graph DB with the Gremlin Client. + + :param serializer: Message serializer to use for the client. + + :return: An instance of the Gremlin Client. + """ + if self.client is not None: + return self.client + + self.connection = self.get_connection(self.gremlin_conn_id) + + uri = self.get_uri(self.connection) + self.log.info("Connecting to URI: %s", uri) + + self.client = self.get_client( + self.connection, self.traversal_source, uri, message_serializer=serializer + ) + return self.client + + def get_uri(self, conn: Connection) -> str: + """ + Build the URI from the connection object and extra parameters. + + :param conn: Airflow Connection object. + + :return: URI string. + """ + # For Graph DB using Gremlin, the secure WebSocket scheme is typically "wss" + scheme = "wss" if conn.conn_type == "gremlin" else "ws" + host = conn.host + port = conn.port if conn.port is not None else self.default_port + schema = "" if conn.conn_type == "gremlin" else "gremlin" + return f"{scheme}://{host}:{port}/{schema}" + + def get_client( + self, conn: Connection, traversal_source: str, uri: str, message_serializer=None + ) -> Client: + """ + Create and return a new Gremlin client. + + :param conn: Airflow Connection object. + :param traversal_source: Traversal source for the Gremlin client. + :param uri: URI string for connecting to Graph DB. + :param message_serializer: Message serializer to use for the client. + + :return: An instance of the Gremlin Client. + """ + # Build the username. This example uses the connection's schema and login. + login = conn.login if conn.login not in ["mylogin", None] else "" + schema = conn.schema if conn.schema not in ["gremlin", None] else "" + password = conn.password if conn.password not in ["mysecret", None] else "" + username = f"/dbs/{login}/colls/{schema}" if login and schema else "" + # Build the kwargs for the Client. + client_kwargs = { + "url": uri, + "traversal_source": traversal_source, + "username": username, + "password": password, + } + + # If a serializer is provided, check if it's a type and instantiate it. + if message_serializer is not None: + if isinstance(message_serializer, type): + message_serializer = message_serializer() + client_kwargs["message_serializer"] = message_serializer + + return Client(**client_kwargs) + + def run(self, query: str, serializer=None, bindings=None, request_options=None) -> list[Any]: + """ + Execute a Gremlin query and return the results. + + :param query: Gremlin query string. + :param serializer: Message serializer to use for the query. + :param bindings: Bindings to use for the query. + :param request_options: Request options to use for the query. + + :return: List containing the query results. + """ + client = self.get_conn(serializer) + + try: + results_list = ( + client.submit(message=query, bindings=bindings, request_options=request_options) + .all() + .result() + ) + except Exception as e: + logger.error("An error occurred while running the query: %s", str(e)) + raise e + finally: + if client is not None: + client.close() + self.client = None + + return results_list diff --git a/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/operators/__init__.py b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/operators/__init__.py new file mode 100644 index 0000000000000..217e5db960782 --- /dev/null +++ b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/operators/__init__.py @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/operators/gremlin.py b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/operators/gremlin.py new file mode 100644 index 0000000000000..f7064890d5d4b --- /dev/null +++ b/providers/apache/tinkerpop/src/airflow/providers/apache/tinkerpop/operators/gremlin.py @@ -0,0 +1,55 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +from airflow.models import BaseOperator +from airflow.providers.apache.tinkerpop.hooks.gremlin import GremlinHook + +if TYPE_CHECKING: + try: + from airflow.sdk.definitions.context import Context + except ImportError: + # TODO: Remove once provider drops support for Airflow 2 + from airflow.utils.context import Context + + +class GremlinOperator(BaseOperator): + """ + Execute a Gremlin query. + + :param query: The Gremlin query to execute. + :param gremlin_conn_id: The connection ID to use when connecting to Gremlin. Defaults to "gremlin_default". + """ + + template_fields = ("query",) + + def __init__(self, query: str, gremlin_conn_id: str = "gremlin_default", **kwargs) -> None: + super().__init__(**kwargs) + self.query = query + self.gremlin_conn_id = gremlin_conn_id + + def execute(self, context: Context) -> Any: + hook = GremlinHook(conn_id=self.gremlin_conn_id) + # Note: the hook method is defined as run() in our hook implementation. + # If you prefer, you can add an alias run_query = run in your hook. + try: + return hook.run(self.query) + finally: + if hasattr(hook, "client") and hook.client: + hook.client.close() # Ensure client cleanup diff --git a/providers/apache/tinkerpop/tests/conftest.py b/providers/apache/tinkerpop/tests/conftest.py new file mode 100644 index 0000000000000..f56ccce0a3f69 --- /dev/null +++ b/providers/apache/tinkerpop/tests/conftest.py @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +pytest_plugins = "tests_common.pytest_plugin" diff --git a/providers/apache/tinkerpop/tests/integration/__init__.py b/providers/apache/tinkerpop/tests/integration/__init__.py new file mode 100644 index 0000000000000..13a83393a9124 --- /dev/null +++ b/providers/apache/tinkerpop/tests/integration/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/providers/apache/tinkerpop/tests/integration/apache/__init__.py b/providers/apache/tinkerpop/tests/integration/apache/__init__.py new file mode 100644 index 0000000000000..e8fd22856438c --- /dev/null +++ b/providers/apache/tinkerpop/tests/integration/apache/__init__.py @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/providers/apache/tinkerpop/tests/integration/apache/tinkerpop/__init__.py b/providers/apache/tinkerpop/tests/integration/apache/tinkerpop/__init__.py new file mode 100644 index 0000000000000..13a83393a9124 --- /dev/null +++ b/providers/apache/tinkerpop/tests/integration/apache/tinkerpop/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/providers/apache/tinkerpop/tests/integration/apache/tinkerpop/hooks/__init__.py b/providers/apache/tinkerpop/tests/integration/apache/tinkerpop/hooks/__init__.py new file mode 100644 index 0000000000000..13a83393a9124 --- /dev/null +++ b/providers/apache/tinkerpop/tests/integration/apache/tinkerpop/hooks/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/providers/apache/tinkerpop/tests/integration/apache/tinkerpop/hooks/test_gremlin.py b/providers/apache/tinkerpop/tests/integration/apache/tinkerpop/hooks/test_gremlin.py new file mode 100644 index 0000000000000..2a2ea25f95625 --- /dev/null +++ b/providers/apache/tinkerpop/tests/integration/apache/tinkerpop/hooks/test_gremlin.py @@ -0,0 +1,49 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +import os + +import pytest +from gremlin_python.driver.serializer import GraphSONSerializersV2d0 + +from airflow.providers.apache.tinkerpop.hooks.gremlin import GremlinHook + +AIRFLOW_CONN_GREMLIN_DEFAULT = "ws://mylogin:mysecret@gremlin:8182/gremlin" + + +@pytest.mark.integration("gremlin") +class TestGremlinHook: + def setup_method(self): + os.environ["AIRFLOW_CONN_GREMLIN_DEFAULT"] = AIRFLOW_CONN_GREMLIN_DEFAULT + self.hook = GremlinHook() + add_query = "g.addV('person').property('id', 'person1').property('name', 'Alice')" + self.hook.run(add_query) + + def teardown_method(self): + self.hook.run("g.V().drop().iterate()") + + def test_another_query(self): + result = self.hook.run("g.V().hasLabel('person').count()") + assert isinstance(result, list) + + def test_run(self): + result = self.hook.run( + "g.V().hasLabel('person').valueMap(true)", serializer=GraphSONSerializersV2d0() + ) + expected = "[{'id': ['person1'], 'label': 'person', 'name': ['Alice']}]" + assert str(result) == expected diff --git a/providers/apache/tinkerpop/tests/system/__init__.py b/providers/apache/tinkerpop/tests/system/__init__.py new file mode 100644 index 0000000000000..13a83393a9124 --- /dev/null +++ b/providers/apache/tinkerpop/tests/system/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/providers/apache/tinkerpop/tests/system/apache/__init__.py b/providers/apache/tinkerpop/tests/system/apache/__init__.py new file mode 100644 index 0000000000000..e8fd22856438c --- /dev/null +++ b/providers/apache/tinkerpop/tests/system/apache/__init__.py @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/providers/apache/tinkerpop/tests/system/apache/tinkerpop/__init__.py b/providers/apache/tinkerpop/tests/system/apache/tinkerpop/__init__.py new file mode 100644 index 0000000000000..13a83393a9124 --- /dev/null +++ b/providers/apache/tinkerpop/tests/system/apache/tinkerpop/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/providers/apache/tinkerpop/tests/system/apache/tinkerpop/example_gremlin_dag.py b/providers/apache/tinkerpop/tests/system/apache/tinkerpop/example_gremlin_dag.py new file mode 100644 index 0000000000000..94f3e304125c6 --- /dev/null +++ b/providers/apache/tinkerpop/tests/system/apache/tinkerpop/example_gremlin_dag.py @@ -0,0 +1,52 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +""" +Example use of Gremlin related operators. +""" + +from __future__ import annotations + +import os +from datetime import datetime + +from airflow import DAG +from airflow.providers.apache.tinkerpop.operators.gremlin import GremlinOperator + +ENV_ID = os.environ.get("SYSTEM_TESTS_ENV_ID") +DAG_ID = "example_gremlin_dag" + + +with DAG( + DAG_ID, + start_date=datetime(2021, 1, 1), + schedule=None, + tags=["example"], + catchup=False, +) as dag: + # [START run_query_gremlin_operator] + + gremlin_task = GremlinOperator( + task_id="run_gremlin_query", gremlin_conn_id="gremlin_conn_id", query="g.V()" + ) + + # [END run_query_gremlin_operator] + +from tests_common.test_utils.system_tests import get_test_run # noqa: E402 + +# Needed to run the example DAG with pytest (see: tests/system/README.md#run_via_pytest) +test_run = get_test_run(dag) diff --git a/providers/apache/tinkerpop/tests/unit/__init__.py b/providers/apache/tinkerpop/tests/unit/__init__.py new file mode 100644 index 0000000000000..e8fd22856438c --- /dev/null +++ b/providers/apache/tinkerpop/tests/unit/__init__.py @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/providers/apache/tinkerpop/tests/unit/apache/__init__.py b/providers/apache/tinkerpop/tests/unit/apache/__init__.py new file mode 100644 index 0000000000000..e8fd22856438c --- /dev/null +++ b/providers/apache/tinkerpop/tests/unit/apache/__init__.py @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +__path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/__init__.py b/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/__init__.py new file mode 100644 index 0000000000000..13a83393a9124 --- /dev/null +++ b/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/__init__.py @@ -0,0 +1,16 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/hooks/__init__.py b/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/hooks/__init__.py new file mode 100644 index 0000000000000..217e5db960782 --- /dev/null +++ b/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/hooks/__init__.py @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/hooks/test_gremlin.py b/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/hooks/test_gremlin.py new file mode 100644 index 0000000000000..d002dcb2f609b --- /dev/null +++ b/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/hooks/test_gremlin.py @@ -0,0 +1,151 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +from __future__ import annotations + +from unittest import mock + +import pytest + +from airflow.models import Connection +from airflow.providers.apache.tinkerpop.hooks.gremlin import GremlinHook + + +@pytest.fixture +def gremlin_hook(): + """Fixture to provide a GremlinHook instance with proper teardown.""" + hook = GremlinHook() + yield hook + # Teardown: Ensure the client is closed if it exists + if hook.client: + hook.client.close() + + +class TestGremlinHook: + @pytest.mark.parametrize( + "host, port, expected_uri", + [ + ("host", None, "ws://host:443/gremlin"), + ("myhost", 1234, "ws://myhost:1234/gremlin"), + ("localhost", 8888, "ws://localhost:8888/gremlin"), + ], + ) + def test_get_uri(self, host, port, expected_uri, gremlin_hook): + """ + Test that get_uri builds the expected URI from the connection. + """ + conn = Connection(conn_id="gremlin_default", host=host, port=port) + with mock.patch.dict("os.environ", AIRFLOW_CONN_GREMLIN_DEFAULT=conn.get_uri()): + uri = gremlin_hook.get_uri(conn) + + assert uri == expected_uri + + def test_get_conn(self, gremlin_hook): + """ + Test that get_conn() retrieves the connection and creates a client correctly. + """ + conn = Connection( + conn_type="gremlin", + conn_id="gremlin_default", + host="host", + port=1234, + schema="mydb", + login="login", + password="mypassword", + ) + gremlin_hook.get_connection = lambda conn_id: conn + + with mock.patch("airflow.providers.apache.tinkerpop.hooks.gremlin.Client") as mock_client: + gremlin_hook.get_conn() + expected_uri = "wss://host:1234/" + expected_username = "/dbs/login/colls/mydb" + + mock_client.assert_called_once_with( + url=expected_uri, + traversal_source=gremlin_hook.traversal_source, + username=expected_username, + password="mypassword", + ) + + @pytest.mark.parametrize( + "serializer, should_include", + [ + (None, False), + ("dummy_serializer", True), + ], + ) + def test_get_client_message_serializer(self, serializer, should_include, gremlin_hook): + """ + Test that get_client() includes message_serializer only when provided. + """ + conn = Connection( + conn_id="gremlin_default", + host="host", + port=1234, + schema="mydb", + login="login", + password="mypassword", + ) + uri = "wss://test.uri" + traversal_source = "g" + + with mock.patch("airflow.providers.apache.tinkerpop.hooks.gremlin.Client") as mock_client: + gremlin_hook.get_client(conn, traversal_source, uri, message_serializer=serializer) + call_args = mock_client.call_args.kwargs + if should_include: + assert "message_serializer" in call_args + assert call_args["message_serializer"] == serializer + else: + assert "message_serializer" not in call_args + + @pytest.mark.parametrize( + "side_effect, expected_exception, expected_result", + [ + (None, None, ["dummy_result"]), + (Exception("Test error"), Exception, None), + ], + ) + def test_run(self, side_effect, expected_exception, expected_result, gremlin_hook): + """ + Test that run() returns the expected result or propagates an exception, with proper cleanup. + """ + query = "g.V().limit(1)" + + # Mock the client instance + with mock.patch("airflow.providers.apache.tinkerpop.hooks.gremlin.Client") as mock_client: + instance = mock_client.return_value + if side_effect is None: + instance.submit.return_value.all.return_value.result.return_value = expected_result + else: + instance.submit.return_value.all.return_value.result.side_effect = side_effect + + # Mock get_connection to simplify setup + conn = Connection( + conn_id="gremlin_default", + host="host", + port=1234, + schema="mydb", + login="login", + password="mypassword", + ) + gremlin_hook.get_connection = lambda conn_id: conn + + if expected_exception: + with pytest.raises(expected_exception, match="Test error"): + gremlin_hook.run(query) + else: + result = gremlin_hook.run(query) + assert result == expected_result diff --git a/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/operators/__init__.py b/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/operators/__init__.py new file mode 100644 index 0000000000000..217e5db960782 --- /dev/null +++ b/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/operators/__init__.py @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. diff --git a/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/operators/test_gremlin.py b/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/operators/test_gremlin.py new file mode 100644 index 0000000000000..59fe2f6c50457 --- /dev/null +++ b/providers/apache/tinkerpop/tests/unit/apache/tinkerpop/operators/test_gremlin.py @@ -0,0 +1,66 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from __future__ import annotations + +from unittest import mock + +from airflow.models import Connection +from airflow.providers.apache.tinkerpop.operators.gremlin import GremlinOperator +from airflow.utils import timezone + +DEFAULT_DATE = timezone.datetime(2015, 1, 1) +TEST_DAG_ID = "unit_test_dag" + + +class TestGremlinOperator: + @mock.patch("airflow.providers.apache.tinkerpop.operators.gremlin.GremlinHook") + def test_gremlin_operator(self, mock_hook): + """ + Test that the GremlinOperator instantiates the hook with the proper connection id + and calls its run() method with the provided query. + """ + query = "g.V().limit(1)" + op = GremlinOperator(task_id="basic_gremlin", query=query, gremlin_conn_id="gremlin_default") + + # Create a dummy context + context = mock.MagicMock() + + # Create a dummy connection + dummy_conn = Connection( + conn_id="gremlin_default", + host="host", + port=443, + schema="mydb", + login="mylogin", + password="mypassword", + ) + + # Mock hook instance + mock_hook_instance = mock_hook.return_value + mock_hook_instance.get_connection.return_value = dummy_conn + mock_hook_instance.run.return_value = None + mock_hook_instance.client = mock.MagicMock() # Mock client attribute + mock_hook_instance.client.close = mock.MagicMock() # Mock close method + + # Execute the operator + op.execute(context) + + # Verify hook instantiation and run call + mock_hook.assert_called_once_with(conn_id="gremlin_default") + mock_hook_instance.run.assert_called_once_with(query) + mock_hook_instance.client.close.assert_called_once() # Verify cleanup diff --git a/pyproject.toml b/pyproject.toml index 27266a56e006e..07389183aacf4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -178,6 +178,9 @@ packages = [] "apache.spark" = [ "apache-airflow-providers-apache-spark>=4.11.1" ] +"apache.tinkerpop" = [ + "apache-airflow-providers-apache-tinkerpop" +] "apprise" = [ "apache-airflow-providers-apprise>=1.4.1" ] @@ -429,6 +432,7 @@ packages = [] "apache-airflow-providers-apache-pig>=4.6.0", "apache-airflow-providers-apache-pinot>=4.5.1", "apache-airflow-providers-apache-spark>=4.11.1", + "apache-airflow-providers-apache-tinkerpop", "apache-airflow-providers-apprise>=1.4.1", "apache-airflow-providers-arangodb>=2.7.0", "apache-airflow-providers-asana>=2.7.0", @@ -998,6 +1002,8 @@ mypy_path = [ "$MYPY_CONFIG_FILE_DIR/providers/apache/pinot/tests", "$MYPY_CONFIG_FILE_DIR/providers/apache/spark/src", "$MYPY_CONFIG_FILE_DIR/providers/apache/spark/tests", + "$MYPY_CONFIG_FILE_DIR/providers/apache/tinkerpop/src", + "$MYPY_CONFIG_FILE_DIR/providers/apache/tinkerpop/tests", "$MYPY_CONFIG_FILE_DIR/providers/apprise/src", "$MYPY_CONFIG_FILE_DIR/providers/apprise/tests", "$MYPY_CONFIG_FILE_DIR/providers/arangodb/src", @@ -1268,6 +1274,7 @@ apache-airflow-providers-apache-livy = { workspace = true } apache-airflow-providers-apache-pig = { workspace = true } apache-airflow-providers-apache-pinot = { workspace = true } apache-airflow-providers-apache-spark = { workspace = true } +apache-airflow-providers-apache-tinkerpop = { workspace = true } apache-airflow-providers-apprise = { workspace = true } apache-airflow-providers-arangodb = { workspace = true } apache-airflow-providers-asana = { workspace = true } @@ -1379,6 +1386,7 @@ members = [ "providers/apache/pig", "providers/apache/pinot", "providers/apache/spark", + "providers/apache/tinkerpop", "providers/apprise", "providers/arangodb", "providers/asana", diff --git a/scripts/ci/docker-compose/gremlin/graph.properties b/scripts/ci/docker-compose/gremlin/graph.properties new file mode 100644 index 0000000000000..e8550156de7bd --- /dev/null +++ b/scripts/ci/docker-compose/gremlin/graph.properties @@ -0,0 +1,27 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Specify the graph implementation class +gremlin.graph=org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph + +# Optional: Specify a file location for persistent storage. +# Uncomment the following line if you wish to persist graph data between restarts. +gremlin.tinkergraph.graphLocation=/opt/gremlin-server/data/graph.json + +# Configure the ID managers for vertices and edges +gremlin.tinkergraph.vertexIdManager=LONG +gremlin.tinkergraph.graphFormat=graphson diff --git a/scripts/ci/docker-compose/gremlin/gremlin-entrypoint.sh b/scripts/ci/docker-compose/gremlin/gremlin-entrypoint.sh new file mode 100755 index 0000000000000..2c58e7b518c96 --- /dev/null +++ b/scripts/ci/docker-compose/gremlin/gremlin-entrypoint.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +#!/bin/sh +set -eu + +# Fix permissions on the config directory +echo "Fixing permissions for /opt/gremlin-server/conf..." +chmod -R a+rw /opt/gremlin-server/conf +ls -la /opt/gremlin-server/conf + +# Start Gremlin Server in the background +echo "Starting Gremlin Server on port 8182..." +cd /opt/gremlin-server || exit +./bin/gremlin-server.sh conf/gremlin-server.yaml & + +# Wait for Gremlin to be ready +echo "Waiting for Gremlin Server to start on port 8182..." +while ! nc -z gremlin 8182 2>/dev/null; do + echo "Gremlin still not started" + sleep 5 +done +sleep 3 +echo "Gremlin Server is running" + +# Keep the container running +wait diff --git a/scripts/ci/docker-compose/gremlin/gremlin-server.yaml b/scripts/ci/docker-compose/gremlin/gremlin-server.yaml new file mode 100644 index 0000000000000..92e623dcb7a12 --- /dev/null +++ b/scripts/ci/docker-compose/gremlin/gremlin-server.yaml @@ -0,0 +1,63 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +--- +host: 172.18.0.2 +port: 8182 +channelizer: org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer +graphs: { + graph: conf/graph.properties} +scriptEngines: { + gremlin-groovy: { + plugins: { + org.apache.tinkerpop.gremlin.server.jsr223.GremlinServerGremlinPlugin: {}, + org.apache.tinkerpop.gremlin.tinkergraph.jsr223.TinkerGraphGremlinPlugin: {}, + org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: { + classImports: [java.lang.Math], methodImports: [java.lang.Math#*] + }, + org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin: { + files: [scripts/empty-sample.groovy] + }}}} +serializers: + - {className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV2d0, + config: {includeTypes: true}} + - {className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0, + config: {ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3d0]}} + - {className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1} + - {className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1, + config: {serializeResultToString: true}} +processors: + - {className: org.apache.tinkerpop.gremlin.server.op.session.SessionOpProcessor, + config: {sessionTimeout: 28800000}} + - {className: org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor, + config: {cacheExpirationTime: 600000, cacheMaxSize: 1000}} +metrics: { + consoleReporter: {enabled: true, interval: 180000}, + csvReporter: {enabled: true, interval: 180000, fileName: /tmp/gremlin-server-metrics.csv}, + jmxReporter: {enabled: true}, + slf4jReporter: {enabled: true, interval: 180000}} +strictTransactionManagement: false +idleConnectionTimeout: 0 +keepAliveInterval: 0 +maxInitialLineLength: 4096 +maxHeaderSize: 8192 +maxChunkSize: 8192 +maxContentLength: 65536 +maxAccumulationBufferComponents: 1024 +resultIterationBatchSize: 64 +writeBufferLowWaterMark: 32768 +writeBufferHighWaterMark: 65536 +ssl: {enabled: false} diff --git a/scripts/ci/docker-compose/gremlin/log4j-server.properties b/scripts/ci/docker-compose/gremlin/log4j-server.properties new file mode 100644 index 0000000000000..e2d23083842ae --- /dev/null +++ b/scripts/ci/docker-compose/gremlin/log4j-server.properties @@ -0,0 +1,32 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +log4j.rootLogger=INFO, stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[%p] %C{1} - %m%n + +log4j.logger.org.apache.tinkerpop.gremlin.driver.Connection=OFF +log4j.logger.org.apache.tinkerpop.gremlin.driver.ConnectionPool=OFF +log4j.logger.org.apache.tinkerpop.gremlin.neo4j.structure.Neo4jGraph=ERROR +log4j.logger.org.apache.hadoop.mapred.JobClient=INFO +log4j.logger.org.apache.hadoop.mapreduce.Job=INFO +log4j.logger.org.apache.tinkerpop.gremlin.hadoop.process.computer.mapreduce.MapReduceGraphComputer=INFO +log4j.logger.org.apache.tinkerpop.gremlin.hadoop.structure.HadoopGraph=INFO +log4j.logger.org.apache.tinkerpop.gremlin.spark.process.computer.SparkGraphComputer=INFO +log4j.logger.org.apache.spark.metrics.MetricsSystem=ERROR +log4j.logger.com.jcabi.manifests.Manifests=OFF diff --git a/scripts/ci/docker-compose/gremlin/logback.xml b/scripts/ci/docker-compose/gremlin/logback.xml new file mode 100644 index 0000000000000..9b85d870a5225 --- /dev/null +++ b/scripts/ci/docker-compose/gremlin/logback.xml @@ -0,0 +1,38 @@ + + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + + + diff --git a/scripts/ci/docker-compose/integration-gremlin.yml b/scripts/ci/docker-compose/integration-gremlin.yml new file mode 100644 index 0000000000000..27e9783999afd --- /dev/null +++ b/scripts/ci/docker-compose/integration-gremlin.yml @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +--- +services: + gremlin: + hostname: gremlin + container_name: gremlin + image: tinkerpop/gremlin-server:3.4.2 + labels: + breeze.description: "Integration required for gremlin operator and hook." + volumes: + - ./gremlin:/opt/gremlin-server/conf + - graph-data:/opt/gremlin-server/data + - ./gremlin/gremlin-entrypoint.sh:/opt/gremlin-server/gremlin-entrypoint.sh # New entrypoint script + ports: + - "${GREMLIN_HOST_PORT}:8182" + entrypoint: /opt/gremlin-server/gremlin-entrypoint.sh # Use custom entrypoint + user: "0:0" # Run as root + airflow: + depends_on: + - gremlin + environment: + - INTEGRATION_GREMLIN=true + stdin_open: true +volumes: + graph-data: diff --git a/scripts/ci/docker-compose/remove-sources.yml b/scripts/ci/docker-compose/remove-sources.yml index c9d500209e772..c12a77f7d4927 100644 --- a/scripts/ci/docker-compose/remove-sources.yml +++ b/scripts/ci/docker-compose/remove-sources.yml @@ -44,6 +44,7 @@ services: - ../../../empty:/opt/airflow/providers/apache/pig/src - ../../../empty:/opt/airflow/providers/apache/pinot/src - ../../../empty:/opt/airflow/providers/apache/spark/src + - ../../../empty:/opt/airflow/providers/apache/tinkerpop/src - ../../../empty:/opt/airflow/providers/apprise/src - ../../../empty:/opt/airflow/providers/arangodb/src - ../../../empty:/opt/airflow/providers/asana/src diff --git a/scripts/ci/docker-compose/tests-sources.yml b/scripts/ci/docker-compose/tests-sources.yml index c8ccc1f629c46..d94a66ad1c796 100644 --- a/scripts/ci/docker-compose/tests-sources.yml +++ b/scripts/ci/docker-compose/tests-sources.yml @@ -56,6 +56,7 @@ services: - ../../../providers/apache/pig/tests:/opt/airflow/providers/apache/pig/tests - ../../../providers/apache/pinot/tests:/opt/airflow/providers/apache/pinot/tests - ../../../providers/apache/spark/tests:/opt/airflow/providers/apache/spark/tests + - ../../../providers/apache/tinkerpop/tests:/opt/airflow/providers/apache/tinkerpop/tests - ../../../providers/apprise/tests:/opt/airflow/providers/apprise/tests - ../../../providers/arangodb/tests:/opt/airflow/providers/arangodb/tests - ../../../providers/asana/tests:/opt/airflow/providers/asana/tests diff --git a/scripts/in_container/check_environment.sh b/scripts/in_container/check_environment.sh index 49c5e7a443ab9..b6ee390577a49 100755 --- a/scripts/in_container/check_environment.sh +++ b/scripts/in_container/check_environment.sh @@ -174,6 +174,10 @@ if [[ ${INTEGRATION_YDB} == "true" ]]; then check_service "YDB Cluster" "run_nc ydb 2136" 50 fi +if [[ ${INTEGRATION_GREMLIN} == "true" ]]; then + check_service "gremlin" "run_nc gremlin 8182" 50 +fi + if [[ ${EXIT_CODE} != 0 ]]; then echo echo "Error: some of the CI environment failed to initialize!"