Skip to content

Commit 0b75bed

Browse files
authored
Merge pull request lowcoder-org#245 from lvhuichao/develop
feat: support dynamic js data source plugins
2 parents f6079a6 + cc69d45 commit 0b75bed

File tree

17 files changed

+457
-108
lines changed

17 files changed

+457
-108
lines changed

server/api-service/openblocks-domain/src/main/java/com/openblocks/domain/datasource/model/Datasource.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.fasterxml.jackson.annotation.JsonIgnore;
1818
import com.fasterxml.jackson.annotation.JsonProperty;
1919
import com.openblocks.domain.plugin.DatasourceMetaInfoConstants;
20+
import com.openblocks.domain.plugin.client.dto.DatasourcePluginDefinition;
2021
import com.openblocks.sdk.models.DatasourceConnectionConfig;
2122
import com.openblocks.sdk.models.HasIdAndAuditing;
2223
import com.openblocks.sdk.models.JsDatasourceConnectionConfig;
@@ -75,7 +76,7 @@ public class Datasource extends HasIdAndAuditing {
7576
// for js data source plugin
7677
@Nullable
7778
@Transient
78-
private Object pluginDefinition;
79+
private DatasourcePluginDefinition pluginDefinition;
7980

8081
@JsonProperty(value = "datasourceConfig")
8182
private DatasourceConnectionConfig detailConfig;

server/api-service/openblocks-domain/src/main/java/com/openblocks/domain/datasource/repository/DatasourceRepository.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import com.openblocks.domain.datasource.model.DatasourceCreationSource;
1717
import com.openblocks.domain.datasource.model.DatasourceDO;
1818
import com.openblocks.domain.datasource.model.DatasourceStatus;
19-
import com.openblocks.domain.datasource.service.DatasourceService;
19+
import com.openblocks.domain.datasource.service.JsDatasourceHelper;
2020
import com.openblocks.domain.encryption.EncryptionService;
2121
import com.openblocks.domain.plugin.client.DatasourcePluginClient;
2222
import com.openblocks.domain.plugin.service.DatasourceMetaInfoService;
@@ -54,7 +54,7 @@ public class DatasourceRepository {
5454
private DatasourcePluginClient datasourcePluginClient;
5555

5656
@Autowired
57-
private DatasourceService datasourceService;
57+
private JsDatasourceHelper jsDatasourceHelper;
5858

5959
public Mono<Datasource> findById(String datasourceId) {
6060
return repository.findById(datasourceId)
@@ -67,6 +67,11 @@ public Mono<Datasource> findWorkspacePredefinedDatasourceByOrgIdAndType(String o
6767
.flatMap(this::convertToDomainObjectAndDecrypt);
6868
}
6969

70+
public Flux<Datasource> findAllById(Iterable<String> ids) {
71+
return repository.findAllById(ids)
72+
.flatMap(this::convertToDomainObjectAndDecrypt);
73+
}
74+
7075
public Flux<Datasource> findAllByOrganizationId(String orgId) {
7176
return repository.findAllByOrganizationId(orgId)
7277
.flatMap(this::convertToDomainObjectAndDecrypt);
@@ -136,7 +141,7 @@ private Mono<Datasource> convertToDomainObjectAndDecrypt(DatasourceDO datasource
136141
datasource.setDetailConfig(detailConfig);
137142
}
138143
})
139-
.delayUntil(datasourceService::processJsDatasourcePlugin)
144+
.delayUntil(jsDatasourceHelper::fillPluginDefinition)
140145
.doOnNext(datasource -> {
141146
DatasourceConnectionConfig decryptedDetailConfig = datasource.getDetailConfig().doDecrypt(encryptionService::decryptString);
142147
// override
@@ -164,7 +169,7 @@ private Mono<DatasourceDO> encryptDataAndConvertToDataObject(Datasource datasour
164169
result.setModifiedBy(datasource.getModifiedBy());
165170
return result;
166171
})
167-
.delayUntil(__ -> datasourceService.processJsDatasourcePlugin(datasource))
172+
.delayUntil(__ -> jsDatasourceHelper.fillPluginDefinition(datasource))
168173
.doOnNext(datasourceDO -> {
169174
DatasourceConnectionConfig detailConfig = datasource.getDetailConfig();
170175
DatasourceConnectionConfig encryptedConfig = detailConfig.doEncrypt(encryptionService::encryptString);

server/api-service/openblocks-domain/src/main/java/com/openblocks/domain/datasource/service/DatasourceService.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@ public interface DatasourceService {
2020

2121
Mono<DatasourceTestResult> testDatasource(Datasource datasource);
2222

23-
/**
24-
* before merge, encrypt, decrypt, and removePasswords
25-
*/
26-
Mono<Void> processJsDatasourcePlugin(Datasource datasource);
27-
2823
Mono<Void> removePasswordTypeKeysFromJsDatasourcePluginConfig(Datasource datasource);
2924

3025
Flux<Datasource> getByOrgId(String orgId);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package com.openblocks.domain.datasource.service;
2+
3+
import java.util.List;
4+
5+
import org.apache.commons.lang3.ObjectUtils;
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.stereotype.Component;
8+
9+
import com.openblocks.domain.datasource.model.Datasource;
10+
import com.openblocks.domain.plugin.client.DatasourcePluginClient;
11+
import com.openblocks.domain.plugin.client.dto.GetPluginDynamicConfigRequestDTO;
12+
import com.openblocks.domain.plugin.service.DatasourceMetaInfoService;
13+
import com.openblocks.sdk.models.JsDatasourceConnectionConfig;
14+
15+
import reactor.core.publisher.Mono;
16+
17+
@Component
18+
public class JsDatasourceHelper {
19+
20+
@Autowired
21+
private DatasourceMetaInfoService datasourceMetaInfoService;
22+
@Autowired
23+
private DatasourcePluginClient datasourcePluginClient;
24+
25+
/**
26+
* before merge, encrypt, decrypt, and removePasswords
27+
*/
28+
public Mono<Void> fillPluginDefinition(Datasource datasource) {
29+
return Mono.defer(() -> {
30+
if (datasourceMetaInfoService.isJsDatasourcePlugin(datasource.getType())
31+
&& datasource.getDetailConfig() instanceof JsDatasourceConnectionConfig jsDatasourceConfig
32+
&& ObjectUtils.anyNull(datasource.getPluginDefinition(), jsDatasourceConfig.getDefinition(), jsDatasourceConfig.getType())) {
33+
34+
return datasourcePluginClient.getDatasourcePluginDefinition(datasource.getType())
35+
.doOnNext(datasourcePluginDTO -> {
36+
datasource.setPluginDefinition(datasourcePluginDTO);
37+
jsDatasourceConfig.setDefinition(datasourcePluginDTO);
38+
jsDatasourceConfig.setType(datasource.getType());
39+
})
40+
.then();
41+
}
42+
return Mono.empty();
43+
});
44+
}
45+
46+
public Mono<Void> processDynamicDatasourceConfigExtra(Datasource datasource) {
47+
if (datasourceMetaInfoService.isJavaDatasourcePlugin(datasource.getType())) {
48+
return Mono.empty();
49+
}
50+
return fillPluginDefinition(datasource)
51+
.then(Mono.fromSupplier(datasource::getPluginDefinition))
52+
.flatMap(datasourcePluginDefinition -> {
53+
if (!datasourcePluginDefinition.isDatasourceConfigExtraDynamic()) {
54+
return Mono.empty();
55+
}
56+
GetPluginDynamicConfigRequestDTO getPluginDynamicConfigRequestDTO = GetPluginDynamicConfigRequestDTO.builder()
57+
.pluginName(datasource.getType())
58+
.path("$.dataSourceConfig.extra")
59+
.dataSourceConfig((JsDatasourceConnectionConfig) datasource.getDetailConfig())
60+
.build();
61+
return datasourcePluginClient.getPluginDynamicConfig(List.of(getPluginDynamicConfigRequestDTO))
62+
.flatMap(list -> {
63+
if (list.size() == 1) {
64+
Object datasourceConfigExtra = list.get(0);
65+
JsDatasourceConnectionConfig jsDatasourceConnectionConfig =
66+
(JsDatasourceConnectionConfig) datasource.getDetailConfig();
67+
jsDatasourceConnectionConfig.put("extra", datasourceConfigExtra);
68+
}
69+
return Mono.empty();
70+
});
71+
});
72+
}
73+
74+
public Mono<Void> processDynamicQueryConfig(Datasource datasource) {
75+
if (datasourceMetaInfoService.isJavaDatasourcePlugin(datasource.getType())) {
76+
return Mono.empty();
77+
}
78+
return fillPluginDefinition(datasource)
79+
.then(Mono.fromSupplier(datasource::getPluginDefinition))
80+
.flatMap(datasourcePluginDefinition -> {
81+
if (!datasourcePluginDefinition.isQueryConfigDynamic()) {
82+
return Mono.empty();
83+
}
84+
GetPluginDynamicConfigRequestDTO getPluginDynamicConfigRequestDTO = GetPluginDynamicConfigRequestDTO.builder()
85+
.pluginName(datasource.getType())
86+
.path("$.queryConfig")
87+
.dataSourceConfig((JsDatasourceConnectionConfig) datasource.getDetailConfig())
88+
.build();
89+
return datasourcePluginClient.getPluginDynamicConfigSafely(List.of(getPluginDynamicConfigRequestDTO))
90+
.flatMap(list -> {
91+
if (list.size() == 1) {
92+
Object queryConfig = list.get(0);
93+
datasourcePluginDefinition.put("queryConfig", queryConfig);
94+
}
95+
return Mono.empty();
96+
});
97+
});
98+
}
99+
}

server/api-service/openblocks-domain/src/main/java/com/openblocks/domain/datasource/service/impl/DatasourceServiceImpl.java

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import javax.annotation.Nonnull;
1515

1616
import org.apache.commons.collections4.CollectionUtils;
17-
import org.apache.commons.lang3.ObjectUtils;
1817
import org.apache.commons.lang3.StringUtils;
1918
import org.springframework.beans.factory.annotation.Autowired;
2019
import org.springframework.dao.DuplicateKeyException;
@@ -26,6 +25,7 @@
2625
import com.openblocks.domain.datasource.model.Datasource;
2726
import com.openblocks.domain.datasource.repository.DatasourceRepository;
2827
import com.openblocks.domain.datasource.service.DatasourceService;
28+
import com.openblocks.domain.datasource.service.JsDatasourceHelper;
2929
import com.openblocks.domain.permission.model.ResourceRole;
3030
import com.openblocks.domain.permission.service.ResourcePermissionService;
3131
import com.openblocks.domain.plugin.client.DatasourcePluginClient;
@@ -59,6 +59,8 @@ public class DatasourceServiceImpl implements DatasourceService {
5959
private DatasourceRepository repository;
6060
@Autowired
6161
private DatasourcePluginClient datasourcePluginClient;
62+
@Autowired
63+
private JsDatasourceHelper jsDatasourceHelper;
6264

6365
@Override
6466
public Mono<Datasource> create(Datasource datasource, String creatorId) {
@@ -81,7 +83,7 @@ public Mono<Datasource> update(String datasourceId, Datasource updatedDatasource
8183
}
8284

8385
return repository.findById(datasourceId)
84-
.delayUntil(this::processJsDatasourcePlugin)
86+
.delayUntil(jsDatasourceHelper::fillPluginDefinition)
8587
.map(currentDatasource -> currentDatasource.mergeWith(updatedDatasource))
8688
.flatMap(this::validateDatasource)
8789
.flatMap(this::trySaveDatasource);
@@ -160,7 +162,7 @@ public Mono<DatasourceTestResult> testDatasource(Datasource testDatasource) {
160162
if (testDatasource.getId() != null) {
161163
datasourceMono = getById(testDatasource.getId())
162164
.switchIfEmpty(deferredError(BizError.NOT_AUTHORIZED, "NOT_AUTHORIZED"))
163-
.delayUntil(this::processJsDatasourcePlugin)
165+
.delayUntil(jsDatasourceHelper::fillPluginDefinition)
164166
.map(datasource -> datasource.mergeWith(testDatasource));
165167
}
166168

@@ -185,31 +187,9 @@ private Mono<DatasourceTestResult> testDatasourceByNodeJs(Datasource datasource)
185187
return datasourcePluginClient.test(datasource.getType(), datasource.getDetailConfig());
186188
}
187189

188-
/**
189-
* before merge, encrypt, decrypt, and removePasswords
190-
*/
191-
@Override
192-
public Mono<Void> processJsDatasourcePlugin(Datasource datasource) {
193-
return Mono.defer(() -> {
194-
if (datasourceMetaInfoService.isJsDatasourcePlugin(datasource.getType())
195-
&& datasource.getDetailConfig() instanceof JsDatasourceConnectionConfig jsDatasourceConfig
196-
&& ObjectUtils.anyNull(datasource.getPluginDefinition(), jsDatasourceConfig.getDefinition(), jsDatasourceConfig.getType())) {
197-
198-
return datasourcePluginClient.getDatasourcePlugin(datasource.getType())
199-
.doOnNext(datasourcePluginDTO -> {
200-
datasource.setPluginDefinition(datasourcePluginDTO);
201-
jsDatasourceConfig.setDefinition(datasourcePluginDTO);
202-
jsDatasourceConfig.setType(datasource.getType());
203-
})
204-
.then();
205-
}
206-
return Mono.empty();
207-
});
208-
}
209-
210190
@Override
211191
public Mono<Void> removePasswordTypeKeysFromJsDatasourcePluginConfig(Datasource datasource) {
212-
return processJsDatasourcePlugin(datasource)
192+
return jsDatasourceHelper.fillPluginDefinition(datasource)
213193
.doFinally(__ -> {
214194
if (datasourceMetaInfoService.isJsDatasourcePlugin(datasource.getType())
215195
&& datasource.getDetailConfig() instanceof JsDatasourceConnectionConfig jsDatasourceConnectionConfig) {

0 commit comments

Comments
 (0)