diff --git a/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt b/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt index c2751ab0..80ec9c72 100644 --- a/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt +++ b/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt @@ -85,8 +85,17 @@ internal object ReportInstanceActions { Metrics.REPORT_PERMISSION_USER_ERROR.counter.increment() throw OpenSearchStatusException("Permission denied for Report Definition ${request.reportDefinitionId}", RestStatus.FORBIDDEN) } - val beginTime: Instant = currentTime.minus(reportDefinitionDetails.reportDefinition.format.duration) - val endTime: Instant = currentTime + val beginTime: Instant + val endTime: Instant + + if (!reportDefinitionDetails.reportDefinition.format.timeFrom.isNullOrBlank() && + !reportDefinitionDetails.reportDefinition.format.timeTo.isNullOrBlank()) { + beginTime = Instant.parse(reportDefinitionDetails.reportDefinition.format.timeFrom) + endTime = Instant.parse(reportDefinitionDetails.reportDefinition.format.timeTo) + } else { + beginTime = currentTime.minus(reportDefinitionDetails.reportDefinition.format.duration) + endTime = currentTime + } val currentStatus: Status = Status.Success // TODO: Revert to Executing when background job execution supported val reportInstance = ReportInstance( "ignore", diff --git a/src/main/kotlin/org/opensearch/reportsscheduler/model/ReportDefinition.kt b/src/main/kotlin/org/opensearch/reportsscheduler/model/ReportDefinition.kt index 44fc671f..024d3c58 100644 --- a/src/main/kotlin/org/opensearch/reportsscheduler/model/ReportDefinition.kt +++ b/src/main/kotlin/org/opensearch/reportsscheduler/model/ReportDefinition.kt @@ -234,74 +234,85 @@ internal data class ReportDefinition( * Report definition format data class */ internal data class Format( - val duration: Duration, - val fileFormat: FileFormat, - val limit: Int?, - val header: String?, - val footer: String? - ) : ToXContentObject { - internal companion object { - private const val DURATION_TAG = "duration" - private const val FILE_FORMAT_TAG = "fileFormat" - private const val LIMIT_TAG = "limit" - private const val HEADER_TAG = "header" - private const val FOOTER_TAG = "footer" + val duration: Duration, + val fileFormat: FileFormat, + val limit: Int?, + val header: String?, + val footer: String?, + val timeFrom: String?, + val timeTo: String? +) : ToXContentObject { + internal companion object { + private const val DURATION_TAG = "duration" + private const val FILE_FORMAT_TAG = "fileFormat" + private const val LIMIT_TAG = "limit" + private const val HEADER_TAG = "header" + private const val FOOTER_TAG = "footer" + private const val TIME_FROM_TAG = "timeFrom" + private const val TIME_TO_TAG = "timeTo" - /** - * Parse the data from parser and create Format object - * @param parser data referenced at parser - * @return created Format object - */ - fun parse(parser: XContentParser): Format { - var durationSeconds: Duration? = null - var fileFormat: FileFormat? = null - var limit: Int? = null - var header: String? = null - var footer: String? = null - XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser) - while (XContentParser.Token.END_OBJECT != parser.nextToken()) { - val fieldName = parser.currentName() - parser.nextToken() - when (fieldName) { - DURATION_TAG -> durationSeconds = Duration.parse(parser.text()) - FILE_FORMAT_TAG -> fileFormat = FileFormat.valueOf(parser.text()) - LIMIT_TAG -> limit = parser.intValue() - HEADER_TAG -> header = parser.textOrNull() - FOOTER_TAG -> footer = parser.textOrNull() - else -> { - parser.skipChildren() - log.info("$LOG_PREFIX:Format Skipping Unknown field $fieldName") - } + /** + * Parse the data from parser and create Format object + * @param parser data referenced at parser + * @return created Format object + */ + fun parse(parser: XContentParser): Format { + var durationSeconds: Duration? = null + var fileFormat: FileFormat? = null + var limit: Int? = null + var header: String? = null + var footer: String? = null + var timeFrom: String? = null + var timeTo: String? = null + XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser) + while (XContentParser.Token.END_OBJECT != parser.nextToken()) { + val fieldName = parser.currentName() + parser.nextToken() + when (fieldName) { + DURATION_TAG -> durationSeconds = Duration.parse(parser.text()) + FILE_FORMAT_TAG -> fileFormat = FileFormat.valueOf(parser.text()) + LIMIT_TAG -> limit = parser.intValue() + HEADER_TAG -> header = parser.textOrNull() + FOOTER_TAG -> footer = parser.textOrNull() + TIME_FROM_TAG -> timeFrom = parser.textOrNull() + TIME_TO_TAG -> timeTo = parser.textOrNull() + else -> { + parser.skipChildren() + log.info("$LOG_PREFIX:Format Skipping Unknown field $fieldName") } } - durationSeconds - ?: throw IllegalArgumentException("$DURATION_TAG field absent") - fileFormat ?: throw IllegalArgumentException("$FILE_FORMAT_TAG field absent") - return Format( - durationSeconds, - fileFormat, - limit, - header, - footer - ) } + durationSeconds ?: throw IllegalArgumentException("$DURATION_TAG field absent") + fileFormat ?: throw IllegalArgumentException("$FILE_FORMAT_TAG field absent") + return Format( + durationSeconds, + fileFormat, + limit, + header, + footer, + timeFrom, + timeTo + ) } + } - /** - * {@inheritDoc} - */ - override fun toXContent(builder: XContentBuilder?, params: ToXContent.Params?): XContentBuilder { - builder!! - builder.startObject() - .field(DURATION_TAG, duration.toString()) - .field(FILE_FORMAT_TAG, fileFormat.name) - if (limit != null) builder.field(LIMIT_TAG, limit) - if (header != null) builder.field(HEADER_TAG, header) - if (footer != null) builder.field(FOOTER_TAG, footer) - builder.endObject() - return builder - } + /** + * {@inheritDoc} + */ + override fun toXContent(builder: XContentBuilder?, params: ToXContent.Params?): XContentBuilder { + builder!! + builder.startObject() + .field(DURATION_TAG, duration.toString()) + .field(FILE_FORMAT_TAG, fileFormat.name) + if (limit != null) builder.field(LIMIT_TAG, limit) + if (header != null) builder.field(HEADER_TAG, header) + if (footer != null) builder.field(FOOTER_TAG, footer) + builder.field(TIME_FROM_TAG, timeFrom) + builder.field(TIME_TO_TAG, timeTo) + builder.endObject() + return builder } +} /** * Report definition trigger data class