use of io.syndesis.common.model.WithResourceId in project syndesis by syndesisio.
the class PublicApiHandler method updateConnection.
private void updateConnection(Connection c, Map<String, String> values, Boolean refreshIntegrations, Date lastImportedAt, List<WithResourceId> results) {
final String connectionId = c.getId().get();
// encrypt properties
final Connector connector = dataMgr.fetch(Connector.class, c.getConnectorId());
final Map<String, String> encryptedValues = encryptionComponent.encryptPropertyValues(values, connector.getProperties());
// update connection properties
final HashMap<String, String> map = new HashMap<>(c.getConfiguredProperties());
map.putAll(encryptedValues);
// TODO how can credential flow be handled without a user session??
// is there any way to determine which connections require manual
// intervention??
final Connection updatedConnection = c.builder().configuredProperties(map).lastUpdated(lastImportedAt).build();
dataMgr.update(updatedConnection);
// refresh integrations that reference this connection?
if (Boolean.TRUE.equals(refreshIntegrations)) {
// we have to use the super heavy weight getOverview method below,
// which returns a bunch of other data we ignore,
// but it's also deeply involved with refreshing the integration,
// which is what the UI does
final Map<String, Integration> updated = dataMgr.fetchAll(Integration.class, l -> {
final List<Integration> integrations = l.getItems().stream().filter(i -> i.getConnectionIds().contains(connectionId)).collect(Collectors.toList());
return new ListResult.Builder<Integration>().addAllItems(integrations).build();
}, l -> new ListResult.Builder<Integration>().addAllItems(l.getItems().stream().map(i -> integrationHandler.getOverview(i.getId().get())).map(i -> new Integration.Builder().createFrom(i).build()).collect(Collectors.toList())).build()).getItems().stream().peek(i -> integrationHandler.update(i.getId().get(), i)).collect(Collectors.toMap(i -> i.getId().get(), Function.identity()));
int updatedCount = updated.size();
// if necessary, update results
if (results != null) {
for (int i = 0; i < results.size(); i++) {
final WithResourceId resource = results.get(i);
if (resource instanceof Integration) {
final Integration newInt = updated.remove(resource.getId().get());
if (newInt != null) {
results.set(i, newInt);
}
}
}
}
LOG.debug("Refreshed {} integrations for connection {}", updatedCount, connectionId);
}
}
use of io.syndesis.common.model.WithResourceId in project syndesis by syndesisio.
the class PublicApiHandler method configureConnection.
/**
* Configure a connection.
*/
@POST
@Path("connections/{id}/properties")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public ConnectionOverview configureConnection(@Context SecurityContext sec, @NotNull @PathParam("id") @Parameter(required = true) String connectionId, @NotNull @QueryParam("refreshIntegrations") @Parameter Boolean refeshIntegrations, @NotNull @Parameter(required = true) Map<String, String> properties) {
validateParam("connectionId", connectionId);
final Connection connection = getResource(Connection.class, connectionId, WithResourceId::hasId);
@SuppressWarnings("JdkObsolete") Date now = new Date();
updateConnection(connection, properties, refeshIntegrations, now, null);
return connectionHandler.get(connection.getId().get());
}
use of io.syndesis.common.model.WithResourceId in project syndesis by syndesisio.
the class PublicApiHandler method importResources.
/**
* Import integrations into a target environment.
*/
@POST
@Path("integrations")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
public ContinuousDeliveryImportResults importResources(@Context SecurityContext sec, @NotNull @MultipartForm @Parameter(required = true) ImportFormDataInput formInput) {
if (formInput == null) {
throw new ClientErrorException("Multipart request is empty", Response.Status.BAD_REQUEST);
}
final String environment = formInput.getEnvironment();
EnvironmentHandler.validateEnvironment("environment", environment);
final boolean deploy = Boolean.TRUE.equals(formInput.getDeploy());
final Environment env = environmentHandler.getEnvironment(environment);
try (InputStream importFile = formInput.getData();
InputStream properties = formInput.getProperties()) {
// above
if (importFile == null) {
throw new ClientErrorException("Missing file 'data' in multipart request", Response.Status.BAD_REQUEST);
}
// importedAt date to be updated in all imported integrations
@SuppressWarnings("JdkObsolete") final Date lastImportedAt = new Date();
final Map<String, List<WithResourceId>> resources = handler.importIntegration(sec, importFile);
final List<WithResourceId> results = new ArrayList<>();
resources.values().forEach(results::addAll);
// get imported integrations
final List<Integration> integrations = getResourcesOfType(results, Integration.class);
// update importedAt field for imported integrations
environmentHandler.updateCDEnvironments(integrations, env.getId().get(), lastImportedAt, b -> b.lastImportedAt(lastImportedAt));
// optional connection properties configuration file
if (properties != null) {
// update connection fields using properties
Map<String, Map<String, String>> params = getParams(properties);
final List<Connection> connections = getResourcesOfType(results, Connection.class);
connections.forEach(c -> {
final Map<String, String> values = params.get(c.getName());
if (values != null) {
updateConnection(c, values, formInput.getRefreshIntegrations(), lastImportedAt, results);
}
});
}
if (deploy) {
// deploy integrations
integrations.forEach(i -> publishIntegration(sec, i));
}
return new ContinuousDeliveryImportResults.Builder().lastImportedAt(lastImportedAt).results(results).build();
} catch (IOException e) {
throw new ClientErrorException(String.format("Error processing multipart request: %s", e.getMessage()), Response.Status.BAD_REQUEST, e);
}
}
use of io.syndesis.common.model.WithResourceId in project syndesis by syndesisio.
the class PublicApiHandlerTest method importResources.
@Test
public void importResources() {
final DataManager dataManager = mock(DataManager.class);
final SecurityContext securityContext = newMockSecurityContext();
final InputStream givenDataStream = new ByteArrayInputStream(new byte[0]);
// too convoluted to use the implementation directly
final IntegrationSupportHandler supportHandler = mock(IntegrationSupportHandler.class);
final Connection testConnection = new Connection.Builder().id("connection-id").connectorId("connector-id").name("test-connection").build();
final Integration integration = new Integration.Builder().id("integration-id").addConnection(testConnection).build();
Map<String, List<WithResourceId>> resultMap = new HashMap<>();
resultMap.put("integration-id", Collections.singletonList(integration));
resultMap.put("connection-id", Collections.singletonList(testConnection));
when(supportHandler.importIntegration(securityContext, givenDataStream)).thenReturn(resultMap);
final Environment env = newEnvironment("env");
when(dataManager.fetchByPropertyValue(Environment.class, "name", "env")).thenReturn(Optional.of(env));
when(dataManager.fetch(Connector.class, "connector-id")).thenReturn(new Connector.Builder().putProperty("prop", new ConfigurationProperty.Builder().build()).build());
when(dataManager.fetchAll(eq(Integration.class), any())).then((Answer<ListResult<Integration>>) invocation -> {
final Object[] arguments = invocation.getArguments();
ListResult<Integration> result = new ListResult.Builder<Integration>().addItem(integration).build();
for (int i = 1; i < arguments.length; i++) {
@SuppressWarnings("unchecked") Function<ListResult<Integration>, ListResult<Integration>> operator = (Function<ListResult<Integration>, ListResult<Integration>>) arguments[i];
result = operator.apply(result);
}
return result;
});
final EnvironmentHandler environmentHandler = new EnvironmentHandler(dataManager);
final IntegrationDeploymentHandler deploymentHandler = mock(IntegrationDeploymentHandler.class);
final EncryptionComponent encryptionComponent = mock(EncryptionComponent.class);
when(encryptionComponent.encryptPropertyValues(any(), any())).thenReturn(Collections.singletonMap("prop", "value"));
IntegrationHandler integrationHandler = mock(IntegrationHandler.class);
when(integrationHandler.getOverview(any())).thenReturn(new IntegrationOverview.Builder().createFrom(integration).connections(Collections.singletonList(testConnection.builder().putConfiguredProperty("prop", "value").build())).build());
// null's are not used
final PublicApiHandler handler = new PublicApiHandler(dataManager, encryptionComponent, deploymentHandler, null, null, environmentHandler, supportHandler, integrationHandler);
final PublicApiHandler.ImportFormDataInput formInput = new PublicApiHandler.ImportFormDataInput();
formInput.setData(givenDataStream);
formInput.setProperties(new ByteArrayInputStream("test-connection.prop=value".getBytes(StandardCharsets.UTF_8)));
formInput.setRefreshIntegrations(Boolean.TRUE);
formInput.setEnvironment("env");
formInput.setDeploy(Boolean.TRUE);
final ContinuousDeliveryImportResults importResults = handler.importResources(securityContext, formInput);
verify(deploymentHandler).update(securityContext, "integration-id");
assertThat(importResults.getLastImportedAt()).isNotNull();
assertThat(importResults.getResults().size()).isEqualTo(2);
// verify the integration connection was refreshed
final Integration importedIntegration = (Integration) importResults.getResults().get(0);
assertThat(importedIntegration.getConnections().get(0).getConfiguredProperties().get("prop")).isEqualTo("value");
}
use of io.syndesis.common.model.WithResourceId in project syndesis by syndesisio.
the class IntegrationSupportHandler method importModels.
public Map<String, List<WithResourceId>> importModels(SecurityContext sec, ModelExport export, JsonDB given) throws IOException {
// Apply per version migrations to get the schema upgraded on the import.
int from = export.schemaVersion();
int to = Schema.VERSION;
if (from > to) {
throw new IOException("Cannot import an export at schema version level: " + export.schemaVersion());
}
for (int i = from; i < to; i++) {
int version = i + 1;
migrator.migrate(given, version);
}
Map<String, List<WithResourceId>> result = new HashMap<>();
// id->new-name map
Map<String, String> renamedIds = new HashMap<>();
// Import the extensions..
final JsonDbDao<Extension> extensionDao = new JsonDbDao<Extension>(given) {
@Override
public Class<Extension> getType() {
return Extension.class;
}
};
final Map<String, String> replacedIds = new HashMap<>();
importExtensions(extensionDao, replacedIds, renamedIds, result);
// NOTE: connectors are imported without renaming and ignoring renamed ids
// as a matter of fact, the lambda should never be called
importModels(new JsonDbDao<Connector>(given) {
@Override
public Class<Connector> getType() {
return Connector.class;
}
}, (c, n) -> new Connector.Builder().createFrom(c).name(c.getName()).build(), new HashMap<>(), result);
importModels(new JsonDbDao<Connection>(given) {
@Override
public Class<Connection> getType() {
return Connection.class;
}
}, IntegrationSupportHandler::renameConnection, renamedIds, result);
// remove hidden external secrets from imported connections
final List<WithResourceId> connections = result.get("connections");
if (connections != null && !connections.isEmpty()) {
for (WithResourceId connection : connections) {
removeHiddenExternalSecrets((Connection) connection);
}
}
// import missing environments
importEnvironments(new JsonDbDao<Environment>(given) {
@Override
public Class<Environment> getType() {
return Environment.class;
}
}, replacedIds, renamedIds, result);
importIntegrations(sec, new JsonDbDao<Integration>(given) {
@Override
public Class<Integration> getType() {
return Integration.class;
}
}, renamedIds, replacedIds, result);
importModels(new JsonDbDao<OpenApi>(given) {
@Override
public Class<OpenApi> getType() {
return OpenApi.class;
}
}, (a, n) -> new OpenApi.Builder().createFrom(a).name(n).build(), new HashMap<>(), result);
importModels(new JsonDbDao<Icon>(given) {
@Override
public Class<Icon> getType() {
return Icon.class;
}
}, result);
return result;
}
Aggregations