forked from community/device-mgt-core
commit
ed256ad346
@ -0,0 +1,338 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2021, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
~
|
||||
~ Entgra (Pvt) Ltd. licenses this file to you 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>grafana-mgt</artifactId>
|
||||
<version>5.0.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>io.entgra.analytics.mgt.grafana.proxy.api</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<name>Entgra - Grafana Proxy API</name>
|
||||
<description>Entgra - Grafana Proxy API</description>
|
||||
<url>http://entgra.io</url>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<packagingExcludes>WEB-INF/lib/*cxf*.jar</packagingExcludes>
|
||||
<warName>api#grafana-mgt#v1.0</warName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>deploy</id>
|
||||
<build>
|
||||
<defaultGoal>compile</defaultGoal>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.7</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<copy todir="${basedir}/../../../repository/deployment/server/webapps" overwrite="true">
|
||||
<fileset dir="${basedir}/target">
|
||||
<include name="api#grafana-mgt#v1.0.war" />
|
||||
</fileset>
|
||||
</copy>
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-bundle</artifactId>
|
||||
<version>3.0.0-milestone2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cxf</groupId>
|
||||
<artifactId>cxf-bundle-jaxrs</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-httpclient.wso2</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.utils</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.identity.framework</groupId>
|
||||
<artifactId>org.wso2.carbon.user.mgt</artifactId>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.logging</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.identity.inbound.auth.oauth2</groupId>
|
||||
<artifactId>org.wso2.carbon.identity.oauth.stub</artifactId>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.axis2.wso2</groupId>
|
||||
<artifactId>axis2-client</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.json.wso2</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec.wso2</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.certificate.mgt.core</artifactId>
|
||||
<scope>provided</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-jaxb-annotations</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.wso2.orbit.com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-jaxrs</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-jaxb-annotations</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.wso2.orbit.com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.orbit.com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>jsr311-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.commons</groupId>
|
||||
<artifactId>org.wso2.carbon.application.mgt.stub</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.analytics</groupId>
|
||||
<artifactId>org.wso2.carbon.analytics.api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.identity.jwt.client.extension</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.registry.core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.registry</groupId>
|
||||
<artifactId>org.wso2.carbon.registry.resource</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.identity.framework</groupId>
|
||||
<artifactId>org.wso2.carbon.identity.user.store.count</artifactId>
|
||||
<version>${carbon.identity.framework.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!--<dependency>-->
|
||||
<!--<groupId>org.wso2.carbon.analytics</groupId>-->
|
||||
<!--<artifactId>org.wso2.carbon.analytics.dataservice.commons</artifactId>-->
|
||||
<!--<scope>provided</scope>-->
|
||||
<!--</dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.analytics-common</groupId>
|
||||
<artifactId>org.wso2.carbon.event.receiver.stub</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.analytics-common</groupId>
|
||||
<artifactId>org.wso2.carbon.event.stream.stub</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.analytics-common</groupId>
|
||||
<artifactId>org.wso2.carbon.event.publisher.stub</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.analytics-common</groupId>
|
||||
<artifactId>org.wso2.carbon.event.stream.persistence.stub</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-module-testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-mockito</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.extensions</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.identity.framework</groupId>
|
||||
<artifactId>org.wso2.carbon.identity.claim.metadata.mgt</artifactId>
|
||||
<version>${carbon.identity.framework.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>io.entgra.analytics.mgt.grafana.proxy.core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>io.entgra.analytics.mgt.grafana.proxy.common</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (pvt) Ltd. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.api.service;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.Extension;
|
||||
import io.swagger.annotations.ExtensionProperty;
|
||||
import io.swagger.annotations.Info;
|
||||
import io.swagger.annotations.SwaggerDefinition;
|
||||
import io.swagger.annotations.Tag;
|
||||
import org.wso2.carbon.apimgt.annotations.api.Scope;
|
||||
import org.wso2.carbon.apimgt.annotations.api.Scopes;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
@SwaggerDefinition(
|
||||
info = @Info(
|
||||
version = "1.0.0",
|
||||
title = "Grafana API Proxy Service",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = "name", value = "GrafanaAPIManagement"),
|
||||
@ExtensionProperty(name = "context", value = "/api/grafana-mgt/v1.0/api"),
|
||||
})
|
||||
}
|
||||
),
|
||||
tags = {
|
||||
@Tag(name = "analytics_management", description = "")
|
||||
}
|
||||
)
|
||||
@Scopes(
|
||||
scopes = {
|
||||
@Scope(
|
||||
name = "Using Grafana APIs required for Grafana iframes",
|
||||
description = "Grafana API proxy to validate requests.",
|
||||
key = "perm:grafana:api:view",
|
||||
roles = {"Internal/grafanamgt-user"},
|
||||
permissions = {"/analytics-mgt/grafana-mgt/api/view"}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
@Path("/api")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.MEDIA_TYPE_WILDCARD)
|
||||
@Api(value = "Grafana API Management", description = "Grafana api related operations can be found here.")
|
||||
public interface GrafanaAPIProxyService {
|
||||
|
||||
String SCOPE = "scope";
|
||||
|
||||
@POST
|
||||
@Path("/ds/query")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "POST",
|
||||
value = "Grafana query API proxy",
|
||||
tags = "Analytics",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:grafana:api:view")
|
||||
})
|
||||
}
|
||||
)
|
||||
Response queryDatasource(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo);
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/frontend-metrics")
|
||||
@ApiOperation(
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "POST",
|
||||
value = "Grafana frontend-metric API proxy",
|
||||
tags = "Analytics",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:grafana:api:view")
|
||||
})
|
||||
}
|
||||
)
|
||||
Response frontendMetrics(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/dashboards/uid/{uid}")
|
||||
@ApiOperation(
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "POST",
|
||||
value = "Grafana dashboard details API proxy",
|
||||
tags = "Analytics",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:grafana:api:view")
|
||||
})
|
||||
}
|
||||
)
|
||||
Response getDashboard(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) throws ClassNotFoundException;
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/annotations")
|
||||
@ApiOperation(
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "GET",
|
||||
value = "Grafana annotations API proxy",
|
||||
tags = "Analytics",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:grafana:api:view")
|
||||
})
|
||||
}
|
||||
)
|
||||
Response getAnnotations(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) throws ClassNotFoundException;
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/alerts/states-for-dashboard")
|
||||
@ApiOperation(
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "POST",
|
||||
value = "Get Grafana alert states for dashboard details API proxy",
|
||||
tags = "Analytics",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:grafana:api:view")
|
||||
})
|
||||
}
|
||||
)
|
||||
Response getAlertStateForDashboards(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) throws ClassNotFoundException;
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (Pvt) Ltd. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.api.service.addons;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ApiOriginFilter implements Filter {
|
||||
|
||||
public void doFilter(ServletRequest request, ServletResponse response,
|
||||
FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletResponse res = (HttpServletResponse) response;
|
||||
res.addHeader("Access-Control-Allow-Origin", "*");
|
||||
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
|
||||
res.addHeader("Access-Control-Allow-Headers", "Content-Type");
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
//do nothing
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.api.service.addons;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.MultivaluedMap;
|
||||
import javax.ws.rs.ext.MessageBodyReader;
|
||||
import javax.ws.rs.ext.MessageBodyWriter;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
import java.io.*;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||
|
||||
@Provider
|
||||
@Produces(APPLICATION_JSON)
|
||||
@Consumes(APPLICATION_JSON)
|
||||
public class GsonMessageBodyHandler implements MessageBodyWriter<Object>, MessageBodyReader<Object> {
|
||||
|
||||
public static final String DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss Z";
|
||||
private Gson gson;
|
||||
private static final String UTF_8 = "UTF-8";
|
||||
|
||||
public boolean isReadable(Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private Gson getGson() {
|
||||
if (gson == null) {
|
||||
final GsonBuilder gsonBuilder = new GsonBuilder();
|
||||
gson = gsonBuilder.setDateFormat(DATE_FORMAT).create();
|
||||
}
|
||||
return gson;
|
||||
}
|
||||
|
||||
public Object readFrom(Class<Object> objectClass, Type type, Annotation[] annotations, MediaType mediaType,
|
||||
MultivaluedMap<String, String> stringStringMultivaluedMap, InputStream entityStream)
|
||||
throws IOException, WebApplicationException {
|
||||
|
||||
InputStreamReader reader = new InputStreamReader(entityStream, "UTF-8");
|
||||
|
||||
try {
|
||||
return getGson().fromJson(reader, type);
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isWriteable(Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public long getSize(Object o, Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void writeTo(Object object, Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType,
|
||||
MultivaluedMap<String, Object> stringObjectMultivaluedMap, OutputStream entityStream)
|
||||
throws IOException, WebApplicationException {
|
||||
|
||||
OutputStreamWriter writer = new OutputStreamWriter(entityStream, UTF_8);
|
||||
try {
|
||||
getGson().toJson(object, type, writer);
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
/* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (Pvt) Ltd. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.api.service.addons;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.cxf.interceptor.Fault;
|
||||
import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
|
||||
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
|
||||
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
|
||||
import org.apache.cxf.message.Message;
|
||||
import org.apache.cxf.message.MessageContentsList;
|
||||
import org.apache.cxf.phase.AbstractPhaseInterceptor;
|
||||
import org.apache.cxf.phase.Phase;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
import javax.validation.ValidatorFactory;
|
||||
import javax.validation.executable.ExecutableValidator;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ValidationInterceptor extends AbstractPhaseInterceptor<Message> {
|
||||
private Log log = LogFactory.getLog(getClass());
|
||||
private Validator validator = null; //validator interface is thread-safe
|
||||
|
||||
public ValidationInterceptor() {
|
||||
super(Phase.PRE_INVOKE);
|
||||
ValidatorFactory defaultFactory = Validation.buildDefaultValidatorFactory();
|
||||
validator = defaultFactory.getValidator();
|
||||
if (validator == null) {
|
||||
log.warn("Bean Validation provider could not be found, no validation will be performed");
|
||||
} else {
|
||||
log.debug("Validation In-Interceptor initialized successfully");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message message) throws Fault {
|
||||
final OperationResourceInfo operationResource = message.getExchange().get(OperationResourceInfo.class);
|
||||
if (operationResource == null) {
|
||||
log.info("OperationResourceInfo is not available, skipping validation");
|
||||
return;
|
||||
}
|
||||
|
||||
final ClassResourceInfo classResource = operationResource.getClassResourceInfo();
|
||||
if (classResource == null) {
|
||||
log.info("ClassResourceInfo is not available, skipping validation");
|
||||
return;
|
||||
}
|
||||
|
||||
final ResourceProvider resourceProvider = classResource.getResourceProvider();
|
||||
if (resourceProvider == null) {
|
||||
log.info("ResourceProvider is not available, skipping validation");
|
||||
return;
|
||||
}
|
||||
|
||||
final List<Object> arguments = MessageContentsList.getContentsList(message);
|
||||
final Method method = operationResource.getAnnotatedMethod();
|
||||
final Object instance = resourceProvider.getInstance(message);
|
||||
if (method != null && arguments != null) {
|
||||
//validate the parameters(arguments) over the invoked method
|
||||
validate(method, arguments.toArray(), instance);
|
||||
|
||||
//validate the fields of each argument
|
||||
for (Object arg : arguments) {
|
||||
if (arg != null)
|
||||
validate(arg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public <T> void validate(final Method method, final Object[] arguments, final T instance) {
|
||||
if (validator == null) {
|
||||
log.warn("Bean Validation provider could not be found, no validation will be performed");
|
||||
return;
|
||||
}
|
||||
|
||||
ExecutableValidator methodValidator = validator.forExecutables();
|
||||
Set<ConstraintViolation<T>> violations = methodValidator.validateParameters(instance,
|
||||
method, arguments);
|
||||
|
||||
if (!violations.isEmpty()) {
|
||||
throw new ConstraintViolationException(violations);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void validate(final T object) {
|
||||
if (validator == null) {
|
||||
log.warn("Bean Validation provider could be found, no validation will be performed");
|
||||
return;
|
||||
}
|
||||
|
||||
Set<ConstraintViolation<T>> violations = validator.validate(object);
|
||||
|
||||
if (!violations.isEmpty()) {
|
||||
throw new ConstraintViolationException(violations);
|
||||
}
|
||||
}
|
||||
|
||||
public void handleFault(org.apache.cxf.message.Message messageParam) {
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.api.service.bean;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel(description = "")
|
||||
public class ErrorListItem {
|
||||
|
||||
@NotNull
|
||||
private String code = null;
|
||||
@NotNull
|
||||
private String message = null;
|
||||
|
||||
@ApiModelProperty(required = true, value = "")
|
||||
@JsonProperty("code")
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public ErrorListItem() {}
|
||||
|
||||
public ErrorListItem(String code, String msg) {
|
||||
this.code = code;
|
||||
this.message = msg;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Description about individual errors occurred
|
||||
**/
|
||||
@ApiModelProperty(required = true, value = "Description about individual errors occurred")
|
||||
@JsonProperty("message")
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("errorItem {\n");
|
||||
|
||||
sb.append(" code: ").append(code).append("\n");
|
||||
sb.append(" message: ").append(message).append("\n");
|
||||
sb.append("}\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.api.service.bean;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel(description = "")
|
||||
public class ErrorResponse {
|
||||
|
||||
private Long code = null;
|
||||
private String message = null;
|
||||
private String description = null;
|
||||
private String moreInfo = null;
|
||||
private List<ErrorListItem> errorItems = new ArrayList<>();
|
||||
|
||||
public ErrorResponse() {
|
||||
}
|
||||
|
||||
@JsonProperty(value = "code")
|
||||
@ApiModelProperty(required = true, value = "")
|
||||
public Long getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(Long code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@JsonProperty(value = "message")
|
||||
@ApiModelProperty(required = true, value = "ErrorResponse message.")
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@JsonProperty(value = "description")
|
||||
@ApiModelProperty(value = "A detail description about the error message.")
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@JsonProperty(value = "moreInfo")
|
||||
@ApiModelProperty(value = "Preferably an url with more details about the error.")
|
||||
public String getMoreInfo() {
|
||||
return moreInfo;
|
||||
}
|
||||
|
||||
public void setMoreInfo(String moreInfo) {
|
||||
this.moreInfo = moreInfo;
|
||||
}
|
||||
|
||||
public void addErrorListItem(ErrorListItem item) {
|
||||
this.errorItems.add(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* If there are more than one error list them out. \nFor example, list out validation errors by each field.
|
||||
*/
|
||||
@JsonProperty(value = "errorItems")
|
||||
@ApiModelProperty(value = "If there are more than one error list them out. \n" +
|
||||
"For example, list out validation errors by each field.")
|
||||
public List<ErrorListItem> getErrorItems() {
|
||||
return errorItems;
|
||||
}
|
||||
|
||||
public void setErrorItems(List<ErrorListItem> error) {
|
||||
this.errorItems = error;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class ErrorResponseBuilder {
|
||||
|
||||
private Long code = null;
|
||||
private String message = null;
|
||||
private String description = null;
|
||||
private String moreInfo = null;
|
||||
private List<ErrorListItem> error;
|
||||
|
||||
|
||||
public ErrorResponseBuilder() {
|
||||
this.error = new ArrayList<>();
|
||||
}
|
||||
|
||||
public ErrorResponseBuilder setCode(long code) {
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ErrorResponseBuilder setMessage(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ErrorResponseBuilder setDescription(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ErrorResponseBuilder setMoreInfo(String moreInfo) {
|
||||
this.moreInfo = moreInfo;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ErrorResponseBuilder addErrorItem(String code, String msg) {
|
||||
ErrorListItem item = new ErrorListItem();
|
||||
item.setCode(code);
|
||||
item.setMessage(msg);
|
||||
this.error.add(item);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ErrorResponse build() {
|
||||
ErrorResponse errorResponse = new ErrorResponse();
|
||||
errorResponse.setCode(code);
|
||||
errorResponse.setMessage(message);
|
||||
errorResponse.setErrorItems(error);
|
||||
errorResponse.setDescription(description);
|
||||
errorResponse.setMoreInfo(moreInfo);
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
package io.entgra.analytics.mgt.grafana.proxy.api.service.exception;
|
||||
|
||||
public class RefererNotValid extends Exception {
|
||||
public RefererNotValid(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
package io.entgra.analytics.mgt.grafana.proxy.api.service.impl;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.api.service.GrafanaAPIProxyService;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.api.service.bean.ErrorResponse;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.api.service.exception.RefererNotValid;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.api.service.impl.util.GrafanaRequestHandlerUtil;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.bean.GrafanaPanelIdentifier;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.exception.MaliciousQueryAttempt;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.internal.GrafanaMgtDataHolder;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.util.GrafanaUtil;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
@Path("/api")
|
||||
public class GrafanaAPIProxyServiceImpl implements GrafanaAPIProxyService {
|
||||
|
||||
private static final Log log = LogFactory.getLog(GrafanaAPIProxyServiceImpl.class);
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/ds/query")
|
||||
@Override
|
||||
public Response queryDatasource(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo) {
|
||||
try {
|
||||
GrafanaPanelIdentifier panelIdentifier = GrafanaRequestHandlerUtil.getPanelIdentifier(headers);
|
||||
GrafanaMgtDataHolder.getInstance().getGrafanaQueryService().
|
||||
buildSafeQuery(body, panelIdentifier.getDashboardId(), panelIdentifier.getPanelId(), requestUriInfo.getRequestUri());
|
||||
return GrafanaRequestHandlerUtil.proxyPassPostRequest(body, requestUriInfo, panelIdentifier.getOrgId());
|
||||
} catch (MaliciousQueryAttempt e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(
|
||||
new ErrorResponse.ErrorResponseBuilder().setMessage(e.getMessage()).build()).build();
|
||||
} catch (GrafanaManagementException e) {
|
||||
return GrafanaRequestHandlerUtil.constructInternalServerError(e, e.getMessage());
|
||||
} catch (RefererNotValid e) {
|
||||
return GrafanaRequestHandlerUtil.constructInvalidReferer();
|
||||
} catch (SQLException | IOException | DBConnectionException |
|
||||
io.entgra.application.mgt.common.exception.DBConnectionException e) {
|
||||
log.error(e);
|
||||
return GrafanaRequestHandlerUtil.constructInternalServerError(e, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/frontend-metrics")
|
||||
@Override
|
||||
public Response frontendMetrics(JsonObject body, @Context HttpHeaders headers, @Context UriInfo requestUriInfo) {
|
||||
return proxyPassPostRequest(body, headers, requestUriInfo);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/dashboards/uid/{uid}")
|
||||
@Override
|
||||
public Response getDashboard(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) {
|
||||
return proxyPassGetRequest(headers, requestUriInfo);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/annotations")
|
||||
@Override
|
||||
public Response getAnnotations(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) {
|
||||
return proxyPassGetRequest(headers, requestUriInfo);
|
||||
}
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/alerts/states-for-dashboard")
|
||||
@Override
|
||||
public Response getAlertStateForDashboards(@Context HttpHeaders headers, @Context UriInfo requestUriInfo) {
|
||||
return proxyPassGetRequest(headers, requestUriInfo);
|
||||
}
|
||||
|
||||
public Response proxyPassGetRequest(HttpHeaders headers, UriInfo requestUriInfo) {
|
||||
try {
|
||||
GrafanaPanelIdentifier panelIdentifier = GrafanaRequestHandlerUtil.getPanelIdentifier(headers);
|
||||
return GrafanaRequestHandlerUtil.proxyPassGetRequest(requestUriInfo, panelIdentifier.getOrgId());
|
||||
} catch (RefererNotValid e) {
|
||||
return GrafanaRequestHandlerUtil.constructInvalidReferer();
|
||||
} catch (GrafanaManagementException e) {
|
||||
return GrafanaRequestHandlerUtil.constructInternalServerError(e, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public Response proxyPassPostRequest(JsonObject body, HttpHeaders headers, UriInfo requestUriInfo) {
|
||||
try {
|
||||
GrafanaPanelIdentifier panelIdentifier = GrafanaRequestHandlerUtil.getPanelIdentifier(headers);
|
||||
return GrafanaRequestHandlerUtil.proxyPassPostRequest(body, requestUriInfo, panelIdentifier.getOrgId());
|
||||
} catch (RefererNotValid e) {
|
||||
return GrafanaRequestHandlerUtil.constructInvalidReferer();
|
||||
} catch (GrafanaManagementException e) {
|
||||
return GrafanaRequestHandlerUtil.constructInternalServerError(e, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.api.service.impl.util;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.api.service.bean.ErrorResponse;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.api.service.exception.RefererNotValid;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.bean.GrafanaPanelIdentifier;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.exception.GrafanaEnvVariablesNotDefined;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.util.GrafanaConstants;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.util.GrafanaUtil;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.wso2.carbon.device.mgt.core.common.util.HttpUtil;
|
||||
import org.wso2.carbon.device.mgt.core.report.mgt.Constants;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GrafanaRequestHandlerUtil {
|
||||
|
||||
private static final Log log = LogFactory.getLog(GrafanaRequestHandlerUtil.class);
|
||||
|
||||
public static Response proxyPassGetRequest(UriInfo requestUriInfo, String orgId) throws GrafanaEnvVariablesNotDefined {
|
||||
HttpGet grafanaGetReq = new HttpGet();
|
||||
return forwardRequestToGrafanaEndpoint(grafanaGetReq, requestUriInfo, orgId);
|
||||
}
|
||||
|
||||
public static Response proxyPassPostRequest(JsonObject body, UriInfo requestUriInfo, String orgId)
|
||||
throws GrafanaEnvVariablesNotDefined {
|
||||
HttpPost grafanaPostReq = new HttpPost();
|
||||
try {
|
||||
setRequestEntity(grafanaPostReq, body);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
String errorMsg = "Error occurred while parsing body";
|
||||
log.error(errorMsg, e);
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(
|
||||
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMsg).build()).build();
|
||||
}
|
||||
return forwardRequestToGrafanaEndpoint(grafanaPostReq, requestUriInfo, orgId);
|
||||
}
|
||||
|
||||
private static Response forwardRequestToGrafanaEndpoint(HttpRequestBase requestBase, UriInfo requestUriInfo, String orgId)
|
||||
throws GrafanaEnvVariablesNotDefined {
|
||||
URI grafanaUri = generateGrafanaUri(requestUriInfo);
|
||||
requestBase.setURI(grafanaUri);
|
||||
requestBase.setHeader(GrafanaConstants.X_GRAFANA_ORG_ID_HEADER, orgId);
|
||||
try(CloseableHttpClient client = HttpClients.createDefault()) {
|
||||
HttpResponse grafanaResponse = invokeGrafanaAPI(client, requestBase);
|
||||
String grafanaResponseBody = HttpUtil.getResponseString(grafanaResponse);
|
||||
return Response.status(Response.Status.OK).entity(grafanaResponseBody).
|
||||
header(HttpHeaders.CONTENT_TYPE, HttpUtil.getContentType(grafanaResponse)).build();
|
||||
} catch (IOException e) {
|
||||
String msg = "Error occurred while calling Grafana API";
|
||||
log.error(msg, e);
|
||||
return Response.serverError().entity(
|
||||
new ErrorResponse.ErrorResponseBuilder().setMessage(msg).build()).build();
|
||||
} catch (GrafanaManagementException e) {
|
||||
String err = "Error occurred while retrieving Grafana configuration";
|
||||
log.error(err, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
|
||||
new ErrorResponse.ErrorResponseBuilder().setMessage(err).build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static HttpResponse invokeGrafanaAPI(HttpClient client, HttpRequestBase request) throws IOException, GrafanaManagementException {
|
||||
setBasicAuthHeader(request);
|
||||
return client.execute(request);
|
||||
}
|
||||
|
||||
public static void setBasicAuthHeader(HttpRequestBase request) throws GrafanaManagementException {
|
||||
String basicAuth = GrafanaUtil.getBasicAuthBase64Header();
|
||||
request.setHeader(HttpHeaders.AUTHORIZATION, basicAuth);
|
||||
}
|
||||
|
||||
public static URI generateGrafanaUri(UriInfo requestUriInfo) throws GrafanaEnvVariablesNotDefined {
|
||||
String base = GrafanaUtil.getGrafanaHTTPBase(requestUriInfo.getRequestUri().getScheme());
|
||||
String grafanaRequestPath = getGrafanaRequestPathWQuery(requestUriInfo);
|
||||
return HttpUtil.createURI(GrafanaUtil.generateGrafanaUrl(grafanaRequestPath, base));
|
||||
}
|
||||
|
||||
public static String getGrafanaRequestPathWQuery(UriInfo requestUriInfo) {
|
||||
String path = requestUriInfo.getPath();
|
||||
String queryParam = requestUriInfo.getRequestUri().getRawQuery();
|
||||
if (queryParam != null) {
|
||||
path += Constants.URI_QUERY_SEPARATOR + queryParam;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
public static GrafanaPanelIdentifier getPanelIdentifier(HttpHeaders headers) throws RefererNotValid {
|
||||
String referer = headers.getHeaderString(GrafanaConstants.REFERER_HEADER);
|
||||
if(referer == null) {
|
||||
String errMsg = "Request does not contain Referer header";
|
||||
log.error(errMsg);
|
||||
throw new RefererNotValid(errMsg);
|
||||
}
|
||||
GrafanaPanelIdentifier panelIdentifier = GrafanaUtil.getPanelIdentifierFromReferer(referer);
|
||||
if(panelIdentifier.getDashboardId() == null ||
|
||||
panelIdentifier.getPanelId() == null || panelIdentifier.getOrgId() == null) {
|
||||
String errMsg = "Referer must contain dashboardId, panelId and orgId";
|
||||
log.error(errMsg);
|
||||
throw new RefererNotValid(errMsg);
|
||||
}
|
||||
return panelIdentifier;
|
||||
}
|
||||
|
||||
public static void setRequestEntity(HttpPost postRequest, JsonObject body) throws UnsupportedEncodingException {
|
||||
StringEntity bodyEntity = new StringEntity(body.toString());
|
||||
bodyEntity.setContentType(MediaType.APPLICATION_JSON);
|
||||
postRequest.setEntity(bodyEntity);
|
||||
}
|
||||
|
||||
public static Response constructInvalidReferer() {
|
||||
String errorMsg = "Request does not contain a valid Referer header";
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(
|
||||
new ErrorResponse.ErrorResponseBuilder().setMessage(errorMsg).build()).build();
|
||||
}
|
||||
public static Response constructInternalServerError(Exception e, String errMsg) {
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
|
||||
new ErrorResponse.ErrorResponseBuilder().setMessage(errMsg).build()).build();
|
||||
}
|
||||
|
||||
public static void copyHeadersToGrafanaRequest(HttpRequestBase grafanaRequest, HttpHeaders headers) {
|
||||
Map<String, List<String>> headerValues = headers.getRequestHeaders();
|
||||
for (String key : headerValues.keySet()) {
|
||||
if (!key.equals(HttpHeaders.AUTHORIZATION) && !key.equals(HttpHeaders.CONTENT_LENGTH)) {
|
||||
for (String value : headerValues.get(key)) {
|
||||
grafanaRequest.setHeader(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||
~
|
||||
~ Entgra (pvt) Ltd. licenses this file to you 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.
|
||||
-->
|
||||
|
||||
<!-- This file contains the list of permissions that are associated with URL end points
|
||||
of the web app. Each permission should contain the name, permission path ,API path
|
||||
(URL) , HTTP method and OAUTH2 authorization scope (not-required).
|
||||
When defining dynamic paths for APIs, path variables are denoted by '*' notation.
|
||||
For ex:
|
||||
Actual API endpoint: devicemgt_admin/1.0.0/devices/{device-id}
|
||||
URL to be represented here: /devices/*
|
||||
NOTE: All the endpoints of the web app should be available in this file. Otherwise
|
||||
it will result 403 error at the runtime.
|
||||
-->
|
||||
<PermissionConfiguration>
|
||||
<APIVersion></APIVersion>
|
||||
</PermissionConfiguration>
|
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<!--
|
||||
* Copyright (c) 2019, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (Pvt) Ltd. licenses this file to you 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
This file defines class loading policy of the whole container. But this behaviour can be overridden by individual webapps by putting this file into the META-INF/ directory.
|
||||
-->
|
||||
<Classloading xmlns="http://wso2.org/projects/as/classloading">
|
||||
|
||||
<!-- Parent-first or child-first. Default behaviour is child-first.-->
|
||||
<ParentFirst>false</ParentFirst>
|
||||
|
||||
<!--
|
||||
Default environments that contains provides to all the webapps. This can be overridden by individual webapps by specifing required environments
|
||||
Tomcat environment is the default and every webapps gets it even if they didn't specify it.
|
||||
e.g. If a webapps requires CXF, they will get both Tomcat and CXF.
|
||||
-->
|
||||
<Environments>CXF3,Carbon</Environments>
|
||||
</Classloading>
|
@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2021, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
~
|
||||
~ Entgra (Pvt) Ltd. licenses this file to you 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.
|
||||
-->
|
||||
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
|
||||
|
||||
<jaxrs:server id="services" address="/">
|
||||
<jaxrs:serviceBeans>
|
||||
<ref bean="grafanaAPIProxyService"/>
|
||||
<ref bean="swaggerResource"/>
|
||||
</jaxrs:serviceBeans>
|
||||
<jaxrs:providers>
|
||||
<ref bean="jsonProvider"/>
|
||||
<ref bean="swaggerWriter"/>
|
||||
</jaxrs:providers>
|
||||
</jaxrs:server>
|
||||
|
||||
<bean id="swaggerConfig" class="io.swagger.jaxrs.config.BeanConfig">
|
||||
<property name="resourcePackage" value="io.entgra.analytics.mgt.grafana.proxy.api.service"/>
|
||||
<property name="version" value="1.0"/>
|
||||
<property name="host" value="localhost:9443"/>
|
||||
<property name="schemes" value="https" />
|
||||
<property name="basePath" value="/api/grafana-mgt/v1.0"/>
|
||||
<property name="title" value="Device Management Admin Service API Definitions"/>
|
||||
<property name="contact" value="dev@entgra.io"/>
|
||||
<property name="license" value="Apache 2.0"/>
|
||||
<property name="licenseUrl" value="http://www.apache.org/licenses/LICENSE-2.0.html"/>
|
||||
<property name="scan" value="true"/>
|
||||
</bean>
|
||||
|
||||
<bean id="grafanaAPIProxyService" class="io.entgra.analytics.mgt.grafana.proxy.api.service.impl.GrafanaAPIProxyServiceImpl"/>
|
||||
<bean id="swaggerWriter" class="io.swagger.jaxrs.listing.SwaggerSerializers" />
|
||||
<bean id="swaggerResource" class="io.swagger.jaxrs.listing.ApiListingResource" />
|
||||
<bean id="jsonProvider" class="io.entgra.analytics.mgt.grafana.proxy.api.service.addons.GsonMessageBodyHandler"/>
|
||||
<bean id="io.entgra.analytics.mgt.grafana.proxy.api.service.addons.ValidationInterceptor" class="io.entgra.analytics.mgt.grafana.proxy.api.service.addons.ValidationInterceptor"/>
|
||||
|
||||
<cxf:bus>
|
||||
<cxf:inInterceptors>
|
||||
<ref bean="io.entgra.analytics.mgt.grafana.proxy.api.service.addons.ValidationInterceptor"/>
|
||||
</cxf:inInterceptors>
|
||||
</cxf:bus>
|
||||
|
||||
</beans>
|
@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2021, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
~
|
||||
~ Entgra (Pvt) Ltd. licenses this file to you 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.
|
||||
-->
|
||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
|
||||
<display-name>Grafana-API-Proxy-Webapp</display-name>
|
||||
<servlet>
|
||||
<description>JAX-WS/JAX-RS Grafana API Management Endpoint</description>
|
||||
<display-name>JAX-WS/JAX-RS Servlet</display-name>
|
||||
<servlet-name>CXFServlet</servlet-name>
|
||||
<servlet-class>
|
||||
org.apache.cxf.transport.servlet.CXFServlet
|
||||
</servlet-class>
|
||||
<!-- configure a security filter -->
|
||||
<init-param>
|
||||
<param-name>swagger.security.filter</param-name>
|
||||
<param-value>ApiAuthorizationFilterImpl</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>CXFServlet</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
<session-config>
|
||||
<session-timeout>60</session-timeout>
|
||||
</session-config>
|
||||
|
||||
<context-param>
|
||||
<param-name>doAuthentication</param-name>
|
||||
<param-value>true</param-value>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<param-name>nonSecuredEndPoints</param-name>
|
||||
<param-value></param-value>
|
||||
</context-param>
|
||||
|
||||
<!--publish to apim-->
|
||||
<context-param>
|
||||
<param-name>managed-api-enabled</param-name>
|
||||
<param-value>true</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>managed-api-owner</param-name>
|
||||
<param-value>admin</param-value>
|
||||
</context-param>
|
||||
<context-param>
|
||||
<param-name>isSharedWithAllTenants</param-name>
|
||||
<param-value>true</param-value>
|
||||
</context-param>
|
||||
|
||||
<filter>
|
||||
<filter-name>ApiOriginFilter</filter-name>
|
||||
<filter-class>io.entgra.analytics.mgt.grafana.proxy.api.service.addons.ApiOriginFilter</filter-class>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>ApiOriginFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<filter>
|
||||
<filter-name>HttpHeaderSecurityFilter</filter-name>
|
||||
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
|
||||
<init-param>
|
||||
<param-name>hstsEnabled</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
|
||||
<filter>
|
||||
<filter-name>ContentTypeBasedCachePreventionFilter</filter-name>
|
||||
<filter-class>org.wso2.carbon.ui.filters.cache.ContentTypeBasedCachePreventionFilter</filter-class>
|
||||
<init-param>
|
||||
<param-name>patterns</param-name>
|
||||
<param-value>text/html" ,application/json" ,text/plain</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>filterAction</param-name>
|
||||
<param-value>enforce</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>httpHeaders</param-name>
|
||||
<param-value>Cache-Control: no-store, no-cache, must-revalidate, private</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>HttpHeaderSecurityFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>ContentTypeBasedCachePreventionFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
</web-app>
|
@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2021, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
~
|
||||
~ Entgra (Pvt) Ltd. licenses this file to you 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>grafana-mgt</artifactId>
|
||||
<version>5.0.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>io.entgra.analytics.mgt.grafana.proxy.common</artifactId>
|
||||
<packaging>bundle</packaging>
|
||||
<name>Entgra - Grafana API Handler Common</name>
|
||||
<description>Entgra - Grafana API Handler Common</description>
|
||||
<url>http://entgra.io</url>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||
<Bundle-Name>${project.artifactId}</Bundle-Name>
|
||||
<Bundle-Version>${carbon.device.mgt.version}</Bundle-Version>
|
||||
<Bundle-Description>Grafana Management Common Bundle</Bundle-Description>
|
||||
<Export-Package>
|
||||
io.entgra.analytics.mgt.grafana.proxy.common.*
|
||||
</Export-Package>
|
||||
<Import-Package>
|
||||
javax.xml.bind.annotation; version="${javax.xml.bind.imp.pkg.version}",
|
||||
com.fasterxml.jackson.annotation;version="${jackson-annotations.version}",
|
||||
io.swagger.annotations; version="${swagger.annotations.version}"; resolution:=optional,
|
||||
com.google.gson
|
||||
</Import-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>jacoco-initialize</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>jacoco-site</id>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
|
||||
<outputDirectory>${basedir}/target/coverage-reports/site</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.orbit.com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.common.exception;
|
||||
|
||||
public class GrafanaManagementException extends Exception{
|
||||
|
||||
private static final long serialVersionUID = -3922279312829079297L;
|
||||
|
||||
public GrafanaManagementException(String msg, Exception nestedEx) {
|
||||
super(msg, nestedEx);
|
||||
}
|
||||
public GrafanaManagementException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
@ -0,0 +1,329 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2021, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
~
|
||||
~ Entgra (Pvt) Ltd. licenses this file to you 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>grafana-mgt</artifactId>
|
||||
<version>5.0.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>io.entgra.analytics.mgt.grafana.proxy.core</artifactId>
|
||||
<packaging>bundle</packaging>
|
||||
<name>Entgra - Grafana API Handler Core</name>
|
||||
<description>Entgra - Grafana API Handler Core</description>
|
||||
<url>http://entgra.io</url>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-scr-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>jacoco-initialize</id>
|
||||
<goals>
|
||||
<goal>prepare-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>jacoco-site</id>
|
||||
<phase>test</phase>
|
||||
<goals>
|
||||
<goal>report</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
|
||||
<outputDirectory>${basedir}/target/coverage-reports/site</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||
<Bundle-Name>${project.artifactId}</Bundle-Name>
|
||||
<Bundle-Version>${carbon.device.mgt.version}</Bundle-Version>
|
||||
<Bundle-Description>Grafana API Management Core Bundle</Bundle-Description>
|
||||
<Private-Package>io.entgra.analytics.mgt.grafana.proxy.core.internal</Private-Package>
|
||||
<Import-Package>
|
||||
io.entgra.analytics.mgt.grafana.proxy.common.*,
|
||||
javax.xml.parsers;version="${javax.xml.parsers.import.pkg.version}";resolution:=optional,
|
||||
javax.xml.bind.annotation,
|
||||
javax.xml.bind,
|
||||
org.apache.commons.lang,
|
||||
org.wso2.carbon,
|
||||
org.wso2.carbon.device.mgt.common.*,
|
||||
org.wso2.carbon.device.mgt.core.*
|
||||
io.entgra.application.mgt.core.*
|
||||
</Import-Package>
|
||||
<Export-Package>
|
||||
!org.wso2.carbon.email.sender.core.internal,
|
||||
io.entgra.analytics.mgt.grafana.proxy.core.*
|
||||
</Export-Package>
|
||||
<Embed-Dependency>
|
||||
scribe;scope=compile|runtime;inline=false,
|
||||
</Embed-Dependency>
|
||||
<DynamicImport-Package>*</DynamicImport-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.osgi</groupId>
|
||||
<artifactId>org.eclipse.osgi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.osgi</groupId>
|
||||
<artifactId>org.eclipse.osgi.services</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.orbit.org.scannotation</groupId>
|
||||
<artifactId>scannotation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.utils</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.logging</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.core</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>io.entgra.analytics.mgt.grafana.proxy.common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>io.entgra.application.mgt.core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.wso2</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.1.1.wso2v1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.identity.jwt.client.extension</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>javax.ws.rs-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.ws.rs</groupId>
|
||||
<artifactId>jsr311-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-mockito</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.ndatasource.core</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec.wso2</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database.wso2</groupId>
|
||||
<artifactId>h2-database-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-module-testng</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.user.core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.user.api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.registry.api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.registry.core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat.wso2</groupId>
|
||||
<artifactId>jdbc-pool</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon</groupId>
|
||||
<artifactId>org.wso2.carbon.base</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.governance</groupId>
|
||||
<artifactId>org.wso2.carbon.governance.api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.axis2.transport</groupId>
|
||||
<artifactId>axis2-transport-mail</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.ws.commons.axiom.wso2</groupId>
|
||||
<artifactId>axiom</artifactId>
|
||||
</dependency>
|
||||
<!--dependency>
|
||||
<groupId>org.apache.ws.commons.axiom.wso2</groupId>
|
||||
<artifactId>axiom-impl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.ws.commons.axiom.wso2</groupId>
|
||||
<artifactId>axiom</artifactId>
|
||||
</dependency-->
|
||||
<dependency>
|
||||
<groupId>org.apache.axis2.wso2</groupId>
|
||||
<artifactId>axis2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.identity.inbound.auth.oauth2</groupId>
|
||||
<artifactId>org.wso2.carbon.identity.oauth.stub</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.tomcat</groupId>
|
||||
<artifactId>tomcat</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.tomcat</groupId>
|
||||
<artifactId>tomcat-servlet-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--Ntask dependencies-->
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.commons</groupId>
|
||||
<artifactId>org.wso2.carbon.ntask.core</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-collections.wso2</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.email.sender.core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>org.wso2.carbon.apimgt.annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.event-processing</groupId>
|
||||
<artifactId>org.wso2.carbon.event.processor.stub</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.multitenancy</groupId>
|
||||
<artifactId>org.wso2.carbon.tenant.mgt</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-validator</groupId>
|
||||
<artifactId>commons-validator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>io.entgra.server.bootup.heartbeat.beacon</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
||||
</project>
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.bean;
|
||||
|
||||
public class GrafanaPanelIdentifier {
|
||||
|
||||
private String orgId;
|
||||
private String dashboardUID;
|
||||
private String panelId;
|
||||
|
||||
public GrafanaPanelIdentifier(String orgId, String dashboardUID, String panelId) {
|
||||
this.orgId = orgId;
|
||||
this.dashboardUID = dashboardUID;
|
||||
this.panelId = panelId;
|
||||
}
|
||||
|
||||
public String getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(String orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getDashboardId() {
|
||||
return dashboardUID;
|
||||
}
|
||||
|
||||
public void setDashboardId(String dashboardId) {
|
||||
this.dashboardUID = dashboardId;
|
||||
}
|
||||
|
||||
public String getPanelId() {
|
||||
return panelId;
|
||||
}
|
||||
|
||||
public void setPanelId(String panelId) {
|
||||
this.panelId = panelId;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (Pvt) Ltd. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.config;
|
||||
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.config.xml.bean.CacheConfiguration;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.config.xml.bean.User;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import java.util.List;
|
||||
|
||||
@XmlRootElement(name = "GrafanaConfiguration")
|
||||
public class GrafanaConfiguration {
|
||||
|
||||
private User adminUser;
|
||||
private List<CacheConfiguration> caches;
|
||||
|
||||
@XmlElement(name = "AdminUser")
|
||||
public User getAdminUser() {
|
||||
return adminUser;
|
||||
}
|
||||
|
||||
public void setAdminUser(User user) {
|
||||
this.adminUser = user;
|
||||
}
|
||||
|
||||
|
||||
@XmlElementWrapper(name = "Cache")
|
||||
@XmlElement(name = "CacheConfiguration")
|
||||
public List<CacheConfiguration> getCaches() {
|
||||
return caches;
|
||||
}
|
||||
|
||||
public CacheConfiguration getCacheByName(String cacheName) {
|
||||
for (CacheConfiguration cache : caches) {
|
||||
if (cache.getName().equals(cacheName)) {
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setCaches(List<CacheConfiguration> caches) {
|
||||
this.caches = caches;
|
||||
}
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.config;
|
||||
|
||||
import io.entgra.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.util.GrafanaConstants;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.wso2.carbon.utils.CarbonUtils;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.io.File;
|
||||
|
||||
public class GrafanaConfigurationManager {
|
||||
|
||||
private static final Log log = LogFactory.getLog(GrafanaConfigurationManager.class);
|
||||
private static GrafanaConfigurationManager grafanaConfigurationManager;
|
||||
private GrafanaConfiguration grafanaConfiguration;
|
||||
private static final String GRAFANA_CONFIG_PATH = CarbonUtils.getCarbonConfigDirPath() + File.separator
|
||||
+ GrafanaConstants.CONFIG_XML_NAME;
|
||||
|
||||
public static GrafanaConfigurationManager getInstance() {
|
||||
if (grafanaConfigurationManager == null) {
|
||||
synchronized (GrafanaConfigurationManager.class) {
|
||||
if (grafanaConfigurationManager == null) {
|
||||
grafanaConfigurationManager = new GrafanaConfigurationManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
return grafanaConfigurationManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Grafana Configuration through the provided configuration location
|
||||
* @param configLocation has the path of the configuration file
|
||||
* @throws GrafanaManagementException throws when there are any errors during the initialization of
|
||||
* Grafana configuration
|
||||
*/
|
||||
public synchronized void initConfig(String configLocation) throws GrafanaManagementException {
|
||||
try {
|
||||
File smsConfig = new File(configLocation);
|
||||
Document doc = convertXMLToDocument(smsConfig);
|
||||
|
||||
/* Un-marshaling Grafana configuration */
|
||||
JAXBContext smsContext = JAXBContext.newInstance(GrafanaConfiguration.class);
|
||||
Unmarshaller unmarshaller = smsContext.createUnmarshaller();
|
||||
this.grafanaConfiguration = (GrafanaConfiguration) unmarshaller.unmarshal(doc);
|
||||
} catch (JAXBException e) {
|
||||
String msg = "Error occurred while initializing Grafana config '" + configLocation + "'";
|
||||
log.error(msg, e);
|
||||
throw new GrafanaManagementException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Grafana Configuration through the grafana-config.xml file in the GRAFANA_CONFIG_PATH
|
||||
* @throws GrafanaManagementException throws when there are any errors during the initialization of config
|
||||
*/
|
||||
public void initConfig() throws GrafanaManagementException {
|
||||
this.initConfig(GRAFANA_CONFIG_PATH);
|
||||
}
|
||||
|
||||
public GrafanaConfiguration getGrafanaConfiguration() throws GrafanaManagementException {
|
||||
if (grafanaConfiguration != null) {
|
||||
return grafanaConfiguration;
|
||||
}
|
||||
initConfig();
|
||||
return grafanaConfiguration;
|
||||
}
|
||||
|
||||
private static Document convertXMLToDocument(File file) throws GrafanaManagementException {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
try {
|
||||
factory.setFeature(GrafanaConstants.XML.FEATURES_DISALLOW_DOCTYPE_DECL, true);
|
||||
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||
DocumentBuilder docBuilder = factory.newDocumentBuilder();
|
||||
return docBuilder.parse(file);
|
||||
} catch (Exception e) {
|
||||
String errMsg = "Error occurred while parsing file, while converting to a org.w3c.dom.Document";
|
||||
log.error(errMsg, e);
|
||||
throw new GrafanaManagementException(errMsg, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (Pvt) Ltd. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.config.xml.bean;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
|
||||
public class CacheConfiguration {
|
||||
|
||||
private String name;
|
||||
private int capacity;
|
||||
|
||||
@XmlAttribute(name = "name")
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@XmlElement(name = "Capacity")
|
||||
public int getCapacity() {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setCapacity(int capacity) {
|
||||
this.capacity = capacity;
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.config.xml.bean;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
@XmlRootElement(name="AdminUser")
|
||||
public class User {
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
@XmlElement(name="Username")
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
@XmlElement(name="Password")
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.exception;
|
||||
|
||||
public class DashboardNotFound extends GrafanaAPIException {
|
||||
|
||||
private static final long serialVersionUID = -2111271331930066297L;
|
||||
|
||||
public DashboardNotFound(String errMsg) {
|
||||
super(errMsg);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.exception;
|
||||
|
||||
public class DatasourceNotFound extends GrafanaAPIException {
|
||||
|
||||
private static final long serialVersionUID = -3171333332936220227L;
|
||||
|
||||
public DatasourceNotFound(String errMsg) {
|
||||
super(errMsg);
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.exception;
|
||||
|
||||
import io.entgra.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
|
||||
|
||||
public class GrafanaAPIException extends GrafanaManagementException {
|
||||
|
||||
private static final long serialVersionUID = -3121249462130274227L;
|
||||
|
||||
public GrafanaAPIException(String errMsg) {
|
||||
super(errMsg);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.exception;
|
||||
|
||||
|
||||
import io.entgra.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
|
||||
|
||||
public class GrafanaEnvVariablesNotDefined extends GrafanaManagementException {
|
||||
|
||||
private static final long serialVersionUID = -3424429462350570237L;
|
||||
|
||||
public GrafanaEnvVariablesNotDefined(String errMsg) {
|
||||
super(errMsg);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.exception;
|
||||
|
||||
|
||||
import io.entgra.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
|
||||
|
||||
public class MaliciousQueryAttempt extends GrafanaManagementException {
|
||||
|
||||
private static final long serialVersionUID = -3171279331530570257L;
|
||||
|
||||
public MaliciousQueryAttempt(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public MaliciousQueryAttempt(String msg, Exception nestedException) {
|
||||
super(msg, nestedException);
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.exception;
|
||||
|
||||
public class PanelNotFound extends GrafanaAPIException {
|
||||
|
||||
private static final long serialVersionUID = -3471379441938070287L;
|
||||
public PanelNotFound(String errMsg) {
|
||||
super(errMsg);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.exception;
|
||||
|
||||
public class QueryMisMatch extends MaliciousQueryAttempt {
|
||||
|
||||
private static final long serialVersionUID = -3171277334737076294L;
|
||||
|
||||
public QueryMisMatch(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.exception;
|
||||
|
||||
public class QueryNotFound extends GrafanaAPIException {
|
||||
|
||||
private static final long serialVersionUID = -3151259311910070297L;
|
||||
public QueryNotFound(String errMsg) {
|
||||
super(errMsg);
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.exception;
|
||||
|
||||
public class TemplateNotFound extends GrafanaAPIException {
|
||||
|
||||
private static final long serialVersionUID = -3481878481835562209L;
|
||||
public TemplateNotFound(String errMsg) {
|
||||
super(errMsg);
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (pvt) Ltd. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.internal;
|
||||
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.GrafanaAPIService;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.GrafanaQueryService;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.impl.GrafanaAPIServiceImpl;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.impl.GrafanaQueryServiceImpl;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.service.component.ComponentContext;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
|
||||
/**
|
||||
* @scr.component name="io.entgra.analytics.mgt.grafana.proxy.grafanamanagementservicecomponent" immediate="true"
|
||||
*/
|
||||
public class GrafanaManagementServiceComponent {
|
||||
|
||||
private static Log log = LogFactory.getLog(GrafanaManagementServiceComponent.class);
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void activate(ComponentContext componentContext) {
|
||||
try {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Initializing grafana proxy management core bundle");
|
||||
}
|
||||
|
||||
BundleContext bundleContext = componentContext.getBundleContext();
|
||||
|
||||
GrafanaAPIService grafanaAPIService = new GrafanaAPIServiceImpl();
|
||||
GrafanaQueryService grafanaQueryService = new GrafanaQueryServiceImpl(grafanaAPIService);
|
||||
bundleContext.registerService(GrafanaAPIService.class.getName(), grafanaAPIService, null);
|
||||
GrafanaMgtDataHolder.getInstance().setGrafanaAPIService(grafanaAPIService);
|
||||
bundleContext.registerService(GrafanaQueryService.class.getName(), grafanaQueryService, null);
|
||||
GrafanaMgtDataHolder.getInstance().setGrafanaQueryService(grafanaQueryService);
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Grafana management core bundle has been successfully initialized");
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
log.error("Error occurred while initializing grafana management core bundle", e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void deactivate(ComponentContext componentContext) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("De-activating Grafana Management Service Component");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (pvt) Ltd. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.internal;
|
||||
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.GrafanaAPIService;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.GrafanaQueryService;
|
||||
|
||||
public class GrafanaMgtDataHolder {
|
||||
|
||||
private GrafanaAPIService grafanaAPIService;
|
||||
private GrafanaQueryService grafanaQueryService;
|
||||
|
||||
private GrafanaMgtDataHolder() {
|
||||
|
||||
}
|
||||
|
||||
public GrafanaAPIService getGrafanaAPIService() {
|
||||
return grafanaAPIService;
|
||||
}
|
||||
|
||||
public void setGrafanaAPIService(GrafanaAPIService grafanaAPIService) {
|
||||
this.grafanaAPIService = grafanaAPIService;
|
||||
}
|
||||
|
||||
public GrafanaQueryService getGrafanaQueryService() {
|
||||
return grafanaQueryService;
|
||||
}
|
||||
|
||||
public void setGrafanaQueryService(GrafanaQueryService grafanaQueryService) {
|
||||
this.grafanaQueryService = grafanaQueryService;
|
||||
}
|
||||
|
||||
public static class InstanceHolder {
|
||||
public static GrafanaMgtDataHolder instance = new GrafanaMgtDataHolder();
|
||||
}
|
||||
|
||||
public static GrafanaMgtDataHolder getInstance() {
|
||||
return InstanceHolder.instance;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.service;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.bean.Datasource;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface GrafanaAPIService {
|
||||
|
||||
/**
|
||||
* Get predefined query template from grafana for given panel/variable
|
||||
* @param dashboardUID
|
||||
* @param panelId
|
||||
* @param refId
|
||||
* @param requestScheme
|
||||
* @return query of the given panel/variable
|
||||
* @throws IOException
|
||||
* @throws GrafanaManagementException
|
||||
*/
|
||||
String getQueryTemplate(String dashboardUID, String panelId, String refId,
|
||||
String requestScheme) throws IOException, GrafanaManagementException;
|
||||
|
||||
/**
|
||||
* Get panel details by dashboard uid and panel Id
|
||||
* @param dashboardUID
|
||||
* @param panelId
|
||||
* @param requestScheme
|
||||
* @return Panel details
|
||||
* @throws IOException
|
||||
* @throws GrafanaManagementException
|
||||
*/
|
||||
JsonObject getPanelDetails(String dashboardUID, String panelId, String requestScheme) throws
|
||||
IOException, GrafanaManagementException;
|
||||
|
||||
/**
|
||||
* Get dashboard details by uid
|
||||
* @param dashboardUID
|
||||
* @param requestScheme
|
||||
* @return Dashboard details
|
||||
* @throws IOException
|
||||
* @throws GrafanaManagementException
|
||||
*/
|
||||
JsonObject getDashboardDetails(String dashboardUID, String requestScheme) throws IOException,
|
||||
GrafanaManagementException;
|
||||
|
||||
/**
|
||||
* Get datasource details by id
|
||||
* @param datasourceId
|
||||
* @param requestScheme
|
||||
* @return Datasource details
|
||||
* @throws IOException
|
||||
* @throws GrafanaManagementException
|
||||
*/
|
||||
Datasource getDatasource(int datasourceId, String requestScheme) throws IOException,
|
||||
GrafanaManagementException;
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.service;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
|
||||
import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public interface GrafanaQueryService {
|
||||
|
||||
void buildSafeQuery(JsonObject queryRequestBody, String dashboardUID, String panelId,
|
||||
URI requestUri) throws IOException, SQLException, GrafanaManagementException,
|
||||
DBConnectionException, io.entgra.application.mgt.common.exception.DBConnectionException;
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.service.bean;
|
||||
|
||||
public class Datasource {
|
||||
private int id;
|
||||
private String url;
|
||||
private String name;
|
||||
private String type;
|
||||
private String database;
|
||||
|
||||
public Datasource(int id, String url, String name, String type, String database) {
|
||||
this.id = id;
|
||||
this.url = url;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
public void setDatabase(String database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (Pvt) Ltd. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.service.cache;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.config.GrafanaConfiguration;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.config.GrafanaConfigurationManager;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.config.xml.bean.CacheConfiguration;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.bean.Datasource;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.util.GrafanaConstants;
|
||||
import org.apache.juli.logging.Log;
|
||||
import org.apache.juli.logging.LogFactory;
|
||||
|
||||
public class CacheManager {
|
||||
private static final Log log = LogFactory.getLog(CacheManager.class);
|
||||
|
||||
private Cache<Integer, Datasource> datasourceAPICache;
|
||||
private Cache<QueryTemplateCacheKey, String> queryTemplateAPICache;
|
||||
private Cache<String, String> encodedQueryCache;
|
||||
|
||||
private CacheManager() {
|
||||
initCache();
|
||||
}
|
||||
|
||||
private static final class CacheManagerHolder {
|
||||
static final CacheManager cacheManager = new CacheManager();
|
||||
}
|
||||
|
||||
public static CacheManager getInstance() {
|
||||
return CacheManagerHolder.cacheManager;
|
||||
}
|
||||
|
||||
public Cache<String, String> getEncodedQueryCache() {
|
||||
return encodedQueryCache;
|
||||
}
|
||||
|
||||
public Cache<QueryTemplateCacheKey, String> getQueryTemplateAPICache() {
|
||||
return queryTemplateAPICache;
|
||||
}
|
||||
|
||||
|
||||
public Cache<Integer, Datasource> getDatasourceAPICache() {
|
||||
return datasourceAPICache;
|
||||
}
|
||||
|
||||
|
||||
private void initCache() {
|
||||
this.datasourceAPICache = buildDatasourceCache();
|
||||
this.queryTemplateAPICache = buildQueryCacheByName(GrafanaConstants.QUERY_API_CACHE_NAME);
|
||||
this.encodedQueryCache = buildQueryCacheByName(GrafanaConstants.ENCODED_QUERY_CACHE_NAME);
|
||||
}
|
||||
|
||||
private <K, V> Cache<K, V> buildDatasourceCache() {
|
||||
return CacheBuilder.newBuilder().build();
|
||||
}
|
||||
|
||||
private <K , V> Cache<K, V> buildQueryCacheByName(String cacheName) {
|
||||
int capacity = getCacheCapacity(cacheName);
|
||||
return CacheBuilder.newBuilder().maximumSize(capacity).build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static int getCacheCapacity(String cacheName) {
|
||||
try {
|
||||
GrafanaConfiguration configuration = GrafanaConfigurationManager.getInstance().getGrafanaConfiguration();
|
||||
CacheConfiguration cacheConfig = configuration.getCacheByName(cacheName);
|
||||
if (cacheConfig == null) {
|
||||
log.error("CacheConfiguration config not defined for " + cacheName);
|
||||
throw new GrafanaManagementException("Query API CacheConfiguration configuration not properly defined");
|
||||
}
|
||||
return cacheConfig.getCapacity();
|
||||
} catch (GrafanaManagementException e) {
|
||||
String errMsg = "Error occurred while initializing cache capacity for " + cacheName;
|
||||
log.error(errMsg);
|
||||
throw new RuntimeException(errMsg, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (Pvt) Ltd. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.service.cache;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class QueryTemplateCacheKey {
|
||||
|
||||
private final String dashboardUID;
|
||||
private final String panelId;
|
||||
private final String refId;
|
||||
private volatile int hashCode;
|
||||
|
||||
public QueryTemplateCacheKey(String dashboardUID, String panelId, String refId) {
|
||||
this.dashboardUID = dashboardUID;
|
||||
this.panelId = panelId;
|
||||
this.refId = refId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof QueryTemplateCacheKey) {
|
||||
final QueryTemplateCacheKey other = (QueryTemplateCacheKey) obj;
|
||||
String thisId = this.dashboardUID + this.panelId + this.refId;
|
||||
String otherId = other.dashboardUID + other.panelId + other.refId;
|
||||
return thisId.equals(otherId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (hashCode == 0) {
|
||||
hashCode = Objects.hash(dashboardUID, panelId, refId);
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
}
|
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.service.impl;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.exception.DashboardNotFound;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.exception.DatasourceNotFound;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.exception.GrafanaEnvVariablesNotDefined;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.exception.PanelNotFound;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.exception.QueryNotFound;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.exception.TemplateNotFound;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.GrafanaAPIService;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.bean.Datasource;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.cache.CacheManager;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.cache.QueryTemplateCacheKey;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.util.GrafanaConstants;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.util.GrafanaUtil;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.wso2.carbon.device.mgt.core.common.util.HttpUtil;
|
||||
import org.wso2.carbon.device.mgt.core.report.mgt.Constants;
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import java.io.IOException;
|
||||
|
||||
public class GrafanaAPIServiceImpl implements GrafanaAPIService {
|
||||
|
||||
private static final Log log = LogFactory.getLog(GrafanaAPIServiceImpl.class);
|
||||
|
||||
public String getQueryTemplate(String dashboardUID, String panelId, String refId,
|
||||
String requestScheme) throws IOException, GrafanaManagementException {
|
||||
try {
|
||||
return getPanelQuery(dashboardUID, panelId, refId, requestScheme);
|
||||
} catch (QueryNotFound e) {
|
||||
return getTemplateQuery(dashboardUID, refId, requestScheme);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get predefined query template from grafana for given panel
|
||||
* @param dashboardUID
|
||||
* @param panelId
|
||||
* @param refId
|
||||
* @param requestScheme
|
||||
* @return query of the given panel
|
||||
* @throws IOException
|
||||
* @throws GrafanaManagementException
|
||||
*/
|
||||
public String getPanelQuery(String dashboardUID, String panelId, String refId,
|
||||
String requestScheme) throws IOException, GrafanaManagementException {
|
||||
JsonObject panel = getPanelDetails(dashboardUID, panelId, requestScheme);
|
||||
JsonArray queries = panel.getAsJsonArray(GrafanaConstants.DASHBOARD_PANEL_DETAIL_QUERIES_KEY);
|
||||
JsonObject query = getQueryByRefId(queries, refId);
|
||||
if (query == null) {
|
||||
throw new QueryNotFound("No query exists for {dashboard: " + dashboardUID +
|
||||
", panelId: " + panelId + ", refId: " + refId + "}");
|
||||
}
|
||||
String queryTemplate = query.get(GrafanaConstants.RAW_SQL_KEY).getAsString();
|
||||
CacheManager.getInstance().getQueryTemplateAPICache().
|
||||
put(new QueryTemplateCacheKey(dashboardUID, panelId, refId), queryTemplate);
|
||||
return queryTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get predefined query template from grafana for given variable (template variable)
|
||||
* Note: Here template query means the grafana template variable queries
|
||||
* @param dashboardUID
|
||||
* @param refId
|
||||
* @param requestScheme
|
||||
* @return query of grafana template variable
|
||||
* @throws IOException
|
||||
* @throws GrafanaManagementException
|
||||
*/
|
||||
// Here template query means the grafana template variable queries
|
||||
public String getTemplateQuery(String dashboardUID, String refId,
|
||||
String requestScheme) throws IOException, GrafanaManagementException {
|
||||
JsonObject template = getTemplatingDetails(dashboardUID, refId, requestScheme);
|
||||
JsonElement queryElement = template.get(GrafanaConstants.TEMPLATE_QUERY_KEY);
|
||||
if (queryElement == null) {
|
||||
throw new QueryNotFound("No template query exists for {dashboard: " + dashboardUID +
|
||||
", refId: " + refId + "}");
|
||||
}
|
||||
String query = queryElement.getAsString();
|
||||
CacheManager.getInstance().getQueryTemplateAPICache().
|
||||
put(new QueryTemplateCacheKey(dashboardUID, null, refId), query);
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get grafana template variable details of given dashboard uid
|
||||
* @param dashboardUID
|
||||
* @param refId
|
||||
* @param requestScheme
|
||||
* @return Template variable details of given dashboard uid
|
||||
* @throws IOException
|
||||
* @throws GrafanaManagementException
|
||||
*/
|
||||
public JsonObject getTemplatingDetails(String dashboardUID, String refId, String requestScheme) throws
|
||||
IOException, GrafanaManagementException {
|
||||
JsonObject dashboard = getDashboardDetails(dashboardUID, requestScheme);
|
||||
JsonObject template = getTemplateByRefId(dashboard, refId);
|
||||
if (template == null) {
|
||||
String errorMsg = "Template for {refId: " + refId + ", dashboard: " + dashboardUID + "} is not found";
|
||||
log.error(errorMsg);
|
||||
throw new TemplateNotFound(errorMsg);
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
public JsonObject getPanelDetails(String dashboardUID, String panelId, String requestScheme) throws
|
||||
IOException, GrafanaManagementException {
|
||||
JsonObject dashboard = getDashboardDetails(dashboardUID, requestScheme);
|
||||
JsonObject panel = getPanelById(dashboard, panelId);
|
||||
if (panel == null) {
|
||||
String errorMsg = "Panel " + panelId + " for dashboard " + dashboardUID + " is not found";
|
||||
log.error(errorMsg);
|
||||
throw new PanelNotFound(errorMsg);
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
public JsonObject getDashboardDetails(String dashboardUID, String requestScheme) throws IOException,
|
||||
GrafanaManagementException {
|
||||
String dashboardAPI = generateGrafanaAPIBaseUri(GrafanaConstants.DASHBOARD_API, requestScheme) + dashboardUID;
|
||||
HttpGet request = new HttpGet(dashboardAPI);
|
||||
JsonObject dashboardResponseJsonBody = getGrafanaAPIJsonResponse(request);
|
||||
JsonObject dashboardDetails = dashboardResponseJsonBody.getAsJsonObject(GrafanaConstants.DASHBOARD_KEY);
|
||||
if (dashboardDetails == null) {
|
||||
throw new DashboardNotFound("Grafana response: " + dashboardResponseJsonBody);
|
||||
}
|
||||
return dashboardResponseJsonBody.getAsJsonObject(GrafanaConstants.DASHBOARD_KEY);
|
||||
}
|
||||
|
||||
public Datasource getDatasource(int datasourceId, String requestScheme) throws IOException, GrafanaManagementException {
|
||||
String datasourceAPI = generateGrafanaAPIBaseUri(GrafanaConstants.DATASOURCE_API, requestScheme) + datasourceId;
|
||||
HttpGet request = new HttpGet(datasourceAPI);
|
||||
JsonObject datasourceDetails = getGrafanaAPIJsonResponse(request);
|
||||
if (datasourceDetails.get(GrafanaConstants.DATASOURCE_NAME_KEY) == null) {
|
||||
throw new DatasourceNotFound("Grafana response: " + datasourceDetails);
|
||||
}
|
||||
String url = datasourceDetails.get(GrafanaConstants.DATASOURCE_URL_KEY).getAsString();
|
||||
String name = datasourceDetails.get(GrafanaConstants.DATASOURCE_NAME_KEY).getAsString();
|
||||
String type = datasourceDetails.get(GrafanaConstants.DATASOURCE_TYPE_KEY).getAsString();
|
||||
String database = datasourceDetails.get(GrafanaConstants.DATASOURCE_DB_KEY).getAsString();
|
||||
Datasource ds = new Datasource(datasourceId, url, name, type, database);
|
||||
CacheManager.getInstance().getDatasourceAPICache().put(datasourceId, ds);
|
||||
return ds;
|
||||
}
|
||||
|
||||
private String generateGrafanaAPIBaseUri(String api, String requestScheme) throws GrafanaEnvVariablesNotDefined {
|
||||
return GrafanaUtil.getGrafanaHTTPBase(requestScheme) + api + Constants.URI_SEPARATOR;
|
||||
}
|
||||
|
||||
|
||||
private JsonObject getGrafanaAPIJsonResponse(HttpRequestBase request) throws IOException,
|
||||
GrafanaManagementException {
|
||||
try(CloseableHttpClient client = HttpClients.createDefault()) {
|
||||
HttpResponse response = invokeAPI(client, request);
|
||||
return GrafanaUtil.getJsonBody(HttpUtil.getResponseString(response));
|
||||
}
|
||||
}
|
||||
|
||||
private HttpResponse invokeAPI(HttpClient client, HttpRequestBase request) throws IOException, GrafanaManagementException {
|
||||
setBasicAuthHeader(request);
|
||||
return client.execute(request);
|
||||
}
|
||||
|
||||
private void setBasicAuthHeader(HttpRequestBase request) throws GrafanaManagementException {
|
||||
String basicAuth = GrafanaUtil.getBasicAuthBase64Header();
|
||||
request.setHeader(HttpHeaders.AUTHORIZATION, basicAuth);
|
||||
}
|
||||
|
||||
private JsonObject getQueryByRefId(JsonArray queries, String refId) {
|
||||
for (int i = 0; i < queries.size(); i++) {
|
||||
JsonObject query = queries.get(i).getAsJsonObject();
|
||||
String queryRefId = query.get(GrafanaConstants.QUERY_REF_ID_KEY).getAsString();
|
||||
if (queryRefId.equals(refId)) {
|
||||
return query;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private JsonObject getTemplateByRefId(JsonObject dashboard, String refId) {
|
||||
JsonArray templates = dashboard.getAsJsonObject(GrafanaConstants.TEMPLATING_KEY).
|
||||
getAsJsonArray(GrafanaConstants.TEMPLATING_LIST_KEY);
|
||||
for (int i = 0; i < templates.size(); i++) {
|
||||
JsonObject templateObj = templates.get(i).getAsJsonObject();
|
||||
String name = templateObj.get(GrafanaConstants.TEMPLATING_NAME_KEY).getAsString();
|
||||
// RefId in query body corresponds to template name
|
||||
if (refId.equals(name)) {
|
||||
return templateObj;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private JsonObject getPanelById(JsonObject dashboard, String panelId) {
|
||||
JsonArray panels = dashboard.getAsJsonArray(GrafanaConstants.PANEL_KEY);
|
||||
for (int i = 0; i < panels.size(); i++) {
|
||||
JsonObject panelObj = panels.get(i).getAsJsonObject();
|
||||
String id = panelObj.get(GrafanaConstants.ID_KEY).getAsString();
|
||||
if (id.equals(panelId)) {
|
||||
return panelObj;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.service.impl;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.exception.MaliciousQueryAttempt;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.exception.QueryMisMatch;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.exception.QueryNotFound;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.GrafanaAPIService;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.GrafanaQueryService;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.bean.Datasource;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.cache.CacheManager;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.cache.QueryTemplateCacheKey;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.sql.query.GrafanaPreparedQueryBuilder;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.sql.query.PreparedQuery;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.sql.query.encoder.QueryEncoderFactory;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.util.GrafanaConstants;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class GrafanaQueryServiceImpl implements GrafanaQueryService {
|
||||
|
||||
private static final Log log = LogFactory.getLog(GrafanaQueryServiceImpl.class);
|
||||
private final GrafanaAPIService grafanaAPIService;
|
||||
|
||||
public GrafanaQueryServiceImpl(GrafanaAPIService grafanaAPIService) {
|
||||
this.grafanaAPIService = grafanaAPIService;
|
||||
}
|
||||
|
||||
public void buildSafeQuery(JsonObject queryRequestBody, String dashboardUID, String panelId, URI requestUri)
|
||||
throws IOException, SQLException, GrafanaManagementException, DBConnectionException, io.entgra.application.mgt.common.exception.DBConnectionException {
|
||||
JsonArray queries = queryRequestBody.getAsJsonArray(GrafanaConstants.QUERY_BODY_QUERIES_KEY);
|
||||
for (int i = 0; i < queries.size(); i++) {
|
||||
JsonObject queryObj = queries.get(i).getAsJsonObject();
|
||||
JsonElement refIdJson = queryObj.get(GrafanaConstants.QUERY_REF_ID_KEY);
|
||||
JsonElement rawSqlJson = queryObj.get(GrafanaConstants.RAW_SQL_KEY);
|
||||
JsonElement datasourceIdJson = queryObj.get(GrafanaConstants.DATASOURCE_ID_KEY);
|
||||
if (refIdJson == null || rawSqlJson == null || datasourceIdJson == null) {
|
||||
String errMsg = "Query json body: refId, rawSql and datasourceId cannot be null";
|
||||
log.error(errMsg);
|
||||
throw new MaliciousQueryAttempt(errMsg);
|
||||
}
|
||||
String refId = refIdJson.getAsString();
|
||||
String rawSql = rawSqlJson.getAsString();
|
||||
int datasourceId = datasourceIdJson.getAsInt();
|
||||
CacheManager cacheManager = CacheManager.getInstance();
|
||||
String encodedQuery = cacheManager.getEncodedQueryCache().getIfPresent(rawSql);
|
||||
if (cacheManager.getEncodedQueryCache().getIfPresent(rawSql) != null) {
|
||||
queryObj.addProperty(GrafanaConstants.RAW_SQL_KEY, encodedQuery);
|
||||
return;
|
||||
}
|
||||
Datasource datasource = cacheManager.getDatasourceAPICache().getIfPresent(datasourceId);
|
||||
if (datasource == null) {
|
||||
datasource = grafanaAPIService.getDatasource(datasourceId, requestUri.getScheme());
|
||||
}
|
||||
String queryTemplate = cacheManager.getQueryTemplateAPICache().
|
||||
getIfPresent(new QueryTemplateCacheKey(dashboardUID, panelId, refId));
|
||||
try {
|
||||
if (queryTemplate != null) {
|
||||
try {
|
||||
encodeQuery(queryObj, datasource, queryTemplate, rawSql);
|
||||
} catch (QueryMisMatch e) {
|
||||
log.error("Error occurred while encoding query, " +
|
||||
"retrying to encode by getting the query template from api instead of cache", e);
|
||||
queryTemplate = grafanaAPIService.getQueryTemplate(dashboardUID, panelId, refId, requestUri.getScheme());
|
||||
encodeQuery(queryObj, datasource, queryTemplate, rawSql);
|
||||
}
|
||||
} else {
|
||||
queryTemplate = grafanaAPIService.getQueryTemplate(dashboardUID, panelId, refId, requestUri.getScheme());
|
||||
encodeQuery(queryObj, datasource, queryTemplate, rawSql);
|
||||
}
|
||||
} catch (QueryNotFound e) {
|
||||
String errMsg = "No query exists for {dashboard: " + dashboardUID +
|
||||
", panelId: " + panelId + ", refId: " + refId + "}";
|
||||
log.error(errMsg);
|
||||
throw new QueryNotFound(errMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void encodeQuery(JsonObject queryObj, Datasource datasource, String queryTemplate, String rawSql)
|
||||
throws SQLException, GrafanaManagementException, DBConnectionException,
|
||||
io.entgra.application.mgt.common.exception.DBConnectionException {
|
||||
PreparedQuery pq = GrafanaPreparedQueryBuilder.build(queryTemplate, rawSql);
|
||||
String encodedQuery = QueryEncoderFactory.createEncoder(datasource.getType(), datasource.getName()).encode(pq);
|
||||
CacheManager.getInstance().getEncodedQueryCache().put(rawSql, encodedQuery);
|
||||
if(log.isDebugEnabled()) {
|
||||
log.debug("Encoded query: " + encodedQuery);
|
||||
}
|
||||
queryObj.addProperty(GrafanaConstants.RAW_SQL_KEY, encodedQuery);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package io.entgra.analytics.mgt.grafana.proxy.core.sql.connection;
|
||||
|
||||
import io.entgra.application.mgt.core.config.Configuration;
|
||||
import io.entgra.application.mgt.core.config.ConfigurationManager;
|
||||
import io.entgra.application.mgt.core.util.ConnectionManagerUtil;
|
||||
import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException;
|
||||
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
|
||||
import org.wso2.carbon.device.mgt.core.config.DeviceManagementConfig;
|
||||
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
|
||||
import org.wso2.carbon.device.mgt.core.report.mgt.config.ReportMgtConfiguration;
|
||||
import org.wso2.carbon.device.mgt.core.report.mgt.config.ReportMgtConfigurationManager;
|
||||
import org.wso2.carbon.device.mgt.core.report.mgt.dao.common.ReportMgtConnectionManager;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class GrafanaDatasourceConnectionFactory {
|
||||
|
||||
private static final ReportMgtConfiguration reportMgtConfiguration= ReportMgtConfigurationManager.getInstance().
|
||||
getConfiguration();
|
||||
private static final DeviceManagementConfig deviceManagementConfig = DeviceConfigurationManager.getInstance().
|
||||
getDeviceManagementConfig();
|
||||
|
||||
private static final Configuration applicationMgtConfig = ConfigurationManager.getInstance().getConfiguration();
|
||||
|
||||
public static Connection getConnection(String databaseName) throws SQLException, DBConnectionException,
|
||||
io.entgra.application.mgt.common.exception.DBConnectionException {
|
||||
if(databaseName.equals(getReportManagementDatasourceName())) {
|
||||
ReportMgtConnectionManager.openDBConnection();
|
||||
return ReportMgtConnectionManager.getDBConnection();
|
||||
} else if (databaseName.equals(getDeviceManagementDatasourceName())) {
|
||||
DeviceManagementDAOFactory.openConnection();
|
||||
return DeviceManagementDAOFactory.getConnection();
|
||||
} else if (databaseName.equals(getApplicationManagementDatasourceName())) {
|
||||
ConnectionManagerUtil.openDBConnection();
|
||||
return ConnectionManagerUtil.getDBConnection();
|
||||
} else {
|
||||
throw new RuntimeException("No such datasource with the name: " + databaseName);
|
||||
}
|
||||
}
|
||||
public static void closeConnection(String databaseName) {
|
||||
if(databaseName.equals(getReportManagementDatasourceName())) {
|
||||
ReportMgtConnectionManager.closeDBConnection();
|
||||
} else if (databaseName.equals(getDeviceManagementDatasourceName())) {
|
||||
DeviceManagementDAOFactory.closeConnection();
|
||||
} else if (databaseName.equals(getApplicationManagementDatasourceName())) {
|
||||
ConnectionManagerUtil.closeDBConnection();
|
||||
} else {
|
||||
throw new RuntimeException("No such datasource with the name: " + databaseName);
|
||||
}
|
||||
}
|
||||
|
||||
private static String getReportManagementDatasourceName() {
|
||||
return reportMgtConfiguration.getDatasourceName();
|
||||
}
|
||||
|
||||
private static String getDeviceManagementDatasourceName() {
|
||||
return deviceManagementConfig.getDeviceManagementConfigRepository().getDataSourceConfig().
|
||||
getJndiLookupDefinition().getJndiName();
|
||||
}
|
||||
|
||||
private static String getApplicationManagementDatasourceName() {
|
||||
return applicationMgtConfig.getDatasourceName();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.sql.query;
|
||||
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.exception.QueryMisMatch;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.util.GrafanaConstants;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.util.GrafanaUtil;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class GrafanaPreparedQueryBuilder {
|
||||
|
||||
private static final Log log = LogFactory.getLog(GrafanaPreparedQueryBuilder.class);
|
||||
|
||||
private static final String QUERY_MISMATCH_EXCEPTION_MESSAGE = "Grafana query api request rawSql does not match relevant query template";
|
||||
private static final String COMMA_SEPARATOR = ",";
|
||||
private static final String VAR_PARAM_TEMPLATE = "$param";
|
||||
private static final String GRAFANA_QUOTED_VAR_REGEX = "('\\$(\\d|\\w|_)+')|('\\$\\{.*?\\}')|(\"\\$(\\d|\\w|_)+\")|(\"\\$\\{.*?\\}\")";
|
||||
private static final String GRAFANA_VAR_REGEX = "(\\$(\\d|\\w|_)+)|(\\$\\{.*?\\})";
|
||||
|
||||
|
||||
public static PreparedQuery build(String queryTemplate, String rawQuery) throws QueryMisMatch {
|
||||
// In Grafana, a variable can coexist with a hardcoded parameter (ie: '${__from:date:YYYY-MM-DD} 00:00:00')
|
||||
// hence this function templates the whole parameter in order to make valid prepared statement
|
||||
queryTemplate = templateParamWGrafanaVariables(queryTemplate);
|
||||
|
||||
String queryUpToVarStart = queryTemplate;
|
||||
String rawQueryUpToVarStart = rawQuery;
|
||||
|
||||
// Pattern matcher to get query string before the first grafana variable
|
||||
Pattern toVarStart = Pattern.compile("([^\\$]+(?=\"\\$))|([^\\$]+(?='\\$))|([^\\$]+(?=\\$))");
|
||||
Matcher matchToVarStart = toVarStart.matcher(queryTemplate);
|
||||
|
||||
if (matchToVarStart.find()) {
|
||||
queryUpToVarStart = matchToVarStart.group();
|
||||
if(rawQuery.length() < queryUpToVarStart.length()) {
|
||||
throw new QueryMisMatch(QUERY_MISMATCH_EXCEPTION_MESSAGE);
|
||||
}
|
||||
rawQueryUpToVarStart = rawQuery.substring(0, queryUpToVarStart.length());
|
||||
}
|
||||
if(!queryUpToVarStart.equals(rawQueryUpToVarStart)){
|
||||
throw new QueryMisMatch(QUERY_MISMATCH_EXCEPTION_MESSAGE);
|
||||
}
|
||||
StringBuilder preparedQueryBuilder = new StringBuilder().append(queryUpToVarStart);
|
||||
|
||||
String queryFromVarStart = queryTemplate.substring(queryUpToVarStart.length());
|
||||
String rawQueryFromVarStart = rawQuery.substring(queryUpToVarStart.length());
|
||||
queryTemplate = queryFromVarStart;
|
||||
rawQuery = rawQueryFromVarStart;
|
||||
Pattern varPattern = Pattern.compile(GRAFANA_QUOTED_VAR_REGEX + "|" + GRAFANA_VAR_REGEX);
|
||||
Matcher varMatch = varPattern.matcher(queryTemplate);
|
||||
List<String> parameters = new ArrayList<>();
|
||||
while(varMatch.find()) {
|
||||
String currentVar = varMatch.group();
|
||||
// Pattern matcher to get query string between grafana current variable and next variable
|
||||
matchToVarStart = toVarStart.matcher(queryTemplate.substring(currentVar.length()));
|
||||
|
||||
String matchToLookBehindRawQuery;
|
||||
if (matchToVarStart.find()) {
|
||||
matchToLookBehindRawQuery = matchToVarStart.group();
|
||||
} else {
|
||||
// If next variable does not exist get query string after the current variable
|
||||
matchToLookBehindRawQuery = queryTemplate.substring(currentVar.length());
|
||||
}
|
||||
String currentVarInput;
|
||||
if (matchToLookBehindRawQuery.isEmpty()) {
|
||||
// If there is no string after the current variable, then remaining segment of rawQuery is the
|
||||
// current variable input (rawQuery is sliced up to the next variable)
|
||||
currentVarInput = rawQuery;
|
||||
} else {
|
||||
Matcher lookBehindRQ = Pattern.compile("(.*?)(?=" + Pattern.quote(matchToLookBehindRawQuery) + ")").matcher(rawQuery);
|
||||
if (!lookBehindRQ.find()) {
|
||||
throw new QueryMisMatch(QUERY_MISMATCH_EXCEPTION_MESSAGE);
|
||||
}
|
||||
currentVarInput = lookBehindRQ.group();
|
||||
}
|
||||
if (isTenantIdVar(currentVar)) {
|
||||
preparedQueryBuilder.append(GrafanaUtil.getTenantId());
|
||||
} else {
|
||||
// Grafana variable input can be multi-valued, which are separated by comma by default
|
||||
String[] varValues = splitByComma(currentVarInput);
|
||||
List<String> preparedStatementPlaceHolders = new ArrayList<>();
|
||||
for (String v : varValues) {
|
||||
String param = unQuoteString(v);
|
||||
if (isSafeVariableInput(param)) {
|
||||
preparedStatementPlaceHolders.add(v);
|
||||
} else {
|
||||
parameters.add(param);
|
||||
preparedStatementPlaceHolders.add(PreparedQuery.PREPARED_SQL_PARAM_PLACEHOLDER);
|
||||
}
|
||||
}
|
||||
preparedQueryBuilder.append(String.join(COMMA_SEPARATOR, preparedStatementPlaceHolders));
|
||||
}
|
||||
preparedQueryBuilder.append(matchToLookBehindRawQuery);
|
||||
// Get template and raw query string from next variable
|
||||
queryTemplate = queryTemplate.substring(currentVar.length() + matchToLookBehindRawQuery.length());
|
||||
rawQuery = rawQuery.substring(currentVarInput.length() + matchToLookBehindRawQuery.length());
|
||||
|
||||
varMatch = varPattern.matcher(queryTemplate);
|
||||
}
|
||||
if (!queryTemplate.equals(rawQuery)) {
|
||||
throw new QueryMisMatch(QUERY_MISMATCH_EXCEPTION_MESSAGE);
|
||||
}
|
||||
return new PreparedQuery(preparedQueryBuilder.toString(), parameters);
|
||||
}
|
||||
|
||||
private static String[] splitByComma(String str) {
|
||||
// Using regex to avoid splitting by comma inside quotes
|
||||
return str.split("(\\s|\\t)*,(\\s|\\t)*(?=(?:[^'\"]*['|\"][^'\"]*['|\"])*[^'\"]*$)");
|
||||
}
|
||||
|
||||
private static String templateParamWGrafanaVariables(String queryTemplate) {
|
||||
// TODO: handle escaped quotes and special characters
|
||||
Pattern quotedStringPattern = Pattern.compile("(\"(.+?)\")|('(.+?)')");
|
||||
Matcher quotedStringMatch = quotedStringPattern.matcher(queryTemplate);
|
||||
while(quotedStringMatch.find()) {
|
||||
String quotedString = quotedStringMatch.group();
|
||||
Matcher varMatcher = Pattern.compile(GRAFANA_VAR_REGEX).matcher(quotedString);
|
||||
// If grafana variable exists in single quoted string
|
||||
if(varMatcher.find()) {
|
||||
String var = varMatcher.group();
|
||||
if (!isTenantIdVar(var)) {
|
||||
String templatedQuotedString = templateQuotedString(quotedString);
|
||||
// escape any special characters
|
||||
templatedQuotedString = Matcher.quoteReplacement(templatedQuotedString);
|
||||
queryTemplate = queryTemplate.replaceFirst(Pattern.quote(quotedString), templatedQuotedString);
|
||||
}
|
||||
}
|
||||
}
|
||||
return queryTemplate;
|
||||
}
|
||||
|
||||
private static String templateQuotedString(String quotedString) {
|
||||
return quotedString.replaceFirst("[^']+|[^\"]+",
|
||||
Matcher.quoteReplacement(VAR_PARAM_TEMPLATE));
|
||||
}
|
||||
|
||||
private static boolean isSafeVariableInput(String currentVarInput) {
|
||||
if (StringUtils.isEmpty(currentVarInput)) {
|
||||
return true;
|
||||
}
|
||||
return currentVarInput.matches("\\$?[a-zA-Z0-9-_\\.]+|^\"[a-zA-Z0-9-_\\.\\s]+\"$|^'[a-zA-Z0-9-_\\.\\s]+'$");
|
||||
}
|
||||
|
||||
private static String unQuoteString(String str) {
|
||||
if (isQuoted(str)) {
|
||||
int firstCharIndex = 0;
|
||||
int lastCharIndex = str.length() - 1;
|
||||
return str.substring(firstCharIndex + 1, lastCharIndex);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
private static boolean isQuoted(String str) {
|
||||
if (StringUtils.isEmpty(str)) {
|
||||
return false;
|
||||
}
|
||||
int firstCharIndex = 0;
|
||||
int lastCharIndex = str.length() - 1;
|
||||
return (str.charAt(firstCharIndex) == '\'' && str.charAt(lastCharIndex) == '\'') ||
|
||||
(str.charAt(firstCharIndex) == '"' && str.charAt(lastCharIndex) == '"');
|
||||
}
|
||||
|
||||
private static boolean isTenantIdVar(String var) {
|
||||
return var.equals(GrafanaConstants.TENANT_ID_VAR) || var.equals(singleQuoteString(GrafanaConstants.TENANT_ID_VAR))
|
||||
|| var.equals(doubleQuoteString(GrafanaConstants.TENANT_ID_VAR));
|
||||
}
|
||||
|
||||
private static String doubleQuoteString(String str) {
|
||||
return "\"" + str + "\"";
|
||||
}
|
||||
|
||||
private static String singleQuoteString(String str) {
|
||||
return "'" + str + "'";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.sql.query;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PreparedQuery {
|
||||
|
||||
public static final String PREPARED_SQL_PARAM_PLACEHOLDER = "?";
|
||||
|
||||
private String preparedSQL;
|
||||
private List<String> parameters;
|
||||
|
||||
public PreparedQuery(String preparedSQL, List<String> parameters) {
|
||||
this.preparedSQL = preparedSQL;
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public String getPreparedSQL() {
|
||||
return preparedSQL;
|
||||
}
|
||||
|
||||
public void setPreparedSQL(String preparedSQL) {
|
||||
this.preparedSQL = preparedSQL;
|
||||
}
|
||||
|
||||
public List<String> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void setParameters(List<String> parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.sql.query.encoder;
|
||||
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.sql.query.PreparedQuery;
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class GenericQueryEncoder implements QueryEncoder {
|
||||
|
||||
public GenericQueryEncoder() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encode(PreparedQuery preparedQuery) throws SQLException {
|
||||
return generateEncodedSQL(preparedQuery.getPreparedSQL(), preparedQuery.getParameters());
|
||||
}
|
||||
|
||||
private String generateEncodedSQL(String preparedSQL, List<String> parameters) throws SQLException {
|
||||
List<String> escapedParams = escapeParameters(parameters);
|
||||
Matcher placeHolderMatcher = Pattern.compile(Pattern.quote(PreparedQuery.PREPARED_SQL_PARAM_PLACEHOLDER)).matcher(preparedSQL);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (String param: escapedParams) {
|
||||
if(placeHolderMatcher.find()) {
|
||||
placeHolderMatcher.appendReplacement(sb, Matcher.quoteReplacement(param));
|
||||
} else {
|
||||
String errMsg = "Given parameter count doesn't match parameters available in SQL";
|
||||
throw new SQLException(errMsg);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private List<String> escapeParameters(List<String> parameters) {
|
||||
List<String> escapedParams = new ArrayList<>();
|
||||
for (String param : parameters) {
|
||||
String escapedParam = StringEscapeUtils.escapeSql(param);
|
||||
escapedParams.add(escapedParam);
|
||||
}
|
||||
return escapedParams;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.sql.query.encoder;
|
||||
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.sql.connection.GrafanaDatasourceConnectionFactory;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.sql.query.PreparedQuery;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
public class MySQLQueryEncoder implements QueryEncoder {
|
||||
|
||||
private static final Log log = LogFactory.getLog(MySQLQueryEncoder.class);
|
||||
private static final String PREPARED_STATEMENT_STRING_OBJECT_ID_SEPARATOR = ": ";
|
||||
|
||||
private final String databaseName;
|
||||
|
||||
public MySQLQueryEncoder(String databaseName) {
|
||||
this.databaseName = databaseName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encode(PreparedQuery preparedQuery) throws SQLException, DBConnectionException,
|
||||
io.entgra.application.mgt.common.exception.DBConnectionException {
|
||||
try {
|
||||
Connection con = GrafanaDatasourceConnectionFactory.getConnection(databaseName);
|
||||
PreparedStatement stmt = con.prepareStatement(preparedQuery.getPreparedSQL());
|
||||
setParameters(stmt, preparedQuery.getParameters());
|
||||
return generateQueryFromPreparedStatement(stmt);
|
||||
} finally {
|
||||
GrafanaDatasourceConnectionFactory.closeConnection(databaseName);
|
||||
}
|
||||
}
|
||||
|
||||
public void setParameters(PreparedStatement stmt, List<String> parameters)
|
||||
throws SQLException {
|
||||
int i = 0;
|
||||
for (String p : parameters) {
|
||||
stmt.setObject(++i, p);
|
||||
}
|
||||
}
|
||||
|
||||
private String generateQueryFromPreparedStatement(PreparedStatement stmt) {
|
||||
String query = stmt.toString().substring(stmt.toString().indexOf(PREPARED_STATEMENT_STRING_OBJECT_ID_SEPARATOR) +
|
||||
PREPARED_STATEMENT_STRING_OBJECT_ID_SEPARATOR.length());
|
||||
// Below is how generated string of prepared statement may look like
|
||||
// org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy[Proxy=1138452482; Query=<query>; Delegate=com.mysql.cj.jdbc.ClientPreparedStatement: <query>]
|
||||
// This removes unnecessary "]" char at the end that may remain after extracting the query
|
||||
if (query.charAt(query.length() - 1) == ']') {
|
||||
query = query.substring(0, query.length() - 1);
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.sql.query.encoder;
|
||||
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.sql.query.PreparedQuery;
|
||||
import org.wso2.carbon.device.mgt.common.exceptions.DBConnectionException;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public interface QueryEncoder {
|
||||
|
||||
String encode(PreparedQuery preparedQuery) throws SQLException, DBConnectionException, io.entgra.application.mgt.common.exception.DBConnectionException;
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.sql.query.encoder;
|
||||
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.util.GrafanaConstants;
|
||||
|
||||
public class QueryEncoderFactory {
|
||||
|
||||
public static QueryEncoder createEncoder(String datasourceType, String databaseName) {
|
||||
if (datasourceType.equals(GrafanaConstants.DATASOURCE_TYPE.MYSQL)) {
|
||||
return new MySQLQueryEncoder(databaseName);
|
||||
} else {
|
||||
return new GenericQueryEncoder();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.util;
|
||||
|
||||
public class GrafanaConstants {
|
||||
|
||||
public static final String QUERY_API_CACHE_NAME = "queryAPICache";
|
||||
public static final String ENCODED_QUERY_CACHE_NAME = "encodedQueryCache";
|
||||
public static final String REFERER_HEADER = "Referer";
|
||||
public static final String CONFIG_XML_NAME = "grafana-config.xml";
|
||||
public static final String X_GRAFANA_ORG_ID_HEADER = "x-org-grafana-id";
|
||||
|
||||
public static class XML {
|
||||
public static final String FEATURES_DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
|
||||
}
|
||||
|
||||
public static class DATASOURCE_TYPE {
|
||||
public static final String MYSQL = "mysql";
|
||||
public static final String POSTGRESQL = "postgresql";
|
||||
public static final String MICROSOFT_SQL_SERVER = "mssql";
|
||||
public static final String ORACLE = "oracle";
|
||||
}
|
||||
|
||||
public static final int IFRAME_URL_DASHBOARD_UID_INDEX = 1;
|
||||
|
||||
public static final String TENANT_ID_VAR_NAME = "tenantId";
|
||||
public static final String VAR_PREFIX = "$";
|
||||
public static final String TENANT_ID_VAR = VAR_PREFIX + TENANT_ID_VAR_NAME;
|
||||
public static final String QUERY_PARAM_VAR_PREFIX = "var-";
|
||||
public static final String TENANT_ID_VAR_QUERY_PARAM = QUERY_PARAM_VAR_PREFIX + TENANT_ID_VAR_NAME;
|
||||
public static final String API_PATH = "/api";
|
||||
public static final String DASHBOARD_KEY = "dashboard";
|
||||
public static final String DATASOURCE_TYPE_KEY = "type";
|
||||
public static final String DATASOURCE_DB_KEY = "database";
|
||||
public static final String DATASOURCE_ID_KEY = "datasourceId";
|
||||
public static final String DATASOURCE_NAME_KEY = "name";
|
||||
public static final String DATASOURCE_URL_KEY = "name";
|
||||
public static final String PANEL_KEY = "panels";
|
||||
public static final String TEMPLATING_KEY = "templating";
|
||||
public static final String TEMPLATING_NAME_KEY = "name";
|
||||
public static final String TEMPLATE_QUERY_KEY = "query";
|
||||
public static final String TEMPLATING_LIST_KEY = "list";
|
||||
public static final String RAW_SQL_KEY = "rawSql";
|
||||
public static final String QUERY_BODY_QUERIES_KEY = "queries";
|
||||
public static final String DASHBOARD_PANEL_DETAIL_QUERIES_KEY = "targets";
|
||||
public static final String QUERY_REF_ID_KEY = "refId";
|
||||
public static final String PANEL_ID_QUERY_PARAM = "panelId";
|
||||
public static final String ORG_ID_QUERY_PARAM = "panelId";
|
||||
public static final String ID_KEY = "id";
|
||||
|
||||
public static final String WS_LIVE_API = "/api/live/ws";
|
||||
public static final String DASHBOARD_API = "/api/dashboards/uid";
|
||||
public static final String DATASOURCE_API = "/api/datasources";
|
||||
public static final String HTTP_HOST_ENV_VAR = "iot.grafana.http.host";
|
||||
public static final String HTTPS_HOST_ENV_VAR = "iot.grafana.https.host";
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/* Copyright (c) 2020, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (Pvt) Ltd. licenses this file to you 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.entgra.analytics.mgt.grafana.proxy.core.util;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.common.exception.GrafanaManagementException;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.bean.GrafanaPanelIdentifier;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.config.GrafanaConfiguration;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.config.GrafanaConfigurationManager;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.exception.GrafanaEnvVariablesNotDefined;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.GrafanaAPIService;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.GrafanaQueryService;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.impl.GrafanaAPIServiceImpl;
|
||||
import io.entgra.analytics.mgt.grafana.proxy.core.service.impl.GrafanaQueryServiceImpl;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||
import org.wso2.carbon.device.mgt.core.common.util.HttpUtil;
|
||||
import org.wso2.carbon.device.mgt.core.report.mgt.Constants;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GrafanaUtil {
|
||||
|
||||
private static final Log log = LogFactory.getLog(GrafanaUtil.class);
|
||||
|
||||
public static boolean isGrafanaAPI(String uri) {
|
||||
return uri.contains(GrafanaConstants.API_PATH);
|
||||
}
|
||||
|
||||
public static String generateGrafanaUrl(String requestPath, String base) {
|
||||
base += Constants.URI_SEPARATOR;
|
||||
return base + requestPath;
|
||||
}
|
||||
public static String getGrafanaWebSocketBase(String requestScheme) throws GrafanaEnvVariablesNotDefined {
|
||||
return getGrafanaBase(requestScheme, Constants.WS_PROTOCOL, Constants.WSS_PROTOCOL);
|
||||
}
|
||||
public static String getGrafanaHTTPBase(String requestScheme) throws GrafanaEnvVariablesNotDefined {
|
||||
return getGrafanaBase(requestScheme, Constants.HTTP_PROTOCOL, Constants.HTTPS_PROTOCOL);
|
||||
}
|
||||
|
||||
public static String getGrafanaBase(String requestScheme, String httpProtocol, String httpsProtocol)
|
||||
throws GrafanaEnvVariablesNotDefined {
|
||||
String grafanaHost = System.getProperty(GrafanaConstants.HTTPS_HOST_ENV_VAR);
|
||||
String scheme = httpsProtocol;
|
||||
if (Constants.HTTP_PROTOCOL.equals(requestScheme) || StringUtils.isEmpty(grafanaHost)){
|
||||
grafanaHost = System.getProperty(GrafanaConstants.HTTP_HOST_ENV_VAR);
|
||||
scheme = httpProtocol;
|
||||
}
|
||||
if(StringUtils.isEmpty(grafanaHost)) {
|
||||
String errMsg = "Grafana host is not defined in the iot-server.sh properly.";
|
||||
log.error(errMsg);
|
||||
throw new GrafanaEnvVariablesNotDefined(errMsg);
|
||||
}
|
||||
return scheme + Constants.SCHEME_SEPARATOR + grafanaHost;
|
||||
}
|
||||
|
||||
public static String getPanelId(URI iframeURL) {
|
||||
Map<String, List<String>> queryMap = HttpUtil.getQueryMap(iframeURL);
|
||||
return HttpUtil.getFirstQueryValue(GrafanaConstants.PANEL_ID_QUERY_PARAM, queryMap);
|
||||
}
|
||||
public static String getOrgId(URI iframeURL) {
|
||||
Map<String, List<String>> queryMap = HttpUtil.getQueryMap(iframeURL);
|
||||
return HttpUtil.getFirstQueryValue(GrafanaConstants.ORG_ID_QUERY_PARAM, queryMap);
|
||||
}
|
||||
|
||||
public static String getDashboardUID(URI iframeURL) {
|
||||
return HttpUtil.getRequestSubPathFromEnd(iframeURL, GrafanaConstants.IFRAME_URL_DASHBOARD_UID_INDEX);
|
||||
}
|
||||
|
||||
public static JsonObject getJsonBody(String body) {
|
||||
return new Gson().fromJson(body, JsonObject.class);
|
||||
}
|
||||
|
||||
public static String getBasicAuthBase64Header() throws GrafanaManagementException {
|
||||
GrafanaConfiguration configuration = GrafanaConfigurationManager.getInstance().getGrafanaConfiguration();
|
||||
String username = configuration.getAdminUser().getUsername();
|
||||
String password = configuration.getAdminUser().getPassword();
|
||||
return Constants.BASIC_AUTH_HEADER_PREFIX + GrafanaUtil.getBase64Encode(username, password);
|
||||
}
|
||||
|
||||
public static String getBase64Encode(String key, String value) {
|
||||
return new String(Base64.encodeBase64((key + ":" + value).getBytes()));
|
||||
}
|
||||
|
||||
public static GrafanaPanelIdentifier getPanelIdentifierFromReferer(String referer) {
|
||||
URI refererUri = HttpUtil.createURI(referer);
|
||||
String orgId = GrafanaUtil.getOrgId(refererUri);
|
||||
String dashboardUID = GrafanaUtil.getDashboardUID(refererUri);
|
||||
String panelId = GrafanaUtil.getPanelId(refererUri);
|
||||
return new GrafanaPanelIdentifier(orgId, dashboardUID, panelId);
|
||||
}
|
||||
|
||||
public static int getTenantId() {
|
||||
return PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2021, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
~
|
||||
~ Entgra (Pvt) Ltd. licenses this file to you 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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>analytics-mgt</artifactId>
|
||||
<version>5.0.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>grafana-mgt</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>Entgra - Grafana API Handler Component</name>
|
||||
<url>http://entgra.io</url>
|
||||
|
||||
|
||||
<modules>
|
||||
<module>io.entgra.analytics.mgt.grafana.proxy.core</module>
|
||||
<module>io.entgra.analytics.mgt.grafana.proxy.common</module>
|
||||
<module>io.entgra.analytics.mgt.grafana.proxy.api</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>carbon-devicemgt</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.3-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>analytics-mgt</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>Entgra - Analytics Management Component</name>
|
||||
<url>http://entgra.io</url>
|
||||
|
||||
<modules>
|
||||
<module>grafana-mgt</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
@ -0,0 +1,61 @@
|
||||
package org.wso2.carbon.device.mgt.common.type.mgt;
|
||||
|
||||
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class DeviceStatus {
|
||||
private EnrolmentInfo.Status status;
|
||||
private Date updateTime;
|
||||
private int enrolmentId;
|
||||
private int deviceId;
|
||||
private String changedBy;
|
||||
|
||||
public DeviceStatus(int enrolmentId, int deviceId, EnrolmentInfo.Status status, Date updateTime, String changedBy) {
|
||||
this.status = status;
|
||||
this.updateTime = updateTime;
|
||||
this.enrolmentId = enrolmentId;
|
||||
this.deviceId = deviceId;
|
||||
this.changedBy = changedBy;
|
||||
}
|
||||
|
||||
public String getChangedBy() {
|
||||
return changedBy;
|
||||
}
|
||||
|
||||
public void setChangedBy(String changedBy) {
|
||||
this.changedBy = changedBy;
|
||||
}
|
||||
|
||||
public EnrolmentInfo.Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(EnrolmentInfo.Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public int getEnrolmentId() {
|
||||
return enrolmentId;
|
||||
}
|
||||
|
||||
public void setEnrolmentId(int enrolmentId) {
|
||||
this.enrolmentId = enrolmentId;
|
||||
}
|
||||
|
||||
public int getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public void setDeviceId(int deviceId) {
|
||||
this.deviceId = deviceId;
|
||||
}
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Entgra (pvt) Ltd. (http://entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (pvt) Ltd. licenses this file to you 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 org.wso2.carbon.device.mgt.core.common.util;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.wso2.carbon.device.mgt.core.report.mgt.Constants;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HttpUtil {
|
||||
|
||||
public static URI createURI(String uriString) {
|
||||
uriString = uriString.replace(" ", "%20");
|
||||
return URI.create(uriString);
|
||||
}
|
||||
|
||||
public static String getRequestSubPathFromEnd(URI requestUri, int position) {
|
||||
if (requestUri.getPath() != null) {
|
||||
String[] pathList = requestUri.getPath().split("/");
|
||||
if (pathList.length - 1 >= position) {
|
||||
return pathList[pathList.length - 1 - position];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getRequestSubPath(String fullPath, int position) {
|
||||
String[] pathList = fullPath.split("/");
|
||||
if (pathList.length - 1 > position) {
|
||||
String path = pathList[position + 1];
|
||||
if(path.contains(Constants.URI_QUERY_SEPARATOR)) {
|
||||
path = path.substring(0, path.indexOf(Constants.URI_QUERY_SEPARATOR));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getResponseString(HttpResponse response) throws IOException {
|
||||
return EntityUtils.toString(response.getEntity());
|
||||
}
|
||||
|
||||
public static boolean isQueryParamExist(String param, URI request) {
|
||||
Map<String, List<String>> queryMap = getQueryMap(request);
|
||||
return queryMap.containsKey(param);
|
||||
}
|
||||
public static String getFirstQueryValue(String param, Map<String, List<String>> queryMap) {
|
||||
List<String> valueList = queryMap.get(param);
|
||||
String firstValue = null;
|
||||
if(valueList != null) {
|
||||
firstValue = valueList.get(0);
|
||||
}
|
||||
return firstValue;
|
||||
}
|
||||
public static Map<String, List<String>> getQueryMap(String uri) {
|
||||
String query = getQueryFromURIPath(uri);
|
||||
Map<String, List<String>> map = new HashMap<>();
|
||||
if (query != null) {
|
||||
String[] params = query.split("&");
|
||||
for (String param : params) {
|
||||
String[] paramArr = param.split("=");
|
||||
if (paramArr.length == 2) {
|
||||
String name = paramArr[0];
|
||||
String value = paramArr[1];
|
||||
if (!map.containsKey(name)) {
|
||||
List<String> valueList = new ArrayList<>();
|
||||
map.put(name, valueList);
|
||||
}
|
||||
map.get(name).add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
public static Map<String, List<String>> getQueryMap(URI request) {
|
||||
String query = request.getQuery();
|
||||
Map<String, List<String>> map = new HashMap<>();
|
||||
if (query != null) {
|
||||
String[] params = query.split("&");
|
||||
for (String param : params) {
|
||||
String[] paramArr = param.split("=");
|
||||
if (paramArr.length == 2) {
|
||||
String name = paramArr[0];
|
||||
String value = paramArr[1];
|
||||
if (!map.containsKey(name)) {
|
||||
List<String> valueList = new ArrayList<>();
|
||||
map.put(name, valueList);
|
||||
}
|
||||
map.get(name).add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
public static String getQueryFromURIPath(String uri) {
|
||||
String query = null;
|
||||
if (uri.length() > "?".length() && uri.contains("?")) {
|
||||
query = uri.substring(uri.lastIndexOf("?") + "?".length());
|
||||
}
|
||||
if (StringUtils.isEmpty(query)) {
|
||||
query = null;
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
public static String getContentType(HttpResponse response) {
|
||||
ContentType contentType = ContentType.getOrDefault(response.getEntity());
|
||||
return contentType.getMimeType();
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (Pvt) Ltd. licenses this file to you 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 org.wso2.carbon.device.mgt.core.config.operation.timeout;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import java.util.List;
|
||||
|
||||
@XmlRootElement(name = "OperationTimeout")
|
||||
public class OperationTimeout {
|
||||
|
||||
private String code;
|
||||
private int timeout;
|
||||
private List<String> deviceTypes;
|
||||
private String initialStatus;
|
||||
private String nextStatus;
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@XmlElement(name = "Code", required = true)
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
@XmlElement(name = "Timeout", required = true)
|
||||
public void setTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public List<String> getDeviceTypes() {
|
||||
return deviceTypes;
|
||||
}
|
||||
|
||||
@XmlElementWrapper(name = "DeviceTypes", required = true)
|
||||
@XmlElement(name = "DeviceType", required = true)
|
||||
public void setDeviceTypes(List<String> deviceTypes) {
|
||||
this.deviceTypes = deviceTypes;
|
||||
}
|
||||
|
||||
public String getInitialStatus() {
|
||||
return initialStatus;
|
||||
}
|
||||
|
||||
@XmlElement(name = "InitialStatus", required = true)
|
||||
public void setInitialStatus(String initialStatus) {
|
||||
this.initialStatus = initialStatus;
|
||||
}
|
||||
|
||||
public String getNextStatus() {
|
||||
return nextStatus;
|
||||
}
|
||||
|
||||
@XmlElement(name = "NextStatus", required = true)
|
||||
public void setNextStatus(String nextStatus) {
|
||||
this.nextStatus = nextStatus;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Entgra (Pvt) Ltd. (http://www.entgra.io) All Rights Reserved.
|
||||
*
|
||||
* Entgra (Pvt) Ltd. licenses this file to you 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 org.wso2.carbon.device.mgt.core.config.operation.timeout;
|
||||
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import java.util.List;
|
||||
|
||||
@XmlRootElement(name = "OperationTimeoutConfigurations")
|
||||
public class OperationTimeoutConfiguration {
|
||||
private List<OperationTimeout> operationTimeoutList;
|
||||
|
||||
public List<OperationTimeout> getOperationTimeoutList() {
|
||||
return operationTimeoutList;
|
||||
}
|
||||
|
||||
@XmlElementWrapper(name = "OperationTimeouts", required = true)
|
||||
@XmlElement(name = "OperationTimeout", required = false)
|
||||
public void setOperationTimeoutList(List<OperationTimeout> operationTimeoutList) {
|
||||
this.operationTimeoutList = operationTimeoutList;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
|
||||
*
|
||||
* WSO2 Inc. licenses this file to you 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 org.wso2.carbon.device.mgt.core.dao;
|
||||
|
||||
import org.wso2.carbon.device.mgt.common.Device;
|
||||
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
|
||||
import org.wso2.carbon.device.mgt.common.EnrolmentInfo.Status;
|
||||
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceStatus;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public interface DeviceStatusDAO {
|
||||
|
||||
// boolean updateStatus(int deviceId, Status status, int tenantId) throws DeviceManagementDAOException;
|
||||
|
||||
// boolean updateStatus(int enrolmentId, Status status) throws DeviceManagementDAOException;
|
||||
|
||||
List<DeviceStatus> getStatus(int deviceId, int tenantId) throws DeviceManagementDAOException;
|
||||
|
||||
List<DeviceStatus> getStatus(int deviceId, int tenantId, Date fromDate, Date toDate) throws DeviceManagementDAOException;
|
||||
|
||||
List<DeviceStatus> getStatus(int enrolmentId) throws DeviceManagementDAOException;
|
||||
|
||||
List<DeviceStatus> getStatus(int enrolmentId, Date fromDate, Date toDate) throws DeviceManagementDAOException;
|
||||
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package org.wso2.carbon.device.mgt.core.dao.impl;
|
||||
|
||||
import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
|
||||
import org.wso2.carbon.device.mgt.common.type.mgt.DeviceStatus;
|
||||
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOException;
|
||||
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
|
||||
import org.wso2.carbon.device.mgt.core.dao.DeviceStatusDAO;
|
||||
import org.wso2.carbon.device.mgt.core.dao.EnrollmentDAO;
|
||||
import org.wso2.carbon.device.mgt.core.dao.util.DeviceManagementDAOUtil;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class DeviceStatusDAOImpl implements DeviceStatusDAO {
|
||||
|
||||
private List<DeviceStatus> getStatus(int id, Date fromDate, Date toDate, boolean isDeviceId) throws DeviceManagementDAOException {
|
||||
List<DeviceStatus> result = new ArrayList<>();
|
||||
Connection conn;
|
||||
PreparedStatement stmt = null;
|
||||
ResultSet rs = null;
|
||||
EnrolmentInfo.Status status = null;
|
||||
try {
|
||||
conn = this.getConnection();
|
||||
// either we list all status values for the device using the device id or only get status values for the given enrolment id
|
||||
String idType = isDeviceId ? "DEVICE_ID" : "ENROLMENT_ID";
|
||||
String sql = "SELECT ENROLMENT_ID, DEVICE_ID, UPDATE_TIME, STATUS, CHANGED_BY FROM DM_DEVICE_STATUS WHERE " + idType + " = ?";
|
||||
// filter the data based on a date range if specified
|
||||
if (fromDate != null){
|
||||
sql += " AND UPDATE_TIME >= ?";
|
||||
}
|
||||
if (toDate != null){
|
||||
sql += " AND UPDATE_TIME <= ?";
|
||||
}
|
||||
|
||||
stmt = conn.prepareStatement(sql);
|
||||
|
||||
int i = 1;
|
||||
stmt.setInt(i++, id);
|
||||
if (fromDate != null){
|
||||
Timestamp fromTime = new Timestamp(fromDate.getTime());
|
||||
stmt.setTimestamp(i++, fromTime);
|
||||
}
|
||||
if (toDate != null){
|
||||
Timestamp toTime = new Timestamp(toDate.getTime());
|
||||
stmt.setTimestamp(i++, toTime);
|
||||
}
|
||||
rs = stmt.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
DeviceStatus ds = new DeviceStatus(rs.getInt("ENROLMENT_ID"), rs.getInt("DEVICE_ID"),
|
||||
EnrolmentInfo.Status.valueOf(rs.getString("STATUS")),
|
||||
new Date(rs.getTimestamp("UPDATE_TIME").getTime()), rs.getString("CHANGED_BY"));
|
||||
result.add(ds);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DeviceManagementDAOException("Error occurred while setting the status of device enrolment", e);
|
||||
} finally {
|
||||
DeviceManagementDAOUtil.cleanupResources(stmt, rs);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DeviceStatus> getStatus(int enrolmentId, Date fromDate, Date toDate) throws DeviceManagementDAOException {
|
||||
return getStatus(enrolmentId, fromDate, toDate, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DeviceStatus> getStatus(int deviceId, int tenantId) throws DeviceManagementDAOException {
|
||||
return getStatus(deviceId, tenantId, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DeviceStatus> getStatus(int deviceId, int tenantId, Date fromDate, Date toDate) throws DeviceManagementDAOException {
|
||||
return getStatus(deviceId, fromDate, toDate, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DeviceStatus> getStatus(int enrolmentId) throws DeviceManagementDAOException {
|
||||
return getStatus(enrolmentId, null, null);
|
||||
}
|
||||
|
||||
|
||||
private Connection getConnection() throws SQLException {
|
||||
return DeviceManagementDAOFactory.getConnection();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue