This is an automated email from the ASF dual-hosted git repository.

bennoe pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit b368d897d83df2f261e01fa7583798d80d098052
Author: Benno Evers <[email protected]>
AuthorDate: Fri Nov 8 14:06:16 2019 +0100

    Updated 'Master::Http::_reserve' to pass along new 'source' field.
    
    Updated 'Master::Http::_reserve()' to correctly set the new `source`
    field in the `Offer::Operation` created from operator API input.
    
    Review: https://reviews.apache.org/r/71695/
---
 src/master/http.cpp   | 84 ++++++++++++++++++++++++++++++++-------------------
 src/master/master.hpp |  1 +
 2 files changed, 54 insertions(+), 31 deletions(-)

diff --git a/src/master/http.cpp b/src/master/http.cpp
index 9efe4a3..1778664 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -1914,11 +1914,45 @@ Future<Response> Master::Http::reserve(
     return BadRequest("Unable to decode query string: " + decode.error());
   }
 
-  const hashmap<string, string>& values = decode.get();
+  // Helper function to parse a list of resource from query parameters.
+  auto parseResourcesList = [](
+      const std::string& key,
+      const hashmap<string, string>& queryParameters)
+    -> Try<RepeatedPtrField<Resource>>
+    {
+      Option<string> value = queryParameters.get(key);
+      if (value.isNone()) {
+        return Error(
+          "Missing '" + key + "' query parameter in the request body");
+      }
 
-  Option<string> value;
+      Try<JSON::Array> parse =
+        JSON::parse<JSON::Array>(value.get());
 
-  value = values.get("slaveId");
+      if (parse.isError()) {
+        return Error(
+            "Error parsing '" + key +
+            "' query parameter in the request body: " + parse.error());
+      }
+
+      RepeatedPtrField<Resource> resources;
+      foreach (const JSON::Value& value, parse->values) {
+        Try<Resource> resource = ::protobuf::parse<Resource>(value);
+        if (resource.isError()) {
+          return Error(
+              "Error parsing '" + key +
+              "' query parameter in the request body: " + resource.error());
+        }
+
+        resources.Add()->CopyFrom(resource.get());
+      }
+
+      return resources;
+    };
+
+  const hashmap<string, string>& values = decode.get();
+
+  Option<string> value = values.get("slaveId");
   if (value.isNone()) {
     return BadRequest("Missing 'slaveId' query parameter in the request body");
   }
@@ -1926,39 +1960,32 @@ Future<Response> Master::Http::reserve(
   SlaveID slaveId;
   slaveId.set_value(value.get());
 
-  value = values.get("resources");
-  if (value.isNone()) {
-    return BadRequest(
-        "Missing 'resources' query parameter in the request body");
-  }
-
-  Try<JSON::Array> parse =
-    JSON::parse<JSON::Array>(value.get());
+  Try<RepeatedPtrField<Resource>> resources =
+    parseResourcesList("resources", values);
 
-  if (parse.isError()) {
-    return BadRequest(
-        "Error in parsing 'resources' query parameter in the request body: " +
-        parse.error());
+  if (resources.isError()) {
+    return BadRequest(resources.error());
   }
 
-  RepeatedPtrField<Resource> resources;
-  foreach (const JSON::Value& value, parse->values) {
-    Try<Resource> resource = ::protobuf::parse<Resource>(value);
-    if (resource.isError()) {
-      return BadRequest(
-          "Error in parsing 'resources' query parameter in the request body: " 
+
-          resource.error());
+  RepeatedPtrField<Resource> source;
+  if (values.contains("source")) {
+    Try<RepeatedPtrField<Resource>> parsedSource =
+      parseResourcesList("source", values);
+
+    if (parsedSource.isError()) {
+      return BadRequest(parsedSource.error());
     }
 
-    resources.Add()->CopyFrom(resource.get());
+    source = parsedSource.get();
   }
 
-  return _reserve(slaveId, resources, principal);
+  return _reserve(slaveId, source, resources.get(), principal);
 }
 
 
 Future<Response> Master::Http::_reserve(
     const SlaveID& slaveId,
+    const RepeatedPtrField<Resource>& source,
     const RepeatedPtrField<Resource>& resources,
     const Option<Principal>& principal) const
 {
@@ -1970,6 +1997,7 @@ Future<Response> Master::Http::_reserve(
   // Create an operation.
   Offer::Operation operation;
   operation.set_type(Offer::Operation::RESERVE);
+  operation.mutable_reserve()->mutable_source()->CopyFrom(source);
   operation.mutable_reserve()->mutable_resources()->CopyFrom(resources);
 
   Option<Error> error = validateAndUpgradeResources(&operation);
@@ -2009,13 +2037,7 @@ Future<Response> Master::Http::reserveResources(
   const RepeatedPtrField<Resource>& resources =
     call.reserve_resources().resources();
 
-  // Reject all `Reserve` operations whenever `source` is set
-  // until we have a proper implementation in place.
-  if (!source.empty()) {
-    return BadRequest("Reservation updates not yet supported.");
-  }
-
-  return _reserve(slaveId, resources, principal);
+  return _reserve(slaveId, source, resources, principal);
 }
 
 
diff --git a/src/master/master.hpp b/src/master/master.hpp
index d2392d7..8a14065 100644
--- a/src/master/master.hpp
+++ b/src/master/master.hpp
@@ -1728,6 +1728,7 @@ private:
 
     process::Future<process::http::Response> _reserve(
         const SlaveID& slaveId,
+        const google::protobuf::RepeatedPtrField<Resource>& source,
         const google::protobuf::RepeatedPtrField<Resource>& resources,
         const Option<process::http::authentication::Principal>&
             principal) const;

Reply via email to