public PutMetricAlarmResponseType putMetricAlarm(PutMetricAlarmType request)
      throws CloudWatchException {
    PutMetricAlarmResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();

    try {
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_PUTMETRICALARM, ctx);

      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final String accountId = ownerFullName.getAccountNumber();
      final Boolean actionsEnabled = validateActionsEnabled(request.getActionsEnabled(), true);
      final Map<String, String> dimensionMap =
          TransformationFunctions.DimensionsToMap.INSTANCE.apply(
              validateDimensions(request.getDimensions()));
      final Collection<String> alarmActions =
          validateActions(request.getAlarmActions(), dimensionMap, "AlarmActions");
      final String alarmDescription = validateAlarmDescription(request.getAlarmDescription());
      final String alarmName = validateAlarmName(request.getAlarmName(), true);
      final ComparisonOperator comparisonOperator =
          validateComparisonOperator(request.getComparisonOperator(), true);
      Integer evaluationPeriods = validateEvaluationPeriods(request.getEvaluationPeriods(), true);
      final Integer period = validatePeriod(request.getPeriod(), true);
      validatePeriodAndEvaluationPeriodsNotAcrossDays(period, evaluationPeriods);
      final Collection<String> insufficientDataActions =
          validateActions(
              request.getInsufficientDataActions(), dimensionMap, "InsufficientDataActions");
      final String metricName = validateMetricName(request.getMetricName(), true);
      final String namespace = validateNamespace(request.getNamespace(), true);
      final Collection<String> okActions =
          validateActions(request.getOkActions(), dimensionMap, "OKActions");
      final Statistic statistic = validateStatistic(request.getStatistic(), true);
      final Double threshold = validateThreshold(request.getThreshold(), true);
      final Units unit = validateUnits(request.getUnit(), true);
      if (AlarmManager.countMetricAlarms(accountId) >= 5000) {
        throw new LimitExceededException("The maximum limit of 5000 alarms would be exceeded.");
      }
      AlarmManager.putMetricAlarm(
          accountId,
          actionsEnabled,
          alarmActions,
          alarmDescription,
          alarmName,
          comparisonOperator,
          dimensionMap,
          evaluationPeriods,
          insufficientDataActions,
          metricName,
          getMetricTypeFromNamespace(namespace),
          namespace,
          okActions,
          period,
          statistic,
          threshold,
          unit);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
  public DescribeAlarmsForMetricResponseType describeAlarmsForMetric(
      DescribeAlarmsForMetricType request) throws CloudWatchException {
    DescribeAlarmsForMetricResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();

    try {
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_DESCRIBEALARMSFORMETRIC, ctx);
      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final String accountId = ownerFullName.getAccountNumber();
      final Map<String, String> dimensionMap =
          TransformationFunctions.DimensionsToMap.INSTANCE.apply(
              validateDimensions(request.getDimensions()));
      final String metricName = validateMetricName(request.getMetricName(), true);
      final String namespace = validateNamespace(request.getNamespace(), true);
      final Integer period = validatePeriod(request.getPeriod(), false);
      final Statistic statistic = validateStatistic(request.getStatistic(), false);
      final Units unit = validateUnits(request.getUnit(), true);
      Collection<AlarmEntity> results =
          AlarmManager.describeAlarmsForMetric(
              accountId, dimensionMap, metricName, namespace, period, statistic, unit);
      MetricAlarms metricAlarms = new MetricAlarms();
      metricAlarms.setMember(
          Lists.newArrayList(
              Collections2.<AlarmEntity, MetricAlarm>transform(
                  results, TransformationFunctions.AlarmEntityToMetricAlarm.INSTANCE)));
      reply.getDescribeAlarmsForMetricResult().setMetricAlarms(metricAlarms);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
  public DisableAlarmActionsResponseType disableAlarmActions(DisableAlarmActionsType request)
      throws EucalyptusCloudException {
    DisableAlarmActionsResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();

    try {
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_DISABLEALARMACTIONS, ctx);
      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final String accountId = ownerFullName.getAccountNumber();
      Collection<String> alarmNames = validateAlarmNames(request.getAlarmNames(), true);
      AlarmManager.disableAlarmActions(accountId, alarmNames);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
  public DescribeAlarmsResponseType describeAlarms(DescribeAlarmsType request)
      throws CloudWatchException {
    DescribeAlarmsResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();

    try {
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_DESCRIBEALARMS, ctx);

      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final String accountId = ownerFullName.getAccountNumber();
      final String actionPrefix = validateActionPrefix(request.getActionPrefix(), false);
      final String alarmNamePrefix = validateAlarmNamePrefix(request.getAlarmNamePrefix(), false);
      final Collection<String> alarmNames = validateAlarmNames(request.getAlarmNames(), false);
      validateNotBothAlarmNamesAndAlarmNamePrefix(alarmNames, alarmNamePrefix);
      final Integer maxRecords = validateMaxRecords(request.getMaxRecords());
      final String nextToken = request.getNextToken();
      final StateValue stateValue = validateStateValue(request.getStateValue(), false);
      List<AlarmEntity> results =
          AlarmManager.describeAlarms(
              accountId,
              actionPrefix,
              alarmNamePrefix,
              alarmNames,
              maxRecords,
              stateValue,
              nextToken);
      if (maxRecords != null && results.size() == maxRecords) {
        reply
            .getDescribeAlarmsResult()
            .setNextToken(results.get(results.size() - 1).getNaturalId());
      }
      MetricAlarms metricAlarms = new MetricAlarms();
      metricAlarms.setMember(
          Lists.newArrayList(
              Collections2.<AlarmEntity, MetricAlarm>transform(
                  results, TransformationFunctions.AlarmEntityToMetricAlarm.INSTANCE)));
      reply.getDescribeAlarmsResult().setMetricAlarms(metricAlarms);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
  public SetAlarmStateResponseType setAlarmState(SetAlarmStateType request)
      throws CloudWatchException {
    SetAlarmStateResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();
    try {

      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_SETALARMSTATE, ctx);
      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final String accountId = ownerFullName.getAccountNumber();
      final String alarmName = validateAlarmName(request.getAlarmName(), true);
      final String stateReason = validateStateReason(request.getStateReason(), true);
      final String stateReasonData = validateStateReasonData(request.getStateReasonData(), false);
      final StateValue stateValue = validateStateValue(request.getStateValue(), true);
      AlarmManager.setAlarmState(accountId, alarmName, stateReason, stateReasonData, stateValue);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }
  public DescribeAlarmHistoryResponseType describeAlarmHistory(DescribeAlarmHistoryType request)
      throws CloudWatchException {
    DescribeAlarmHistoryResponseType reply = request.getReply();
    final Context ctx = Contexts.lookup();

    try {
      // IAM Action Check
      checkActionPermission(PolicySpec.CLOUDWATCH_DESCRIBEALARMHISTORY, ctx);

      final OwnerFullName ownerFullName = ctx.getUserFullName();
      final String accountId = ownerFullName.getAccountNumber();
      final String alarmName = validateAlarmName(request.getAlarmName(), false);
      final Date endDate = validateEndDate(request.getEndDate(), false);
      final Date startDate = validateStartDate(request.getStartDate(), false);
      validateDateOrder(startDate, endDate, "StartDate", "EndDate", false, false);
      final HistoryItemType historyItemType =
          validateHistoryItemType(request.getHistoryItemType(), false);
      final Integer maxRecords = validateMaxRecords(request.getMaxRecords());
      final String nextToken = request.getNextToken();
      List<AlarmHistory> results =
          AlarmManager.describeAlarmHistory(
              accountId, alarmName, endDate, historyItemType, maxRecords, startDate, nextToken);
      if (maxRecords != null && results.size() == maxRecords) {
        reply
            .getDescribeAlarmHistoryResult()
            .setNextToken(results.get(results.size() - 1).getNaturalId());
      }
      AlarmHistoryItems alarmHistoryItems = new AlarmHistoryItems();
      alarmHistoryItems.setMember(
          Lists.newArrayList(
              Collections2.<AlarmHistory, AlarmHistoryItem>transform(
                  results, TransformationFunctions.AlarmHistoryToAlarmHistoryItem.INSTANCE)));
      reply.getDescribeAlarmHistoryResult().setAlarmHistoryItems(alarmHistoryItems);
    } catch (Exception ex) {
      handleException(ex);
    }
    return reply;
  }