Search in sources :

Example 1 with ServiceStatistics

use of org.opencastproject.serviceregistry.api.ServiceStatistics in project opencast by opencast.

the class ServicesEndpoint method getServices.

@GET
@Path("services.json")
@Produces(MediaType.APPLICATION_JSON)
@RestQuery(description = "Returns the list of services", name = "services", restParameters = { @RestParameter(name = "limit", description = "The maximum number of items to return per page", isRequired = false, type = RestParameter.Type.INTEGER), @RestParameter(name = "offset", description = "The offset", isRequired = false, type = RestParameter.Type.INTEGER), @RestParameter(name = "filter", description = "Filter results by name, host, actions, status or free text query", isRequired = false, type = STRING), @RestParameter(name = "sort", description = "The sort order.  May include any " + "of the following: host, name, running, queued, completed,  meanRunTime, meanQueueTime, " + "status. The sort suffix must be :asc for ascending sort order and :desc for descending.", isRequired = false, type = STRING) }, reponses = { @RestResponse(description = "Returns the list of services from Opencast", responseCode = HttpServletResponse.SC_OK) }, returnDescription = "The list of services")
public Response getServices(@QueryParam("limit") final int limit, @QueryParam("offset") final int offset, @QueryParam("filter") String filter, @QueryParam("sort") String sort) throws Exception {
    Option<String> sortOpt = Option.option(StringUtils.trimToNull(sort));
    ServicesListQuery query = new ServicesListQuery();
    EndpointUtil.addRequestFiltersToQuery(filter, query);
    String fName = null;
    if (query.getName().isSome())
        fName = StringUtils.trimToNull(query.getName().get());
    String fHostname = null;
    if (query.getHostname().isSome())
        fHostname = StringUtils.trimToNull(query.getHostname().get());
    String fStatus = null;
    if (query.getStatus().isSome())
        fStatus = StringUtils.trimToNull(query.getStatus().get());
    String fFreeText = null;
    if (query.getFreeText().isSome())
        fFreeText = StringUtils.trimToNull(query.getFreeText().get());
    List<Service> services = new ArrayList<Service>();
    for (ServiceStatistics stats : serviceRegistry.getServiceStatistics()) {
        Service service = new Service(stats);
        if (fName != null && !StringUtils.equalsIgnoreCase(service.getName(), fName))
            continue;
        if (fHostname != null && !StringUtils.equalsIgnoreCase(service.getHost(), fHostname))
            continue;
        if (fStatus != null && !StringUtils.equalsIgnoreCase(service.getStatus().toString(), fStatus))
            continue;
        if (query.getActions().isSome()) {
            ServiceState serviceState = service.getStatus();
            if (query.getActions().get()) {
                if (ServiceState.NORMAL == serviceState)
                    continue;
            } else {
                if (ServiceState.NORMAL != serviceState)
                    continue;
            }
        }
        if (fFreeText != null && !StringUtils.containsIgnoreCase(service.getName(), fFreeText) && !StringUtils.containsIgnoreCase(service.getHost(), fFreeText) && !StringUtils.containsIgnoreCase(service.getStatus().toString(), fFreeText))
            continue;
        services.add(service);
    }
    int total = services.size();
    if (sortOpt.isSome()) {
        Set<SortCriterion> sortCriteria = RestUtils.parseSortQueryParameter(sortOpt.get());
        if (!sortCriteria.isEmpty()) {
            try {
                SortCriterion sortCriterion = sortCriteria.iterator().next();
                Collections.sort(services, new ServiceStatisticsComparator(sortCriterion.getFieldName(), sortCriterion.getOrder() == SearchQuery.Order.Ascending));
            } catch (Exception ex) {
                logger.warn("Failed to sort services collection.", ex);
            }
        }
    }
    List<JValue> jsonList = new ArrayList<JValue>();
    for (Service s : new SmartIterator<Service>(limit, offset).applyLimitAndOffset(services)) {
        jsonList.add(s.toJSON());
    }
    return RestUtils.okJsonList(jsonList, offset, limit, total);
}
Also used : ServiceState(org.opencastproject.serviceregistry.api.ServiceState) ArrayList(java.util.ArrayList) RestService(org.opencastproject.util.doc.rest.RestService) ServiceStatistics(org.opencastproject.serviceregistry.api.ServiceStatistics) SortCriterion(org.opencastproject.matterhorn.search.SortCriterion) JValue(com.entwinemedia.fn.data.json.JValue) ServicesListQuery(org.opencastproject.index.service.resources.list.query.ServicesListQuery) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) RestQuery(org.opencastproject.util.doc.rest.RestQuery)

Example 2 with ServiceStatistics

use of org.opencastproject.serviceregistry.api.ServiceStatistics in project opencast by opencast.

the class ServerEndpoint method getServers.

@GET
@Path("servers.json")
@Produces(MediaType.APPLICATION_JSON)
@RestQuery(description = "Returns the list of servers", name = "servers", restParameters = { @RestParameter(name = "limit", description = "The maximum number of items to return per page", isRequired = false, type = INTEGER), @RestParameter(name = "offset", description = "The offset", isRequired = false, type = INTEGER), @RestParameter(name = "filter", description = "Filter results by hostname, status or free text query", isRequired = false, type = STRING), @RestParameter(name = "sort", description = "The sort order.  May include any " + "of the following: COMPLETED (jobs), CORES, HOSTNAME, MAINTENANCE, MEANQUEUETIME (mean for jobs), " + "MEANRUNTIME (mean for jobs), ONLINE, QUEUED (jobs), RUNNING (jobs)." + "The suffix must be :ASC for ascending or :DESC for descending sort order (e.g. HOSTNAME:DESC).", isRequired = false, type = STRING) }, reponses = { @RestResponse(description = "Returns the list of jobs from Opencast", responseCode = HttpServletResponse.SC_OK) }, returnDescription = "The list of servers")
public Response getServers(@QueryParam("limit") final int limit, @QueryParam("offset") final int offset, @QueryParam("filter") String filter, @QueryParam("sort") String sort) throws Exception {
    ServersListQuery query = new ServersListQuery();
    EndpointUtil.addRequestFiltersToQuery(filter, query);
    query.setLimit(limit);
    query.setOffset(offset);
    List<JSONObject> servers = new ArrayList<>();
    // Get service statistics for all hosts and services
    List<ServiceStatistics> servicesStatistics = serviceRegistry.getServiceStatistics();
    for (HostRegistration server : serviceRegistry.getHostRegistrations()) {
        // Calculate statistics per server
        long jobsCompleted = 0;
        int jobsRunning = 0;
        int jobsQueued = 0;
        long sumMeanRuntime = 0;
        long sumMeanQueueTime = 0;
        int totalServiceOnHost = 0;
        int offlineJobProducerServices = 0;
        int totalJobProducerServices = 0;
        Set<String> serviceTypes = new HashSet<>();
        for (ServiceStatistics serviceStat : servicesStatistics) {
            if (server.getBaseUrl().equals(serviceStat.getServiceRegistration().getHost())) {
                totalServiceOnHost++;
                jobsCompleted += serviceStat.getFinishedJobs();
                jobsRunning += serviceStat.getRunningJobs();
                jobsQueued += serviceStat.getQueuedJobs();
                // mean time values are given in milliseconds,
                // we should convert them to seconds,
                // because the adminNG UI expect it in this format
                sumMeanRuntime += TimeUnit.MILLISECONDS.toSeconds(serviceStat.getMeanRunTime());
                sumMeanQueueTime += TimeUnit.MILLISECONDS.toSeconds(serviceStat.getMeanQueueTime());
                if (!serviceStat.getServiceRegistration().isOnline() && serviceStat.getServiceRegistration().isJobProducer()) {
                    offlineJobProducerServices++;
                    totalJobProducerServices++;
                } else if (serviceStat.getServiceRegistration().isJobProducer()) {
                    totalJobProducerServices++;
                }
                serviceTypes.add(serviceStat.getServiceRegistration().getServiceType());
            }
        }
        long meanRuntime = totalServiceOnHost > 0 ? Math.round((double) sumMeanRuntime / totalServiceOnHost) : 0L;
        long meanQueueTime = totalServiceOnHost > 0 ? Math.round((double) sumMeanQueueTime / totalServiceOnHost) : 0L;
        boolean vOnline = server.isOnline();
        boolean vMaintenance = server.isMaintenanceMode();
        String vHostname = server.getBaseUrl();
        int vCores = server.getCores();
        if (query.getHostname().isSome() && !StringUtils.equalsIgnoreCase(vHostname, query.getHostname().get()))
            continue;
        if (query.getStatus().isSome()) {
            if (StringUtils.equalsIgnoreCase(ServersListProvider.SERVER_STATUS_ONLINE, query.getStatus().get()) && !vOnline)
                continue;
            if (StringUtils.equalsIgnoreCase(ServersListProvider.SERVER_STATUS_OFFLINE, query.getStatus().get()) && vOnline)
                continue;
            if (StringUtils.equalsIgnoreCase(ServersListProvider.SERVER_STATUS_MAINTENANCE, query.getStatus().get()) && !vMaintenance)
                continue;
        }
        if (query.getFreeText().isSome() && !StringUtils.containsIgnoreCase(vHostname, query.getFreeText().get()) && !StringUtils.containsIgnoreCase(server.getIpAddress(), query.getFreeText().get()))
            continue;
        JSONObject jsonServer = new JSONObject();
        jsonServer.put(KEY_ONLINE, vOnline && offlineJobProducerServices <= totalJobProducerServices / 2);
        jsonServer.put(KEY_MAINTENANCE, vMaintenance);
        jsonServer.put(KEY_HOSTNAME, vHostname);
        jsonServer.put(KEY_CORES, vCores);
        jsonServer.put(KEY_RUNNING, jobsRunning);
        jsonServer.put(KEY_QUEUED, jobsQueued);
        jsonServer.put(KEY_COMPLETED, jobsCompleted);
        jsonServer.put(KEY_MEAN_RUN_TIME, meanRuntime);
        jsonServer.put(KEY_MEAN_QUEUE_TIME, meanQueueTime);
        servers.add(jsonServer);
    }
    // Sorting
    Sort sortKey = Sort.HOSTNAME;
    Boolean ascending = true;
    if (StringUtils.isNotBlank(sort)) {
        try {
            SortCriterion sortCriterion = RestUtils.parseSortQueryParameter(sort).iterator().next();
            sortKey = Sort.valueOf(sortCriterion.getFieldName().toUpperCase());
            ascending = SearchQuery.Order.Ascending == sortCriterion.getOrder() || SearchQuery.Order.None == sortCriterion.getOrder();
        } catch (WebApplicationException ex) {
            logger.warn("Failed to parse sort criterion \"{}\", invalid format.", sort);
        } catch (IllegalArgumentException ex) {
            logger.warn("Can not apply sort criterion \"{}\", no field with this name.", sort);
        }
    }
    JSONArray jsonList = new JSONArray();
    if (!servers.isEmpty()) {
        Collections.sort(servers, new ServerComparator(sortKey, ascending));
        jsonList.addAll(new SmartIterator(query.getLimit().getOrElse(0), query.getOffset().getOrElse(0)).applyLimitAndOffset(servers));
    }
    return RestUtils.okJsonList(getServersListAsJson(jsonList), query.getOffset().getOrElse(0), query.getLimit().getOrElse(0), servers.size());
}
Also used : WebApplicationException(javax.ws.rs.WebApplicationException) SmartIterator(org.opencastproject.util.SmartIterator) ArrayList(java.util.ArrayList) JSONArray(org.json.simple.JSONArray) ServiceStatistics(org.opencastproject.serviceregistry.api.ServiceStatistics) JSONObject(org.json.simple.JSONObject) SortCriterion(org.opencastproject.matterhorn.search.SortCriterion) HostRegistration(org.opencastproject.serviceregistry.api.HostRegistration) ServersListQuery(org.opencastproject.index.service.resources.list.query.ServersListQuery) HashSet(java.util.HashSet) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) RestQuery(org.opencastproject.util.doc.rest.RestQuery)

Example 3 with ServiceStatistics

use of org.opencastproject.serviceregistry.api.ServiceStatistics in project opencast by opencast.

the class ServiceRegistryJpaImpl method getServiceStatistics.

/**
 * Gets performance and runtime statistics for each known service registration.
 * For the statistics, only jobs created within the time interval [startDate, endDate] are being considered
 *
 * @param startDate
 *          Only jobs created after this data are considered for statistics
 * @param endDate
 *          Only jobs created before this data are considered for statistics
 * @return the service statistics
 * @throws ServiceRegistryException
 *           if there is a problem accessing the service registry
 */
private List<ServiceStatistics> getServiceStatistics(Date startDate, Date endDate) throws ServiceRegistryException {
    EntityManager em = null;
    try {
        em = emf.createEntityManager();
        Map<Long, JaxbServiceStatistics> statsMap = new HashMap<Long, JaxbServiceStatistics>();
        // Make sure we also include the services that have no processing history so far
        List<ServiceRegistrationJpaImpl> services = em.createNamedQuery("ServiceRegistration.getAll").getResultList();
        for (ServiceRegistrationJpaImpl s : services) {
            statsMap.put(s.getId(), new JaxbServiceStatistics(s));
        }
        Query query = em.createNamedQuery("ServiceRegistration.statistics");
        query.setParameter("minDateCreated", startDate, TemporalType.TIMESTAMP);
        query.setParameter("maxDateCreated", endDate, TemporalType.TIMESTAMP);
        List queryResults = query.getResultList();
        for (Object result : queryResults) {
            Object[] oa = (Object[]) result;
            Number serviceRegistrationId = ((Number) oa[0]);
            if (serviceRegistrationId == null || serviceRegistrationId.longValue() == 0)
                continue;
            Status status = Status.values()[((Number) oa[1]).intValue()];
            Number count = (Number) oa[2];
            Number meanQueueTime = (Number) oa[3];
            Number meanRunTime = (Number) oa[4];
            // The statistics query returns a cartesian product, so we need to iterate over them to build up the objects
            JaxbServiceStatistics stats = statsMap.get(serviceRegistrationId.longValue());
            if (stats == null)
                continue;
            // the status will be null if there are no jobs at all associated with this service registration
            if (status != null) {
                switch(status) {
                    case RUNNING:
                        stats.setRunningJobs(count.intValue());
                        break;
                    case QUEUED:
                    case DISPATCHING:
                        stats.setQueuedJobs(count.intValue());
                        break;
                    case FINISHED:
                        stats.setMeanRunTime(meanRunTime.longValue());
                        stats.setMeanQueueTime(meanQueueTime.longValue());
                        stats.setFinishedJobs(count.intValue());
                        break;
                    default:
                        break;
                }
            }
        }
        List<ServiceStatistics> stats = new ArrayList<ServiceStatistics>(statsMap.values());
        Collections.sort(stats, new Comparator<ServiceStatistics>() {

            @Override
            public int compare(ServiceStatistics o1, ServiceStatistics o2) {
                ServiceRegistration reg1 = o1.getServiceRegistration();
                ServiceRegistration reg2 = o2.getServiceRegistration();
                int typeComparison = reg1.getServiceType().compareTo(reg2.getServiceType());
                return typeComparison == 0 ? reg1.getHost().compareTo(reg2.getHost()) : typeComparison;
            }
        });
        return stats;
    } catch (Exception e) {
        throw new ServiceRegistryException(e);
    } finally {
        if (em != null)
            em.close();
    }
}
Also used : HttpStatus(org.apache.http.HttpStatus) Status(org.opencastproject.job.api.Job.Status) Query(javax.persistence.Query) TypedQuery(javax.persistence.TypedQuery) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ServiceRegistrationJpaImpl(org.opencastproject.serviceregistry.impl.jpa.ServiceRegistrationJpaImpl) URISyntaxException(java.net.URISyntaxException) NoResultException(javax.persistence.NoResultException) ConfigurationException(org.osgi.service.cm.ConfigurationException) ServiceRegistryException(org.opencastproject.serviceregistry.api.ServiceRegistryException) InvalidSyntaxException(org.osgi.framework.InvalidSyntaxException) TrustedHttpClientException(org.opencastproject.security.api.TrustedHttpClientException) PersistenceException(javax.persistence.PersistenceException) RollbackException(javax.persistence.RollbackException) NotFoundException(org.opencastproject.util.NotFoundException) ServiceRegistryException(org.opencastproject.serviceregistry.api.ServiceRegistryException) ServiceStatistics(org.opencastproject.serviceregistry.api.ServiceStatistics) JaxbServiceStatistics(org.opencastproject.serviceregistry.api.JaxbServiceStatistics) EntityManager(javax.persistence.EntityManager) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) JaxbServiceStatistics(org.opencastproject.serviceregistry.api.JaxbServiceStatistics) ServiceRegistration(org.opencastproject.serviceregistry.api.ServiceRegistration)

Example 4 with ServiceStatistics

use of org.opencastproject.serviceregistry.api.ServiceStatistics in project opencast by opencast.

the class ServiceRegistryJpaImpl method activate.

public void activate(ComponentContext cc) {
    logger.info("Activate service registry");
    // Find this host's url
    if (cc == null || StringUtils.isBlank(cc.getBundleContext().getProperty(OpencastConstants.SERVER_URL_PROPERTY))) {
        hostName = UrlSupport.DEFAULT_BASE_URL;
    } else {
        hostName = cc.getBundleContext().getProperty(OpencastConstants.SERVER_URL_PROPERTY);
    }
    // Check hostname for sanity. It should be the hosts URL with protocol but without any part of the service paths.
    if (hostName.endsWith("/")) {
        logger.warn("The configured value of {} ends with '/'. This is very likely a configuration error which could " + "lead to services not working properly. Note that this configuration should not contain any part of " + "the service paths.", OpencastConstants.SERVER_URL_PROPERTY);
    }
    // Clean all undispatchable jobs that were orphaned when this host was last deactivated
    cleanUndispatchableJobs(hostName);
    // Register JMX beans with statistics
    try {
        List<ServiceStatistics> serviceStatistics = getServiceStatistics();
        hostsStatistics = new HostsStatistics(serviceStatistics);
        servicesStatistics = new ServicesStatistics(hostName, serviceStatistics);
        jobsStatistics = new JobsStatistics(hostName);
        jmxBeans.add(JmxUtil.registerMXBean(hostsStatistics, JMX_HOSTS_STATISTICS_TYPE));
        jmxBeans.add(JmxUtil.registerMXBean(servicesStatistics, JMX_SERVICES_STATISTICS_TYPE));
        jmxBeans.add(JmxUtil.registerMXBean(jobsStatistics, JMX_JOBS_STATISTICS_TYPE));
    } catch (ServiceRegistryException e) {
        logger.error("Error registering JMX statistic beans", e);
    }
    // Find the jobs URL
    if (cc == null || StringUtils.isBlank(cc.getBundleContext().getProperty("org.opencastproject.jobs.url"))) {
        jobHost = hostName;
    } else {
        jobHost = cc.getBundleContext().getProperty("org.opencastproject.jobs.url");
    }
    // Register this host
    try {
        float maxLoad = Runtime.getRuntime().availableProcessors();
        if (cc != null && StringUtils.isNotBlank(cc.getBundleContext().getProperty(OPT_MAXLOAD))) {
            try {
                maxLoad = Float.parseFloat(cc.getBundleContext().getProperty(OPT_MAXLOAD));
                logger.info("Max load has been manually to {}", maxLoad);
            } catch (NumberFormatException e) {
                logger.warn("Configuration key '{}' is not an integer. Falling back to the number of cores ({})", OPT_MAXLOAD, maxLoad);
            }
        }
        logger.info("Node maximum load set to {}", maxLoad);
        String address = InetAddress.getByName(URI.create(hostName).getHost()).getHostAddress();
        long maxMemory = Runtime.getRuntime().maxMemory();
        int cores = Runtime.getRuntime().availableProcessors();
        registerHost(hostName, address, maxMemory, cores, maxLoad);
    } catch (Exception e) {
        throw new IllegalStateException("Unable to register host " + hostName + " in the service registry", e);
    }
    // Track any services from this host that need to be added to the service registry
    if (cc != null) {
        try {
            tracker = new RestServiceTracker(cc.getBundleContext());
            tracker.open(true);
        } catch (InvalidSyntaxException e) {
            logger.error("Invalid filter syntax:", e);
            throw new IllegalStateException(e);
        }
    }
    // Whether a service accepts a job whose load exceeds the host’s max load
    if (cc != null) {
        acceptJobLoadsExeedingMaxLoad = getOptContextProperty(cc, ACCEPT_JOB_LOADS_EXCEEDING_PROPERTY).map(Strings.toBool).getOrElse(DEFAULT_ACCEPT_JOB_LOADS_EXCEEDING);
    }
    systemLoad = getHostLoads(emf.createEntityManager());
}
Also used : JobsStatistics(org.opencastproject.serviceregistry.impl.jmx.JobsStatistics) HostsStatistics(org.opencastproject.serviceregistry.impl.jmx.HostsStatistics) ServicesStatistics(org.opencastproject.serviceregistry.impl.jmx.ServicesStatistics) ServiceRegistryException(org.opencastproject.serviceregistry.api.ServiceRegistryException) URISyntaxException(java.net.URISyntaxException) NoResultException(javax.persistence.NoResultException) ConfigurationException(org.osgi.service.cm.ConfigurationException) ServiceRegistryException(org.opencastproject.serviceregistry.api.ServiceRegistryException) InvalidSyntaxException(org.osgi.framework.InvalidSyntaxException) TrustedHttpClientException(org.opencastproject.security.api.TrustedHttpClientException) PersistenceException(javax.persistence.PersistenceException) RollbackException(javax.persistence.RollbackException) NotFoundException(org.opencastproject.util.NotFoundException) ServiceStatistics(org.opencastproject.serviceregistry.api.ServiceStatistics) JaxbServiceStatistics(org.opencastproject.serviceregistry.api.JaxbServiceStatistics) InvalidSyntaxException(org.osgi.framework.InvalidSyntaxException)

Aggregations

ServiceStatistics (org.opencastproject.serviceregistry.api.ServiceStatistics)4 ArrayList (java.util.ArrayList)3 URISyntaxException (java.net.URISyntaxException)2 NoResultException (javax.persistence.NoResultException)2 PersistenceException (javax.persistence.PersistenceException)2 RollbackException (javax.persistence.RollbackException)2 GET (javax.ws.rs.GET)2 Path (javax.ws.rs.Path)2 Produces (javax.ws.rs.Produces)2 SortCriterion (org.opencastproject.matterhorn.search.SortCriterion)2 TrustedHttpClientException (org.opencastproject.security.api.TrustedHttpClientException)2 JaxbServiceStatistics (org.opencastproject.serviceregistry.api.JaxbServiceStatistics)2 ServiceRegistryException (org.opencastproject.serviceregistry.api.ServiceRegistryException)2 NotFoundException (org.opencastproject.util.NotFoundException)2 RestQuery (org.opencastproject.util.doc.rest.RestQuery)2 InvalidSyntaxException (org.osgi.framework.InvalidSyntaxException)2 ConfigurationException (org.osgi.service.cm.ConfigurationException)2 JValue (com.entwinemedia.fn.data.json.JValue)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1