NIFI-8386: Ensure that we set (and merge) bulletins when creating AffectedComponent entities and ControllerService Reference entities

NIFI-8386: Addressed review feedback: removed unused call to determine permissions, null out bulletins in standalone mode if permissions not allowed. Also fixed automated tests that were failing due to changes

This closes #4955
This commit is contained in:
Mark Payne 2021-03-31 15:48:45 -04:00 committed by Matt Gilman
parent 2edf5514b7
commit 7db1b8d564
No known key found for this signature in database
GPG Key ID: DF61EC19432AEE37
8 changed files with 88 additions and 15 deletions

View File

@ -16,7 +16,6 @@
*/
package org.apache.nifi.web.filter
import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.junit.After
import org.junit.Before
import org.junit.BeforeClass
@ -29,7 +28,6 @@ import org.slf4j.LoggerFactory
import javax.servlet.FilterConfig
import javax.servlet.ServletContext
import javax.servlet.http.HttpServletRequest
import java.security.Security
@RunWith(JUnit4.class)
class SanitizeContextPathFilterTest extends GroovyTestCase {
@ -37,8 +35,6 @@ class SanitizeContextPathFilterTest extends GroovyTestCase {
@BeforeClass
static void setUpOnce() throws Exception {
Security.addProvider(new BouncyCastleProvider())
logger.metaClass.methodMissing = { String name, args ->
logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
}

View File

@ -23,6 +23,7 @@ import org.apache.nifi.web.api.dto.AffectedComponentDTO;
import org.apache.nifi.web.api.dto.ParameterContextDTO;
import org.apache.nifi.web.api.dto.ParameterDTO;
import org.apache.nifi.web.api.entity.AffectedComponentEntity;
import org.apache.nifi.web.api.entity.BulletinEntity;
import org.apache.nifi.web.api.entity.ParameterContextEntity;
import org.apache.nifi.web.api.entity.ParameterEntity;
import org.apache.nifi.web.api.entity.ProcessGroupEntity;
@ -30,6 +31,7 @@ import org.apache.nifi.web.api.entity.ProcessGroupEntity;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -135,6 +137,22 @@ public class ParameterContextMerger {
static void merge(final AffectedComponentEntity merged, final AffectedComponentEntity additional) {
PermissionsDtoMerger.mergePermissions(merged.getPermissions(), additional.getPermissions());
// Merge the bulletins
if (merged.getPermissions().getCanRead() == Boolean.TRUE) {
final List<BulletinEntity> additionalBulletins = additional.getBulletins();
if (additionalBulletins != null) {
List<BulletinEntity> mergedBulletins = merged.getBulletins();
if (mergedBulletins == null) {
mergedBulletins = new ArrayList<>();
merged.setBulletins(mergedBulletins);
}
mergedBulletins.addAll(additionalBulletins);
}
} else {
merged.setBulletins(null);
}
if (!Boolean.TRUE.equals(merged.getPermissions().getCanRead()) || additional.getComponent() == null) {
merged.setComponent(null);
return;

View File

@ -21,8 +21,11 @@ import org.apache.nifi.controller.service.ControllerServiceState;
import org.apache.nifi.web.api.dto.AffectedComponentDTO;
import org.apache.nifi.web.api.dto.PermissionsDTO;
import org.apache.nifi.web.api.entity.AffectedComponentEntity;
import org.apache.nifi.web.api.entity.BulletinEntity;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -33,6 +36,7 @@ public class AffectedComponentEntityMerger {
final Map<String, Integer> activeThreadCounts = new HashMap<>();
final Map<String, String> states = new HashMap<>();
final Map<String, PermissionsDTO> canReads = new HashMap<>();
final Map<String, List<BulletinEntity>> bulletins = new HashMap<>();
for (final Map.Entry<NodeIdentifier, Set<AffectedComponentEntity>> nodeEntry : affectedComponentMap.entrySet()) {
final Set<AffectedComponentEntity> nodeAffectedComponents = nodeEntry.getValue();
@ -62,6 +66,13 @@ public class AffectedComponentEntityMerger {
states.put(nodeAffectedComponent.getId(), ControllerServiceState.ENABLING.name());
}
}
// Merged bulletins into above bulletins map
final List<BulletinEntity> bulletinsForComponent = bulletins.computeIfAbsent(nodeAffectedComponentEntity.getId(), k -> new ArrayList<>());
final List<BulletinEntity> nodeComponentBulletins = nodeAffectedComponentEntity.getBulletins();
if (nodeComponentBulletins != null) {
bulletinsForComponent.addAll(nodeComponentBulletins);
}
}
// handle read permissions
@ -92,6 +103,8 @@ public class AffectedComponentEntityMerger {
if (state != null) {
affectedComponent.getComponent().setState(state);
}
affectedComponent.setBulletins(bulletins.get(affectedComponent.getId()));
} else {
affectedComponent.setPermissions(permissions);
affectedComponent.setComponent(null);
@ -99,6 +112,8 @@ public class AffectedComponentEntityMerger {
if (affectedComponent.getProcessGroup() != null) {
affectedComponent.getProcessGroup().setName(affectedComponent.getProcessGroup().getId());
}
affectedComponent.setBulletins(null);
}
}
}

View File

@ -16,21 +16,24 @@
*/
package org.apache.nifi.cluster.manager;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.controller.service.ControllerServiceState;
import org.apache.nifi.web.api.dto.ControllerServiceDTO;
import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO;
import org.apache.nifi.web.api.dto.PermissionsDTO;
import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
import org.apache.nifi.web.api.entity.BulletinEntity;
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class ControllerServiceEntityMerger implements ComponentEntityMerger<ControllerServiceEntity> {
/**
@ -172,6 +175,7 @@ public class ControllerServiceEntityMerger implements ComponentEntityMerger<Cont
for (final ControllerServiceReferencingComponentEntity referencingComponent : referencingComponents) {
final PermissionsDTO permissions = permissionsHolder.get(referencingComponent.getId());
final PermissionsDTO operatePermissions = operatePermissionsHolder.get(referencingComponent.getId());
if (permissions != null && permissions.getCanRead() != null && permissions.getCanRead()) {
final Integer activeThreadCount = activeThreadCounts.get(referencingComponent.getId());
if (activeThreadCount != null) {
@ -200,6 +204,7 @@ public class ControllerServiceEntityMerger implements ComponentEntityMerger<Cont
referencingComponent.setPermissions(permissions);
referencingComponent.setOperatePermissions(operatePermissions);
referencingComponent.setComponent(null);
referencingComponent.setBulletins(null);
}
}
}
@ -226,7 +231,7 @@ public class ControllerServiceEntityMerger implements ComponentEntityMerger<Cont
for (Map.Entry<NodeIdentifier, ControllerServiceReferencingComponentEntity> entry : nodeEntities.entrySet()) {
final NodeIdentifier nodeIdentifier = entry.getKey();
final ControllerServiceReferencingComponentEntity nodeEntity = entry.getValue();
nodeEntity.getComponent().getDescriptors().values().stream().forEach(propertyDescriptor -> {
nodeEntity.getComponent().getDescriptors().values().forEach(propertyDescriptor -> {
propertyDescriptorMap.computeIfAbsent(propertyDescriptor.getName(), nodeIdToPropertyDescriptor -> new HashMap<>()).put(nodeIdentifier, propertyDescriptor);
});
nodeReferencingComponentsMap.put(nodeIdentifier, nodeEntity.getComponent().getReferencingComponents());
@ -243,6 +248,16 @@ public class ControllerServiceEntityMerger implements ComponentEntityMerger<Cont
}
}
// Merge bulletins
final List<BulletinEntity> bulletins = new ArrayList<>();
for (ControllerServiceReferencingComponentEntity entity : nodeEntities.values()) {
final List<BulletinEntity> entityBulletins = entity.getBulletins();
if (entityBulletins != null) {
bulletins.addAll(entityBulletins);
}
}
clientEntity.setBulletins(bulletins);
final Set<ControllerServiceReferencingComponentEntity> referencingComponents = clientEntity.getComponent().getReferencingComponents();
mergeControllerServiceReferences(referencingComponents, nodeReferencingComponentsMap);
}

View File

@ -110,6 +110,7 @@ class ControllerServiceEntityMergerSpec extends Specification {
[(createNodeIdentifier(1)): new ControllerServiceEntity(id: '1',
permissions: new PermissionsDTO(canRead: true, canWrite: true),
operatePermissions: new PermissionsDTO(canRead: false, canWrite: true),
bulletins: [],
component: new ControllerServiceDTO(referencingComponents: [new ControllerServiceReferencingComponentEntity(
permissions: new PermissionsDTO(canRead: true, canWrite: true),
operatePermissions: new PermissionsDTO(canRead: false, canWrite: true),
@ -118,6 +119,7 @@ class ControllerServiceEntityMergerSpec extends Specification {
(createNodeIdentifier(2)): new ControllerServiceEntity(id: '1',
permissions: new PermissionsDTO(canRead: true, canWrite: true),
operatePermissions: new PermissionsDTO(canRead: false, canWrite: true),
bulletins: [],
component: new ControllerServiceDTO(referencingComponents: [new ControllerServiceReferencingComponentEntity(
permissions: new PermissionsDTO(canRead: true, canWrite: true),
operatePermissions: new PermissionsDTO(canRead: false, canWrite: true),
@ -126,6 +128,7 @@ class ControllerServiceEntityMergerSpec extends Specification {
(createNodeIdentifier(3)): new ControllerServiceEntity(id: '1',
permissions: new PermissionsDTO(canRead: true, canWrite: true),
operatePermissions: new PermissionsDTO(canRead: false, canWrite: true),
bulletins: [],
component: new ControllerServiceDTO(referencingComponents: [new ControllerServiceReferencingComponentEntity(
permissions: new PermissionsDTO(canRead: true, canWrite: true),
operatePermissions: new PermissionsDTO(canRead: false, canWrite: true),
@ -139,6 +142,7 @@ class ControllerServiceEntityMergerSpec extends Specification {
referencingComponents: [new ControllerServiceReferencingComponentEntity(
permissions: new PermissionsDTO(canRead: true, canWrite: true),
operatePermissions: new PermissionsDTO(canRead: false, canWrite: true),
bulletins: [],
component: new ControllerServiceReferencingComponentDTO(activeThreadCount: 3, state: ControllerServiceState.ENABLING.name()))]))
}

View File

@ -2834,7 +2834,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
}
componentEntities.add(entityFactory.createControllerServiceReferencingComponentEntity(refComponent.getIdentifier(), dto, revisionDto, permissions, operatePermissions));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(refComponent.getIdentifier()));
componentEntities.add(entityFactory.createControllerServiceReferencingComponentEntity(refComponent.getIdentifier(), dto, revisionDto, permissions, operatePermissions, bulletins));
}
final ControllerServiceReferencingComponentsEntity entity = new ControllerServiceReferencingComponentsEntity();

View File

@ -2857,7 +2857,13 @@ public final class DtoFactory {
}
}
return entityFactory.createAffectedComponentEntity(affectedComponent, revision, permissions, groupNameDto);
final List<BulletinDTO> bulletins = createBulletins(componentNode);
return entityFactory.createAffectedComponentEntity(affectedComponent, revision, permissions, groupNameDto, bulletins);
}
private List<BulletinDTO> createBulletins(final ComponentNode componentNode) {
final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(componentNode.getIdentifier()));
return bulletins;
}
public VariableRegistryDTO createVariableRegistryDto(final ProcessGroup processGroup, final RevisionManager revisionManager) {

View File

@ -85,6 +85,7 @@ import org.apache.nifi.web.api.entity.VersionControlInformationEntity;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
public final class EntityFactory {
@ -384,7 +385,7 @@ public final class EntityFactory {
}
public AffectedComponentEntity createAffectedComponentEntity(final AffectedComponentDTO dto, final RevisionDTO revision, final PermissionsDTO permissions,
final ProcessGroupNameDTO processGroupNameDto) {
final ProcessGroupNameDTO processGroupNameDto, final List<BulletinDTO> bulletins) {
final AffectedComponentEntity entity = new AffectedComponentEntity();
entity.setRevision(revision);
if (dto != null) {
@ -397,6 +398,13 @@ public final class EntityFactory {
}
}
if (Boolean.TRUE == permissions.getCanRead()) {
final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList());
entity.setBulletins(bulletinEntities);
} else {
entity.setBulletins(null);
}
entity.setProcessGroup(processGroupNameDto);
return entity;
}
@ -615,8 +623,11 @@ public final class EntityFactory {
}
public ControllerServiceReferencingComponentEntity createControllerServiceReferencingComponentEntity(final String id,
final ControllerServiceReferencingComponentDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final PermissionsDTO operatePermissions) {
final ControllerServiceReferencingComponentDTO dto, final RevisionDTO revision, final PermissionsDTO permissions, final PermissionsDTO operatePermissions,
final List<BulletinDTO> bulletins) {
final ControllerServiceReferencingComponentEntity entity = new ControllerServiceReferencingComponentEntity();
entity.setId(id);
entity.setRevision(revision);
if (dto != null) {
entity.setPermissions(permissions);
@ -627,6 +638,13 @@ public final class EntityFactory {
}
}
if (permissions.getCanRead() == Boolean.TRUE) {
final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList());
entity.setBulletins(bulletinEntities);
} else {
entity.setBulletins(null);
}
return entity;
}