Search in sources :

Example 21 with PodEvent

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;
}
Also used : PodEvent(org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent)

Example 22 with PodEvent

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());
}
Also used : PodEvent(org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent) Test(org.testng.annotations.Test)

Example 23 with PodEvent

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());
}
Also used : Field(java.lang.reflect.Field) ObjectMeta(io.fabric8.kubernetes.api.model.ObjectMeta) Calendar(java.util.Calendar) Event(io.fabric8.kubernetes.api.model.Event) PodEvent(org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent) PodEvent(org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent) Date(java.util.Date) Test(org.testng.annotations.Test)

Example 24 with PodEvent

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));
}
Also used : ObjectMeta(io.fabric8.kubernetes.api.model.ObjectMeta) Calendar(java.util.Calendar) Event(io.fabric8.kubernetes.api.model.Event) PodEvent(org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent) PodEvent(org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent) Date(java.util.Date) Test(org.testng.annotations.Test)

Example 25 with PodEvent

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);
}
Also used : Matcher(java.util.regex.Matcher) Watcher(io.fabric8.kubernetes.client.Watcher) LogWatcher(org.eclipse.che.workspace.infrastructure.kubernetes.namespace.log.LogWatcher) PodEvent(org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent) KubernetesInfrastructureException(org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException) Date(java.util.Date) WatcherException(io.fabric8.kubernetes.client.WatcherException) LocalObjectReference(io.fabric8.kubernetes.api.model.LocalObjectReference) ObjectReference(io.fabric8.kubernetes.api.model.ObjectReference) Event(io.fabric8.kubernetes.api.model.Event) PodEvent(org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent) ParseException(java.text.ParseException) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException)

Aggregations

PodEvent (org.eclipse.che.workspace.infrastructure.kubernetes.namespace.event.PodEvent)40 Test (org.testng.annotations.Test)32 Event (io.fabric8.kubernetes.api.model.Event)8 Date (java.util.Date)8 ObjectMeta (io.fabric8.kubernetes.api.model.ObjectMeta)6 Calendar (java.util.Calendar)6 LocalObjectReference (io.fabric8.kubernetes.api.model.LocalObjectReference)2 ObjectReference (io.fabric8.kubernetes.api.model.ObjectReference)2 KubernetesClientException (io.fabric8.kubernetes.client.KubernetesClientException)2 Watcher (io.fabric8.kubernetes.client.Watcher)2 WatcherException (io.fabric8.kubernetes.client.WatcherException)2 Field (java.lang.reflect.Field)2 ParseException (java.text.ParseException)2 Matcher (java.util.regex.Matcher)2 RuntimeLogEvent (org.eclipse.che.api.workspace.shared.dto.event.RuntimeLogEvent)2 KubernetesInfrastructureException (org.eclipse.che.workspace.infrastructure.kubernetes.KubernetesInfrastructureException)2 LogWatcher (org.eclipse.che.workspace.infrastructure.kubernetes.namespace.log.LogWatcher)2