/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package com.emc.vipr.client.core; import static com.emc.vipr.client.core.util.ResourceUtils.refIds; import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.List; import com.emc.storageos.model.BulkIdParam; import com.emc.storageos.model.DataObjectRestRep; import com.emc.storageos.model.RelatedResourceRep; import com.emc.vipr.client.core.filters.ResourceFilter; import com.emc.vipr.client.core.impl.PathConstants; import com.emc.vipr.client.impl.RestClient; /** * Base class for all resources types that support bulk operations. This overrides the {@link #getByIds(Collection, ResourceFilter)} method * to query through the bulk API for improved performance. * * @param <T> * the type of resource. */ public abstract class AbstractBulkResources<T extends DataObjectRestRep> extends AbstractResources<T> implements BulkResources<T> { public AbstractBulkResources(RestClient client, Class<T> resourceClass, String baseUrl) { super(client, resourceClass, baseUrl); } /** * Gets the URL for bulk queries: <tt><i>baseUrl</i>/bulk</tt> * * @return the bulk URL. */ protected String getBulkUrl() { return String.format(PathConstants.BULK_URL_FORMAT, baseUrl); } protected String getSearchUrl() { return String.format(PathConstants.SEARCH_URL_FORMAT, baseUrl); } @Override public List<URI> listBulkIds() { BulkIdParam response = client.get(BulkIdParam.class, getBulkUrl()); return response.getIds(); } @Override public List<T> getByIds(Collection<URI> ids, ResourceFilter<T> filter) { List<T> results = new ArrayList<T>(); if (ids != null) { BulkIdParam input = new BulkIdParam(); for (URI id : ids) { addId(id, input, filter, results); } if (!input.getIds().isEmpty()) { fetchChunk(input, filter, results); } } return results; } @Override public List<T> getByRefs(Collection<? extends RelatedResourceRep> refs, ResourceFilter<T> filter) { return getByIds(refIds(refs), filter); } /** * Adds an ID to the bulk input. If the fetch limit is reached, a chunk will be fetched and the input will be * cleared. * * @param id * the ID to add. * @param input * the bulk input. * @param filter * the filter to apply (may be null, for no filtering). * @param results * the result list to add to if a chunk is fetched. */ private void addId(URI id, BulkIdParam input, ResourceFilter<T> filter, List<T> results) { if ((filter == null) || filter.acceptId(id)) { input.getIds().add(id); } if (input.getIds().size() >= client.getConfig().getBulkSize()) { fetchChunk(input, filter, results); input.getIds().clear(); } } /** * Fetches a chunk and filters (if required). * * @param input * the bulk input. * @param filter * the filter to apply (may be null, for no filtering). * @param results * the result list to add to. */ private void fetchChunk(BulkIdParam input, ResourceFilter<T> filter, List<T> results) { List<T> items = getBulkResources(input); for (T item : items) { if (accept(item, filter)) { results.add(item); } } } /** * Performs a bulk fetch of the IDs in the input. * * @param input * the bulk input. * @return the results. */ protected abstract List<T> getBulkResources(BulkIdParam input); }