@ApiOperation(value = "Get Customer Entity Views (getCustomerEntityViews)",
            notes = "Returns a page of Entity View objects assigned to customer. " +
                    PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH)
    @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
    @RequestMapping(value = "/customer/{customerId}/entityViews", params = {"pageSize", "page"}, method = RequestMethod.GET)
    @ResponseBody
    public PageData<EntityView> getCustomerEntityViews(
            @Parameter(description = CUSTOMER_ID_PARAM_DESCRIPTION, required = true)
            @PathVariable(CUSTOMER_ID) String strCustomerId,
            @Parameter(description = PAGE_SIZE_DESCRIPTION, required = true)
            @RequestParam int pageSize,
            @Parameter(description = PAGE_NUMBER_DESCRIPTION, required = true)
            @RequestParam int page,
            @Parameter(description = ENTITY_VIEW_TYPE)
            @RequestParam(required = false) String type,
            @Parameter(description = ENTITY_VIEW_TEXT_SEARCH_DESCRIPTION)
            @RequestParam(required = false) String textSearch,
            @Parameter(description = SORT_PROPERTY_DESCRIPTION, schema = @Schema(allowableValues = {"createdTime", "name", "type"}))
            @RequestParam(required = false) String sortProperty,
            @Parameter(description = SORT_ORDER_DESCRIPTION, schema = @Schema(allowableValues = {"ASC", "DESC"}))
            @RequestParam(required = false) String sortOrder) throws ThingsboardException {
        checkParameter(CUSTOMER_ID, strCustomerId);
        TenantId tenantId = getCurrentUser().getTenantId();
        CustomerId customerId = new CustomerId(toUUID(strCustomerId));
        checkCustomerId(customerId, Operation.READ);
        PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
        if (type != null && type.trim().length() > 0) {
            return checkNotNull(entityViewService.findEntityViewsByTenantIdAndCustomerIdAndType(tenantId, customerId, pageLink, type));
        } else {
            return checkNotNull(entityViewService.findEntityViewsByTenantIdAndCustomerId(tenantId, customerId, pageLink));
        }
    }
@Test
    public void testGetCustomerEntityViews() throws Exception {
        Customer customer = doPost("/api/customer", getNewCustomer("Test customer"), Customer.class);
        CustomerId customerId = customer.getId();
        String urlTemplate = "/api/customer/" + customerId.getId().toString() + "/entityViewInfos?";

        Mockito.reset(tbClusterService, auditLogService);

        int cntEntity = 128;
        List<ListenableFuture<EntityViewInfo>> viewFutures = new ArrayList<>(cntEntity);
        for (int i = 0; i < cntEntity; i++) {
            String entityName = "Test entity view " + i;
            viewFutures.add(executor.submit(() ->
                    new EntityViewInfo(doPost("/api/customer/" + customerId.getId().toString() + "/entityView/"
                            + getNewSavedEntityView(entityName).getId().getId().toString(), EntityView.class),
                            customer.getTitle(), customer.isPublic())));
        }
        List<EntityViewInfo> entityViewInfos = Futures.allAsList(viewFutures).get(TIMEOUT, SECONDS);
        List<EntityViewInfo> loadedViews = loadListOfInfo(new PageLink(23), urlTemplate);

        assertThat(entityViewInfos).containsExactlyInAnyOrderElementsOf(loadedViews);

        testNotifyEntityBroadcastEntityStateChangeEventMany(new EntityView(), new EntityView(),
                tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL,
                ActionType.ADDED, ActionType.ADDED, cntEntity, cntEntity, cntEntity * 2, 0);

        testNotifyEntityBroadcastEntityStateChangeEventMany(new EntityView(), new EntityView(),
                tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL,
                ActionType.ASSIGNED_TO_CUSTOMER, ActionType.UPDATED, cntEntity, cntEntity,
                cntEntity * 2, 3);
    }