/*
* Copyright 2015-2016 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.cache;
import static org.hawkular.alerts.api.services.DefinitionsEvent.Type.ACTION_DEFINITION_CREATE;
import static org.hawkular.alerts.api.services.DefinitionsEvent.Type.ACTION_DEFINITION_REMOVE;
import static org.hawkular.alerts.api.services.DefinitionsEvent.Type.ACTION_DEFINITION_UPDATE;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import org.hawkular.alerts.api.model.action.ActionDefinition;
import org.hawkular.alerts.api.services.DefinitionsService;
import org.hawkular.alerts.engine.log.MsgLogger;
import org.infinispan.Cache;
import org.jboss.logging.Logger;
/**
* It manages the cache of global actions.
*
* @author Jay Shaughnessy
* @author Lucas Ponce
*/
@Singleton
@Startup
@TransactionAttribute(value = TransactionAttributeType.NOT_SUPPORTED)
public class ActionsCacheManager {
private final Logger log = Logger.getLogger(ActionsCacheManager.class);
private final MsgLogger msgLog = MsgLogger.LOGGER;
@EJB
DefinitionsService definitions;
@Resource(lookup = "java:jboss/infinispan/cache/hawkular-alerts/globalActions")
private Cache<ActionKey, ActionDefinition> globalActionsCache;
@PostConstruct
public void init() {
msgLog.infoInitActionsCache();
globalActionsCache.clear();
initialCacheUpdate();
definitions.registerListener(events -> {
events.stream().forEach(event -> {
ActionKey key = new ActionKey(event.getTargetTenantId(), event.getActionPlugin(), event.getTargetId());
switch (event.getType()) {
case ACTION_DEFINITION_CREATE:
case ACTION_DEFINITION_UPDATE:
ActionDefinition actionDefinition = event.getActionDefinition();
if (actionDefinition.isGlobal()) {
globalActionsCache.put(key, actionDefinition);
}
break;
case ACTION_DEFINITION_REMOVE:
globalActionsCache.remove(key);
}
});
}, ACTION_DEFINITION_CREATE, ACTION_DEFINITION_REMOVE, ACTION_DEFINITION_UPDATE);
}
public boolean hasGlobalActions() {
return !globalActionsCache.isEmpty();
}
public Collection<ActionDefinition> getGlobalActions(String tenantId) {
List<ActionDefinition> globalActions = new ArrayList<>();
for (ActionKey key : globalActionsCache.keySet()) {
if (key.getTenantId().equals(tenantId)) {
globalActions.add(globalActionsCache.get(key));
}
}
return globalActions;
}
private void initialCacheUpdate() {
try {
log.debug("Initial ActionsCacheManager update in progress..");
globalActionsCache.startBatch();
Collection<ActionDefinition> actionDefinitions = definitions.getAllActionDefinitions();
for (ActionDefinition actionDefinition : actionDefinitions) {
if (actionDefinition.isGlobal()) {
ActionKey key = new ActionKey(actionDefinition.getTenantId(),
actionDefinition.getActionPlugin(),
actionDefinition.getActionId());
globalActionsCache.put(key, actionDefinition);
}
}
globalActionsCache.endBatch(true);
} catch (Exception e) {
log.error("Failed to load global actions", e);
globalActionsCache.endBatch(false);
return;
}
}
public static class ActionKey implements Serializable {
private String tenantId;
private String actionPlugin;
private String actionId;
public ActionKey(String tenantId, String actionPlugin, String actionId) {
this.tenantId = tenantId;
this.actionPlugin = actionPlugin;
this.actionId = actionId;
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public String getActionPlugin() {
return actionPlugin;
}
public void setActionPlugin(String actionPlugin) {
this.actionPlugin = actionPlugin;
}
public String getActionId() {
return actionId;
}
public void setActionId(String actionId) {
this.actionId = actionId;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ActionKey actionKey = (ActionKey) o;
if (tenantId != null ? !tenantId.equals(actionKey.tenantId) : actionKey.tenantId != null) return false;
if (actionPlugin != null ? !actionPlugin.equals(actionKey.actionPlugin) : actionKey.actionPlugin != null)
return false;
return actionId != null ? actionId.equals(actionKey.actionId) : actionKey.actionId == 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);
return result;
}
@Override
public String toString() {
return "ActionKey{" +
"tenantId='" + tenantId + '\'' +
", actionPlugin='" + actionPlugin + '\'' +
", actionId='" + actionId + '\'' +
'}';
}
}
}