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

ai.grakn.engine.controller.SystemController Maven / Gradle / Ivy

There is a newer version: 1.4.3
Show newest version
/*
 * Grakn - A Distributed Semantic Database
 * Copyright (C) 2016-2018 Grakn Labs Limited
 *
 * Grakn is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Grakn is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Grakn. If not, see .
 */

package ai.grakn.engine.controller;


import ai.grakn.GraknConfigKey;
import ai.grakn.GraknTx;
import ai.grakn.engine.GraknConfig;
import ai.grakn.engine.GraknEngineStatus;
import ai.grakn.engine.GraknKeyspaceStore;
import ai.grakn.engine.controller.response.Keyspace;
import ai.grakn.engine.controller.response.Keyspaces;
import ai.grakn.engine.controller.response.Root;
import ai.grakn.engine.controller.util.Requests;
import ai.grakn.exception.GraknServerException;
import ai.grakn.util.GraknVersion;
import ai.grakn.util.REST;
import com.codahale.metrics.MetricFilter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.json.MetricsModule;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.dropwizard.DropwizardExports;
import io.prometheus.client.exporter.common.TextFormat;
import org.apache.commons.io.Charsets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import spark.Request;
import spark.Response;
import spark.Service;

import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.file.Files;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static ai.grakn.util.REST.Request.FORMAT;
import static ai.grakn.util.REST.Request.KEYSPACE_PARAM;
import static ai.grakn.util.REST.Response.ContentType.APPLICATION_JSON;
import static org.apache.http.HttpHeaders.CACHE_CONTROL;


/**
 * 

Controller Providing Configs for building Grakn Graphs

* *

When calling {@link ai.grakn.Grakn#session(String, String)} and using the non memory location * this controller is accessed. The controller provides the necessary config needed in order to * build a {@link GraknTx}. * * This controller also allows the retrieval of all {@link ai.grakn.Keyspace}s opened so far.

* * @author Filipe Peliz Pinto Teixeira */ public class SystemController implements HttpController { private static final String PROMETHEUS_CONTENT_TYPE = "text/plain; version=0.0.4"; private static final String PROMETHEUS = "prometheus"; private static final String JSON = "json"; private static final ObjectMapper objectMapper = new ObjectMapper(); private final Logger LOG = LoggerFactory.getLogger(SystemController.class); private final GraknEngineStatus graknEngineStatus; private final MetricRegistry metricRegistry; private final ObjectMapper mapper; private final CollectorRegistry prometheusRegistry; private final GraknKeyspaceStore graknKeyspaceStore; private final GraknConfig config; public SystemController(GraknConfig config, GraknKeyspaceStore graknKeyspaceStore, GraknEngineStatus graknEngineStatus, MetricRegistry metricRegistry) { this.graknKeyspaceStore = graknKeyspaceStore; this.config = config; this.graknEngineStatus = graknEngineStatus; this.metricRegistry = metricRegistry; DropwizardExports prometheusMetricWrapper = new DropwizardExports(metricRegistry); this.prometheusRegistry = new CollectorRegistry(); prometheusRegistry.register(prometheusMetricWrapper); final TimeUnit rateUnit = TimeUnit.SECONDS; final TimeUnit durationUnit = TimeUnit.SECONDS; final boolean showSamples = false; MetricFilter filter = MetricFilter.ALL; this.mapper = new ObjectMapper().registerModule( new MetricsModule(rateUnit, durationUnit, showSamples, filter)); } @Override public void start(Service spark) { spark.get(REST.WebPath.ROOT, this::getRoot); spark.get(REST.WebPath.KB, (req, res) -> getKeyspaces(res)); spark.get(REST.WebPath.KB_KEYSPACE, this::getKeyspace); spark.put(REST.WebPath.KB_KEYSPACE, this::putKeyspace); spark.delete(REST.WebPath.KB_KEYSPACE, this::deleteKeyspace); spark.get(REST.WebPath.METRICS, this::getMetrics); spark.get(REST.WebPath.STATUS, (req, res) -> getStatus()); spark.get(REST.WebPath.VERSION, (req, res) -> getVersion()); } @GET @Path(REST.WebPath.ROOT) private String getRoot(Request request, Response response) throws JsonProcessingException { // Handle root here for JSON, otherwise redirect to HTML page if (Requests.getAcceptType(request).equals(APPLICATION_JSON)) { return getJsonRoot(response); } else { return getIndexPage(); } } private String getJsonRoot(Response response) throws JsonProcessingException { response.type(APPLICATION_JSON); Root root = Root.create(); return objectMapper.writeValueAsString(root); } private String getIndexPage() { try { return new String(Files.readAllBytes(dashboardHtml()), Charsets.UTF_8); } catch (IOException e) { throw new RuntimeException(e); } } private java.nio.file.Path dashboardHtml() { return config.getPath(GraknConfigKey.STATIC_FILES_PATH).resolve("dashboard.html"); } @GET @Path(REST.WebPath.VERSION) private String getVersion() { return GraknVersion.VERSION; } @GET @Path(REST.WebPath.KB) private String getKeyspaces(Response response) throws JsonProcessingException { response.type(APPLICATION_JSON); Set keyspaces = graknKeyspaceStore.keyspaces().stream(). map(Keyspace::of). collect(Collectors.toSet()); return objectMapper.writeValueAsString(Keyspaces.of(keyspaces)); } @GET @Path("/kb/{keyspace}") private String getKeyspace(Request request, Response response) throws JsonProcessingException { response.type(APPLICATION_JSON); ai.grakn.Keyspace keyspace = ai.grakn.Keyspace.of(Requests.mandatoryPathParameter(request, KEYSPACE_PARAM)); if (graknKeyspaceStore.containsKeyspace(keyspace)) { response.status(HttpServletResponse.SC_OK); return objectMapper.writeValueAsString(Keyspace.of(keyspace)); } else { response.status(HttpServletResponse.SC_NOT_FOUND); return ""; } } @PUT @Path("/kb/{keyspace}") private String putKeyspace(Request request, Response response) throws JsonProcessingException { ai.grakn.Keyspace keyspace = ai.grakn.Keyspace.of(Requests.mandatoryPathParameter(request, KEYSPACE_PARAM)); graknKeyspaceStore.addKeyspace(keyspace); response.status(HttpServletResponse.SC_OK); response.type(APPLICATION_JSON); return objectMapper.writeValueAsString(config); } @DELETE @Path("/kb/{keyspace}") private boolean deleteKeyspace(Request request, Response response) { ai.grakn.Keyspace keyspace = ai.grakn.Keyspace.of(Requests.mandatoryPathParameter(request, KEYSPACE_PARAM)); boolean deletionComplete = graknKeyspaceStore.deleteKeyspace(keyspace); if (deletionComplete) { LOG.info("Keyspace {} deleted", keyspace); response.status(HttpServletResponse.SC_NO_CONTENT); return true; } else { throw GraknServerException.couldNotDelete(keyspace); } } @GET @Path("/status") private String getStatus() { return graknEngineStatus.isReady() ? "READY" : "INITIALIZING"; } @GET @Path("/metrics") private String getMetrics(Request request, Response response) throws IOException { response.header(CACHE_CONTROL, "must-revalidate,no-cache,no-store"); response.status(HttpServletResponse.SC_OK); Optional format = Optional.ofNullable(request.queryParams(FORMAT)); String dFormat = format.orElse(JSON); switch (dFormat) { case PROMETHEUS: // Prometheus format for the metrics response.type(PROMETHEUS_CONTENT_TYPE); final Writer writer1 = new StringWriter(); TextFormat.write004(writer1, this.prometheusRegistry.metricFamilySamples()); return writer1.toString(); case JSON: // Json/Dropwizard format response.type(APPLICATION_JSON); final ObjectWriter writer = mapper.writer(); try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { writer.writeValue(output, this.metricRegistry); return new String(output.toByteArray(), "UTF-8"); } default: throw GraknServerException.requestInvalidParameter(FORMAT, dFormat); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy