Skip to content

Commit e0ab902

Browse files
committed
add destinationImplementationsHandler
1 parent 7dd72f2 commit e0ab902

File tree

7 files changed

+452
-28
lines changed

7 files changed

+452
-28
lines changed

dataline-api/src/main/openapi/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ components:
872872
required:
873873
- destinations
874874
properties:
875-
sources:
875+
destinations:
876876
type: array
877877
items:
878878
$ref: "#/components/schemas/DestinationImplementationRead"

dataline-config/src/main/resources/json/DestinationConnectionImplementation.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,22 @@
44
"title": "DestinationConnectionImplementation",
55
"description": "information required for connection to a destination.",
66
"type": "object",
7-
"required": ["destinationSpecificationId", "destinationImplementationId", "configuration"],
7+
"required": [
8+
"destinationSpecificationId",
9+
"workspaceId",
10+
"destinationImplementationId",
11+
"configuration"
12+
],
813
"additionalProperties": false,
914
"properties": {
1015
"destinationSpecificationId": {
1116
"type": "string",
1217
"format": "uuid"
1318
},
19+
"workspaceId": {
20+
"type": "string",
21+
"format": "uuid"
22+
},
1423
"destinationImplementationId": {
1524
"type": "string",
1625
"format": "uuid"

dataline-server/src/main/java/io/dataline/server/apis/ConfigurationApi.java

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class ConfigurationApi implements io.dataline.api.V1Api {
1515
private final SourceImplementationsHandler sourceImplementationsHandler;
1616
private final DestinationsHandler destinationsHandler;
1717
private final DestinationSpecificationsHandler destinationSpecificationsHandler;
18+
private final DestinationImplementationsHandler destinationImplementationsHandler;
1819

1920
public ConfigurationApi() {
2021
ConfigPersistence configPersistence = ConfigPersistenceImpl.get();
@@ -24,6 +25,7 @@ public ConfigurationApi() {
2425
sourceImplementationsHandler = new SourceImplementationsHandler(configPersistence);
2526
destinationsHandler = new DestinationsHandler(configPersistence);
2627
destinationSpecificationsHandler = new DestinationSpecificationsHandler(configPersistence);
28+
destinationImplementationsHandler = new DestinationImplementationsHandler(configPersistence);
2729
}
2830

2931
// WORKSPACE
@@ -64,16 +66,17 @@ public SourceSpecificationRead getSourceSpecification(
6466
}
6567

6668
// SOURCE IMPLEMENTATION
69+
6770
@Override
6871
public SourceImplementationRead createSourceImplementation(
6972
@Valid SourceImplementationCreate sourceImplementationCreate) {
7073
return sourceImplementationsHandler.createSourceImplementation(sourceImplementationCreate);
7174
}
7275

7376
@Override
74-
public SourceImplementationRead getSourceImplementation(
75-
@Valid SourceImplementationIdRequestBody sourceImplementationIdRequestBody) {
76-
return sourceImplementationsHandler.getSourceImplementation(sourceImplementationIdRequestBody);
77+
public SourceImplementationRead updateSourceImplementation(
78+
@Valid SourceImplementationUpdate sourceImplementationUpdate) {
79+
return sourceImplementationsHandler.updateSourceImplementation(sourceImplementationUpdate);
7780
}
7881

7982
@Override
@@ -84,15 +87,15 @@ public SourceImplementationReadList listSourceImplementationsForWorkspace(
8487
}
8588

8689
@Override
87-
public SourceImplementationTestConnectionRead testConnectionToSourceImplementation(
90+
public SourceImplementationRead getSourceImplementation(
8891
@Valid SourceImplementationIdRequestBody sourceImplementationIdRequestBody) {
89-
return null;
92+
return sourceImplementationsHandler.getSourceImplementation(sourceImplementationIdRequestBody);
9093
}
9194

9295
@Override
93-
public SourceImplementationRead updateSourceImplementation(
94-
@Valid SourceImplementationUpdate sourceImplementationUpdate) {
95-
return sourceImplementationsHandler.updateSourceImplementation(sourceImplementationUpdate);
96+
public SourceImplementationTestConnectionRead testConnectionToSourceImplementation(
97+
@Valid SourceImplementationIdRequestBody sourceImplementationIdRequestBody) {
98+
return null;
9699
}
97100

98101
@Override
@@ -122,54 +125,59 @@ public DestinationSpecificationRead getDestinationSpecification(
122125
}
123126

124127
// DESTINATION IMPLEMENTATION
125-
126128
@Override
127-
public DestinationImplementationRead getDestinationImplementation(
128-
@Valid DestinationImplementationIdRequestBody destinationImplementationIdRequestBody) {
129-
return null;
129+
public DestinationImplementationRead createDestinationImplementation(
130+
@Valid DestinationImplementationCreate destinationImplementationCreate) {
131+
return destinationImplementationsHandler.createDestinationImplementation(
132+
destinationImplementationCreate);
130133
}
131134

132135
@Override
133-
public ConnectionRead getConnection(@Valid ConnectionIdRequestBody connectionIdRequestBody) {
134-
return null;
136+
public DestinationImplementationRead updateDestinationImplementation(
137+
@Valid DestinationImplementationUpdate destinationImplementationUpdate) {
138+
return destinationImplementationsHandler.updateDestinationImplementation(
139+
destinationImplementationUpdate);
135140
}
136141

137142
@Override
138-
public ConnectionRead createConnection(@Valid ConnectionCreate connectionCreate) {
139-
return null;
143+
public DestinationImplementationReadList listDestinationImplementationsForWorkspace(
144+
@Valid WorkspaceIdRequestBody workspaceIdRequestBody) {
145+
return destinationImplementationsHandler.listDestinationImplementationsForWorkspace(
146+
workspaceIdRequestBody);
140147
}
141148

142149
@Override
143-
public DestinationImplementationRead createDestinationImplementation(
144-
@Valid DestinationImplementationCreate destinationImplementationCreate) {
145-
return null;
150+
public DestinationImplementationRead getDestinationImplementation(
151+
@Valid DestinationImplementationIdRequestBody destinationImplementationIdRequestBody) {
152+
return destinationImplementationsHandler.getDestinationImplementation(
153+
destinationImplementationIdRequestBody);
146154
}
147155

156+
// CONNECTION
157+
148158
@Override
149159
public ConnectionReadList listConnectionsForWorkspace(
150160
@Valid WorkspaceIdRequestBody workspaceIdRequestBody) {
151161
return null;
152162
}
153163

154164
@Override
155-
public DestinationImplementationReadList listDestinationImplementationsForWorkspace(
156-
@Valid WorkspaceIdRequestBody workspaceIdRequestBody) {
165+
public ConnectionRead getConnection(@Valid ConnectionIdRequestBody connectionIdRequestBody) {
157166
return null;
158167
}
159168

160169
@Override
161-
public ConnectionSyncRead syncConnection(@Valid ConnectionIdRequestBody connectionIdRequestBody) {
170+
public ConnectionRead createConnection(@Valid ConnectionCreate connectionCreate) {
162171
return null;
163172
}
164173

165174
@Override
166-
public ConnectionRead updateConnection(@Valid ConnectionUpdate connectionUpdate) {
175+
public ConnectionSyncRead syncConnection(@Valid ConnectionIdRequestBody connectionIdRequestBody) {
167176
return null;
168177
}
169178

170179
@Override
171-
public DestinationImplementationRead updateDestinationImplementation(
172-
@Valid DestinationImplementationUpdate destinationImplementationUpdate) {
180+
public ConnectionRead updateConnection(@Valid ConnectionUpdate connectionUpdate) {
173181
return null;
174182
}
175183
}
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
package io.dataline.server.handlers;
2+
3+
import io.dataline.api.model.*;
4+
import io.dataline.config.DestinationConnectionImplementation;
5+
import io.dataline.config.persistence.ConfigNotFoundException;
6+
import io.dataline.config.persistence.ConfigPersistence;
7+
import io.dataline.config.persistence.JsonValidationException;
8+
import io.dataline.config.persistence.PersistenceConfigType;
9+
import io.dataline.server.errors.KnownException;
10+
import io.dataline.server.validation.IntegrationSchemaValidation;
11+
import java.util.List;
12+
import java.util.UUID;
13+
import java.util.stream.Collectors;
14+
15+
public class DestinationImplementationsHandler {
16+
private final ConfigPersistence configPersistence;
17+
private final IntegrationSchemaValidation validator;
18+
19+
public DestinationImplementationsHandler(ConfigPersistence configPersistence) {
20+
this.configPersistence = configPersistence;
21+
this.validator = new IntegrationSchemaValidation(configPersistence);
22+
}
23+
24+
public DestinationImplementationRead createDestinationImplementation(
25+
DestinationImplementationCreate destinationImplementationCreate) {
26+
// validate configuration
27+
validateDestinationImplementation(
28+
destinationImplementationCreate.getDestinationSpecificationId(),
29+
destinationImplementationCreate.getConnectionConfiguration());
30+
31+
// persist
32+
final UUID destinationImplementationId = UUID.randomUUID();
33+
persistDestinationConnectionImplementation(
34+
destinationImplementationCreate.getDestinationSpecificationId(),
35+
destinationImplementationCreate.getWorkspaceId(),
36+
destinationImplementationId,
37+
destinationImplementationCreate.getConnectionConfiguration());
38+
39+
// read configuration from db
40+
return getDestinationImplementationInternal(destinationImplementationId);
41+
}
42+
43+
public DestinationImplementationRead updateDestinationImplementation(
44+
DestinationImplementationUpdate destinationImplementationUpdate) {
45+
// get existing implementation
46+
final DestinationImplementationRead persistedDestinationImplementation =
47+
getDestinationImplementationInternal(
48+
destinationImplementationUpdate.getDestinationImplementationId());
49+
50+
// validate configuration
51+
validateDestinationImplementation(
52+
persistedDestinationImplementation.getDestinationSpecificationId(),
53+
destinationImplementationUpdate.getConnectionConfiguration());
54+
55+
// persist
56+
persistDestinationConnectionImplementation(
57+
persistedDestinationImplementation.getDestinationSpecificationId(),
58+
persistedDestinationImplementation.getWorkspaceId(),
59+
destinationImplementationUpdate.getDestinationImplementationId(),
60+
destinationImplementationUpdate.getConnectionConfiguration());
61+
62+
// read configuration from db
63+
return getDestinationImplementationInternal(
64+
destinationImplementationUpdate.getDestinationImplementationId());
65+
}
66+
67+
public DestinationImplementationRead getDestinationImplementation(
68+
DestinationImplementationIdRequestBody destinationImplementationIdRequestBody) {
69+
70+
return getDestinationImplementationInternal(
71+
destinationImplementationIdRequestBody.getDestinationImplementationId());
72+
}
73+
74+
public DestinationImplementationReadList listDestinationImplementationsForWorkspace(
75+
WorkspaceIdRequestBody workspaceIdRequestBody) {
76+
try {
77+
78+
final List<DestinationImplementationRead> reads =
79+
configPersistence
80+
.getConfigs(
81+
PersistenceConfigType.DESTINATION_CONNECTION_IMPLEMENTATION,
82+
DestinationConnectionImplementation.class)
83+
.stream()
84+
.filter(
85+
destinationConnectionImplementation ->
86+
destinationConnectionImplementation
87+
.getWorkspaceId()
88+
.equals(workspaceIdRequestBody.getWorkspaceId()))
89+
.map(this::toDestinationImplementationRead)
90+
.collect(Collectors.toList());
91+
92+
final DestinationImplementationReadList destinationImplementationReadList =
93+
new DestinationImplementationReadList();
94+
destinationImplementationReadList.setDestinations(reads);
95+
return destinationImplementationReadList;
96+
} catch (JsonValidationException e) {
97+
throw new KnownException(
98+
422,
99+
String.format(
100+
"Attempted to retrieve a configuration does not fulfill the specification. Errors: %s",
101+
e.getMessage()));
102+
}
103+
}
104+
105+
private DestinationImplementationRead getDestinationImplementationInternal(
106+
UUID destinationImplementationId) {
107+
// read configuration from db
108+
final DestinationConnectionImplementation retrievedDestinationConnectionImplementation;
109+
try {
110+
retrievedDestinationConnectionImplementation =
111+
configPersistence.getConfig(
112+
PersistenceConfigType.DESTINATION_CONNECTION_IMPLEMENTATION,
113+
destinationImplementationId.toString(),
114+
DestinationConnectionImplementation.class);
115+
} catch (JsonValidationException e) {
116+
throw new KnownException(
117+
422,
118+
String.format(
119+
"The provided configuration does not fulfill the specification. Errors: %s",
120+
e.getMessage()));
121+
} catch (ConfigNotFoundException e) {
122+
throw new KnownException(
123+
422,
124+
String.format(
125+
"Could not find destination specification: %s.", destinationImplementationId));
126+
}
127+
128+
return toDestinationImplementationRead(retrievedDestinationConnectionImplementation);
129+
}
130+
131+
private void validateDestinationImplementation(
132+
UUID destinationConnectionSpecificationId, Object implementation) {
133+
try {
134+
validator.validateDestinationConnectionConfiguration(
135+
destinationConnectionSpecificationId, implementation);
136+
} catch (JsonValidationException e) {
137+
throw new KnownException(
138+
422,
139+
String.format(
140+
"The provided configuration does not fulfill the specification. Errors: %s",
141+
e.getMessage()));
142+
} catch (ConfigNotFoundException e) {
143+
throw new KnownException(
144+
422,
145+
String.format(
146+
"Could not find destination specification: %s.",
147+
destinationConnectionSpecificationId));
148+
}
149+
}
150+
151+
private void persistDestinationConnectionImplementation(
152+
UUID destinationSpecificationId,
153+
UUID workspaceId,
154+
UUID destinationImplementationId,
155+
Object configuration) {
156+
final DestinationConnectionImplementation destinationConnectionImplementation =
157+
new DestinationConnectionImplementation();
158+
destinationConnectionImplementation.setDestinationSpecificationId(destinationSpecificationId);
159+
destinationConnectionImplementation.setWorkspaceId(workspaceId);
160+
destinationConnectionImplementation.setDestinationImplementationId(destinationImplementationId);
161+
destinationConnectionImplementation.setConfiguration(configuration);
162+
163+
configPersistence.writeConfig(
164+
PersistenceConfigType.DESTINATION_CONNECTION_IMPLEMENTATION,
165+
destinationImplementationId.toString(),
166+
destinationConnectionImplementation);
167+
}
168+
169+
private DestinationImplementationRead toDestinationImplementationRead(
170+
DestinationConnectionImplementation destinationConnectionImplementation) {
171+
final DestinationImplementationRead destinationImplementationRead =
172+
new DestinationImplementationRead();
173+
destinationImplementationRead.setDestinationImplementationId(
174+
destinationConnectionImplementation.getDestinationImplementationId());
175+
destinationImplementationRead.setWorkspaceId(
176+
destinationConnectionImplementation.getWorkspaceId());
177+
destinationImplementationRead.setDestinationSpecificationId(
178+
destinationConnectionImplementation.getDestinationSpecificationId());
179+
destinationImplementationRead.setConnectionConfiguration(
180+
destinationConnectionImplementation.getConfiguration());
181+
182+
return destinationImplementationRead;
183+
}
184+
}

dataline-server/src/main/java/io/dataline/server/validation/IntegrationSchemaValidation.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.fasterxml.jackson.databind.JsonNode;
44
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import io.dataline.config.DestinationConnectionSpecification;
56
import io.dataline.config.SourceConnectionSpecification;
67
import io.dataline.config.persistence.*;
78
import java.util.UUID;
@@ -34,4 +35,20 @@ public void validateSourceConnectionConfiguration(
3435

3536
jsonSchemaValidation.validateThrow(schemaJson, configJson);
3637
}
38+
39+
public void validateDestinationConnectionConfiguration(
40+
UUID destinationConnectionSpecificationId, Object configuration)
41+
throws JsonValidationException, ConfigNotFoundException {
42+
final DestinationConnectionSpecification destinationConnectionSpecification =
43+
configPersistence.getConfig(
44+
PersistenceConfigType.DESTINATION_CONNECTION_SPECIFICATION,
45+
destinationConnectionSpecificationId.toString(),
46+
DestinationConnectionSpecification.class);
47+
48+
final JsonNode schemaJson =
49+
objectMapper.valueToTree(destinationConnectionSpecification.getSpecification());
50+
final JsonNode configJson = objectMapper.valueToTree(configuration);
51+
52+
jsonSchemaValidation.validateThrow(schemaJson, configJson);
53+
}
3754
}

0 commit comments

Comments
 (0)