16
16
package com .oceanbase .odc .service .connection .database ;
17
17
18
18
import java .sql .Connection ;
19
- import java .sql .SQLException ;
20
19
import java .util .ArrayList ;
21
20
import java .util .Arrays ;
22
21
import java .util .Collection ;
27
26
import java .util .List ;
28
27
import java .util .Map ;
29
28
import java .util .Objects ;
29
+ import java .util .Optional ;
30
30
import java .util .Set ;
31
31
import java .util .TreeSet ;
32
32
import java .util .concurrent .ExecutionException ;
72
72
import com .oceanbase .odc .core .shared .exception .BadRequestException ;
73
73
import com .oceanbase .odc .core .shared .exception .ConflictException ;
74
74
import com .oceanbase .odc .core .shared .exception .NotFoundException ;
75
+ import com .oceanbase .odc .core .shared .exception .UnexpectedException ;
75
76
import com .oceanbase .odc .metadb .connection .DatabaseEntity ;
76
77
import com .oceanbase .odc .metadb .connection .DatabaseRepository ;
77
78
import com .oceanbase .odc .metadb .connection .DatabaseSpecs ;
115
116
import com .oceanbase .odc .service .iam .ResourceRoleService ;
116
117
import com .oceanbase .odc .service .iam .UserService ;
117
118
import com .oceanbase .odc .service .iam .auth .AuthenticationFacade ;
119
+ import com .oceanbase .odc .service .iam .model .Organization ;
118
120
import com .oceanbase .odc .service .iam .model .User ;
119
121
import com .oceanbase .odc .service .iam .model .UserResourceRole ;
120
122
import com .oceanbase .odc .service .monitor .datasource .GetConnectionFailedEventListener ;
@@ -512,19 +514,24 @@ public Boolean internalSyncDataSourceSchemas(@NonNull Long dataSourceId) throws
512
514
throw new ConflictException (ErrorCodes .ResourceSynchronizing ,
513
515
new Object [] {ResourceType .ODC_DATABASE .getLocalizedMessage ()}, "Can not acquire jdbc lock" );
514
516
}
517
+ ConnectionConfig connection ;
518
+ Optional <Organization > organizationOpt = Optional .empty ();
515
519
try {
516
- ConnectionConfig connection = connectionService .getForConnectionSkipPermissionCheck (dataSourceId );
520
+ connection = connectionService .getForConnectionSkipPermissionCheck (dataSourceId );
517
521
horizontalDataPermissionValidator .checkCurrentOrganization (connection );
518
- organizationService .get (connection .getOrganizationId ()).ifPresent (organization -> {
519
- if (organization .getType () == OrganizationType .INDIVIDUAL ) {
520
- syncIndividualDataSources (connection );
521
- } else {
522
- syncTeamDataSources (connection );
523
- }
524
- });
522
+ organizationOpt = organizationService .get (connection .getOrganizationId ());
523
+ Organization organization =
524
+ organizationOpt .orElseThrow (() -> new UnexpectedException ("Organization not found" ));
525
+ if (organization .getType () == OrganizationType .INDIVIDUAL ) {
526
+ syncIndividualDataSources (connection );
527
+ } else {
528
+ syncTeamDataSources (connection );
529
+ }
530
+ connectionSyncHistoryService .upsert (connection .getId (), ConnectionSyncResult .SUCCESS ,
531
+ connection .getOrganizationId (), null , null );
525
532
return true ;
526
533
} catch (Exception ex ) {
527
- log . warn ( "Sync database failed , dataSourceId={}, errorMessage={}" , dataSourceId , ex . getLocalizedMessage () );
534
+ handleSyncException ( ex , dataSourceId , organizationOpt );
528
535
return false ;
529
536
} finally {
530
537
lock .unlock ();
@@ -535,7 +542,8 @@ public int updateEnvironmentIdByConnectionId(@NotNull Long environmentId, @NotNu
535
542
return databaseRepository .setEnvironmentIdByConnectionId (environmentId , connectionId );
536
543
}
537
544
538
- private void syncTeamDataSources (ConnectionConfig connection ) {
545
+ private void syncTeamDataSources (ConnectionConfig connection )
546
+ throws ExecutionException , InterruptedException , TimeoutException {
539
547
Long currentProjectId = connection .getProjectId ();
540
548
boolean blockExcludeSchemas = dbSchemaSyncProperties .isBlockExclusionsWhenSyncDbToProject ();
541
549
List <String > excludeSchemas = dbSchemaSyncProperties .getExcludeSchemas (connection .getDialectType ());
@@ -633,20 +641,6 @@ private void syncTeamDataSources(ConnectionConfig connection) {
633
641
}
634
642
connectionSyncHistoryService .upsert (connection .getId (), ConnectionSyncResult .SUCCESS ,
635
643
connection .getOrganizationId (), null , null );
636
- } catch (ExecutionException | InterruptedException | TimeoutException e ) {
637
- String errorMessage = e .getMessage ();
638
- Throwable rootCause = e .getCause ();
639
- ConnectionSyncErrorReason failedReason = ConnectionSyncErrorReason .UNKNOWN ;
640
- log .warn ("Failed to obtain the connection, errorMessage={}" , errorMessage );
641
- if (rootCause instanceof SQLException
642
- && StringUtils .containsIgnoreCase (errorMessage , "cluster not exist" )) {
643
- failedReason = ConnectionSyncErrorReason .CLUSTER_NOT_EXISTS ;
644
- deleteDatabaseIfClusterNotExists ((SQLException ) rootCause ,
645
- connection .getId (), "update connect_database set is_existed = 0 where connection_id=?" );
646
- }
647
- connectionSyncHistoryService .upsert (connection .getId (), ConnectionSyncResult .FAILURE ,
648
- connection .getOrganizationId (), failedReason ,
649
- rootCause .getMessage ());
650
644
} finally {
651
645
try {
652
646
executorService .shutdownNow ();
@@ -685,7 +679,8 @@ private Long getProjectId(DatabaseEntity database, Long currentProjectId, List<S
685
679
return projectId ;
686
680
}
687
681
688
- private void syncIndividualDataSources (ConnectionConfig connection ) {
682
+ private void syncIndividualDataSources (ConnectionConfig connection )
683
+ throws ExecutionException , InterruptedException , TimeoutException {
689
684
DataSource individualDataSource = getDataSourceFactory (connection ).getDataSource ();
690
685
ExecutorService executorService = Executors .newFixedThreadPool (1 );
691
686
Future <Set <String >> future = executorService .submit (() -> {
@@ -733,20 +728,6 @@ private void syncIndividualDataSources(ConnectionConfig connection) {
733
728
}
734
729
connectionSyncHistoryService .upsert (connection .getId (), ConnectionSyncResult .SUCCESS ,
735
730
connection .getOrganizationId (), null , null );
736
- } catch (ExecutionException | InterruptedException | TimeoutException e ) {
737
- String errorMessage = e .getMessage ();
738
- Throwable rootCause = e .getCause ();
739
- ConnectionSyncErrorReason failedReason = ConnectionSyncErrorReason .UNKNOWN ;
740
- log .warn ("Failed to obtain the connection, errorMessage={}" , errorMessage );
741
- if (rootCause instanceof SQLException
742
- && StringUtils .containsIgnoreCase (errorMessage , "cluster not exist" )) {
743
- failedReason = ConnectionSyncErrorReason .CLUSTER_NOT_EXISTS ;
744
- deleteDatabaseIfClusterNotExists ((SQLException ) rootCause ,
745
- connection .getId (), "delete from connect_database where connection_id=?" );
746
- }
747
- connectionSyncHistoryService .upsert (connection .getId (), ConnectionSyncResult .FAILURE ,
748
- connection .getOrganizationId (), failedReason ,
749
- rootCause .getMessage ());
750
731
} finally {
751
732
try {
752
733
executorService .shutdownNow ();
@@ -1056,19 +1037,44 @@ private List<UserResourceRole> buildUserResourceRoles(Collection<Long> databaseI
1056
1037
return userResourceRoles ;
1057
1038
}
1058
1039
1040
+ private void handleSyncException (@ NonNull Exception ex , @ NonNull Long dataSourceId ,
1041
+ @ NonNull Optional <Organization > organizationOpt ) {
1042
+ String errorMessage = ex .getMessage ();
1043
+ log .warn ("Sync database failed, dataSourceId={}, errorMessage={}" , dataSourceId , errorMessage );
1044
+ if (!organizationOpt .isPresent ()) {
1045
+ return ;
1046
+ }
1047
+ Organization organization = organizationOpt .get ();
1048
+ ConnectionSyncErrorReason failedReason = ConnectionSyncErrorReason .UNKNOWN ;
1049
+ if (StringUtils .containsIgnoreCase (errorMessage , "cluster not exist" )) {
1050
+ failedReason = ConnectionSyncErrorReason .CLUSTER_NOT_EXISTS ;
1051
+ deleteDatabaseIfInstanceNotExists (dataSourceId , organization .getType ());
1052
+ } else if (StringUtils .containsIgnoreCase (errorMessage , "No tenants found" ) || StringUtils
1053
+ .containsIgnoreCase (errorMessage , "tenant expected 1 but was" )) {
1054
+ failedReason = ConnectionSyncErrorReason .TENANT_NOT_EXISTS ;
1055
+ deleteDatabaseIfInstanceNotExists (dataSourceId , organization .getType ());
1056
+ }
1057
+ connectionSyncHistoryService .upsert (dataSourceId , ConnectionSyncResult .FAILURE , organization .getId (),
1058
+ failedReason , errorMessage );
1059
+ }
1059
1060
1060
- private void deleteDatabaseIfClusterNotExists (SQLException e , Long connectionId , String deleteSql ) {
1061
- if (StringUtils .containsIgnoreCase (e .getMessage (), "cluster not exist" )) {
1062
- log .info (
1063
- "Cluster not exist, set existed to false for all databases in this data source, data source id = {}" ,
1064
- connectionId );
1065
- JdbcTemplate jdbcTemplate = new JdbcTemplate (dataSource );
1066
- try {
1067
- jdbcTemplate .update (deleteSql , new Object [] {connectionId });
1068
- } catch (Exception ex ) {
1069
- log .warn ("Failed to delete databases when cluster not exist, errorMessage={}" ,
1070
- ex .getLocalizedMessage ());
1071
- }
1061
+ private void deleteDatabaseIfInstanceNotExists (Long connectionId , OrganizationType organizationType ) {
1062
+ log .info (
1063
+ "Cluster or tenant not exist, set existed to false for all databases in this data source, data source id = {}" ,
1064
+ connectionId );
1065
+ JdbcTemplate jdbcTemplate = new JdbcTemplate (dataSource );
1066
+ String deleteSql ;
1067
+ if (organizationType == OrganizationType .INDIVIDUAL ) {
1068
+ deleteSql = "delete from connect_database where connection_id=?" ;
1069
+ } else {
1070
+ deleteSql = "update connect_database set is_existed = 0 where connection_id=?" ;
1072
1071
}
1072
+ try {
1073
+ jdbcTemplate .update (deleteSql , connectionId );
1074
+ } catch (Exception ex ) {
1075
+ log .warn ("Failed to delete databases when cluster not exist, errorMessage={}" ,
1076
+ ex .getLocalizedMessage ());
1077
+ }
1078
+
1073
1079
}
1074
1080
}
0 commit comments