YARN-4340. Add list API to reservation system. (Sean Po via wangda) (cherry picked from commit 9875325d5c63f343809907d06bf48a298035a611)
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/c487453b Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/c487453b Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/c487453b Branch: refs/heads/branch-2.8 Commit: c487453b91bac34ee9f9d98406c6e9dfbe8d38ab Parents: 9862879 Author: Wangda Tan <[email protected]> Authored: Tue Feb 2 10:17:33 2016 +0800 Committer: Wangda Tan <[email protected]> Committed: Tue Feb 2 10:23:25 2016 +0800 ---------------------------------------------------------------------- .../hadoop/mapred/ResourceMgrDelegate.java | 7 + .../hadoop/mapred/TestClientRedirect.java | 8 + hadoop-yarn-project/CHANGES.txt | 2 + .../yarn/api/ApplicationClientProtocol.java | 49 ++- .../protocolrecords/ReservationListRequest.java | 228 ++++++++++++++ .../ReservationListResponse.java | 79 +++++ .../api/records/ReservationAllocationState.java | 191 +++++++++++ .../api/records/ResourceAllocationRequest.java | 123 ++++++++ .../main/proto/applicationclient_protocol.proto | 1 + .../src/main/proto/yarn_protos.proto | 17 + .../src/main/proto/yarn_service_protos.proto | 12 + .../hadoop/yarn/client/api/YarnClient.java | 49 ++- .../yarn/client/api/impl/YarnClientImpl.java | 10 +- .../yarn/client/api/impl/TestYarnClient.java | 173 ++++++++++ .../ApplicationClientProtocolPBClientImpl.java | 17 + .../ApplicationClientProtocolPBServiceImpl.java | 24 +- .../impl/pb/ReservationListRequestPBImpl.java | 178 +++++++++++ .../impl/pb/ReservationListResponsePBImpl.java | 157 ++++++++++ .../pb/ReservationAllocationStatePBImpl.java | 288 +++++++++++++++++ .../pb/ResourceAllocationRequestPBImpl.java | 188 +++++++++++ .../hadoop/yarn/api/TestPBImplRecords.java | 22 +- .../amrmproxy/MockResourceManagerFacade.java | 14 +- .../server/resourcemanager/ClientRMService.java | 44 +++ .../server/resourcemanager/RMAuditLogger.java | 2 + .../recovery/FileSystemRMStateStore.java | 2 +- .../recovery/LeveldbRMStateStore.java | 2 +- .../recovery/MemoryRMStateStore.java | 2 +- .../recovery/NullRMStateStore.java | 2 +- .../resourcemanager/recovery/RMStateStore.java | 2 +- .../RMStateStoreStoreReservationEvent.java | 2 +- .../recovery/ZKRMStateStore.java | 2 +- .../reservation/AbstractReservationSystem.java | 2 +- .../reservation/InMemoryPlan.java | 71 +++-- .../resourcemanager/reservation/PlanView.java | 17 + .../reservation/ReservationInputValidator.java | 122 ++++--- .../reservation/ReservationSystemUtil.java | 45 ++- .../yarn_server_resourcemanager_recovery.proto | 16 - .../resourcemanager/TestClientRMService.java | 179 +++++++++++ .../TestReservationSystemWithRMHA.java | 2 +- .../recovery/RMStateStoreTestBase.java | 6 +- .../reservation/TestInMemoryPlan.java | 314 +++++++++++++------ .../TestReservationInputValidator.java | 103 +++++- .../reservation/TestReservationSystemUtil.java | 134 ++++++++ 43 files changed, 2702 insertions(+), 206 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ResourceMgrDelegate.java ---------------------------------------------------------------------- diff --git a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ResourceMgrDelegate.java b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ResourceMgrDelegate.java index f5fd0cb..54e1549 100644 --- a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ResourceMgrDelegate.java +++ b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/main/java/org/apache/hadoop/mapred/ResourceMgrDelegate.java @@ -46,6 +46,8 @@ import org.apache.hadoop.security.token.Token; import org.apache.hadoop.yarn.api.ApplicationClientProtocol; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteResponse; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListRequest; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateRequest; @@ -452,6 +454,11 @@ public class ResourceMgrDelegate extends YarnClient { } @Override + public ReservationListResponse listReservations( + ReservationListRequest request) throws YarnException, IOException { + return client.listReservations(request); + } + @Override public Map<NodeId, Set<NodeLabel>> getNodeToLabels() throws YarnException, IOException { return client.getNodeToLabels(); http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapred/TestClientRedirect.java ---------------------------------------------------------------------- diff --git a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapred/TestClientRedirect.java b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapred/TestClientRedirect.java index 8ab3304..64f967d 100644 --- a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapred/TestClientRedirect.java +++ b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapred/TestClientRedirect.java @@ -110,6 +110,8 @@ import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenRequest; import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteResponse; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListRequest; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateRequest; @@ -440,6 +442,12 @@ public class TestClientRedirect { } @Override + public ReservationListResponse listReservations( + ReservationListRequest request) throws YarnException, IOException { + return null; + } + + @Override public GetNodesToLabelsResponse getNodeToLabels( GetNodesToLabelsRequest request) throws YarnException, IOException { return null; http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/CHANGES.txt ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt index be726fb..901a1eb 100644 --- a/hadoop-yarn-project/CHANGES.txt +++ b/hadoop-yarn-project/CHANGES.txt @@ -590,6 +590,8 @@ Release 2.8.0 - UNRELEASED YARN-4371. "yarn application -kill" should take multiple application ids (Sunil G via jlowe) + YARN-4340. Add "list" API to reservation system. (Sean Po via wangda) + OPTIMIZATIONS YARN-3339. TestDockerContainerExecutor should pull a single image and not http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationClientProtocol.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationClientProtocol.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationClientProtocol.java index 1f0e777..bca062e 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationClientProtocol.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/ApplicationClientProtocol.java @@ -49,6 +49,8 @@ import org.apache.hadoop.yarn.api.protocolrecords.MoveApplicationAcrossQueuesReq import org.apache.hadoop.yarn.api.protocolrecords.MoveApplicationAcrossQueuesResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteResponse; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListRequest; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateRequest; @@ -398,7 +400,7 @@ public interface ApplicationClientProtocol extends ApplicationBaseProtocol { * @throws YarnException if the request is invalid or reservation cannot be * deleted successfully * @throws IOException - * + * */ @Public @Unstable @@ -407,6 +409,51 @@ public interface ApplicationClientProtocol extends ApplicationBaseProtocol { /** * <p> + * The interface used by clients to get the list of reservations in a plan. + * The reservationId will be used to search for reservations to list if it is + * provided. Otherwise, it will select active reservations within the + * startTime and endTime (inclusive). + * </p> + * + * @param request to list reservations in a plan. Contains fields to select + * String queue, ReservationId reservationId, long startTime, + * long endTime, and a bool includeReservationAllocations. + * + * queue: Required. Cannot be null or empty. Refers to the + * reservable queue in the scheduler that was selected when + * creating a reservation submission + * {@link ReservationSubmissionRequest}. + * + * reservationId: Optional. If provided, other fields will + * be ignored. + * + * startTime: Optional. If provided, only reservations that + * end after the startTime will be selected. This defaults + * to 0 if an invalid number is used. + * + * endTime: Optional. If provided, only reservations that + * start on or before endTime will be selected. This defaults + * to Long.MAX_VALUE if an invalid number is used. + * + * includeReservationAllocations: Optional. Flag that + * determines whether the entire reservation allocations are + * to be returned. Reservation allocations are subject to + * change in the event of re-planning as described by + * {@code ReservationDefinition}. + * + * @return response that contains information about reservations that are + * being searched for. + * @throws YarnException if the request is invalid + * @throws IOException on IO failures + * + */ + @Public + @Unstable + ReservationListResponse listReservations( + ReservationListRequest request) throws YarnException, IOException; + + /** + * <p> * The interface used by client to get node to labels mappings in existing cluster * </p> * http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/ReservationListRequest.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/ReservationListRequest.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/ReservationListRequest.java new file mode 100644 index 0000000..0b5275c --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/ReservationListRequest.java @@ -0,0 +1,228 @@ +/** + * 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.protocolrecords; + +import org.apache.hadoop.classification.InterfaceAudience.Public; +import org.apache.hadoop.classification.InterfaceStability.Unstable; +import org.apache.hadoop.yarn.util.Records; + +/** + * {@link ReservationListRequest} captures the set of requirements the + * user has to list reservations. + */ +@Public +@Unstable +public abstract class ReservationListRequest { + + /** + * The {@link ReservationListRequest} will use the reservationId to search for + * reservations to list if it is provided. Otherwise, it will select active + * reservations within the startTime and endTime (inclusive). + * + * @param queue Required. Cannot be null or empty. Refers to the reservable + * queue in the scheduler that was selected when creating a + * reservation submission {@link ReservationSubmissionRequest}. + * @param reservationId Optional. String representation of + * {@code ReservationId} If provided, other fields will + * be ignored. + * @param startTime Optional. If provided, only reservations that + * end after the startTime will be selected. This defaults + * to 0 if an invalid number is used. + * @param endTime Optional. If provided, only reservations that + * start on or before endTime will be selected. This defaults + * to Long.MAX_VALUE if an invalid number is used. + * @param includeReservationAllocations Optional. Flag that + * determines whether the entire reservation allocations are + * to be returned. Reservation allocations are subject to + * change in the event of re-planning as described by + * {@code ReservationDefinition}. + */ + @Public + @Unstable + public static ReservationListRequest newInstance( + String queue, String reservationId, long startTime, long endTime, + boolean includeReservationAllocations) { + ReservationListRequest request = + Records.newRecord(ReservationListRequest.class); + request.setQueue(queue); + request.setReservationId(reservationId); + request.setStartTime(startTime); + request.setEndTime(endTime); + request.setIncludeResourceAllocations(includeReservationAllocations); + return request; + } + + /** + * The {@link ReservationListRequest} will use the reservationId to search for + * reservations to list if it is provided. Otherwise, it will select active + * reservations within the startTime and endTime (inclusive). + * + * @param queue Required. Cannot be null or empty. Refers to the reservable + * queue in the scheduler that was selected when creating a + * reservation submission {@link ReservationSubmissionRequest}. + * @param reservationId Optional. String representation of + * {@code ReservationId} If provided, other fields will + * be ignored. + * @param includeReservationAllocations Optional. Flag that + * determines whether the entire reservation allocations are + * to be returned. Reservation allocations are subject to + * change in the event of re-planning as described by + * {@code ReservationDefinition}. + */ + @Public + @Unstable + public static ReservationListRequest newInstance( + String queue, String reservationId, boolean + includeReservationAllocations) { + return newInstance(queue, reservationId, -1, -1, + includeReservationAllocations); + } + + /** + * The {@link ReservationListRequest} will use the reservationId to search for + * reservations to list if it is provided. Otherwise, it will select active + * reservations within the startTime and endTime (inclusive). + * + * @param queue Required. Cannot be null or empty. Refers to the reservable + * queue in the scheduler that was selected when creating a + * reservation submission {@link ReservationSubmissionRequest}. + * @param reservationId Optional. String representation of + * {@code ReservationId} If provided, other fields will + * be ignored. + */ + @Public + @Unstable + public static ReservationListRequest newInstance( + String queue, String reservationId) { + return newInstance(queue, reservationId, -1, -1, false); + } + + /** + * Get queue name to use to find reservations. + * + * @return the queue name to use to find reservations. + */ + @Public + @Unstable + public abstract String getQueue(); + + /** + * Set queue name to use to find resource allocations. + * + * @param queue Required. Cannot be null or empty. + */ + @Public + @Unstable + public abstract void setQueue(String queue); + + /** + * Get the reservation id to use to find a reservation. + * + * @return the reservation id of the reservation. + */ + @Public + @Unstable + public abstract String getReservationId(); + + /** + * Set the reservation id to use to find a reservation. + * + * @param reservationId Optional. String representation of + * {@code ReservationId} If provided, other fields will + * be ignored. + */ + @Public + @Unstable + public abstract void setReservationId(String reservationId); + + /** + * Get the start time to use to search for reservations. + * When this is set, reservations that start before this start + * time are ignored. + * + * @return the start time to use to search for reservations. + */ + @Public + @Unstable + public abstract long getStartTime(); + + /** + * Set the start time to use to search for reservations. + * When this is set, reservations that start before this start + * time are ignored. + * + * @param startTime Optional. If provided, only reservations that + * end after the startTime will be selected. This defaults + * to 0 if an invalid number is used. + */ + @Public + @Unstable + public abstract void setStartTime(long startTime); + + /** + * Get the end time to use to search for reservations. + * When this is set, reservations that start after this end + * time are ignored. + * + * @return the end time to use to search for reservations. + */ + @Public + @Unstable + public abstract long getEndTime(); + + /** + * Set the end time to use to search for reservations. + * When this is set, reservations that start after this end + * time are ignored. + * + * @param endTime Optional. If provided, only reservations that + * start before endTime will be selected. This defaults + * to Long.MAX_VALUE if an invalid number is used. + */ + @Public + @Unstable + public abstract void setEndTime(long endTime); + + /** + * Get the boolean representing whether or not the user + * is requesting the full resource allocation. + * If this is true, the full resource allocation will + * be included in the response. + * + * @return the end time to use to search for reservations. + */ + @Public + @Unstable + public abstract boolean getIncludeResourceAllocations(); + + /** + * Set the boolean representing whether or not the user + * is requesting the full resource allocation. + * If this is true, the full resource allocation will + * be included in the response. + * + * @param includeReservationAllocations Optional. Flag that + * determines whether the entire list of + * {@code ResourceAllocationRequest} will be returned. + */ + @Public + @Unstable + public abstract void setIncludeResourceAllocations( + boolean includeReservationAllocations); +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/ReservationListResponse.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/ReservationListResponse.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/ReservationListResponse.java new file mode 100644 index 0000000..a5a5e08 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/ReservationListResponse.java @@ -0,0 +1,79 @@ +/** + * 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.protocolrecords; + +import org.apache.hadoop.classification.InterfaceAudience.Private; +import org.apache.hadoop.classification.InterfaceAudience.Public; +import org.apache.hadoop.classification.InterfaceStability.Unstable; +import org.apache.hadoop.yarn.api.records.ReservationAllocationState; +import org.apache.hadoop.yarn.util.Records; + +import java.util.List; + +/** + * {@link ReservationListResponse} captures the list of reservations that the + * user has queried. + * + * The resulting list of {@link ReservationAllocationState} contains a list of + * {@code ResourceAllocationRequest} representing the current state of the + * reservation resource allocations will be returned. This is subject to change + * in the event of re-planning a described by {@code ReservationDefinition} + * + * @see ReservationAllocationState + * + */ +@Public +@Unstable +public abstract class ReservationListResponse { + + @Private + @Unstable + public static ReservationListResponse newInstance( + List<ReservationAllocationState> reservationAllocationState) { + ReservationListResponse response = + Records.newRecord(ReservationListResponse.class); + response.setReservationAllocationState(reservationAllocationState); + return response; + } + + /** + * Get the list of {@link ReservationAllocationState}, that corresponds + * to a reservation in the scheduler. + * + * @return the list of {@link ReservationAllocationState} which holds + * information of a particular reservation + */ + @Public + @Unstable + public abstract List<ReservationAllocationState> + getReservationAllocationState(); + + /** + * Set the list of {@link ReservationAllocationState}, that correspond + * to a reservation in the scheduler. + * + * @param reservationAllocationState the list of + * {@link ReservationAllocationState} which holds information of a + * particular reservation. + */ + @Private + @Unstable + public abstract void setReservationAllocationState( + List<ReservationAllocationState> reservationAllocationState); +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationAllocationState.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationAllocationState.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationAllocationState.java new file mode 100644 index 0000000..c67b736 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ReservationAllocationState.java @@ -0,0 +1,191 @@ +/** + * 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; + +import org.apache.hadoop.classification.InterfaceAudience.Private; +import org.apache.hadoop.classification.InterfaceAudience.Public; +import org.apache.hadoop.classification.InterfaceStability.Stable; +import org.apache.hadoop.classification.InterfaceStability.Unstable; +import org.apache.hadoop.yarn.util.Records; + +import java.util.List; + +/** + * {@code ReservationAllocationState} represents the reservation that is + * made by a user. + * <p> + * It includes: + * <ul> + * <li>Duration of the reservation.</li> + * <li>Acceptance time of the duration.</li> + * <li> + * List of {@link ResourceAllocationRequest}, which includes the time + * interval, and capability of the allocation. + * {@code ResourceAllocationRequest} represents an allocation + * made for a reservation for the current state of the queue. This can be + * changed for reasons such as re-planning, but will always be subject to + * the constraints of the user contract as described by + * {@link ReservationDefinition} + * </li> + * <li>{@link ReservationId} of the reservation.</li> + * <li>{@link ReservationDefinition} used to make the reservation.</li> + * </ul> + * + * @see ResourceAllocationRequest + * @see ReservationId + * @see ReservationDefinition + */ +@Public +@Stable +public abstract class ReservationAllocationState { + + /** + * + * @param acceptanceTime The acceptance time of the reservation. + * @param user The username of the user who made the reservation. + * @param resourceAllocations List of {@link ResourceAllocationRequest} + * representing the current state of the + * reservation resource allocations. This is + * subject to change in the event of re-planning. + * @param reservationId {@link ReservationId } of the reservation being + * listed. + * @param reservationDefinition {@link ReservationDefinition} used to make + * the reservation. + * @return {@code ReservationAllocationState} that represents the state of + * the reservation. + */ + @Public + @Stable + public static ReservationAllocationState newInstance(long acceptanceTime, + String user, List<ResourceAllocationRequest> resourceAllocations, + ReservationId reservationId, + ReservationDefinition reservationDefinition) { + ReservationAllocationState ri = Records.newRecord( + ReservationAllocationState.class); + ri.setAcceptanceTime(acceptanceTime); + ri.setUser(user); + ri.setResourceAllocationRequests(resourceAllocations); + ri.setReservationId(reservationId); + ri.setReservationDefinition(reservationDefinition); + return ri; + } + + /** + * Get the acceptance time of the reservation. + * + * @return the time that the reservation was accepted. + */ + @Public + @Unstable + public abstract long getAcceptanceTime(); + + /** + * Set the time that the reservation was accepted. + * + * @param acceptanceTime The acceptance time of the reservation. + */ + @Private + @Unstable + public abstract void setAcceptanceTime(long acceptanceTime); + + /** + * Get the user who made the reservation. + * + * @return the name of the user who made the reservation. + */ + @Public + @Unstable + public abstract String getUser(); + + /** + * Set the user who made the reservation. + * + * @param user The username of the user who made the reservation. + */ + @Private + @Unstable + public abstract void setUser(String user); + + /** + * Get the Resource allocations of the reservation based on the current state + * of the plan. This is subject to change in the event of re-planning. + * The allocations will be constraint to the user contract as described by + * the {@link ReservationDefinition} + * + * @return a list of resource allocations for the reservation. + */ + @Public + @Unstable + public abstract List<ResourceAllocationRequest> + getResourceAllocationRequests(); + + /** + * Set the list of resource allocations made for the reservation. + * + * @param resourceAllocations List of {@link ResourceAllocationRequest} + * representing the current state of the + * reservation resource allocations. This is + * subject to change in the event of re-planning. + */ + @Private + @Unstable + public abstract void setResourceAllocationRequests( + List<ResourceAllocationRequest> resourceAllocations); + + /** + * Get the id of the reservation. + * + * @return the reservation id corresponding to the reservation. + */ + @Public + @Unstable + public abstract ReservationId getReservationId(); + + /** + * Set the id corresponding to the reservation. + * ` + * @param reservationId {@link ReservationId } of the reservation being + * listed. + */ + @Private + @Unstable + public abstract void setReservationId(ReservationId reservationId); + + /** + * Get the reservation definition used to make the reservation. + * + * @return the reservation definition used to make the reservation. + */ + @Public + @Unstable + public abstract ReservationDefinition getReservationDefinition(); + + /** + * Set the definition of the reservation. + * + * @param reservationDefinition {@link ReservationDefinition} used to make + * the reservation. + */ + @Private + @Unstable + public abstract void setReservationDefinition(ReservationDefinition + reservationDefinition); + + +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ResourceAllocationRequest.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ResourceAllocationRequest.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ResourceAllocationRequest.java new file mode 100644 index 0000000..23a590a --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/records/ResourceAllocationRequest.java @@ -0,0 +1,123 @@ +/** + * 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; + +import org.apache.hadoop.classification.InterfaceAudience.Private; +import org.apache.hadoop.classification.InterfaceAudience.Public; +import org.apache.hadoop.classification.InterfaceStability.Unstable; +import org.apache.hadoop.classification.InterfaceStability.Stable; +import org.apache.hadoop.yarn.util.Records; + +/** + * {@code ResourceAllocationRequest} represents an allocation + * made for a reservation for the current state of the plan. This can be + * changed for reasons such as re-planning, but will always be subject to the + * constraints of the user contract as described by + * {@link ReservationDefinition} + * {@link Resource} + * + * <p> + * It includes: + * <ul> + * <li>StartTime of the allocation.</li> + * <li>EndTime of the allocation.</li> + * <li>{@link Resource} reserved for the allocation.</li> + * </ul> + * + * @see Resource + */ +@Public +@Stable +public abstract class ResourceAllocationRequest { + + /** + * @param startTime The start time that the capability is reserved for. + * @param endTime The end time that the capability is reserved for. + * @param capability {@link Resource} representing the capability of the + * resource allocation. + * @return {ResourceAllocationRequest} which represents the capability of + * the resource allocation for a time interval. + */ + @Public + @Stable + public static ResourceAllocationRequest newInstance(long startTime, + long endTime, Resource capability) { + ResourceAllocationRequest ra = Records.newRecord( + ResourceAllocationRequest.class); + ra.setEndTime(endTime); + ra.setStartTime(startTime); + ra.setCapability(capability); + return ra; + } + + /** + * Get the start time that the resource is allocated. + * + * @return the start time that the resource is allocated. + */ + @Public + @Unstable + public abstract long getStartTime(); + + /** + * Set the start time that the resource is allocated. + * + * @param startTime The start time that the capability is reserved for. + */ + @Private + @Unstable + public abstract void setStartTime(long startTime); + + /** + * Get the end time that the resource is allocated. + * + * @return the end time that the resource is allocated. + */ + @Public + @Unstable + public abstract long getEndTime(); + + /** + * Set the end time that the resource is allocated. + * + * @param endTime The end time that the capability is reserved for. + */ + @Private + @Unstable + public abstract void setEndTime(long endTime); + + /** + * Get the allocated resource. + * + * @return the allocated resource. + */ + @Public + @Unstable + public abstract Resource getCapability(); + + /** + * Set the allocated resource. + * + * @param resource {@link Resource} representing the capability of the + * resource allocation. + */ + @Private + @Unstable + public abstract void setCapability(Resource resource); +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/applicationclient_protocol.proto ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/applicationclient_protocol.proto b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/applicationclient_protocol.proto index e98726b..763c839 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/applicationclient_protocol.proto +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/applicationclient_protocol.proto @@ -53,6 +53,7 @@ service ApplicationClientProtocolService { rpc submitReservation (ReservationSubmissionRequestProto) returns (ReservationSubmissionResponseProto); rpc updateReservation (ReservationUpdateRequestProto) returns (ReservationUpdateResponseProto); rpc deleteReservation (ReservationDeleteRequestProto) returns (ReservationDeleteResponseProto); + rpc listReservations (ReservationListRequestProto) returns (ReservationListResponseProto); rpc getNodeToLabels (GetNodesToLabelsRequestProto) returns (GetNodesToLabelsResponseProto); rpc getLabelsToNodes (GetLabelsToNodesRequestProto) returns (GetLabelsToNodesResponseProto); rpc getClusterNodeLabels (GetClusterNodeLabelsRequestProto) returns (GetClusterNodeLabelsResponseProto); http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_protos.proto ---------------------------------------------------------------------- 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 ce11880..02fb28b 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 @@ -469,6 +469,23 @@ message ReservationDefinitionProto { optional string reservation_name = 4; } +message ResourceAllocationRequestProto { + optional int64 start_time = 1; + optional int64 end_time = 2; + optional ResourceProto resource = 3; +} + +message ReservationAllocationStateProto { + optional ReservationDefinitionProto reservation_definition = 1; + repeated ResourceAllocationRequestProto allocation_requests = 2; + optional int64 start_time = 3; + optional int64 end_time = 4; + optional string user = 5; + optional bool contains_gangs = 6; + optional int64 acceptance_time = 7; + optional ReservationIdProto reservation_id = 8; +} + enum ReservationRequestInterpreterProto { R_ANY = 0; R_ALL = 1; http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto index 6a27070..4ee0571 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/proto/yarn_service_protos.proto @@ -390,6 +390,18 @@ message ReservationDeleteRequestProto { message ReservationDeleteResponseProto { } +message ReservationListRequestProto { + optional string queue = 1; + optional string reservation_id = 3; + optional int64 start_time = 4; + optional int64 end_time = 5; + optional bool include_resource_allocations = 6; +} + +message ReservationListResponseProto { + repeated ReservationAllocationStateProto reservations = 1; +} + ////////////////////////////////////////////////////// /////// SCM_Admin_Protocol ////////////////////////// ////////////////////////////////////////////////////// http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/YarnClient.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/YarnClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/YarnClient.java index 523698f..73ee7b2 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/YarnClient.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/YarnClient.java @@ -34,6 +34,8 @@ import org.apache.hadoop.service.AbstractService; import org.apache.hadoop.yarn.api.ApplicationClientProtocol; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteResponse; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListRequest; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateRequest; @@ -626,7 +628,52 @@ public abstract class YarnClient extends AbstractService { @Unstable public abstract ReservationDeleteResponse deleteReservation( ReservationDeleteRequest request) throws YarnException, IOException; - + + /** + * <p> + * The interface used by clients to get the list of reservations in a plan. + * The reservationId will be used to search for reservations to list if it is + * provided. Otherwise, it will select active reservations within the + * startTime and endTime (inclusive). + * </p> + * + * @param request to list reservations in a plan. Contains fields to select + * String queue, ReservationId reservationId, long startTime, + * long endTime, and a bool includeReservationAllocations. + * + * queue: Required. Cannot be null or empty. Refers to the + * reservable queue in the scheduler that was selected when + * creating a reservation submission + * {@link ReservationSubmissionRequest}. + * + * reservationId: Optional. If provided, other fields will + * be ignored. + * + * startTime: Optional. If provided, only reservations that + * end after the startTime will be selected. This defaults + * to 0 if an invalid number is used. + * + * endTime: Optional. If provided, only reservations that + * start on or before endTime will be selected. This defaults + * to Long.MAX_VALUE if an invalid number is used. + * + * includeReservationAllocations: Optional. Flag that + * determines whether the entire reservation allocations are + * to be returned. Reservation allocations are subject to + * change in the event of re-planning as described by + * {@link ReservationDefinition}. + * + * @return response that contains information about reservations that are + * being searched for. + * @throws YarnException if the request is invalid + * @throws IOException + * + */ + @Public + @Unstable + public abstract ReservationListResponse listReservations( + ReservationListRequest request) throws YarnException, IOException; + /** * <p> * The interface used by client to get node to labels mappings in existing cluster http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java index 29fd417..26548be 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/main/java/org/apache/hadoop/yarn/client/api/impl/YarnClientImpl.java @@ -73,6 +73,8 @@ import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationResponse; import org.apache.hadoop.yarn.api.protocolrecords.MoveApplicationAcrossQueuesRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteResponse; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListRequest; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateRequest; @@ -803,7 +805,13 @@ public class YarnClientImpl extends YarnClient { ReservationDeleteRequest request) throws YarnException, IOException { return rmClient.deleteReservation(request); } - + + @Override + public ReservationListResponse listReservations( + ReservationListRequest request) throws YarnException, IOException { + return rmClient.listReservations(request); + } + @Override public Map<NodeId, Set<NodeLabel>> getNodeToLabels() throws YarnException, IOException { http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java index 5c2f23f..2c34b99 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-client/src/test/java/org/apache/hadoop/yarn/client/api/impl/TestYarnClient.java @@ -73,6 +73,8 @@ import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationRequest; import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteResponse; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListRequest; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateRequest; @@ -1233,6 +1235,163 @@ public class TestYarnClient { Assert.assertNotNull(sResponse); System.out.println("Update reservation response: " + uResponse); + // List reservations, search by reservation ID + ReservationListRequest request = + ReservationListRequest.newInstance( + ReservationSystemTestUtil.reservationQ, + reservationID.toString(), -1, -1, false); + + ReservationListResponse response = null; + try { + response = client.listReservations(request); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + Assert.assertNotNull(response); + Assert.assertEquals(1, response.getReservationAllocationState().size()); + Assert.assertEquals(response.getReservationAllocationState().get(0) + .getReservationId().getId(), reservationID.getId()); + Assert.assertEquals(response.getReservationAllocationState().get(0) + .getResourceAllocationRequests().size(), 0); + + // List reservations, search by time interval. + request = ReservationListRequest.newInstance( + ReservationSystemTestUtil.reservationQ, "", arrival + + duration/2, arrival + duration/2, true); + + response = null; + try { + response = client.listReservations(request); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + Assert.assertNotNull(response); + Assert.assertEquals(1, response.getReservationAllocationState().size()); + Assert.assertEquals(response.getReservationAllocationState().get(0) + .getReservationId().getId(), reservationID.getId()); + + // List reservations, search by invalid end time == -1. + request = ReservationListRequest.newInstance( + ReservationSystemTestUtil.reservationQ, "", 1, -1, + true); + + response = null; + try { + response = client.listReservations(request); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + Assert.assertNotNull(response); + Assert.assertEquals(1, response.getReservationAllocationState().size()); + Assert.assertEquals(response.getReservationAllocationState().get(0) + .getReservationId().getId(), reservationID.getId()); + + // List reservations, search by invalid end time < -1. + request = ReservationListRequest.newInstance( + ReservationSystemTestUtil.reservationQ, "", 1, -10, + true); + + response = null; + try { + response = client.listReservations(request); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + Assert.assertNotNull(response); + Assert.assertEquals(1, response.getReservationAllocationState().size()); + Assert.assertEquals(response.getReservationAllocationState().get(0) + .getReservationId().getId(), reservationID.getId()); + + // List reservations, search by time within reservation interval. + request = ReservationListRequest.newInstance( + ReservationSystemTestUtil.reservationQ, "", 1, Long.MAX_VALUE, + true); + + response = null; + try { + response = client.listReservations(request); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + Assert.assertNotNull(response); + Assert.assertEquals(1, response.getReservationAllocationState().size()); + Assert.assertEquals(response.getReservationAllocationState().get(0) + .getReservationId().getId(), reservationID.getId()); + + // Verify that the full resource allocations exist. + Assert.assertTrue(response.getReservationAllocationState().get(0) + .getResourceAllocationRequests().size() > 0); + + // Verify that the full RDL is returned. + ReservationRequests reservationRequests = response + .getReservationAllocationState().get(0) + .getReservationDefinition().getReservationRequests(); + Assert.assertTrue(reservationRequests.getInterpreter().toString() + .equals("R_ALL")); + Assert.assertTrue(reservationRequests.getReservationResources().get(0) + .getDuration() == duration); + + // List reservations, search by very large start time. + request = ReservationListRequest.newInstance( + ReservationSystemTestUtil.reservationQ, "", Long.MAX_VALUE, + -1, false); + + response = null; + try { + response = client.listReservations(request); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + + // List reservations, search by start time after the reservation + // end time. + request = ReservationListRequest.newInstance( + ReservationSystemTestUtil.reservationQ, "", deadline + duration, + deadline + 2 * duration, false); + + response = null; + try { + response = client.listReservations(request); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + + // Ensure all reservations are filtered out. + Assert.assertNotNull(response); + Assert.assertEquals(response.getReservationAllocationState().size(), 0); + + // List reservations, search by end time before the reservation start + // time. + request = ReservationListRequest.newInstance( + ReservationSystemTestUtil.reservationQ, "", 0, arrival - + duration, false); + + response = null; + try { + response = client.listReservations(request); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + + // Ensure all reservations are filtered out. + Assert.assertNotNull(response); + Assert.assertEquals(response.getReservationAllocationState().size(), 0); + + // List reservations, search by very small end time. + request = ReservationListRequest.newInstance( + ReservationSystemTestUtil.reservationQ, "", 0, 1, false); + + response = null; + try { + response = client.listReservations(request); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + + // Ensure all reservations are filtered out. + Assert.assertNotNull(response); + Assert.assertEquals(response.getReservationAllocationState().size(), 0); + // Delete the reservation ReservationDeleteRequest dRequest = ReservationDeleteRequest.newInstance(reservationID); @@ -1244,6 +1403,20 @@ public class TestYarnClient { } Assert.assertNotNull(sResponse); System.out.println("Delete reservation response: " + dResponse); + + // List reservations, search by non-existent reservationID + request = ReservationListRequest.newInstance( + ReservationSystemTestUtil.reservationQ, + reservationID.toString(), -1, -1, false); + + response = null; + try { + response = client.listReservations(request); + } catch (Exception e) { + Assert.fail(e.getMessage()); + } + Assert.assertNotNull(response); + Assert.assertEquals(0, response.getReservationAllocationState().size()); } finally { // clean-up if (client != null) { http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/client/ApplicationClientProtocolPBClientImpl.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/client/ApplicationClientProtocolPBClientImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/client/ApplicationClientProtocolPBClientImpl.java index c1e6e9a..e5aad74 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/client/ApplicationClientProtocolPBClientImpl.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/client/ApplicationClientProtocolPBClientImpl.java @@ -73,6 +73,8 @@ import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenRequest; import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteResponse; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListRequest; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionRequest; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateRequest; @@ -125,6 +127,8 @@ import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.RenewDelegationTokenRe import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.RenewDelegationTokenResponsePBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationDeleteRequestPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationDeleteResponsePBImpl; +import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationListRequestPBImpl; +import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationListResponsePBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationSubmissionRequestPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationSubmissionResponsePBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationUpdateRequestPBImpl; @@ -490,6 +494,19 @@ public class ApplicationClientProtocolPBClientImpl implements ApplicationClientP } } + @Override + public ReservationListResponse listReservations(ReservationListRequest + request) throws YarnException, IOException { + YarnServiceProtos.ReservationListRequestProto requestProto = + ((ReservationListRequestPBImpl) request).getProto(); + try { + return new ReservationListResponsePBImpl(proxy.listReservations(null, + requestProto)); + } catch (ServiceException e) { + RPCUtil.unwrapAndThrowException(e); + return null; + } + } @Override public GetNodesToLabelsResponse getNodeToLabels( http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/service/ApplicationClientProtocolPBServiceImpl.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/service/ApplicationClientProtocolPBServiceImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/service/ApplicationClientProtocolPBServiceImpl.java index 2ee88c8..2c5794e 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/service/ApplicationClientProtocolPBServiceImpl.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/impl/pb/service/ApplicationClientProtocolPBServiceImpl.java @@ -50,6 +50,7 @@ import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationResponse; import org.apache.hadoop.yarn.api.protocolrecords.MoveApplicationAcrossQueuesResponse; import org.apache.hadoop.yarn.api.protocolrecords.RenewDelegationTokenResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationDeleteResponse; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationSubmissionResponse; import org.apache.hadoop.yarn.api.protocolrecords.ReservationUpdateResponse; import org.apache.hadoop.yarn.api.protocolrecords.UpdateApplicationPriorityResponse; @@ -97,10 +98,14 @@ import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.RenewDelegationTokenRe import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.RenewDelegationTokenResponsePBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationDeleteRequestPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationDeleteResponsePBImpl; +import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationListRequestPBImpl; +import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationListResponsePBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationSubmissionRequestPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationSubmissionResponsePBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationUpdateRequestPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.ReservationUpdateResponsePBImpl; +import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.SignalContainerRequestPBImpl; +import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.SignalContainerResponsePBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.UpdateApplicationPriorityRequestPBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.UpdateApplicationPriorityResponsePBImpl; import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.SubmitApplicationRequestPBImpl; @@ -147,11 +152,11 @@ import org.apache.hadoop.yarn.proto.YarnServiceProtos.ReservationSubmissionReque import org.apache.hadoop.yarn.proto.YarnServiceProtos.ReservationSubmissionResponseProto; import org.apache.hadoop.yarn.proto.YarnServiceProtos.ReservationUpdateRequestProto; import org.apache.hadoop.yarn.proto.YarnServiceProtos.ReservationUpdateResponseProto; +import org.apache.hadoop.yarn.proto.YarnServiceProtos.ReservationListRequestProto; +import org.apache.hadoop.yarn.proto.YarnServiceProtos.ReservationListResponseProto; import org.apache.hadoop.yarn.proto.YarnServiceProtos.SignalContainerResponseProto; import org.apache.hadoop.yarn.proto.YarnServiceProtos.UpdateApplicationPriorityRequestProto; import org.apache.hadoop.yarn.proto.YarnServiceProtos.UpdateApplicationPriorityResponseProto; -import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.SignalContainerRequestPBImpl; -import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.SignalContainerResponsePBImpl; import org.apache.hadoop.yarn.proto.YarnServiceProtos.SubmitApplicationRequestProto; import org.apache.hadoop.yarn.proto.YarnServiceProtos.SubmitApplicationResponseProto; @@ -489,6 +494,21 @@ public class ApplicationClientProtocolPBServiceImpl implements ApplicationClient } @Override + public ReservationListResponseProto listReservations(RpcController controller, + ReservationListRequestProto requestProto) throws ServiceException { + ReservationListRequestPBImpl request = + new ReservationListRequestPBImpl(requestProto); + try { + ReservationListResponse response = real.listReservations(request); + return ((ReservationListResponsePBImpl) response).getProto(); + } catch (YarnException e) { + throw new ServiceException(e); + } catch (IOException e) { + throw new ServiceException(e); + } + } + + @Override public GetNodesToLabelsResponseProto getNodeToLabels( RpcController controller, GetNodesToLabelsRequestProto proto) throws ServiceException { http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/ReservationListRequestPBImpl.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/ReservationListRequestPBImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/ReservationListRequestPBImpl.java new file mode 100644 index 0000000..044cff6 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/ReservationListRequestPBImpl.java @@ -0,0 +1,178 @@ +/** + * 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.protocolrecords.impl.pb; + +import com.google.protobuf.TextFormat; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListRequest; +import org.apache.hadoop.yarn.proto.YarnServiceProtos + .ReservationListRequestProto; +import org.apache.hadoop.yarn.proto.YarnServiceProtos + .ReservationListRequestProtoOrBuilder; + +/** + * {@link ReservationListRequestPBImpl} implements the {@link + * ReservationListRequest} abstract class which captures the set of requirements + * the user has to list reservations. + * + * @see ReservationListRequest + */ +public class ReservationListRequestPBImpl extends + ReservationListRequest { + + private ReservationListRequestProto proto = ReservationListRequestProto + .getDefaultInstance(); + private ReservationListRequestProto.Builder builder = null; + private boolean viaProto = false; + + public ReservationListRequestPBImpl() { + builder = ReservationListRequestProto.newBuilder(); + } + + public ReservationListRequestPBImpl( + ReservationListRequestProto proto) { + this.proto = proto; + viaProto = true; + } + + public ReservationListRequestProto getProto() { + proto = viaProto ? proto : builder.build(); + viaProto = true; + return proto; + } + + @Override + public String getQueue() { + ReservationListRequestProtoOrBuilder p = viaProto ? proto : builder; + if (!p.hasQueue()) { + return null; + } + return (p.getQueue()); + } + + @Override + public void setQueue(String queue) { + maybeInitBuilder(); + if (queue == null) { + builder.clearQueue(); + return; + } + builder.setQueue(queue); + } + + @Override + public String getReservationId() { + ReservationListRequestProtoOrBuilder p = viaProto ? proto : builder; + if (!p.hasReservationId()) { + return null; + } + return (p.getReservationId()); + } + + @Override + public void setReservationId(String reservationId) { + maybeInitBuilder(); + if (reservationId == null) { + builder.clearReservationId(); + return; + } + builder.setReservationId(reservationId); + } + + @Override + public long getStartTime() { + ReservationListRequestProtoOrBuilder p = viaProto ? proto : builder; + if (!p.hasStartTime()) { + return 0; + } + return (p.getStartTime()); + } + + @Override + public void setStartTime(long startTime) { + maybeInitBuilder(); + if (startTime <= 0) { + builder.clearStartTime(); + return; + } + builder.setStartTime(startTime); + } + + @Override + public long getEndTime() { + ReservationListRequestProtoOrBuilder p = viaProto ? proto : builder; + if (!p.hasEndTime()) { + return Long.MAX_VALUE; + } + return (p.getEndTime()); + } + + @Override + public void setEndTime(long endTime) { + maybeInitBuilder(); + if (endTime < 0) { + builder.setEndTime(Long.MAX_VALUE); + return; + } + builder.setEndTime(endTime); + } + + @Override + public boolean getIncludeResourceAllocations() { + ReservationListRequestProtoOrBuilder p = viaProto ? proto : builder; + if (!p.hasIncludeResourceAllocations()) { + return false; + } + return (p.getIncludeResourceAllocations()); + } + + @Override + public void setIncludeResourceAllocations(boolean + includeReservationAllocations) { + maybeInitBuilder(); + builder.setIncludeResourceAllocations(includeReservationAllocations); + } + + private void maybeInitBuilder() { + if (viaProto || builder == null) { + builder = ReservationListRequestProto.newBuilder(proto); + } + viaProto = false; + } + + @Override + public String toString() { + return TextFormat.shortDebugString(getProto()); + } + + @Override + public boolean equals(Object other) { + if (other == null) { + return false; + } + if (other.getClass().isAssignableFrom(this.getClass())) { + return this.getProto().equals(this.getClass().cast(other).getProto()); + } + return false; + } + + @Override + public int hashCode() { + return getProto().hashCode(); + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/ReservationListResponsePBImpl.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/ReservationListResponsePBImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/ReservationListResponsePBImpl.java new file mode 100644 index 0000000..7bc43cd --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl/pb/ReservationListResponsePBImpl.java @@ -0,0 +1,157 @@ +/** + * 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.protocolrecords.impl.pb; + +import com.google.protobuf.TextFormat; +import org.apache.hadoop.yarn.api.protocolrecords.ReservationListResponse; +import org.apache.hadoop.yarn.api.records.ReservationAllocationState; +import org.apache.hadoop.yarn.api.records.impl.pb.ReservationAllocationStatePBImpl; +import org.apache.hadoop.yarn.proto.YarnProtos.ReservationAllocationStateProto; +import org.apache.hadoop.yarn.proto.YarnServiceProtos.ReservationListResponseProto; +import org.apache.hadoop.yarn.proto.YarnServiceProtos.ReservationListResponseProtoOrBuilder; + +import java.util.ArrayList; +import java.util.List; + +/** + * {@link ReservationListResponsePBImpl} is the implementation of the + * {@link ReservationListResponse} which captures the list of reservations + * that the user has queried. + */ +public class ReservationListResponsePBImpl extends + ReservationListResponse { + + private ReservationListResponseProto proto = ReservationListResponseProto + .getDefaultInstance(); + private ReservationListResponseProto.Builder builder = null; + private boolean viaProto = false; + + private List<ReservationAllocationState> reservations; + + public ReservationListResponsePBImpl() { + builder = ReservationListResponseProto.newBuilder(); + } + + public ReservationListResponsePBImpl( + ReservationListResponseProto proto) { + this.proto = proto; + viaProto = true; + } + + public ReservationListResponseProto getProto() { + if (viaProto) { + mergeLocalToProto(); + } else { + proto = builder.build(); + } + viaProto = true; + return proto; + } + + private void maybeInitBuilder() { + if (viaProto || builder == null) { + builder = ReservationListResponseProto.newBuilder(proto); + } + viaProto = false; + } + + @Override + public List<ReservationAllocationState> getReservationAllocationState() { + initReservations(); + mergeLocalToProto(); + return this.reservations; + } + + @Override + public void setReservationAllocationState(List<ReservationAllocationState> + newReservations) { + if (newReservations == null) { + builder.clearReservations(); + return; + } + reservations = newReservations; + mergeLocalToProto(); + } + + private void mergeLocalToBuilder() { + if (this.reservations != null) { + int size = reservations.size(); + builder.clearReservations(); + for (int i = 0; i < size; i++) { + builder.addReservations(i, convertToProtoFormat( + reservations.get(i) + )); + } + } + } + + private void mergeLocalToProto() { + if (viaProto) { + maybeInitBuilder(); + } + mergeLocalToBuilder(); + proto = builder.build(); + viaProto = true; + } + + private ReservationAllocationStatePBImpl convertFromProtoFormat( + ReservationAllocationStateProto p) { + return new ReservationAllocationStatePBImpl(p); + } + + private ReservationAllocationStateProto convertToProtoFormat( + ReservationAllocationState r) { + return ((ReservationAllocationStatePBImpl)r).getProto(); + } + + private void initReservations() { + if (this.reservations != null) { + return; + } + ReservationListResponseProtoOrBuilder p = viaProto ? proto : builder; + List<ReservationAllocationStateProto> reservationProtos = + p.getReservationsList(); + reservations = new ArrayList<>(); + + for (ReservationAllocationStateProto r : reservationProtos) { + reservations.add(convertFromProtoFormat(r)); + } + } + + @Override + public String toString() { + return TextFormat.shortDebugString(getProto()); + } + + @Override + public boolean equals(Object other) { + if (other == null) { + return false; + } + if (other.getClass().isAssignableFrom(this.getClass())) { + return this.getProto().equals(this.getClass().cast(other).getProto()); + } + return false; + } + + @Override + public int hashCode() { + return getProto().hashCode(); + } +} http://git-wip-us.apache.org/repos/asf/hadoop/blob/c487453b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ReservationAllocationStatePBImpl.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ReservationAllocationStatePBImpl.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ReservationAllocationStatePBImpl.java new file mode 100644 index 0000000..88e39ec --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/api/records/impl/pb/ReservationAllocationStatePBImpl.java @@ -0,0 +1,288 @@ +/** + * 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.apache.hadoop.classification.InterfaceAudience.Private; +import org.apache.hadoop.classification.InterfaceStability.Unstable; +import org.apache.hadoop.yarn.api.records.*; +import org.apache.hadoop.yarn.proto.YarnProtos.ReservationAllocationStateProto; +import org.apache.hadoop.yarn.proto.YarnProtos.ReservationAllocationStateProtoOrBuilder; +import org.apache.hadoop.yarn.proto.YarnProtos.ReservationIdProto; +import org.apache.hadoop.yarn.proto.YarnProtos.ReservationDefinitionProto; +import org.apache.hadoop.yarn.proto.YarnProtos.ResourceAllocationRequestProto; + +import java.util.ArrayList; +import java.util.List; + +/** + * {@code ReservationAllocationStatePBImpl} implements the {@link + * ReservationAllocationState} that represents the reservation that is + * made by a user. + * + * <p> + * It includes: + * <ul> + * <li>Duration of the reservation.</li> + * <li>Acceptance time of the duration.</li> + * <li> + * List of {@link ResourceAllocationRequest}, which includes the time + * interval, and capability of the allocation. + * {@code ResourceAllocationRequest} represents an allocation + * made for a reservation for the current state of the plan. This can be + * changed for reasons such as re-planning, but will always be subject to + * the constraints of the user contract as described by + * {@link ReservationDefinition} + * </li> + * <li>{@link ReservationId} of the reservation.</li> + * <li>{@link ReservationDefinition} used to make the reservation.</li> + * </ul> + * + * @see ResourceAllocationRequest + * @see ReservationId + * @see ReservationDefinition + */ +@Private +@Unstable +public class ReservationAllocationStatePBImpl extends + ReservationAllocationState { + private ReservationAllocationStateProto proto = + ReservationAllocationStateProto.getDefaultInstance();; + private ReservationAllocationStateProto.Builder builder = null; + private boolean viaProto = false; + + private List<ResourceAllocationRequest> resourceAllocations = null; + private ReservationId reservationId = null; + private ReservationDefinition reservationDefinition = null; + + public ReservationAllocationStatePBImpl() { + builder = ReservationAllocationStateProto.newBuilder(); + } + + public ReservationAllocationStatePBImpl( + ReservationAllocationStateProto proto) { + this.proto = proto; + viaProto = true; + } + + public ReservationAllocationStateProto getProto() { + mergeLocalToProto(); + proto = viaProto ? proto : builder.build(); + viaProto = true; + return proto; + } + + private void maybeInitBuilder() { + if (viaProto || builder == null) { + builder = ReservationAllocationStateProto.newBuilder(proto); + } + viaProto = false; + } + + private void mergeLocalToBuilder() { + if (this.resourceAllocations != null) { + int size = resourceAllocations.size(); + builder.clearAllocationRequests(); + for (int i = 0; i < size; i++) { + builder.addAllocationRequests(i, convertToProtoFormat( + resourceAllocations.get(i) + )); + } + } + + if (this.reservationId != null) { + builder.setReservationId(convertToProtoFormat(this.reservationId)); + } + + if (this.reservationDefinition != null) { + builder.setReservationDefinition(convertToProtoFormat(this + .reservationDefinition)); + } + } + + private void mergeLocalToProto() { + if (viaProto) { + maybeInitBuilder(); + } + mergeLocalToBuilder(); + proto = builder.build(); + viaProto = true; + } + + @Override + public long getAcceptanceTime() { + ReservationAllocationStateProtoOrBuilder p = viaProto ? proto : builder; + if (!p.hasAcceptanceTime()) { + return 0; + } + return (p.getAcceptanceTime()); + } + + @Override + public void setAcceptanceTime(long acceptanceTime) { + maybeInitBuilder(); + if (acceptanceTime <= 0) { + builder.clearAcceptanceTime(); + return; + } + builder.setAcceptanceTime(acceptanceTime); + } + + @Override + public String getUser() { + ReservationAllocationStateProtoOrBuilder p = viaProto ? proto : builder; + if (!p.hasUser()) { + return null; + } + return p.getUser(); + } + + @Override + public void setUser(String user) { + maybeInitBuilder(); + if (user == null) { + builder.clearUser(); + return; + } + builder.setUser(user); + } + + @Override + public List<ResourceAllocationRequest> + getResourceAllocationRequests() { + initResourceAllocations(); + return this.resourceAllocations; + } + + @Override + public void setResourceAllocationRequests( + List<ResourceAllocationRequest> newResourceAllocations) { + maybeInitBuilder(); + if (newResourceAllocations == null) { + builder.clearAllocationRequests(); + } + this.resourceAllocations = newResourceAllocations; + } + + @Override + public ReservationId getReservationId() { + ReservationAllocationStateProtoOrBuilder p = viaProto ? proto : builder; + if (this.reservationId != null) { + return this.reservationId; + } + this.reservationId = convertFromProtoFormat(p.getReservationId()); + return this.reservationId; + } + + @Override + public void setReservationId(ReservationId newReservationId) { + maybeInitBuilder(); + if (newReservationId == null) { + builder.clearReservationId(); + } + reservationId = newReservationId; + } + + @Override + public ReservationDefinition getReservationDefinition() { + ReservationAllocationStateProtoOrBuilder p = viaProto ? proto : builder; + if (this.reservationDefinition != null) { + return this.reservationDefinition; + } + this.reservationDefinition = convertFromProtoFormat( + p.getReservationDefinition()); + return this.reservationDefinition; + } + + @Override + public void setReservationDefinition(ReservationDefinition + newReservationDefinition) { + maybeInitBuilder(); + if (newReservationDefinition == null) { + builder.clearReservationDefinition(); + } + reservationDefinition = newReservationDefinition; + } + + private ResourceAllocationRequestPBImpl convertFromProtoFormat( + ResourceAllocationRequestProto p) { + return new ResourceAllocationRequestPBImpl(p); + } + + private ReservationIdPBImpl convertFromProtoFormat(ReservationIdProto p) { + return new ReservationIdPBImpl(p); + } + + private ReservationDefinitionPBImpl convertFromProtoFormat( + ReservationDefinitionProto p) { + return new ReservationDefinitionPBImpl(p); + } + + private ResourceAllocationRequestProto convertToProtoFormat( + ResourceAllocationRequest p) { + return ((ResourceAllocationRequestPBImpl)p).getProto(); + } + + private ReservationIdProto convertToProtoFormat(ReservationId p) { + return ((ReservationIdPBImpl)p).getProto(); + } + + private ReservationDefinitionProto convertToProtoFormat( + ReservationDefinition p) { + return ((ReservationDefinitionPBImpl)p).getProto(); + } + + private void initResourceAllocations() { + if (this.resourceAllocations != null) { + return; + } + ReservationAllocationStateProtoOrBuilder p = viaProto ? proto : builder; + List<ResourceAllocationRequestProto> resourceAllocationProtos = + p.getAllocationRequestsList(); + resourceAllocations = new ArrayList<>(); + + for (ResourceAllocationRequestProto r : resourceAllocationProtos) { + resourceAllocations.add(convertFromProtoFormat(r)); + } + } + + @Override + public String toString() { + return "{Acceptance Time: " + + getAcceptanceTime() + ", User: " + getUser() + + ", Resource Allocations: " + getResourceAllocationRequests() + + ", Reservation Id: " + getReservationId() + + ", Reservation Definition: " + getReservationDefinition() + "}"; + } + + @Override + public boolean equals(Object other) { + if (other == null) { + return false; + } + if (other.getClass().isAssignableFrom(this.getClass())) { + return this.getProto().equals(this.getClass().cast(other).getProto()); + } + return false; + } + + @Override + public int hashCode() { + return getProto().hashCode(); + } +} \ No newline at end of file
