/*
* 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.engine.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.enterprise.concurrent.ManagedExecutorService;
import javax.inject.Inject;
import org.hawkular.alerts.api.json.JsonUtil;
import org.hawkular.alerts.api.model.action.Action;
import org.hawkular.alerts.api.model.action.ActionDefinition;
import org.hawkular.alerts.api.model.event.Event;
import org.hawkular.alerts.api.model.paging.ActionComparator;
import org.hawkular.alerts.api.model.paging.ActionComparator.Field;
import org.hawkular.alerts.api.model.paging.Order;
import org.hawkular.alerts.api.model.paging.Page;
import org.hawkular.alerts.api.model.paging.Pager;
import org.hawkular.alerts.api.model.trigger.Trigger;
import org.hawkular.alerts.api.model.trigger.TriggerAction;
import org.hawkular.alerts.api.services.ActionListener;
import org.hawkular.alerts.api.services.ActionsCriteria;
import org.hawkular.alerts.api.services.ActionsService;
import org.hawkular.alerts.api.services.DefinitionsService;
import org.hawkular.alerts.engine.cache.ActionsCacheManager;
import org.hawkular.alerts.engine.log.MsgLogger;
import org.hawkular.alerts.engine.util.ActionsValidator;
import org.jboss.logging.Logger;
import com.datastax.driver.core.BoundStatement;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.ResultSetFuture;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;
import com.google.common.util.concurrent.Futures;
/**
* Cassandra implementation of {@link org.hawkular.alerts.api.services.ActionsService}.
*
* @author Jay Shaughnessy
* @author Lucas Ponce
*/
@Local(ActionsService.class)
@Stateless
@TransactionAttribute(value = TransactionAttributeType.NOT_SUPPORTED)
public class CassActionsServiceImpl implements ActionsService {
private final MsgLogger msgLog = MsgLogger.LOGGER;
private final Logger log = Logger.getLogger(CassActionsServiceImpl.class);
private static final String WAITING_RESULT = "WAITING";
private static final String UNKNOWN_RESULT = "UNKNOWN";
@EJB
AlertsContext alertsContext;
@EJB
DefinitionsService definitions;
@EJB
ActionsCacheManager actionsCacheManager;
@Resource
private ManagedExecutorService executor;
@Inject
@CassClusterSession
Session session;
public CassActionsServiceImpl() {
log.debug("Creating instance.");
}
public void setAlertsContext(AlertsContext alertsContext) {
this.alertsContext = alertsContext;
}
public void setDefinitions(DefinitionsService definitions) {
this.definitions = definitions;
}
public void setExecutor(ManagedExecutorService executor) {
this.executor = executor;
}
public void setSession(Session session) {
this.session = session;
}
@Override
public void send(Trigger trigger, Event event) {
if (trigger == null) {
throw new IllegalArgumentException("Trigger must be not null");
}
if (!isEmpty(trigger.getActions())) {
for (TriggerAction triggerAction : trigger.getActions()) {
send(triggerAction, event);
}
}
if (actionsCacheManager.hasGlobalActions()) {
Collection<ActionDefinition> globalActions = actionsCacheManager.getGlobalActions(trigger.getTenantId());
for (ActionDefinition globalAction : globalActions) {
send(globalAction, event);
}
}
}
private void send(final TriggerAction triggerAction, final Event event) {
if (triggerAction == null || isEmpty(triggerAction.getTenantId()) ||
isEmpty(triggerAction.getActionPlugin()) || isEmpty(triggerAction.getActionId())) {
throw new IllegalArgumentException("TriggerAction must be not null");
}
if (event == null || isEmpty(event.getTenantId())) {
throw new IllegalArgumentException("Event must be not null");
}
if (!triggerAction.getTenantId().equals(event.getTenantId())) {
throw new IllegalArgumentException("TriggerAction and Event must have same tenantId");
}
executor.submit(() -> {
Action action = new Action(triggerAction.getTenantId(), triggerAction.getActionPlugin(),
triggerAction.getActionId(), event);
try {
ActionDefinition actionDefinition = definitions.getActionDefinition(triggerAction.getTenantId(),
triggerAction.getActionPlugin(), triggerAction.getActionId());
Map<String, String> defaultProperties =
definitions.getDefaultActionPlugin(triggerAction.getActionPlugin());
if (actionDefinition != null && defaultProperties != null) {
Map<String, String> mixedProps = mixProperties(actionDefinition.getProperties(), defaultProperties);
action.setProperties(mixedProps);
} else {
if (log.isDebugEnabled()) {
log.debug("Action " + action + " has not an ActionDefinition");
}
}
// If no constraints defined at TriggerAction level, ActionDefinition constraints are used.
if (isEmpty(triggerAction.getStates()) && triggerAction.getCalendar() == null) {
triggerAction.setStates(actionDefinition.getStates());
triggerAction.setCalendar(actionDefinition.getCalendar());
if (log.isDebugEnabled()) {
log.debug("Using ActionDefinition constraints: " + actionDefinition);
}
}
if (ActionsValidator.validate(triggerAction, event)) {
for (ActionListener listener : alertsContext.getActionsListeners()) {
listener.process(action);
}
insertActionHistory(action);
}
} catch (Exception e) {
log.debug(e.getMessage(), e);
msgLog.errorCannotUpdateAction(e.getMessage());
}
});
}
private void send(final ActionDefinition globalActionDefinition, final Event event) {
if (globalActionDefinition == null || isEmpty(globalActionDefinition.getTenantId()) ||
isEmpty(globalActionDefinition.getActionPlugin()) || isEmpty(globalActionDefinition.getActionId())) {
throw new IllegalArgumentException("ActionDefinition must be not null");
}
if (event == null || isEmpty(event.getTenantId())) {
throw new IllegalArgumentException("Event must be not null");
}
if (!globalActionDefinition.getTenantId().equals(event.getTenantId())) {
throw new IllegalArgumentException("ActionDefinition and Event must have same tenantId");
}
executor.submit(() -> {
TriggerAction globalTriggerAction = new TriggerAction(globalActionDefinition.getTenantId(),
globalActionDefinition.getActionPlugin(), globalActionDefinition.getActionId());
Action action = new Action(globalTriggerAction.getTenantId(), globalTriggerAction.getActionPlugin(),
globalTriggerAction.getActionId(), event);
try {
Map<String, String> defaultProperties =
definitions.getDefaultActionPlugin(globalTriggerAction.getActionPlugin());
if (defaultProperties != null) {
Map<String, String> mixedProps = mixProperties(globalActionDefinition.getProperties(),
defaultProperties);
action.setProperties(mixedProps);
}
globalTriggerAction.setStates(globalActionDefinition.getStates());
globalTriggerAction.setCalendar(globalActionDefinition.getCalendar());
if (ActionsValidator.validate(globalTriggerAction, event)) {
for (ActionListener listener : alertsContext.getActionsListeners()) {
listener.process(action);
}
insertActionHistory(action);
}
} catch (Exception e) {
log.debug(e.getMessage(), e);
msgLog.errorCannotUpdateAction(e.getMessage());
}
});
}
@Override
public void updateResult(Action action) {
if (action == null || action.getActionPlugin() == null || action.getActionId() == null
|| action.getActionPlugin().isEmpty()
|| action.getActionId().isEmpty()) {
throw new IllegalArgumentException("Action must be not null");
}
if (action.getEvent() == null) {
throw new IllegalArgumentException("Action must have an alert");
}
executor.submit(() -> {
updateActionHistory(action);
});
}
private void insertActionHistory(Action action) {
if (action.getResult() == null) {
action.setResult(WAITING_RESULT);
}
try {
PreparedStatement insertActionHistory = CassStatement.get(session,
CassStatement.INSERT_ACTION_HISTORY);
PreparedStatement insertActionHistoryAction = CassStatement.get(session,
CassStatement.INSERT_ACTION_HISTORY_ACTION);
PreparedStatement insertActionHistoryAlert = CassStatement.get(session,
CassStatement.INSERT_ACTION_HISTORY_ALERT);
PreparedStatement insertActionHistoryCtime = CassStatement.get(session,
CassStatement.INSERT_ACTION_HISTORY_CTIME);
PreparedStatement insertActionHistoryResult = CassStatement.get(session,
CassStatement.INSERT_ACTION_HISTORY_RESULT);
List<ResultSetFuture> futures = new ArrayList<>();
futures.add(session.executeAsync(insertActionHistory.bind(action.getTenantId(), action.getActionPlugin(),
action.getActionId(), action.getEvent().getId(), action.getCtime(), JsonUtil.toJson(action))));
futures.add(session.executeAsync(insertActionHistoryAction.bind(action.getTenantId(),
action.getActionId(), action.getActionPlugin(), action.getEvent().getId(),
action.getCtime())));
futures.add(session.executeAsync(insertActionHistoryAlert.bind(action.getTenantId(),
action.getEvent().getId(), action.getActionPlugin(), action.getActionId(),
action.getCtime())));
futures.add(session.executeAsync(insertActionHistoryCtime.bind(action.getTenantId(),
action.getCtime(), action.getActionPlugin(), action.getActionId(),
action.getEvent().getId())));
futures.add(session.executeAsync(insertActionHistoryResult.bind(action.getTenantId(),
action.getResult(), action.getActionPlugin(), action.getActionId(), action.getEvent().getId(),
action.getCtime())));
Futures.allAsList(futures).get();
} catch (Exception e) {
msgLog.errorDatabaseException(e.getMessage());
}
}
private Action selectActionHistory(String tenantId, String actionPlugin, String actionId, String alertId,
long ctime) {
Action actionHistory = null;
try {
PreparedStatement selectActionHistory = CassStatement.get(session, CassStatement.SELECT_ACTION_HISTORY);
ResultSet rsActionHistory = session.execute(selectActionHistory.bind(tenantId, actionPlugin, actionId,
alertId, ctime));
Iterator<Row> itActionHistory = rsActionHistory.iterator();
if (itActionHistory.hasNext()) {
Row row = itActionHistory.next();
actionHistory = JsonUtil.fromJson(row.getString("payload"), Action.class);
}
} catch (Exception e) {
msgLog.errorDatabaseException(e.getMessage());
}
return actionHistory;
}
private void updateActionHistory(Action action) {
if (action.getResult() == null) {
action.setResult(UNKNOWN_RESULT);
}
try {
Action oldActionHistory = selectActionHistory(action.getTenantId(), action.getActionPlugin(),
action.getActionId(), action.getEvent().getId(), action.getCtime());
if (oldActionHistory == null) {
insertActionHistory(action);
return;
}
String oldResult = oldActionHistory.getResult();
PreparedStatement deleteActionHistoryResult = CassStatement.get(session,
CassStatement.DELETE_ACTION_HISTORY_RESULT);
PreparedStatement insertActionHistoryResult = CassStatement.get(session,
CassStatement.INSERT_ACTION_HISTORY_RESULT);
PreparedStatement updateActionHistory = CassStatement.get(session, CassStatement.UPDATE_ACTION_HISTORY);
List<ResultSetFuture> futures = new ArrayList<>();
futures.add(session.executeAsync(deleteActionHistoryResult.bind(action.getTenantId(), oldResult,
action.getActionPlugin(), action.getActionId(), action.getEvent().getId(),
action.getCtime())));
futures.add(session.executeAsync(insertActionHistoryResult.bind(action.getTenantId(),
action.getResult(), action.getActionPlugin(), action.getActionId(), action.getEvent().getId(),
action.getCtime())));
futures.add(session.executeAsync(updateActionHistory.bind(JsonUtil.toJson(action), action.getTenantId(),
action.getActionPlugin(), action.getActionId(), action.getEvent().getId(),
action.getCtime())));
Futures.allAsList(futures).get();
} catch (Exception e) {
msgLog.errorDatabaseException(e.getMessage());
}
}
@Override
public void addListener(ActionListener listener) {
alertsContext.registerActionListener(listener);
msgLog.infoActionListenerRegistered(listener.toString());
}
@Override
public Page<Action> getActions(String tenantId, ActionsCriteria criteria, Pager pager) throws Exception {
if (isEmpty(tenantId)) {
throw new IllegalArgumentException("TenantId must be not null");
}
boolean thin = (null != criteria && criteria.isThin());
boolean filter = (null != criteria && criteria.hasCriteria());
List<Action> actions = new ArrayList<>();
Set<ActionHistoryPK> actionPks = new HashSet<>();
if (filter) {
/*
* Get Action PKs filtered by ctime
*/
Set<ActionHistoryPK> actionPKsfilteredByCtime = new HashSet<>();
boolean filterByCtime = filterByCtime(tenantId, actionPKsfilteredByCtime, criteria);
if (filterByCtime) {
actionPks.addAll(actionPKsfilteredByCtime);
if (actionPks.isEmpty()) {
return new Page<>(actions, pager, 0);
}
}
/*
* Get Action PKs filtered by actionPlugin
*/
Set<ActionHistoryPK> actionPKsfilteredByActionPlugin = new HashSet<>();
boolean filterByActionPlugin = filterByActionPlugin(tenantId, actionPKsfilteredByActionPlugin, criteria);
if (filterByActionPlugin) {
if (actionPks.isEmpty()) {
actionPks.addAll(actionPKsfilteredByActionPlugin);
} else {
actionPks.retainAll(actionPKsfilteredByActionPlugin);
}
if (actionPks.isEmpty()) {
return new Page<>(actions, pager, 0);
}
}
/*
* Get Action PKs filtered by actionId
*/
Set<ActionHistoryPK> actionPKsfilteredByActionId = new HashSet<>();
boolean filterByActionId = filterByActionId(tenantId, actionPKsfilteredByActionId, criteria);
if (filterByActionId) {
if (actionPks.isEmpty()) {
actionPks.addAll(actionPKsfilteredByActionId);
} else {
actionPks.retainAll(actionPKsfilteredByActionId);
}
if (actionPks.isEmpty()) {
return new Page<>(actions, pager, 0);
}
}
/*
* Get Action PKs filtered by alertId
*/
Set<ActionHistoryPK> actionPKsfilteredByAlertId = new HashSet<>();
boolean filterByAlertId = filterByAlertId(tenantId, actionPKsfilteredByAlertId, criteria);
if (filterByAlertId) {
if (actionPks.isEmpty()) {
actionPks.addAll(actionPKsfilteredByAlertId);
} else {
actionPks.retainAll(actionPKsfilteredByAlertId);
}
if (actionPks.isEmpty()) {
return new Page<>(actions, pager, 0);
}
}
/*
* Get Action PKs filtered by result
*/
Set<ActionHistoryPK> actionPKsfilteredByResult = new HashSet<>();
boolean filterByResult = filterByResult(tenantId, actionPKsfilteredByResult, criteria);
if (filterByResult) {
if (actionPks.isEmpty()) {
actionPks.addAll(actionPKsfilteredByResult);
} else {
actionPks.retainAll(actionPKsfilteredByResult);
}
if (actionPks.isEmpty()) {
return new Page<>(actions, pager, 0);
}
}
}
if (!filter) {
/*
* Get all actions
*/
PreparedStatement selectActionHistoryByTenant = CassStatement.get(session,
CassStatement.SELECT_ACTION_HISTORY_BY_TENANT);
ResultSet rsActionHistoryByTenant = session.execute(selectActionHistoryByTenant.bind(tenantId));
Iterator<Row> itActionHistoryByTenant = rsActionHistoryByTenant.iterator();
while (itActionHistoryByTenant.hasNext()) {
Row row = itActionHistoryByTenant.next();
Action actionHistory = JsonUtil.fromJson(row.getString("payload"), Action.class, thin);
actions.add(actionHistory);
}
} else {
PreparedStatement selectActionHistory = CassStatement.get(session,
CassStatement.SELECT_ACTION_HISTORY);
List<ResultSetFuture> futures = actionPks.stream().map(actionPk ->
session.executeAsync(selectActionHistory.bind(actionPk.tenantId, actionPk.actionPlugin, actionPk
.actionId, actionPk.alertId, actionPk.ctime))).collect(Collectors.toList());
List<ResultSet> rsActionHistory = Futures.allAsList(futures).get();
rsActionHistory.stream().forEach(r -> {
for (Row row : r) {
Action actionHistory = JsonUtil.fromJson(row.getString("payload"), Action.class, thin);
actions.add(actionHistory);
}
});
}
return preparePage(actions, pager);
}
private boolean filterByCtime(String tenantId, Set<ActionHistoryPK> actionPks, ActionsCriteria criteria)
throws Exception {
boolean filterByCtime = false;
if (criteria.getStartTime() != null || criteria.getEndTime() != null) {
filterByCtime = true;
BoundStatement boundCtime;
if (criteria.getStartTime() != null && criteria.getEndTime() != null) {
PreparedStatement selectActionHistoryCTimeStartEnd = CassStatement.get(session,
CassStatement.SELECT_ACTION_HISTORY_CTIME_START_END);
boundCtime = selectActionHistoryCTimeStartEnd.bind(tenantId, criteria.getStartTime(),
criteria.getEndTime());
} else if (criteria.getStartTime() != null) {
PreparedStatement selectActionHistoryCTimeStart = CassStatement.get(session,
CassStatement.SELECT_ACTION_HISTORY_CTIME_START);
boundCtime = selectActionHistoryCTimeStart.bind(tenantId, criteria.getStartTime());
} else {
PreparedStatement selectActionHistoryCTimeEnd = CassStatement.get(session,
CassStatement.SELECT_ACTION_HISTORY_CTIME_END);
boundCtime = selectActionHistoryCTimeEnd.bind(tenantId, criteria.getEndTime());
}
ResultSet rsActionHistoryCtimes = session.execute(boundCtime);
Iterator<Row> itActionHistoryCtimes = rsActionHistoryCtimes.iterator();
while (itActionHistoryCtimes.hasNext()) {
Row row = itActionHistoryCtimes.next();
ActionHistoryPK actionHistoryPK = new ActionHistoryPK();
actionHistoryPK.tenantId = tenantId;
actionHistoryPK.actionPlugin = row.getString("actionPlugin");
actionHistoryPK.actionId = row.getString("actionId");
actionHistoryPK.alertId = row.getString("alertId");
actionHistoryPK.ctime = row.getLong("ctime");
actionPks.add(actionHistoryPK);
}
}
return filterByCtime;
}
private boolean filterByActionPlugin(String tenantId, Set<ActionHistoryPK> actionPks, ActionsCriteria criteria)
throws Exception {
boolean filterByActionPlugin = false;
if (criteria.getActionPlugin() != null
|| (criteria.getActionPlugins() != null && !criteria.getActionPlugins().isEmpty())) {
filterByActionPlugin = true;
PreparedStatement selectActionHistoryActionPlugin = CassStatement.get(session,
CassStatement.SELECT_ACTION_HISTORY_ACTION_PLUGIN);
List<ResultSetFuture> futures = new ArrayList<>();
if (criteria.getActionPlugin() != null) {
futures.add(session.executeAsync(selectActionHistoryActionPlugin.bind(tenantId,
criteria.getActionPlugin())));
}
if (criteria.getActionPlugins() != null && !criteria.getActionPlugins().isEmpty()) {
for (String actionPlugin : criteria.getActionPlugins()) {
futures.add(session.executeAsync(selectActionHistoryActionPlugin.bind(tenantId, actionPlugin)));
}
}
List<ResultSet> rsActionHistory = Futures.allAsList(futures).get();
rsActionHistory.stream().forEach(r -> {
for (Row row : r) {
ActionHistoryPK actionHistoryPK = new ActionHistoryPK();
actionHistoryPK.tenantId = tenantId;
actionHistoryPK.actionPlugin = row.getString("actionPlugin");
actionHistoryPK.actionId = row.getString("actionId");
actionHistoryPK.alertId = row.getString("alertId");
actionHistoryPK.ctime = row.getLong("ctime");
actionPks.add(actionHistoryPK);
}
});
}
return filterByActionPlugin;
}
private boolean filterByActionId(String tenantId, Set<ActionHistoryPK> actionPks, ActionsCriteria criteria)
throws Exception {
boolean filterByActionId = false;
if (criteria.getActionId() != null
|| (criteria.getActionIds() != null && !criteria.getActionIds().isEmpty())) {
filterByActionId = true;
PreparedStatement selectActionHistoryActionId = CassStatement.get(session,
CassStatement.SELECT_ACTION_HISTORY_ACTION_ID);
List<ResultSetFuture> futures = new ArrayList<>();
if (criteria.getActionId() != null) {
futures.add(session.executeAsync(selectActionHistoryActionId.bind(tenantId, criteria.getActionId())));
}
if (criteria.getActionIds() != null && !criteria.getActionIds().isEmpty()) {
for (String actionId : criteria.getActionIds()) {
futures.add(session.executeAsync(selectActionHistoryActionId.bind(tenantId, actionId)));
}
}
List<ResultSet> rsActionHistory = Futures.allAsList(futures).get();
rsActionHistory.stream().forEach(r -> {
for (Row row : r) {
ActionHistoryPK actionHistoryPK = new ActionHistoryPK();
actionHistoryPK.tenantId = tenantId;
actionHistoryPK.actionPlugin = row.getString("actionPlugin");
actionHistoryPK.actionId = row.getString("actionId");
actionHistoryPK.alertId = row.getString("alertId");
actionHistoryPK.ctime = row.getLong("ctime");
actionPks.add(actionHistoryPK);
}
});
}
return filterByActionId;
}
private boolean filterByAlertId(String tenantId, Set<ActionHistoryPK> actionPks, ActionsCriteria criteria)
throws Exception {
boolean filterByAlertId = false;
if (criteria.getAlertId() != null
|| (criteria.getAlertIds() != null && !criteria.getAlertIds().isEmpty())) {
filterByAlertId = true;
PreparedStatement selectActionHistoryAlertId = CassStatement.get(session,
CassStatement.SELECT_ACTION_HISTORY_ALERT_ID);
List<ResultSetFuture> futures = new ArrayList<>();
if (criteria.getAlertId() != null) {
futures.add(session.executeAsync(selectActionHistoryAlertId.bind(tenantId, criteria.getAlertId())));
}
if (criteria.getAlertIds() != null && !criteria.getAlertIds().isEmpty()) {
for (String alertId : criteria.getAlertIds()) {
futures.add(session.executeAsync(selectActionHistoryAlertId.bind(tenantId, alertId)));
}
}
List<ResultSet> rsActionHistory = Futures.allAsList(futures).get();
rsActionHistory.stream().forEach(r -> {
for (Row row : r) {
ActionHistoryPK actionHistoryPK = new ActionHistoryPK();
actionHistoryPK.tenantId = tenantId;
actionHistoryPK.actionPlugin = row.getString("actionPlugin");
actionHistoryPK.actionId = row.getString("actionId");
actionHistoryPK.alertId = row.getString("alertId");
actionHistoryPK.ctime = row.getLong("ctime");
actionPks.add(actionHistoryPK);
}
});
}
return filterByAlertId;
}
private boolean filterByResult(String tenantId, Set<ActionHistoryPK> actionPks, ActionsCriteria criteria)
throws Exception {
boolean filterByResult = false;
if (criteria.getResult() != null
|| (criteria.getResults() != null && !criteria.getResults().isEmpty())) {
filterByResult = true;
PreparedStatement selectActionHistoryResult = CassStatement.get(session,
CassStatement.SELECT_ACTION_HISTORY_RESULT);
List<ResultSetFuture> futures = new ArrayList<>();
if (criteria.getResult() != null) {
futures.add(session.executeAsync(selectActionHistoryResult.bind(tenantId, criteria.getResult())));
}
if (criteria.getResults() != null && !criteria.getResults().isEmpty()) {
for (String result : criteria.getResults()) {
futures.add(session.executeAsync(selectActionHistoryResult.bind(tenantId, result)));
}
}
List<ResultSet> rsActionHistory = Futures.allAsList(futures).get();
rsActionHistory.stream().forEach(r -> {
for (Row row : r) {
ActionHistoryPK actionHistoryPK = new ActionHistoryPK();
actionHistoryPK.tenantId = tenantId;
actionHistoryPK.actionPlugin = row.getString("actionPlugin");
actionHistoryPK.actionId = row.getString("actionId");
actionHistoryPK.alertId = row.getString("alertId");
actionHistoryPK.ctime = row.getLong("ctime");
actionPks.add(actionHistoryPK);
}
});
}
return filterByResult;
}
private Page<Action> preparePage(List<Action> actions, Pager pager) {
if (pager != null) {
if (pager.getOrder() != null
&& !pager.getOrder().isEmpty()
&& pager.getOrder().get(0).getField() == null) {
pager = Pager.builder()
.withPageSize(pager.getPageSize())
.withStartPage(pager.getPageNumber())
.orderBy(Field.ALERT_ID.getText(), Order.Direction.DESCENDING).build();
}
List<Action> ordered = actions;
if (pager.getOrder() != null) {
pager.getOrder().stream().filter(o -> o.getField() != null && o.getDirection() != null)
.forEach(o -> {
ActionComparator comparator = new ActionComparator(
Field.getField(o.getField()),
o.getDirection());
Collections.sort(ordered, comparator);
});
}
if (!pager.isLimited() || ordered.size() < pager.getStart()) {
pager = new Pager(0, ordered.size(), pager.getOrder());
return new Page(ordered, pager, ordered.size());
}
if (pager.getEnd() >= ordered.size()) {
return new Page(ordered.subList(pager.getStart(), ordered.size()), pager, ordered.size());
}
return new Page(ordered.subList(pager.getStart(), pager.getEnd()), pager, ordered.size());
} else {
pager = Pager.builder().withPageSize(actions.size()).orderBy(Field.ALERT_ID.getText(),
Order.Direction.ASCENDING).build();
return new Page(actions, pager, actions.size());
}
}
@Override
public int deleteActions(String tenantId, ActionsCriteria criteria) throws Exception {
if (isEmpty(tenantId)) {
throw new IllegalArgumentException("TenantId must be not null");
}
if (null == criteria) {
throw new IllegalArgumentException("Criteria must be not null");
}
List<Action> actionsToDelete = getActions(tenantId, criteria, null);
if (actionsToDelete == null || actionsToDelete.isEmpty()) {
return 0;
}
PreparedStatement deleteActionHistory = CassStatement.get(session,
CassStatement.DELETE_ACTION_HISTORY);
PreparedStatement deleteActionHistoryAction = CassStatement.get(session,
CassStatement.DELETE_ACTION_HISTORY_ACTION);
PreparedStatement deleteActionHistoryAlert = CassStatement.get(session,
CassStatement.DELETE_ACTION_HISTORY_ALERT);
PreparedStatement deleteActionHistoryCtime = CassStatement.get(session,
CassStatement.DELETE_ACTION_HISTORY_CTIME);
PreparedStatement deleteActionHistoryResult = CassStatement.get(session,
CassStatement.DELETE_ACTION_HISTORY_RESULT);
for (Action action : actionsToDelete) {
List<ResultSetFuture> futures = new ArrayList<>();
futures.add(session.executeAsync(deleteActionHistory.bind(action.getTenantId(), action.getActionPlugin(),
action.getActionId(), action.getEvent().getId(), action.getCtime())));
futures.add(session.executeAsync(deleteActionHistoryAction.bind(action.getTenantId(),
action.getActionId(),
action.getActionPlugin(), action.getEvent().getId(), action.getCtime())));
futures.add(session.executeAsync(deleteActionHistoryAlert.bind(action.getTenantId(),
action.getEvent().getId(), action.getActionPlugin(), action.getActionId(),
action.getCtime())));
futures.add(session.executeAsync(deleteActionHistoryCtime.bind(action.getTenantId(), action.getCtime(),
action.getActionPlugin(), action.getActionId(), action.getEvent().getId())));
futures.add(session.executeAsync(deleteActionHistoryResult.bind(action.getTenantId(),
action.getResult(), action.getActionPlugin(), action.getActionId(), action.getEvent().getId(),
action.getCtime())));
Futures.allAsList(futures).get();
}
return actionsToDelete.size();
}
private boolean isEmpty(String s) {
return null == s || s.trim().isEmpty();
}
private boolean isEmpty(Collection c) {
return null == c || c.isEmpty();
}
private Map<String, String> mixProperties(Map<String, String> props, Map<String, String> defProps) {
Map<String, String> mixed = new HashMap<>();
if (props != null) {
mixed.putAll(props);
}
if (defProps != null) {
for (String defKey : defProps.keySet()) {
mixed.putIfAbsent(defKey, defProps.get(defKey));
}
}
return mixed;
}
private class ActionHistoryPK {
public String tenantId;
public String actionPlugin;
public String actionId;
public String alertId;
public long ctime;
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
ActionHistoryPK that = (ActionHistoryPK) o;
if (ctime != that.ctime)
return false;
if (tenantId != null ? !tenantId.equals(that.tenantId) : that.tenantId != null)
return false;
if (actionPlugin != null ? !actionPlugin.equals(that.actionPlugin) : that.actionPlugin != null)
return false;
if (actionId != null ? !actionId.equals(that.actionId) : that.actionId != null)
return false;
return !(alertId != null ? !alertId.equals(that.alertId) : that.alertId != null);
}
@Override
public int hashCode() {
int result = tenantId != null ? tenantId.hashCode() : 0;
result = 31 * result + (actionPlugin != null ? actionPlugin.hashCode() : 0);
result = 31 * result + (actionId != null ? actionId.hashCode() : 0);
result = 31 * result + (alertId != null ? alertId.hashCode() : 0);
result = 31 * result + (int) (ctime ^ (ctime >>> 32));
return result;
}
}
}