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

io.datarouter.webappinstance.web.WebappInstanceServersHandler Maven / Gradle / Ivy

There is a newer version: 0.0.125
Show newest version
/*
 * Copyright © 2009 HotPads ([email protected])
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.datarouter.webappinstance.web;

import static j2html.TagCreator.div;
import static j2html.TagCreator.span;
import static j2html.TagCreator.td;

import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import io.datarouter.scanner.Scanner;
import io.datarouter.util.duration.DatarouterDuration;
import io.datarouter.util.time.ZonedDateFormatterTool;
import io.datarouter.web.handler.BaseHandler;
import io.datarouter.web.handler.mav.Mav;
import io.datarouter.web.html.j2html.J2HtmlTable;
import io.datarouter.web.html.j2html.bootstrap4.Bootstrap4PageFactory;
import io.datarouter.web.html.pager.Bootstrap4PagerHtml;
import io.datarouter.web.html.pager.MemoryPager;
import io.datarouter.web.html.pager.MemoryPager.Page;
import io.datarouter.web.html.pager.MemorySorter;
import io.datarouter.webappinstance.config.DatarouterWebappInstancePaths;
import io.datarouter.webappinstance.storage.webappinstance.DatarouterWebappInstanceDao;
import io.datarouter.webappinstance.storage.webappinstance.WebappInstanceKey;
import io.datarouter.webappinstance.storage.webappinstancelog.DatarouterWebappInstanceLogDao;
import io.datarouter.webappinstance.storage.webappinstancelog.WebappInstanceLog;
import io.datarouter.webappinstance.storage.webappinstancelog.WebappInstanceLogKey;
import j2html.tags.ContainerTag;

public class WebappInstanceServersHandler extends BaseHandler{

	@Inject
	private DatarouterWebappInstanceLogDao logDao;
	@Inject
	private Bootstrap4PageFactory pageFactory;
	@Inject
	private DatarouterWebappInstancePaths paths;
	@Inject
	private DatarouterWebappInstanceDao webappInstanceDao;

	@Handler(defaultHandler = true)
	private Mav view(){
		Scanner logs = Scanner.of(logDao.scan()
				.groupBy(WebappInstanceLogKeyDto::new).entrySet())
				.map(entry -> new WebappInstanceLogDto(entry.getKey(), entry.getValue()))
				.sort(Comparator.comparing((WebappInstanceLogDto dto) -> dto.key.buildDate).reversed());
		MemoryPager pager = new MemoryPager<>(
				Collections.emptyList(),
				new MemorySorter<>(),
				request.getContextPath() + paths.datarouter.webappInstanceServers.toSlashedString(),
				new HashMap<>(),
				params,
				50);
		List activeServerNames = webappInstanceDao.scanKeys()
				.map(WebappInstanceKey::getServerName)
				.list();
		Page page = pager.collect(logs);
		var content = makeContent(page, activeServerNames);
		return pageFactory.startBuilder(request)
				.withTitle("Server Startup and Shutdowns")
				.withContent(content)
				.buildMav();
	}

	private ContainerTag makeContent(Page page, List activeServerNames){
		var form = Bootstrap4PagerHtml.renderForm(page)
				.withClass("mt-4");
		var linkBar = Bootstrap4PagerHtml.renderLinkBar(page)
				.withClass("mt-2");
		ZoneId zoneId = getUserZoneId();
		var table = new J2HtmlTable()
				.withClasses("sortable table table-sm table-striped my-4 border")
				.withHtmlColumn("", row -> {
					if(activeServerNames.contains(row.key.serverName)){
						if(row.shutdown.isEmpty()){
							return td();
						}
						if(row.shutdown.get().toEpochMilli() < System.currentTimeMillis()){
							return td();
						}
						return td(span("Active").withClass("badge badge-success"));
					}
					return td();
				})
				.withColumn("Server Name", row -> row.key.serverName)
				.withColumn("Private IP", row -> row.key.serverPrivateIp)
				.withColumn("Build Date", row -> ZonedDateFormatterTool.formatInstantWithZone(row.key.buildDate,
						zoneId))
				.withColumn("Startup Range", row ->
						row.startup
								.map(date -> ZonedDateFormatterTool.formatInstantWithZone(date, zoneId))
								.orElse("unknown")
						+ " - "
						+ row.shutdown
								.map(date -> ZonedDateFormatterTool.formatInstantWithZone(date, zoneId))
								.orElse("unknown"))
				.withColumn("Up Time", row -> {
						if(row.startup.isEmpty() || row.shutdown.isEmpty()){
							return "unknown";
						}
						var duration = Duration.ofMillis(row.shutdown.get().toEpochMilli()
								- row.startup.get().toEpochMilli());
						return new DatarouterDuration(duration).toString(TimeUnit.MINUTES);
				})
				.build(page.rows);
		return div(form, linkBar, table)
				.withClass("container-fluid");
	}

	private static class WebappInstanceLogKeyDto{

		public final String serverName;
		public final Instant buildDate;
		public final String buildId;
		public final String commitId;
		public final String serverPrivateIp;

		public WebappInstanceLogKeyDto(WebappInstanceLog log){
			this.serverName = log.getKey().getServerName();
			this.buildDate = log.getKey().getBuild();
			this.buildId = log.getBuildId();
			this.commitId = log.getCommitId();
			this.serverPrivateIp = log.getServerPrivateIp();
		}

		@Override
		public boolean equals(Object other){
			if(this == other){
				return true;
			}
			if(!(other instanceof WebappInstanceLogKeyDto)){
				return false;
			}
			WebappInstanceLogKeyDto that = (WebappInstanceLogKeyDto) other;

			return Objects.equals(this.serverName, that.serverName)
					&& Objects.equals(this.buildDate, that.buildDate)
					&& Objects.equals(this.buildId, that.buildId)
					&& Objects.equals(this.commitId, that.commitId)
					&& Objects.equals(this.serverPrivateIp, that.serverPrivateIp);
		}

		@Override
		public int hashCode(){
			return Objects.hash(serverName, buildDate, buildId, commitId, serverPrivateIp);
		}

	}

	private static class WebappInstanceLogDto{

		public final WebappInstanceLogKeyDto key;
		private final Optional startup;
		private final Optional shutdown;

		public WebappInstanceLogDto(WebappInstanceLogKeyDto key, List logRanges){
			this.key = key;
			this.startup = Scanner.of(logRanges)
					.map(WebappInstanceLog::getKey)
					.map(WebappInstanceLogKey::getStartup)
					.sort()
					.findFirst();
			this.shutdown = Scanner.of(logRanges)
					.map(WebappInstanceLog::getRefreshedLast)
					.exclude(Objects::isNull)
					.sort()
					.findLast();
		}

	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy