Drools Integration Primavera
1. Introdução
Neste tutorial rápido, vamos integrar o Drools ao Spring. Se você está apenas começando com o Drools,check out this intro article.
2. Dependências do Maven
Vamos começar adicionando as seguintes dependências ao nosso arquivopom.xml:
org.drools
drools-core
7.0.0.Final
org.kie
kie-spring
7.0.0.Final
As versões mais recentes podem ser encontradas aqui paradrools-coree aqui parakie-spring.
3. Dados iniciais
Vamos agora definir os dados que serão usados em nosso exemplo. Vamos calcular a tarifa de uma viagem com base na distância percorrida e na bandeira da sobretaxa noturna.
Aqui está um objeto simples que será usado como umFact:
public class TaxiRide {
private Boolean isNightSurcharge;
private Long distanceInMile;
// standard constructors, getters/setters
}
Vamos também definir outro objeto de negócios que será usado para representar tarifas:
public class Fare {
private Long nightSurcharge;
private Long rideFare;
// standard constructors, getters/setters
}
Agora, vamos definir uma regra de negócios para calcular as tarifas de táxi:
global com.example.spring.drools.model.Fare rideFare;
dialect "mvel"
rule "Calculate Taxi Fare - Scenario 1"
when
taxiRideInstance:TaxiRide(isNightSurcharge == false && distanceInMile < 10);
then
rideFare.setNightSurcharge(0);
rideFare.setRideFare(70);
end
Como podemos ver, uma regra é definida para calcular a tarifa total de determinadoTaxiRide.
Esta regra aceita um objetoTaxiRide e verifica se o atributoisNightSurcharge éfalsee o valor do atributodistanceInMile é menor que 10, então calcule a tarifa como 70 e define onightSurcharge propriedade para 0.
A saída calculada é definida comoFare objeto para uso posterior.
4. Integração Spring
4.1. Configuração do Spring Bean
Agora, vamos prosseguir para a integração do Spring.
Vamos definir uma classe de configuração do Spring bean - que será responsável por instanciar o beanTaxiFareCalculatorService e suas dependências:
@Configuration
@ComponentScan("com.example.spring.drools.service")
public class TaxiFareConfiguration {
private static final String drlFile = "TAXI_FARE_RULE.drl";
@Bean
public KieContainer kieContainer() {
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
kieFileSystem.write(ResourceFactory.newClassPathResource(drlFile));
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
KieModule kieModule = kieBuilder.getKieModule();
return kieServices.newKieContainer(kieModule.getReleaseId());
}
}
KieServices é um singleton que atua como uma entrada de ponto único para obter todos os serviços fornecidos pelo Kie. KieServices é recuperado usandoKieServices.Factory.get().
Em seguida, precisamos obterKieContainer, que é um marcador para todos os objetos de que precisamos para executar o mecanismo de regras.
KieContainer é construído com a ajuda de outros beans incluindoKieFileSystem, KieBuilder,eKieModule.
Vamos prosseguir para criar umKieModule que é um contêiner de todos os recursos necessários para definir o conhecimento da regra conhecido comoKieBase.
KieModule kieModule = kieBuilder.getKieModule();
KieBase é um repositório que contém todo o conhecimento relacionado ao aplicativo como regras, processos, funções, modelos de tipo e está escondido dentro deKieModule. OKieBase pode ser obtido a partir doKieContainer.
Depois de criarKieModule, podemos prosseguir para criarKieContainer– que contémKieModule ondeKieBase foi definido. OKieContainer é criado usando um módulo:
KieContainer kContainer = kieServices.newKieContainer(kieModule.getReleaseId());
4.2. Spring Service
Vamos definir uma classe de serviço que executa a lógica de negócios real, passando o objetoFact para o mecanismo para processar o resultado:
@Service
public class TaxiFareCalculatorService {
@Autowired
private KieContainer kieContainer;
public Long calculateFare(TaxiRide taxiRide, Fare rideFare) {
KieSession kieSession = kieContainer.newKieSession();
kieSession.setGlobal("rideFare", rideFare);
kieSession.insert(taxiRide);
kieSession.fireAllRules();
kieSession.dispose();
return rideFare.getTotalFare();
}
}
Finalmente, umKieSession é criado usando a instânciaKieContainer. Uma instânciaKieSession é um local onde os dados de entrada podem ser inseridos. OKieSession interage com o mecanismo para processar a lógica de negócios real definida na regra com base nos fatos inseridos.
Global (assim como uma variável global) é usada para passar informações para o mecanismo. Podemos definir o Global usandosetGlobal(“key”, value); neste exemplo, definimos o objetoFare como Global para armazenar a tarifa de táxi calculada.
Como discutimos na Seção 4,a Rule requires data to operate on. Estamos inserindoFact na sessão usandokieSession.insert(taxiRide);
Assim que terminarmos de configurar a entradaFact,, podemos solicitar que o mecanismo execute a lógica de negócios chamandofireAllRules().
Finalmente, precisamos limpar a sessão para evitar vazamento de memória chamando o métododispose().
5. Exemplo em ação
Agora, podemos conectar um contexto do Spring e ver em ação que o Drools funciona conforme o esperado:
@Test
public void whenNightSurchargeFalseAndDistLessThan10_thenFixWithoutNightSurcharge() {
TaxiRide taxiRide = new TaxiRide();
taxiRide.setIsNightSurcharge(false);
taxiRide.setDistanceInMile(9L);
Fare rideFare = new Fare();
Long totalCharge = taxiFareCalculatorService.calculateFare(taxiRide, rideFare);
assertNotNull(totalCharge);
assertEquals(Long.valueOf(70), totalCharge);
}
6. Conclusão
Neste artigo, aprendemos sobre a integração do Drools Spring com um caso de uso simples.
Como sempre, a implementação do exemplo e trechos de código estão disponíveisover on GitHub.