use of com.thinkbiganalytics.nifi.rest.model.NifiProperty in project kylo by Teradata.
the class FeedImporter method importFeed.
// Import
/**
* Import a feed zip file
*/
private ImportFeed importFeed() throws Exception {
// read the JSON into the Feed object
FeedMetadata metadata = importFeed.getFeedToImport();
// query for this feed.
String feedCategory = StringUtils.isNotBlank(importFeedOptions.getCategorySystemName()) ? importFeedOptions.getCategorySystemName() : metadata.getSystemCategoryName();
FeedMetadata existingFeed = metadataAccess.read(() -> metadataService.getFeedByName(feedCategory, metadata.getSystemFeedName()));
metadata.getCategory().setSystemName(feedCategory);
ImportTemplateOptions importTemplateOptions = new ImportTemplateOptions();
importTemplateOptions.setImportComponentOptions(importFeedOptions.getImportComponentOptions());
importTemplateOptions.findImportComponentOption(ImportComponent.TEMPLATE_DATA).setContinueIfExists(true);
ImportTemplate importTemplate = importFeed.getTemplate();
importTemplate.setImportOptions(importTemplateOptions);
importTemplateOptions.setUploadKey(importFeedOptions.getUploadKey());
importTemplate.setValid(true);
importTemplateOptions.setDeferCleanup(true);
// Import the Template
ImportTemplateRoutine importTemplateRoutine = importTemplateRoutineFactory.apply(importTemplate, importTemplateOptions, ImportTemplate.TYPE.ARCHIVE);
importTemplateRoutine.importTemplate();
if (importTemplate.isSuccess()) {
// import the feed
importFeed.setTemplate(importTemplate);
// now that we have the Feed object we need to create the instance of the feed
UploadProgressMessage uploadProgressMessage = uploadProgressService.addUploadStatus(importFeedOptions.getUploadKey(), "Saving and creating feed instance in NiFi");
metadata.setIsNew(existingFeed == null ? true : false);
metadata.setFeedId(existingFeed != null ? existingFeed.getFeedId() : null);
metadata.setId(existingFeed != null ? existingFeed.getId() : null);
// reassign the templateId to the newly registered template id
metadata.setTemplateId(importTemplate.getTemplateId());
if (metadata.getRegisteredTemplate() != null) {
metadata.getRegisteredTemplate().setNifiTemplateId(importTemplate.getNifiTemplateId());
metadata.getRegisteredTemplate().setId(importTemplate.getTemplateId());
}
// get/create category
FeedCategory category = metadataService.getCategoryBySystemName(metadata.getCategory().getSystemName());
if (category == null) {
metadata.getCategory().setId(null);
metadataService.saveCategory(metadata.getCategory());
} else {
metadata.setCategory(category);
}
if (importFeedOptions.isDisableUponImport()) {
metadata.setActive(false);
metadata.setState(FeedMetadata.STATE.DISABLED.name());
}
// remap any preconditions to this new feed/category name.
if (metadata.getSchedule().hasPreconditions()) {
metadata.getSchedule().getPreconditions().stream().flatMap(preconditionRule -> preconditionRule.getProperties().stream()).filter(fieldRuleProperty -> PolicyPropertyTypes.PROPERTY_TYPE.currentFeed.name().equals(fieldRuleProperty.getType())).forEach(fieldRuleProperty -> fieldRuleProperty.setValue(metadata.getCategoryAndFeedName()));
}
// //for all those properties where the template value is != userEditable and the template value has a metadata. property, remove that property from the feed properties so it can be imported and assigned correctly
RegisteredTemplate template1 = registeredTemplateService.findRegisteredTemplateById(importTemplate.getTemplateId());
if (template1 != null) {
// Find all the properties in the template that have ${metadata. and are not userEditable.
// These are the properties we need to replace on the feed metadata
List<NifiProperty> metadataProperties = template1.getProperties().stream().filter(nifiProperty -> {
return nifiProperty != null && StringUtils.isNotBlank(nifiProperty.getValue()) && !nifiProperty.isUserEditable() && nifiProperty.getValue().contains("${" + MetadataFieldAnnotationFieldNameResolver.metadataPropertyPrefix);
}).collect(Collectors.toList());
// Replace the Feed Metadata properties with those that match the template ones from above.
List<NifiProperty> updatedProperties = metadata.getProperties().stream().map(nifiProperty -> {
NifiProperty p = NifiPropertyUtil.findPropertyByProcessorName(metadataProperties, nifiProperty);
return p != null ? p : nifiProperty;
}).collect(Collectors.toList());
metadata.setProperties(updatedProperties);
}
NifiFeed nifiFeed = metadataService.createFeed(metadata);
if (nifiFeed != null) {
importFeed.setFeedName(nifiFeed.getFeedMetadata().getCategoryAndFeedName());
if (nifiFeed.isSuccess()) {
uploadProgressMessage.update("Successfully saved the feed " + importFeed.getFeedName(), true);
} else {
if (nifiFeed.getFeedProcessGroup() != null && nifiFeed.getFeedProcessGroup().isRolledBack()) {
if (importTemplateRoutine != null) {
importTemplateRoutine.rollback();
}
}
uploadProgressMessage.update("Errors were found importing the feed " + importFeed.getFeedName(), false);
}
importTemplateRoutine.cleanup();
}
importFeed.setNifiFeed(nifiFeed);
importFeed.setSuccess(nifiFeed != null && nifiFeed.isSuccess());
} else {
importFeed.setSuccess(false);
importFeed.setTemplate(importTemplate);
importFeed.addErrorMessage(existingFeed, "The feed " + FeedNameUtil.fullName(feedCategory, metadata.getSystemFeedName()) + " needs additional properties to be supplied before importing.");
}
uploadProgressService.completeSection(importFeedOptions, ImportSection.Section.IMPORT_FEED_DATA);
return importFeed;
}
use of com.thinkbiganalytics.nifi.rest.model.NifiProperty in project kylo by Teradata.
the class CreateFeedBuilder method updateProcessGroupProperties.
/**
* Updates a process groups properties
*/
private void updateProcessGroupProperties(String processGroupId, String processGroupName) throws FeedCreationException {
Stopwatch stopwatch = Stopwatch.createStarted();
List<NifiProperty> propertiesToUpdate = restClient.getPropertiesForProcessGroup(processGroupId);
stopwatch.stop();
log.debug("Time to get Properties in Feed updateProcessGroupProperties: {} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS));
stopwatch.reset();
stopwatch.start();
// get the Root processGroup
ProcessGroupDTO rootProcessGroup = niFiObjectCache.getRootProcessGroup();
stopwatch.stop();
log.debug("Time to get root Process Group in updateProcessGroupProperties: {} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS));
stopwatch.reset();
stopwatch.start();
modifiedProperties = new ArrayList<>();
// resolve the static properties
// first fill in any properties with static references
List<NifiProperty> modifiedStaticProperties = propertyExpressionResolver.resolveStaticProperties(propertiesToUpdate);
// now apply any of the incoming metadata properties to this
List<NifiProperty> modifiedFeedMetadataProperties = NifiPropertyUtil.matchAndSetPropertyValues(rootProcessGroup.getName(), processGroupName, propertiesToUpdate, properties);
modifiedProperties.addAll(modifiedStaticProperties);
modifiedProperties.addAll(modifiedFeedMetadataProperties);
stopwatch.stop();
log.debug("Time to set modifiedProperties: {} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS));
stopwatch.reset();
stopwatch.start();
restClient.updateProcessGroupProperties(modifiedProperties);
stopwatch.stop();
log.debug("Time to update properties in the process group: {} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS));
}
use of com.thinkbiganalytics.nifi.rest.model.NifiProperty in project kylo by Teradata.
the class CreateFeedBuilder method build.
/**
* Build the NiFi flow instance
*
* @return an object indicating if the feed flow was successfully built or not
*/
public NifiProcessGroup build() throws FeedCreationException {
try {
log.info("Creating the feed {}.{} ", category, feedName);
newProcessGroup = null;
Stopwatch totalTime = Stopwatch.createStarted();
Stopwatch eventTime = Stopwatch.createStarted();
TemplateDTO template = getTemplate();
if (template != null) {
log.debug("Time to get Template {}. ElapsedTime: {} ms", template.getName(), eventTime(eventTime));
// create the encompassing process group
eventTime.start();
ProcessGroupDTO feedProcessGroup = createProcessGroupForFeed();
log.debug("Time to create process group. ElapsedTime: {} ms", eventTime(eventTime));
if (feedProcessGroup != null) {
String processGroupId = feedProcessGroup.getId();
// snapshot the existing controller services
eventTime.start();
templateCreationHelper.snapshotControllerServiceReferences();
log.debug("Time to snapshotControllerServices. ElapsedTime: {} ms", eventTime(eventTime));
// create the flow from the template
eventTime.start();
TemplateInstance instance = templateCreationHelper.instantiateFlowFromTemplate(processGroupId, templateId);
FlowSnippetDTO feedInstance = instance.getFlowSnippetDTO();
feedProcessGroup.setContents(feedInstance);
log.debug("Time to instantiateFlowFromTemplate. ElapsedTime: {} ms", eventTime(eventTime));
eventTime.start();
String feedCategoryId = feedProcessGroup.getParentGroupId();
ProcessGroupDTO categoryGroup = this.categoryGroup;
if (categoryGroup == null) {
categoryGroup = this.categoryGroup = restClient.getProcessGroup(feedCategoryId, false, false);
}
// update the group with this template?
updatePortConnectionsForProcessGroup(feedProcessGroup, categoryGroup);
log.debug("Time to updatePortConnectionsForProcessGroup. ElapsedTime: {} ms", eventTime(eventTime));
eventTime.start();
// mark the new services that were created as a result of creating the new flow from the template
templateCreationHelper.identifyNewlyCreatedControllerServiceReferences(instance);
log.debug("Time to identifyNewlyCreatedControllerServiceReferences. ElapsedTime: {} ms", eventTime(eventTime));
eventTime.start();
// match the properties incoming to the defined properties
updateProcessGroupProperties(processGroupId, feedProcessGroup.getName());
log.debug("Time to updateProcessGroupProperties. ElapsedTime: {} ms", eventTime(eventTime));
eventTime.start();
// Fetch the Feed Group now that it has the flow in it
ProcessGroupDTO entity = restClient.getProcessGroup(processGroupId, true, true);
log.debug("Time to getProcessGroup. ElapsedTime: {} ms", eventTime(eventTime));
eventTime.start();
ProcessorDTO input = fetchInputProcessorForProcessGroup(entity);
ProcessorDTO cleanupProcessor = NifiProcessUtil.findFirstProcessorsByType(NifiProcessUtil.getInputProcessors(entity), "com.thinkbiganalytics.nifi.v2.metadata.TriggerCleanup");
List<ProcessorDTO> nonInputProcessors = NifiProcessUtil.getNonInputProcessors(entity);
log.debug("Time to fetchInputProcessorForProcessGroup. ElapsedTime: {} ms", eventTime(eventTime));
eventTime.start();
List<NifiProperty> updatedControllerServiceProperties = new ArrayList<>();
// update any references to the controller services and try to assign the value to an enabled service if it is not already
if (input != null) {
updatedControllerServiceProperties.addAll(templateCreationHelper.updateControllerServiceReferences(Lists.newArrayList(input), instance));
}
if (cleanupProcessor != null) {
updatedControllerServiceProperties.addAll(templateCreationHelper.updateControllerServiceReferences(Collections.singletonList(cleanupProcessor), instance));
}
updatedControllerServiceProperties.addAll(templateCreationHelper.updateControllerServiceReferences(nonInputProcessors, instance));
log.debug("Time to updatedControllerServiceProperties. ElapsedTime: {} ms", eventTime(eventTime));
eventTime.start();
// refetch processors for updated errors
entity = restClient.getProcessGroup(processGroupId, true, true);
input = fetchInputProcessorForProcessGroup(entity);
nonInputProcessors = NifiProcessUtil.getNonInputProcessors(entity);
newProcessGroup = new NifiProcessGroup(entity, input, nonInputProcessors);
log.debug("Time to re-fetchInputProcessorForProcessGroup. ElapsedTime: {} ms", eventTime(eventTime));
// Validate and if invalid Delete the process group
if (newProcessGroup.hasFatalErrors()) {
eventTime.start();
removeProcessGroup(entity);
// cleanupControllerServices();
newProcessGroup.setSuccess(false);
log.debug("Time to removeProcessGroup. Errors found. ElapsedTime: {} ms", eventTime(eventTime));
} else {
eventTime.start();
// update the input schedule
updateFeedSchedule(newProcessGroup, input);
log.debug("Time to update feed schedule. ElapsedTime: {} ms", eventTime(eventTime));
eventTime.start();
// just need to update for this processgroup
Collection<ProcessorDTO> processors = NifiProcessUtil.getProcessors(entity);
Collection<ConnectionDTO> connections = NifiConnectionUtil.getAllConnections(entity);
nifiFlowCache.updateFlowForFeed(feedMetadata, entity.getId(), processors, connections);
log.debug("Time to build flow graph with {} processors and {} connections. ElapsedTime: {} ms", processors.size(), connections.size(), eventTime(eventTime));
/*
//Cache the processorIds to the respective flowIds for availability in the ProvenanceReportingTask
NifiVisitableProcessGroup group = nifiFlowCache.getFlowOrder(newProcessGroup.getProcessGroupEntity(), true);
log.debug("Time to get the flow order. ElapsedTime: {} ms", eventTime(eventTime));
eventTime.start();
NifiFlowProcessGroup
flow =
new NifiFlowBuilder().build(
group);
log.debug("Time to build flow graph with {} processors. ElapsedTime: {} ms", flow.getProcessorMap().size(), eventTime(eventTime));
eventTime.start();
nifiFlowCache.updateFlow(feedMetadata, flow);
log.debug("Time to update NiFiFlowCache with {} processors. ElapsedTime: {} ms", flow.getProcessorMap().size(), eventTime(eventTime));
*/
eventTime.start();
// disable all inputs
restClient.disableInputProcessors(newProcessGroup.getProcessGroupEntity().getId());
log.debug("Time to disableInputProcessors. ElapsedTime: {} ms", eventTime(eventTime));
eventTime.start();
// mark everything else as running
templateCreationHelper.markProcessorsAsRunning(newProcessGroup);
log.debug("Time to markNonInputsAsRunning. ElapsedTime: {} ms", eventTime(eventTime));
// if desired start the input processor
if (input != null) {
eventTime.start();
if (enabled) {
markInputAsRunning(newProcessGroup, input);
// /make the input/output ports in the category group as running
if (hasConnectionPorts()) {
templateCreationHelper.markConnectionPortsAsRunning(entity);
}
} else {
// /make the input/output ports in the category group as running
if (hasConnectionPorts()) {
templateCreationHelper.markConnectionPortsAsRunning(entity);
}
markInputAsStopped(newProcessGroup, input);
}
log.debug("Time to mark input as {}. ElapsedTime: {} ms", (enabled ? "Running" : "Stopped"), eventTime(eventTime));
}
if (newProcessGroup.hasFatalErrors()) {
eventTime.start();
rollback();
newProcessGroup.setRolledBack(true);
// cleanupControllerServices();
newProcessGroup.setSuccess(false);
log.debug("Time to rollback on Fatal Errors. ElapsedTime: {} ms", eventTime(eventTime));
}
List<NifiError> templateCreationErrors = templateCreationHelper.getErrors();
if (templateCreationErrors != null) {
errors.addAll(templateCreationErrors);
}
// add any global errors to the object
if (errors != null && !errors.isEmpty()) {
for (NifiError error : errors) {
newProcessGroup.addError(error);
if (error.isFatal()) {
newProcessGroup.setSuccess(false);
if (!newProcessGroup.isRolledBack()) {
rollback();
newProcessGroup.setRolledBack(true);
}
}
}
}
}
eventTime.start();
templateCreationHelper.cleanupControllerServices();
// fix the feed metadata controller service references
updateFeedMetadataControllerServiceReferences(updatedControllerServiceProperties);
log.debug("Time cleanup controller services. ElapsedTime: {} ms", eventTime(eventTime));
// align items
if (this.autoAlign) {
eventTime.start();
log.info("Aligning Feed flows in NiFi ");
AlignProcessGroupComponents alignProcessGroupComponents = new AlignProcessGroupComponents(restClient.getNiFiRestClient(), entity.getParentGroupId());
alignProcessGroupComponents.autoLayout();
// fetch the parent to get that id to align
if (newCategory) {
log.info("This is the first feed created in the category {}. Aligning the categories. ", feedMetadata.getCategory().getSystemName());
new AlignProcessGroupComponents(restClient.getNiFiRestClient(), this.categoryGroup.getParentGroupId()).autoLayout();
}
log.info("Time align feed process groups. ElapsedTime: {} ms", eventTime(eventTime));
} else {
log.info("Skipping auto alignment in NiFi. You can always manually align this category and all of its feeds by using the rest api: /v1/feedmgr/nifi/auto-align/{}", entity.getParentGroupId());
if (newCategory) {
log.info("To re align the categories: /v1/feedmgr/nifi/auto-align/{}", this.categoryGroup.getParentGroupId());
}
}
}
} else {
log.error("Unable to create/save the feed {}. Unable to find a template for id {}", feedName, templateId);
throw new FeedCreationException("Unable to create the feed [" + feedName + "]. Unable to find a template with id " + templateId);
}
log.info("Time save Feed flow in NiFi. ElapsedTime: {} ms", eventTime(totalTime));
return newProcessGroup;
} catch (NifiClientRuntimeException e) {
throw new FeedCreationException("Unable to create the feed [" + feedName + "]. " + e.getMessage(), e);
}
}
use of com.thinkbiganalytics.nifi.rest.model.NifiProperty in project kylo by Teradata.
the class PropertyExpressionResolver method resolveVariables.
/**
* Resolve the str with values from the supplied {@code properties} This will recursively fill out the str looking back at the properties to get the correct value. NOTE the property values will be
* overwritten if replacement is found!
*/
public ResolvedVariables resolveVariables(String str, List<NifiProperty> properties) {
ResolvedVariables variables = new ResolvedVariables(str);
StrLookup resolver = new StrLookup() {
@Override
public String lookup(String key) {
Optional<NifiProperty> optional = properties.stream().filter(prop -> key.equals(prop.getKey())).findFirst();
if (optional.isPresent()) {
NifiProperty property = optional.get();
String value = StringUtils.isNotBlank(property.getValue()) ? property.getValue().trim() : "";
variables.getResolvedVariables().put(property.getKey(), value);
return value;
} else {
return null;
}
}
};
StrSubstitutor ss = new StrSubstitutor(resolver);
variables.setResolvedString(ss.replace(str));
Map<String, String> map = variables.getResolvedVariables();
Map<String, String> vars = map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> ss.replace(entry.getValue())));
variables.getResolvedVariables().putAll(vars);
return variables;
}
use of com.thinkbiganalytics.nifi.rest.model.NifiProperty in project kylo by Teradata.
the class FeedRestController method getFileUploadContext.
private FileUploadContext getFileUploadContext(List<NifiProperty> properties) {
String dropzone = null;
String regexFileFilter = null;
for (NifiProperty property : properties) {
if (property.getProcessorType().equals("org.apache.nifi.processors.standard.GetFile")) {
if (property.getKey().equals("File Filter")) {
regexFileFilter = property.getValue();
} else if (property.getKey().equals("Input Directory")) {
dropzone = property.getValue();
}
}
}
return new FileUploadContext(dropzone, regexFileFilter);
}
Aggregations