io.camunda.operate.webapp.api.v1.dao.opensearch.OpensearchDecisionDefinitionDao Maven / Gradle / Ivy
The newest version!
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under
* one or more contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright ownership.
* Licensed under the Camunda License 1.0. You may not use this file
* except in compliance with the Camunda License 1.0.
*/
package io.camunda.operate.webapp.api.v1.dao.opensearch;
import io.camunda.operate.conditions.OpensearchCondition;
import io.camunda.operate.schema.indices.DecisionIndex;
import io.camunda.operate.schema.indices.DecisionRequirementsIndex;
import io.camunda.operate.store.opensearch.client.sync.RichOpenSearchClient;
import io.camunda.operate.webapp.api.v1.dao.DecisionDefinitionDao;
import io.camunda.operate.webapp.api.v1.dao.DecisionRequirementsDao;
import io.camunda.operate.webapp.api.v1.entities.DecisionDefinition;
import io.camunda.operate.webapp.api.v1.entities.DecisionRequirements;
import io.camunda.operate.webapp.api.v1.entities.Query;
import io.camunda.operate.webapp.api.v1.entities.Results;
import io.camunda.operate.webapp.api.v1.exceptions.ServerException;
import io.camunda.operate.webapp.opensearch.OpensearchQueryDSLWrapper;
import io.camunda.operate.webapp.opensearch.OpensearchRequestDSLWrapper;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.opensearch.client.opensearch.core.SearchRequest;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Component;
@Conditional(OpensearchCondition.class)
@Component
public class OpensearchDecisionDefinitionDao
extends OpensearchKeyFilteringDao
implements DecisionDefinitionDao {
private final DecisionIndex decisionIndex;
private final DecisionRequirementsIndex decisionRequirementsIndex;
private final DecisionRequirementsDao decisionRequirementsDao;
public OpensearchDecisionDefinitionDao(
OpensearchQueryDSLWrapper queryDSLWrapper,
OpensearchRequestDSLWrapper requestDSLWrapper,
RichOpenSearchClient richOpenSearchClient,
DecisionIndex decisionIndex,
DecisionRequirementsIndex decisionRequirementsIndex,
DecisionRequirementsDao decisionRequirementsDao) {
super(queryDSLWrapper, requestDSLWrapper, richOpenSearchClient);
this.decisionIndex = decisionIndex;
this.decisionRequirementsIndex = decisionRequirementsIndex;
this.decisionRequirementsDao = decisionRequirementsDao;
}
@Override
public DecisionDefinition byKey(Long key) {
final var decisionDefinition = super.byKey(key);
final DecisionRequirements decisionRequirements =
decisionRequirementsDao.byKey(decisionDefinition.getDecisionRequirementsKey());
decisionDefinition.setDecisionRequirementsName(decisionRequirements.getName());
decisionDefinition.setDecisionRequirementsVersion(decisionRequirements.getVersion());
return decisionDefinition;
}
@Override
protected String getKeyFieldName() {
return DecisionIndex.KEY;
}
@Override
protected String getByKeyServerReadErrorMessage(Long key) {
return String.format("Error in reading decision definition for key %s", key);
}
@Override
protected String getByKeyNoResultsErrorMessage(Long key) {
return String.format("No decision definition found for key %s", key);
}
@Override
protected String getByKeyTooManyResultsErrorMessage(Long key) {
return String.format("Found more than one decision definition for key %s", key);
}
@Override
public Results search(Query query) {
final var results = super.search(query);
final var decisionDefinitions = results.getItems();
populateDecisionRequirementsNameAndVersion(decisionDefinitions);
return results;
}
@Override
protected String getUniqueSortKey() {
return DecisionDefinition.KEY;
}
@Override
protected Class getInternalDocumentModelClass() {
return DecisionDefinition.class;
}
@Override
protected String getIndexName() {
return decisionIndex.getAlias();
}
@Override
protected void buildFiltering(Query query, SearchRequest.Builder request) {
final DecisionDefinition filter = query.getFilter();
if (filter != null) {
final var queryTerms =
Stream.of(
queryDSLWrapper.term(DecisionDefinition.ID, filter.getId()),
queryDSLWrapper.term(DecisionDefinition.KEY, filter.getKey()),
queryDSLWrapper.term(DecisionDefinition.DECISION_ID, filter.getDecisionId()),
queryDSLWrapper.term(DecisionDefinition.TENANT_ID, filter.getTenantId()),
queryDSLWrapper.term(DecisionDefinition.NAME, filter.getName()),
queryDSLWrapper.term(DecisionDefinition.VERSION, filter.getVersion()),
queryDSLWrapper.term(
DecisionDefinition.DECISION_REQUIREMENTS_ID,
filter.getDecisionRequirementsId()),
queryDSLWrapper.term(
DecisionDefinition.DECISION_REQUIREMENTS_KEY,
filter.getDecisionRequirementsKey()),
buildFilteringBy(
filter.getDecisionRequirementsName(),
filter.getDecisionRequirementsVersion()))
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (!queryTerms.isEmpty()) {
request.query(queryDSLWrapper.and(queryTerms));
}
}
}
@Override
protected DecisionDefinition convertInternalToApiResult(DecisionDefinition internalResult) {
return internalResult;
}
/**
* populateDecisionRequirementsNameAndVersion - adds decisionRequirementsName and
* decisionRequirementsVersion fields to the decision definitions
*/
private void populateDecisionRequirementsNameAndVersion(
List decisionDefinitions) {
final Set decisionRequirementsKeys =
decisionDefinitions.stream()
.map(DecisionDefinition::getDecisionRequirementsKey)
.collect(Collectors.toSet());
final List decisionRequirements =
decisionRequirementsDao.byKeys(decisionRequirementsKeys);
final Map decisionReqMap = new HashMap<>();
decisionRequirements.forEach(
decisionReq -> decisionReqMap.put(decisionReq.getKey(), decisionReq));
decisionDefinitions.forEach(
decisionDef -> {
final DecisionRequirements decisionReq =
(decisionDef.getDecisionRequirementsKey() == null)
? null
: decisionReqMap.get(decisionDef.getDecisionRequirementsKey());
if (decisionReq != null) {
decisionDef.setDecisionRequirementsName(decisionReq.getName());
decisionDef.setDecisionRequirementsVersion(decisionReq.getVersion());
}
});
}
private org.opensearch.client.opensearch._types.query_dsl.Query buildFilteringBy(
String decisionRequirementsName, Integer decisionRequirementsVersion) {
try {
final List queryTerms =
new LinkedList<>();
queryTerms.add(
queryDSLWrapper.term(DecisionRequirementsIndex.NAME, decisionRequirementsName));
queryTerms.add(
queryDSLWrapper.term(DecisionRequirementsIndex.VERSION, decisionRequirementsVersion));
final var query = queryDSLWrapper.and(queryTerms);
if (query == null) {
return null;
}
final var request =
requestDSLWrapper
.searchRequestBuilder(decisionRequirementsIndex.getAlias())
.query(queryDSLWrapper.withTenantCheck(query))
.source(queryDSLWrapper.sourceInclude(DecisionRequirementsIndex.KEY));
final var decisionRequirements =
richOpenSearchClient.doc().scrollValues(request, DecisionRequirements.class);
final List nonNullKeys =
decisionRequirements.stream()
.map(DecisionRequirements::getKey)
.filter(Objects::nonNull)
.toList();
if (nonNullKeys.isEmpty()) {
return queryDSLWrapper.matchNone();
}
return queryDSLWrapper.longTerms(DecisionDefinition.DECISION_REQUIREMENTS_KEY, nonNullKeys);
} catch (Exception e) {
throw new ServerException("Error in reading decision requirements by name and version", e);
}
}
}