Skip to content

Commit e745e73

Browse files
authored
document that web backends should not have db access (#22509)
1 parent dfd5429 commit e745e73

File tree

3 files changed

+42
-22
lines changed

3 files changed

+42
-22
lines changed

airbyte-commons-server/src/main/java/io/airbyte/commons/server/handlers/WebBackendCheckUpdatesHandler.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,24 @@
1818
import java.util.stream.Collectors;
1919
import lombok.extern.slf4j.Slf4j;
2020

21+
/**
22+
* The web backend is an abstraction that allows the frontend to structure data in such a way that
23+
* it is easier for a react frontend to consume. It should NOT have direct access to the database.
24+
* It should operate exclusively by calling other endpoints that are exposed in the API.
25+
**/
2126
@Slf4j
2227
@Singleton
2328
public class WebBackendCheckUpdatesHandler {
2429

2530
private static final int NO_CHANGES_FOUND = 0;
2631

27-
final ConfigRepository configRepository;
32+
// todo (cgardens) - this handler should NOT have access to the db. only access via handler.
33+
@Deprecated
34+
final ConfigRepository configRepositoryDoNotUse;
2835
final AirbyteGithubStore githubStore;
2936

30-
public WebBackendCheckUpdatesHandler(final ConfigRepository configRepository, final AirbyteGithubStore githubStore) {
31-
this.configRepository = configRepository;
37+
public WebBackendCheckUpdatesHandler(final ConfigRepository configRepositoryDoNotUse, final AirbyteGithubStore githubStore) {
38+
this.configRepositoryDoNotUse = configRepositoryDoNotUse;
3239
this.githubStore = githubStore;
3340
}
3441

@@ -47,7 +54,7 @@ private int getDestinationDiffCount() {
4754
final Map<UUID, String> newActorDefToDockerImageTag;
4855

4956
try {
50-
currentActorDefToDockerImageTag = configRepository.listStandardDestinationDefinitions(false)
57+
currentActorDefToDockerImageTag = configRepositoryDoNotUse.listStandardDestinationDefinitions(false)
5158
.stream()
5259
.map(def -> Map.entry(def.getDestinationDefinitionId(), def.getDockerImageTag()))
5360
.toList();
@@ -73,7 +80,7 @@ private int getSourceDiffCount() {
7380
final Map<UUID, String> newActorDefToDockerImageTag;
7481

7582
try {
76-
currentActorDefToDockerImageTag = configRepository.listStandardSourceDefinitions(false)
83+
currentActorDefToDockerImageTag = configRepositoryDoNotUse.listStandardSourceDefinitions(false)
7784
.stream()
7885
.map(def -> Map.entry(def.getSourceDefinitionId(), def.getDockerImageTag()))
7986
.toList();

airbyte-commons-server/src/main/java/io/airbyte/commons/server/handlers/WebBackendConnectionsHandler.java

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@
7575
import java.util.function.Function;
7676
import java.util.stream.Collectors;
7777

78+
/**
79+
* The web backend is an abstraction that allows the frontend to structure data in such a way that
80+
* it is easier for a react frontend to consume. It should NOT have direct access to the database.
81+
* It should operate exclusively by calling other endpoints that are exposed in the API.
82+
**/
7883
@Singleton
7984
public class WebBackendConnectionsHandler {
8085

@@ -87,7 +92,8 @@ public class WebBackendConnectionsHandler {
8792
private final OperationsHandler operationsHandler;
8893
private final EventRunner eventRunner;
8994
// todo (cgardens) - this handler should NOT have access to the db. only access via handler.
90-
private final ConfigRepository configRepository;
95+
@Deprecated
96+
private final ConfigRepository configRepositoryDoNotUse;
9197

9298
public WebBackendConnectionsHandler(final ConnectionsHandler connectionsHandler,
9399
final StateHandler stateHandler,
@@ -97,7 +103,7 @@ public WebBackendConnectionsHandler(final ConnectionsHandler connectionsHandler,
97103
final SchedulerHandler schedulerHandler,
98104
final OperationsHandler operationsHandler,
99105
final EventRunner eventRunner,
100-
final ConfigRepository configRepository) {
106+
final ConfigRepository configRepositoryDoNotUse) {
101107
this.connectionsHandler = connectionsHandler;
102108
this.stateHandler = stateHandler;
103109
this.sourceHandler = sourceHandler;
@@ -106,14 +112,14 @@ public WebBackendConnectionsHandler(final ConnectionsHandler connectionsHandler,
106112
this.schedulerHandler = schedulerHandler;
107113
this.operationsHandler = operationsHandler;
108114
this.eventRunner = eventRunner;
109-
this.configRepository = configRepository;
115+
this.configRepositoryDoNotUse = configRepositoryDoNotUse;
110116
}
111117

112118
public WebBackendWorkspaceStateResult getWorkspaceState(final WebBackendWorkspaceState webBackendWorkspaceState) throws IOException {
113119
final var workspaceId = webBackendWorkspaceState.getWorkspaceId();
114-
final var connectionCount = configRepository.countConnectionsForWorkspace(workspaceId);
115-
final var destinationCount = configRepository.countDestinationsForWorkspace(workspaceId);
116-
final var sourceCount = configRepository.countSourcesForWorkspace(workspaceId);
120+
final var connectionCount = configRepositoryDoNotUse.countConnectionsForWorkspace(workspaceId);
121+
final var destinationCount = configRepositoryDoNotUse.countDestinationsForWorkspace(workspaceId);
122+
final var sourceCount = configRepositoryDoNotUse.countSourcesForWorkspace(workspaceId);
117123

118124
return new WebBackendWorkspaceStateResult()
119125
.hasConnections(connectionCount > 0)
@@ -135,7 +141,7 @@ public WebBackendConnectionReadList webBackendListConnectionsForWorkspace(final
135141
// passing 'false' so that deleted connections are not included
136142
false);
137143

138-
final List<StandardSync> standardSyncs = configRepository.listWorkspaceStandardSyncs(query);
144+
final List<StandardSync> standardSyncs = configRepositoryDoNotUse.listWorkspaceStandardSyncs(query);
139145
final List<UUID> sourceIds = standardSyncs.stream().map(StandardSync::getSourceId).toList();
140146
final List<UUID> destinationIds = standardSyncs.stream().map(StandardSync::getDestinationId).toList();
141147
final List<UUID> connectionIds = standardSyncs.stream().map(StandardSync::getConnectionId).toList();
@@ -148,7 +154,7 @@ public WebBackendConnectionReadList webBackendListConnectionsForWorkspace(final
148154
// right status filtering for this.
149155
final Map<UUID, JobRead> runningJobByConnectionId = getRunningJobByConnectionId(connectionIds);
150156
final Map<UUID, ActorCatalogFetchEvent> newestFetchEventsByActorId =
151-
configRepository.getMostRecentActorCatalogFetchEventForSources(sourceIds);
157+
configRepositoryDoNotUse.getMostRecentActorCatalogFetchEventForSources(sourceIds);
152158

153159
final List<WebBackendConnectionListItem> connectionItems = Lists.newArrayList();
154160

@@ -177,14 +183,14 @@ private Map<UUID, JobRead> getRunningJobByConnectionId(final List<UUID> connecti
177183
}
178184

179185
private Map<UUID, SourceSnippetRead> getSourceSnippetReadById(final List<UUID> sourceIds) throws IOException {
180-
return configRepository.getSourceAndDefinitionsFromSourceIds(sourceIds)
186+
return configRepositoryDoNotUse.getSourceAndDefinitionsFromSourceIds(sourceIds)
181187
.stream()
182188
.map(sourceAndDefinition -> SourceHandler.toSourceSnippetRead(sourceAndDefinition.source(), sourceAndDefinition.definition()))
183189
.collect(Collectors.toMap(SourceSnippetRead::getSourceId, Function.identity()));
184190
}
185191

186192
private Map<UUID, DestinationSnippetRead> getDestinationSnippetReadById(final List<UUID> destinationIds) throws IOException {
187-
return configRepository.getDestinationAndDefinitionsFromDestinationIds(destinationIds)
193+
return configRepositoryDoNotUse.getDestinationAndDefinitionsFromDestinationIds(destinationIds)
188194
.stream()
189195
.map(destinationAndDefinition -> DestinationHandler.toDestinationSnippetRead(destinationAndDefinition.destination(),
190196
destinationAndDefinition.definition()))
@@ -210,7 +216,7 @@ private WebBackendConnectionRead buildWebBackendConnectionRead(final ConnectionR
210216
});
211217

212218
final Optional<ActorCatalogFetchEvent> mostRecentFetchEvent =
213-
configRepository.getMostRecentActorCatalogFetchEventForSource(connectionRead.getSourceId());
219+
configRepositoryDoNotUse.getMostRecentActorCatalogFetchEventForSource(connectionRead.getSourceId());
214220

215221
final SchemaChange schemaChange = getSchemaChange(connectionRead, currentSourceCatalogId, mostRecentFetchEvent);
216222

@@ -539,13 +545,15 @@ public WebBackendConnectionRead webBackendUpdateConnection(final WebBackendConne
539545
if (webBackendConnectionPatch.getSyncCatalog() != null) {
540546
// Get the most recent actor catalog fetched for this connection's source and the newly updated sync
541547
// catalog
542-
Optional<ActorCatalog> mostRecentActorCatalog = configRepository.getMostRecentActorCatalogForSource(originalConnectionRead.getSourceId());
543-
AirbyteCatalog newAirbyteCatalog = webBackendConnectionPatch.getSyncCatalog();
548+
final Optional<ActorCatalog> mostRecentActorCatalog =
549+
configRepositoryDoNotUse.getMostRecentActorCatalogForSource(originalConnectionRead.getSourceId());
550+
final AirbyteCatalog newAirbyteCatalog = webBackendConnectionPatch.getSyncCatalog();
544551
// Get the diff between these two catalogs to check for breaking changes
545552
if (mostRecentActorCatalog.isPresent()) {
546553
final io.airbyte.protocol.models.AirbyteCatalog mostRecentAirbyteCatalog =
547554
Jsons.object(mostRecentActorCatalog.get().getCatalog(), io.airbyte.protocol.models.AirbyteCatalog.class);
548-
final StandardSourceDefinition sourceDefinition = configRepository.getSourceDefinitionFromSource(originalConnectionRead.getSourceId());
555+
final StandardSourceDefinition sourceDefinition =
556+
configRepositoryDoNotUse.getSourceDefinitionFromSource(originalConnectionRead.getSourceId());
549557
final CatalogDiff catalogDiff =
550558
connectionsHandler.getDiff(newAirbyteCatalog, CatalogConverter.toApi(mostRecentAirbyteCatalog, sourceDefinition),
551559
CatalogConverter.toConfiguredProtocol(newAirbyteCatalog));
@@ -556,7 +564,7 @@ public WebBackendConnectionRead webBackendUpdateConnection(final WebBackendConne
556564
// before doing any updates, fetch the existing catalog so that it can be diffed
557565
// with the final catalog to determine which streams might need to be reset.
558566
final ConfiguredAirbyteCatalog oldConfiguredCatalog =
559-
configRepository.getConfiguredCatalogForConnection(connectionId);
567+
configRepositoryDoNotUse.getConfiguredCatalogForConnection(connectionId);
560568

561569
final List<UUID> newAndExistingOperationIds = createOrUpdateOperations(originalConnectionRead, webBackendConnectionPatch);
562570

@@ -619,7 +627,7 @@ private void resetStreamsIfNeeded(final WebBackendConnectionUpdate webBackendCon
619627
final ConnectionStateType stateType = getStateType(connectionIdRequestBody);
620628

621629
if (stateType == ConnectionStateType.LEGACY || stateType == ConnectionStateType.NOT_SET) {
622-
streamsToReset = configRepository.getAllStreamsForConnection(connectionId);
630+
streamsToReset = configRepositoryDoNotUse.getAllStreamsForConnection(connectionId);
623631
}
624632
eventRunner.resetConnection(
625633
connectionId,
@@ -728,7 +736,7 @@ protected static ConnectionCreate toConnectionCreate(final WebBackendConnectionC
728736
@VisibleForTesting
729737
protected static ConnectionUpdate toConnectionPatch(final WebBackendConnectionUpdate webBackendConnectionPatch,
730738
final List<UUID> finalOperationIds,
731-
boolean breakingChange) {
739+
final boolean breakingChange) {
732740
final ConnectionUpdate connectionPatch = new ConnectionUpdate();
733741

734742
connectionPatch.connectionId(webBackendConnectionPatch.getConnectionId());

airbyte-commons-server/src/main/java/io/airbyte/commons/server/handlers/WebBackendGeographiesHandler.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
import java.util.Arrays;
1111
import java.util.Collections;
1212

13+
/**
14+
* The web backend is an abstraction that allows the frontend to structure data in such a way that
15+
* it is easier for a react frontend to consume. It should NOT have direct access to the database.
16+
* It should operate exclusively by calling other endpoints that are exposed in the API.
17+
**/
1318
@Singleton
1419
public class WebBackendGeographiesHandler {
1520

0 commit comments

Comments
 (0)