diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationRequest.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationRequest.java index 4ebe1c2..ce9dd46 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationRequest.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationRequest.java @@ -50,15 +50,22 @@ public static ReservationRequest newInstance(Resource capability, return newInstance(capability, numContainers, 1, -1); } + public static ReservationRequest newInstance(Resource capability, + int numContainers, int concurrency, long duration) { + return newInstance(capability, numContainers, concurrency, duration, null); + } + @Public @Unstable public static ReservationRequest newInstance(Resource capability, - int numContainers, int concurrency, long duration) { + int numContainers, int concurrency, long duration, + String labelExpression) { ReservationRequest request = Records.newRecord(ReservationRequest.class); request.setCapability(capability); request.setNumContainers(numContainers); request.setConcurrency(concurrency); request.setDuration(duration); + request.setNodeLabelExpression(labelExpression); return request; } @@ -79,6 +86,11 @@ public int compare(ReservationRequest r1, ReservationRequest r2) { if (ret == 0) { ret = r1.getCapability().compareTo(r2.getCapability()); } + // compare node label expressions as well + if (ret == 0) { + ret = + r1.getNodeLabelExpression().compareTo(r2.getNodeLabelExpression()); + } return ret; } } @@ -163,6 +175,14 @@ public int compare(ReservationRequest r1, ReservationRequest r2) { @Unstable public abstract void setDuration(long duration); + @Public + @Unstable + public abstract String getNodeLabelExpression(); + + @Public + @Unstable + public abstract void setNodeLabelExpression(String nodelabelExpression); + @Override public int hashCode() { final int prime = 2153; @@ -194,6 +214,10 @@ public boolean equals(Object obj) { return false; if (getConcurrency() != other.getConcurrency()) return false; + if (!getNodeLabelExpression().equals(other.getNodeLabelExpression())) { + return false; + } + return true; } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto index 09d2bd5..65a3a0e 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto @@ -440,6 +440,7 @@ message ReservationRequestProto { optional int32 num_containers = 2 [default = 1]; optional int32 concurrency = 3 [default = 1]; optional int64 duration = 4 [default = -1]; + optional string node_label_expression = 5; } message ReservationRequestsProto { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ReservationRequestPBImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ReservationRequestPBImpl.java index e36b9fb..39bd9a7 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ReservationRequestPBImpl.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ReservationRequestPBImpl.java @@ -135,6 +135,26 @@ public void setDuration(long duration) { builder.setDuration(duration); } + @Override + public String getNodeLabelExpression() { + ReservationRequestProtoOrBuilder p = viaProto ? proto : builder; + if (!p.hasNodeLabelExpression()) { + return null; + } + return p.getNodeLabelExpression().trim(); + } + + @Override + public void setNodeLabelExpression(String nodeLabelExpression) { + maybeInitBuilder(); + // sanity check on input + if (null == nodeLabelExpression) { + builder.clearNodeLabelExpression(); + return; + } + builder.setNodeLabelExpression(nodeLabelExpression); + } + private ResourcePBImpl convertFromProtoFormat(ResourceProto p) { return new ResourcePBImpl(p); } @@ -147,6 +167,7 @@ private ResourceProto convertToProtoFormat(Resource t) { public String toString() { return "{Capability: " + getCapability() + ", # Containers: " + getNumContainers() + ", Concurrency: " + getConcurrency() - + ", Lease Duration: " + getDuration() + "}"; + + ", Lease Duration: " + getDuration() + + ", Node Label Expression: " + getNodeLabelExpression() + "}"; } } \ No newline at end of file diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/api/TestPBImplRecords.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/api/TestPBImplRecords.java index 5f707b5..ea05fc3 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/api/TestPBImplRecords.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/api/TestPBImplRecords.java @@ -171,6 +171,7 @@ import org.apache.hadoop.yarn.api.records.impl.pb.PriorityPBImpl; import org.apache.hadoop.yarn.api.records.impl.pb.QueueInfoPBImpl; import org.apache.hadoop.yarn.api.records.impl.pb.QueueUserACLInfoPBImpl; +import org.apache.hadoop.yarn.api.records.impl.pb.ReservationRequestPBImpl; import org.apache.hadoop.yarn.api.records.impl.pb.ResourceBlacklistRequestPBImpl; import org.apache.hadoop.yarn.api.records.impl.pb.ResourceOptionPBImpl; import org.apache.hadoop.yarn.api.records.impl.pb.ResourcePBImpl; @@ -203,6 +204,7 @@ import org.apache.hadoop.yarn.proto.YarnProtos.PriorityProto; import org.apache.hadoop.yarn.proto.YarnProtos.QueueInfoProto; import org.apache.hadoop.yarn.proto.YarnProtos.QueueUserACLInfoProto; +import org.apache.hadoop.yarn.proto.YarnProtos.ReservationRequestProto; import org.apache.hadoop.yarn.proto.YarnProtos.ResourceBlacklistRequestProto; import org.apache.hadoop.yarn.proto.YarnProtos.ResourceOptionProto; import org.apache.hadoop.yarn.proto.YarnProtos.ResourceProto; @@ -1067,6 +1069,12 @@ public void testResourceRequestPBImpl() throws Exception { } @Test + public void testReservationRequestPBImpl() throws Exception { + validatePBImplRecord(ReservationRequestPBImpl.class, + ReservationRequestProto.class); + } + + @Test public void testSerializedExceptionPBImpl() throws Exception { validatePBImplRecord(SerializedExceptionPBImpl.class, SerializedExceptionProto.class); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/api/records/impl/pb/TestReservationRequestPBImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/api/records/impl/pb/TestReservationRequestPBImpl.java new file mode 100644 index 0000000..4163c6c --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/api/records/impl/pb/TestReservationRequestPBImpl.java @@ -0,0 +1,72 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.hadoop.yarn.api.records.impl.pb; + +import org.junit.Assert; +import org.apache.hadoop.yarn.proto.YarnProtos.ReservationRequestProto; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class TestReservationRequestPBImpl { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testReservationRequest() throws Exception { + final String simple_nl = "x"; + final String simple_nle = "sc1 || sc2"; + + // initialize an instance of the class that represents the + // ReservationRequest proto + ReservationRequestPBImpl orig = new ReservationRequestPBImpl(); + orig.setNodeLabelExpression(simple_nl); + orig.setConcurrency(10); + orig.setDuration(100); + orig.setNumContainers(1000); + // get the serialized protobuf + ReservationRequestProto proto = orig.getProto(); + // now attempt to deserialize this protobuf by instantiating a new object + // from it + ReservationRequestPBImpl deser = new ReservationRequestPBImpl(proto); + + System.out.println("resreq from orig record: " + orig.toString()); + System.out.println("resreq from orig proto: " + proto.toString()); + System.out.println("resreq from deser record: " + deser.toString()); + + Assert.assertEquals(orig, deser); + Assert.assertTrue(orig.equals(deser)); + Assert.assertEquals(orig.getNodeLabelExpression(), + deser.getNodeLabelExpression()); + Assert.assertEquals(orig.getNodeLabelExpression(), simple_nl); + + // now modify deser and test + deser.setNodeLabelExpression(simple_nle); + Assert.assertEquals(simple_nle, deser.getNodeLabelExpression()); + Assert.assertNotEquals(orig.getNodeLabelExpression(), + deser.getNodeLabelExpression()); + Assert.assertFalse("deser nle should be different from orig nle", + deser.equals(orig)); + } +}