use of com.thinkbiganalytics.kylo.catalog.rest.model.DataSource in project kylo by Teradata.
the class DataSourceProvider method createOrUpdateNiFiControllerService.
/**
* Creates or updates the NiFi controller service linked to the specified data source.
*/
private void createOrUpdateNiFiControllerService(@Nonnull final DataSource dataSource, @Nonnull final ConnectorPluginDescriptor connectorPluginDescriptor, boolean checkExisting) throws PotentialControllerServiceConflictException {
ConnectorPluginNiFiControllerService plugin = connectorPluginDescriptor.getNifiControllerService();
// Resolve properties
final PropertyPlaceholderHelper.PlaceholderResolver resolver = new DataSourcePlaceholderResolver(dataSource);
final Map<String, String> properties = new HashMap<>(plugin.getProperties().size());
final Map<String, ConnectorPluginNiFiControllerServicePropertyDescriptor> propertyDescriptors = plugin.getPropertyDescriptors();
plugin.getProperties().forEach((key, value) -> {
final String resolvedValue = placeholderHelper.replacePlaceholders(value, resolver);
// set empty string to null
ConnectorPluginNiFiControllerServicePropertyDescriptor descriptor = propertyDescriptors != null ? propertyDescriptors.get(key) : null;
if (StringUtils.isBlank(resolvedValue) && (descriptor == null || (descriptor != null && !descriptor.isEmptyStringIfNull()))) {
// set the value to null if its not explicitly configured to be set to an empty string
properties.put(key, null);
} else if (resolvedValue != null && !resolvedValue.startsWith("{cipher}")) {
properties.put(key, resolvedValue);
}
});
// Update or create the controller service
ControllerServiceDTO controllerService = null;
if (dataSource.getNifiControllerServiceId() != null && dataSource.getId() != null) {
controllerService = new ControllerServiceDTO();
controllerService.setId(dataSource.getNifiControllerServiceId());
controllerService.setName(dataSource.getTitle());
controllerService.setProperties(properties);
try {
controllerService = nifiRestClient.controllerServices().updateServiceAndReferencingComponents(controllerService);
dataSource.setNifiControllerServiceId(controllerService.getId());
} catch (final NifiComponentNotFoundException e) {
log.warn("Controller service is missing for data source: {}", dataSource.getId(), e);
controllerService = null;
}
}
if (controllerService == null && StringUtils.isBlank(dataSource.getNifiControllerServiceId())) {
if (checkExisting) {
List<ControllerServiceDTO> matchingServices = findMatchingControllerService(dataSource, properties, connectorPluginDescriptor);
if (matchingServices != null && !matchingServices.isEmpty()) {
Map<String, String> identityProperties = plugin.getIdentityProperties().stream().collect(Collectors.toMap(propertyKey -> propertyKey, propertyKey -> properties.get(propertyKey)));
throw new PotentialControllerServiceConflictException(new ControllerServiceConflictEntity(dataSource.getTitle(), identityProperties, matchingServices));
}
}
controllerService = new ControllerServiceDTO();
controllerService.setType(plugin.getType());
controllerService.setName(dataSource.getTitle());
controllerService.setProperties(properties);
controllerService = nifiRestClient.controllerServices().create(controllerService);
try {
nifiRestClient.controllerServices().updateStateById(controllerService.getId(), NiFiControllerServicesRestClient.State.ENABLED);
} catch (final NifiClientRuntimeException e) {
log.error("Failed to enable controller service for data source: {}", dataSource.getId(), e);
nifiRestClient.controllerServices().disableAndDeleteAsync(controllerService.getId());
throw e;
}
dataSource.setNifiControllerServiceId(controllerService.getId());
}
}
use of com.thinkbiganalytics.kylo.catalog.rest.model.DataSource in project kylo by Teradata.
the class DataSourceProvider method findDataSource.
/**
* Gets the connector with the specified id.
*/
@Nonnull
@SuppressWarnings("squid:S2259")
public Optional<DataSource> findDataSource(@Nonnull final String id, final boolean includeCredentials) {
return metadataService.read(() -> {
// Find the data source
DataSource dataSource = metadataProvider.find(metadataProvider.resolveId(id)).map(modelTransform.dataSourceToRestModel()).orElse(null);
if (dataSource != null) {
dataSource = new DataSource(dataSource);
} else {
try {
final Datasource feedDataSource = feedDataSourceProvider.getDatasource(feedDataSourceProvider.resolve(id));
DatasourceModelTransform.Level level = DatasourceModelTransform.Level.FULL;
if (includeCredentials) {
level = DatasourceModelTransform.Level.ADMIN;
}
dataSource = toDataSource(feedDataSource, level);
} catch (final IllegalArgumentException e) {
log.debug("Failed to resolve data source {}: {}", id, e, e);
}
}
// Set connector
final Optional<Connector> connector = Optional.ofNullable(dataSource).map(DataSource::getConnector).map(Connector::getId).map(connectorProvider::resolveId).flatMap(connectorProvider::find).map(modelTransform.connectorToRestModel());
if (connector.isPresent()) {
dataSource.setConnector(connector.get());
return Optional.of(dataSource);
} else {
if (dataSource != null) {
log.error("Unable to find connector for data source: {}", dataSource);
}
return Optional.empty();
}
});
}
use of com.thinkbiganalytics.kylo.catalog.rest.model.DataSource in project kylo by Teradata.
the class DataSourceProvider method createDataSource.
/**
* Creates a new data source using the specified template.
*
* @throws CatalogException if the data source is not valid
*/
@Nonnull
public DataSource createDataSource(@Nonnull final DataSource source, boolean checkExisting) throws PotentialControllerServiceConflictException {
return metadataService.commit(() -> {
// Find connector
final com.thinkbiganalytics.metadata.api.catalog.Connector connector = Optional.ofNullable(source.getConnector()).map(Connector::getId).map(connectorProvider::resolveId).flatMap(connectorProvider::find).orElseThrow(() -> new CatalogException("catalog.datasource.connector.invalid"));
// Create data source
final com.thinkbiganalytics.metadata.api.catalog.DataSource domain = metadataProvider.create(connector.getId(), source.getTitle());
// Create or update controller service
final ConnectorPluginDescriptor plugin = pluginManager.getPlugin(connector.getPluginId()).map(ConnectorPlugin::getDescriptor).orElse(null);
if (plugin != null && plugin.getNifiControllerService() != null) {
createOrUpdateNiFiControllerService(source, plugin, checkExisting);
}
// Update catalog
final DataSource updatedDataSource = this.credentialManager.applyPlaceholders(source, SecurityContextUtil.getCurrentPrincipals());
modelTransform.updateDataSource(updatedDataSource, domain);
// Return a copy with the connector
return modelTransform.dataSourceToRestModel().apply(domain);
});
}
use of com.thinkbiganalytics.kylo.catalog.rest.model.DataSource in project kylo by Teradata.
the class DataSourceProvider method findMatchingControllerService.
private List<ControllerServiceDTO> findMatchingControllerService(@Nonnull final DataSource dataSource, @Nonnull final Map<String, String> properties, @Nonnull final ConnectorPluginDescriptor connectorPluginDescriptor) {
ConnectorPluginNiFiControllerService plugin = connectorPluginDescriptor.getNifiControllerService();
String type = plugin.getType();
Map<String, String> identityProperties = plugin.getIdentityProperties().stream().collect(Collectors.toMap(propertyKey -> propertyKey, propertyKey -> properties.get(propertyKey)));
// TODO hit cache first
String rootProcessGroupId = nifiRestClient.processGroups().findRoot().getId();
return nifiRestClient.processGroups().getControllerServices(rootProcessGroupId).stream().filter(controllerServiceDTO -> isMatch(controllerServiceDTO, type, dataSource.getTitle(), identityProperties)).collect(Collectors.toList());
}
use of com.thinkbiganalytics.kylo.catalog.rest.model.DataSource in project kylo by Teradata.
the class DataSourceController method updateDataSource.
@PUT
@ApiOperation("Updates an existing data source")
@ApiResponses({ @ApiResponse(code = 200, message = "Data source updated", response = DataSource.class), @ApiResponse(code = 400, message = "Invalid connector", response = RestResponseStatus.class), @ApiResponse(code = 500, message = "Internal server error", response = RestResponseStatus.class) })
@Path("{id}")
@Consumes(MediaType.APPLICATION_JSON)
public Response updateDataSource(@Nonnull final DataSource source) {
log.entry(source);
final DataSource dataSource;
try {
dataSource = dataSourceService.updateDataSource(source);
} catch (final CatalogException e) {
if (log.isDebugEnabled()) {
log.debug("Cannot create data source from request: " + source, e);
}
throw new BadRequestException(getMessage(e));
}
return Response.ok(log.exit(dataSource)).build();
}
Aggregations