@Test @SuppressWarnings("PMD.AvoidUsingHardCodedIP") public void test_get_application_activity() throws CloudFoundryException { final String applicationId = "application-id"; final String applicationState = "RUNNING"; final String applicationName = "application-name"; ApplicationsV2 applications = mock(ApplicationsV2.class); Events events = mock(Events.class); when(cfClient.applicationsV2()).thenReturn(applications); when(cfClient.events()).thenReturn(events); mockGetApplication(applications, applicationName, applicationState); Instant now = Instant.now(); Instant eventTimestamp = now.minus(Duration.ofDays(3)); when(events.list(any(ListEventsRequest.class))) .thenReturn(Mono.just(ListEventsResponse.builder() .resource(EventResource.builder() .metadata(Metadata.builder().build()) .entity(EventEntity.builder() .actee("43dc8103-6d62-46c7-8456-6dcebfa2f2d1") .acteeName("hello-cf-java-client") .acteeType("app") .actor("526cc2f7-3d07-4e04-85b2-e3c96282541c") .actorName("user@email.com") .acteeType("user") .organizationId("37816bdf-a476-473d-9ae4-75d7cfefabca") .spaceId("3518c030-0b99-4075-834e-1b47e6ec7909") .timestamp(eventTimestamp.toString()) .type("audit.app.create") .build()) .build()) .build())); long lastTimestampNanos = now.getEpochSecond() * 1000000000 + now.getNano(); Function<Integer, Envelope> envelopeBuilder = diff -> Envelope.builder() .deployment("cf-cfapps-io2-diego") .eventType(EventType.LOG_MESSAGE) .index("3e49c9d7-8e67-4dc1-8672-ebc2299e261f") .ip("10.10.148.105") .job("cell_2xl_z2") .logMessage(LogMessage.builder() .applicationId("application-id") .message("message-" + diff) .messageType(MessageType.OUT) .sourceInstance("0") .sourceType("CELL") .timestamp(lastTimestampNanos + diff) .build()) .origin("rep") .tags(new HashMap<>()) .timestamp(lastTimestampNanos + diff) .valueMetric(null) .build(); when(dopplerClient.recentLogs(any(RecentLogsRequest.class))) .thenReturn(Flux.fromIterable( Arrays.asList(envelopeBuilder.apply(1), envelopeBuilder.apply(2), envelopeBuilder.apply(3), envelopeBuilder.apply(0), envelopeBuilder.apply(4)) )); ApplicationActivity activity = cloudFoundryApi.getApplicationActivity(applicationId); assertNotNull(activity); assertNotNull(activity.getApplication()); assertEquals(applicationId, activity.getApplication().getGuid()); assertEquals(applicationName, activity.getApplication().getName()); assertNotNull(activity.getLastEvent()); assertEquals(eventTimestamp, activity.getLastEvent().getTimestamp()); assertEquals("last event ordered by timestamp be the most recent by 4 nanosecs", Instant.ofEpochSecond(0, lastTimestampNanos +4), activity.getLastLog().getTimestamp()); assertEquals("message-" + 4, activity.getLastLog().getMessage()); }
@Override public ApplicationActivity getApplicationActivity(String appUid) throws CloudFoundryException { log.debug("getApplicationActivity - {}", appUid); final CountDownLatch latch = new CountDownLatch(3); final AtomicReference<Throwable> errorEncountered = new AtomicReference<>(null); final AtomicReference<LogMessage> lastLogReference = new AtomicReference<>(null); final AtomicReference<ListEventsResponse> lastEventsReference = new AtomicReference<>(null); final AtomicReference<GetApplicationResponse> appReference = new AtomicReference<>(null); final AtomicReference<Instant> mostRecentLogInstant = new AtomicReference<>(null); cfClient.applicationsV2() .get(GetApplicationRequest.builder() .applicationId(appUid) .build()) .subscribe(new BaseSubscriber<>(latch, errorEncountered::set, appReference::set)); cfClient.events() .list(ListEventsRequest.builder() .actee(appUid) .build()) .subscribe(new BaseSubscriber<>(latch, errorEncountered::set, lastEventsReference::set)); dopplerClient.recentLogs(RecentLogsRequest.builder() .applicationId(appUid) .build()) .subscribe(new BaseSubscriber<>( latch, errorEncountered::set, envelope -> { LogMessage logMessage = envelope.getLogMessage(); if (logMessage == null) { log.warn("recent log without log message. Skipping. Envelope: {}", envelope); return; } Long timestamp = logMessage.getTimestamp(); if (timestamp == null) { log.warn("recent log without log message timestamp. Skipping. Envelope: {}", envelope); return; } Instant msgInstant = getInstantFromLogMessageTimestamp(timestamp); if (mostRecentLogInstant.get() == null || mostRecentLogInstant.get().isBefore(msgInstant)) { mostRecentLogInstant.set(msgInstant); lastLogReference.set(envelope.getLogMessage()); } } )); ApplicationActivity applicationActivity = waitForResult(latch, errorEncountered, () -> ApplicationActivity.builder() .application(ApplicationIdentity.builder() .guid(appUid) .name(appReference.get().getEntity().getName()) .build()) .lastEvent( lastEventsReference.get().getResources().isEmpty() ? null : buildAppEvent(lastEventsReference.get().getResources().get(0))) .lastLog(buildAppLog(lastLogReference.get())) .state(appReference.get().getEntity().getState()) .build()); log.debug("getApplicationActivity - {} - resulted in {}", appUid, applicationActivity); return applicationActivity; }
CloudFoundryApi implements CloudFoundryApiService { @Override public ApplicationActivity getApplicationActivity(String appUid) throws CloudFoundryException { log.debug("getApplicationActivity - {}", appUid); final CountDownLatch latch = new CountDownLatch(3); final AtomicReference<Throwable> errorEncountered = new AtomicReference<>(null); final AtomicReference<LogMessage> lastLogReference = new AtomicReference<>(null); final AtomicReference<ListEventsResponse> lastEventsReference = new AtomicReference<>(null); final AtomicReference<GetApplicationResponse> appReference = new AtomicReference<>(null); final AtomicReference<Instant> mostRecentLogInstant = new AtomicReference<>(null); cfClient.applicationsV2() .get(GetApplicationRequest.builder() .applicationId(appUid) .build()) .subscribe(new BaseSubscriber<>(latch, errorEncountered::set, appReference::set)); cfClient.events() .list(ListEventsRequest.builder() .actee(appUid) .build()) .subscribe(new BaseSubscriber<>(latch, errorEncountered::set, lastEventsReference::set)); dopplerClient.recentLogs(RecentLogsRequest.builder() .applicationId(appUid) .build()) .subscribe(new BaseSubscriber<>( latch, errorEncountered::set, envelope -> { LogMessage logMessage = envelope.getLogMessage(); if (logMessage == null) { log.warn("recent log without log message. Skipping. Envelope: {}", envelope); return; } Long timestamp = logMessage.getTimestamp(); if (timestamp == null) { log.warn("recent log without log message timestamp. Skipping. Envelope: {}", envelope); return; } Instant msgInstant = getInstantFromLogMessageTimestamp(timestamp); if (mostRecentLogInstant.get() == null || mostRecentLogInstant.get().isBefore(msgInstant)) { mostRecentLogInstant.set(msgInstant); lastLogReference.set(envelope.getLogMessage()); } } )); ApplicationActivity applicationActivity = waitForResult(latch, errorEncountered, () -> ApplicationActivity.builder() .application(ApplicationIdentity.builder() .guid(appUid) .name(appReference.get().getEntity().getName()) .build()) .lastEvent( lastEventsReference.get().getResources().isEmpty() ? null : buildAppEvent(lastEventsReference.get().getResources().get(0))) .lastLog(buildAppLog(lastLogReference.get())) .state(appReference.get().getEntity().getState()) .build()); log.debug("getApplicationActivity - {} - resulted in {}", appUid, applicationActivity); return applicationActivity; } }
CloudFoundryApi implements CloudFoundryApiService { @Override public ApplicationActivity getApplicationActivity(String appUid) throws CloudFoundryException { log.debug("getApplicationActivity - {}", appUid); final CountDownLatch latch = new CountDownLatch(3); final AtomicReference<Throwable> errorEncountered = new AtomicReference<>(null); final AtomicReference<LogMessage> lastLogReference = new AtomicReference<>(null); final AtomicReference<ListEventsResponse> lastEventsReference = new AtomicReference<>(null); final AtomicReference<GetApplicationResponse> appReference = new AtomicReference<>(null); final AtomicReference<Instant> mostRecentLogInstant = new AtomicReference<>(null); cfClient.applicationsV2() .get(GetApplicationRequest.builder() .applicationId(appUid) .build()) .subscribe(new BaseSubscriber<>(latch, errorEncountered::set, appReference::set)); cfClient.events() .list(ListEventsRequest.builder() .actee(appUid) .build()) .subscribe(new BaseSubscriber<>(latch, errorEncountered::set, lastEventsReference::set)); dopplerClient.recentLogs(RecentLogsRequest.builder() .applicationId(appUid) .build()) .subscribe(new BaseSubscriber<>( latch, errorEncountered::set, envelope -> { LogMessage logMessage = envelope.getLogMessage(); if (logMessage == null) { log.warn("recent log without log message. Skipping. Envelope: {}", envelope); return; } Long timestamp = logMessage.getTimestamp(); if (timestamp == null) { log.warn("recent log without log message timestamp. Skipping. Envelope: {}", envelope); return; } Instant msgInstant = getInstantFromLogMessageTimestamp(timestamp); if (mostRecentLogInstant.get() == null || mostRecentLogInstant.get().isBefore(msgInstant)) { mostRecentLogInstant.set(msgInstant); lastLogReference.set(envelope.getLogMessage()); } } )); ApplicationActivity applicationActivity = waitForResult(latch, errorEncountered, () -> ApplicationActivity.builder() .application(ApplicationIdentity.builder() .guid(appUid) .name(appReference.get().getEntity().getName()) .build()) .lastEvent( lastEventsReference.get().getResources().isEmpty() ? null : buildAppEvent(lastEventsReference.get().getResources().get(0))) .lastLog(buildAppLog(lastLogReference.get())) .state(appReference.get().getEntity().getState()) .build()); log.debug("getApplicationActivity - {} - resulted in {}", appUid, applicationActivity); return applicationActivity; }  }
CloudFoundryApi implements CloudFoundryApiService { @Override public ApplicationActivity getApplicationActivity(String appUid) throws CloudFoundryException { log.debug("getApplicationActivity - {}", appUid); final CountDownLatch latch = new CountDownLatch(3); final AtomicReference<Throwable> errorEncountered = new AtomicReference<>(null); final AtomicReference<LogMessage> lastLogReference = new AtomicReference<>(null); final AtomicReference<ListEventsResponse> lastEventsReference = new AtomicReference<>(null); final AtomicReference<GetApplicationResponse> appReference = new AtomicReference<>(null); final AtomicReference<Instant> mostRecentLogInstant = new AtomicReference<>(null); cfClient.applicationsV2() .get(GetApplicationRequest.builder() .applicationId(appUid) .build()) .subscribe(new BaseSubscriber<>(latch, errorEncountered::set, appReference::set)); cfClient.events() .list(ListEventsRequest.builder() .actee(appUid) .build()) .subscribe(new BaseSubscriber<>(latch, errorEncountered::set, lastEventsReference::set)); dopplerClient.recentLogs(RecentLogsRequest.builder() .applicationId(appUid) .build()) .subscribe(new BaseSubscriber<>( latch, errorEncountered::set, envelope -> { LogMessage logMessage = envelope.getLogMessage(); if (logMessage == null) { log.warn("recent log without log message. Skipping. Envelope: {}", envelope); return; } Long timestamp = logMessage.getTimestamp(); if (timestamp == null) { log.warn("recent log without log message timestamp. Skipping. Envelope: {}", envelope); return; } Instant msgInstant = getInstantFromLogMessageTimestamp(timestamp); if (mostRecentLogInstant.get() == null || mostRecentLogInstant.get().isBefore(msgInstant)) { mostRecentLogInstant.set(msgInstant); lastLogReference.set(envelope.getLogMessage()); } } )); ApplicationActivity applicationActivity = waitForResult(latch, errorEncountered, () -> ApplicationActivity.builder() .application(ApplicationIdentity.builder() .guid(appUid) .name(appReference.get().getEntity().getName()) .build()) .lastEvent( lastEventsReference.get().getResources().isEmpty() ? null : buildAppEvent(lastEventsReference.get().getResources().get(0))) .lastLog(buildAppLog(lastLogReference.get())) .state(appReference.get().getEntity().getState()) .build()); log.debug("getApplicationActivity - {} - resulted in {}", appUid, applicationActivity); return applicationActivity; }  @Override void bindApplications(String serviceInstanceId, List<ApplicationIdentity> applications); void bindRoutes(String serviceInstanceId, List<String> routeIds); @Override ApplicationActivity getApplicationActivity(String appUid); Instant getInstantFromLogMessageTimestamp(Long logMessageTimestamp); @Override String getApplicationState(String applicationUuid); @Override String getHost(String routeId); @Override boolean isAppRunning(String appUid); @Override List<ApplicationIdentity> listAliveApplications(String spaceUuid, Pattern excludeNames); @Override List<String> listApplicationRoutes(String applicationUuid); @Override List<String> listRouteApplications(String routeUuid); @Override boolean startApplication(String applicationUuid); @Override boolean stopApplication(String applicationUuid); @Override void unbind(String bindingId); boolean isValidOrganization(String organizationGuid); }
CloudFoundryApi implements CloudFoundryApiService { @Override public ApplicationActivity getApplicationActivity(String appUid) throws CloudFoundryException { log.debug("getApplicationActivity - {}", appUid); final CountDownLatch latch = new CountDownLatch(3); final AtomicReference<Throwable> errorEncountered = new AtomicReference<>(null); final AtomicReference<LogMessage> lastLogReference = new AtomicReference<>(null); final AtomicReference<ListEventsResponse> lastEventsReference = new AtomicReference<>(null); final AtomicReference<GetApplicationResponse> appReference = new AtomicReference<>(null); final AtomicReference<Instant> mostRecentLogInstant = new AtomicReference<>(null); cfClient.applicationsV2() .get(GetApplicationRequest.builder() .applicationId(appUid) .build()) .subscribe(new BaseSubscriber<>(latch, errorEncountered::set, appReference::set)); cfClient.events() .list(ListEventsRequest.builder() .actee(appUid) .build()) .subscribe(new BaseSubscriber<>(latch, errorEncountered::set, lastEventsReference::set)); dopplerClient.recentLogs(RecentLogsRequest.builder() .applicationId(appUid) .build()) .subscribe(new BaseSubscriber<>( latch, errorEncountered::set, envelope -> { LogMessage logMessage = envelope.getLogMessage(); if (logMessage == null) { log.warn("recent log without log message. Skipping. Envelope: {}", envelope); return; } Long timestamp = logMessage.getTimestamp(); if (timestamp == null) { log.warn("recent log without log message timestamp. Skipping. Envelope: {}", envelope); return; } Instant msgInstant = getInstantFromLogMessageTimestamp(timestamp); if (mostRecentLogInstant.get() == null || mostRecentLogInstant.get().isBefore(msgInstant)) { mostRecentLogInstant.set(msgInstant); lastLogReference.set(envelope.getLogMessage()); } } )); ApplicationActivity applicationActivity = waitForResult(latch, errorEncountered, () -> ApplicationActivity.builder() .application(ApplicationIdentity.builder() .guid(appUid) .name(appReference.get().getEntity().getName()) .build()) .lastEvent( lastEventsReference.get().getResources().isEmpty() ? null : buildAppEvent(lastEventsReference.get().getResources().get(0))) .lastLog(buildAppLog(lastLogReference.get())) .state(appReference.get().getEntity().getState()) .build()); log.debug("getApplicationActivity - {} - resulted in {}", appUid, applicationActivity); return applicationActivity; }  @Override void bindApplications(String serviceInstanceId, List<ApplicationIdentity> applications); void bindRoutes(String serviceInstanceId, List<String> routeIds); @Override ApplicationActivity getApplicationActivity(String appUid); Instant getInstantFromLogMessageTimestamp(Long logMessageTimestamp); @Override String getApplicationState(String applicationUuid); @Override String getHost(String routeId); @Override boolean isAppRunning(String appUid); @Override List<ApplicationIdentity> listAliveApplications(String spaceUuid, Pattern excludeNames); @Override List<String> listApplicationRoutes(String applicationUuid); @Override List<String> listRouteApplications(String routeUuid); @Override boolean startApplication(String applicationUuid); @Override boolean stopApplication(String applicationUuid); @Override void unbind(String bindingId); boolean isValidOrganization(String organizationGuid);  }