/** * Result set size threshold is expressed in bytes. This is just an approximation, see @{link {@link JsonUtils#size(JsonNode)} for details. * * @param maxResultSetSizeB error when this threshold is breached * @param warnResultSetSizeB log a warning when this threshold is breached * @param forRequest request which resulted in this response, for logging purposes */ private void registerMemoryMonitors(int maxResultSetSizeB, int warnResultSetSizeB, final Request forRequest) { // Order is significant – warn first for request in log output. memoryMonitor.registerMonitor(new MemoryMonitor.ThresholdMonitor<>(warnResultSetSizeB, (current, threshold, doc) -> LOGGER.warn("crud:ExecutionContextIsLarge: request={}, executionDataSizeB={} threshold={}", forRequest, current, threshold))); memoryMonitor.registerMonitor(new MemoryMonitor.ThresholdMonitor<>(maxResultSetSizeB, (current, threshold, doc) -> { throw Error.get( CrudConstants.ERR_EXECUTION_CONTEXT_TOO_LARGE, current + "B > " + threshold + "B"); })); }
/** * Result set size threshold is expressed in bytes. This is just an approximation, see @{link {@link JsonUtils#size(JsonNode)} for details. * * @param maxResultSetSizeB error when this threshold is breached * @param warnResultSetSizeB log a warning when this threshold is breached * @param forRequest request which resulted in this response, for logging purposes */ private void registerMemoryMonitors(int maxResultSetSizeB, int warnResultSetSizeB, final Request forRequest) { // Order is significant – warn first for request in log output. memoryMonitor.registerMonitor(new MemoryMonitor.ThresholdMonitor<>(warnResultSetSizeB, (current, threshold, doc) -> LOGGER.warn("crud:ExecutionContextIsLarge: request={}, executionDataSizeB={} threshold={}", forRequest, current, threshold))); memoryMonitor.registerMonitor(new MemoryMonitor.ThresholdMonitor<>(maxResultSetSizeB, (current, threshold, doc) -> { throw Error.get( CrudConstants.ERR_EXECUTION_CONTEXT_TOO_LARGE, current + "B > " + threshold + "B"); })); }
/** * Threshold is expressed in bytes. This is just an approximation, see @{link {@link JsonUtils#size(JsonNode)} for details. * * @param maxResultSetSizeB error when this threshold is breached * @param warnResultSetSizeB log a warning when this threshold is breached * @param forRequest request which resulted in this response, for logging purposes * @param initialDataSizeB initial size in memory (memory occupied by prior operations) */ public void setQueuedHooksSizeThresholds(int maxQueuedHooksSizeB, int warnQueuedHooksSizeB, final QueryExpression query, int initialDataSizeB) { this.monitor = new MemoryMonitor<>((node) -> JsonUtils.size(node), initialDataSizeB); this.monitor.registerMonitor(new ThresholdMonitor<>(warnQueuedHooksSizeB, (current, threshold, node) -> { LOGGER.warn("crud:ResultSizeIsLarge: query={}, queuedHooksSizeB={} threshold={}", query, current, threshold); })); this.monitor.registerMonitor(new ThresholdMonitor<>(maxQueuedHooksSizeB, (current, threshold, node) -> { throw Error.get(Response.ERR_RESULT_SIZE_TOO_LARGE, current+"B > "+threshold+"B (during hook processing)"); })); }
/** * Threshold is expressed in bytes. This is just an approximation, see @{link {@link JsonUtils#size(JsonNode)} for details. * * @param maxResultSetSizeB error when this threshold is breached * @param warnResultSetSizeB log a warning when this threshold is breached * @param forRequest request which resulted in this response, for logging purposes * @param initialDataSizeB initial size in memory (memory occupied by prior operations) */ public void setQueuedHooksSizeThresholds(int maxQueuedHooksSizeB, int warnQueuedHooksSizeB, final QueryExpression query, int initialDataSizeB) { this.monitor = new MemoryMonitor<>((node) -> JsonUtils.size(node), initialDataSizeB); this.monitor.registerMonitor(new ThresholdMonitor<>(warnQueuedHooksSizeB, (current, threshold, node) -> { LOGGER.warn("crud:ResultSizeIsLarge: query={}, queuedHooksSizeB={} threshold={}", query, current, threshold); })); this.monitor.registerMonitor(new ThresholdMonitor<>(maxQueuedHooksSizeB, (current, threshold, node) -> { throw Error.get(Response.ERR_RESULT_SIZE_TOO_LARGE, current+"B > "+threshold+"B (during hook processing)"); })); }
/** * Bulk result set size threshold is expressed in bytes. This is just an approximation, see @{link {@link JsonUtils#size(JsonNode)} for details. * * @param maxResultSetSizeB error when this threshold is breached * @param warnResultSetSizeB log a warning when this threshold is breached * @param forRequest request which resulted in this response, for logging purposes */ public void setResultSizeThresholds(int maxResultSetSizeB, int warnResultSetSizeB, BulkRequest forRequest) { this.memoryMonitor = new MemoryMonitor<>((response) -> response.getResponseDataSizeB()); memoryMonitor.registerMonitor(new ThresholdMonitor<Response>(warnResultSetSizeB, (current, threshold, response) -> { LOGGER.warn("crud:ResultSizeIsLarge: request={}, responseDataSizeB={} threshold={}", forRequest, current, threshold); })); memoryMonitor.registerMonitor(new ThresholdMonitor<Response>(maxResultSetSizeB, (current, threshold, response) -> { // remove data response.setEntityData(JsonNodeFactory.instance.arrayNode()); response.getErrors().add(Error.get(Response.ERR_RESULT_SIZE_TOO_LARGE, current+"B > "+threshold+"B")); })); }
/** * Bulk result set size threshold is expressed in bytes. This is just an approximation, see @{link {@link JsonUtils#size(JsonNode)} for details. * * @param maxResultSetSizeB error when this threshold is breached * @param warnResultSetSizeB log a warning when this threshold is breached * @param forRequest request which resulted in this response, for logging purposes */ public void setResultSizeThresholds(int maxResultSetSizeB, int warnResultSetSizeB, BulkRequest forRequest) { this.memoryMonitor = new MemoryMonitor<>((response) -> response.getResponseDataSizeB()); memoryMonitor.registerMonitor(new ThresholdMonitor<Response>(warnResultSetSizeB, (current, threshold, response) -> { LOGGER.warn("crud:ResultSizeIsLarge: request={}, responseDataSizeB={} threshold={}", forRequest, current, threshold); })); memoryMonitor.registerMonitor(new ThresholdMonitor<Response>(maxResultSetSizeB, (current, threshold, response) -> { // remove data response.setEntityData(JsonNodeFactory.instance.arrayNode()); response.getErrors().add(Error.get(Response.ERR_RESULT_SIZE_TOO_LARGE, current+"B > "+threshold+"B")); })); }
/** * Result set size threshold is expressed in bytes. This is just an approximation, see @{link {@link JsonUtils#size(JsonNode)} for details. * * @param maxResultSetSizeB error when this threshold is breached * @param warnResultSetSizeB log a warning when this threshold is breached * @param forRequest request which resulted in this response, for logging purposes */ public void setResultSizeThresholds(int maxResultSetSizeB, int warnResultSetSizeB, final Request forRequest) { this.memoryMonitor = new MemoryMonitor<>((jsonNode) -> JsonUtils.size(jsonNode)); // Order is significant – warn first for request in log output. memoryMonitor.registerMonitor(new ThresholdMonitor<JsonNode>(warnResultSetSizeB, (current, threshold, doc) -> { LOGGER.warn("crud:ResultSizeIsLarge: request={}, responseDataSizeB={} threshold={}", forRequest, current, threshold); })); memoryMonitor.registerMonitor(new ThresholdMonitor<JsonNode>(maxResultSetSizeB, (current, threshold, doc) -> { // empty data // returning incomplete result set could be useful, but also confusing and thus dangerous // the counts - matchCount, modifiedCount - are unmodified setEntityData(JsonNodeFactory.instance.arrayNode()); setStatus(OperationStatus.ERROR); throw Error.get(ERR_RESULT_SIZE_TOO_LARGE, current + "B > " + threshold + "B"); })); }
/** * Result set size threshold is expressed in bytes. This is just an approximation, see @{link {@link JsonUtils#size(JsonNode)} for details. * * @param maxResultSetSizeB error when this threshold is breached * @param warnResultSetSizeB log a warning when this threshold is breached * @param forRequest request which resulted in this response, for logging purposes */ public void setResultSizeThresholds(int maxResultSetSizeB, int warnResultSetSizeB, final Request forRequest) { this.memoryMonitor = new MemoryMonitor<>((jsonNode) -> JsonUtils.size(jsonNode)); // Order is significant – warn first for request in log output. memoryMonitor.registerMonitor(new ThresholdMonitor<JsonNode>(warnResultSetSizeB, (current, threshold, doc) -> { LOGGER.warn("crud:ResultSizeIsLarge: request={}, responseDataSizeB={} threshold={}", forRequest, current, threshold); })); memoryMonitor.registerMonitor(new ThresholdMonitor<JsonNode>(maxResultSetSizeB, (current, threshold, doc) -> { // empty data // returning incomplete result set could be useful, but also confusing and thus dangerous // the counts - matchCount, modifiedCount - are unmodified setEntityData(JsonNodeFactory.instance.arrayNode()); setStatus(OperationStatus.ERROR); throw Error.get(ERR_RESULT_SIZE_TOO_LARGE, current + "B > " + threshold + "B"); })); }
public void setResultSizeThresholds(int maxResultSetSizeB, int warnResultSetSizeB, final QueryExpression forQuery) { this.memoryMonitor = new MemoryMonitor<>((doc) -> { int size = JsonUtils.size(doc.getRoot()); // account for docs copied by DocCtx.startModifications() if (doc.getOriginalDocument() != null) { size += JsonUtils.size(doc.getOriginalDocument().getRoot()); } if (doc.getUpdatedDocument() != null) { size += JsonUtils.size(doc.getUpdatedDocument().getRoot()); } return size; }); memoryMonitor.registerMonitor(new ThresholdMonitor<DocCtx>(maxResultSetSizeB, (current, threshold, doc) -> { throw Error.get(MongoCrudConstants.ERROR_RESULT_SIZE_TOO_LARGE, current+"B > "+threshold+"B"); })); memoryMonitor.registerMonitor(new ThresholdMonitor<DocCtx>(warnResultSetSizeB, (current, threshold, doc) -> { LOGGER.warn("{}: query={}, responseDataSizeB={}", MongoCrudConstants.WARN_RESULT_SIZE_LARGE,forQuery, current); })); }