Drools Integration Primavera

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.