Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -226,19 +226,32 @@ public Authorizable getCounters() {
return COUNTERS_AUTHORIZABLE;
}

@Override
public Authorizable getControllerServiceReferencingComponent(String controllerSeriveId, String id) {
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerSeriveId);
final ControllerServiceReference referencingComponents = controllerService.getReferences();

private ConfiguredComponent findControllerServiceReferencingComponent(final ControllerServiceReference referencingComponents, final String id) {
ConfiguredComponent reference = null;
for (final ConfiguredComponent component : referencingComponents.getReferencingComponents()) {
if (component.getIdentifier().equals(id)) {
reference = component;
break;
}

if (component instanceof ControllerServiceNode) {
final ControllerServiceNode refControllerService = (ControllerServiceNode) component;
reference = findControllerServiceReferencingComponent(refControllerService.getReferences(), id);
if (reference != null) {
break;
}
}
}

return reference;
}

@Override
public Authorizable getControllerServiceReferencingComponent(String controllerSeriveId, String id) {
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerSeriveId);
final ControllerServiceReference referencingComponents = controllerService.getReferences();
final ConfiguredComponent reference = findControllerServiceReferencingComponent(referencingComponents, id);

if (reference == null) {
throw new ResourceNotFoundException("Unable to find referencing component with id " + id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1676,13 +1676,32 @@ public ControllerServiceEntity updateControllerService(final Revision revision,
final RevisionUpdate<ControllerServiceDTO> snapshot = updateComponent(revision,
controllerService,
() -> controllerServiceDAO.updateControllerService(controllerServiceDTO),
cs -> dtoFactory.createControllerServiceDto(cs));
cs -> {
final ControllerServiceDTO dto = dtoFactory.createControllerServiceDto(cs);
final ControllerServiceReference ref = controllerService.getReferences();
final ControllerServiceReferencingComponentsEntity referencingComponentsEntity =
createControllerServiceReferencingComponentsEntity(ref, Sets.newHashSet(controllerService.getIdentifier()));
dto.setReferencingComponents(referencingComponentsEntity.getControllerServiceReferencingComponents());
return dto;
});

final PermissionsDTO permissions = dtoFactory.createPermissionsDto(controllerService);
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(controllerServiceDTO.getId()));
return entityFactory.createControllerServiceEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, bulletins);
}

private Set<ConfiguredComponent> findAllReferencingComponents(final ControllerServiceReference reference) {
final Set<ConfiguredComponent> referencingComponents = new HashSet<>(reference.getReferencingComponents());

for (final ConfiguredComponent referencingComponent : reference.getReferencingComponents()) {
if (referencingComponent instanceof ControllerServiceNode) {
referencingComponents.addAll(findAllReferencingComponents(((ControllerServiceNode) referencingComponent).getReferences()));
}
}

return referencingComponents;
}

@Override
public ControllerServiceReferencingComponentsEntity updateControllerServiceReferencingComponents(
final Map<String, Revision> referenceRevisions, final String controllerServiceId, final ScheduledState scheduledState, final ControllerServiceState controllerServiceState) {
Expand All @@ -1705,13 +1724,9 @@ public RevisionUpdate<ControllerServiceReferencingComponentsEntity> update() {
updatedRevisions.put(component.getIdentifier(), currentRevision.incrementRevision(requestRevision.getClientId()));
}

// return the current revision if the component wasn't updated
for (final Map.Entry<String, Revision> entry : referenceRevisions.entrySet()) {
final String componentId = entry.getKey();
if (!updatedRevisions.containsKey(componentId)) {
final Revision currentRevision = revisionManager.getRevision(componentId);
updatedRevisions.put(componentId, currentRevision);
}
// ensure the revision for all referencing components is included regardless of whether they were updated in this request
for (final ConfiguredComponent component : findAllReferencingComponents(updatedReference)) {
updatedRevisions.putIfAbsent(component.getIdentifier(), revisionManager.getRevision(component.getIdentifier()));
}

final ControllerServiceReferencingComponentsEntity entity = createControllerServiceReferencingComponentsEntity(updatedReference, updatedRevisions);
Expand Down Expand Up @@ -1757,6 +1772,7 @@ private ControllerServiceReferencingComponentsEntity createControllerServiceRefe
for (final ConfiguredComponent component : reference.getReferencingComponents()) {
referencingRevisions.put(component.getIdentifier(), revisionManager.getRevision(component.getIdentifier()));
}

return createControllerServiceReferencingComponentsEntity(reference, referencingRevisions);
}

Expand Down Expand Up @@ -1806,7 +1822,12 @@ private ControllerServiceReferencingComponentsEntity createControllerServiceRefe

// if we haven't encountered this service before include it's referencing components
if (!dto.getReferenceCycle()) {
final ControllerServiceReferencingComponentsEntity references = createControllerServiceReferencingComponentsEntity(node.getReferences(), revisions, visited);
final ControllerServiceReference refReferences = node.getReferences();
final Map<String, Revision> referencingRevisions = new HashMap<>(revisions);
for (final ConfiguredComponent component : refReferences.getReferencingComponents()) {
referencingRevisions.putIfAbsent(component.getIdentifier(), revisionManager.getRevision(component.getIdentifier()));
}
final ControllerServiceReferencingComponentsEntity references = createControllerServiceReferencingComponentsEntity(refReferences, referencingRevisions, visited);
dto.setReferencingComponents(references.getControllerServiceReferencingComponents());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ nf.ControllerService = (function () {
};

/**
* Reloads the specified controller service. It's referencing and referenced
* Reloads the specified controller service if we have read permissions. It's referencing and referenced
* components are NOT reloaded.
*
* @param {jQuery} serviceTable
Expand All @@ -123,8 +123,9 @@ nf.ControllerService = (function () {

// this may happen if controller service A references another controller
// service B that has been removed. attempting to enable/disable/remove A
// will attempt to reload B which is no longer a known service
if (nf.Common.isUndefined(controllerServiceEntity)) {
// will attempt to reload B which is no longer a known service. also ensure
// we have permissions to reload the service
if (nf.Common.isUndefined(controllerServiceEntity) || controllerServiceEntity.permissions.canRead === false) {
return $.Deferred(function (deferred) {
deferred.reject();
}).promise();
Expand Down Expand Up @@ -457,7 +458,8 @@ nf.ControllerService = (function () {
if (serviceTwist.hasClass('collapsed')) {
var controllerServiceGrid = serviceTable.data('gridInstance');
var controllerServiceData = controllerServiceGrid.getData();
var referencingService = controllerServiceData.getItemById(referencingComponent.id);
var referencingServiceEntity = controllerServiceData.getItemById(referencingComponent.id);
var referencingService = referencingServiceEntity.component;

// create the markup for the references
createReferencingComponents(serviceTable, referencingServiceReferencesContainer, referencingService.referencingComponents);
Expand Down Expand Up @@ -673,6 +675,33 @@ nf.ControllerService = (function () {
return ids;
};

/**
* Gathers all referencing component revisions.
*
* @param referencingComponents
* @param referencingComponentRevisions
* @param serviceOnly - true includes only services, false includes only schedulable components
*/
var getReferencingComponentRevisions = function (referencingComponents, referencingComponentRevisions, serviceOnly) {
// include the revision of each referencing component
$.each(referencingComponents, function (_, referencingComponentEntity) {
var referencingComponent = referencingComponentEntity.component;

if (serviceOnly) {
if (referencingComponent.referenceType === 'ControllerService') {
referencingComponentRevisions[referencingComponentEntity.id] = nf.Client.getRevision(referencingComponentEntity);
}
} else {
if (referencingComponent.referenceType !== 'ControllerService') {
referencingComponentRevisions[referencingComponentEntity.id] = nf.Client.getRevision(referencingComponentEntity);
}
}

// recurse
getReferencingComponentRevisions(referencingComponent.referencingComponents, referencingComponentRevisions, serviceOnly);
});
};

/**
* Updates the scheduled state of the processors/reporting tasks referencing
* the specified controller service.
Expand All @@ -683,17 +712,15 @@ nf.ControllerService = (function () {
* @param {function} pollCondition
*/
var updateReferencingSchedulableComponents = function (serviceTable, controllerServiceEntity, running, pollCondition) {
var referencingRevisions = {};
getReferencingComponentRevisions(controllerServiceEntity.component.referencingComponents, referencingRevisions, false);

var referenceEntity = {
'id': controllerServiceEntity.id,
'state': running ? 'RUNNING' : 'STOPPED',
'referencingComponentRevisions': {}
'referencingComponentRevisions': referencingRevisions
};

// include the revision of each referencing component
$.each(controllerServiceEntity.component.referencingComponents, function (_, referencingComponent) {
referenceEntity.referencingComponentRevisions[referencingComponent.id] = nf.Client.getRevision(referencingComponent);
});

// issue the request to update the referencing components
var updated = $.ajax({
type: 'PUT',
Expand Down Expand Up @@ -956,18 +983,16 @@ nf.ControllerService = (function () {
* @param {function} pollCondition
*/
var updateReferencingServices = function (serviceTable, controllerServiceEntity, enabled, pollCondition) {
var referencingRevisions = {};
getReferencingComponentRevisions(controllerServiceEntity.component.referencingComponents, referencingRevisions, true);

// build the reference entity
var referenceEntity = {
'id': controllerServiceEntity.id,
'state': enabled ? 'ENABLED' : 'DISABLED',
'referencingComponentRevisions': {}
'referencingComponentRevisions': referencingRevisions
};

// include the revision of each referencing component
$.each(controllerServiceEntity.component.referencingComponents, function (_, referencingComponent) {
referenceEntity.referencingComponentRevisions[referencingComponent.id] = nf.Client.getRevision(referencingComponent);
});

// issue the request to update the referencing components
var updated = $.ajax({
type: 'PUT',
Expand Down Expand Up @@ -1029,34 +1054,20 @@ nf.ControllerService = (function () {
var referencingComponentsContainer = $('#disable-controller-service-referencing-components');
createReferencingComponents(serviceTable, referencingComponentsContainer, controllerService.referencingComponents);

var hasUnauthorized = false;
$.each(controllerService.referencingComponents, function (_, referencingComponent) {
if (referencingComponent.permissions.canRead === false || referencingComponent.permissions.canWrite === false) {
hasUnauthorized = true;
return false;
}
});

// build the button model
var buttons = [];

if (hasUnauthorized === false) {
buttons.push({
buttonText: 'Disable',
color: {
base: '#728E9B',
hover: '#004849',
text: '#ffffff'
},
handler: {
click: function () {
disableHandler(serviceTable);
}
var buttons = [{
buttonText: 'Disable',
color: {
base: '#728E9B',
hover: '#004849',
text: '#ffffff'
},
handler: {
click: function () {
disableHandler(serviceTable);
}
});
}

buttons.push({
}
}, {
buttonText: 'Cancel',
color: {
base: '#E3E8EB',
Expand All @@ -1066,7 +1077,7 @@ nf.ControllerService = (function () {
handler: {
click: closeModal
}
});
}];

// show the dialog
$('#disable-controller-service-dialog').modal('setButtonModel', buttons).modal('show');
Expand Down Expand Up @@ -1197,6 +1208,17 @@ nf.ControllerService = (function () {
}]);
};

// ensure we have access to all referencing components before attempting the sequence
if (hasUnauthorizedReferencingComponent(controllerService.referencingComponents)) {
setCloseButton();

nf.Dialog.showOkDialog({
headerText: 'Controller Service',
dialogContent: 'Unable to disable due to unauthorized referencing components.'
});
return;
}

$('#disable-progress-label').text('Steps to disable ' + controllerService.name);
var disableReferencingSchedulable = $('#disable-referencing-schedulable').addClass('ajax-loading');

Expand Down Expand Up @@ -1247,6 +1269,31 @@ nf.ControllerService = (function () {
});
};

/**
* Determines if any of the specified referencing components are not authorized.
*
* @param referencingComponents referencing components
* @returns {boolean}
*/
var hasUnauthorizedReferencingComponent = function (referencingComponents) {
var hasUnauthorized = false;

$.each(referencingComponents, function (_, referencingComponentEntity) {
if (referencingComponentEntity.permissions.canRead === false || referencingComponentEntity.permissions.canWrite === false) {
hasUnauthorized = true;
return false;
}

var referencingComponent = referencingComponentEntity.component;
if (hasUnauthorizedReferencingComponent(referencingComponent.referencingComponents)) {
hasUnauthorized = true;
return false;
}
});

return hasUnauthorized;
};

/**
* Handles the enable action of the enable controller service dialog.
*
Expand All @@ -1263,26 +1310,9 @@ nf.ControllerService = (function () {
var controllerServiceEntity = controllerServiceData.getItemById(controllerServiceId);
var controllerService = controllerServiceEntity.component;

var hasUnauthorized = false;
$.each(controllerService.referencingComponents, function (_, referencingComponent) {
if (referencingComponent.permissions.canRead === false || referencingComponent.permissions.canWrite === false) {
hasUnauthorized = true;
return false;
}
});

// determine if we want to also activate referencing components
var scope = $('#enable-controller-service-scope').combo('getSelectedOption').value;

// ensure appropriate access
if (scope === config.serviceAndReferencingComponents && hasUnauthorized) {
nf.Dialog.showOkDialog({
headerText: 'Controller Service',
dialogContent: 'Unable to enable due to unauthorized referencing components.'
});
return;
}

// update visibility
if (scope === config.serviceOnly) {
$('#enable-controller-service-progress li.referencing-component').hide();
Expand Down Expand Up @@ -1331,6 +1361,17 @@ nf.ControllerService = (function () {
}]);
};

// ensure appropriate access
if (scope === config.serviceAndReferencingComponents && hasUnauthorizedReferencingComponent(controllerService.referencingComponents)) {
setCloseButton();

nf.Dialog.showOkDialog({
headerText: 'Controller Service',
dialogContent: 'Unable to enable due to unauthorized referencing components.'
});
return;
}

$('#enable-progress-label').text('Steps to enable ' + controllerService.name);
var enableControllerService = $('#enable-controller-service').addClass('ajax-loading');

Expand Down Expand Up @@ -1504,7 +1545,7 @@ nf.ControllerService = (function () {
};

/**
* Identifies descritpors that reference controller services.
* Identifies descriptors that reference controller services.
*
* @param {object} component
*/
Expand Down