Fix NPE push Management UI on events (#543)

* NEP check on event.getEntity . Performance optimization on DS table.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* Fix event tests.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>

* used method reference.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2017-06-20 17:20:22 +02:00
committed by GitHub
parent 2383aff5bf
commit 648123c1d7
11 changed files with 100 additions and 34 deletions

View File

@@ -18,6 +18,8 @@ public class DistributionSetUpdatedEvent extends RemoteEntityEvent<DistributionS
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private boolean complete;
/** /**
* Default constructor. * Default constructor.
*/ */
@@ -32,8 +34,21 @@ public class DistributionSetUpdatedEvent extends RemoteEntityEvent<DistributionS
* Distribution Set * Distribution Set
* @param applicationId * @param applicationId
* the origin application id * the origin application id
* @param complete
* <code>true</code> if {@link DistributionSet} is after the
* update {@link DistributionSet#isComplete()}
*/ */
public DistributionSetUpdatedEvent(final DistributionSet ds, final String applicationId) { public DistributionSetUpdatedEvent(final DistributionSet ds, final String applicationId, final boolean complete) {
super(ds, applicationId); super(ds, applicationId);
this.complete = complete;
} }
/**
* @return <code>true</code> if {@link DistributionSet} is after the update
* {@link DistributionSet#isComplete()}
*/
public boolean isComplete() {
return complete;
}
} }

View File

@@ -338,7 +338,7 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { public void fireUpdateEvent(final DescriptorEvent descriptorEvent) {
publishEventWithEventPublisher( publishEventWithEventPublisher(
new DistributionSetUpdatedEvent(this, EventPublisherHolder.getInstance().getApplicationId())); new DistributionSetUpdatedEvent(this, EventPublisherHolder.getInstance().getApplicationId(), complete));
if (isSoftDeleted(descriptorEvent)) { if (isSoftDeleted(descriptorEvent)) {
publishEventWithEventPublisher(new DistributionSetDeletedEvent(getTenant(), getId(), getClass().getName(), publishEventWithEventPublisher(new DistributionSetDeletedEvent(getTenant(), getId(), getClass().getName(),

View File

@@ -0,0 +1,37 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.event.remote.entity;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.junit.Test;
import ru.yandex.qatools.allure.annotations.Description;
import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
/**
* Test the remote entity events.
*/
@Features("Component Tests - Repository")
@Stories("Test DistributionSetCreatedEvent")
public class DistributionSetCreatedEventTest extends AbstractRemoteEntityEventTest<DistributionSet> {
@Test
@Description("Verifies that the distribution set entity reloading by remote created event works")
public void testDistributionSetCreatedEvent() {
assertAndCreateRemoteEvent(DistributionSetCreatedEvent.class);
}
@Override
protected DistributionSet createEntity() {
return distributionSetManagement.createDistributionSet(entityFactory.distributionSet().create()
.name("incomplete").version("2").description("incomplete").type("os"));
}
}

View File

@@ -19,14 +19,8 @@ import ru.yandex.qatools.allure.annotations.Stories;
* Test the remote entity events. * Test the remote entity events.
*/ */
@Features("Component Tests - Repository") @Features("Component Tests - Repository")
@Stories("Test DistributionSetCreatedEvent and DistributionSetUpdateEvent") @Stories("Test DistributionSetUpdateEvent")
public class DistributionSetEventTest extends AbstractRemoteEntityEventTest<DistributionSet> { public class DistributionSetUpdatedEventTest extends AbstractRemoteEntityEventTest<DistributionSet> {
@Test
@Description("Verifies that the distribution set entity reloading by remote created event works")
public void testDistributionSetCreatedEvent() {
assertAndCreateRemoteEvent(DistributionSetCreatedEvent.class);
}
@Test @Test
@Description("Verifies that the distribution set entity reloading by remote updated event works") @Description("Verifies that the distribution set entity reloading by remote updated event works")
@@ -34,6 +28,13 @@ public class DistributionSetEventTest extends AbstractRemoteEntityEventTest<Dist
assertAndCreateRemoteEvent(DistributionSetUpdatedEvent.class); assertAndCreateRemoteEvent(DistributionSetUpdatedEvent.class);
} }
@Override
protected RemoteEntityEvent<?> createRemoteEvent(final DistributionSet baseEntity,
final Class<? extends RemoteEntityEvent<?>> eventType) {
return new DistributionSetUpdatedEvent(baseEntity, "1", true);
}
@Override @Override
protected DistributionSet createEntity() { protected DistributionSet createEntity() {
return distributionSetManagement.createDistributionSet(entityFactory.distributionSet().create() return distributionSetManagement.createDistributionSet(entityFactory.distributionSet().create()

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.ui.artifacts.smtable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import org.eclipse.hawkbit.repository.SoftwareModuleManagement; import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
@@ -175,6 +176,7 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final List<Long> visibleItemIds = (List<Long>) getVisibleItemIds(); final List<Long> visibleItemIds = (List<Long>) getVisibleItemIds();
eventContainer.getEvents().stream().filter(event -> visibleItemIds.contains(event.getEntityId())) eventContainer.getEvents().stream().filter(event -> visibleItemIds.contains(event.getEntityId()))
.filter(Objects::nonNull)
.forEach(event -> updateSoftwareModuleInTable(event.getEntity())); .forEach(event -> updateSoftwareModuleInTable(event.getEntity()));
} }

View File

@@ -9,8 +9,10 @@
package org.eclipse.hawkbit.ui.common.tagdetails; package org.eclipse.hawkbit.ui.common.tagdetails;
import java.util.List; import java.util.List;
import java.util.Objects;
import org.eclipse.hawkbit.repository.TagManagement; import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagUpdatedEvent;
import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.ui.SpPermissionChecker; import org.eclipse.hawkbit.ui.SpPermissionChecker;
@@ -46,7 +48,8 @@ public abstract class AbstractTargetTagToken<T extends BaseEntity> extends Abstr
@EventBusListenerMethod(scope = EventScope.UI) @EventBusListenerMethod(scope = EventScope.UI)
void onEventTargetTagCreated(final TargetTagCreatedEventContainer container) { void onEventTargetTagCreated(final TargetTagCreatedEventContainer container) {
container.getEvents().stream().map(event -> event.getEntity()) container.getEvents().stream().filter(Objects::nonNull)
.map(TargetTagCreatedEvent::getEntity)
.forEach(tag -> setContainerPropertValues(tag.getId(), tag.getName(), tag.getColour())); .forEach(tag -> setContainerPropertValues(tag.getId(), tag.getName(), tag.getColour()));
} }

View File

@@ -9,10 +9,13 @@
package org.eclipse.hawkbit.ui.common.tagdetails; package org.eclipse.hawkbit.ui.common.tagdetails;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.TagManagement; import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagUpdatedEvent;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
@@ -126,7 +129,8 @@ public class DistributionTagToken extends AbstractTagToken<DistributionSet> {
@EventBusListenerMethod(scope = EventScope.UI) @EventBusListenerMethod(scope = EventScope.UI)
void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedEventContainer eventContainer) { void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedEventContainer eventContainer) {
eventContainer.getEvents().stream().map(event -> event.getEntity()) eventContainer.getEvents().stream().filter(Objects::nonNull)
.map(DistributionSetTagCreatedEvent::getEntity)
.forEach(distributionSetTag -> setContainerPropertValues(distributionSetTag.getId(), .forEach(distributionSetTag -> setContainerPropertValues(distributionSetTag.getId(),
distributionSetTag.getName(), distributionSetTag.getColour())); distributionSetTag.getName(), distributionSetTag.getColour()));
} }
@@ -139,7 +143,8 @@ public class DistributionTagToken extends AbstractTagToken<DistributionSet> {
@EventBusListenerMethod(scope = EventScope.UI) @EventBusListenerMethod(scope = EventScope.UI)
void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdatedEventContainer eventContainer) { void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdatedEventContainer eventContainer) {
eventContainer.getEvents().stream().map(event -> event.getEntity()).forEach(entity -> { eventContainer.getEvents().stream().filter(Objects::nonNull)
.map(DistributionSetTagUpdatedEvent::getEntity).forEach(entity -> {
final Item item = container.getItem(entity.getId()); final Item item = container.getItem(entity.getId());
if (item != null) { if (item != null) {
updateItem(entity.getName(), entity.getColour(), item); updateItem(entity.getName(), entity.getColour(), item);

View File

@@ -13,6 +13,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@@ -121,7 +122,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
private void handleSelectedAndUpdatedDs(final List<DistributionSetUpdatedEvent> events) { private void handleSelectedAndUpdatedDs(final List<DistributionSetUpdatedEvent> events) {
manageDistUIState.getLastSelectedDistribution() manageDistUIState.getLastSelectedDistribution()
.ifPresent(lastSelectedDsIdName -> events.stream() .ifPresent(lastSelectedDsIdName -> events.stream().filter(Objects::nonNull)
.filter(event -> event.getEntityId().equals(lastSelectedDsIdName)).findAny() .filter(event -> event.getEntityId().equals(lastSelectedDsIdName)).findAny()
.ifPresent(event -> eventBus.publish(this, .ifPresent(event -> eventBus.publish(this,
new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, event.getEntity())))); new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, event.getEntity()))));
@@ -130,7 +131,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
private void updateVisableTableEntries(final List<DistributionSetUpdatedEvent> events, private void updateVisableTableEntries(final List<DistributionSetUpdatedEvent> events,
final List<Long> visibleItemIds) { final List<Long> visibleItemIds) {
events.stream().filter(event -> visibleItemIds.contains(event.getEntityId())) events.stream().filter(event -> visibleItemIds.contains(event.getEntityId()))
.filter(event -> event.getEntity().isComplete()) .filter(DistributionSetUpdatedEvent::isComplete).filter(Objects::nonNull)
.forEach(event -> updateDistributionInTable(event.getEntity())); .forEach(event -> updateDistributionInTable(event.getEntity()));
} }

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.ui.distributions.smtable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@@ -134,13 +135,15 @@ public class SwModuleTable extends AbstractNamedVersionTable<SoftwareModule> {
final List<Long> visibleItemIds = (List<Long>) getVisibleItemIds(); final List<Long> visibleItemIds = (List<Long>) getVisibleItemIds();
handleSelectedAndUpdatedSoftwareModules(eventContainer.getEvents()); handleSelectedAndUpdatedSoftwareModules(eventContainer.getEvents());
eventContainer.getEvents().stream().filter(event -> visibleItemIds.contains(event.getEntityId())) eventContainer.getEvents().stream().filter(event -> visibleItemIds.contains(event.getEntityId()))
.filter(Objects::nonNull)
.forEach(event -> updateSoftwareModuleInTable(event.getEntity())); .forEach(event -> updateSoftwareModuleInTable(event.getEntity()));
} }
private void handleSelectedAndUpdatedSoftwareModules(final List<SoftwareModuleUpdatedEvent> events) { private void handleSelectedAndUpdatedSoftwareModules(final List<SoftwareModuleUpdatedEvent> events) {
manageDistUIState.getLastSelectedSoftwareModule() manageDistUIState.getLastSelectedSoftwareModule()
.ifPresent(lastSelectedModuleId -> events.stream() .ifPresent(lastSelectedModuleId -> events.stream()
.filter(event -> lastSelectedModuleId.equals(event.getEntityId())).findAny() .filter(event -> lastSelectedModuleId.equals(event.getEntityId()))
.filter(Objects::nonNull).findAny()
.ifPresent(lastEvent -> eventBus.publish(this, .ifPresent(lastEvent -> eventBus.publish(this,
new SoftwareModuleEvent(BaseEntityEventType.SELECTED_ENTITY, lastEvent.getEntity())))); new SoftwareModuleEvent(BaseEntityEventType.SELECTED_ENTITY, lastEvent.getEntity()))));
} }

View File

@@ -13,6 +13,7 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -137,31 +138,29 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
updateVisableTableEntries(eventContainer.getEvents(), visibleItemIds); updateVisableTableEntries(eventContainer.getEvents(), visibleItemIds);
} }
final Long lastSelectedDsIdName = managementUIState.getLastSelectedDsIdName(); final Long lastSelectedDsIdName = managementUIState.getLastSelectedDsIdName();
eventContainer.getEvents().stream().filter(event -> event.getEntityId().equals(lastSelectedDsIdName)).findAny() eventContainer.getEvents().stream().filter(event -> event.getEntityId().equals(lastSelectedDsIdName))
.ifPresent(event -> eventBus.publish(this, .filter(Objects::nonNull).findAny().ifPresent(event -> eventBus.publish(this,
new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, event.getEntity()))); new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, event.getEntity())));
} }
private static boolean allOfThemAffectCompletedSetsThatAreNotVisible(final List<DistributionSetUpdatedEvent> events, private static boolean allOfThemAffectCompletedSetsThatAreNotVisible(final List<DistributionSetUpdatedEvent> events,
final List<Long> visibleItemIds) { final List<Long> visibleItemIds) {
return events.stream() return events.stream().allMatch(event -> !visibleItemIds.contains(event.getEntityId()) && event.isComplete());
.allMatch(event -> !visibleItemIds.contains(event.getEntityId()) && event.getEntity().isComplete());
} }
private void updateVisableTableEntries(final List<DistributionSetUpdatedEvent> events, private void updateVisableTableEntries(final List<DistributionSetUpdatedEvent> events,
final List<Long> visibleItemIds) { final List<Long> visibleItemIds) {
events.stream().filter(event -> visibleItemIds.contains(event.getEntityId())) events.stream().filter(event -> visibleItemIds.contains(event.getEntityId()))
.filter(event -> event.getEntity().isComplete()) .filter(DistributionSetUpdatedEvent::isComplete).filter(Objects::nonNull)
.forEach(event -> updateDistributionInTable(event.getEntity())); .forEach(event -> updateDistributionInTable(event.getEntity()));
} }
private boolean checkAndHandleIfVisibleDsSwitchesFromCompleteToIncomplete( private boolean checkAndHandleIfVisibleDsSwitchesFromCompleteToIncomplete(
final List<DistributionSetUpdatedEvent> events, final List<Long> visibleItemIds) { final List<DistributionSetUpdatedEvent> events, final List<Long> visibleItemIds) {
final List<Long> setsThatAreVisibleButNotCompleteAnymore = events.stream() final List<Long> setsThatAreVisibleButNotCompleteAnymore = events.stream()
.filter(event -> visibleItemIds.contains(event.getEntityId())) .filter(event -> visibleItemIds.contains(event.getEntityId())).filter(event -> !event.isComplete())
.filter(event -> !event.getEntity().isComplete()).map(DistributionSetUpdatedEvent::getEntityId) .map(DistributionSetUpdatedEvent::getEntityId).collect(Collectors.toList());
.collect(Collectors.toList());
if (!setsThatAreVisibleButNotCompleteAnymore.isEmpty()) { if (!setsThatAreVisibleButNotCompleteAnymore.isEmpty()) {
refreshContainer(); refreshContainer();

View File

@@ -152,7 +152,7 @@ public class TargetTable extends AbstractTable<Target> {
refreshTargets(); refreshTargets();
} else { } else {
eventContainer.getEvents().stream().filter(event -> visibleItemIds.contains(event.getEntityId())) eventContainer.getEvents().stream().filter(event -> visibleItemIds.contains(event.getEntityId()))
.filter(event -> !Objects.isNull(event.getEntity())) .filter(Objects::nonNull)
.forEach(event -> updateVisibleItemOnEvent(event.getEntity())); .forEach(event -> updateVisibleItemOnEvent(event.getEntity()));
} }
publishTargetSelectedEntityForRefresh(eventContainer.getEvents().stream()); publishTargetSelectedEntityForRefresh(eventContainer.getEvents().stream());
@@ -160,8 +160,8 @@ public class TargetTable extends AbstractTable<Target> {
private void publishTargetSelectedEntityForRefresh( private void publishTargetSelectedEntityForRefresh(
final Stream<? extends RemoteEntityEvent<Target>> targetEntityEventStream) { final Stream<? extends RemoteEntityEvent<Target>> targetEntityEventStream) {
targetEntityEventStream.filter(event -> isLastSelectedTarget(event.getEntityId())).findAny() targetEntityEventStream.filter(event -> isLastSelectedTarget(event.getEntityId()))
.ifPresent(event -> eventBus.publish(this, .filter(Objects::nonNull).findAny().ifPresent(event -> eventBus.publish(this,
new TargetTableEvent(BaseEntityEventType.SELECTED_ENTITY, event.getEntity()))); new TargetTableEvent(BaseEntityEventType.SELECTED_ENTITY, event.getEntity())));
} }