package org.alien4cloud.tosca.catalog.index;
import static alien4cloud.dao.FilterUtil.fromKeyValueCouples;
import static alien4cloud.utils.AlienUtils.safe;
import java.util.Collection;
import java.util.Map;
import javax.annotation.Resource;
import javax.inject.Inject;
import org.alien4cloud.tosca.model.CSARDependency;
import org.alien4cloud.tosca.model.types.AbstractInheritableToscaType;
import org.alien4cloud.tosca.model.types.AbstractToscaType;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.mapping.ElasticSearchClient;
import org.springframework.stereotype.Service;
import com.google.common.collect.Maps;
import alien4cloud.dao.ElasticSearchDAO;
import alien4cloud.dao.IGenericSearchDAO;
import alien4cloud.dao.model.FetchContext;
import alien4cloud.dao.model.GetMultipleDataResult;
import alien4cloud.images.IImageDAO;
import alien4cloud.model.common.Tag;
import alien4cloud.model.components.IndexedModelUtils;
import alien4cloud.tosca.context.ToscaContext;
import alien4cloud.tosca.context.ToscaContextual;
import alien4cloud.tosca.normative.ToscaType;
/**
* This service is responsible for indexing and searching tosca types.
*/
@Service
public class ToscaTypeIndexerService implements IToscaTypeIndexerService {
@Resource(name = "alien-es-dao")
private IGenericSearchDAO alienDAO;
@Inject
private ElasticSearchClient elasticSearchClient;
@Inject
private IImageDAO imageDAO;
private void refreshIndexForSearching() {
elasticSearchClient.getClient().admin().indices().prepareRefresh(ElasticSearchDAO.TOSCA_ELEMENT_INDEX).execute().actionGet();
}
@Override
public Map<String, AbstractToscaType> getArchiveElements(String archiveName, String archiveVersion) {
return getArchiveElements(archiveName, archiveVersion, AbstractToscaType.class);
}
@Override
public <T extends AbstractToscaType> Map<String, T> getArchiveElements(String archiveName, String archiveVersion, Class<T> type) {
GetMultipleDataResult<T> elements = alienDAO.buildQuery(type)
.setFilters(fromKeyValueCouples("archiveName", archiveName, "archiveVersion", archiveVersion)).prepareSearch().search(0, Integer.MAX_VALUE);
Map<String, T> elementsByIds = Maps.newHashMap();
if (elements == null) {
return elementsByIds;
}
for (T element : elements.getData()) {
elementsByIds.put(element.getId(), element);
}
return elementsByIds;
}
@Override
public void deleteElements(String name, String version) {
GetMultipleDataResult<AbstractToscaType> result = alienDAO.buildQuery(AbstractToscaType.class)
.setFilters(fromKeyValueCouples("archiveName", name, "archiveVersion", version)).prepareSearch().setFetchContext(FetchContext.SUMMARY)
.search(0, Integer.MAX_VALUE);
AbstractToscaType[] elements = result.getData();
// we need to delete each element
for (AbstractToscaType element : elements) {
deleteElement(element);
}
}
@Override
public void indexInheritableElements(Map<String, ? extends AbstractInheritableToscaType> archiveElements, Collection<CSARDependency> dependencies) {
for (AbstractInheritableToscaType element : safe(archiveElements).values()) {
alienDAO.save(element);
}
refreshIndexForSearching();
}
@Override
@ToscaContextual
public void indexInheritableElement(String archiveName, String archiveVersion, AbstractInheritableToscaType element,
Collection<CSARDependency> dependencies) {
// FIXME do we need all the merge in case of substitution ?
if (CollectionUtils.isNotEmpty(element.getDerivedFrom())) {
boolean deriveFromSimpleType = false;
String parentId = element.getDerivedFrom().get(0);
if (element.getDerivedFrom().size() == 1 && ToscaType.isSimple(parentId)) {
deriveFromSimpleType = true;
}
if (!deriveFromSimpleType) {
AbstractInheritableToscaType superElement = ToscaContext.getOrFail(element.getClass(), parentId);
IndexedModelUtils.mergeInheritableIndex(superElement, element);
}
}
alienDAO.save(element);
refreshIndexForSearching();
}
private void deleteElement(AbstractToscaType element) {
Tag iconTag = ArchiveImageLoader.getIconTag(element.getTags());
if (iconTag != null) {
imageDAO.delete(iconTag.getValue());
}
alienDAO.delete(element.getClass(), element.getId());
}
@Override
public void deleteElements(Collection<AbstractToscaType> elements) {
for (AbstractToscaType element : elements) {
alienDAO.delete(element.getClass(), element.getId());
}
}
}