Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: JDBC support for creating and listing integrations #7018

Merged
merged 1 commit into from Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -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<Integration, String> implements IntegrationRepository {

private static final Logger LOGGER = LoggerFactory.getLogger(JdbcIntegrationRepository.class);

JdbcIntegrationRepository(@Value("${management.jdbc.prefix:}") String prefix) {
super(prefix, "integrations");
}

@Override
public Page<Integration> findAllByEnvironment(String environmentId, Pageable pageable) throws TechnicalException {
LOGGER.debug("JdbcIntegrationRepository.findAllByEnvironment({}, {})", environmentId, pageable);
final List<Integration> 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<Integration> 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();
}
}
@@ -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
Expand Up @@ -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
Expand Up @@ -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<String> tablesToDrop = concatenate(
tablesToTruncate,
Expand Down
Expand Up @@ -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
Expand Down
@@ -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();
}
}
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
}

Expand Down
@@ -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 {
jgiovaresco marked this conversation as resolved.
Show resolved Hide resolved
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<Integration> 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<Integration> integrations = integrationRepository
.findAllByEnvironment("other-env", new PageableBuilder().pageSize(10).pageNumber(0).build())
.getContent();

assertThat(integrations).hasSize(0);
}
}
Expand Up @@ -51,6 +51,7 @@
IdentityProviderActivationRepositoryTest.class,
IdentityProviderRepositoryTest.class,
InstallationRepositoryTest.class,
IntegrationRepositoryTest.class,
InvitationRepositoryTest.class,
MediaRepositoryTest.class,
MembershipRepositoryTest.class,
Expand Down
@@ -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
}
]
Expand Up @@ -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:
#############
Expand Down