@Override
    public void onMsg(TbContext ctx, TbMsg msg) {
        ListenableFuture<Boolean> deleteResultFuture = config.isDeleteForSingleEntity() ?
                Futures.transformAsync(getTargetEntityId(ctx, msg), targetEntityId ->
                        deleteRelationToSpecificEntity(ctx, msg, targetEntityId), MoreExecutors.directExecutor()) :
                deleteRelationsByTypeAndDirection(ctx, msg, ctx.getDbCallbackExecutor());
        withCallback(deleteResultFuture, deleted -> {
                    if (deleted) {
                        ctx.tellSuccess(msg);
                        return;
                    }
                    ctx.tellFailure(msg, new RuntimeException("Failed to delete relation(s) with originator!"));
                },
                t -> ctx.tellFailure(msg, t), MoreExecutors.directExecutor());
    }
@Test
    void givenSupportedEntityType_whenOnMsgAndDeleteForSingleEntityIsFalse_thenVerifyRelationFailedToDeleteAndOutMsgFailure() throws TbNodeException {
        // GIVEN
        config.setEntityType(EntityType.DEVICE);
        config.setEntityNamePattern("${name}");
        config.setEntityTypePattern("${type}");

        var nodeConfiguration = new TbNodeConfiguration(JacksonUtil.valueToTree(config));
        node.init(ctxMock, nodeConfiguration);

        when(ctxMock.getTenantId()).thenReturn(tenantId);
        when(ctxMock.getRelationService()).thenReturn(relationServiceMock);
        when(ctxMock.getDbCallbackExecutor()).thenReturn(dbExecutor);

        var relationToDelete = new EntityRelation();
        when(relationServiceMock.findByFromAndTypeAsync(any(), any(), any(), any())).thenReturn(Futures.immediateFuture(List.of(relationToDelete)));
        when(relationServiceMock.deleteRelationAsync(any(), any())).thenReturn(Futures.immediateFuture(false));

        var md = getMetadataWithNameTemplate();
        var msg = getTbMsg(originatorId, md);

        // WHEN
        node.onMsg(ctxMock, msg);

        verify(relationServiceMock).findByFromAndTypeAsync(eq(tenantId), eq(originatorId), eq(EntityRelation.CONTAINS_TYPE), eq(RelationTypeGroup.COMMON));
        verify(relationServiceMock).deleteRelationAsync(eq(tenantId), eq(relationToDelete));

        var throwableCaptor = ArgumentCaptor.forClass(Throwable.class);
        verify(ctxMock).tellFailure(eq(msg), throwableCaptor.capture());
        verify(ctxMock, never()).tellNext(any(), anyString());
        verify(ctxMock, never()).tellNext(any(), anySet());
        verify(ctxMock, never()).tellSuccess(any());
        verifyNoMoreInteractions(ctxMock, relationServiceMock);
        assertThat(throwableCaptor.getValue()).isInstanceOf(RuntimeException.class).hasMessage("Failed to delete relation(s) with originator!");
    }