All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.cds.feature.dashboard.service.DashboardServiceConfiguration Maven / Gradle / Ivy

There is a newer version: 3.2.0
Show newest version
/**************************************************************************
 * (C) 2019-2021 SAP SE or an SAP affiliate company. All rights reserved. *
 **************************************************************************/
package com.sap.cds.feature.dashboard.service;

import java.util.Collections;
import java.util.LinkedList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import com.sap.cds.feature.dashboard.connectivity.InfoEvent;
import com.sap.cds.feature.dashboard.info.InfoCollector;
import com.sap.cds.feature.dashboard.info.Path;
import com.sap.cds.feature.dashboard.info.collectors.CdsInfoCollector;
import com.sap.cds.feature.dashboard.info.collectors.ClientInfoCollector;
import com.sap.cds.feature.dashboard.info.collectors.LogCollector;
import com.sap.cds.feature.dashboard.info.collectors.MessagingInfoCollector;
import com.sap.cds.feature.dashboard.info.collectors.MultitenancyInfoCollector;
import com.sap.cds.feature.dashboard.info.collectors.OutboxInfoCollector;
import com.sap.cds.feature.dashboard.info.collectors.PersistenceCollector;
import com.sap.cds.feature.dashboard.info.collectors.SystemInfoCollector;
import com.sap.cds.services.application.ApplicationLifecycleService;
import com.sap.cds.services.impl.messaging.composite.MessagingCompositeService;
import com.sap.cds.services.runtime.CdsRuntimeConfiguration;
import com.sap.cds.services.runtime.CdsRuntimeConfigurer;

public class DashboardServiceConfiguration implements CdsRuntimeConfiguration {

	private DashboardService dashboardService;
	private int totalEventsCount;
	private AtomicInteger eventsSample = new AtomicInteger();
	private SizeLimitedQueue queue = new SizeLimitedQueue(120);

	private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
	private boolean schedulerInitialized;


	@Override
	public int order() {
		return Integer.MAX_VALUE;
	}

	@Override
	public void services(CdsRuntimeConfigurer configurer) {
		if (configurer.getCdsRuntime().getEnvironment().getCdsProperties().getIndexPage().isEnabled()) {
			dashboardService = new DashboardServiceImpl();
			configurer.service(dashboardService);
		}
	}

	@Override
	public void eventHandlers(CdsRuntimeConfigurer configurer) {

		if (dashboardService != null) {

			configurer.eventHandler(new ClientInfoCollector(configurer.getCdsRuntime(), dashboardService));
			configurer.eventHandler(new SystemInfoCollector(configurer.getCdsRuntime(), dashboardService));
			configurer.eventHandler(new MultitenancyInfoCollector(configurer.getCdsRuntime(), dashboardService));
			configurer.eventHandler(new MessagingInfoCollector(configurer.getCdsRuntime(), dashboardService));
			configurer.eventHandler(new OutboxInfoCollector(configurer.getCdsRuntime(), dashboardService));
			configurer.eventHandler(new PersistenceCollector(configurer.getCdsRuntime(), dashboardService));
			configurer.eventHandler(new CdsInfoCollector(configurer.getCdsRuntime(), dashboardService));
			configurer.eventHandler(new LogCollector(configurer.getCdsRuntime(), dashboardService));

			configurer.getCdsRuntime().getServiceCatalog().getServices().forEach(service -> {
				// we don't want to trace dashboard events and also to force messaging composite configuration for '*' event
				if (!service.getName().equals(DashboardService.DEFAULT_NAME) &&
						!service.getName().equals(MessagingCompositeService.COMPOSITE_NAME)) {
					service.after("*", null, ctx -> {
						// trace only events produced outside dashboard context
						if (!InfoCollector.isInDashboardContext()) {
							totalEventsCount++;
							eventsSample.incrementAndGet();
							dashboardService.emit(PersistenceCollector.createInfo(ctx, Path.TRACES_EVENTS));
							dashboardService.emit(createTotalEventsCount());
						}
					});
				}
			});


			((DashboardServiceImpl) dashboardService).after(ClientInfoCollector.COMMAND_ATTACHED, null, ctx -> {
				dashboardService.emit(createEventsSeries());

				synchronized (scheduler) {
					if (!schedulerInitialized) {

						ScheduledFuture sampler = scheduler.scheduleAtFixedRate(() -> {
							int val = eventsSample.getAndSet(0);
							queue.add(val);
							dashboardService.emit(createEventSampel(val));
						}, 0, 3, TimeUnit.SECONDS);
						schedulerInitialized = true;

						// we need to stop the sampler on shutdown as we could potentially run in a relaunch scenario (watch)
						configurer.getCdsRuntime().getServiceCatalog()
						.getService(ApplicationLifecycleService.class, ApplicationLifecycleService.DEFAULT_NAME)
						.on(ApplicationLifecycleService.EVENT_APPLICATION_STOPPED, null, context -> {
							if (sampler != null) {
								sampler.cancel(true);
							}
						});
					}
				}

			});
		}
	}

	public InfoEvent createTotalEventsCount() {
		InfoEvent event = InfoEvent.create(Path.SYSTEM);
		event.getData().put("total_events_count", totalEventsCount);
		return event;
	}

	public InfoEvent createEventsSeries() {
		InfoEvent event = InfoEvent.create(Path.SYSTEM);
		event.getData().put("event_series", queue.toArray());
		return event;
	}

	public InfoEvent createEventSampel(int value) {
		InfoEvent event = InfoEvent.create(Path.SYSTEM);
		event.getData().put("events_sampel", Collections.singletonMap("value", value));
		return event;
	}

	public static class SizeLimitedQueue extends LinkedList {

		private static final long serialVersionUID = 1L;
		private int queueSize;

		public SizeLimitedQueue(int queueSize) {
			this.queueSize = queueSize;
			for (int i = 0;  i < queueSize; i++) {
				add(0);
			}
		}

		@Override
		public boolean add(Integer o) {

			while (this.size() == queueSize) {
				super.remove();
			}
			super.add(o);
			return true;
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy