Software module metadata available to targets (in DMF and DDI) (#608)

* Software module metadata can be configure as target visible.

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

* Added metadata to DDI.

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

* Managed by UI.

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

* Complete DMF integration and started UI.

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

* Add DMF tests and completed UI.

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

* Add RSQL test. Fix sonar issues.

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

* Add JavaDocs. foreachtenant robustness.

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

* Review feedback included.

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

* Updated DMF docs.

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

* targetVisible optional in builder.

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

* Fix typos.

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

* Fix checkbox ID.

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

* DB optimization.

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

* Fix component ID of sm metadat details tab.

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2017-12-16 17:17:54 +01:00
committed by GitHub
parent c3035231e2
commit 80d9f1b8fc
108 changed files with 1883 additions and 917 deletions

View File

@@ -34,6 +34,7 @@ import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
import org.eclipse.hawkbit.dmf.json.model.DmfDownloadAndUpdateRequest;
import org.eclipse.hawkbit.dmf.json.model.DmfMetadata;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
@@ -46,6 +47,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TenantMetaData;
import org.eclipse.hawkbit.repository.test.util.AbstractIntegrationTest;
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
import org.eclipse.hawkbit.util.IpUtil;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@@ -109,7 +111,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
amqpMessageDispatcherService = new AmqpMessageDispatcherService(rabbitTemplate, senderService,
artifactUrlHandlerMock, systemSecurityContext, systemManagement, targetManagement, serviceMatcher,
distributionSetManagement);
distributionSetManagement, softwareModuleManagement);
}
@@ -129,6 +131,8 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
public void testSendDownloadRequesWithSoftwareModulesAndNoArtifacts() {
final DistributionSet createDistributionSet = testdataFactory
.createDistributionSet(UUID.randomUUID().toString());
testdataFactory.addSoftwareModuleMetadata(createDistributionSet);
final Action action = createAction(createDistributionSet);
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
@@ -142,6 +146,10 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
for (final org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule softwareModule : downloadAndUpdateRequest
.getSoftwareModules()) {
assertTrue("Artifact list for softwaremodule should be empty", softwareModule.getArtifacts().isEmpty());
assertThat(softwareModule.getMetadata()).containsExactly(
new DmfMetadata(TestdataFactory.VISIBLE_SM_MD_KEY, TestdataFactory.VISIBLE_SM_MD_VALUE));
for (final SoftwareModule softwareModule2 : action.getDistributionSet().getModules()) {
assertNotNull("Sofware module ID should be set", softwareModule.getModuleId());
if (!softwareModule.getModuleId().equals(softwareModule2.getId())) {

View File

@@ -22,7 +22,6 @@ import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
@@ -421,7 +420,7 @@ public class AmqpMessageHandlerServiceTest {
final ArgumentCaptor<Long> actionIdCaptor = ArgumentCaptor.forClass(Long.class);
verify(amqpMessageDispatcherServiceMock, times(1)).sendUpdateMessageToTarget(tenantCaptor.capture(),
targetCaptor.capture(), actionIdCaptor.capture(), any(Collection.class));
targetCaptor.capture(), actionIdCaptor.capture(), any(Map.class));
final String tenant = tenantCaptor.getValue();
final String controllerId = targetCaptor.getValue().getControllerId();
final Long actionId = actionIdCaptor.getValue();

View File

@@ -20,6 +20,7 @@ import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -45,6 +46,7 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
public void sendDownloadAndInstallStatus() {
@@ -63,6 +65,7 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
@Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = ActionUpdatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 3) })
public void assignDistributionSetMultipleTimes() {
@@ -88,6 +91,7 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AmqpServiceInte
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
@Expect(type = ActionUpdatedEvent.class, count = 1), @Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
public void sendCancelStatus() {

View File

@@ -30,6 +30,7 @@ import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.model.Action.Status;
@@ -363,6 +364,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionUpdatedEvent.class, count = 1), @Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
public void finishActionStatus() {
@@ -376,6 +378,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionUpdatedEvent.class, count = 0), @Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
public void runningActionStatus() {
@@ -389,6 +392,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
public void downloadActionStatus() {
@@ -402,6 +406,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionUpdatedEvent.class, count = 1), @Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 2), @Expect(type = TargetPollEvent.class, count = 1) })
public void errorActionStatus() {
@@ -415,6 +420,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
public void warningActionStatus() {
@@ -428,6 +434,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
public void retrievedActionStatus() {
@@ -441,6 +448,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
public void cancelNotAllowActionStatus() {
@@ -455,6 +463,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 2) })
public void receiveDownLoadAndInstallMessageAfterAssignment() {
@@ -463,6 +472,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
// setup
createAndSendTarget(controllerId, TENANT_EXIST);
final DistributionSet distributionSet = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
testdataFactory.addSoftwareModuleMetadata(distributionSet);
assignDistributionSet(distributionSet.getId(), controllerId);
// test
@@ -507,6 +517,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionUpdatedEvent.class, count = 1), @Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
@@ -526,6 +537,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
public void canceledRejectedNotAllowActionStatus() {
@@ -541,6 +553,7 @@ public class AmqpMessageHandlerServiceIntegrationTest extends AmqpServiceIntegra
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
@Expect(type = ActionUpdatedEvent.class, count = 1), @Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
public void canceledRejectedActionStatus() {

View File

@@ -24,6 +24,7 @@ import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
import org.eclipse.hawkbit.dmf.json.model.DmfAttributeUpdate;
import org.eclipse.hawkbit.dmf.json.model.DmfDownloadAndUpdateRequest;
import org.eclipse.hawkbit.dmf.json.model.DmfMetadata;
import org.eclipse.hawkbit.integration.listener.DeadletterListener;
import org.eclipse.hawkbit.integration.listener.ReplyToListener;
import org.eclipse.hawkbit.matcher.SoftwareModuleJsonMatcher;
@@ -35,6 +36,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
import org.eclipse.hawkbit.util.IpUtil;
import org.junit.Assert;
import org.junit.Before;
@@ -107,6 +109,8 @@ public abstract class AmqpServiceIntegrationTest extends AbstractAmqpIntegration
protected DistributionSetAssignmentResult registerTargetAndAssignDistributionSet(final String controllerId) {
distributionSet = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
testdataFactory.addSoftwareModuleMetadata(distributionSet);
return registerTargetAndAssignDistributionSet(distributionSet.getId(), TargetUpdateStatus.REGISTERED,
distributionSet.getModules(), controllerId);
}
@@ -165,6 +169,10 @@ public abstract class AmqpServiceIntegrationTest extends AbstractAmqpIntegration
Assert.assertThat(dsModules,
SoftwareModuleJsonMatcher.containsExactly(downloadAndUpdateRequest.getSoftwareModules()));
downloadAndUpdateRequest.getSoftwareModules()
.forEach(dmfModule -> assertThat(dmfModule.getMetadata()).containsExactly(
new DmfMetadata(TestdataFactory.VISIBLE_SM_MD_KEY, TestdataFactory.VISIBLE_SM_MD_VALUE)));
final Target updatedTarget = waitUntilIsPresent(() -> targetManagement.getByControllerID(controllerId));
assertThat(updatedTarget.getSecurityToken()).isEqualTo(downloadAndUpdateRequest.getTargetSecurityToken());

View File

@@ -12,6 +12,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
@@ -44,21 +45,19 @@ public final class SoftwareModuleJsonMatcher {
* the json sofware modules.
*/
@Factory
public static SoftwareModulesMatcher containsExactly(
final List<org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule> expectedModules) {
public static SoftwareModulesMatcher containsExactly(final List<DmfSoftwareModule> expectedModules) {
return new SoftwareModulesMatcher(expectedModules);
}
private static class SoftwareModulesMatcher extends BaseMatcher<Set<SoftwareModule>> {
private final List<org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule> expectedModules;
private final List<DmfSoftwareModule> expectedModules;
public SoftwareModulesMatcher(List<org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule> expectedModules) {
public SoftwareModulesMatcher(final List<DmfSoftwareModule> expectedModules) {
this.expectedModules = expectedModules;
}
static boolean containsExactly(Object actual,
List<org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule> expected) {
static boolean containsExactly(final Object actual, final List<DmfSoftwareModule> expected) {
if (actual == null) {
return expected == null;
}
@@ -73,7 +72,7 @@ public final class SoftwareModuleJsonMatcher {
for (final SoftwareModule repoSoftwareModule : modules) {
boolean containsElement = false;
for (final org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule jsonSoftwareModule : expected) {
for (final DmfSoftwareModule jsonSoftwareModule : expected) {
if (!jsonSoftwareModule.getModuleId().equals(repoSoftwareModule.getId())) {
continue;
}
@@ -100,12 +99,12 @@ public final class SoftwareModuleJsonMatcher {
}
@Override
public boolean matches(Object actualValue) {
public boolean matches(final Object actualValue) {
return containsExactly(actualValue, expectedModules);
}
@Override
public void describeTo(Description description) {
public void describeTo(final Description description) {
description.appendValue(expectedModules);
}
}