777 lines
29 KiB
Java
777 lines
29 KiB
Java
/*
|
|
* Copyright 2015 FUJITSU LIMITED
|
|
* Copyright 2016 Hewlett Packard Enterprise Development Company, L.P.
|
|
*
|
|
* 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 monasca.api.infrastructure.persistence.hibernate;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
import javax.inject.Inject;
|
|
import javax.inject.Named;
|
|
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
import org.apache.commons.collections4.MapUtils;
|
|
import org.hibernate.Query;
|
|
import org.hibernate.Session;
|
|
import org.hibernate.SessionFactory;
|
|
import org.hibernate.StatelessSession;
|
|
import org.hibernate.Transaction;
|
|
import org.hibernate.criterion.Projections;
|
|
import org.hibernate.criterion.Restrictions;
|
|
import org.hibernate.transform.AliasToEntityMapResultTransformer;
|
|
import org.hibernate.transform.ResultTransformer;
|
|
import org.joda.time.DateTime;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import com.google.common.base.Joiner;
|
|
import com.google.common.base.Splitter;
|
|
import com.google.common.collect.Iterables;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Maps;
|
|
import com.google.common.collect.Sets;
|
|
|
|
import monasca.api.domain.exception.EntityNotFoundException;
|
|
import monasca.api.domain.model.alarmdefinition.AlarmDefinition;
|
|
import monasca.api.domain.model.alarmdefinition.AlarmDefinitionRepo;
|
|
import monasca.api.infrastructure.persistence.SubAlarmDefinitionQueries;
|
|
import monasca.api.resource.exception.Exceptions;
|
|
import monasca.common.hibernate.db.AlarmActionDb;
|
|
import monasca.common.hibernate.db.AlarmDb;
|
|
import monasca.common.hibernate.db.AlarmDefinitionDb;
|
|
import monasca.common.hibernate.db.SubAlarmDefinitionDb;
|
|
import monasca.common.hibernate.db.SubAlarmDefinitionDimensionDb;
|
|
import monasca.common.hibernate.db.SubAlarmDefinitionDimensionId;
|
|
import monasca.common.model.alarm.AggregateFunction;
|
|
import monasca.common.model.alarm.AlarmOperator;
|
|
import monasca.common.model.alarm.AlarmSeverity;
|
|
import monasca.common.model.alarm.AlarmState;
|
|
import monasca.common.model.alarm.AlarmSubExpression;
|
|
import monasca.common.model.metric.MetricDefinition;
|
|
|
|
/**
|
|
* Alarm repository implementation.
|
|
*/
|
|
public class AlarmDefinitionSqlRepoImpl
|
|
extends BaseSqlRepo
|
|
implements AlarmDefinitionRepo {
|
|
private static final ResultTransformer ALARM_DEF_RESULT_TRANSFORMER = getAlarmDefResultTransformer();
|
|
private static final String ID = "ID";
|
|
private static final String NAME = "NAME";
|
|
private static final String DESCRIPTION = "DESCRIPTION";
|
|
private static final String EXPRESSION = "EXPRESSION";
|
|
private static final String SEVERITY = "SEVERITY";
|
|
private static final String MATCH_BY = "MATCH_BY";
|
|
private static final String ACTIONS_ENABLED = "ACTIONS_ENABLED";
|
|
private static final String STATE = "STATES";
|
|
private static final String NOTIFICATION_ID = "NOTIFICATIONIDS";
|
|
private static final Joiner COMMA_JOINER = Joiner.on(',');
|
|
private static final Splitter COMMA_SPLITTER = Splitter.on(',').omitEmptyStrings().trimResults();
|
|
private static final Logger logger = LoggerFactory.getLogger(AlarmDefinitionSqlRepoImpl.class);
|
|
|
|
@Inject
|
|
public AlarmDefinitionSqlRepoImpl(@Named("orm") SessionFactory sessionFactory) {
|
|
super(sessionFactory);
|
|
}
|
|
|
|
@Override
|
|
public AlarmDefinition create(String tenantId, String id, String name, String description, String severity, String expression,
|
|
Map<String, AlarmSubExpression> subExpressions, List<String> matchBy, List<String> alarmActions, List<String> okActions,
|
|
List<String> undeterminedActions) {
|
|
logger.trace(ORM_LOG_MARKER, "create(...) entering...");
|
|
|
|
Transaction tx = null;
|
|
Session session = null;
|
|
try {
|
|
session = sessionFactory.openSession();
|
|
tx = session.beginTransaction();
|
|
|
|
final DateTime now = this.getUTCNow();
|
|
final AlarmDefinitionDb alarmDefinition = new AlarmDefinitionDb(
|
|
id,
|
|
tenantId,
|
|
name,
|
|
description,
|
|
expression,
|
|
AlarmSeverity.valueOf(severity.toUpperCase()),
|
|
matchBy == null || Iterables.isEmpty(matchBy) ? null : COMMA_JOINER.join(matchBy),
|
|
true,
|
|
now,
|
|
now,
|
|
null
|
|
);
|
|
session.save(alarmDefinition);
|
|
|
|
this.createSubExpressions(session, alarmDefinition, subExpressions);
|
|
|
|
// Persist actions
|
|
this.persistActions(session, alarmDefinition, AlarmState.ALARM, alarmActions);
|
|
this.persistActions(session, alarmDefinition, AlarmState.OK, okActions);
|
|
this.persistActions(session, alarmDefinition, AlarmState.UNDETERMINED, undeterminedActions);
|
|
|
|
tx.commit();
|
|
tx = null;
|
|
|
|
logger.debug(ORM_LOG_MARKER, "AlarmDefinition [ {} ] has been committed to database", alarmDefinition);
|
|
|
|
return new AlarmDefinition(
|
|
id,
|
|
name,
|
|
description,
|
|
severity,
|
|
expression,
|
|
matchBy,
|
|
true,
|
|
alarmActions == null ? Collections.<String>emptyList() : alarmActions,
|
|
okActions == null ? Collections.<String>emptyList() : okActions,
|
|
undeterminedActions == null ? Collections.<String>emptyList() : undeterminedActions
|
|
);
|
|
|
|
} catch (RuntimeException e) {
|
|
this.rollbackIfNotNull(tx);
|
|
throw e;
|
|
} finally {
|
|
if (session != null) {
|
|
session.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void deleteById(String tenantId, String alarmDefId) {
|
|
logger.trace(ORM_LOG_MARKER, "deleteById(...) entering...");
|
|
|
|
Session session = null;
|
|
Transaction tx = null;
|
|
try {
|
|
session = sessionFactory.openSession();
|
|
tx = session.beginTransaction();
|
|
|
|
final AlarmDefinitionDb result = (AlarmDefinitionDb) session
|
|
.getNamedQuery(AlarmDefinitionDb.Queries.FIND_BY_TENANT_AND_ID_NOT_DELETED)
|
|
.setString("tenant_id", tenantId)
|
|
.setString("id", alarmDefId)
|
|
.uniqueResult();
|
|
|
|
result.setDeletedAt(this.getUTCNow());
|
|
session.update(result);
|
|
|
|
// Cascade soft delete to alarms
|
|
session
|
|
.getNamedQuery(AlarmDb.Queries.DELETE_BY_ALARMDEFINITION_ID)
|
|
.setString("alarmDefinitionId", alarmDefId)
|
|
.executeUpdate();
|
|
|
|
tx.commit();
|
|
tx = null;
|
|
|
|
logger.debug(ORM_LOG_MARKER, "AlarmDefinition [ {} ] has been deleted from database", result);
|
|
|
|
} catch (Exception e) {
|
|
this.rollbackIfNotNull(tx);
|
|
throw e;
|
|
} finally {
|
|
if (session != null) {
|
|
session.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String exists(final String tenantId,
|
|
final String name) {
|
|
logger.trace(ORM_LOG_MARKER, "exists(...) entering...");
|
|
|
|
StatelessSession session = null;
|
|
try {
|
|
session = sessionFactory.openStatelessSession();
|
|
|
|
List<?> ids = session
|
|
.createCriteria(AlarmDefinitionDb.class)
|
|
.add(Restrictions.eq("tenantId", tenantId))
|
|
.add(Restrictions.eq("name", name))
|
|
.add(Restrictions.isNull("deletedAt"))
|
|
.setProjection(Projections.property("id"))
|
|
.setMaxResults(1)
|
|
.list();
|
|
|
|
final String existingId = CollectionUtils.isEmpty(ids) ? null : (String) ids.get(0);
|
|
|
|
if (null == existingId) {
|
|
logger.debug(ORM_LOG_MARKER, "No AlarmDefinition matched tenantId={} and name={}", tenantId, name);
|
|
}
|
|
|
|
return existingId;
|
|
} finally {
|
|
if (session != null) {
|
|
session.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
@SuppressWarnings("unchecked")
|
|
public List<AlarmDefinition> find(String tenantId, String name, Map<String, String> dimensions, List<String> sortBy, String offset, int limit) {
|
|
logger.trace(ORM_LOG_MARKER, "find(...) entering...");
|
|
if (sortBy != null && !sortBy.isEmpty()) {
|
|
throw Exceptions.unprocessableEntity("Sort_by is not implemented for the hibernate database type");
|
|
}
|
|
|
|
Session session = null;
|
|
List<AlarmDefinition> resultSet = Lists.newArrayList();
|
|
|
|
// TODO introduce criteria here, will make code significantly better
|
|
String query =
|
|
" SELECT t.id, t.tenant_id, t.name, t.description, t.expression, t.severity, t.match_by, "
|
|
+ "t.actions_enabled, aa.alarm_state AS states, aa.action_id AS notificationIds "
|
|
+ "FROM (SELECT distinct ad.id, ad.tenant_id, ad.name, ad.description, ad.expression, "
|
|
+ "ad.severity, ad.match_by, ad.actions_enabled, ad.created_at, ad.updated_at, ad.deleted_at "
|
|
+ "FROM alarm_definition AS ad LEFT OUTER JOIN sub_alarm_definition AS sad ON ad.id = sad.alarm_definition_id "
|
|
+ "LEFT OUTER JOIN sub_alarm_definition_dimension AS dim ON sad.id = dim.sub_alarm_definition_id %1$s "
|
|
+ "WHERE ad.tenant_id = :tenantId AND ad.deleted_at IS NULL %2$s %3$s) AS t "
|
|
+ "LEFT OUTER JOIN alarm_action AS aa ON t.id = aa.alarm_definition_id ORDER BY t.id, t.created_at";
|
|
|
|
StringBuilder sbWhere = new StringBuilder();
|
|
|
|
if (name != null) {
|
|
sbWhere.append(" and ad.name = :name");
|
|
}
|
|
|
|
if (offset != null) {
|
|
sbWhere.append(" and ad.id > :offset");
|
|
}
|
|
|
|
String limitPart = "";
|
|
if (limit > 0) {
|
|
limitPart = " limit :limit";
|
|
}
|
|
|
|
String sql = String.format(query, SubAlarmDefinitionQueries.buildJoinClauseFor(dimensions), sbWhere, limitPart);
|
|
|
|
try {
|
|
session = sessionFactory.openSession();
|
|
|
|
final Query qAlarmDefinition = session
|
|
.createSQLQuery(sql)
|
|
.setString("tenantId", tenantId)
|
|
.setResultTransformer(ALARM_DEF_RESULT_TRANSFORMER);
|
|
|
|
if (name != null) {
|
|
qAlarmDefinition.setString("name", name);
|
|
}
|
|
|
|
if (offset != null) {
|
|
qAlarmDefinition.setString("offset", offset);
|
|
}
|
|
|
|
if (limit > 0) {
|
|
qAlarmDefinition.setInteger("limit", limit + 1);
|
|
}
|
|
|
|
this.bindDimensionsToQuery(qAlarmDefinition, dimensions);
|
|
|
|
final List<Map<?,?>> alarmDefinitionDbList = qAlarmDefinition.list();
|
|
|
|
resultSet = CollectionUtils.isEmpty(alarmDefinitionDbList) ?
|
|
Lists.<AlarmDefinition>newArrayList() :
|
|
this.createAlarmDefinitions(alarmDefinitionDbList);
|
|
|
|
} finally {
|
|
if (session != null) {
|
|
session.close();
|
|
}
|
|
}
|
|
|
|
return resultSet;
|
|
}
|
|
|
|
@Override
|
|
@SuppressWarnings("unchecked")
|
|
public AlarmDefinition findById(String tenantId, String alarmDefId) {
|
|
logger.trace(ORM_LOG_MARKER, "findById(...) entering...");
|
|
|
|
Session session = null;
|
|
List<String> okActionIds = null;
|
|
List<String> alarmActionIds = null;
|
|
List<String> undeterminedActionIds = null;
|
|
|
|
try {
|
|
session = sessionFactory.openSession();
|
|
|
|
final AlarmDefinitionDb alarmDefinitionDb = (AlarmDefinitionDb) session
|
|
.getNamedQuery(AlarmDefinitionDb.Queries.FIND_BY_TENANT_AND_ID_NOT_DELETED)
|
|
.setString("tenant_id", tenantId)
|
|
.setString("id", alarmDefId).uniqueResult();
|
|
|
|
if (alarmDefinitionDb == null) {
|
|
throw new EntityNotFoundException("No alarm definition exists for tenantId=%s and id=%s", tenantId, alarmDefId);
|
|
}
|
|
|
|
final List<AlarmActionDb> alarmActionList = session
|
|
.getNamedQuery(AlarmActionDb.Queries.FIND_BY_TENANT_ID_AND_ALARMDEFINITION_ID_DISTINCT)
|
|
.setString("tenantId", tenantId)
|
|
.setString("alarmDefId", alarmDefId)
|
|
.list();
|
|
|
|
if(!CollectionUtils.isEmpty(alarmActionList)) {
|
|
|
|
logger.debug(ORM_LOG_MARKER, "Located {} AlarmActions for AlarmDefinition {}", alarmActionList.size(), alarmDefinitionDb);
|
|
|
|
okActionIds = Lists.newArrayList();
|
|
alarmActionIds = Lists.newArrayList();
|
|
undeterminedActionIds = Lists.newArrayList();
|
|
|
|
for (final AlarmActionDb alarmAction : alarmActionList) {
|
|
if (alarmAction.isInAlarmState(AlarmState.UNDETERMINED)) {
|
|
undeterminedActionIds.add(alarmAction.getAlarmActionId().getActionId());
|
|
} else if (alarmAction.isInAlarmState(AlarmState.OK)) {
|
|
okActionIds.add(alarmAction.getAlarmActionId().getActionId());
|
|
} else if (alarmAction.isInAlarmState(AlarmState.ALARM)) {
|
|
alarmActionIds.add(alarmAction.getAlarmActionId().getActionId());
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return new AlarmDefinition(
|
|
alarmDefinitionDb.getId(),
|
|
alarmDefinitionDb.getName(),
|
|
alarmDefinitionDb.getDescription(),
|
|
alarmDefinitionDb.getSeverity().name(),
|
|
alarmDefinitionDb.getExpression(),
|
|
this.splitStringIntoList(alarmDefinitionDb.getMatchBy()),
|
|
alarmDefinitionDb.isActionsEnabled(),
|
|
alarmActionIds == null ? Collections.<String>emptyList() : alarmActionIds,
|
|
okActionIds == null ? Collections.<String>emptyList() : okActionIds,
|
|
undeterminedActionIds == null ? Collections.<String>emptyList() : undeterminedActionIds
|
|
);
|
|
|
|
} finally {
|
|
if (session != null) {
|
|
session.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
@SuppressWarnings("unchecked")
|
|
public Map<String, MetricDefinition> findSubAlarmMetricDefinitions(String alarmDefId) {
|
|
logger.trace(ORM_LOG_MARKER, "findSubAlarmMetricDefinitions(...) entering...");
|
|
|
|
Session session = null;
|
|
Map<String, MetricDefinition> subAlarmMetricDefs = Maps.newHashMap();
|
|
|
|
try {
|
|
|
|
session = sessionFactory.openSession();
|
|
|
|
final List<SubAlarmDefinitionDb> subAlarmDefList = session
|
|
.getNamedQuery(SubAlarmDefinitionDb.Queries.BY_ALARMDEFINITION_ID)
|
|
.setString("id", alarmDefId)
|
|
.list();
|
|
final List<SubAlarmDefinitionDimensionDb> subAlarmDefDimensionList = session
|
|
.getNamedQuery(SubAlarmDefinitionDb.Queries.BY_ALARMDEFINITIONDIMENSION_SUBEXPRESSION_ID)
|
|
.setString("id", alarmDefId)
|
|
.list();
|
|
|
|
final Map<String, Map<String, String>> subAlarmDefDimensionMapExpression = this.mapAlarmDefDimensionExpression(
|
|
subAlarmDefDimensionList
|
|
);
|
|
|
|
for (SubAlarmDefinitionDb subAlarmDef : subAlarmDefList) {
|
|
String id = subAlarmDef.getId();
|
|
String metricName = subAlarmDef.getMetricName();
|
|
Map<String, String> dimensions = Collections.emptyMap();
|
|
if (subAlarmDefDimensionMapExpression.containsKey(id)) {
|
|
dimensions = subAlarmDefDimensionMapExpression.get(id);
|
|
}
|
|
subAlarmMetricDefs.put(id, new MetricDefinition(metricName, dimensions));
|
|
}
|
|
return subAlarmMetricDefs;
|
|
|
|
} finally {
|
|
if (session != null) {
|
|
session.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
@SuppressWarnings("unchecked")
|
|
public Map<String, AlarmSubExpression> findSubExpressions(String alarmDefId) {
|
|
logger.trace(ORM_LOG_MARKER, "findSubExpressions(...) entering...");
|
|
|
|
Session session = null;
|
|
Map<String, AlarmSubExpression> subExpressions = Maps.newHashMap();
|
|
try {
|
|
|
|
session = sessionFactory.openSession();
|
|
|
|
List<SubAlarmDefinitionDb> subAlarmDefList = session
|
|
.getNamedQuery(SubAlarmDefinitionDb.Queries.BY_ALARMDEFINITION_ID)
|
|
.setString("id", alarmDefId)
|
|
.list();
|
|
|
|
Query querySybAlarmDefDimension = session
|
|
.getNamedQuery(SubAlarmDefinitionDb.Queries.BY_ALARMDEFINITIONDIMENSION_SUBEXPRESSION_ID)
|
|
.setString("id", alarmDefId);
|
|
|
|
List<SubAlarmDefinitionDimensionDb> subAlarmDefDimensionList = querySybAlarmDefDimension.list();
|
|
|
|
Map<String, Map<String, String>> subAlarmDefDimensionMapExpression = mapAlarmDefDimensionExpression(subAlarmDefDimensionList);
|
|
|
|
for (SubAlarmDefinitionDb subAlarmDef : subAlarmDefList) {
|
|
String id = subAlarmDef.getId();
|
|
AggregateFunction function = AggregateFunction.fromJson(subAlarmDef.getFunction());
|
|
String metricName = subAlarmDef.getMetricName();
|
|
AlarmOperator operator = AlarmOperator.fromJson(subAlarmDef.getOperator());
|
|
double threshold = subAlarmDef.getThreshold();
|
|
int period = subAlarmDef.getPeriod();
|
|
int periods = subAlarmDef.getPeriods();
|
|
Map<String, String> dimensions = Collections.emptyMap();
|
|
|
|
if (subAlarmDefDimensionMapExpression.containsKey(id)) {
|
|
dimensions = subAlarmDefDimensionMapExpression.get(id);
|
|
}
|
|
|
|
subExpressions.put(id, new AlarmSubExpression(function, new MetricDefinition(metricName, dimensions), operator, threshold, period, periods));
|
|
}
|
|
|
|
return subExpressions;
|
|
|
|
} finally {
|
|
if (session != null) {
|
|
session.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void update(String tenantId, String id, boolean patch, String name, String description, String expression, List<String> matchBy,
|
|
String severity, boolean actionsEnabled, Collection<String> oldSubAlarmIds, Map<String, AlarmSubExpression> changedSubAlarms,
|
|
Map<String, AlarmSubExpression> newSubAlarms, List<String> alarmActions, List<String> okActions, List<String> undeterminedActions) {
|
|
logger.trace(ORM_LOG_MARKER, "update(...) entering...");
|
|
|
|
Transaction tx = null;
|
|
Session session = null;
|
|
try {
|
|
session = sessionFactory.openSession();
|
|
tx = session.beginTransaction();
|
|
|
|
final AlarmDefinitionDb alarmDefinitionDb = this.updateAlarmDefinition(
|
|
tenantId,
|
|
id,
|
|
name,
|
|
description,
|
|
expression,
|
|
matchBy,
|
|
severity,
|
|
actionsEnabled,
|
|
session
|
|
);
|
|
|
|
this.deleteOldSubAlarms(oldSubAlarmIds, session);
|
|
this.updateChangedSubAlarms(changedSubAlarms, session);
|
|
this.createSubExpressions(session, alarmDefinitionDb, newSubAlarms);
|
|
this.deleteOldAlarmActions(id, patch, alarmActions, okActions, undeterminedActions, session);
|
|
|
|
// Insert new actions
|
|
this.persistActions(session, alarmDefinitionDb, AlarmState.ALARM, alarmActions);
|
|
this.persistActions(session, alarmDefinitionDb, AlarmState.OK, okActions);
|
|
this.persistActions(session, alarmDefinitionDb, AlarmState.UNDETERMINED, undeterminedActions);
|
|
// Insert new actions
|
|
|
|
tx.commit();
|
|
tx = null;
|
|
} catch (RuntimeException e) {
|
|
this.rollbackIfNotNull(tx);
|
|
throw e;
|
|
} finally {
|
|
if (session != null) {
|
|
session.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void deleteOldAlarmActions(final String id,
|
|
final boolean patch,
|
|
final List<String> alarmActions,
|
|
final List<String> okActions,
|
|
final List<String> undeterminedActions,
|
|
final Session session) {
|
|
if (patch) {
|
|
this.deleteActions(session, id, AlarmState.ALARM, alarmActions);
|
|
this.deleteActions(session, id, AlarmState.OK, okActions);
|
|
this.deleteActions(session, id, AlarmState.UNDETERMINED, undeterminedActions);
|
|
} else {
|
|
session
|
|
.getNamedQuery(AlarmActionDb.Queries.DELETE_BY_ALARMDEFINITION_ID)
|
|
.setString("id", id)
|
|
.executeUpdate();
|
|
}
|
|
}
|
|
|
|
private void updateChangedSubAlarms(final Map<String, AlarmSubExpression> changedSubAlarms,
|
|
final Session session) {
|
|
if (!MapUtils.isEmpty(changedSubAlarms))
|
|
for (Map.Entry<String, AlarmSubExpression> entry : changedSubAlarms.entrySet()) {
|
|
final AlarmSubExpression sa = entry.getValue();
|
|
final String subAlarmDefinitionId = entry.getKey();
|
|
|
|
SubAlarmDefinitionDb subAlarmDefinitionDb = session.get(SubAlarmDefinitionDb.class, subAlarmDefinitionId);
|
|
subAlarmDefinitionDb.setOperator(sa.getOperator().name());
|
|
subAlarmDefinitionDb.setThreshold(sa.getThreshold());
|
|
subAlarmDefinitionDb.setUpdatedAt(new DateTime());
|
|
session.saveOrUpdate(subAlarmDefinitionDb);
|
|
}
|
|
}
|
|
|
|
private void deleteOldSubAlarms(final Collection<String> oldSubAlarmIds,
|
|
final Session session) {
|
|
if (!CollectionUtils.isEmpty(oldSubAlarmIds)) {
|
|
session
|
|
.getNamedQuery(SubAlarmDefinitionDb.Queries.DELETE_BY_IDS)
|
|
.setParameterList("ids", oldSubAlarmIds)
|
|
.executeUpdate();
|
|
}
|
|
}
|
|
|
|
private AlarmDefinitionDb updateAlarmDefinition(final String tenantId,
|
|
final String id,
|
|
final String name,
|
|
final String description,
|
|
final String expression,
|
|
final List<String> matchBy,
|
|
final String severity,
|
|
final boolean actionsEnabled,
|
|
final Session session) {
|
|
final AlarmDefinitionDb alarmDefinitionDb = (AlarmDefinitionDb) session
|
|
.getNamedQuery(AlarmDefinitionDb.Queries.FIND_BY_TENANT_ID_AND_ID)
|
|
.setString("tenantId", tenantId)
|
|
.setString("id", id)
|
|
.uniqueResult();
|
|
|
|
alarmDefinitionDb.setName(name);
|
|
alarmDefinitionDb.setDescription(description);
|
|
alarmDefinitionDb.setExpression(expression);
|
|
alarmDefinitionDb.setMatchBy(matchBy == null || Iterables.isEmpty(matchBy) ? null : COMMA_JOINER.join(matchBy));
|
|
alarmDefinitionDb.setSeverity(AlarmSeverity.valueOf(severity));
|
|
alarmDefinitionDb.setActionsEnabled(actionsEnabled);
|
|
|
|
session.saveOrUpdate(alarmDefinitionDb);
|
|
|
|
return alarmDefinitionDb;
|
|
}
|
|
|
|
private void deleteActions(final Session session,
|
|
final String id,
|
|
final AlarmState alarmState,
|
|
final List<String> actions) {
|
|
if (!CollectionUtils.isEmpty(actions))
|
|
session
|
|
.getNamedQuery(AlarmActionDb.Queries.DELETE_BY_ALARMDEFINITION_ID_AND_ALARMSTATE)
|
|
.setString("id", id)
|
|
.setString("alarmState", alarmState.name())
|
|
.executeUpdate();
|
|
}
|
|
|
|
private Map<String, Map<String, String>> mapAlarmDefDimensionExpression(List<SubAlarmDefinitionDimensionDb> subAlarmDefDimensionList) {
|
|
Map<String, Map<String, String>> subAlarmDefDimensionMapExpression = Maps.newHashMapWithExpectedSize(subAlarmDefDimensionList.size());
|
|
|
|
// Map expressions on sub_alarm_definition_dimension.sub_alarm_definition_id =
|
|
// sub_alarm_definition.id
|
|
for (SubAlarmDefinitionDimensionDb subAlarmDefDimension : subAlarmDefDimensionList) {
|
|
String subAlarmDefId = subAlarmDefDimension.getSubAlarmDefinitionDimensionId().getSubExpression().getId();
|
|
String name = subAlarmDefDimension.getSubAlarmDefinitionDimensionId().getDimensionName();
|
|
String value = subAlarmDefDimension.getValue();
|
|
|
|
if (subAlarmDefDimensionMapExpression.containsKey(subAlarmDefId)) {
|
|
subAlarmDefDimensionMapExpression.get(subAlarmDefId).put(name, value);
|
|
} else {
|
|
Map<String, String> expressionMap = Maps.newHashMap();
|
|
expressionMap.put(name, value);
|
|
subAlarmDefDimensionMapExpression.put(subAlarmDefId, expressionMap);
|
|
}
|
|
}
|
|
|
|
return subAlarmDefDimensionMapExpression;
|
|
}
|
|
|
|
private void bindDimensionsToQuery(Query query, Map<String, String> dimensions) {
|
|
if (dimensions != null) {
|
|
int i = 0;
|
|
for (Iterator<Map.Entry<String, String>> it = dimensions.entrySet().iterator(); it.hasNext(); i++) {
|
|
Map.Entry<String, String> entry = it.next();
|
|
query.setString("dname" + i, entry.getKey());
|
|
query.setString("dvalue" + i, entry.getValue());
|
|
}
|
|
}
|
|
}
|
|
|
|
private List<AlarmDefinition> createAlarmDefinitions(List<Map<?,?>> rows) {
|
|
final List<AlarmDefinition> result = new ArrayList<>();
|
|
Map<String, List<String>> okActionIdsMap = Maps.newHashMap();
|
|
Map<String, List<String>> alarmActionIdsMap = Maps.newHashMap();
|
|
Map<String, List<String>> undeterminedActionIdsMap = Maps.newHashMap();
|
|
Set<String> alarmDefinitionSet = Sets.newHashSet();
|
|
|
|
for (Map<?,?> row : rows) {
|
|
|
|
String alarmDefId = (String) row.get(ID);
|
|
String singleState = (String) row.get(STATE);
|
|
String notificationId = (String) row.get(NOTIFICATION_ID);
|
|
|
|
if (!okActionIdsMap.containsKey(alarmDefId)) {
|
|
okActionIdsMap.put(alarmDefId, Lists.<String>newArrayList());
|
|
}
|
|
if (!alarmActionIdsMap.containsKey(alarmDefId)) {
|
|
alarmActionIdsMap.put(alarmDefId, Lists.<String>newArrayList());
|
|
}
|
|
if (!undeterminedActionIdsMap.containsKey(alarmDefId)) {
|
|
undeterminedActionIdsMap.put(alarmDefId, Lists.<String>newArrayList());
|
|
}
|
|
|
|
if (singleState != null && notificationId != null) {
|
|
if (singleState.equals(AlarmState.UNDETERMINED.name())) {
|
|
undeterminedActionIdsMap.get(alarmDefId).add(notificationId);
|
|
}
|
|
if (singleState.equals(AlarmState.OK.name())) {
|
|
okActionIdsMap.get(alarmDefId).add(notificationId);
|
|
}
|
|
if (singleState.equals(AlarmState.ALARM.name())) {
|
|
alarmActionIdsMap.get(alarmDefId).add(notificationId);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (Map<?,?> row : rows) {
|
|
String alarmDefId = (String) row.get(ID);
|
|
|
|
if (!alarmDefinitionSet.contains(alarmDefId)) {
|
|
String name = (String) row.get(NAME);
|
|
String description = (String) row.get(DESCRIPTION);
|
|
String severity = (String) row.get(SEVERITY);
|
|
String expression = (String) row.get(EXPRESSION);
|
|
List<String> match = this.splitStringIntoList((String) row.get(MATCH_BY));
|
|
Boolean actionEnabled = (Boolean) row.get(ACTIONS_ENABLED);
|
|
|
|
AlarmDefinition ad = new AlarmDefinition(
|
|
alarmDefId,
|
|
name,
|
|
description,
|
|
severity,
|
|
expression,
|
|
match,
|
|
actionEnabled,
|
|
alarmActionIdsMap.get(alarmDefId),
|
|
okActionIdsMap.get(alarmDefId),
|
|
undeterminedActionIdsMap.get(alarmDefId)
|
|
);
|
|
|
|
result.add(ad);
|
|
}
|
|
|
|
alarmDefinitionSet.add(alarmDefId);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private List<String> splitStringIntoList(String str) {
|
|
return str == null ? Lists.<String>newArrayList() : Lists.newArrayList(COMMA_SPLITTER.split(str));
|
|
}
|
|
|
|
private void createSubExpressions(Session session,
|
|
AlarmDefinitionDb alarmDefinition,
|
|
Map<String, AlarmSubExpression> alarmSubExpressions) {
|
|
|
|
if (alarmSubExpressions != null) {
|
|
for (Map.Entry<String, AlarmSubExpression> subEntry : alarmSubExpressions.entrySet()) {
|
|
String subAlarmId = subEntry.getKey();
|
|
AlarmSubExpression subExpr = subEntry.getValue();
|
|
MetricDefinition metricDef = subExpr.getMetricDefinition();
|
|
|
|
// Persist sub-alarm
|
|
final DateTime now = this.getUTCNow();
|
|
SubAlarmDefinitionDb subAlarmDefinitionDb = new SubAlarmDefinitionDb(
|
|
subAlarmId,
|
|
alarmDefinition,
|
|
subExpr.getFunction().name(),
|
|
metricDef.name,
|
|
subExpr.getOperator().name(),
|
|
subExpr.getThreshold(),
|
|
subExpr.getPeriod(),
|
|
subExpr.getPeriods(),
|
|
now,
|
|
now
|
|
);
|
|
session.save(subAlarmDefinitionDb);
|
|
|
|
// Persist sub-alarm dimensions
|
|
if (!MapUtils.isEmpty(metricDef.dimensions)) {
|
|
SubAlarmDefinitionDimensionDb definitionDimension;
|
|
SubAlarmDefinitionDimensionId definitionDimensionId;
|
|
|
|
for (Map.Entry<String, String> dimEntry : metricDef.dimensions.entrySet()) {
|
|
definitionDimensionId = new SubAlarmDefinitionDimensionId(subAlarmDefinitionDb, dimEntry.getKey());
|
|
definitionDimension = new SubAlarmDefinitionDimensionDb(definitionDimensionId, dimEntry.getValue());
|
|
session.save(definitionDimension);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private void persistActions(final Session session,
|
|
final AlarmDefinitionDb alarmDefinition,
|
|
final AlarmState alarmState,
|
|
final List<String> actions) {
|
|
if (actions != null) {
|
|
for (String action : actions) {
|
|
session.save(new AlarmActionDb(alarmDefinition, alarmState, action));
|
|
}
|
|
}
|
|
}
|
|
|
|
// method extracted for code-readability
|
|
private static ResultTransformer getAlarmDefResultTransformer() {
|
|
return new ResultTransformer() {
|
|
private static final long serialVersionUID = -3052468375925339521L;
|
|
|
|
@Override
|
|
public Object transformTuple(final Object[] tuple, final String[] aliases) {
|
|
for (int i = 0, length = aliases.length; i < length; i++) {
|
|
aliases[i] = aliases[i].toUpperCase();
|
|
}
|
|
return AliasToEntityMapResultTransformer
|
|
.INSTANCE
|
|
.transformTuple(tuple, aliases);
|
|
}
|
|
|
|
@Override
|
|
public List transformList(final List collection) {
|
|
return AliasToEntityMapResultTransformer
|
|
.INSTANCE
|
|
.transformList(collection);
|
|
}
|
|
};
|
|
}
|
|
}
|