public TimelineWriteResponse putEntities(TimelineEntities entities,
      UserGroupInformation callerUgi) throws IOException {
    LOG.debug("putEntities(entities={}, callerUgi={})", entities, callerUgi);

    TimelineWriteResponse response = null;
    try {
      boolean isStorageUp = checkRetryWithSleep();
      if (isStorageUp) {
        // synchronize on the writer object so that no other threads can
        // flush the writer buffer concurrently and swallow any exception
        // caused by the timeline enitites that are being put here.
        synchronized (writer) {
          response = writeTimelineEntities(entities, callerUgi);
          flushBufferedTimelineEntities();
        }
      } else {
        String msg = String.format("Failed to putEntities(" +
            "entities=%s, callerUgi=%s) as Timeline Storage is Down",
            entities, callerUgi);
        throw new IOException(msg);
      }
    } catch (InterruptedException ex) {
      String msg = String.format("Interrupted while retrying to putEntities(" +
          "entities=%s, callerUgi=%s)", entities, callerUgi);
      throw new IOException(msg);
    }

    return response;
  }
@Test
  void testPutEntity() throws IOException {
    TimelineWriter writer = mock(TimelineWriter.class);
    TimelineHealth timelineHealth = new TimelineHealth(TimelineHealth.
        TimelineHealthStatus.RUNNING, "");
    when(writer.getHealthStatus()).thenReturn(timelineHealth);

    Configuration conf = new Configuration();
    conf.setInt(YarnConfiguration.TIMELINE_SERVICE_CLIENT_MAX_RETRIES, 5);
    conf.setLong(YarnConfiguration.TIMELINE_SERVICE_CLIENT_RETRY_INTERVAL_MS,
        500L);

    TimelineCollector collector = new TimelineCollectorForTest(writer);
    collector.init(conf);

    TimelineEntities entities = generateTestEntities(1, 1);
    collector.putEntities(
        entities, UserGroupInformation.createRemoteUser("test-user"));

    verify(writer, times(1)).write(any(TimelineCollectorContext.class),
        any(TimelineEntities.class), any(UserGroupInformation.class));
    verify(writer, times(1)).flush();
  }