From 5c8e60d77121b8d614ef6f4d3f37104fdd87e867 Mon Sep 17 00:00:00 2001 From: Lawrence Wong Date: Fri, 3 Jun 2022 11:30:59 -0700 Subject: [PATCH 1/4] Fix duplicate host issue for aurora scheduler, DTCPIOPS-5221 --- .../scheduler/offers/HttpOfferSetImpl.java | 39 +++++---- .../offers/HttpOfferSetImplTest.java | 83 +++++++++++++++++++ 2 files changed, 102 insertions(+), 20 deletions(-) diff --git a/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java b/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java index d8f741a18..b02df775d 100644 --- a/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java +++ b/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java @@ -18,13 +18,7 @@ import java.lang.annotation.Target; import java.net.MalformedURLException; import java.net.URL; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentSkipListSet; import java.util.stream.Collectors; @@ -331,30 +325,35 @@ List processResponse(List mOffers, String responseStr) LOG.info("Received {} offers", response.hosts.size()); Map offerMap = mOffers.stream() - .collect(Collectors.toMap(offer -> offer.getAttributes().getHost(), offer -> offer)); + .collect(Collectors. + toMap(offer -> offer.getOffer().getId().getValue(), offer -> offer)); + if (!response.error.trim().isEmpty()) { LOG.error("Unable to receive offers from {} due to {}", endpoint, response.error); throw new IOException(response.error); } - - List orderedOffers = response.hosts.stream() - .map(host -> offerMap.get(host)) - .filter(offer -> offer != null) - .collect(Collectors.toList()); - List extraOffers = response.hosts.stream() - .filter(host -> offerMap.get(host) == null) + List offerIDList = offerMap.keySet().stream() + .filter(offerId -> offerMap.get(offerId) != null && response.hosts + .contains(offerMap.get(offerId).getOffer().getHostname())) + .collect(Collectors.toList()); + List orderedOffers = offerIDList.stream() + .map(offerId -> offerMap.get(offerId)) .collect(Collectors.toList()); - //offSetDiff is the total number of missing offers and the extra offers - long offSetDiff = mOffers.size() - (response.hosts.size() - extraOffers.size()) - + extraOffers.size(); + List mHosts = mOffers.stream().map(offer -> offer.getOffer().getHostname()) + .collect(Collectors.toList()); + List extraOffers = response.hosts.stream().filter(host -> !mHosts.contains(host)) + .collect(Collectors.toList()); + + //offSetDiff is the absolute value of the different between Aurora offers and response offers + long offSetDiff = mOffers.size() - offerIDList.size() + extraOffers.size(); + offSetDiff = Math.abs(offSetDiff); offerSetDiffList.add(offSetDiff); if (offSetDiff > 0) { LOG.warn("The number of different offers between the original and received offer sets is {}", offSetDiff); if (LOG.isDebugEnabled()) { - List missedOffers = mOffers.stream() - .map(offer -> offer.getAttributes().getHost()) + List missedOffers = mHosts.stream() .filter(host -> !response.hosts.contains(host)) .collect(Collectors.toList()); LOG.debug("missed offers: {}", missedOffers); diff --git a/src/test/java/io/github/aurora/scheduler/offers/HttpOfferSetImplTest.java b/src/test/java/io/github/aurora/scheduler/offers/HttpOfferSetImplTest.java index 3007924e5..cb13d03a3 100644 --- a/src/test/java/io/github/aurora/scheduler/offers/HttpOfferSetImplTest.java +++ b/src/test/java/io/github/aurora/scheduler/offers/HttpOfferSetImplTest.java @@ -64,12 +64,16 @@ public class HttpOfferSetImplTest extends EasyMockTest { private static final HostOffer OFFER_C = new HostOffer( Offers.makeOffer("OFFER_C", HOST_C), IHostAttributes.build(new HostAttributes().setMode(NONE).setHost(HOST_C))); + private static final HostOffer OFFER_C1 = new HostOffer( + Offers.makeOffer("OFFER_C1", HOST_C), + IHostAttributes.build(new HostAttributes().setMode(NONE).setHost(HOST_C))); private static final String HOST_D = "HOST_D"; private final Storage storage = MemStorageModule.newEmptyStorage(); private HttpOfferSetImpl httpOfferSet; private Set offers; + private HttpOfferSetImpl duplicateHostsHttpOfferSet; @Before public void setUp() throws IOException { @@ -112,6 +116,20 @@ public void setUp() throws IOException { 0, 0, false); + + // duplicate host offers + Set duplicateHostOffers = new HashSet<>(); + duplicateHostOffers.add(OFFER_A); + duplicateHostOffers.add(OFFER_B); + duplicateHostOffers.add(OFFER_C); + duplicateHostOffers.add(OFFER_C1); + + duplicateHostsHttpOfferSet = new HttpOfferSetImpl(duplicateHostOffers, + 0, + new URL("http://localhost:9090/v1/offerset"), + 0, + 0, + false); } @Test @@ -194,6 +212,71 @@ public void testProcessResponse() throws IOException { isException = true; } assertTrue(isException); + + // Duplicate host test + responseStr = "{\"error\": \"\", \"hosts\": [\"" + + HOST_A + "\",\"" + + HOST_B + "\",\"" + + HOST_C + "\"]}"; + + List mDuplicateHostOffers = ImmutableList. + copyOf(duplicateHostsHttpOfferSet.values()); + assertEquals(mDuplicateHostOffers.size(), 4); + + sortedOffers = duplicateHostsHttpOfferSet.processResponse(mDuplicateHostOffers, + responseStr); + assertEquals(sortedOffers.size(), 4); + assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); + assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_B); + assertEquals(sortedOffers.get(2).getAttributes().getHost(), HOST_C); + assertEquals(sortedOffers.get(3).getAttributes().getHost(), HOST_C); + assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(4), 0); + + // plugin returns less offers than Aurora has. + responseStr = "{\"error\": \"\", \"hosts\": [\"" + + HOST_A + "\",\"" + + HOST_C + "\"]}"; + sortedOffers = duplicateHostsHttpOfferSet.processResponse(mDuplicateHostOffers, responseStr); + assertEquals(sortedOffers.size(), 3); + assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); + assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_C); + assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(5), 1); + + // plugin returns more offers than Aurora has. + responseStr = "{\"error\": \"\", \"hosts\": [\"" + + HOST_A + "\",\"" + + HOST_B + "\",\"" + + HOST_D + "\",\"" + + HOST_C + "\"]}"; + sortedOffers = duplicateHostsHttpOfferSet.processResponse(mDuplicateHostOffers, responseStr); + assertEquals(sortedOffers.size(), 4); + assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); + assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_B); + assertEquals(sortedOffers.get(2).getAttributes().getHost(), HOST_C); + assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(6), 1); + + // plugin omits 1 offer & returns 1 extra offer + responseStr = "{\"error\": \"\", \"hosts\": [\"" + + HOST_A + "\",\"" + + HOST_D + "\",\"" + + HOST_B + "\"]}"; + sortedOffers = duplicateHostsHttpOfferSet.processResponse(mDuplicateHostOffers, responseStr); + assertEquals(sortedOffers.size(), 2); + assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); + assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_B); + assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(7), 3); + + responseStr = "{\"error\": \"Error\", \"hosts\": [\"" + + HOST_A + "\",\"" + + HOST_B + "\",\"" + + HOST_C + "\"]}"; + isException = false; + try { + duplicateHostsHttpOfferSet.processResponse(mOffers, responseStr); + } catch (IOException ioe) { + isException = true; + } + assertTrue(isException); } @Test From 1d31e94fd889310eb0d0d425923865cbde46670d Mon Sep 17 00:00:00 2001 From: Lawrence Wong Date: Mon, 6 Jun 2022 15:06:01 -0700 Subject: [PATCH 2/4] Address Tan code review comment --- .../scheduler/offers/HttpOfferSetImpl.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java b/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java index b02df775d..737109822 100644 --- a/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java +++ b/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java @@ -18,7 +18,13 @@ import java.lang.annotation.Target; import java.net.MalformedURLException; import java.net.URL; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.concurrent.ConcurrentSkipListSet; import java.util.stream.Collectors; @@ -332,22 +338,17 @@ List processResponse(List mOffers, String responseStr) LOG.error("Unable to receive offers from {} due to {}", endpoint, response.error); throw new IOException(response.error); } - List offerIDList = offerMap.keySet().stream() - .filter(offerId -> offerMap.get(offerId) != null && response.hosts - .contains(offerMap.get(offerId).getOffer().getHostname())) + List orderedOffers = offerMap.values().stream().filter(offer -> response.hosts. + contains(offer.getOffer().getHostname())) .collect(Collectors.toList()); - List orderedOffers = offerIDList.stream() - .map(offerId -> offerMap.get(offerId)) - .collect(Collectors.toList()); List mHosts = mOffers.stream().map(offer -> offer.getOffer().getHostname()) .collect(Collectors.toList()); List extraOffers = response.hosts.stream().filter(host -> !mHosts.contains(host)) .collect(Collectors.toList()); - //offSetDiff is the absolute value of the different between Aurora offers and response offers - long offSetDiff = mOffers.size() - offerIDList.size() + extraOffers.size(); - offSetDiff = Math.abs(offSetDiff); + //offSetDiff is the value of the different between Aurora offers and response offers + long offSetDiff = mOffers.size() - orderedOffers.size() + extraOffers.size(); offerSetDiffList.add(offSetDiff); if (offSetDiff > 0) { LOG.warn("The number of different offers between the original and received offer sets is {}", From 0048bd1e6e4a6ab19da00bfecc8c469825d799a5 Mon Sep 17 00:00:00 2001 From: Lawrence Wong Date: Mon, 6 Jun 2022 15:47:59 -0700 Subject: [PATCH 3/4] Address code review comment for #401 story --- .../scheduler/offers/HttpOfferSetImpl.java | 8 ++-- .../offers/HttpOfferSetImplTest.java | 46 ++++++++++++------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java b/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java index 737109822..50bc5d71d 100644 --- a/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java +++ b/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java @@ -262,8 +262,8 @@ public Iterable getOrdered(TaskGroupKey groupKey, ResourceRequest res ScheduleRequest scheduleRequest = createRequest(goodOffers, resourceRequest, startTime); LOG.info("Sending request {}", scheduleRequest.jobKey); String responseStr = sendRequest(scheduleRequest); - orderedOffers = processResponse(goodOffers, responseStr); - } catch (IOException e) { + orderedOffers = processResponse(goodOffers, responseStr, badOffers.size()); + } catch (Exception e) { LOG.error("Failed to schedule the task of {} using {} ", resourceRequest.getTask().getJob().toString(), endpoint, e); HttpOfferSetImpl.incrementFailureCount(); @@ -325,7 +325,7 @@ private String sendRequest(ScheduleRequest scheduleRequest) throws IOException { } } - List processResponse(List mOffers, String responseStr) + List processResponse(List mOffers, String responseStr, int badOfferSize) throws IOException { ScheduleResponse response = jsonMapper.readValue(responseStr, ScheduleResponse.class); LOG.info("Received {} offers", response.hosts.size()); @@ -348,7 +348,7 @@ List processResponse(List mOffers, String responseStr) .collect(Collectors.toList()); //offSetDiff is the value of the different between Aurora offers and response offers - long offSetDiff = mOffers.size() - orderedOffers.size() + extraOffers.size(); + long offSetDiff = mOffers.size() + badOfferSize - orderedOffers.size() + extraOffers.size(); offerSetDiffList.add(offSetDiff); if (offSetDiff > 0) { LOG.warn("The number of different offers between the original and received offer sets is {}", diff --git a/src/test/java/io/github/aurora/scheduler/offers/HttpOfferSetImplTest.java b/src/test/java/io/github/aurora/scheduler/offers/HttpOfferSetImplTest.java index cb13d03a3..6900e9b57 100644 --- a/src/test/java/io/github/aurora/scheduler/offers/HttpOfferSetImplTest.java +++ b/src/test/java/io/github/aurora/scheduler/offers/HttpOfferSetImplTest.java @@ -142,7 +142,7 @@ public void testProcessResponse() throws IOException { List mOffers = ImmutableList.copyOf(httpOfferSet.values()); - List sortedOffers = httpOfferSet.processResponse(mOffers, responseStr); + List sortedOffers = httpOfferSet.processResponse(mOffers, responseStr, 0); assertEquals(sortedOffers.size(), 3); assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_B); @@ -153,7 +153,7 @@ public void testProcessResponse() throws IOException { responseStr = "{\"error\": \"\", \"hosts\": [\"" + HOST_A + "\",\"" + HOST_C + "\"]}"; - sortedOffers = httpOfferSet.processResponse(mOffers, responseStr); + sortedOffers = httpOfferSet.processResponse(mOffers, responseStr, 0); assertEquals(sortedOffers.size(), 2); assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_C); @@ -165,7 +165,7 @@ public void testProcessResponse() throws IOException { + HOST_B + "\",\"" + HOST_D + "\",\"" + HOST_C + "\"]}"; - sortedOffers = httpOfferSet.processResponse(mOffers, responseStr); + sortedOffers = httpOfferSet.processResponse(mOffers, responseStr, 0); assertEquals(sortedOffers.size(), 3); assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_B); @@ -177,19 +177,26 @@ public void testProcessResponse() throws IOException { + HOST_A + "\",\"" + HOST_D + "\",\"" + HOST_C + "\"]}"; - sortedOffers = httpOfferSet.processResponse(mOffers, responseStr); + sortedOffers = httpOfferSet.processResponse(mOffers, responseStr, 0); assertEquals(sortedOffers.size(), 2); assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_C); assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(3), 2); + // Test with 1 bad offer + sortedOffers = httpOfferSet.processResponse(mOffers, responseStr, 1); + assertEquals(sortedOffers.size(), 2); + assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); + assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_C); + assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(4), 3); + responseStr = "{\"error\": \"Error\", \"hosts\": [\"" + HOST_A + "\",\"" + HOST_B + "\",\"" + HOST_C + "\"]}"; boolean isException = false; try { - httpOfferSet.processResponse(mOffers, responseStr); + httpOfferSet.processResponse(mOffers, responseStr, 0); } catch (IOException ioe) { isException = true; } @@ -198,7 +205,7 @@ public void testProcessResponse() throws IOException { responseStr = "{\"error\": \"error\"}"; isException = false; try { - httpOfferSet.processResponse(mOffers, responseStr); + httpOfferSet.processResponse(mOffers, responseStr, 0); } catch (IOException ioe) { isException = true; } @@ -207,7 +214,7 @@ public void testProcessResponse() throws IOException { responseStr = "{\"weird\": \"cannot decode this json string\"}"; isException = false; try { - httpOfferSet.processResponse(mOffers, responseStr); + httpOfferSet.processResponse(mOffers, responseStr, 0); } catch (IOException ioe) { isException = true; } @@ -224,23 +231,23 @@ public void testProcessResponse() throws IOException { assertEquals(mDuplicateHostOffers.size(), 4); sortedOffers = duplicateHostsHttpOfferSet.processResponse(mDuplicateHostOffers, - responseStr); + responseStr, 0); assertEquals(sortedOffers.size(), 4); assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_B); assertEquals(sortedOffers.get(2).getAttributes().getHost(), HOST_C); assertEquals(sortedOffers.get(3).getAttributes().getHost(), HOST_C); - assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(4), 0); + assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(5), 0); // plugin returns less offers than Aurora has. responseStr = "{\"error\": \"\", \"hosts\": [\"" + HOST_A + "\",\"" + HOST_C + "\"]}"; - sortedOffers = duplicateHostsHttpOfferSet.processResponse(mDuplicateHostOffers, responseStr); + sortedOffers = duplicateHostsHttpOfferSet.processResponse(mDuplicateHostOffers, responseStr, 0); assertEquals(sortedOffers.size(), 3); assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_C); - assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(5), 1); + assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(6), 1); // plugin returns more offers than Aurora has. responseStr = "{\"error\": \"\", \"hosts\": [\"" @@ -248,23 +255,30 @@ public void testProcessResponse() throws IOException { + HOST_B + "\",\"" + HOST_D + "\",\"" + HOST_C + "\"]}"; - sortedOffers = duplicateHostsHttpOfferSet.processResponse(mDuplicateHostOffers, responseStr); + sortedOffers = duplicateHostsHttpOfferSet.processResponse(mDuplicateHostOffers, responseStr, 0); assertEquals(sortedOffers.size(), 4); assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_B); assertEquals(sortedOffers.get(2).getAttributes().getHost(), HOST_C); - assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(6), 1); + assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(7), 1); // plugin omits 1 offer & returns 1 extra offer responseStr = "{\"error\": \"\", \"hosts\": [\"" + HOST_A + "\",\"" + HOST_D + "\",\"" + HOST_B + "\"]}"; - sortedOffers = duplicateHostsHttpOfferSet.processResponse(mDuplicateHostOffers, responseStr); + sortedOffers = duplicateHostsHttpOfferSet.processResponse(mDuplicateHostOffers, responseStr, 0); + assertEquals(sortedOffers.size(), 2); + assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); + assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_B); + assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(8), 3); + + // Test with 1 bad offer + sortedOffers = duplicateHostsHttpOfferSet.processResponse(mDuplicateHostOffers, responseStr, 1); assertEquals(sortedOffers.size(), 2); assertEquals(sortedOffers.get(0).getAttributes().getHost(), HOST_A); assertEquals(sortedOffers.get(1).getAttributes().getHost(), HOST_B); - assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(7), 3); + assertEquals((long) HttpOfferSetImpl.offerSetDiffList.get(9), 4); responseStr = "{\"error\": \"Error\", \"hosts\": [\"" + HOST_A + "\",\"" @@ -272,7 +286,7 @@ public void testProcessResponse() throws IOException { + HOST_C + "\"]}"; isException = false; try { - duplicateHostsHttpOfferSet.processResponse(mOffers, responseStr); + duplicateHostsHttpOfferSet.processResponse(mOffers, responseStr, 0); } catch (IOException ioe) { isException = true; } From 659adbe97ebb4323e78fb61f6f4c12721f7bfe32 Mon Sep 17 00:00:00 2001 From: Lawrence Wong Date: Tue, 7 Jun 2022 15:42:50 -0700 Subject: [PATCH 4/4] address code review comments from Tan --- .../scheduler/offers/HttpOfferSetImpl.java | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java b/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java index 50bc5d71d..b012ee183 100644 --- a/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java +++ b/src/main/java/io/github/aurora/scheduler/offers/HttpOfferSetImpl.java @@ -330,31 +330,28 @@ List processResponse(List mOffers, String responseStr, int ScheduleResponse response = jsonMapper.readValue(responseStr, ScheduleResponse.class); LOG.info("Received {} offers", response.hosts.size()); - Map offerMap = mOffers.stream() - .collect(Collectors. - toMap(offer -> offer.getOffer().getId().getValue(), offer -> offer)); - if (!response.error.trim().isEmpty()) { LOG.error("Unable to receive offers from {} due to {}", endpoint, response.error); throw new IOException(response.error); } - List orderedOffers = offerMap.values().stream().filter(offer -> response.hosts. - contains(offer.getOffer().getHostname())) - .collect(Collectors.toList()); - - List mHosts = mOffers.stream().map(offer -> offer.getOffer().getHostname()) - .collect(Collectors.toList()); - List extraOffers = response.hosts.stream().filter(host -> !mHosts.contains(host)) - .collect(Collectors.toList()); - - //offSetDiff is the value of the different between Aurora offers and response offers + // Use Map> to fix offers with duplicate host name issue + Map> offerMap = mOffers.stream(). + collect(Collectors.groupingBy(offer -> offer.getOffer().getHostname(), + Collectors.mapping(offer -> offer, Collectors.toList()))); + List orderedOffers = response.hosts.stream().map(host -> offerMap.get(host)) + .filter(offerList -> offerList != null && !offerList.isEmpty()). + flatMap(e -> e.stream()).collect(Collectors.toList()); + List extraOffers = response.hosts.stream().filter(host -> offerMap.get(host) == null). + collect(Collectors.toList()); + + //offSetDiff is the value of the difference between Aurora offers and response offers long offSetDiff = mOffers.size() + badOfferSize - orderedOffers.size() + extraOffers.size(); offerSetDiffList.add(offSetDiff); if (offSetDiff > 0) { LOG.warn("The number of different offers between the original and received offer sets is {}", offSetDiff); if (LOG.isDebugEnabled()) { - List missedOffers = mHosts.stream() + List missedOffers = offerMap.keySet().stream() .filter(host -> !response.hosts.contains(host)) .collect(Collectors.toList()); LOG.debug("missed offers: {}", missedOffers);