@Test
  public void setUserMetadataHeadersTest() throws Exception {
    // empty user metadata
    MockRestResponseChannel responseChannel = new MockRestResponseChannel();
    assertTrue("Should report that headers are set", RestUtils.setUserMetadataHeaders(new byte[0], responseChannel));
    assertEquals("No headers should have been set", 0, responseChannel.getResponseHeaders().size());

    JSONObject headers = new JSONObject();
    setUserMetadataHeaders(headers, Collections.emptyMap());
    RestRequest restRequest = createRestRequest(RestMethod.POST, "/", headers);
    byte[] userMetadata = RestUtils.buildUserMetadata(restRequest.getArgs());
    responseChannel = new MockRestResponseChannel();
    assertTrue("Should report that headers are set", RestUtils.setUserMetadataHeaders(userMetadata, responseChannel));
    assertEquals("No headers should have been set", 0, responseChannel.getResponseHeaders().size());

    // user metadata that can be deserialized
    Map<String, String> usermetadataMap = new HashMap<>();
    for (int i = 0; i < 10; i++) {
      usermetadataMap.put(RestUtils.Headers.USER_META_DATA_HEADER_PREFIX + "key" + i, "value" + i);
    }
    setUserMetadataHeaders(headers, usermetadataMap);
    restRequest = createRestRequest(RestMethod.POST, "/", headers);
    userMetadata = RestUtils.buildUserMetadata(restRequest.getArgs());
    responseChannel = new MockRestResponseChannel();
    assertTrue("Should report that headers are set", RestUtils.setUserMetadataHeaders(userMetadata, responseChannel));
    final Map<String, Object> responseHeaders = responseChannel.getResponseHeaders();
    assertEquals("There is a mismatch in the numebr of headers", usermetadataMap.size(), responseHeaders.size());
    usermetadataMap.forEach((k, v) -> assertEquals("Value of " + k + " not as expected", v, responseHeaders.get(k)));

    // user metadata that cannot be deserialized
    responseChannel = new MockRestResponseChannel();
    userMetadata = TestUtils.getRandomBytes(100);
    assertFalse("Should report that headers are not set",
        RestUtils.setUserMetadataHeaders(userMetadata, responseChannel));
    assertEquals("No headers should have been set", 0, responseChannel.getResponseHeaders().size());

    // user metadata that needs to be encoded
    usermetadataMap.clear();
    headers = new JSONObject();
    String umHeader = "filename";
    String filenameValue = "death\nstar";
    usermetadataMap.put(RestUtils.Headers.USER_META_DATA_HEADER_PREFIX + umHeader, filenameValue);
    setUserMetadataHeaders(headers, usermetadataMap);
    restRequest = createRestRequest(RestMethod.POST, "/", headers);
    userMetadata = RestUtils.buildUserMetadata(restRequest.getArgs());
    responseChannel = spy(new MockRestResponseChannel());
    doThrow(new IllegalArgumentException("Bad header")).when(responseChannel).setHeader(any(), eq(filenameValue));
    assertTrue("Should report that headers are set", RestUtils.setUserMetadataHeaders(userMetadata, responseChannel));
    Map<String, Object> encodedHeaders = responseChannel.getResponseHeaders();
    assertEquals("Expected a header", 1, encodedHeaders.size());
    Object encodedValue = encodedHeaders.get(RestUtils.Headers.USER_META_DATA_ENCODED_HEADER_PREFIX + umHeader);
    assertNotNull("Expected encoded header", encodedValue);
    assertNotSame("Expected different value", filenameValue, encodedValue);

    // user metadata, but with a set of keys that shouldn't be prefixed
    usermetadataMap = new HashMap<>();
    Set<String> keysNotToPrefix = new HashSet<>();
    for (int i = 0; i < 10; i++) {
      String key = "key" + i;
      usermetadataMap.put(RestUtils.Headers.USER_META_DATA_HEADER_PREFIX + key, "value" + i);
      if (i % 2 == 0) {
        keysNotToPrefix.add(key);
      }
    }
    headers = new JSONObject();
    setUserMetadataHeaders(headers, usermetadataMap);
    restRequest = createRestRequest(RestMethod.POST, "/", headers);
    userMetadata = RestUtils.buildUserMetadata(restRequest.getArgs());
    responseChannel = new MockRestResponseChannel();
    assertTrue("Should report that headers are set",
        RestUtils.setUserMetadataHeaders(userMetadata, responseChannel, keysNotToPrefix));
    responseHeaders.clear();
    responseHeaders.putAll(responseChannel.getResponseHeaders());
    assertEquals("There is a mismatch in the numebr of headers", usermetadataMap.size(), responseHeaders.size());
    for (int i = 0; i < 10; i++) {
      String keyWithoutPrefix = "key" + i;
      String keyWithPrefix = RestUtils.Headers.USER_META_DATA_HEADER_PREFIX + keyWithoutPrefix;
      if (i % 2 == 0) {
        assertTrue(responseHeaders.containsKey(keyWithoutPrefix));
        assertEquals("Value mismatch", usermetadataMap.get(keyWithPrefix), responseHeaders.get(keyWithoutPrefix));
      } else {
        assertTrue(responseHeaders.containsKey(keyWithPrefix));
        assertEquals("Value mismatch", usermetadataMap.get(keyWithPrefix), responseHeaders.get(keyWithPrefix));
      }
    }
  }
Tests for {@link RestUtils#setUserMetadataHeaders(byte[], RestResponseChannel)}
@throws Exception
ambry-api/src/test/java/com/github/ambry/rest/RestUtilsTest.java