All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencastproject.statistics.remote.StatisticsServiceRemoteImpl Maven / Gradle / Ivy

There is a newer version: 16.7
Show newest version
/**
 * Licensed to The Apereo Foundation under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 *
 * The Apereo Foundation licenses this file to you under the Educational
 * Community 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://opensource.org/licenses/ecl2.txt
 *
 * 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.opencastproject.statistics.remote;

import static java.nio.charset.StandardCharsets.UTF_8;
import static javax.servlet.http.HttpServletResponse.SC_OK;

import org.opencastproject.serviceregistry.api.RemoteBase;
import org.opencastproject.statistics.api.DataResolution;
import org.opencastproject.statistics.api.ResourceType;
import org.opencastproject.statistics.api.StatisticsProvider;
import org.opencastproject.statistics.api.StatisticsService;
import org.opencastproject.statistics.api.TimeSeries;
import org.opencastproject.statistics.api.TimeSeriesProvider;
import org.opencastproject.util.doc.rest.RestService;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.codehaus.jettison.json.JSONException;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import javax.ws.rs.Path;

/**
 * A proxy to a remote series service.
 */
@Path("/")
@RestService(name = "statisticsservice", title = "Statistics Service Remote", abstractText = "This service provides statistics.", notes = {
    "All paths above are relative to the REST endpoint base (something like http://your.server/files)",
    "If the service is down or not working it will return a status 503, this means the the underlying service is "
        + "not working and is either restarting or has failed",
    "A status code 500 means a general failure has occurred which is not recoverable and was not anticipated. In "
        + "other words, there is a bug! You should file an error report with your server logs from the time when the "
        + "error occurred: Opencast Issue Tracker"})
public class StatisticsServiceRemoteImpl extends RemoteBase implements StatisticsService {

  private static final JSONParser jsonParser = new JSONParser();

  public StatisticsServiceRemoteImpl() {
    super(JOB_TYPE);
  }

  @Override
  public Set getProviders() {
    final HttpGet get = new HttpGet("providers.json");
    final HttpResponse response = getResponse(get, SC_OK);
    try {
      if (response != null) {
        return jsonToProviders(EntityUtils.toString(response.getEntity(), UTF_8));
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    } finally {
      closeConnection(response);
    }
    throw new RuntimeException("Unable to get providers from remote service");
  }

  @Override
  public Set getProviders(ResourceType resourceType) {
    return getProviders().stream().filter(p -> p.getResourceType().equals(resourceType)).collect(Collectors.toSet());
  }

  @Override
  public Optional getProvider(String providerId) {
    return getProviders().stream().filter(p -> p.getId().equals(providerId)).findAny();
  }

  @Override
  public TimeSeries getTimeSeriesData(StatisticsProvider provider, String resourceId, Instant from, Instant to, DataResolution resolution, ZoneId zoneId) {
    final List queryStringParams = new ArrayList<>();
    queryStringParams.add(new BasicNameValuePair("resourceId", resourceId));
    queryStringParams.add(new BasicNameValuePair("from", from.toString()));
    queryStringParams.add(new BasicNameValuePair("to", to.toString()));
    queryStringParams.add(new BasicNameValuePair("resolution", resolution.name()));
    queryStringParams.add(new BasicNameValuePair("zoneId", zoneId.getId()));
    final HttpGet get = new HttpGet("timeseries/" + provider.getId() + ".json?" + URLEncodedUtils.format(queryStringParams, UTF_8));
    final HttpResponse response = getResponse(get, SC_OK);
    try {
      if (response != null) {
        return jsonToTimeSeries(EntityUtils.toString(response.getEntity(), UTF_8));
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    } finally {
      closeConnection(response);
    }
    throw new RuntimeException("Unable to get time series data from remote service");
  }

  @Override
  public void writeDuration(String organizationId, String measurementName, String retentionPolicy,
          String organizationIdResourceName, String fieldName, TimeUnit temporalResolution, Duration duration) {
    final List queryStringParams = new ArrayList<>();
    queryStringParams.add(new BasicNameValuePair("organizationId", organizationId));
    queryStringParams.add(new BasicNameValuePair("measurementName", measurementName));
    queryStringParams.add(new BasicNameValuePair("retentionPolicy", retentionPolicy));
    queryStringParams.add(new BasicNameValuePair("organizationIdResourceName", organizationIdResourceName));
    queryStringParams.add(new BasicNameValuePair("fieldName", fieldName));
    queryStringParams.add(new BasicNameValuePair("temporalResolution", temporalResolution.toString()));
    queryStringParams.add(new BasicNameValuePair("duration", duration.toString()));

    final HttpGet get = new HttpGet("/writeDuration?" + URLEncodedUtils.format(queryStringParams, UTF_8));
    final HttpResponse response = getResponse(get, SC_OK);
    closeConnection(response);
    throw new RuntimeException("Unable to get time series data from remote service");
  }

  @SuppressWarnings("unchecked")
  private TimeSeries jsonToTimeSeries(String json) throws ParseException {
    final JSONObject jsonObject = (JSONObject) jsonParser.parse(json);
    final JSONArray labelsJson = (JSONArray) jsonObject.get("labels");
    final JSONArray valuesJson = (JSONArray) jsonObject.get("values");
    final List labels = new ArrayList<>();
    final List values = new ArrayList<>();
    for (int i = 0; i < labelsJson.size(); i++) {
      labels.add((String) labelsJson.get(i));
      values.add((Double) valuesJson.get(i));
    }
    return new TimeSeries(labels, values, (Double) jsonObject.getOrDefault("total", null));
  }

  private Set jsonToProviders(String json) throws ParseException, JSONException {
    final JSONArray providersJson = (JSONArray) jsonParser.parse(json);
    final Set providers = new HashSet<>();
    for (Object object : providersJson) {
      JSONObject jsonObject = (JSONObject) object;
      final String idJson = (String) jsonObject.get("id");
      final String titleJson = (String) jsonObject.get("title");
      final String descriptionJson = (String) jsonObject.get("description");
      final String resourceTypeJson = (String) jsonObject.get("resourceType");
      if (jsonObject.containsKey("dataResolutions")) {
        final JSONArray resolutionsJson = (JSONArray) jsonObject.get("dataResolutions");
        providers.add(new TimeSeriesProvider() {
          @Override
          public String getId() {
            return idJson;
          }

          @Override
          public ResourceType getResourceType() {
            return ResourceType.valueOf(resourceTypeJson);
          }

          @Override
          public String getTitle() {
            return titleJson;
          }

          @Override
          public String getDescription() {
            return descriptionJson;
          }

          @Override
          public TimeSeries getValues(String resourceId, Instant from, Instant to, DataResolution resolution, ZoneId zoneId) {
            throw new IllegalStateException("This method should never get called");
          }

          @Override
          public Set getDataResolutions() {
            final Set result = new HashSet<>();
            for (Object obj : resolutionsJson) {
              result.add(DataResolution.valueOf((String) obj));
            }
            return result;
          }
        });
      } else {
        providers.add(new StatisticsProvider() {
          @Override
          public String getId() {
            return idJson;
          }

          @Override
          public ResourceType getResourceType() {
            return ResourceType.valueOf(resourceTypeJson);
          }

          @Override
          public String getTitle() {
            return titleJson;
          }

          @Override
          public String getDescription() {
            return descriptionJson;
          }
        });
      }
    }
    return providers;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy