Integer srcId = Integer.valueOf(sourceId);
sourceIds.add(srcId);
}
catch (NumberFormatException nfe)
{
HttpStatisticsCollector globalHttpStatsCollector = _relay.getHttpStatisticsCollector();
if (null != globalHttpStatsCollector) {
globalHttpStatsCollector.registerInvalidStreamRequest();
}
throw new InvalidRequestParamValueException(COMMAND_NAME, SOURCES_PARAM, sourceId);
}
}
}
//process explicit subscriptions and generate respective logical partition filters
NavigableSet<PhysicalPartitionKey> ppartKeys = null;
if (null != subsStr)
{
List<DatabusSubscription.Builder> subsBuilder = null;
subsBuilder = objMapper.readValue(subsStr,
new TypeReference<List<DatabusSubscription.Builder>>(){});
subs = new ArrayList<DatabusSubscription>(subsBuilder.size());
for (DatabusSubscription.Builder subBuilder: subsBuilder)
{
subs.add(subBuilder.build());
}
ppartKeys = new TreeSet<PhysicalPartitionKey>();
for (DatabusSubscription sub: subs)
{
PhysicalPartition ppart = sub.getPhysicalPartition();
if (ppart.isAnyPartitionWildcard())
{
ppartKeys = _eventBuffer.getAllPhysicalPartitionKeys(); break;
}
else
{
ppartKeys.add(new PhysicalPartitionKey(ppart));
}
}
}
// TODO
// The following if statement is a very conservative one just to make sure that there are
// not some clients out there that send subs, but do not send checkpoint mult. It seems that
// this was the case during development but never in production, so we should remove this
// pretty soon (1/28/2013).
// Need to make sure that we don't have tests that send requests in this form.
if(subs != null && checkpointStringMult == null && checkpointString != null) {
throw new RequestProcessingException("Both Subscriptions and CheckpointMult should be present");
}
//convert source ids into subscriptions
if (null == subs) subs = new ArrayList<DatabusSubscription>();
for (Integer srcId: sourceIds)
{
LogicalSource lsource = srcRegistry.getSource(srcId);
if(lsource == null)
throw new InvalidRequestParamValueException(COMMAND_NAME, SOURCES_PARAM, srcId.toString());
if(isDebug)
LOG.debug("registry returns " + lsource + " for srcid="+ srcId);
DatabusSubscription newSub = DatabusSubscription.createSimpleSourceSubscription(lsource);
subs.add(newSub);
}
DbusFilter ppartFilters = null;
if (subs.size() > 0)
{
try
{
ppartFilters = _eventBuffer.constructFilters(subs);
}
catch (DatabusException de)
{
throw new RequestProcessingException("unable to generate physical partitions filters:" +
de.getMessage(),
de);
}
}
ConjunctionDbusFilter filters = new ConjunctionDbusFilter();
// Source filter comes first
if (v2Mode) filters.addFilter(new SourceDbusFilter(sourceIds));
else if (null != ppartFilters) filters.addFilter(ppartFilters);
/*
// Key range filter comes next
if ((keyMin >0) && (keyMax > 0))
{
filters.addFilter(new KeyRangeFilter(keyMin, keyMax));
}
*/
if ( null != keyCompositeFilter)
{
filters.addFilter(keyCompositeFilter);
}
// need to update registerStreamRequest to support Mult checkpoint TODO (DDSDBUS-80)
// temp solution
// 3 options:
// 1. checkpointStringMult not null - generate checkpoint from it
// 2. checkpointStringMult null, checkpointString not null - create empty CheckpointMult
// and add create Checkpoint(checkpointString) and add it to cpMult;
// 3 both are null - create empty CheckpointMult and add empty Checkpoint to it for each ppartition
PhysicalPartition pPartition;
Checkpoint cp = null;
CheckpointMult cpMult = null;
if(checkpointStringMult != null) {
try {
cpMult = new CheckpointMult(checkpointStringMult);
} catch (InvalidParameterSpecException e) {
LOG.error("Invalid CheckpointMult:" + checkpointStringMult, e);
throw new InvalidRequestParamValueException("stream", "CheckpointMult", checkpointStringMult);
}
} else {
// there is no checkpoint - create an empty one
cpMult = new CheckpointMult();
Iterator<Integer> it = sourceIds.iterator();
while(it.hasNext()) {
Integer srcId = it.next();
pPartition = _eventBuffer.getPhysicalPartition(srcId);
if(pPartition == null)
throw new RequestProcessingException("unable to find physical partitions for source:" + srcId);
if(checkpointString != null) {
cp = new Checkpoint(checkpointString);
} else {
cp = new Checkpoint();
cp.setFlexible();
}
cpMult.addCheckpoint(pPartition, cp);
}
}
if (isDebug) LOG.debug("checkpointStringMult = " + checkpointStringMult + ";singlecheckpointString="+ checkpointString + ";CPM="+cpMult);
// If the client has not sent a cursor partition, then use the one we may have retained as a part
// of the server context.
if (cpMult.getCursorPartition() == null) {
cpMult.setCursorPartition(request.getCursorPartition());
}
if (isDebug) {
if (cpMult.getCursorPartition() != null) {
LOG.debug("Using physical paritition cursor " + cpMult.getCursorPartition());
}
}
// for registerStreamRequest we need a single Checkpoint (TODO - fix it) (DDSDBUS-81)
if(cp==null) {
Iterator<Integer> it = sourceIds.iterator();
if (it.hasNext()) {
Integer srcId = it.next();
pPartition = _eventBuffer.getPhysicalPartition(srcId);
cp = cpMult.getCheckpoint(pPartition);
} else {
cp = new Checkpoint();
cp.setFlexible();
}
}
if (null != checkpointString && isDebug)
LOG.debug("About to stream from cp: " + checkpointString.toString());
HttpStatisticsCollector globalHttpStatsCollector = _relay.getHttpStatisticsCollector();
HttpStatisticsCollector connHttpStatsCollector = null;
if (null != globalHttpStatsCollector)
{
connHttpStatsCollector = (HttpStatisticsCollector)request.getParams().get(globalHttpStatsCollector.getName());
}
if (null != globalHttpStatsCollector) globalHttpStatsCollector.registerStreamRequest(cp, sourceIds);
StatsCollectors<DbusEventsStatisticsCollector> statsCollectors = _relay.getOutBoundStatsCollectors();
try
{
DbusEventBufferBatchReadable bufRead = v2Mode
? _eventBuffer.getDbusEventBufferBatchReadable(sourceIds, cpMult, statsCollectors)
: _eventBuffer.getDbusEventBufferBatchReadable(cpMult, ppartKeys, statsCollectors);
int eventsRead = 0;
int minPendingEventSize = 0;
StreamEventsResult result = null;
bufRead.setClientMaxEventVersion(clientEventVersion);
if (v2Mode)
{
result = bufRead.streamEvents(streamFromLatestSCN, fetchSize,
request.getResponseContent(), enc, filters);
eventsRead = result.getNumEventsStreamed();
minPendingEventSize = result.getSizeOfPendingEvent();
if(isDebug) {
LOG.debug("Process: streamed " + eventsRead + " from sources " +
Arrays.toString(sourceIds.toArray()));
LOG.debug("CP=" + cpMult); //can be used for debugging to stream from a cp
}
//if (null != statsCollectors) statsCollectors.mergeStatsCollectors();
}
else
{
result = bufRead.streamEvents(streamFromLatestSCN, fetchSize,
request.getResponseContent(), enc, filters);
eventsRead = result.getNumEventsStreamed();
minPendingEventSize = result.getSizeOfPendingEvent();
if(isDebug)
LOG.debug("Process: streamed " + eventsRead + " with subscriptions " + subs);
cpMult = bufRead.getCheckpointMult();
if (cpMult != null) {
request.setCursorPartition(cpMult.getCursorPartition());
}
}
if (eventsRead == 0 && minPendingEventSize > 0)
{
// Append a header to indicate to the client that we do have at least one event to
// send, but it is too large to fit into client's offered buffer.
request.getResponseContent().addMetadata(DatabusHttpHeaders.DATABUS_PENDING_EVENT_SIZE,
minPendingEventSize);
LOG.debug("Returning 0 events but have pending event of size " + minPendingEventSize);
}
}
catch (ScnNotFoundException snfe)
{
if (null != globalHttpStatsCollector) {
globalHttpStatsCollector.registerScnNotFoundStreamResponse();
}
throw new RequestProcessingException(snfe);
}
catch (OffsetNotFoundException snfe)
{
LOG.error("OffsetNotFound", snfe);
if (null != globalHttpStatsCollector) {
globalHttpStatsCollector.registerScnNotFoundStreamResponse();
}
throw new RequestProcessingException(snfe);
}
/* FIXME snagaraj
if (null != connEventsStatsCollector && null != globalEventsStatsCollector)
{
globalEventsStatsCollector.merge(connEventsStatsCollector);
connEventsStatsCollector.reset();
}
*/
if (null != connHttpStatsCollector)
{
connHttpStatsCollector.registerStreamResponse(System.currentTimeMillis()-start);
globalHttpStatsCollector.merge(connHttpStatsCollector);
connHttpStatsCollector.reset();
}
else if (null != globalHttpStatsCollector)
{
globalHttpStatsCollector.registerStreamResponse(System.currentTimeMillis()-start);
}
}
catch (InvalidRequestParamValueException e)
{
HttpStatisticsCollector globalHttpStatsCollector = _relay.getHttpStatisticsCollector();
if (null != globalHttpStatsCollector) {
globalHttpStatsCollector.registerInvalidStreamRequest();
}
throw e;
}
return request;
}