package alien4cloud.rest.quicksearch; import java.util.Map; import java.util.Set; import javax.annotation.Resource; import io.swagger.annotations.Api; import org.apache.commons.lang3.ArrayUtils; import org.elasticsearch.index.query.FilterBuilder; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import alien4cloud.dao.ElasticSearchDAO; import alien4cloud.dao.IGenericSearchDAO; import alien4cloud.dao.model.FetchContext; import alien4cloud.dao.model.GetMultipleDataResult; import alien4cloud.model.application.Application; import org.alien4cloud.tosca.model.types.NodeType; import alien4cloud.rest.model.BasicSearchRequest; import alien4cloud.rest.model.RestResponse; import alien4cloud.rest.model.RestResponseBuilder; import alien4cloud.security.AuthorizationUtil; import alien4cloud.security.model.Role; import com.google.common.collect.Sets; import io.swagger.annotations.ApiOperation; /** * Handle Quick Search requests. * * @author 'Igor Ngouagna' */ @RestController @RequestMapping({"/rest/quicksearch", "/rest/v1/quicksearch", "/rest/latest/quicksearch"}) @Api public class QuickSearchController { @Resource(name = "alien-es-dao") private IGenericSearchDAO alienDAO; @ApiOperation(value = "Search for applications or tosca elements in ALIEN's repository.") @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @PreAuthorize("isAuthenticated()") public RestResponse<GetMultipleDataResult> search(@RequestBody BasicSearchRequest requestObject) { Set<String> authoIndexes = Sets.newHashSet(); Set<Class<?>> classes = Sets.newHashSet(); // First phase : COMPONENTS search, needed role Role.COMPONENTS_BROWSER or Role.ADMIN if (AuthorizationUtil.hasOneRoleIn(Role.COMPONENTS_BROWSER)) { authoIndexes.add(ElasticSearchDAO.TOSCA_ELEMENT_INDEX); classes.add(NodeType.class); } GetMultipleDataResult searchResultComponents = searchByType(requestObject, authoIndexes, classes, null, null); // Second phase : APPLICATION search (with rights filter) or with the Role.ADMIN authoIndexes.clear(); classes.clear(); authoIndexes.add(Application.class.getSimpleName().toLowerCase()); classes.add(Application.class); // Adding filters to get only authorized applications // only filter on users roles on the application if the current user is not an ADMIN FilterBuilder authorizationFilter = AuthorizationUtil.getResourceAuthorizationFilters(); GetMultipleDataResult<?> searchResultApplications = searchByType(requestObject, authoIndexes, classes, null, authorizationFilter); // Final merge result : COMPONENTS + APPLICATIONS GetMultipleDataResult searchResult = new GetMultipleDataResult(); searchResult.setQueryDuration(searchResultComponents.getQueryDuration() + searchResultApplications.getQueryDuration()); searchResult.setTypes(ArrayUtils.addAll(searchResultComponents.getTypes(), searchResultApplications.getTypes())); searchResult.setData(ArrayUtils.addAll(searchResultComponents.getData(), searchResultApplications.getData())); searchResult.setTotalResults(searchResultComponents.getTotalResults() + searchResultApplications.getTotalResults()); return RestResponseBuilder.<GetMultipleDataResult> builder().data(searchResult).build(); } private GetMultipleDataResult searchByType(BasicSearchRequest requestObject, Set<String> authoIndexes, Set<Class<?>> classes, Map<String, String[]> filters, FilterBuilder filterBuilder) { String[] indices = authoIndexes.toArray(new String[authoIndexes.size()]); if (indices.length == 0) { return new GetMultipleDataResult(); } Class<?>[] classesArray = classes.toArray(new Class<?>[classes.size()]); GetMultipleDataResult searchResult = alienDAO.search(indices, classesArray, requestObject.getQuery(), filters, filterBuilder, FetchContext.QUICK_SEARCH, requestObject.getFrom(), requestObject.getSize()); return searchResult; } }