diff --git a/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/main/java/io/gravitee/repository/jdbc/management/JdbcIntegrationRepository.java b/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/main/java/io/gravitee/repository/jdbc/management/JdbcIntegrationRepository.java new file mode 100644 index 00000000000..54247af609e --- /dev/null +++ b/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/main/java/io/gravitee/repository/jdbc/management/JdbcIntegrationRepository.java @@ -0,0 +1,78 @@ +/* + * Copyright © 2015 The Gravitee team (http://gravitee.io) + * + * 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. + */ +package io.gravitee.repository.jdbc.management; + +import io.gravitee.common.data.domain.Page; +import io.gravitee.repository.exceptions.TechnicalException; +import io.gravitee.repository.jdbc.orm.JdbcObjectMapper; +import io.gravitee.repository.management.api.IntegrationRepository; +import io.gravitee.repository.management.api.search.Pageable; +import io.gravitee.repository.management.model.*; +import java.sql.Types; +import java.util.Date; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Repository; + +@Repository +public class JdbcIntegrationRepository extends JdbcAbstractCrudRepository implements IntegrationRepository { + + private static final Logger LOGGER = LoggerFactory.getLogger(JdbcIntegrationRepository.class); + + JdbcIntegrationRepository(@Value("${management.jdbc.prefix:}") String prefix) { + super(prefix, "integrations"); + } + + @Override + public Page findAllByEnvironment(String environmentId, Pageable pageable) throws TechnicalException { + LOGGER.debug("JdbcIntegrationRepository.findAllByEnvironment({}, {})", environmentId, pageable); + final List integrations; + try { + integrations = + jdbcTemplate.query( + getOrm().getSelectAllSql() + " where environment_id = ? order by updated_at desc", + getOrm().getRowMapper(), + environmentId + ); + } catch (final Exception ex) { + final String message = "Failed to find integrations of environment: " + environmentId; + LOGGER.error(message, ex); + throw new TechnicalException(message, ex); + } + return getResultAsPage(pageable, integrations); + } + + @Override + protected String getId(Integration item) { + return item.getId(); + } + + @Override + protected JdbcObjectMapper buildOrm() { + return JdbcObjectMapper + .builder(Integration.class, this.tableName, "id") + .addColumn("id", Types.NVARCHAR, String.class) + .addColumn("name", Types.NVARCHAR, String.class) + .addColumn("description", Types.NVARCHAR, String.class) + .addColumn("provider", Types.NVARCHAR, String.class) + .addColumn("environment_id", Types.NVARCHAR, String.class) + .addColumn("created_at", Types.TIMESTAMP, Date.class) + .addColumn("updated_at", Types.TIMESTAMP, Date.class) + .build(); + } +} diff --git a/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/main/resources/liquibase/changelogs/v4_4_0/schema.yml b/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/main/resources/liquibase/changelogs/v4_4_0/schema.yml new file mode 100644 index 00000000000..db231e240c7 --- /dev/null +++ b/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/main/resources/liquibase/changelogs/v4_4_0/schema.yml @@ -0,0 +1,30 @@ +databaseChangeLog: + - changeSet: + id: 4.4.0 + author: GraviteeSource Team + changes: + # ################ + # Integration changes + # ################ + - createTable: + tableName: ${gravitee_prefix}integrations + columns: + - column: {name: id, type: nvarchar(64), constraints: { nullable: false } } + - column: {name: name, type: nvarchar(64), constraints: { nullable: false } } + - column: {name: description, type: nvarchar(256), constraints: { nullable: true } } + - column: {name: provider, type: nvarchar(16), constraints: { nullable: false } } + - column: {name: environment_id, type: nvarchar(64), constraints: { nullable: false } } + - column: {name: created_at, type: timestamp(6), constraints: { nullable: false }, defaultValueComputed: CURRENT_TIMESTAMP(6) } + - column: {name: updated_at, type: timestamp(6), constraints: { nullable: false }, defaultValueComputed: CURRENT_TIMESTAMP(6) } + + - addPrimaryKey: + constraintName: pk_${gravitee_prefix}integrations + columnNames: id + tableName: ${gravitee_prefix}integrations + - createIndex: + indexName: idx_${gravitee_prefix}integrations_environment_id + columns: + - column: + name: environment_id + type: nvarchar(64) + tableName: ${gravitee_prefix}integrations \ No newline at end of file diff --git a/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/main/resources/liquibase/master.yml b/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/main/resources/liquibase/master.yml index 52ca79cb570..81598b747fd 100644 --- a/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/main/resources/liquibase/master.yml +++ b/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/main/resources/liquibase/master.yml @@ -167,3 +167,5 @@ databaseChangeLog: - file: liquibase/changelogs/v4_2_0/schema-quality-rules.yml - include: - file: liquibase/changelogs/v4_3_0/schema.yml + - include: + - file: liquibase/changelogs/v4_4_0/schema.yml diff --git a/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/test/java/io/gravitee/repository/jdbc/JdbcTestRepositoryInitializer.java b/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/test/java/io/gravitee/repository/jdbc/JdbcTestRepositoryInitializer.java index a84884598e0..5adf3d48b2e 100644 --- a/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/test/java/io/gravitee/repository/jdbc/JdbcTestRepositoryInitializer.java +++ b/gravitee-apim-repository/gravitee-apim-repository-jdbc/src/test/java/io/gravitee/repository/jdbc/JdbcTestRepositoryInitializer.java @@ -136,7 +136,8 @@ public class JdbcTestRepositoryInitializer implements TestRepositoryInitializer "flow_selector_channel_operations", "flow_selector_channel_entrypoints", "flow_tags", - "upgraders" + "upgraders", + "integrations" ); private static final List tablesToDrop = concatenate( tablesToTruncate, diff --git a/gravitee-apim-repository/gravitee-apim-repository-mongodb/src/main/java/io/gravitee/repository/mongodb/management/internal/model/IntegrationMongo.java b/gravitee-apim-repository/gravitee-apim-repository-mongodb/src/main/java/io/gravitee/repository/mongodb/management/internal/model/IntegrationMongo.java index f164792915f..6723760240e 100644 --- a/gravitee-apim-repository/gravitee-apim-repository-mongodb/src/main/java/io/gravitee/repository/mongodb/management/internal/model/IntegrationMongo.java +++ b/gravitee-apim-repository/gravitee-apim-repository-mongodb/src/main/java/io/gravitee/repository/mongodb/management/internal/model/IntegrationMongo.java @@ -26,7 +26,7 @@ */ @Getter @Setter -@Document(collection = "#{@environment.getProperty('management.mongodb.prefix')}integration") +@Document(collection = "#{@environment.getProperty('management.mongodb.prefix')}integrations") public class IntegrationMongo extends Auditable { @Id diff --git a/gravitee-apim-repository/gravitee-apim-repository-mongodb/src/main/java/io/gravitee/repository/mongodb/management/upgrade/upgrader/index/integrations/EnvironmentIdIndexUpgrader.java b/gravitee-apim-repository/gravitee-apim-repository-mongodb/src/main/java/io/gravitee/repository/mongodb/management/upgrade/upgrader/index/integrations/EnvironmentIdIndexUpgrader.java new file mode 100644 index 00000000000..70308eb7767 --- /dev/null +++ b/gravitee-apim-repository/gravitee-apim-repository-mongodb/src/main/java/io/gravitee/repository/mongodb/management/upgrade/upgrader/index/integrations/EnvironmentIdIndexUpgrader.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2015 The Gravitee team (http://gravitee.io) + * + * 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. + */ +package io.gravitee.repository.mongodb.management.upgrade.upgrader.index.integrations; + +import io.gravitee.repository.mongodb.management.upgrade.upgrader.index.Index; +import io.gravitee.repository.mongodb.management.upgrade.upgrader.index.IndexUpgrader; +import org.springframework.stereotype.Component; + +@Component("IntegrationsEnvironmentIdIndexUpgrader") +public class EnvironmentIdIndexUpgrader extends IndexUpgrader { + + @Override + protected Index buildIndex() { + return Index + .builder() + .collection("integrations") + .name("ei1") + .key("environmentId", ascending()) + .build(); + } +} diff --git a/gravitee-apim-repository/gravitee-apim-repository-test/src/test/java/io/gravitee/repository/management/AbstractManagementRepositoryTest.java b/gravitee-apim-repository/gravitee-apim-repository-test/src/test/java/io/gravitee/repository/management/AbstractManagementRepositoryTest.java index 45570b13543..625d78390d8 100644 --- a/gravitee-apim-repository/gravitee-apim-repository-test/src/test/java/io/gravitee/repository/management/AbstractManagementRepositoryTest.java +++ b/gravitee-apim-repository/gravitee-apim-repository-test/src/test/java/io/gravitee/repository/management/AbstractManagementRepositoryTest.java @@ -193,6 +193,9 @@ public abstract class AbstractManagementRepositoryTest extends AbstractRepositor @Inject protected AccessPointRepository accessPointRepository; + @Inject + protected IntegrationRepository integrationRepository; + protected void createModel(Object object) throws TechnicalException { if (object instanceof Application) { applicationRepository.create((Application) object); @@ -301,6 +304,8 @@ protected void createModel(Object object) throws TechnicalException { upgraderRepository.create((UpgradeRecord) object); } else if (object instanceof AccessPoint) { accessPointRepository.create((AccessPoint) object); + } else if (object instanceof Integration) { + integrationRepository.create((Integration) object); } } diff --git a/gravitee-apim-repository/gravitee-apim-repository-test/src/test/java/io/gravitee/repository/management/IntegrationRepositoryTest.java b/gravitee-apim-repository/gravitee-apim-repository-test/src/test/java/io/gravitee/repository/management/IntegrationRepositoryTest.java new file mode 100644 index 00000000000..3f03b875732 --- /dev/null +++ b/gravitee-apim-repository/gravitee-apim-repository-test/src/test/java/io/gravitee/repository/management/IntegrationRepositoryTest.java @@ -0,0 +1,97 @@ +/* + * Copyright © 2015 The Gravitee team (http://gravitee.io) + * + * 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. + */ +package io.gravitee.repository.management; + +import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.groups.Tuple.tuple; + +import io.gravitee.common.utils.UUID; +import io.gravitee.repository.exceptions.TechnicalException; +import io.gravitee.repository.management.api.search.builder.PageableBuilder; +import io.gravitee.repository.management.model.Integration; +import java.util.Date; +import java.util.List; +import org.junit.Test; + +public class IntegrationRepositoryTest extends AbstractManagementRepositoryTest { + + @Override + protected String getTestCasesPath() { + return "/data/integration-tests/"; + } + + @Test + public void shouldCreate() throws TechnicalException { + var date = new Date(); + var uuid = UUID.random().toString(); + Integration integration = creatIntegration(uuid, date); + + Integration createdIntegration = integrationRepository.create(integration); + + assertThat(createdIntegration).isEqualTo(integration); + } + + @Test + public void shouldThrowExceptionWhenInsertSameIdIntegration() throws TechnicalException { + var date = new Date(); + var uuid = UUID.random().toString(); + Integration integration = creatIntegration(uuid, date); + + integrationRepository.create(integration); + assertThatThrownBy(() -> integrationRepository.create(integration)) + .isInstanceOf(Exception.class) + .cause() + .hasMessageContaining("duplicate key"); + } + + private static Integration creatIntegration(String uuid, Date date) { + return Integration + .builder() + .id(uuid) + .name("my-name") + .description("my-description") + .provider("my_provider") + .environmentId("my-env") + .createdAt(date) + .updatedAt(date) + .build(); + } + + @Test + public void shouldFindByEnvironmentId() throws TechnicalException { + final List integrations = integrationRepository + .findAllByEnvironment("my-env", new PageableBuilder().pageSize(10).pageNumber(0).build()) + .getContent(); + + assertThat(integrations) + .hasSize(3) + .extracting(Integration::getId, Integration::getName, Integration::getDescription, Integration::getEnvironmentId) + .contains( + tuple("cad107c9-27f2-40b2-9107-c927f2e0b2fc", "my-integration", "test-description", "my-env"), + tuple("f66274c9-3d8f-44c5-a274-c93d8fb4c5f3", "my-another-integration", "test-description", "my-env"), + tuple("459a022c-e79c-4411-9a02-2ce79c141165", "my-yet-another-integration", "test-description", "my-env") + ); + } + + @Test + public void shouldReturnEmptyListWhenEnvironmentIdNotFound() throws TechnicalException { + final List integrations = integrationRepository + .findAllByEnvironment("other-env", new PageableBuilder().pageSize(10).pageNumber(0).build()) + .getContent(); + + assertThat(integrations).hasSize(0); + } +} diff --git a/gravitee-apim-repository/gravitee-apim-repository-test/src/test/java/io/gravitee/repository/management/RepositoryTestSuite.java b/gravitee-apim-repository/gravitee-apim-repository-test/src/test/java/io/gravitee/repository/management/RepositoryTestSuite.java index 95188f1b008..9ae15ba6fbc 100644 --- a/gravitee-apim-repository/gravitee-apim-repository-test/src/test/java/io/gravitee/repository/management/RepositoryTestSuite.java +++ b/gravitee-apim-repository/gravitee-apim-repository-test/src/test/java/io/gravitee/repository/management/RepositoryTestSuite.java @@ -51,6 +51,7 @@ IdentityProviderActivationRepositoryTest.class, IdentityProviderRepositoryTest.class, InstallationRepositoryTest.class, + IntegrationRepositoryTest.class, InvitationRepositoryTest.class, MediaRepositoryTest.class, MembershipRepositoryTest.class, diff --git a/gravitee-apim-repository/gravitee-apim-repository-test/src/test/resources/data/integration-tests/integrations.json b/gravitee-apim-repository/gravitee-apim-repository-test/src/test/resources/data/integration-tests/integrations.json new file mode 100644 index 00000000000..9cc38f5ae58 --- /dev/null +++ b/gravitee-apim-repository/gravitee-apim-repository-test/src/test/resources/data/integration-tests/integrations.json @@ -0,0 +1,29 @@ +[ + { + "id": "cad107c9-27f2-40b2-9107-c927f2e0b2fc", + "description": "test-description", + "environmentId": "my-env", + "name": "my-integration", + "provider": "sample-provider", + "createdAt": 1470157767000, + "updatedAt": 1470157767000 + }, + { + "id": "f66274c9-3d8f-44c5-a274-c93d8fb4c5f3", + "description": "test-description", + "environmentId": "my-env", + "name": "my-another-integration", + "provider": "sample-provider", + "createdAt": 1470157767000, + "updatedAt": 1470157767000 + }, + { + "id": "459a022c-e79c-4411-9a02-2ce79c141165", + "description": "test-description", + "environmentId": "my-env", + "name": "my-yet-another-integration", + "provider": "sample-provider", + "createdAt": 1470157767000, + "updatedAt": 1470157767000 + } +] \ No newline at end of file diff --git a/gravitee-apim-rest-api/gravitee-apim-rest-api-management-v2/gravitee-apim-rest-api-management-v2-rest/src/main/resources/openapi/openapi-apis.yaml b/gravitee-apim-rest-api/gravitee-apim-rest-api-management-v2/gravitee-apim-rest-api-management-v2-rest/src/main/resources/openapi/openapi-apis.yaml index 6f2c0a1d975..13b6c72bc0c 100644 --- a/gravitee-apim-rest-api/gravitee-apim-rest-api-management-v2/gravitee-apim-rest-api-management-v2-rest/src/main/resources/openapi/openapi-apis.yaml +++ b/gravitee-apim-rest-api/gravitee-apim-rest-api-management-v2/gravitee-apim-rest-api-management-v2-rest/src/main/resources/openapi/openapi-apis.yaml @@ -5850,14 +5850,19 @@ components: name: type: string description: Name of the integration + minLength: 1 + maxLength: 50 description: type: string description: Description of the integration + minLength: 0 + maxLength: 250 provider: type: string description: Provider of this integration required: - name + - provider parameters: #############