基于Spring + Drools6.4规则引擎代码实例详解编程语言

基于Spring + Drools6.4规则引擎代码实例详解编程语言

下面简单介绍一下关于Spring+Drools集成实现流程。

需求说明

新用户规则:

1.系统Mock生成用户注册数据,并进入Drools规则引擎处理;

2.对于新注册用户设定用户锁定状态,并初始用户等级为3级,覆盖新用户标识为非;

非新用户规则:

1.设定用户非锁定状态,每次Mock Code执行,用户等级+1(规则比较随意);

实现过程

添加Drools Pom依赖

     <pro..>

       <drools-version>6.4.0.Final</drools-version>

    </pro..>

        <dependency>

            <groupId>org.drools</groupId>

            <artifactId>drools-core</artifactId>

            <version>${drools-version}</version>

        </dependency>

        <dependency>

            <groupId>org.drools</groupId>

            <artifactId>drools-compiler</artifactId>

            <version>${drools-version}</version>

        </dependency>

User实体Bean定义

@Getter

@Setter

@Access(AccessType.FIELD)

@Accessors(chain = true)

@MetaData(value = “登陆/认证用户信息” , comments = “monster-web / monster-web-admin模块使用统一的auth信息”)

@Entity

@Table(name = “auth_MsUser” , uniqueConstraints = @UniqueConstraint(columnNames ={“authUid”,”authType”}))

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

public class User extends BaseNativeEntity {

    @MetaData(value=”用户全局唯一标识” , comments = “同时作为系统用户密码Salt值,Salt形式 [authUuid]”)

    @Column(length = 64 , nullable = false)

    private String authUuid;

    @MetaData(value=”authUid,登陆账号”)

    @Column(length = 128 , nullable = false)

    private String authUid;

    @MetaData(value=”密码”,comments = “MD5加密串,格式:MD5({Salt}+sourcePassword)”)

    @Column(length = 128 , nullable = false)

    private String password;

    @MetaData(value=”用户类型”)

    @Column(length = 32 , nullable = false)

    @Enumerated(EnumType.STRING)

    private AuthTypeEnum authType;

    @MetaData(value = “身份证号码”)

    @Column(length = 32)

    private String idCardNo;

    @MetaData(value=”性别”)

    @Column(length = 32)

    @Enumerated(EnumType.STRING)

    private GenderEnum gender;

    @MetaData(value = “REST访问Token”)

    @Column

    private String accessToken;

    @MetaData(value = “访问Token过期时间”)

    @DateTimeFormat(pattern = DateUtils.DEFAULT_TIME_FORMAT)

    @JsonFormat(pattern = DateUtils.DEFAULT_TIME_FORMAT)

    private Date accessTokenExpireTime;

    @MetaData(value = “是否新用户”,tooltips = “用于新用户相关业务规则”)

    @Column

    private Boolean isNew = Boolean.TRUE;

    @MetaData(value = “账户未锁定标志”, tooltips = “账号锁定后无法登录”)

    @Column

    private Boolean accountNonLocked = Boolean.TRUE;

}

Drools相关Bean定义

提供Drools资源辅助类

package org.monster.drools.technorage;

import org.kie.api.io.ResourceType;

@setter

@getter

public class DroolsResource {

    private String path;

    private ResourcePathType pathType;

    private ResourceType type;

    private String username = null;

    private String password = null;

    public DroolsResource(String path, ResourcePathType pathType,

            ResourceType type) {

        this.path = path;

        this.pathType = pathType;

        this.type = type;

    }

    public DroolsResource(String path, ResourcePathType pathType,

            ResourceType type, String username, String password) {

        this.path = path;

        this.pathType = pathType;

        this.type = type;

        this.username = username;

        this.password = password;

    }

}

定义本地接口,并实现Drools提供的KieServices与KieContainer、KieSession接口

package org.monster.drools.technorage.spring;

import org.kie.api.KieServices;

public interface KieServicesBean extends KieServices {}

package org.monster.drools.technorage.spring;

import org.kie.api.runtime.KieContainer;

public interface KieContainerBean extends KieContainer {}

package org.monster.drools.technorage.spring;

import org.kie.api.runtime.KieSession;

public interface KieSessionBean extends KieSession {}

及其分别实现类

public class DefaultKieServicesBean implements KieServicesBean {

    private static Logger log = LoggerFactory.getLogger(DefaultKieServicesBean.class);

    private DroolsResource[] resources;

    private KieServices kieServices;

    private KieFileSystem kfs;

    public DefaultKieServicesBean(DroolsResource[] resources) throws KieBuildException {

        log.info(“Initialising KnowledgeEnvironment with resources: ” + this.resources);

        this.resources = resources;

        createAndBuildKieServices(resources);

    }

    public DefaultKieServicesBean(String url) throws KieBuildException {

        log.info(“Initialising KnowledgeEnvironment with resources: ” + this.resources);

        this.resources = new DroolsResource[] {

                new DroolsResource(url,

                        ResourcePathType.URL,

                        ResourceType.PKG

            )};

        createAndBuildKieServices(resources);

    }

    public DefaultKieServicesBean(String url, String username, String password) throws KieBuildException {

        this.resources = new DroolsResource[] {

                new DroolsResource(url,

                        ResourcePathType.URL,

                        ResourceType.PKG,

                        username,

                        password

        )};

        createAndBuildKieServices(resources);

    }

    /**

     * 根据提供的DroolsResource创建 [email protected] org.kie.api.KieServices}

     */

    private void createAndBuildKieServices(DroolsResource[] resources) throws KieBuildException {

        this.kieServices = KieServices.Factory.get();

        this.kfs = newKieFileSystem();

        for (DroolsResource resource : resources) {

            log.info(“Resource: ” + resource.getType() + “, path type=”

                    + resource.getPathType() + “, path=” + resource.getPath());

            switch (resource.getPathType()) {

            case CLASSPATH:

                this.kfs.write(ResourceFactory.newClassPathResource(resource.getPath()));

                break;

            case FILE:

                this.kfs.write(ResourceFactory.newFileResource(resource.getPath()));

                break;

            case URL:

                UrlResource urlResource = (UrlResource) ResourceFactory

                        .newUrlResource(resource.getPath());

                if (resource.getUsername() != null) {

                    log.info(“Setting authentication for: ” + resource.getUsername());

                    urlResource.setBasicAuthentication(“enabled”);

                    urlResource.setUsername(resource.getUsername());

                    urlResource.setPassword(resource.getPassword());

                }

                this.kfs.write(urlResource);

                break;

            default:

                throw new IllegalArgumentException(

                        “Unable to build this resource path type.”);

            }

        }

        KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();

        if (kieBuilder.getResults().hasMessages(Level.ERROR)) {

            List<Message> errors = kieBuilder.getResults().getMessages(Level.ERROR);

            StringBuilder sb = new StringBuilder(“Errors:”);

            for (Message msg : errors) {

                sb.append(“/n  ” + prettyBuildMessage(msg));

            }

            throw new KieBuildException(sb.toString());

        }

        log.info(“KieServices built: ” + toString());

    }

    private static String prettyBuildMessage(Message msg) {

        return “Message: {”

            + “id=”+ msg.getId()

            + “, level=” + msg.getLevel()

            + “, path=” + msg.getPath()

            + “, line=” + msg.getLine()

            + “, column=” + msg.getColumn()

            + “, text=/”” + msg.getText() + “/””

            + “}”;

    }

    //省略相关实现方法

}

public class DefaultKieContainerBean implements KieContainerBean {

    private KieServicesBean kieServices;

    private KieContainer kieContainer;

    public DefaultKieContainerBean(KieServicesBean kieServicesBean) {

        this.kieServices = kieServicesBean;

        this.kieContainer = this.kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());

    }

}

public class DefaultKieSessionBean implements KieSessionBean {

    private static Logger log = LoggerFactory.getLogger(DefaultKieSessionBean.class);

    private KieSession kieSession;

    public DefaultKieSessionBean(KieServicesBean kieServices, KieContainerBean kieContainer) {

        this(kieServices, kieContainer, null);

    }

    public DefaultKieSessionBean(KieServicesBean kieServices, KieContainerBean kieContainer, Properties droolsProperties) {

        log.info(“Initialising session…”);

        KieSessionConfiguration conf;

        if (droolsProperties == null) {

            conf = SessionConfiguration.getDefaultInstance();

        } else {

            conf = SessionConfiguration.newInstance(droolsProperties);//new SessionConfiguration(droolsProperties);

        }

        this.kieSession = kieContainer.newKieSession(conf);

    }

    public void addEventListener(RuleRuntimeEventListener listener) {

        kieSession.addEventListener(listener);

    }

    public void addEventListener(ProcessEventListener listener) {

        kieSession.addEventListener(listener);

    }

    public ProcessInstance startProcess(String processId) {

        return kieSession.startProcess(processId);

    }

    public void removeEventListener(RuleRuntimeEventListener listener) {

        kieSession.removeEventListener(listener);

    }

    public int fireAllRules() {

        return kieSession.fireAllRules();

    }

    public void removeEventListener(ProcessEventListener listener) {

        kieSession.removeEventListener(listener);

    }

    public <T extends SessionClock> T getSessionClock() {

        return kieSession.getSessionClock();

    }

    public int fireAllRules(int max) {

        return kieSession.fireAllRules(max);

    }

    public Collection<RuleRuntimeEventListener> getWorkingMemoryEventListeners() {

        return kieSession.getRuleRuntimeEventListeners();

    }

    public Collection<ProcessEventListener> getProcessEventListeners() {

        return kieSession.getProcessEventListeners();

    }

    public void setGlobal(String identifier, Object value) {

        kieSession.setGlobal(identifier, value);

    }

    public void halt() {

        kieSession.halt();

    }

    public ProcessInstance startProcess(String processId,

            Map<String, Object> parameters) {

        return kieSession.startProcess(processId, parameters);

    }

    public void addEventListener(AgendaEventListener listener) {

        kieSession.addEventListener(listener);

    }

    public Object getGlobal(String identifier) {

        return kieSession.getGlobal(identifier);

    }

    public Globals getGlobals() {

        return kieSession.getGlobals();

    }

    public Calendars getCalendars() {

        return kieSession.getCalendars();

    }

    public void removeEventListener(AgendaEventListener listener) {

        kieSession.removeEventListener(listener);

    }

    public Environment getEnvironment() {

        return kieSession.getEnvironment();

    }

    public KieBase getKieBase() {

        return kieSession.getKieBase();

    }

    public int fireAllRules(AgendaFilter agendaFilter) {

        return kieSession.fireAllRules(agendaFilter);

    }

    public void registerChannel(String name, Channel channel) {

        kieSession.registerChannel(name, channel);

    }

    public Collection<AgendaEventListener> getAgendaEventListeners() {

        return kieSession.getAgendaEventListeners();

    }

    public String getEntryPointId() {

        return kieSession.getEntryPointId();

    }

    public void unregisterChannel(String name) {

        kieSession.unregisterChannel(name);

    }

    public Map<String, Channel> getChannels() {

        return kieSession.getChannels();

    }

    public Agenda getAgenda() {

        return kieSession.getAgenda();

    }

    public int fireAllRules(AgendaFilter agendaFilter, int max) {

        return kieSession.fireAllRules(agendaFilter, max);

    }

    public FactHandle insert(Object object) {

        return kieSession.insert(object);

    }

    public KieSessionConfiguration getSessionConfiguration() {

        return kieSession.getSessionConfiguration();

    }

    @Override

    public EntryPoint getEntryPoint(String name) {

        return kieSession.getEntryPoint(name);

    }

    public ProcessInstance createProcessInstance(String processId,

            Map<String, Object> parameters) {

        return kieSession.createProcessInstance(processId, parameters);

    }

    @Deprecated

    public void retract(FactHandle handle) {

        kieSession.retract(handle);

    }

    public Collection<? extends EntryPoint> getEntryPoints() {

        return kieSession.getEntryPoints();

    }

    public void fireUntilHalt() {

        kieSession.fireUntilHalt();

    }

    public <T> T execute(Command<T> command) {

        return kieSession.execute(command);

    }

    public void delete(FactHandle handle) {

        kieSession.delete(handle);

    }

    @Override

    public void delete(FactHandle handle, FactHandle.State fhState) {

    }

    public QueryResults getQueryResults(String query, Object… arguments) {

        return kieSession.getQueryResults(query, arguments);

    }

    public void update(FactHandle handle, Object object) {

        kieSession.update(handle, object);

    }

    public void fireUntilHalt(AgendaFilter agendaFilter) {

        kieSession.fireUntilHalt(agendaFilter);

    }

    public FactHandle getFactHandle(Object object) {

        return kieSession.getFactHandle(object);

    }

    public LiveQuery openLiveQuery(String query, Object[] arguments,

            ViewChangedEventListener listener) {

        return kieSession.openLiveQuery(query, arguments, listener);

    }

    public ProcessInstance startProcessInstance(long processInstanceId) {

        return kieSession.startProcessInstance(processInstanceId);

    }

    public Object getObject(FactHandle factHandle) {

        return kieSession.getObject(factHandle);

    }

    public int getId() {

        return kieSession.getId();

    }

    @Override

    public long getIdentifier() {

        return 0;

    }

    public void signalEvent(String type, Object event) {

        kieSession.signalEvent(type, event);

    }

    public void dispose() {

        kieSession.dispose();

    }

    public Collection<? extends Object> getObjects() {

        return kieSession.getObjects();

    }

    public void destroy() {

        kieSession.destroy();

    }

    public void signalEvent(String type, Object event, long processInstanceId) {

        kieSession.signalEvent(type, event, processInstanceId);

    }

    public Collection<? extends Object> getObjects(ObjectFilter filter) {

        return kieSession.getObjects(filter);

    }

    public <T extends FactHandle> Collection<T> getFactHandles() {

        return kieSession.getFactHandles();

    }

    public <T extends FactHandle> Collection<T> getFactHandles(

            ObjectFilter filter) {

        return kieSession.getFactHandles(filter);

    }

    public Collection<ProcessInstance> getProcessInstances() {

        return kieSession.getProcessInstances();

    }

    public long getFactCount() {

        return kieSession.getFactCount();

    }

    public ProcessInstance getProcessInstance(long processInstanceId) {

        return kieSession.getProcessInstance(processInstanceId);

    }

    public ProcessInstance getProcessInstance(long processInstanceId,

            boolean readonly) {

        return kieSession.getProcessInstance(processInstanceId, readonly);

    }

    public void abortProcessInstance(long processInstanceId) {

        kieSession.abortProcessInstance(processInstanceId);

    }

    public WorkItemManager getWorkItemManager() {

        return kieSession.getWorkItemManager();

    }

    @Override

    public KieRuntimeLogger getLogger() {

        return kieSession.getLogger();

    }

    @Override

    public Collection<RuleRuntimeEventListener> getRuleRuntimeEventListeners() {

        return kieSession.getRuleRuntimeEventListeners();

    }

}

集成Spring,交由spring托管

@Configuration

[email protected](“drools”)

public class BaseKieConfig {

    @Bean(name=”kieServices”)

    public KieServicesBean kieServices() throws KieBuildException {

        DroolsResource [] droolsResources = new DroolsResource[]{

                new DroolsResource(“rules/user-level.drl”, ResourcePathType.CLASSPATH , ResourceType.DRL)

        };

        KieServicesBean kieServicesBean = new DefaultKieServicesBean(droolsResources);

        return kieServicesBean;

    }

    @Bean(name=”kieContainer”)

    public KieContainerBean kieContainer(KieServicesBean kieServices){

        KieContainerBean kieContainer = new DefaultKieContainerBean(kieServices);

        return kieContainer;

    }

}

定义相关业务接口

public interface UserRuleService<T> {

    List<T> userRegister( List<User> users );

    List<T> remUsers( List<User> users );

    List<T> checkUserStatus();

}

@Service

@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON , proxyMode = ScopedProxyMode.INTERFACES)

public class UserRuleServiceImpl implements UserRuleService<User> ,Serializable {

    private Logger logger = LoggerFactory.getLogger(UserRuleServiceImpl.class);

    public KieSessionBean kieSession;

    private TrackingAgendaEventListener agendaEventListener;

    private TrackingWorkingMemoryEventListener workingMemoryEventListener;

    private Map<String , FactHandle> fact2User = Maps.newHashMap();

    private FactFinder<User> userFactFinder = new FactFinder<User>(User.class);

    @Autowired

    public UserRuleServiceImpl(@Qualifier(“kieServices”) KieServicesBean kieServices ,

                               @Qualifier(“kieContainer”) KieContainerBean kieContainer){

        System.setProperty(“drools.negatable”, “on”);

        kieSession                 = new DefaultKieSessionBean(kieServices , kieContainer);

        agendaEventListener        = new TrackingAgendaEventListener();

        workingMemoryEventListener = new TrackingWorkingMemoryEventListener();

        kieSession.addEventListener(agendaEventListener);

        kieSession.addEventListener(workingMemoryEventListener);

    }

    @Override

    public List<User> userRegister(List<User> users) {

        for ( User user : users )

        {

            if(logger.isDebugEnabled()){

                logger.debug(“执行用户注册规则模板,对应用户:{}”,user.toString());

            }

            if(!fact2User.containsKey(user.getId())){

                FactHandle userFireHandle = kieSession.insert(user);

                fact2User.put(String.valueOf(user.getId()) , userFireHandle);

            }

        }

        kieSession.fireAllRules();

        List<User> results = userFactFinder.findFacts(kieSession);

        pause();

        kieSession.dispose();

        return results;

    }

    @Override

    public List<User> remUsers(List<User> users) {

        for( User user : users )

        {

            if(fact2User.containsKey(String.valueOf(user.getId())))

            {

                kieSession.delete(fact2User.get(String.valueOf(user.getId())));

                fact2User.remove(user);

            }

        }

        kieSession.fireAllRules();

        List<User> result = userFactFinder.findFacts(kieSession);

        return result;

    }

    @Override

    public List<User> checkUserStatus() {

        return null;

    }

    public static void pause() {

        System.out.println( “Pressure enter to continue” );

        Scanner keyboard = new Scanner(System.in);

        keyboard.nextLine();

    }

}

Mock代码

int userCnt = countTable(User.class);

        for( int i = userCnt ; (i < INIT_USER_CNT && i<userCnt+5) ; i ++ )

        {

            String salt      =     UidUtils.UID();

            String format    =     String.format(“%06d” , i);

            User user = MockUtils.buildMockEntity(User.class);

            user.setAuthUid(“19999″+format);

            user.setRealName(“用户” + format);

            user.setNickName(“昵称” + format);

            user.setAuthUuid(salt);

            user.setAuthType(User.AuthTypeEnum.SYS);

            user.setPassword(passwordService.encryptPassword(“123456” , salt));

            user.setIdCardNo(“110010” + String.format(“%012d” , i));

            user.setAccessToken(StringUtils.EMPTY);

            //user.setAccessToken(salt);

            users.add(user);

        }

        if(CollectionUtils.isEmpty(users))

        {

            users = userService.findAll();

        }

        //规则引擎服务处理

        users = (List<User>) userRuleService.userRegister(users);

        //存储用户信息

        userService.save(users);

定义规则文件(user-register.drl)

//User-Level规则

package rules

import org.monster.core.auth.entity.User;

rule RegistNewUserRule

//ruleflow-group “Basic-User-Group”

when  $user:User(isNew == Boolean.TRUE)

then

     //1.设置解除锁定状态

     $user.setAccountNonLocked(false);

     //2.用户注册送积分

     $user.setUserLevel(3);

     $user.setIsNew(Boolean.FALSE);

     //3.根据性别

     //System.out.println(“Is New Flg True , [User:” + $user.toString() + “]”);

end

rule RegistNewUserRuleNotNew

//ruleflow-group “Basic-User-Group”

when $user:User(isNew == false)

then

     //1.设置锁定状态

         $user.setAccountNonLocked(true);

         //2.老用户统一设定每次启动增加一级

         $user.setUserLevel($user.getUserLevel()+1);

         //System.out.println(“Is New Flg False, [User:” + $user.toString() +”]”);

end

基于Spring + Drools6.4规则引擎代码实例详解编程语言

转载请注明来源网站:blog.ytso.com谢谢!

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/14627.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论