/*
* Copyright 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.server.services.dmn;
import org.kie.api.runtime.KieSession;
import org.kie.dmn.api.core.DMNContext;
import org.kie.dmn.api.core.DMNModel;
import org.kie.dmn.api.core.DMNResult;
import org.kie.dmn.api.core.DMNRuntime;
import org.kie.dmn.api.core.ast.DecisionNode;
import org.kie.dmn.core.api.DMNFactory;
import org.kie.dmn.model.v1_1.Decision;
import org.kie.server.api.model.*;
import org.kie.server.api.model.cases.CaseFile;
import org.kie.server.api.model.dmn.DMNContextKS;
import org.kie.server.api.model.dmn.DMNDecisionInfo;
import org.kie.server.api.model.dmn.DMNModelInfo;
import org.kie.server.api.model.dmn.DMNModelInfoList;
import org.kie.server.api.model.dmn.DMNResultKS;
import org.kie.server.api.model.instance.ScoreWrapper;
import org.kie.server.api.model.instance.SolverInstance;
import org.kie.server.api.model.instance.SolverInstanceList;
import org.kie.server.api.model.type.JaxbList;
import org.kie.server.api.model.type.JaxbMap;
import org.kie.server.services.api.KieContainerInstance;
import org.kie.server.services.api.KieServerRegistry;
import org.kie.server.services.impl.KieContainerInstanceImpl;
import org.kie.server.services.impl.marshal.MarshallerHelper;
import org.optaplanner.core.api.score.Score;
import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.api.solver.SolverFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
public class ModelEvaluatorServiceBase {
private static final Logger LOG = LoggerFactory.getLogger( ModelEvaluatorServiceBase.class );
private KieServerRegistry context;
private MarshallerHelper marshallerHelper;
public ModelEvaluatorServiceBase(KieServerRegistry context) {
this.context = context;
this.marshallerHelper = new MarshallerHelper(context);
}
public ServiceResponse<DMNModelInfoList> getModels(String containerId) {
try {
KieContainerInstanceImpl kContainer = context.getContainer(containerId);
KieSession kieSession = kContainer.getKieContainer().newKieSession();
DMNRuntime kieRuntime = kieSession.getKieRuntime(DMNRuntime.class);
List<DMNModel> models = kieRuntime.getModels();
List<DMNModelInfo> result = models.stream().map(ModelEvaluatorServiceBase::modelToInfo).collect(Collectors.toList());
return new ServiceResponse<DMNModelInfoList>(
ServiceResponse.ResponseType.SUCCESS,
"OK models successfully retrieved from container '" + containerId + "'",
new DMNModelInfoList( result ) );
} catch ( Exception e ) {
LOG.error( "Error retrieving models from container '" + containerId + "'", e );
return new ServiceResponse<DMNModelInfoList>(
ServiceResponse.ResponseType.FAILURE,
"Error retrieving models from container '" + containerId + "'" + e.getMessage(),
null );
}
}
public static DMNModelInfo modelToInfo(DMNModel model) {
DMNModelInfo res = new DMNModelInfo();
res.setNamespace(model.getNamespace());
res.setName(model.getName());
res.setId(model.getDefinitions().getId());
res.setDecisions(model.getDecisions().stream().map(ModelEvaluatorServiceBase::decisionToInfo).collect(Collectors.toSet()));
return res;
}
public static DMNDecisionInfo decisionToInfo(DecisionNode decisionNode) {
DMNDecisionInfo res = new DMNDecisionInfo();
res.setName(decisionNode.getName());
res.setId(decisionNode.getId());
return res;
}
public ServiceResponse<DMNResultKS> evaluateDecisions(String containerId, String contextPayload, String marshallingType) {
try {
KieContainerInstanceImpl kContainer = context.getContainer(containerId);
KieSession kieSession = kContainer.getKieContainer().newKieSession();
DMNRuntime dmnRuntime = kieSession.getKieRuntime(DMNRuntime.class);
LOG.debug("Will deserialize payload: {}", contextPayload);
DMNContextKS evalCtx = marshallerHelper.unmarshal(containerId, contextPayload, marshallingType, DMNContextKS.class);
DMNModel model;
if ( evalCtx.getModelName() == null ) {
if ( dmnRuntime.getModels().size() > 1 ) {
throw new RuntimeException("more than one (default) model");
}
model = dmnRuntime.getModels().get(0);
} else {
model = dmnRuntime.getModel(evalCtx.getNamespace(), evalCtx.getModelName());
}
if ( model == null ) {
throw new RuntimeException("Unable to locate DMN Model to evaluate");
}
LOG.debug("Will use model: {}", model);
DMNContext dmnContext = DMNFactory.newContext();
for ( Entry<String, Object> e : evalCtx.getDmnContext().entrySet() ) {
dmnContext.set(e.getKey(), e.getValue());
}
LOG.debug("Will use dmnContext: {}", dmnContext);
DMNResult result = null;
if ( evalCtx.getDecisionName() == null && evalCtx.getDecisionId() == null ) {
// then implies evaluate All decisions
LOG.debug("Invoking evaluateAll...");
result = dmnRuntime.evaluateAll(model, dmnContext);
} else if ( evalCtx.getDecisionName() != null && evalCtx.getDecisionId() != null ) {
LOG.debug("Not supported case, trying to reconciliate manually");
if ( !model.getDecisionById(evalCtx.getDecisionId()).equals(model.getDecisionByName(evalCtx.getDecisionName())) ) {
throw new RuntimeException("Unable to locate DMN Decision to evaluate");
}
result = dmnRuntime.evaluateDecisionById(model, evalCtx.getDecisionId(), dmnContext);
} else if ( evalCtx.getDecisionName() != null ) {
LOG.debug("Invoking evaluateDecisionByName using {}", evalCtx.getDecisionName());
result = dmnRuntime.evaluateDecisionByName(model, evalCtx.getDecisionName(), dmnContext);
} else if ( evalCtx.getDecisionId() != null ) {
LOG.debug("Invoking evaluateDecisionById using {}", evalCtx.getDecisionId());
result = dmnRuntime.evaluateDecisionById(model, evalCtx.getDecisionId(), dmnContext);
}
LOG.debug("Result:");
LOG.debug("{}",result);
LOG.debug("{}",result.getContext());
LOG.debug("{}",result.getDecisionResults());
LOG.debug("{}",result.getMessages());
DMNResultKS res = new DMNResultKS(model.getNamespace(), model.getName(), evalCtx.getDecisionName(), result);
kieSession.dispose();
return new ServiceResponse<DMNResultKS>(
ServiceResponse.ResponseType.SUCCESS,
"OK from container '" + containerId + "'",
res );
} catch ( Exception e ) {
e.printStackTrace();
LOG.error( "Error from container '" + containerId + "'", e );
return new ServiceResponse<DMNResultKS>(
ServiceResponse.ResponseType.FAILURE,
"Error from container '" + containerId + "'" + e.getMessage(),
null );
}
}
public KieServerRegistry getKieServerRegistry() {
return this.context;
}
}