Target attributes update can be (re-)triggered by management API (#690)

* extend Management API with attribute `requestAttributes`
* introduce new DMF Event Topic `REQUEST_ATTRIBUTES_UPDATE`
* enhance REST documentation by new functionality
* add tests for:
  * Management API
  * Amqp Message Dispatcher Service
  * Repository (Target Management)

Signed-off-by: Jeroen Jan Laverman (INST/ESY3) <jeroen.laverman@bosch-si.com>
This commit is contained in:
Jeroen Laverman
2018-06-14 12:48:31 +02:00
committed by Dominic Schabel
parent f4340098d9
commit ecfe774e53
18 changed files with 275 additions and 17 deletions

View File

@@ -109,8 +109,7 @@ public interface TargetManagement {
Long installedOrAssignedDistributionSetId, Boolean selectTargetWithNoTag, String... tagNames);
/**
* Counts number of targets with given
* {@link Target#getInstalledDistributionSet()}.
* Counts number of targets with given with given distribution set Id
*
* @param distId
* to search for
@@ -630,4 +629,25 @@ public interface TargetManagement {
* if target with given ID does not exist
*/
Map<String, String> getControllerAttributes(@NotEmpty String controllerId);
/**
* Trigger given {@link Target} to update its attributes.
*
* @param controllerId
* of the target
*
* @throws EntityNotFoundException
* if target with given ID does not exist
*/
void requestControllerAttributes(@NotEmpty String controllerId);
/**
* Check if update of given {@link Target} attributes is already requested.
*
* @param controllerId
* of target
* @return {@code true}: update of controller attributes triggered.
* {@code false}: update of controller attributes not requested.
*/
boolean isControllerAttributesRequested(@NotEmpty String controllerId);
}

View File

@@ -67,4 +67,10 @@ public interface TargetUpdate {
* @return updated builder instance
*/
TargetUpdate status(@NotNull TargetUpdateStatus status);
/**
* @param requestAttributes for {@link Target#isRequestControllerAttributes()}
* @return updated builder instance
*/
TargetUpdate requestAttributes(Boolean requestAttributes);
}

View File

@@ -0,0 +1,58 @@
/**
* Copyright (c) 2018 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;
import org.eclipse.hawkbit.repository.model.Target;
/**
* Defines the remote event of triggering attribute updates of a {@link Target}.
*/
public class TargetAttributesRequestedEvent extends RemoteIdEvent {
private static final long serialVersionUID = 1L;
private String controllerId;
private String targetAddress;
/**
* Default constructor.
*/
public TargetAttributesRequestedEvent() {
// for serialization libs like jackson
}
/**
* Constructor json serialization
*
* @param tenant
* the tenant
* @param entityId
* the entity id
* @param controllerId
* the controllerId of the target
* @param targetAddress
* the target address
* @param entityClass
* the entity class
* @param applicationId
* the origin application id
*/
public TargetAttributesRequestedEvent(final String tenant, final Long entityId, final String controllerId,
final String targetAddress, final String entityClass, final String applicationId) {
super(entityId, tenant, entityClass, applicationId);
this.controllerId = controllerId;
this.targetAddress = targetAddress;
}
public String getControllerId() {
return controllerId;
}
public String getTargetAddress() {
return targetAddress;
}
}

View File

@@ -34,6 +34,8 @@ public class AbstractTargetUpdateCreate<T> extends AbstractNamedEntityBuilder<T>
protected Long lastTargetQuery;
protected TargetUpdateStatus status;
protected Boolean requestAttributes;
protected AbstractTargetUpdateCreate(final String controllerId) {
this.controllerId = StringUtils.trimWhitespace(controllerId);
}
@@ -62,6 +64,11 @@ public class AbstractTargetUpdateCreate<T> extends AbstractNamedEntityBuilder<T>
return (T) this;
}
public T requestAttributes(final Boolean requestAttributes) {
this.requestAttributes = requestAttributes;
return (T) this;
}
public T lastTargetQuery(final Long lastTargetQuery) {
this.lastTargetQuery = lastTargetQuery;
return (T) this;

View File

@@ -32,6 +32,7 @@ import org.eclipse.hawkbit.repository.TimestampCalculator;
import org.eclipse.hawkbit.repository.builder.TargetCreate;
import org.eclipse.hawkbit.repository.builder.TargetUpdate;
import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetCreate;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetUpdate;
@@ -640,4 +641,24 @@ public class JpaTargetManagement implements TargetManagement {
return target.getControllerAttributes();
}
@Override
public void requestControllerAttributes(final String controllerId) {
final JpaTarget target = (JpaTarget) getByControllerID(controllerId)
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
target.setRequestControllerAttributes(true);
eventPublisher.publishEvent(new TargetAttributesRequestedEvent(tenantAware.getCurrentTenant(), target.getId(),
target.getControllerId(), target.getAddress() != null ? target.getAddress().toString() : null,
JpaTarget.class.getName(), applicationContext.getId()));
}
@Override
public boolean isControllerAttributesRequested(final String controllerId) {
final JpaTarget target = (JpaTarget) getByControllerID(controllerId)
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
return target.isRequestControllerAttributes();
}
}

View File

@@ -178,8 +178,7 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
Page<Target> findByAssignedDistributionSetId(final Pageable pageable, final Long setID);
/**
* Counts number of targets with given
* {@link Target#getAssignedDistributionSet()}.
* Counts number of targets with given distribution set Id.
*
* @param distId
* to search for
@@ -189,8 +188,7 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
Long countByAssignedDistributionSetId(final Long distId);
/**
* Counts number of targets with given
* {@link Target#getInstalledDistributionSet()}.
* Counts number of targets with given distribution set Id.
*
* @param distId
* to search for

View File

@@ -880,4 +880,16 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
final List<Long> collect = foundDs.stream().map(Target::getId).collect(Collectors.toList());
assertThat(collect).containsAll(searchIds);
}
@Test
@Description("Verify that the flag for requesting controller attributes is set correctly.")
public void verifyRequestControllerAttributes() {
final String knownTargetId = "KnownControllerId";
createTargetWithAttributes(knownTargetId);
assertThat(targetManagement.isControllerAttributesRequested(knownTargetId)).isFalse();
targetManagement.requestControllerAttributes(knownTargetId);
assertThat(targetManagement.isControllerAttributesRequested(knownTargetId)).isTrue();
}
}