Удаление множества управляемых объектов, выбранных по имени фрагмента - PullRequest
0 голосов
/ 31 мая 2018

Я хочу удалить много управляемых объектов, выбранных по типу фрагмента.В нем более 2000 элементов.К сожалению, я не могу удалить все одним вызовом функции.Мне приходится вызывать эту функцию много раз, пока я не удалю все.Как я могу удалить список управляемых объектов в достаточной степени?Не определение размера страницы не помогло ...

Это моя текущая функция:

    InventoryFilter filter = new InventoryFilter();
    filter.byFragmentType("xy_fragment");

    ManagedObjectCollection moc = inventoryApi.getManagedObjectsByFilter(filter);

    int count = 0;
    // max page size is 2000
    for (ManagedObjectRepresentation mo : moc.get(2000).allPages()) {
        if (mo.get("c8y_IsBinary") != null) {
            binariesApi.deleteFile(mo.getId());
        } else {
            inventoryApi.delete(mo.getId());
        }

        LOG.debug(count + " remove: " + mo.getName() + ", " + mo.getType());
        count++;
    }

    LOG.info("all objectes removed, count:" + count);

Ответы [ 3 ]

0 голосов
/ 01 июня 2018

Я решил проблему, вызвав метод, пока элементы больше не могут быть найдены.Это нехорошо , но у меня нет другой идеи.

    public synchronized void removeManagedObjects(String deviceTypeKey) {
    int count = 0;
    do {
        count = deleteManagedObjectes(deviceTypeKey);
    }while(count > 0);
}

private int deleteManagedObjectes(String deviceTypeKey) {
    InventoryFilter filter = new InventoryFilter();
    filter.byFragmentType("xy_fragment");

    ManagedObjectCollection moc = inventoryApi.getManagedObjectsByFilter(filter);
    int count = 0;

    if(moc == null) {
        LOG.info("ManagedObjectCollection are NULL");
        return count;
    }

    for (ManagedObjectRepresentation mo : moc.get(2000).allPages()) {
        if (mo.get("c8y_IsBinary") != null) {
            binariesApi.deleteFile(mo.getId());
        } else {
            inventoryApi.delete(mo.getId());
        }

        LOG.debug(count + " remove: " + mo.getName() + ", " + mo.getType());
        count++;
    }

    LOG.info("all objectes removed, count:" + count);
    return count;
}
0 голосов
/ 07 июня 2018

Вызывая moc.get(2000).allPages(), вы уже получаете итератор, который запрашивает следующие страницы по запросу при его итерации по нему.

Проблема, с которой вы сталкиваетесь, связана с удалением элементов из того же списка, по которому вы выполняете итерацию.Вы удаляете элемент с первой страницы, но как только вторая страница запрашивается с сервера, он больше не содержит ожидаемых элементов, поскольку вы уже удалили первую страницу.Теперь все элементы смещены вперед на размер вашей страницы.

Вы можете избежать всего этого, сделав локальную копию всех элементов, которые хотите удалить в первую очередь:

List<ManagedObjectRepresentation> allObjects = Lists.newArrayList( moc.get(2000).allPages())
for (ManagedObjectRepresentation mo : allObjects) {
  //delete here   
}
0 голосов
/ 31 мая 2018

В API инвентаризации не разрешено массовое удаление, поэтому ваш метод циклического перемещения по объектам является правильным подходом.

Массовое удаление уже является опасным инструментом в других API, но в API инвентаризации этодаст вам возможность случайно удалить все ваши данные всего одним вызовом (так как все данные, связанные с managedObject, также удаляются при удалении managedObject).Вот почему это не доступно.

...