use of org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent in project che-server by eclipse-che.
the class KubernetesInternalRuntimeTest method mockContainerEvent.
/**
* Mock a container event, as though it was triggered by the OpenShift API. As workspace Pods are
* created indirectly through deployments, they are given generated names with the provided name
* as a root. <br>
* Use this method in a test to ensure that tested code manages this fact correctly. For example,
* code such as unrecoverable events handling cannot directly look at an event's pod name and
* compare it to the internal representation, and so must confirm the event is relevant in some
* other way.
*/
private static PodEvent mockContainerEvent(String podName, String reason, String message, String creationTimestamp, String lastTimestamp) {
final PodEvent event = mock(PodEvent.class);
when(event.getPodName()).thenReturn(podName + POD_NAME_RANDOM_SUFFIX);
when(event.getContainerName()).thenReturn(CONTAINER_NAME_1);
when(event.getReason()).thenReturn(reason);
when(event.getMessage()).thenReturn(message);
when(event.getCreationTimeStamp()).thenReturn(creationTimestamp);
when(event.getLastTimestamp()).thenReturn(lastTimestamp);
return event;
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent in project che-server by eclipse-che.
the class KubernetesInternalRuntimeTest method testDoNotPublishForeignMachineOutput.
@Test
public void testDoNotPublishForeignMachineOutput() throws ParseException {
final MachineLogsPublisher logsPublisher = new MachineLogsPublisher(eventPublisher, machinesCache, IDENTITY);
final PodEvent out1 = mockContainerEvent(WORKSPACE_POD_NAME, "Created", "folder created", EVENT_CREATION_TIMESTAMP, getCurrentTimestampWithOneHourShiftAhead());
logsPublisher.handle(out1);
verify(eventService, never()).publish(any());
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent in project che-server by eclipse-che.
the class KubernetesDeploymentsTest method shouldHandleEventWithEmptyLastTimestampAndFirstTimestamp.
@Test
public void shouldHandleEventWithEmptyLastTimestampAndFirstTimestamp() throws Exception {
// Given
when(objectReference.getKind()).thenReturn(POD_OBJECT_KIND);
kubernetesDeployments.watchEvents(podEventHandler);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, -1);
Date minuteAgo = cal.getTime();
Field f = KubernetesDeployments.class.getDeclaredField("watcherInitializationDate");
f.setAccessible(true);
f.set(kubernetesDeployments, minuteAgo);
verify(eventNamespaceMixedOperation).watch(eventWatcherCaptor.capture());
Watcher<Event> watcher = eventWatcherCaptor.getValue();
Event event = mock(Event.class);
when(event.getInvolvedObject()).thenReturn(objectReference);
when(event.getMetadata()).thenReturn(new ObjectMeta());
when(event.getLastTimestamp()).thenReturn(null);
when(event.getFirstTimestamp()).thenReturn(null);
// When
watcher.eventReceived(Watcher.Action.ADDED, event);
// Then
verify(event, times(1)).getLastTimestamp();
verify(event, times(1)).getFirstTimestamp();
ArgumentCaptor<PodEvent> captor = ArgumentCaptor.forClass(PodEvent.class);
verify(podEventHandler).handle(captor.capture());
PodEvent podEvent = captor.getValue();
assertNotNull(podEvent.getLastTimestamp());
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent in project che-server by eclipse-che.
the class KubernetesDeploymentsTest method shouldUseLastTimestampIfAvailable.
@Test
public void shouldUseLastTimestampIfAvailable() throws InfrastructureException {
// Given
when(objectReference.getKind()).thenReturn(POD_OBJECT_KIND);
kubernetesDeployments.watchEvents(podEventHandler);
verify(eventNamespaceMixedOperation).watch(eventWatcherCaptor.capture());
Watcher<Event> watcher = eventWatcherCaptor.getValue();
Event event = mock(Event.class);
when(event.getInvolvedObject()).thenReturn(objectReference);
when(event.getMetadata()).thenReturn(new ObjectMeta());
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, 2);
Date nextYear = cal.getTime();
when(event.getLastTimestamp()).thenReturn(PodEvents.convertDateToEventTimestamp(nextYear));
// When
watcher.eventReceived(Watcher.Action.ADDED, event);
// Then
verify(event, times(1)).getLastTimestamp();
verify(event, never()).getFirstTimestamp();
ArgumentCaptor<PodEvent> captor = ArgumentCaptor.forClass(PodEvent.class);
verify(podEventHandler).handle(captor.capture());
PodEvent podEvent = captor.getValue();
assertEquals(podEvent.getLastTimestamp(), PodEvents.convertDateToEventTimestamp(nextYear));
}
use of org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent in project che-server by eclipse-che.
the class KubernetesDeployments method watchEvents.
/**
* Registers a specified handler for handling events about changes in pods containers. Registering
* several handlers doesn't create multiple websocket connections, so it is efficient to call this
* method several times instead of using composite handler to combine other handlers.
*
* @param handler pod container events handler
* @throws InfrastructureException if any error occurs while watcher starting
*/
public void watchEvents(PodEventHandler handler) throws InfrastructureException {
if (containerWatch == null) {
final Watcher<Event> watcher = new Watcher<>() {
@Override
public void eventReceived(Action action, Event event) {
ObjectReference involvedObject = event.getInvolvedObject();
if (POD_OBJECT_KIND.equals(involvedObject.getKind()) || REPLICASET_OBJECT_KIND.equals(involvedObject.getKind()) || DEPLOYMENT_OBJECT_KIND.equals(involvedObject.getKind())) {
String podName = involvedObject.getName();
String lastTimestamp = event.getLastTimestamp();
if (lastTimestamp == null) {
String firstTimestamp = event.getFirstTimestamp();
if (firstTimestamp != null) {
// Done in the same way like it made in
// https://github.com/kubernetes/kubernetes/pull/86557
lastTimestamp = firstTimestamp;
} else {
LOG.debug("lastTimestamp and firstTimestamp are undefined. Event: {}. Fallback to the current time.", event);
lastTimestamp = PodEvents.convertDateToEventTimestamp(new Date());
}
}
PodEvent podEvent = new PodEvent(podName, getContainerName(involvedObject.getFieldPath()), event.getReason(), event.getMessage(), event.getMetadata().getCreationTimestamp(), lastTimestamp);
try {
if (happenedAfterWatcherInitialization(podEvent)) {
containerEventsHandlers.forEach(h -> h.handle(podEvent));
}
} catch (ParseException e) {
LOG.error("Failed to parse last timestamp of the event. Cause: {}. Event: {}", e.getMessage(), podEvent, e);
}
}
}
@Override
public void onClose(WatcherException ignored) {
}
/**
* Returns the container name if the event is related to container. When the event is
* related to container `fieldPath` field contain information in the following format:
* `spec.container{web}`, where `web` is container name
*/
private String getContainerName(String fieldPath) {
String containerName = null;
if (fieldPath != null) {
Matcher containerFieldMatcher = CONTAINER_FIELD_PATH_PATTERN.matcher(fieldPath);
if (containerFieldMatcher.matches()) {
containerName = containerFieldMatcher.group(CONTAINER_NAME_GROUP);
}
}
return containerName;
}
/**
* Returns true if 'lastTimestamp' of the event is *after* the time of the watcher
* initialization
*/
private boolean happenedAfterWatcherInitialization(PodEvent event) throws ParseException {
String eventLastTimestamp = event.getLastTimestamp();
Date eventLastTimestampDate = PodEvents.convertEventTimestampToDate(eventLastTimestamp);
return eventLastTimestampDate.after(watcherInitializationDate);
}
};
try {
watcherInitializationDate = new Date();
containerWatch = clientFactory.create(workspaceId).v1().events().inNamespace(namespace).watch(watcher);
} catch (KubernetesClientException ex) {
throw new KubernetesInfrastructureException(ex);
}
}
containerEventsHandlers.add(handler);
}
Aggregations