/** * Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org> * * 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 org.onebusaway.watchdog.api.realtime; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.Response; import org.onebusaway.geospatial.model.CoordinateBounds; import org.onebusaway.geospatial.model.CoordinatePoint; import org.onebusaway.transit_data_federation.impl.realtime.gtfs_realtime.MonitoredDataSource; import org.onebusaway.transit_data_federation.impl.realtime.gtfs_realtime.MonitoredResult; import org.onebusaway.watchdog.api.MetricResource; @Path("/metric/realtime/location") public class LocationResource extends MetricResource { @Path("/{agencyId}/total") @GET public Response getTotalLatLonCount(@PathParam("agencyId") String agencyId) { try { List<CoordinatePoint> totalLatLons = new ArrayList<CoordinatePoint>(); if (this.getDataSources() == null || this.getDataSources().isEmpty()) { _log.error("no configured data sources"); return Response.ok(error("total-lat-lon-count", "no configured data sources")).build(); } for (MonitoredDataSource mds : getDataSources()) { MonitoredResult result = mds.getMonitoredResult(); if (result == null) continue; for (String mAgencyId : result.getAgencyIds()) { if (agencyId.equals(mAgencyId)) { totalLatLons.addAll(result.getAllCoordinates()); } } } return Response.ok(ok("total-lat-lon-count", totalLatLons.size())).build(); } catch (Exception e) { _log.error("getTotalLatLonCount broke", e); return Response.ok(error("total-lat-lon-count", e)).build(); } } @Path("/{agencyId}/invalid") @GET public Response getInvalidLatLonCount(@PathParam("agencyId") String agencyId) { try { List<CoordinatePoint> invalidLatLons = new ArrayList<CoordinatePoint>(); if (this.getDataSources() == null || this.getDataSources().isEmpty()) { _log.error("no configured data sources"); return Response.ok(error("invalid-lat-lon-count", "no configured data sources")).build(); } for (MonitoredDataSource mds : getDataSources()) { MonitoredResult result = mds.getMonitoredResult(); if (result == null) continue; for (String mAgencyId : result.getAgencyIds()) { if (agencyId.equals(mAgencyId)) { invalidLatLons.addAll(findInvalidLatLon(agencyId, result.getAllCoordinates())); } } } return Response.ok(ok("invalid-lat-lon-count", invalidLatLons.size())).build(); } catch (Exception e) { _log.error("getInvalidLatLonCount broke", e); return Response.ok(error("invalid-lat-lon-count", e)).build(); } } @Path("/{agencyId}/invalid-lat-lons") @GET public Response getInvalidLatLons(@PathParam("agencyId") String agencyId) { try { List<CoordinatePoint> invalidLatLons = new ArrayList<CoordinatePoint>(); if (this.getDataSources() == null || this.getDataSources().isEmpty()) { _log.error("no configured data sources"); return Response.ok(error("invalid-lat-lons", "no configured data sources")).build(); } for (MonitoredDataSource mds : getDataSources()) { MonitoredResult result = mds.getMonitoredResult(); if (result == null) continue; for (String mAgencyId : result.getAgencyIds()) { if (agencyId.equals(mAgencyId)) { invalidLatLons.addAll(findInvalidLatLon(agencyId, result.getAllCoordinates())); } } } return Response.ok(ok("invalid-lat-lons", invalidLatLons)).build(); } catch (Exception e) { _log.error("getInvalidLatLons broke", e); return Response.ok(error("invalid-lat-lons", e)).build(); } } private Collection<CoordinatePoint> findInvalidLatLon(String agencyId, Set<CoordinatePoint> coordinatePoints) { List<CoordinatePoint> invalid = new ArrayList<CoordinatePoint>(); List<CoordinateBounds> bounds = getTDS().getAgencyIdsWithCoverageArea().get(agencyId); // ensure we have a valid bounding box for requested agency if (bounds == null || bounds.isEmpty()) { _log.warn("no bounds configured for agency " + agencyId); for (CoordinatePoint pt : coordinatePoints) { invalid.add(pt); } return invalid; } for (CoordinateBounds bound : bounds) { boolean found = false; for (CoordinatePoint pt : coordinatePoints) { // check if point is inside bounds if (bound.contains(pt)) { found = true; } if (!found) { invalid.add(pt); } } } _log.debug("agency " + agencyId + " had " + invalid.size() + " invalid out of " + coordinatePoints.size()); return invalid; } }