@ApiOperation(value = "Create Or update Tenant (saveTenant)",
            notes = "Create or update the Tenant. When creating tenant, platform generates Tenant Id as " + UUID_WIKI_LINK +
                    "Default Rule Chain and Device profile are also generated for the new tenants automatically. " +
                    "The newly created Tenant Id will be present in the response. " +
                    "Specify existing Tenant Id id to update the Tenant. " +
                    "Referencing non-existing Tenant Id will cause 'Not Found' error." +
                    "Remove 'id', 'tenantId' from the request body example (below) to create new Tenant entity." +
                    SYSTEM_AUTHORITY_PARAGRAPH)
    @PreAuthorize("hasAuthority('SYS_ADMIN')")
    @RequestMapping(value = "/tenant", method = RequestMethod.POST)
    @ResponseBody
    public Tenant saveTenant(@Parameter(description = "A JSON value representing the tenant.")
                             @RequestBody Tenant tenant) throws Exception {
        checkEntity(tenant.getId(), tenant, Resource.TENANT);
        return tbTenantService.save(tenant);
    }
@Test
    public void testIsolatedQueueDeletion() throws Exception {
        loginSysAdmin();
        TenantProfile tenantProfile = new TenantProfile();
        tenantProfile.setName("Test profile");
        TenantProfileData tenantProfileData = new TenantProfileData();
        tenantProfileData.setConfiguration(new DefaultTenantProfileConfiguration());
        tenantProfile.setProfileData(tenantProfileData);
        tenantProfile.setIsolatedTbRuleEngine(true);
        addQueueConfig(tenantProfile, MAIN_QUEUE_NAME);
        tenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class);
        createDifferentTenant();
        loginSysAdmin();
        savedDifferentTenant.setTenantProfileId(tenantProfile.getId());
        savedDifferentTenant = saveTenant(savedDifferentTenant);
        TenantId tenantId = differentTenantId;
        await().atMost(30, TimeUnit.SECONDS)
                .until(() -> {
                    TopicPartitionInfo tpi = partitionService.resolve(ServiceType.TB_RULE_ENGINE, MAIN_QUEUE_NAME, tenantId, tenantId);
                    return !tpi.getTenantId().get().isSysTenantId();
                });
        TopicPartitionInfo tpi = new TopicPartitionInfo(MAIN_QUEUE_TOPIC, tenantId, 0, false);
        String isolatedTopic = tpi.getFullTopicName();
        TbMsg expectedMsg = publishTbMsg(tenantId, tpi);
        awaitTbMsg(tbMsg -> tbMsg.getId().equals(expectedMsg.getId()), 10000); // to wait for consumer start

        loginSysAdmin();
        tenantProfile.setIsolatedTbRuleEngine(false);
        tenantProfile.getProfileData().setQueueConfiguration(Collections.emptyList());
        tenantProfile = doPost("/api/tenantProfile", tenantProfile, TenantProfile.class);
        await().atMost(30, TimeUnit.SECONDS)
                .until(() -> partitionService.resolve(ServiceType.TB_RULE_ENGINE, MAIN_QUEUE_NAME, tenantId, tenantId)
                        .getTenantId().get().isSysTenantId());

        List<UUID> submittedMsgs = new ArrayList<>();
        long timeLeft = TimeUnit.SECONDS.toMillis(7); // based on topic-deletion-delay
        int msgs = 100;
        for (int i = 1; i <= msgs; i++) {
            TbMsg tbMsg = publishTbMsg(tenantId, tpi);
            submittedMsgs.add(tbMsg.getId());
            Thread.sleep(timeLeft / msgs);
        }
        await().atMost(30, TimeUnit.SECONDS).untilAsserted(() -> {
            verify(queueAdmin, times(1)).deleteTopic(eq(isolatedTopic));
        });

        await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> {
            for (UUID msgId : submittedMsgs) {
                verify(actorContext).tell(argThat(msg -> {
                    return msg instanceof QueueToRuleEngineMsg && ((QueueToRuleEngineMsg) msg).getMsg().getId().equals(msgId);
                }));
            }
        });
    }