Merge "Issue #2673 Add ability to query only ref times to Data Access Layer." into development

Former-commit-id: eb07c44098abe7f72b578e24a4a7ea7e92dc655c
This commit is contained in:
Nate Jensen 2014-03-04 11:42:51 -06:00 committed by Gerrit Code Review
commit 9b94434a78
14 changed files with 164 additions and 65 deletions

View file

@ -45,11 +45,12 @@ import com.raytheon.uf.common.time.TimeRange;
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Oct 24, 2012 njensen Initial creation * Oct 24, 2012 njensen Initial creation
* Feb 14, 2013 1614 bsteffen Refactor data access framework to use * Feb 14, 2013 1614 bsteffen Refactor data access framework to use
* single request. * single request.
* Mar 03, 2014 2673 bsteffen Add ability to query only ref times.
* *
* </pre> * </pre>
* *
@ -68,8 +69,24 @@ public class DataAccessLayer {
* @throws TimeAgnosticDataException * @throws TimeAgnosticDataException
*/ */
public static DataTime[] getAvailableTimes(IDataRequest request) { public static DataTime[] getAvailableTimes(IDataRequest request) {
return getAvailableTimes(request, false);
}
/**
* Gets the times of available data to the request
*
* @param request
* the request to find available times for
* @param refTimeOnly
* true if only unique refTimes should be returned(without a
* forecastHr)
* @return the available times that match the request
* @throws TimeAgnosticDataException
*/
public static DataTime[] getAvailableTimes(IDataRequest request,
boolean refTimeOnly) {
IDataFactory factory = getFactory(request); IDataFactory factory = getFactory(request);
return factory.getAvailableTimes(request); return factory.getAvailableTimes(request, refTimeOnly);
} }
/** /**

View file

@ -49,11 +49,12 @@ import com.raytheon.uf.common.time.TimeRange;
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Oct 10, 2012 njensen Initial creation * Oct 10, 2012 njensen Initial creation
* Feb 14, 2013 1614 bsteffen Refactor data access framework to use * Feb 14, 2013 1614 bsteffen Refactor data access framework to use
* single request. * single request.
* Mar 03, 2014 2673 bsteffen Add ability to query only ref times.
* *
* </pre> * </pre>
* *
@ -70,10 +71,14 @@ public interface IDataFactory {
* *
* @param request * @param request
* the request to find matching times for * the request to find matching times for
* @param refTimeOnly
* true if only unique refTimes should be returned(without a
* forecastHr)
* @return the times that have data available for this request * @return the times that have data available for this request
* @throws TimeAgnosticDataException * @throws TimeAgnosticDataException
*/ */
public DataTime[] getAvailableTimes(IDataRequest request) public DataTime[] getAvailableTimes(IDataRequest request,
boolean refTimeOnly)
throws TimeAgnosticDataException; throws TimeAgnosticDataException;
/** /**

View file

@ -21,6 +21,7 @@ package com.raytheon.uf.common.dataaccess.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -53,10 +54,14 @@ import com.raytheon.uf.common.time.TimeRange;
* Jan 17, 2013 bsteffen Initial creation * Jan 17, 2013 bsteffen Initial creation
* Feb 14, 2013 1614 bsteffen Refactor data access framework to use * Feb 14, 2013 1614 bsteffen Refactor data access framework to use
* single request. * single request.
* Nov 26, 2013 2537 bsteffen Fix NPEs for dataTimes and timeRange requests. * Nov 26, 2013 2537 bsteffen Fix NPEs for dataTimes and timeRange
* Jan 14, 2014 2667 mnash Change getGridData and getGeometryData methods * equests.
* to throw exception by default * Jan 14, 2014 2667 mnash Change getGridData and getGeometryData
* Jan 21, 2014 2667 bclement changed timeRange buildDbQueryRequest method to query against valid times * methods to throw exception by default
* Jan 21, 2014 2667 bclement changed timeRange buildDbQueryRequest
* method to query against valid times
* Mar 03, 2014 2673 bsteffen Add ability to query only ref times.
*
* *
* </pre> * </pre>
* *
@ -68,6 +73,8 @@ public abstract class AbstractDataPluginFactory extends AbstractDataFactory {
protected static final String FIELD_DATATIME = "dataTime"; protected static final String FIELD_DATATIME = "dataTime";
protected static final String FIELD_REFTIME = FIELD_DATATIME + ".refTime";
protected static final String FIELD_VALID_START = FIELD_DATATIME protected static final String FIELD_VALID_START = FIELD_DATATIME
+ ".validPeriod.start"; + ".validPeriod.start";
@ -76,11 +83,29 @@ public abstract class AbstractDataPluginFactory extends AbstractDataFactory {
protected static final String DBQUERY_PLUGIN_NAME_KEY = "pluginName"; protected static final String DBQUERY_PLUGIN_NAME_KEY = "pluginName";
public DataTime[] getAvailableTimes(IDataRequest request) @Override
public DataTime[] getAvailableTimes(IDataRequest request,
boolean refTimeOnly)
throws TimeAgnosticDataException { throws TimeAgnosticDataException {
return this.getAvailableTimes(request, null); if (refTimeOnly) {
DbQueryRequest dbQueryRequest = buildDbQueryRequest(request);
dbQueryRequest.setDistinct(Boolean.TRUE);
dbQueryRequest.addRequestField(FIELD_REFTIME);
DbQueryResponse dbQueryResponse = this.executeDbQueryRequest(
dbQueryRequest, request.toString());
List<DataTime> times = new ArrayList<DataTime>(dbQueryResponse
.getResults().size());
for (Map<String, Object> result : dbQueryResponse.getResults()) {
Date refTime = (Date) result.get(FIELD_REFTIME);
times.add(new DataTime(refTime));
}
return times.toArray(new DataTime[0]);
} else {
return this.getAvailableTimes(request, null);
}
} }
@Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public DataTime[] getAvailableTimes(IDataRequest request, public DataTime[] getAvailableTimes(IDataRequest request,
BinOffset binOffset) throws TimeAgnosticDataException { BinOffset binOffset) throws TimeAgnosticDataException {
@ -109,6 +134,7 @@ public abstract class AbstractDataPluginFactory extends AbstractDataFactory {
return dataTimes.toArray(new DataTime[dataTimes.size()]); return dataTimes.toArray(new DataTime[dataTimes.size()]);
} }
@Override
public IGeometryData[] getGeometryData(IDataRequest request, public IGeometryData[] getGeometryData(IDataRequest request,
DataTime... times) { DataTime... times) {
validateRequest(request); validateRequest(request);
@ -119,6 +145,7 @@ public abstract class AbstractDataPluginFactory extends AbstractDataFactory {
return getGeometryData(request, dbQueryResponse); return getGeometryData(request, dbQueryResponse);
} }
@Override
public IGeometryData[] getGeometryData(IDataRequest request, public IGeometryData[] getGeometryData(IDataRequest request,
TimeRange timeRange) { TimeRange timeRange) {
validateRequest(request); validateRequest(request);
@ -129,6 +156,7 @@ public abstract class AbstractDataPluginFactory extends AbstractDataFactory {
return getGeometryData(request, dbQueryResponse); return getGeometryData(request, dbQueryResponse);
} }
@Override
public IGridData[] getGridData(IDataRequest request, DataTime... times) { public IGridData[] getGridData(IDataRequest request, DataTime... times) {
validateRequest(request); validateRequest(request);
DbQueryRequest dbQueryRequest = this DbQueryRequest dbQueryRequest = this
@ -138,6 +166,7 @@ public abstract class AbstractDataPluginFactory extends AbstractDataFactory {
return getGridData(request, dbQueryResponse); return getGridData(request, dbQueryResponse);
} }
@Override
public IGridData[] getGridData(IDataRequest request, TimeRange timeRange) { public IGridData[] getGridData(IDataRequest request, TimeRange timeRange) {
validateRequest(request); validateRequest(request);
DbQueryRequest dbQueryRequest = this.buildDbQueryRequest(request, DbQueryRequest dbQueryRequest = this.buildDbQueryRequest(request,
@ -277,6 +306,7 @@ public abstract class AbstractDataPluginFactory extends AbstractDataFactory {
return dbQueryRequest; return dbQueryRequest;
} }
protected IGridData[] getGridData(IDataRequest request, protected IGridData[] getGridData(IDataRequest request,
DbQueryResponse dbQueryResponse) { DbQueryResponse dbQueryResponse) {
throw new UnsupportedOutputTypeException(request.getDatatype(), "grid"); throw new UnsupportedOutputTypeException(request.getDatatype(), "grid");

View file

@ -47,12 +47,14 @@ import com.vividsolutions.jts.geom.Geometry;
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Jan 29, 2013 bkowal Initial creation * Jan 29, 2013 bkowal Initial creation
* Feb 14, 2013 1614 bsteffen Refactor data access framework to use * Feb 14, 2013 1614 bsteffen Refactor data access framework to use
* single request. * single request.
* Jan 14, 2014 2667 mnash Remove getGridData methods * Jan 14, 2014 2667 mnash Remove getGridData methods
* Mar 03, 2014 2673 bsteffen Add ability to query only ref times.
*
* </pre> * </pre>
* *
* @author bkowal * @author bkowal
@ -97,10 +99,12 @@ public abstract class AbstractGeometryDatabaseFactory extends
* raytheon.uf.common.dataaccess.IDataRequest) * raytheon.uf.common.dataaccess.IDataRequest)
*/ */
@Override @Override
public DataTime[] getAvailableTimes(IDataRequest request) public DataTime[] getAvailableTimes(IDataRequest request,
boolean refTimeOnly)
throws TimeAgnosticDataException { throws TimeAgnosticDataException {
this.validateRequest(request); this.validateRequest(request);
return this.executeTimeQuery(this.assembleGetTimes(request), request); return this.executeTimeQuery(
this.assembleGetTimes(request, refTimeOnly), request);
} }
/* /*
@ -254,9 +258,14 @@ public abstract class AbstractGeometryDatabaseFactory extends
* *
* @param request * @param request
* the original request that we are processing * the original request that we are processing
* @param refTimeOnly
* true if only unique refTimes should be returned(without a
* forecastHr)
*
* @return the query * @return the query
*/ */
protected abstract String assembleGetTimes(IDataRequest request); protected abstract String assembleGetTimes(IDataRequest request,
boolean refTimeOnly);
/** /**
* Builds a query that will be used to retrieve time from the database based * Builds a query that will be used to retrieve time from the database based

View file

@ -34,11 +34,12 @@ import com.raytheon.uf.common.time.TimeRange;
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Jan 29, 2013 bkowal Initial creation * Jan 29, 2013 bkowal Initial creation
* Feb 14, 2013 1614 bsteffen Refactor data access framework to use * Feb 14, 2013 1614 bsteffen Refactor data access framework to use
* single request. * single request.
* Mar 03, 2014 2673 bsteffen Add ability to query only ref times.
* *
* </pre> * </pre>
* *
@ -71,7 +72,8 @@ public abstract class AbstractGeometryTimeAgnosticDatabaseFactory extends
* raytheon.uf.common.dataaccess.IDataRequest) * raytheon.uf.common.dataaccess.IDataRequest)
*/ */
@Override @Override
public DataTime[] getAvailableTimes(IDataRequest request) public DataTime[] getAvailableTimes(IDataRequest request,
boolean refTimeOnly)
throws TimeAgnosticDataException { throws TimeAgnosticDataException {
throw new TimeAgnosticDataException(this.buildExceptionMessage(request)); throw new TimeAgnosticDataException(this.buildExceptionMessage(request));
} }
@ -154,7 +156,7 @@ public abstract class AbstractGeometryTimeAgnosticDatabaseFactory extends
* Should we be throwing an exception * Should we be throwing an exception
*/ */
@Override @Override
protected String assembleGetTimes(IDataRequest request) { protected String assembleGetTimes(IDataRequest request, boolean refTimeOnly) {
return null; return null;
} }

View file

@ -33,11 +33,12 @@ import com.raytheon.uf.common.time.DataTime;
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Nov 14, 2012 njensen Initial creation * Nov 14, 2012 njensen Initial creation
* Feb 14, 2013 1614 bsteffen Refactor data access framework to use * Feb 14, 2013 1614 bsteffen Refactor data access framework to use
* single request. * single request.
* Mar 03, 2014 2673 bsteffen Add ability to query only ref times.
* *
* </pre> * </pre>
* *
@ -62,7 +63,7 @@ public class FactoryUtil {
*/ */
public static DataTime[] getAvailableTimes(IDataFactory factory, public static DataTime[] getAvailableTimes(IDataFactory factory,
IDataRequest request, BinOffset binOffset) { IDataRequest request, BinOffset binOffset) {
DataTime[] actualTimes = factory.getAvailableTimes(request); DataTime[] actualTimes = factory.getAvailableTimes(request, false);
if (binOffset != null) { if (binOffset != null) {
Set<DataTime> normalized = binOffset Set<DataTime> normalized = binOffset
.getNormalizedTimes(actualTimes); .getNormalizedTimes(actualTimes);

View file

@ -30,9 +30,10 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* May 23, 2013 dgilling Initial creation * May 23, 2013 dgilling Initial creation
* Mar 03, 2014 2673 bsteffen Add ability to query only ref times.
* *
* </pre> * </pre>
* *
@ -43,6 +44,8 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
@DynamicSerialize @DynamicSerialize
public final class GetAvailableTimesRequest extends AbstractDataAccessRequest { public final class GetAvailableTimesRequest extends AbstractDataAccessRequest {
private boolean refTimeOnly = false;
public GetAvailableTimesRequest() { public GetAvailableTimesRequest() {
super(); super();
} }
@ -50,4 +53,13 @@ public final class GetAvailableTimesRequest extends AbstractDataAccessRequest {
public GetAvailableTimesRequest(final IDataRequest request) { public GetAvailableTimesRequest(final IDataRequest request) {
super(request); super(request);
} }
public boolean isRefTimeOnly() {
return refTimeOnly;
}
public void setRefTimeOnly(boolean refTimeOnly) {
this.refTimeOnly = refTimeOnly;
}
} }

View file

@ -43,13 +43,14 @@ import com.vividsolutions.jts.geom.GeometryFactory;
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* Nov 13, 2012 njensen Initial creation * Nov 13, 2012 njensen Initial creation
* Jan 30, 2012 1551 bkowal Refactored * Jan 30, 2012 1551 bkowal Refactored
* Jan 31, 2012 1555 bkowal Modification based on existing hydro code * Jan 31, 2012 1555 bkowal Modification based on existing hydro code
* Feb 14, 2013 1614 bsteffen Refactor data access framework to use * Feb 14, 2013 1614 bsteffen Refactor data access framework to use
* single request. * single request.
* Mar 03, 2014 2673 bsteffen Add ability to query only ref times.
* *
* </pre> * </pre>
* *
@ -135,7 +136,7 @@ public class HydroGeometryFactory extends AbstractGeometryDatabaseFactory {
* #assembleGetTimes (com.raytheon.uf.common.dataaccess.geom.IDataRequest) * #assembleGetTimes (com.raytheon.uf.common.dataaccess.geom.IDataRequest)
*/ */
@Override @Override
protected String assembleGetTimes(IDataRequest request) { protected String assembleGetTimes(IDataRequest request, boolean refTimeOnly) {
return HydroQueryAssembler.assembleGetTimes(request); return HydroQueryAssembler.assembleGetTimes(request);
} }

View file

@ -32,9 +32,10 @@ import com.raytheon.uf.common.time.DataTime;
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------- -------- ----------- --------------------------
* May 23, 2013 dgilling Initial creation * May 23, 2013 dgilling Initial creation
* Mar 03, 2014 2673 bsteffen Add ability to query only ref times.
* *
* </pre> * </pre>
* *
@ -56,7 +57,8 @@ public final class GetAvailableTimesHandler implements
public DataTime[] handleRequest(final GetAvailableTimesRequest request) public DataTime[] handleRequest(final GetAvailableTimesRequest request)
throws Exception { throws Exception {
return DataAccessLayer return DataAccessLayer
.getAvailableTimes(request.getRequestParameters()); .getAvailableTimes(
request.getRequestParameters(), request.isRefTimeOnly());
} }
} }

View file

@ -29,9 +29,10 @@
# #
# Date Ticket# Engineer Description # Date Ticket# Engineer Description
# ------------ ---------- ----------- -------------------------- # ------------ ---------- ----------- --------------------------
# 12/10/12 njensen Initial Creation. # 12/10/12 njensen Initial Creation.
# Feb 14, 2013 1614 bsteffen refactor data access framework # 02/14/13 1614 bsteffen refactor data access framework
# to use single request. # to use single request.
# 03/03/14 2673 bsteffen Add ability to query only ref times.
# #
# #
# #
@ -49,8 +50,8 @@ import DataTime
import JGeometryData, JGridData, JDataRequest import JGeometryData, JGridData, JDataRequest
def getAvailableTimes(request): def getAvailableTimes(request, refTimeOnly):
javaTimes = JavaDataAccessLayer.getAvailableTimes(request.toJavaObj()) javaTimes = JavaDataAccessLayer.getAvailableTimes(request.toJavaObj(), refTimeOnly)
times = [] times = []
for jt in javaTimes: for jt in javaTimes:
times.append(DataTime.DataTime(jt)) times.append(DataTime.DataTime(jt))

View file

@ -27,6 +27,7 @@
# Date Ticket# Engineer Description # Date Ticket# Engineer Description
# ------------ ---------- ----------- -------------------------- # ------------ ---------- ----------- --------------------------
# 05/28/13 #2023 dgilling Initial Creation. # 05/28/13 #2023 dgilling Initial Creation.
# 03/03/14 #2673 bsteffen Add ability to query only ref times.
# #
# #
@ -38,4 +39,10 @@ class GetAvailableTimesRequest(AbstractDataAccessRequest):
def __init__(self): def __init__(self):
super(GetAvailableTimesRequest, self).__init__() super(GetAvailableTimesRequest, self).__init__()
self.refTimeOnly = False
def getRefTimeOnly(self):
return self.refTimeOnly
def setRefTimeOnly(self, refTimeOnly):
self.refTimeOnly = refTimeOnly

View file

@ -29,6 +29,8 @@
# ??/??/?? xxxxxxxx Initial Creation. # ??/??/?? xxxxxxxx Initial Creation.
# 05/28/13 2023 dgilling Implement __str__(). # 05/28/13 2023 dgilling Implement __str__().
# 01/22/14 2667 bclement preserved milliseconds in string representation # 01/22/14 2667 bclement preserved milliseconds in string representation
# 03/03/14 2673 bsteffen allow construction using a Date for refTime
#
# #
import calendar import calendar
@ -39,8 +41,8 @@ import StringIO
from dynamicserialize.dstypes.java.util import Date from dynamicserialize.dstypes.java.util import Date
from dynamicserialize.dstypes.java.util import EnumSet from dynamicserialize.dstypes.java.util import EnumSet
from dynamicserialize.dstypes.com.raytheon.uf.common.time import TimeRange
from TimeRange import TimeRange
class DataTime(object): class DataTime(object):
@ -58,6 +60,10 @@ class DataTime(object):
self.refTime = long(calendar.timegm(self.refTime.utctimetuple()) * 1000) self.refTime = long(calendar.timegm(self.refTime.utctimetuple()) * 1000)
elif isinstance(self.refTime, time.struct_time): elif isinstance(self.refTime, time.struct_time):
self.refTime = long(calendar.timegm(self.refTime) * 1000) self.refTime = long(calendar.timegm(self.refTime) * 1000)
elif hasattr(self.refTime, 'getTime'):
# getTime should be returning ms, there is no way to check this
# This is expected for java Date
self.refTime = long(self.refTime.getTime())
else: else:
self.refTime = long(refTime) self.refTime = long(refTime)
dateObj = Date() dateObj = Date()
@ -65,10 +71,10 @@ class DataTime(object):
self.refTime = dateObj self.refTime = dateObj
if self.validPeriod is None: if self.validPeriod is None:
validTimeMillis = self.refTime + long(fcstTime * 1000) validTimeMillis = self.refTime.getTime() + long(self.fcstTime * 1000)
self.validPeriod = TimeRange() self.validPeriod = TimeRange()
self.validPeriod.setStart(validTimeMills/1000) self.validPeriod.setStart(validTimeMillis/1000)
self.validPeriod.setEnd(validTimeMills/1000) self.validPeriod.setEnd(validTimeMillis/1000)
# figure out utility flags # figure out utility flags
if fcstTime: if fcstTime:

View file

@ -32,6 +32,7 @@
# to use single request. # to use single request.
# 04/10/13 1871 mnash move getLatLonCoords to JGridData and add default args # 04/10/13 1871 mnash move getLatLonCoords to JGridData and add default args
# 05/29/13 2023 dgilling Hook up ThriftClientRouter. # 05/29/13 2023 dgilling Hook up ThriftClientRouter.
# 03/03/14 2673 bsteffen Add ability to query only ref times.
# #
# #
# #
@ -54,17 +55,20 @@ except ImportError:
USING_NATIVE_THRIFT = True USING_NATIVE_THRIFT = True
def getAvailableTimes(request): def getAvailableTimes(request, refTimeOnly=False):
""" """
Get the times of available data to the request. Get the times of available data to the request.
Args: Args:
request: the IDataRequest to get data for request: the IDataRequest to get data for
Args:
refTimeOnly: True if only unique refTimes should be returned(without
a forecastHr)
Returns: Returns:
a list of DataTimes a list of DataTimes
""" """
return router.getAvailableTimes(request) return router.getAvailableTimes(request, refTimeOnly)
def getGridData(request, times=[]): def getGridData(request, times=[]):
""" """

View file

@ -29,6 +29,7 @@
# ------------ ---------- ----------- -------------------------- # ------------ ---------- ----------- --------------------------
# 05/21/13 #2023 dgilling Initial Creation. # 05/21/13 #2023 dgilling Initial Creation.
# 01/06/14 #2537 bsteffen Share geometry WKT. # 01/06/14 #2537 bsteffen Share geometry WKT.
# 03/03/14 #2673 bsteffen Add ability to query only ref times.
# #
@ -51,9 +52,10 @@ class ThriftClientRouter(object):
def __init__(self, host='localhost'): def __init__(self, host='localhost'):
self._client = ThriftClient.ThriftClient(host) self._client = ThriftClient.ThriftClient(host)
def getAvailableTimes(self, request): def getAvailableTimes(self, request, refTimeOnly):
timesRequest = GetAvailableTimesRequest() timesRequest = GetAvailableTimesRequest()
timesRequest.setRequestParameters(request) timesRequest.setRequestParameters(request)
timesRequest.setRefTimeOnly(refTimeOnly)
response = self._client.sendRequest(timesRequest) response = self._client.sendRequest(timesRequest)
return response return response