Skip to content

Commit

Permalink
Snapshot management default date format in snapshot name (#392)
Browse files Browse the repository at this point in the history
* Default date format

Signed-off-by: bowenlan-amzn <[email protected]>
(cherry picked from commit 1c9f232)
  • Loading branch information
bowenlan-amzn authored and github-actions[bot] committed Jun 28, 2022
1 parent 279f7a6 commit 195adf9
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit
import java.util.Locale
import org.opensearch.common.time.DateFormatters

private val log = LogManager.getLogger("o.i.s.SnapshotManagementHelper")

Expand Down Expand Up @@ -139,17 +140,19 @@ suspend fun Client.indexMetadata(

fun generateSnapshotName(policy: SMPolicy): String {
var result: String = policy.policyName
if (policy.snapshotConfig[DATE_FORMAT_FIELD] != null) {
val dateFormat = if (policy.snapshotConfig[DATE_FORMAT_TIMEZONE_FIELD] != null) {
generateFormatTime(
policy.snapshotConfig[DATE_FORMAT_FIELD] as String,
ZoneId.of(policy.snapshotConfig[DATE_FORMAT_TIMEZONE_FIELD] as String),
)
} else {
generateFormatTime(policy.snapshotConfig[DATE_FORMAT_FIELD] as String)
}
result += "-$dateFormat"
var dateFormat = policy.snapshotConfig[DATE_FORMAT_FIELD] as String?
if (dateFormat == null) {
dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
}
val dateValue = if (policy.snapshotConfig[DATE_FORMAT_TIMEZONE_FIELD] != null) {
generateFormatDate(
dateFormat,
ZoneId.of(policy.snapshotConfig[DATE_FORMAT_TIMEZONE_FIELD] as String),
)
} else {
generateFormatDate(dateFormat)
}.lowercase()
result += "-$dateValue"
return result + "-${getRandomString(RANDOM_STRING_LENGTH)}"
}

Expand All @@ -161,10 +164,12 @@ fun getRandomString(length: Int): String {
.joinToString("")
}

fun generateFormatTime(dateFormat: String, timezone: ZoneId = ZoneId.of("UTC")): String {
/**
* For the supporting formats, refer to [DateFormatters]
*/
fun generateFormatDate(dateFormat: String, timezone: ZoneId = ZoneId.of("UTC")): String {
val dateFormatter = DateFormatter.forPattern(dateFormat).withZone(timezone)
val instant = dateFormatter.toDateMathParser().parse("now/s", System::currentTimeMillis, false, timezone)
return dateFormatter.format(instant)
return dateFormatter.format(now())
}

fun validateDateFormat(dateFormat: String): String? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class SMUtilsTests : OpenSearchTestCase() {

fun `test snapshot name date_format`() {
assertFailsWith<IllegalArgumentException> {
val smPolicy = randomSMPolicy(dateFormat = "")
val smPolicy = randomSMPolicy(dateFormat = " ")
val smPolicyString = smPolicy.toJsonString()
smPolicyString.parser().parseWithType(smPolicy.id, smPolicy.seqNo, smPolicy.primaryTerm, SMPolicy.Companion::parse)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.apache.http.HttpHeaders
import org.apache.http.entity.ContentType.APPLICATION_JSON
import org.apache.http.entity.StringEntity
import org.apache.http.message.BasicHeader
import org.junit.Before
import org.opensearch.client.Response
import org.opensearch.client.ResponseException
import org.opensearch.common.xcontent.XContentParser
Expand All @@ -30,10 +31,24 @@ import org.opensearch.jobscheduler.spi.schedule.IntervalSchedule
import org.opensearch.rest.RestStatus
import java.io.InputStream
import java.time.Duration
import java.time.Instant
import java.time.Instant.now

abstract class SnapshotManagementRestTestCase : IndexManagementRestTestCase() {

var timeout: Instant = Instant.ofEpochSecond(20)

/**
* For multi node test, if the shard of config index is moving, then the job scheduler
* could miss the execution after [updateSMPolicyStartTime]
* Extending this to be more than 1 minute, so even missed at first place, it could still be
* picked up to run in the next scheduled job.
*/
@Before
fun timeoutForMultiNode() {
if (isMultiNode) timeout = Instant.ofEpochSecond(70)
}

protected fun createSMPolicy(
smPolicy: SMPolicy,
refresh: Boolean = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class RestExplainSnapshotManagementIT : SnapshotManagementRestTestCase() {
)
)
updateSMPolicyStartTime(smPolicy)
waitFor {
waitFor(timeout = timeout) {
val explainResponse = explainSMPolicy(smPolicy.policyName)
val responseMap = createParser(XContentType.JSON.xContent(), explainResponse.entity.content).map() as Map<String, Any>
assertTrue(responseMap.containsKey(ExplainSMPolicyResponse.SM_POLICIES_FIELD))
Expand Down Expand Up @@ -76,7 +76,7 @@ class RestExplainSnapshotManagementIT : SnapshotManagementRestTestCase() {
}
// if this proves to be flaky, just index the metadata directly instead of executing to generate metadata
smPolicies.forEach { updateSMPolicyStartTime(it) }
waitFor {
waitFor(timeout = timeout) {
val explainResponse = explainSMPolicy(smPolicies.joinToString(",") { it.policyName })
val responseMap = createParser(XContentType.JSON.xContent(), explainResponse.entity.content).map() as Map<String, Any>
assertTrue(responseMap.containsKey(ExplainSMPolicyResponse.SM_POLICIES_FIELD))
Expand Down Expand Up @@ -104,7 +104,7 @@ class RestExplainSnapshotManagementIT : SnapshotManagementRestTestCase() {
}
// if this proves to be flaky, just index the metadata directly instead of executing to generate metadata
smPolicies.forEach { updateSMPolicyStartTime(it) }
waitFor {
waitFor(timeout = timeout) {
val explainResponse = explainSMPolicy("")
val responseMap = createParser(XContentType.JSON.xContent(), explainResponse.entity.content).map() as Map<String, Any>
assertTrue(responseMap.containsKey(ExplainSMPolicyResponse.SM_POLICIES_FIELD))
Expand Down

0 comments on commit 195adf9

Please sign in to comment.