Skip to content

Commit

Permalink
add updatedAt in resource limit group
Browse files Browse the repository at this point in the history
Signed-off-by: Kaushal Kumar <ravi.kaushal97@gmail.com>
  • Loading branch information
kaushalmahi12 committed Jun 3, 2024
1 parent 9119813 commit 9e11acf
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 18 deletions.
17 changes: 16 additions & 1 deletion server/src/main/java/org/opensearch/cluster/ClusterModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,22 @@
import org.opensearch.cluster.action.index.NodeMappingRefreshAction;
import org.opensearch.cluster.action.shard.ShardStateAction;
import org.opensearch.cluster.decommission.DecommissionAttributeMetadata;
import org.opensearch.cluster.metadata.*;
import org.opensearch.cluster.metadata.ComponentTemplateMetadata;
import org.opensearch.cluster.metadata.ComposableIndexTemplateMetadata;
import org.opensearch.cluster.metadata.DataStreamMetadata;
import org.opensearch.cluster.metadata.IndexGraveyard;
import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
import org.opensearch.cluster.metadata.Metadata;
import org.opensearch.cluster.metadata.MetadataDeleteIndexService;
import org.opensearch.cluster.metadata.MetadataIndexAliasesService;
import org.opensearch.cluster.metadata.MetadataIndexStateService;
import org.opensearch.cluster.metadata.MetadataIndexTemplateService;
import org.opensearch.cluster.metadata.MetadataMappingService;
import org.opensearch.cluster.metadata.MetadataUpdateSettingsService;
import org.opensearch.cluster.metadata.RepositoriesMetadata;
import org.opensearch.cluster.metadata.ResourceLimitGroupMetadata;
import org.opensearch.cluster.metadata.ViewMetadata;
import org.opensearch.cluster.metadata.WeightedRoutingMetadata;
import org.opensearch.cluster.routing.DelayedAllocationService;
import org.opensearch.cluster.routing.allocation.AllocationService;
import org.opensearch.cluster.routing.allocation.ExistingShardsAllocator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.opensearch.core.xcontent.ToXContentObject;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.core.xcontent.XContentParser;
import org.joda.time.Instant;

import java.io.IOException;
import java.util.HashMap;
Expand All @@ -30,7 +31,8 @@
* "analytics" : {
* "jvm": 0.4,
* "mode": "enforced",
* "_id": "fafjafjkaf9ag8a9ga9g7ag0aagaga"
* "_id": "fafjafjkaf9ag8a9ga9g7ag0aagaga",
* "updatedAt": 4513232415
* }
* }
*/
Expand All @@ -41,12 +43,14 @@ public class ResourceLimitGroup extends AbstractDiffable<ResourceLimitGroup> imp
private final String name;
private final String _id;
private final ResourceLimitGroupMode mode;
// It is an epoch in millis
private final long updatedAtInMillis;
private final Map<String, Object> resourceLimits;

// list of resources that are allowed to be present in the ResourceLimitGroupSchema
// list of resources that are allowed to be present in the ResourceLimitGroup schema
public static final List<String> ALLOWED_RESOURCES = List.of("jvm");

public ResourceLimitGroup(String name, String _id, ResourceLimitGroupMode mode, Map<String, Object> resourceLimits) {
public ResourceLimitGroup(String name, String _id, ResourceLimitGroupMode mode, Map<String, Object> resourceLimits, long updatedAt) {
Objects.requireNonNull(name, "ResourceLimitGroup.name can't be null");
Objects.requireNonNull(resourceLimits, "ResourceLimitGroup.resourceLimits can't be null");
Objects.requireNonNull(mode, "ResourceLimitGroup.mode can't be null");
Expand All @@ -60,15 +64,29 @@ public ResourceLimitGroup(String name, String _id, ResourceLimitGroupMode mode,
throw new IllegalArgumentException("ResourceLimitGroup.resourceLimits should at least have 1 resource limit");
}
validateResourceLimits(resourceLimits);
if (!isValid(updatedAt)) {
throw new IllegalArgumentException("ResourceLimitGroup.updatedAtInMillis is not a valid epoch");
}

this.name = name;
this._id = _id;
this.mode = mode;
this.resourceLimits = resourceLimits;
this.updatedAtInMillis = updatedAt;
}

private static boolean isValid(long updatedAt) {
long minValidTimestamp = Instant.ofEpochMilli(0L).getMillis();

// Use Instant.now() to get the current time in seconds since epoch
long currentSeconds = Instant.now().getMillis();

// Check if the timestamp is within a reasonable range
return minValidTimestamp <= updatedAt && updatedAt <= currentSeconds;
}

public ResourceLimitGroup(StreamInput in) throws IOException {
this(in.readString(), in.readString(), ResourceLimitGroupMode.fromName(in.readString()), in.readMap());
this(in.readString(), in.readString(), ResourceLimitGroupMode.fromName(in.readString()), in.readMap(), in.readLong());
}

/**
Expand All @@ -82,6 +100,7 @@ public void writeTo(StreamOutput out) throws IOException {
out.writeString(_id);
out.writeString(mode.getName());
out.writeMap(resourceLimits);
out.writeLong(updatedAtInMillis);
}

private void validateResourceLimits(Map<String, Object> resourceLimits) {
Expand Down Expand Up @@ -115,6 +134,7 @@ public XContentBuilder toXContent(final XContentBuilder builder, final Params pa
builder.startObject(this._id);
builder.field("name", name);
builder.field("mode", mode.getName());
builder.field("updatedAt", updatedAtInMillis);
builder.mapContents(resourceLimits);
builder.endObject();
builder.endObject();
Expand Down Expand Up @@ -151,6 +171,8 @@ public static ResourceLimitGroup fromXContent(final XContentParser parser) throw
builder.name(parser.text());
} else if (fieldName.equals("mode")) {
builder.mode(parser.text());
} else if (fieldName.equals("updatedAt")) {
builder.updatedAt(parser.longValue());
} else if (ALLOWED_RESOURCES.contains(fieldName)) {
resourceLimitGroup_.put(fieldName, parser.doubleValue());
} else {
Expand Down Expand Up @@ -191,6 +213,14 @@ public Map<String, Object> getResourceLimits() {
return resourceLimits;
}

public String get_id() {
return _id;
}

public long getUpdatedAtInMillis() {
return updatedAtInMillis;
}

/**
* builder method for this {@link ResourceLimitGroup}
* @return
Expand Down Expand Up @@ -219,9 +249,8 @@ public String getName() {
}

public static ResourceLimitGroupMode fromName(String s) {
for (ResourceLimitGroupMode mode: values()) {
if (mode.getName().equalsIgnoreCase(s))
return mode;
for (ResourceLimitGroupMode mode : values()) {
if (mode.getName().equalsIgnoreCase(s)) return mode;

}
throw new IllegalArgumentException("Invalid value for ResourceLimitGroupMode: " + s);
Expand All @@ -237,6 +266,7 @@ public static class Builder {
private String name;
private String _id;
private ResourceLimitGroupMode mode;
private long updatedAt;
private Map<String, Object> resourceLimitGroup;

private Builder() {}
Expand All @@ -256,13 +286,18 @@ public Builder mode(String mode) {
return this;
}

public Builder updatedAt(long updatedAt) {
this.updatedAt = updatedAt;
return this;
}

public Builder resourceLimitGroup(Map<String, Object> resourceLimitGroup) {
this.resourceLimitGroup = resourceLimitGroup;
return this;
}

public ResourceLimitGroup build() {
return new ResourceLimitGroup(name, _id, mode, resourceLimitGroup);
return new ResourceLimitGroup(name, _id, mode, resourceLimitGroup, updatedAt);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.opensearch.core.common.io.stream.Writeable;
import org.opensearch.core.xcontent.XContentParser;
import org.opensearch.test.AbstractSerializingTestCase;
import org.joda.time.Instant;

import java.io.IOException;
import java.util.Collections;
Expand All @@ -30,7 +31,7 @@ static ResourceLimitGroup createRandomResourceLimitGroup() {
String name = randomAlphaOfLength(10);
Map<String, Object> resourceLimit = new HashMap<>();
resourceLimit.put("jvm", randomDoubleBetween(0.0, 0.80, false));
return new ResourceLimitGroup(name, "random", randomMode(), resourceLimit);
return new ResourceLimitGroup(name, "random", randomMode(), resourceLimit, Instant.now().getMillis());
}

private static ResourceLimitGroup.ResourceLimitGroupMode randomMode() {
Expand Down Expand Up @@ -66,26 +67,38 @@ protected ResourceLimitGroup createTestInstance() {
}

public void testNullName() {
assertThrows(NullPointerException.class, () -> new ResourceLimitGroup(null, "_id", randomMode(), Collections.emptyMap()));
assertThrows(
NullPointerException.class,
() -> new ResourceLimitGroup(null, "_id", randomMode(), Collections.emptyMap(), Instant.now().getMillis())
);
}

public void testNullId() {
assertThrows(NullPointerException.class, () -> new ResourceLimitGroup("Dummy", null, randomMode(), Collections.emptyMap()));
assertThrows(
NullPointerException.class,
() -> new ResourceLimitGroup("Dummy", null, randomMode(), Collections.emptyMap(), Instant.now().getMillis())
);
}

public void testNullResourceLimits() {
assertThrows(NullPointerException.class, () -> new ResourceLimitGroup("analytics", "_id", randomMode(), null));
assertThrows(
NullPointerException.class,
() -> new ResourceLimitGroup("analytics", "_id", randomMode(), null, Instant.now().getMillis())
);
}

public void testEmptyResourceLimits() {
assertThrows(
IllegalArgumentException.class,
() -> new ResourceLimitGroup("analytics", "_id", randomMode(), Collections.emptyMap())
() -> new ResourceLimitGroup("analytics", "_id", randomMode(), Collections.emptyMap(), Instant.now().getMillis())
);
}

public void testIllegalResourceLimitGroupMode() {
assertThrows(NullPointerException.class, () -> new ResourceLimitGroup("analytics", "_id", null, Map.of("jvm", (Object) 0.4)));
assertThrows(
NullPointerException.class,
() -> new ResourceLimitGroup("analytics", "_id", null, Map.of("jvm", (Object) 0.4), Instant.now().getMillis())
);
}

public void testInvalidResourceLimitWhenInvalidSystemResourceNameIsGiven() {
Expand All @@ -95,7 +108,8 @@ public void testInvalidResourceLimitWhenInvalidSystemResourceNameIsGiven() {
"analytics",
"_id",
randomMode(),
Map.of("RequestRate", (Object) randomDoubleBetween(0.01, 0.8, false))
Map.of("RequestRate", (Object) randomDoubleBetween(0.01, 0.8, false)),
Instant.now().getMillis()
)
);
}
Expand All @@ -107,7 +121,8 @@ public void testInvalidResourceLimitWhenInvalidSystemResourceValueIsGiven() {
"analytics",
"_id",
randomMode(),
Map.of("RequestRate", (Object) randomDoubleBetween(1.1, 1.8, false))
Map.of("RequestRate", (Object) randomDoubleBetween(1.1, 1.8, false)),
Instant.now().getMillis()
)
);
}
Expand All @@ -117,7 +132,8 @@ public void testValidResourceLimitGroup() {
"analytics",
"_id",
randomMode(),
Map.of("jvm", randomDoubleBetween(0.01, 0.8, false))
Map.of("jvm", randomDoubleBetween(0.01, 0.8, false)),
Instant.ofEpochMilli(1717187289).getMillis()
);

assertNotNull(resourceLimitGroup.getName());
Expand All @@ -126,5 +142,6 @@ public void testValidResourceLimitGroup() {
assertFalse(resourceLimitGroup.getResourceLimits().isEmpty());
assertEquals(1, resourceLimitGroup.getResourceLimits().size());
assertTrue(allowedModes.contains(resourceLimitGroup.getMode()));
assertEquals(1717187289, resourceLimitGroup.getUpdatedAtInMillis());
}
}

0 comments on commit 9e11acf

Please sign in to comment.