private MeasurementBaseline calculateBaselineForGroup(
      int groupId,
      int definitionId,
      boolean userEntered,
      long startDate,
      long endDate,
      boolean save)
      throws DataNotAvailableException, BaselineCreationException {

    MeasurementAggregate agg =
        dataManager.getAggregate(
            subjectManager.getOverlord(), groupId, definitionId, startDate, endDate);

    Subject overlord = subjectManager.getOverlord();
    List<Integer> resourceIds = resourceManager.findImplicitResourceIdsByResourceGroup(groupId);
    List<MeasurementSchedule> schedules =
        measurementScheduleManager.findSchedulesByResourceIdsAndDefinitionId(
            overlord, ArrayUtils.unwrapCollection(resourceIds), definitionId);

    MeasurementBaseline baseline = null;
    for (MeasurementSchedule schedule : schedules) {
      // attach the entity, so we can find the baseline
      schedule = entityManager.merge(schedule);

      if (save && (schedule.getBaseline() != null)) {
        /*
         * If saving, make sure we're updating the existing one, if it exists
         */
        baseline = schedule.getBaseline();
      } else {
        /*
         * Otherwise, if we're not saving or if the the schedule doesn't have a current baseline, we create a new
         * baseline object
         */
        baseline = new MeasurementBaseline();

        if (save) {
          /*
           * But, if we *are* in save mode, then set the relationship so when we merge the schedule below it
           * persists this new baseline too
           */
          baseline.setSchedule(schedule);
        }
      }

      baseline.setUserEntered(userEntered);
      baseline.setMean(agg.getAvg());
      baseline.setMin(agg.getMin());
      baseline.setMax(agg.getMax());

      if (save) {
        entityManager.persist(baseline);
        entityManager.merge(schedule);
      }
    }

    // all baselines should be the same
    return baseline;
  }
  private MeasurementBaseline calculateBaseline(
      MeasurementSchedule schedule, boolean userEntered, long startDate, long endDate, boolean save)
      throws DataNotAvailableException, BaselineCreationException {
    /*
     * jmarques: 2007-10-26
     *
     * navigation from schedule to definition is safe here because the only caller to this method is
     * calculateAutoBaseline( Subject, Integer, long, long, boolean ), which uses entityManager.find, so the
     * schedule should still be attached since the transaction is propagated to this method
     */
    if (schedule.getDefinition().getNumericType() != NumericType.DYNAMIC) {
      throw new BaselineCreationException(
          "Baseline calculation is only valid for a dynamic measurement");
    }

    MeasurementAggregate agg =
        dataManager.getAggregate(
            subjectManager.getOverlord(), schedule.getId(), startDate, endDate);

    // attach the entity, so we can find the baseline
    schedule = entityManager.merge(schedule);

    MeasurementBaseline baseline = null;
    if (save && (schedule.getBaseline() != null)) {
      /*
       * If saving, make sure we're updating the existing one, if it exists
       */
      baseline = schedule.getBaseline();
    } else {
      /*
       * Otherwise, if we're not saving or if the the schedule doesn't have a current baseline, we create a new
       * baseline object
       */
      baseline = new MeasurementBaseline();

      if (save) {
        /*
         * But, if we *are* in save mode, then set the relationship so when we merge the schedule below it
         * persists this new baseline too
         */
        baseline.setSchedule(schedule);
      }
    }

    baseline.setUserEntered(userEntered);
    baseline.setMean(agg.getAvg());
    baseline.setMin(agg.getMin());
    baseline.setMax(agg.getMax());

    if (save) {
      entityManager.persist(baseline);
      entityManager.merge(schedule);
    }

    return baseline;
  }
  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  public MeasurementBaseline calculateAutoBaselineInNewTransaction(
      Subject subject, Integer measurementScheduleId, long startDate, long endDate, boolean save)
      throws BaselineCreationException, MeasurementNotFoundException {

    MeasurementBaseline baseline;
    MeasurementSchedule sched =
        entityManager.find(MeasurementSchedule.class, measurementScheduleId);

    if (sched != null) {
      Resource resource = sched.getResource();

      // only check permissions if the user is attempting to save a new baseline
      if (save
          && !authorizationManager.hasResourcePermission(
              subject, Permission.MANAGE_MEASUREMENTS, resource.getId())) {
        log.error(
            "Cannot calculate baseline - permission denied. "
                + "resource="
                + resource
                + "; user="******"; perm="
                + Permission.MANAGE_MEASUREMENTS);
        throw new PermissionException(
            "Cannot calculate baseline - you do not have permission on this resource");
      }
    } else {
      throw new MeasurementNotFoundException(
          "Scheduled measurement [" + measurementScheduleId + "] not found");
    }

    try {
      baseline = calculateBaseline(sched, true, startDate, endDate, save);
      if (save) {
        // We have changed the baseline information for the schedule, so remove the now outdated OOB
        // info.
        oobManager.removeOOBsForSchedule(subject, sched);
      }
    } catch (DataNotAvailableException e) {
      throw new BaselineCreationException(
          "Error fetching data for baseline calculation for measurementSchedule[id="
              + measurementScheduleId
              + "]");
    }

    return baseline;
  }
  @SuppressWarnings("unchecked")
  public PageList<CallTimeDataComposite> findCallTimeDataForResource(
      Subject subject, int scheduleId, long beginTime, long endTime, PageControl pageControl) {
    pageControl.initDefaultOrderingField(
        "SUM(value.total)/SUM(value.count)",
        PageOrdering.DESC); // only set if no ordering yet specified
    pageControl.addDefaultOrderingField(
        "key.callDestination", PageOrdering.ASC); // add this to sort, if not already specified

    MeasurementSchedule schedule = entityManager.find(MeasurementSchedule.class, scheduleId);
    int resourceId = schedule.getResource().getId();
    if (authorizationManager.canViewResource(subject, resourceId) == false) {
      throw new PermissionException(
          "User ["
              + subject
              + "] does not have permission to view call time data for measurementSchedule[id="
              + scheduleId
              + "] and resource[id="
              + resourceId
              + "]");
    }

    String query = CallTimeDataValue.QUERY_FIND_COMPOSITES_FOR_RESOURCE;

    Query queryWithOrderBy =
        PersistenceUtility.createQueryWithOrderBy(entityManager, query, pageControl);
    Query queryCount = PersistenceUtility.createCountQuery(this.entityManager, query);

    queryWithOrderBy.setParameter("scheduleId", scheduleId);
    queryWithOrderBy.setParameter("beginTime", beginTime);
    queryWithOrderBy.setParameter("endTime", endTime);

    List<CallTimeDataComposite> results = queryWithOrderBy.getResultList();

    queryCount.setParameter("scheduleId", scheduleId);
    queryCount.setParameter("beginTime", beginTime);
    queryCount.setParameter("endTime", endTime);

    // Because of the use of the GROUP BY clause, the result list count will be returned as
    // the number of rows, rather than as a single number.
    long count = queryCount.getResultList().size();

    return new PageList<CallTimeDataComposite>(results, (int) count, pageControl);
  }
    public MockInventoryManager() {
      super(pcConfig, null, pluginManager, new EventManager(pcConfig));
      platformType =
          new ResourceType(
              "platformResourceTypeName", "pluginName", ResourceCategory.PLATFORM, null);
      bundleHandlerType =
          new ResourceType("bhRTypeName", "pluginName", ResourceCategory.SERVER, platformType);
      serverTypeFS =
          new ResourceType(
              "typeName-fileSystem", "pluginName", ResourceCategory.SERVER, platformType);
      serverTypePC =
          new ResourceType(
              "typeName-plugConfig", "pluginName", ResourceCategory.SERVER, platformType);
      serverTypeRC =
          new ResourceType(
              "typeName-reSconfig", "pluginName", ResourceCategory.SERVER, platformType);
      serverTypeMT =
          new ResourceType("typeName-trait", "pluginName", ResourceCategory.SERVER, platformType);

      int id = 1;
      platform = new Resource("platformKey", "platformName", platformType);
      platform.setId(id++);
      bundleHandler = new Resource("bhKey", "bhName", bundleHandlerType);
      bundleHandler.setId(id++);
      bundleHandler.setParentResource(platform);
      bundleHandler.setUuid(UUID.randomUUID().toString());
      serverFS = new Resource("serverKey-fileSystem", "serverName-fileSystem", serverTypeFS);
      serverFS.setId(id++);
      serverFS.setParentResource(platform);
      serverPC = new Resource("serverKey-plugConfig", "serverName-plugConfig", serverTypePC);
      serverPC.setId(id++);
      serverPC.setParentResource(platform);
      serverRC = new Resource("serverKey-resConfig", "serverName-resConfig", serverTypeRC);
      serverRC.setId(id++);
      serverRC.setParentResource(platform);
      serverMT = new Resource("serverKey-traitConfig", "serverName-traitConfig", serverTypeMT);
      serverMT.setId(id++);
      serverMT.setParentResource(platform);

      typeResourceMap.put(platformType, platform);
      typeResourceMap.put(bundleHandlerType, bundleHandler);
      typeResourceMap.put(serverTypeFS, serverFS);
      typeResourceMap.put(serverTypePC, serverPC);
      typeResourceMap.put(serverTypeRC, serverRC);
      typeResourceMap.put(serverTypeMT, serverMT);

      ResourceContainer platformContainer = new ResourceContainer(platform, null);
      ResourceContainer bundleHandlerContainer = new ResourceContainer(bundleHandler, null);
      ResourceContainer serverContainerFS = new ResourceContainer(serverFS, null);
      ResourceContainer serverContainerPC = new ResourceContainer(serverPC, null);
      ResourceContainer serverContainerRC = new ResourceContainer(serverRC, null);
      ResourceContainer serverContainerMT = new ResourceContainer(serverMT, null);
      idResourceContainerMap.put(platform.getId(), platformContainer);
      idResourceContainerMap.put(bundleHandler.getId(), bundleHandlerContainer);
      idResourceContainerMap.put(serverFS.getId(), serverContainerFS);
      idResourceContainerMap.put(serverPC.getId(), serverContainerPC);
      idResourceContainerMap.put(serverRC.getId(), serverContainerRC);
      idResourceContainerMap.put(serverMT.getId(), serverContainerMT);

      bundleHandlerContainer.setResourceContext(new MockResourceContext(bundleHandler));

      // each different resource type that supports bundle deployments needs to define its
      // bundle configuration to denote where the base directory location is found.
      // Today we support four ways: via plugin config property, resource config property,
      // measurement trait value, or strictly on the root file system (using no resource specific
      // value)
      ResourceTypeBundleConfiguration rtbc =
          new ResourceTypeBundleConfiguration(new Configuration());
      rtbc.addBundleDestinationBaseDirectory(
          BUNDLE_CONFIG_NAME_FS, Context.fileSystem.name(), BUNDLE_CONFIG_CONTEXT_VALUE_FS, null);
      serverTypeFS.setResourceTypeBundleConfiguration(rtbc);

      rtbc = new ResourceTypeBundleConfiguration(new Configuration());
      rtbc.addBundleDestinationBaseDirectory(
          BUNDLE_CONFIG_NAME_PC,
          Context.pluginConfiguration.name(),
          BUNDLE_CONFIG_CONTEXT_VALUE_PC,
          null);
      serverTypePC.setResourceTypeBundleConfiguration(rtbc);

      rtbc = new ResourceTypeBundleConfiguration(new Configuration());
      rtbc.addBundleDestinationBaseDirectory(
          BUNDLE_CONFIG_NAME_RC,
          Context.resourceConfiguration.name(),
          BUNDLE_CONFIG_CONTEXT_VALUE_RC,
          null);
      serverTypeRC.setResourceTypeBundleConfiguration(rtbc);

      rtbc = new ResourceTypeBundleConfiguration(new Configuration());
      rtbc.addBundleDestinationBaseDirectory(
          BUNDLE_CONFIG_NAME_MT,
          Context.measurementTrait.name(),
          BUNDLE_CONFIG_CONTEXT_VALUE_MT,
          null);
      serverTypeMT.setResourceTypeBundleConfiguration(rtbc);

      // each different resource needs to specify where exactly it wants the bundles deployed
      // using the different contexts that are supported.
      Configuration pluginConfiguration = new Configuration();
      pluginConfiguration.put(
          new PropertySimple(BUNDLE_CONFIG_CONTEXT_VALUE_PC, BUNDLE_CONFIG_LOCATION_PC));
      serverPC.setPluginConfiguration(pluginConfiguration);

      Configuration resourceConfiguration = new Configuration();
      resourceConfiguration.put(
          new PropertySimple(BUNDLE_CONFIG_CONTEXT_VALUE_RC, BUNDLE_CONFIG_LOCATION_RC));
      serverRC.setResourceConfiguration(resourceConfiguration);

      MeasurementDefinition definition =
          new MeasurementDefinition(serverTypeMT, BUNDLE_CONFIG_CONTEXT_VALUE_MT);
      definition.setDataType(DataType.TRAIT);
      definition.setId(123);
      MeasurementSchedule schedule = new MeasurementSchedule(definition, serverMT);
      schedule.setId(123123);
      MeasurementScheduleRequest scheduleRequest = new MeasurementScheduleRequest(schedule);
      Set<MeasurementScheduleRequest> schedules = new HashSet<MeasurementScheduleRequest>(1);
      schedules.add(scheduleRequest);
      serverContainerMT.setMeasurementSchedule(schedules);
    }