Feature add optional name to thing created (#888)

* First implementation pushed because of debugging purpose

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Add name field and tests regarding name field functionality in THING_CREATED

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* SonarQube realted changes in name field functionality in THING_CREATED

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Add name field and tests regarding name field functionality in UPDATE_ATTRIBUTES

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Adapt documentation due to name field in THING_CREATED and UPDATE_ATTRIBUTES

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Add integration tests regarding name field functionality in THING_CREATED

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Reformat after finding format bug regarding THING_CREATED

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Reformat after finding the real format bug regarding THING_CREATED

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Reformat regarding THING_CREATED

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Use constant in THING_CREATED

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Format in THING_CREATED

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Resolving peer review comments regarding THING_CREATED

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Resolving peer review comments (organize imports) regarding THING_CREATED

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Refactoring regarding THING_CREATED

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Refactoring due to peer review

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Refactoring due to peer review

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Excluding UPDATE_ATTRIBUTES changes and provide functionality of updating the name property in THING_CREATED message

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Refactoring due to peer review

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Refactoring due to peer review

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Fix SonarQube finding

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Merge master into current branch

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>

* Fix peer review findings

Signed-off-by: Ammar Bikic <ammar.bikic@bosch-si.com>
This commit is contained in:
Ammar Bikic
2019-10-24 12:13:35 +02:00
committed by Dominic Schabel
parent b50a82fc0f
commit af0f7ceb5a
10 changed files with 525 additions and 388 deletions

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.amqp;
import static org.eclipse.hawkbit.repository.RepositoryConstants.MAX_ACTION_COUNT;
import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED;
import static org.springframework.util.StringUtils.hasText;
import java.io.Serializable;
import java.net.URI;
@@ -26,6 +27,7 @@ import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
import org.eclipse.hawkbit.dmf.json.model.DmfActionUpdateStatus;
import org.eclipse.hawkbit.dmf.json.model.DmfAttributeUpdate;
import org.eclipse.hawkbit.dmf.json.model.DmfCreateThing;
import org.eclipse.hawkbit.dmf.json.model.DmfUpdateMode;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
@@ -51,6 +53,7 @@ import org.springframework.amqp.AmqpRejectAndDontRequeueException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.MessageConversionException;
import org.springframework.data.domain.PageRequest;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
@@ -84,6 +87,8 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
private static final String THING_ID_NULL = "ThingId is null";
private static final String EMPTY_MESSAGE_BODY = "\"\"";
/**
* Constructor.
*
@@ -122,7 +127,6 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
* the message type
* @param tenant
* the contentType of the message
*
* @return a message if <null> no message is send back to sender
*/
@RabbitListener(queues = "${hawkbit.dmf.rabbitmq.receiverQueue:dmf_receiver}", containerFactory = "listenerContainerFactory")
@@ -198,12 +202,14 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
}
/**
* Method to create a new target or to find the target if it already exists.
* Method to create a new target or to find the target if it already exists and
* update its poll time, status and optionally its name.
*
* @param targetID
* the ID of the target/thing
* @param ip
* the ip of the target/thing
* @param message
* the message that contains replyTo property and optionally the name
* in body
* @param virtualHost
* the virtual host
*/
private void registerTarget(final Message message, final String virtualHost) {
final String thingId = getStringHeaderKey(message, MessageHeaderKey.THING_ID, THING_ID_NULL);
@@ -215,14 +221,29 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
try {
final URI amqpUri = IpUtil.createAmqpUri(virtualHost, replyTo);
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist(thingId, amqpUri);
final Target target;
if (isOptionalMessageBodyEmpty(message)) {
target = controllerManagement.findOrRegisterTargetIfItDoesNotExist(thingId, amqpUri);
} else {
checkContentTypeJson(message);
target = controllerManagement.findOrRegisterTargetIfItDoesNotExist(thingId, amqpUri, convertMessage(message, DmfCreateThing.class).getName());
}
LOG.debug("Target {} reported online state.", thingId);
sendUpdateCommandToTarget(target);
} catch (EntityAlreadyExistsException e) {
throw new AmqpRejectAndDontRequeueException("Target already registered, message will be ignored!", e);
} catch (final EntityAlreadyExistsException e) {
throw new AmqpRejectAndDontRequeueException(
"Tried to register previously registered target, message will be ignored!", e);
}
}
private static boolean isOptionalMessageBodyEmpty(final Message message) {
// empty byte array message body is serialized to double-quoted string
// by message converter and should also be considered as empty
return isMessageBodyEmpty(message) || EMPTY_MESSAGE_BODY.equals(new String(message.getBody()));
}
private void sendUpdateCommandToTarget(final Target target) {
if (isMultiAssignmentsEnabled()) {
sendCurrentActionsAsMultiActionToTarget(target);

View File

@@ -69,7 +69,7 @@ public class BaseAmqpService {
return rabbitTemplate.getMessageConverter();
}
private static boolean isMessageBodyEmpty(final Message message) {
protected static boolean isMessageBodyEmpty(final Message message) {
return message.getBody() == null || message.getBody().length == 0;
}