/* * Copyright 2016 JBoss Inc * * 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 io.apiman.manager.api.jdbc; import io.apiman.manager.api.beans.metrics.ClientUsagePerApiBean; import io.apiman.manager.api.beans.metrics.HistogramIntervalType; import io.apiman.manager.api.beans.metrics.ResponseStatsDataPoint; import io.apiman.manager.api.beans.metrics.ResponseStatsHistogramBean; import io.apiman.manager.api.beans.metrics.ResponseStatsPerClientBean; import io.apiman.manager.api.beans.metrics.ResponseStatsPerPlanBean; import io.apiman.manager.api.beans.metrics.ResponseStatsSummaryBean; import io.apiman.manager.api.beans.metrics.UsageDataPoint; import io.apiman.manager.api.beans.metrics.UsageHistogramBean; import io.apiman.manager.api.beans.metrics.UsagePerClientBean; import io.apiman.manager.api.beans.metrics.UsagePerPlanBean; import io.apiman.manager.api.core.IMetricsAccessor; import io.apiman.manager.api.core.metrics.AbstractMetricsAccessor; import io.apiman.manager.api.jdbc.handlers.ClientUsagePerApiHandler; import io.apiman.manager.api.jdbc.handlers.ResponseStatsHistogramHandler; import io.apiman.manager.api.jdbc.handlers.ResponseStatsPerClientHandler; import io.apiman.manager.api.jdbc.handlers.ResponseStatsPerPlanHandler; import io.apiman.manager.api.jdbc.handlers.ResponseStatsSummaryHandler; import io.apiman.manager.api.jdbc.handlers.UsageHistogramHandler; import io.apiman.manager.api.jdbc.handlers.UsagePerClientHandler; import io.apiman.manager.api.jdbc.handlers.UsagePerPlanHandler; import java.sql.SQLException; import java.util.Map; import javax.naming.InitialContext; import javax.sql.DataSource; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.ResultSetHandler; import org.joda.time.DateTime; /** * An implementation of a {@link IMetricsAccessor} that uses JDBC to query a relational * database for the appropriate information. * * @author eric.wittmann@gmail.com */ public class JdbcMetricsAccessor extends AbstractMetricsAccessor implements IMetricsAccessor { protected DataSource ds; /** * Constructor. * @param config */ public JdbcMetricsAccessor(Map<String, String> config) { String dsJndiLocation = config.get("datasource.jndi-location"); //$NON-NLS-1$ if (dsJndiLocation == null) { throw new RuntimeException("Missing datasource JNDI location from JdbcRegistry configuration."); //$NON-NLS-1$ } ds = lookupDS(dsJndiLocation); } /** * @see io.apiman.manager.api.core.IMetricsAccessor#getUsage(java.lang.String, java.lang.String, java.lang.String, io.apiman.manager.api.beans.metrics.HistogramIntervalType, org.joda.time.DateTime, org.joda.time.DateTime) */ @Override public UsageHistogramBean getUsage(String organizationId, String apiId, String version, HistogramIntervalType interval, DateTime from, DateTime to) { UsageHistogramBean rval = new UsageHistogramBean(); Map<Long, UsageDataPoint> index = generateHistogramSkeleton(rval, from, to, interval, UsageDataPoint.class, Long.class); try { QueryRunner run = new QueryRunner(ds); String gbColumn = groupByColumn(interval); String sql = "SELECT " + gbColumn + ", count(*) FROM gw_requests WHERE api_org_id = ? AND api_id = ? AND api_version = ? AND rstart >= ? AND rstart < ? GROUP BY " + gbColumn; //$NON-NLS-1$ //$NON-NLS-2$ ResultSetHandler<UsageHistogramBean> handler = new UsageHistogramHandler(rval, index); run.query(sql, handler, organizationId, apiId, version, from.getMillis(), to.getMillis()); } catch (SQLException e) { e.printStackTrace(); } return rval; } /** * @see io.apiman.manager.api.core.IMetricsAccessor#getUsagePerClient(java.lang.String, java.lang.String, java.lang.String, org.joda.time.DateTime, org.joda.time.DateTime) */ @Override public UsagePerClientBean getUsagePerClient(String organizationId, String apiId, String version, DateTime from, DateTime to) { try { QueryRunner run = new QueryRunner(ds); String sql = "SELECT client_id, count(*) FROM gw_requests WHERE api_org_id = ? AND api_id = ? AND api_version = ? AND rstart >= ? AND rstart < ? GROUP BY client_id"; //$NON-NLS-1$ ResultSetHandler<UsagePerClientBean> handler = new UsagePerClientHandler(); return run.query(sql, handler, organizationId, apiId, version, from.getMillis(), to.getMillis()); } catch (SQLException e) { e.printStackTrace(); return new UsagePerClientBean(); } } /** * @see io.apiman.manager.api.core.IMetricsAccessor#getUsagePerPlan(java.lang.String, java.lang.String, java.lang.String, org.joda.time.DateTime, org.joda.time.DateTime) */ @Override public UsagePerPlanBean getUsagePerPlan(String organizationId, String apiId, String version, DateTime from, DateTime to) { try { QueryRunner run = new QueryRunner(ds); String sql = "SELECT plan, count(*) FROM gw_requests WHERE api_org_id = ? AND api_id = ? AND api_version = ? AND rstart >= ? AND rstart < ? GROUP BY plan"; //$NON-NLS-1$ ResultSetHandler<UsagePerPlanBean> handler = new UsagePerPlanHandler(); return run.query(sql, handler, organizationId, apiId, version, from.getMillis(), to.getMillis()); } catch (SQLException e) { e.printStackTrace(); return new UsagePerPlanBean(); } } /** * @see io.apiman.manager.api.core.IMetricsAccessor#getResponseStats(java.lang.String, java.lang.String, java.lang.String, io.apiman.manager.api.beans.metrics.HistogramIntervalType, org.joda.time.DateTime, org.joda.time.DateTime) */ @Override public ResponseStatsHistogramBean getResponseStats(String organizationId, String apiId, String version, HistogramIntervalType interval, DateTime from, DateTime to) { ResponseStatsHistogramBean rval = new ResponseStatsHistogramBean(); Map<Long, ResponseStatsDataPoint> index = generateHistogramSkeleton(rval, from, to, interval, ResponseStatsDataPoint.class, Long.class); try { QueryRunner run = new QueryRunner(ds); String gbColumn = groupByColumn(interval); String sql = "SELECT " + gbColumn + ", resp_type, count(*) FROM gw_requests WHERE api_org_id = ? AND api_id = ? AND api_version = ? AND rstart >= ? AND rstart < ? GROUP BY resp_type," + gbColumn; //$NON-NLS-1$ //$NON-NLS-2$ ResultSetHandler<ResponseStatsHistogramBean> handler = new ResponseStatsHistogramHandler(rval, index); run.query(sql, handler, organizationId, apiId, version, from.getMillis(), to.getMillis()); } catch (SQLException e) { e.printStackTrace(); } return rval; } /** * @see io.apiman.manager.api.core.IMetricsAccessor#getResponseStatsSummary(java.lang.String, java.lang.String, java.lang.String, org.joda.time.DateTime, org.joda.time.DateTime) */ @Override public ResponseStatsSummaryBean getResponseStatsSummary(String organizationId, String apiId, String version, DateTime from, DateTime to) { try { QueryRunner run = new QueryRunner(ds); String sql = "SELECT resp_type, count(*) FROM gw_requests WHERE api_org_id = ? AND api_id = ? AND api_version = ? AND rstart >= ? AND rstart < ? GROUP BY resp_type"; //$NON-NLS-1$ ResultSetHandler<ResponseStatsSummaryBean> handler = new ResponseStatsSummaryHandler(); return run.query(sql, handler, organizationId, apiId, version, from.getMillis(), to.getMillis()); } catch (SQLException e) { e.printStackTrace(); return new ResponseStatsSummaryBean(); } } /** * @see io.apiman.manager.api.core.IMetricsAccessor#getResponseStatsPerClient(java.lang.String, java.lang.String, java.lang.String, org.joda.time.DateTime, org.joda.time.DateTime) */ @Override public ResponseStatsPerClientBean getResponseStatsPerClient(String organizationId, String apiId, String version, DateTime from, DateTime to) { try { QueryRunner run = new QueryRunner(ds); String sql = "SELECT client_id, resp_type, count(*) FROM gw_requests WHERE api_org_id = ? AND api_id = ? AND api_version = ? AND rstart >= ? AND rstart < ? GROUP BY client_id, resp_type"; //$NON-NLS-1$ ResultSetHandler<ResponseStatsPerClientBean> handler = new ResponseStatsPerClientHandler(); return run.query(sql, handler, organizationId, apiId, version, from.getMillis(), to.getMillis()); } catch (SQLException e) { e.printStackTrace(); return new ResponseStatsPerClientBean(); } } /** * @see io.apiman.manager.api.core.IMetricsAccessor#getResponseStatsPerPlan(java.lang.String, java.lang.String, java.lang.String, org.joda.time.DateTime, org.joda.time.DateTime) */ @Override public ResponseStatsPerPlanBean getResponseStatsPerPlan(String organizationId, String apiId, String version, DateTime from, DateTime to) { try { QueryRunner run = new QueryRunner(ds); String sql = "SELECT plan, resp_type, count(*) FROM gw_requests WHERE api_org_id = ? AND api_id = ? AND api_version = ? AND rstart >= ? AND rstart < ? GROUP BY plan, resp_type"; //$NON-NLS-1$ ResultSetHandler<ResponseStatsPerPlanBean> handler = new ResponseStatsPerPlanHandler(); return run.query(sql, handler, organizationId, apiId, version, from.getMillis(), to.getMillis()); } catch (SQLException e) { e.printStackTrace(); return new ResponseStatsPerPlanBean(); } } /** * @see io.apiman.manager.api.core.IMetricsAccessor#getClientUsagePerApi(java.lang.String, java.lang.String, java.lang.String, org.joda.time.DateTime, org.joda.time.DateTime) */ @Override public ClientUsagePerApiBean getClientUsagePerApi(String organizationId, String clientId, String version, DateTime from, DateTime to) { try { QueryRunner run = new QueryRunner(ds); String sql = "SELECT api_id, count(*) FROM gw_requests WHERE client_org_id = ? AND client_id = ? AND client_version = ? AND rstart >= ? AND rstart < ? GROUP BY api_id"; //$NON-NLS-1$ ResultSetHandler<ClientUsagePerApiBean> handler = new ClientUsagePerApiHandler(); return run.query(sql, handler, organizationId, clientId, version, from.getMillis(), to.getMillis()); } catch (SQLException e) { e.printStackTrace(); return new ClientUsagePerApiBean(); } } /** * Lookup the datasource in JNDI. * @param dsJndiLocation */ private static DataSource lookupDS(String dsJndiLocation) { DataSource ds; try { InitialContext ctx = new InitialContext(); ds = (DataSource) ctx.lookup(dsJndiLocation); } catch (Exception e) { throw new RuntimeException(e); } if (ds == null) { throw new RuntimeException("Datasource not found: " + dsJndiLocation); //$NON-NLS-1$ } return ds; } /** * Returns the group-by column to use for the given interval. * @param interval */ private static String groupByColumn(HistogramIntervalType interval) { return interval.name(); } }