AmqpMessageHandlerService extends BaseAmqpService { @RabbitListener(queues = "${hawkbit.dmf.rabbitmq.receiverQueue:dmf_receiver}", containerFactory = "listenerContainerFactory") public Message onMessage(final Message message, @Header(name = MessageHeaderKey.TYPE, required = false) final String type, @Header(name = MessageHeaderKey.TENANT, required = false) final String tenant) { return onMessage(message, type, tenant, getRabbitTemplate().getConnectionFactory().getVirtualHost()); } AmqpMessageHandlerService(final RabbitTemplate rabbitTemplate,
            final AmqpMessageDispatcherService amqpMessageDispatcherService,
            final ControllerManagement controllerManagement, final EntityFactory entityFactory,
            final SystemSecurityContext systemSecurityContext,
            final TenantConfigurationManagement tenantConfigurationManagement); @RabbitListener(queues = "${hawkbit.dmf.rabbitmq.receiverQueue:dmf_receiver}", containerFactory = "listenerContainerFactory") Message onMessage(final Message message,
            @Header(name = MessageHeaderKey.TYPE, required = false) final String type,
            @Header(name = MessageHeaderKey.TENANT, required = false) final String tenant); Message onMessage(final Message message, final String type, final String tenant, final String virtualHost); void setControllerManagement(final ControllerManagement controllerManagement);  }
@Test @Description("Tests not allowed content-type in message") public void wrongContentType() { final MessageProperties messageProperties = new MessageProperties(); messageProperties.setContentType("xml"); final Message message = new Message(new byte[0], messageProperties); assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to wrong content type") .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, VIRTUAL_HOST)); }
@Test @Description("Tests the creation of a target/thing by calling the same method that incoming RabbitMQ messages would access.") public void createThing() { final String knownThingId = "1"; final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED); messageProperties.setHeader(MessageHeaderKey.THING_ID, "1"); final Message message = messageConverter.toMessage(new byte[0], messageProperties); final Target targetMock = mock(Target.class); final ArgumentCaptor<String> targetIdCaptor = ArgumentCaptor.forClass(String.class); final ArgumentCaptor<URI> uriCaptor = ArgumentCaptor.forClass(URI.class); when(controllerManagementMock.findOrRegisterTargetIfItDoesNotExist(targetIdCaptor.capture(), uriCaptor.capture())).thenReturn(targetMock); when(controllerManagementMock.findActiveActionWithHighestWeight(any())).thenReturn(Optional.empty()); amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, VIRTUAL_HOST); assertThat(targetIdCaptor.getValue()).as("Thing id is wrong").isEqualTo(knownThingId); assertThat(uriCaptor.getValue().toString()).as("Uri is not right") .isEqualTo("amqp: }
@Test @Description("Tests the creation of a target/thing with specified name by calling the same method that incoming RabbitMQ messages would access.") public void createThingWithName() { final String knownThingId = "2"; final DmfCreateThing targetProperties = new DmfCreateThing(); targetProperties.setName("NonDefaultTargetName"); final Target targetMock = mock(Target.class); targetIdCaptor = ArgumentCaptor.forClass(String.class); uriCaptor = ArgumentCaptor.forClass(URI.class); final ArgumentCaptor<String> targetNameCaptor = ArgumentCaptor.forClass(String.class); when(controllerManagementMock.findOrRegisterTargetIfItDoesNotExist(targetIdCaptor.capture(), uriCaptor.capture(), targetNameCaptor.capture())).thenReturn(targetMock); when(controllerManagementMock.findActiveActionWithHighestWeight(any())).thenReturn(Optional.empty()); amqpMessageHandlerService.onMessage( createMessage(targetProperties, getThingCreatedMessageProperties(knownThingId)), MessageType.THING_CREATED.name(), TENANT, "vHost"); assertThat(targetIdCaptor.getValue()).as("Thing id is wrong").isEqualTo(knownThingId); assertThat(uriCaptor.getValue().toString()).as("Uri is not right").isEqualTo("amqp: assertThat(targetNameCaptor.getValue()).as("Thing name is not right").isEqualTo(targetProperties.getName()); }
@Test @Description("Tests not allowed body in message") public void createThingWithWrongBody() { final String knownThingId = "3"; assertThatExceptionOfType(MessageConversionException.class) .as("MessageConversionException was excepeted due to wrong body") .isThrownBy(() -> amqpMessageHandlerService.onMessage( createMessage("Not allowed Body".getBytes(), getThingCreatedMessageProperties(knownThingId)), MessageType.THING_CREATED.name(), TENANT, VIRTUAL_HOST)); }
@Test @Description("Verifies that the update mode is retrieved from the UPDATE_ATTRIBUTES message and passed to the controller management.") public void attributeUpdateModes() { final String knownThingId = "1"; final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT); messageProperties.setHeader(MessageHeaderKey.THING_ID, knownThingId); messageProperties.setHeader(MessageHeaderKey.TOPIC, "UPDATE_ATTRIBUTES"); final DmfAttributeUpdate attributeUpdate = new DmfAttributeUpdate(); attributeUpdate.getAttributes().put("testKey1", "testValue1"); attributeUpdate.getAttributes().put("testKey2", "testValue2"); when(controllerManagementMock.updateControllerAttributes(targetIdCaptor.capture(), attributesCaptor.capture(), modeCaptor.capture())).thenReturn(null); Message message = amqpMessageHandlerService.getMessageConverter().toMessage(attributeUpdate, messageProperties); amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, VIRTUAL_HOST); assertThat(modeCaptor.getValue()).isNull(); attributeUpdate.setMode(DmfUpdateMode.MERGE); message = amqpMessageHandlerService.getMessageConverter().toMessage(attributeUpdate, messageProperties); amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, VIRTUAL_HOST); assertThat(modeCaptor.getValue()).isEqualTo(UpdateMode.MERGE); attributeUpdate.setMode(DmfUpdateMode.REPLACE); message = amqpMessageHandlerService.getMessageConverter().toMessage(attributeUpdate, messageProperties); amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, VIRTUAL_HOST); assertThat(modeCaptor.getValue()).isEqualTo(UpdateMode.REPLACE); attributeUpdate.setMode(DmfUpdateMode.REMOVE); message = amqpMessageHandlerService.getMessageConverter().toMessage(attributeUpdate, messageProperties); amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, VIRTUAL_HOST); assertThat(modeCaptor.getValue()).isEqualTo(UpdateMode.REMOVE); }
@Test @Description("Tests the creation of a thing without a 'reply to' header in message.") public void createThingWithoutReplyTo() { final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED, null); messageProperties.setHeader(MessageHeaderKey.THING_ID, "1"); final Message message = messageConverter.toMessage("", messageProperties); assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no replyTo header was set") .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, VIRTUAL_HOST)); }
@Test @Description("Tests the creation of a target/thing without a thingID by calling the same method that incoming RabbitMQ messages would access.") public void createThingWithoutID() { final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED); final Message message = messageConverter.toMessage(new byte[0], messageProperties); assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no thingId was set") .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, VIRTUAL_HOST)); }
@Test @Description("Tests the call of the same method that incoming RabbitMQ messages would access with an unknown message type.") public void unknownMessageType() { final String type = "bumlux"; final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED); messageProperties.setHeader(MessageHeaderKey.THING_ID, ""); final Message message = messageConverter.toMessage(new byte[0], messageProperties); assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to unknown message type") .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, type, TENANT, VIRTUAL_HOST)); }
@Test @Description("Tests a invalid message without event topic") public void invalidEventTopic() { final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT); final Message message = new Message(new byte[0], messageProperties); assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to unknown message type").isThrownBy( () -> amqpMessageHandlerService.onMessage(message, "unknownMessageType", TENANT, VIRTUAL_HOST)); messageProperties.setHeader(MessageHeaderKey.TOPIC, "wrongTopic"); assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "due to unknown topic").isThrownBy(() -> amqpMessageHandlerService .onMessage(message, MessageType.EVENT.name(), TENANT, VIRTUAL_HOST)); messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.CANCEL_DOWNLOAD.name()); assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "because there was no event topic") .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, VIRTUAL_HOST)); }
@Test @Description("Tests the update of an action of a target without a exist action id") public void updateActionStatusWithoutActionId() { when(controllerManagementMock.findActionWithDetails(anyLong())).thenReturn(Optional.empty()); final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT); messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name()); final DmfActionUpdateStatus actionUpdateStatus = new DmfActionUpdateStatus(1L, DmfActionStatus.DOWNLOAD); final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(actionUpdateStatus, messageProperties); assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no action id was set") .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, VIRTUAL_HOST)); }
@Test @Description("Tests the update of an action of a target without a exist action id") public void updateActionStatusWithoutExistActionId() { final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT); messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name()); when(controllerManagementMock.findActionWithDetails(anyLong())).thenReturn(Optional.empty()); final DmfActionUpdateStatus actionUpdateStatus = createActionUpdateStatus(DmfActionStatus.DOWNLOAD); final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(actionUpdateStatus, messageProperties); assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no action id was set") .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, VIRTUAL_HOST)); }
@Test @Description("Tests TODO") public void lookupNextUpdateActionAfterFinished() throws IllegalAccessException { final Action action = createActionWithTarget(22L, Status.FINISHED); when(controllerManagementMock.findActionWithDetails(anyLong())).thenReturn(Optional.of(action)); when(controllerManagementMock.addUpdateActionStatus(any())).thenReturn(action); final ActionStatusBuilder builder = mock(ActionStatusBuilder.class); final ActionStatusCreate create = mock(ActionStatusCreate.class); when(builder.create(22L)).thenReturn(create); when(create.status(any())).thenReturn(create); when(entityFactoryMock.actionStatus()).thenReturn(builder); when(controllerManagementMock.findActiveActionWithHighestWeight(any())) .thenReturn(Optional.of(action)); final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT); messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name()); final DmfActionUpdateStatus actionUpdateStatus = createActionUpdateStatus(DmfActionStatus.FINISHED, 23L); final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(actionUpdateStatus, messageProperties); amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, VIRTUAL_HOST); final ArgumentCaptor<ActionProperties> actionPropertiesCaptor = ArgumentCaptor.forClass(ActionProperties.class); final ArgumentCaptor<Target> targetCaptor = ArgumentCaptor.forClass(Target.class); verify(amqpMessageDispatcherServiceMock, times(1)).sendUpdateMessageToTarget(actionPropertiesCaptor.capture(), targetCaptor.capture(), any(Map.class)); final ActionProperties actionProperties = actionPropertiesCaptor.getValue(); assertThat(actionProperties).isNotNull(); assertThat(actionProperties.getTenant()).as("event has tenant").isEqualTo("DEFAULT"); assertThat(targetCaptor.getValue().getControllerId()).as("event has wrong controller id").isEqualTo("target1"); assertThat(actionProperties.getId()).as("event has wrong action id").isEqualTo(22L); }
@Test @Description("Tests the deletion of a target/thing, requested by the target itself.") public void deleteThing() { final String knownThingId = "1"; final MessageProperties messageProperties = createMessageProperties(MessageType.THING_REMOVED); messageProperties.setHeader(MessageHeaderKey.THING_ID, knownThingId); final Message message = messageConverter.toMessage(new byte[0], messageProperties); amqpMessageHandlerService.onMessage(message, MessageType.THING_REMOVED.name(), TENANT, VIRTUAL_HOST); verify(controllerManagementMock).deleteExistingTarget(knownThingId); }
@Test @Description("Tests the deletion of a target/thing with missing thingId") public void deleteThingWithoutThingId() { final MessageProperties messageProperties = createMessageProperties(MessageType.THING_REMOVED); final Message message = messageConverter.toMessage(new byte[0], messageProperties); assertThatExceptionOfType(AmqpRejectAndDontRequeueException.class) .as(FAIL_MESSAGE_AMQP_REJECT_REASON + "since no thingId was set") .isThrownBy(() -> amqpMessageHandlerService.onMessage(message, MessageType.THING_REMOVED.name(), TENANT, VIRTUAL_HOST)); }