/*
* Copyright 2015-2017 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* 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.hawkular.alerts.extensions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.TreeSet;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.enterprise.concurrent.ManagedExecutorService;
import org.hawkular.alerts.api.model.event.Event;
import org.hawkular.alerts.api.model.trigger.FullTrigger;
import org.hawkular.alerts.api.services.AlertsService;
import org.jboss.logging.Logger;
import org.kie.api.KieBase;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.event.rule.AfterMatchFiredEvent;
import org.kie.api.event.rule.AgendaEventListener;
import org.kie.api.event.rule.AgendaGroupPoppedEvent;
import org.kie.api.event.rule.AgendaGroupPushedEvent;
import org.kie.api.event.rule.BeforeMatchFiredEvent;
import org.kie.api.event.rule.MatchCancelledEvent;
import org.kie.api.event.rule.MatchCreatedEvent;
import org.kie.api.event.rule.ObjectDeletedEvent;
import org.kie.api.event.rule.ObjectInsertedEvent;
import org.kie.api.event.rule.ObjectUpdatedEvent;
import org.kie.api.event.rule.RuleFlowGroupActivatedEvent;
import org.kie.api.event.rule.RuleFlowGroupDeactivatedEvent;
import org.kie.api.event.rule.RuleRuntimeEventListener;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.KieSessionConfiguration;
import org.kie.api.runtime.conf.ClockTypeOption;
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.utils.KieHelper;
/**
* It evaluates events externally and send data into alerting
*
* @author Jay Shaughnessy
* @author Lucas Ponce
*/
@Singleton
@Startup
public class CepEngineImpl implements CepEngine {
private final Logger log = Logger.getLogger(CepEngineImpl.class);
Expression expression;
List<Event> results;
KieSession kieSession;
@EJB
private AlertsService alertsService;
@Resource
private ManagedExecutorService executor;
@Lock(LockType.READ)
public void processEvents(TreeSet<Event> events) {
if (kieSession != null) {
events.stream().forEach(e -> kieSession.insert(e));
}
}
@Lock(LockType.READ)
public void sendResult(Event event) {
log.debugf("Resulted event %s", event);
executor.submit(() -> {
try {
alertsService.sendEvents(Arrays.asList(event));
} catch (Exception e) {
log.error("Error sending result events.", e);
}
});
}
public void updateConditions(String expiration, Collection<FullTrigger> activeTriggers) {
expression = new Expression(expiration, activeTriggers);
log.debugf("Rules: \n %s", expression);
stop();
KieBaseConfiguration kieBaseConfiguration = KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
kieBaseConfiguration.setOption( EventProcessingOption.STREAM );
KieBase kieBase = new KieHelper().addContent(expression.getDrl(), ResourceType.DRL).build(kieBaseConfiguration);
KieSessionConfiguration kieSessionConf = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
kieSessionConf.setOption( ClockTypeOption.get( "realtime" ) );
kieSession = kieBase.newKieSession(kieSessionConf, null);
results = new ArrayList<>();
kieSession.setGlobal("results", this);
kieSession.setGlobal("log", log);
if (log.isDebugEnabled()) {
kieSession.addEventListener(new CepAgendaEventListener());
kieSession.addEventListener(new CepRuleRuntimeEventListener());
}
log.infof("Clock time [%s] ", kieSession.getSessionClock().getCurrentTime());
kieSession.getKieBase().getKiePackages().stream().forEach(p -> log.debugf("Rules: %s", p.getRules()));
executor.submit(() -> {
log.info("Starting fireUntilHalt()");
kieSession.fireUntilHalt();
log.info("Stopping fireUntilHalt()");
});
}
@Override
public void stop() {
if (kieSession != null) {
kieSession.halt();
kieSession.dispose();
kieSession.destroy();
kieSession = null;
log.info("Sent halt() signal to CEP session");
}
}
public static class CepAgendaEventListener implements AgendaEventListener {
private final Logger log = Logger.getLogger(CepAgendaEventListener.class);
@Override
public void matchCreated(MatchCreatedEvent event) {
log.debug(event);
}
@Override
public void matchCancelled(MatchCancelledEvent event) {
log.debug(event);
}
@Override
public void beforeMatchFired(BeforeMatchFiredEvent event) {
log.debug(event);
}
@Override
public void afterMatchFired(AfterMatchFiredEvent event) {
log.debug(event);
}
@Override
public void agendaGroupPopped(AgendaGroupPoppedEvent event) {
log.debug(event);
}
@Override
public void agendaGroupPushed(AgendaGroupPushedEvent event) {
log.debug(event);
}
@Override
public void beforeRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event) {
log.debug(event);
}
@Override
public void afterRuleFlowGroupActivated(RuleFlowGroupActivatedEvent event) {
log.debug(event);
}
@Override
public void beforeRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event) {
log.debug(event);
}
@Override
public void afterRuleFlowGroupDeactivated(RuleFlowGroupDeactivatedEvent event) {
log.debug(event);
}
}
public static class CepRuleRuntimeEventListener implements RuleRuntimeEventListener {
private final Logger log = Logger.getLogger(CepRuleRuntimeEventListener.class);
@Override
public void objectInserted(ObjectInsertedEvent event) {
log.debug(event);
}
@Override
public void objectUpdated(ObjectUpdatedEvent event) {
log.debug(event);
}
@Override
public void objectDeleted(ObjectDeletedEvent event) {
log.debug(event);
}
}
}