mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Tempory merge conflict resolution
This commit is contained in:
commit
aa2fa45a5f
@ -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.6-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 = "GET",
|
||||
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 = "GET",
|
||||
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,167 @@
|
||||
/*
|
||||
* 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.nio.charset.StandardCharsets;
|
||||
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(), StandardCharsets.UTF_8);
|
||||
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.6-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.6-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 = "orgId";
|
||||
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);
|
||||
}
|
||||
}
|
||||
42
components/analytics-mgt/grafana-mgt/pom.xml
Normal file
42
components/analytics-mgt/grafana-mgt/pom.xml
Normal file
@ -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.6-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>
|
||||
20
components/analytics-mgt/pom.xml
Normal file
20
components/analytics-mgt/pom.xml
Normal file
@ -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.6-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>
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>apimgt-extensions</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<artifactId>apimgt-extensions</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>apimgt-extensions</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -62,11 +62,13 @@ public interface APIManagementProviderService {
|
||||
* @param applicationName Application Name
|
||||
* @param tokenType Token Type
|
||||
* @param validityPeriod Validity Period
|
||||
* @param username Name of the user to create the token. If null, set as carbon context user
|
||||
* @return {@link String} Access Token
|
||||
* @throws APIManagerException if error occurred while getting the access token for given scopes,
|
||||
* validity period etc.
|
||||
*/
|
||||
AccessTokenInfo getAccessToken(String scopes, String[] tags, String applicationName, String tokenType, String validityPeriod)
|
||||
AccessTokenInfo getAccessToken(String scopes, String[] tags, String applicationName, String
|
||||
tokenType, String validityPeriod, String username)
|
||||
throws APIManagerException;
|
||||
|
||||
}
|
||||
|
||||
@ -233,7 +233,7 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
|
||||
|
||||
@Override
|
||||
public AccessTokenInfo getAccessToken(String scopes, String[] tags, String applicationName, String tokenType,
|
||||
String validityPeriod) throws APIManagerException {
|
||||
String validityPeriod, String username) throws APIManagerException {
|
||||
try {
|
||||
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain(true);
|
||||
ApiApplicationKey clientCredentials = getClientCredentials(tenantDomain, tags, applicationName, tokenType,
|
||||
@ -245,15 +245,22 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe
|
||||
throw new APIManagerException(msg);
|
||||
}
|
||||
|
||||
String user =
|
||||
if (username == null || username.isEmpty()) {
|
||||
username =
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername() + "@" + PrivilegedCarbonContext
|
||||
.getThreadLocalCarbonContext().getTenantDomain(true);
|
||||
} else {
|
||||
if (!username.contains("@")) {
|
||||
username += "@" + PrivilegedCarbonContext
|
||||
.getThreadLocalCarbonContext().getTenantDomain(true);
|
||||
}
|
||||
}
|
||||
|
||||
JWTClientManagerService jwtClientManagerService = APIApplicationManagerExtensionDataHolder.getInstance()
|
||||
.getJwtClientManagerService();
|
||||
JWTClient jwtClient = jwtClientManagerService.getJWTClient();
|
||||
AccessTokenInfo accessTokenForAdmin = jwtClient
|
||||
.getAccessToken(clientCredentials.getConsumerKey(), clientCredentials.getConsumerSecret(), user,
|
||||
.getAccessToken(clientCredentials.getConsumerKey(), clientCredentials.getConsumerSecret(), username,
|
||||
scopes);
|
||||
|
||||
return accessTokenForAdmin;
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>apimgt-extensions</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>carbon-devicemgt</artifactId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
<parent>
|
||||
<artifactId>application-mgt</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>application-mgt</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>application-mgt</artifactId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -23,12 +23,14 @@ import java.sql.Timestamp;
|
||||
|
||||
public class DeviceSubscriptionData {
|
||||
|
||||
private int subId;
|
||||
private String action;
|
||||
private long actionTriggeredTimestamp;
|
||||
private String actionTriggeredBy;
|
||||
private String actionType;
|
||||
private String status;
|
||||
private Device device;
|
||||
private String currentInstalledVersion;
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
@ -77,4 +79,16 @@ public class DeviceSubscriptionData {
|
||||
public void setDevice(Device device) {
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
public String getCurrentInstalledVersion() { return currentInstalledVersion; }
|
||||
|
||||
public void setCurrentInstalledVersion(String currentInstalledVersion) { this.currentInstalledVersion = currentInstalledVersion; }
|
||||
|
||||
public int getSubId() {
|
||||
return subId;
|
||||
}
|
||||
|
||||
public void setSubId(int subId) {
|
||||
this.subId = subId;
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,6 +108,11 @@ public class Filter {
|
||||
*/
|
||||
private String appReleaseState;
|
||||
|
||||
/**
|
||||
* Username of whose favourite apps to be retrieved
|
||||
*/
|
||||
private String favouredBy;
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
@ -195,4 +200,12 @@ public class Filter {
|
||||
public String getAppReleaseType() { return appReleaseType; }
|
||||
|
||||
public void setAppReleaseType(String appReleaseType) { this.appReleaseType = appReleaseType; }
|
||||
|
||||
public String getFavouredBy() {
|
||||
return favouredBy;
|
||||
}
|
||||
|
||||
public void setFavouredBy(String favouredBy) {
|
||||
this.favouredBy = favouredBy;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
package io.entgra.application.mgt.common;
|
||||
|
||||
public class OperationStatusBean {
|
||||
|
||||
private int operationId;
|
||||
private String status;
|
||||
private String operationCode;
|
||||
|
||||
public int getOperationId() {
|
||||
return operationId;
|
||||
}
|
||||
|
||||
public void setOperationId(int operationId) {
|
||||
this.operationId = operationId;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getOperationCode() {
|
||||
return operationCode;
|
||||
}
|
||||
|
||||
public void setOperationCode(String operationCode) {
|
||||
this.operationCode = operationCode;
|
||||
}
|
||||
}
|
||||
@ -96,6 +96,10 @@ public class ApplicationDTO {
|
||||
value = "package name of the application")
|
||||
private String packageName;
|
||||
|
||||
@ApiModelProperty(name = "isFavourite",
|
||||
value = "if the app is favoured by the user")
|
||||
private boolean isFavourite;
|
||||
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
@ -189,4 +193,12 @@ public class ApplicationDTO {
|
||||
public double getAppRating() { return appRating; }
|
||||
|
||||
public void setAppRating(double appRating) { this.appRating = appRating; }
|
||||
|
||||
public boolean isFavourite() {
|
||||
return isFavourite;
|
||||
}
|
||||
|
||||
public void setFavourite(boolean favourite) {
|
||||
isFavourite = favourite;
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,6 +103,10 @@ public class Application {
|
||||
value = "package name of the application")
|
||||
private String packageName;
|
||||
|
||||
@ApiModelProperty(name = "isFavourite",
|
||||
value = "if the app is favoured by the user")
|
||||
private boolean isFavourite;
|
||||
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
@ -181,4 +185,12 @@ public class Application {
|
||||
public String getInstallerName() { return installerName; }
|
||||
|
||||
public void setInstallerName(String installerName) { this.installerName = installerName; }
|
||||
|
||||
public boolean isFavourite() {
|
||||
return isFavourite;
|
||||
}
|
||||
|
||||
public void setFavourite(boolean favourite) {
|
||||
isFavourite = favourite;
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,6 +128,26 @@ public interface ApplicationManager {
|
||||
* @throws ApplicationManagementException if any error occurred while creating the application
|
||||
*/
|
||||
<T> Application createApplication(T app) throws ApplicationManagementException;
|
||||
/**
|
||||
* Add an application to favourites
|
||||
* @param appId id of the application
|
||||
* @throws ApplicationManagementException Catch all other throwing exceptions and throw {@link ApplicationManagementException}
|
||||
*/
|
||||
void addAppToFavourites(int appId) throws ApplicationManagementException;
|
||||
|
||||
/**
|
||||
* Remove an application from favourites
|
||||
* @param appId id of the application
|
||||
* @throws ApplicationManagementException Catch all other throwing exceptions and throw {@link ApplicationManagementException}
|
||||
*/
|
||||
void removeAppFromFavourites(int appId) throws ApplicationManagementException;
|
||||
|
||||
/**
|
||||
* Check if an application is a favourite app
|
||||
* @param appId id of the application
|
||||
* @throws ApplicationManagementException Catch all other throwing exceptions and throw {@link ApplicationManagementException}
|
||||
*/
|
||||
boolean isFavouriteApp(int appId) throws ApplicationManagementException;
|
||||
|
||||
/**
|
||||
* Check the existence of an application for given application name and the device type.
|
||||
@ -175,6 +195,8 @@ public interface ApplicationManager {
|
||||
*/
|
||||
void deleteApplicationRelease(String releaseUuid) throws ApplicationManagementException;
|
||||
|
||||
ApplicationList getFavouriteApplications(Filter filter) throws ApplicationManagementException;
|
||||
|
||||
/**
|
||||
* Use to delete application artifact files (For example this is useful to delete application release artifacts
|
||||
* (I.E screenshots) when an application is deleted)
|
||||
@ -291,6 +313,17 @@ public interface ApplicationManager {
|
||||
ApplicationRelease changeLifecycleState(String releaseUuid, LifecycleChanger lifecycleChanger)
|
||||
throws ApplicationManagementException;
|
||||
|
||||
/**
|
||||
* To get all the releases of a particular ApplicationDTO.
|
||||
*
|
||||
* @param applicationReleaseDTO of the ApplicationDTO Release.
|
||||
* @param lifecycleChanger Lifecycle changer that contains the action and the reason for the change.
|
||||
* @throws ApplicationManagementException ApplicationDTO Management Exception.
|
||||
* @return
|
||||
*/
|
||||
ApplicationRelease changeLifecycleState(ApplicationReleaseDTO applicationReleaseDTO, LifecycleChanger lifecycleChanger)
|
||||
throws ApplicationManagementException;
|
||||
|
||||
/**
|
||||
* To update release images such as icons, banner and screenshots.
|
||||
*
|
||||
@ -470,7 +503,9 @@ public interface ApplicationManager {
|
||||
*/
|
||||
boolean checkSubDeviceIdsForOperations(int operationId, int deviceId) throws ApplicationManagementException;
|
||||
|
||||
void updateSubsStatus (int deviceId, int operationId, String status) throws ApplicationManagementException;
|
||||
void updateSubStatus(int deviceId, List<Integer> operationId, String status) throws ApplicationManagementException;
|
||||
|
||||
void updateSubsStatus(int deviceId, int operationId, String status) throws ApplicationManagementException;
|
||||
|
||||
/**
|
||||
* Get plist content to download and install the application.
|
||||
@ -482,5 +517,4 @@ public interface ApplicationManager {
|
||||
String getPlistArtifact(String uuid) throws ApplicationManagementException;
|
||||
|
||||
List<ApplicationReleaseDTO> getReleaseByPackageNames(List<String> packageIds) throws ApplicationManagementException;
|
||||
|
||||
}
|
||||
|
||||
@ -34,6 +34,16 @@ import java.util.Properties;
|
||||
*/
|
||||
public interface SubscriptionManager {
|
||||
|
||||
/**
|
||||
* Use to update status of a subscription
|
||||
*
|
||||
* @param deviceId Id of the device
|
||||
* @param subId subscription id
|
||||
* @param status status to be changed
|
||||
*/
|
||||
void updateSubscriptionStatus(int deviceId, int subId, String status)
|
||||
throws SubscriptionManagementException;
|
||||
|
||||
/**
|
||||
* Performs bulk subscription operation for a given application and a subscriber list.
|
||||
* @param applicationUUID UUID of the application to subscribe/unsubscribe
|
||||
@ -175,12 +185,13 @@ public interface SubscriptionManager {
|
||||
* @param actionStatus status of the operation.
|
||||
* @param action action related to the device.
|
||||
* @param appUUID application release UUID
|
||||
* @param installedVersion installed version
|
||||
* @return {@link PaginationResult}
|
||||
* @throws ApplicationManagementException if offset or limit contains incorrect values, if it couldn't find an
|
||||
* application release for given UUID, if an error occurred while getting device details of subscribed device ids,
|
||||
* if an error occurred while getting subscription details of given application release UUID.
|
||||
*/
|
||||
PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, String action)
|
||||
PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus, String action, String installedVersion)
|
||||
throws ApplicationManagementException;
|
||||
|
||||
/***
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
<parent>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>application-mgt</artifactId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -39,6 +39,33 @@ public interface ApplicationDAO {
|
||||
*/
|
||||
int createApplication(ApplicationDTO applicationDTO, int tenantId) throws ApplicationManagementDAOException;
|
||||
|
||||
/**
|
||||
* Use to add an application to favourites for given appId, username and tenantId
|
||||
*
|
||||
* @param appId id of the application
|
||||
* @param userName currently logged-in user
|
||||
* @throws ApplicationManagementDAOException if error occurred wile executing query to insert data into database.
|
||||
*/
|
||||
void addAppToFavourite(int appId, String userName, int tenantId) throws ApplicationManagementDAOException;
|
||||
|
||||
/**
|
||||
* Use to remove an application from favourites for given appId, username and tenantId
|
||||
*
|
||||
* @param appId id of the application
|
||||
* @param userName currently logged-in username
|
||||
* @throws ApplicationManagementDAOException if error occurred wile executing query to delete data from database.
|
||||
*/
|
||||
void removeAppFromFavourite(int appId, String userName, int tenantId) throws ApplicationManagementDAOException;
|
||||
|
||||
/**
|
||||
* Use to check if an app is favourite for given username and tenantId
|
||||
* @param appId id of the application
|
||||
* @param userName currently logged-in username
|
||||
* @return If application is favourite
|
||||
* @throws ApplicationManagementDAOException if error occurred wile executing query to check if application is a favourite
|
||||
*/
|
||||
boolean isFavouriteApp(int appId, String userName, int tenantId) throws ApplicationManagementDAOException;
|
||||
|
||||
/**
|
||||
* To add tags for a particular application.
|
||||
*
|
||||
|
||||
@ -101,6 +101,10 @@ public interface SubscriptionDAO {
|
||||
List<Integer> getDeviceSubIds(List<Integer> deviceIds, int applicationReleaseId, int tenantId)
|
||||
throws ApplicationManagementDAOException;
|
||||
|
||||
int getDeviceIdForSubId(int subId, int tenantId) throws ApplicationManagementDAOException;
|
||||
|
||||
List<Integer> getOperationIdsForSubId(int subId, int tenantId) throws ApplicationManagementDAOException;
|
||||
|
||||
List<Integer> getDeviceSubIdsForOperation(int operationId, int deviceID, int tenantId)
|
||||
throws ApplicationManagementDAOException;
|
||||
|
||||
@ -239,4 +243,13 @@ public interface SubscriptionDAO {
|
||||
*/
|
||||
List<Integer> getAppSubscribedDevicesForGroups(int appReleaseId, String subtype, int tenantId)
|
||||
throws ApplicationManagementDAOException;
|
||||
|
||||
/**
|
||||
* This method is used to get the currently installed version for given app release id
|
||||
* @param appId id of the application
|
||||
* @param deviceIdList id list of devices
|
||||
* @return Map with device id as a key and currently installed version as value
|
||||
* @throws {@link ApplicationManagementDAOException} if connections establishment fails.
|
||||
*/
|
||||
Map<Integer,String> getCurrentInstalledAppVersion(int appId, List<Integer> deviceIdList, String installedVersion) throws ApplicationManagementDAOException;
|
||||
}
|
||||
|
||||
@ -135,8 +135,12 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
|
||||
+ "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, "
|
||||
+ "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, "
|
||||
+ "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE "
|
||||
+ "FROM AP_APP "
|
||||
+ "LEFT JOIN AP_APP_RELEASE ON "
|
||||
+ "FROM AP_APP ";
|
||||
if (StringUtils.isNotEmpty(filter.getFavouredBy())) {
|
||||
sql += "INNER JOIN AP_APP_FAVOURITES ON "
|
||||
+ "AP_APP.ID = AP_APP_FAVOURITES.AP_APP_ID ";
|
||||
}
|
||||
sql += "LEFT JOIN AP_APP_RELEASE ON "
|
||||
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "
|
||||
+ "INNER JOIN (SELECT AP_APP.ID FROM AP_APP ";
|
||||
if (StringUtils.isNotEmpty(filter.getVersion()) || StringUtils.isNotEmpty(filter.getAppReleaseState())
|
||||
@ -189,8 +193,11 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
|
||||
+ "FROM AP_APP_LIFECYCLE_STATE "
|
||||
+ "GROUP BY AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID)) AS NEW_AP_APP_LIFECYCLE_STATE "
|
||||
+ "ON AP_APP_RELEASE.ID = NEW_AP_APP_LIFECYCLE_STATE.AP_APP_RELEASE_ID "
|
||||
+ "WHERE AP_APP.TENANT_ID = ? "
|
||||
+ "ORDER BY AP_APP.ID, LATEST_UPDATE DESC";
|
||||
+ "WHERE AP_APP.TENANT_ID = ? ";
|
||||
if (StringUtils.isNotEmpty(filter.getFavouredBy())) {
|
||||
sql += "AND AP_APP_FAVOURITES.USER_NAME = ? ";
|
||||
}
|
||||
sql += "ORDER BY AP_APP.ID, LATEST_UPDATE DESC";
|
||||
|
||||
try {
|
||||
Connection conn = this.getDBConnection();
|
||||
@ -229,7 +236,10 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
|
||||
stmt.setInt(paramIndex++, filter.getLimit());
|
||||
stmt.setInt(paramIndex++, filter.getOffset());
|
||||
}
|
||||
stmt.setInt(paramIndex, tenantId);
|
||||
stmt.setInt(paramIndex++, tenantId);
|
||||
if (StringUtils.isNotEmpty(filter.getFavouredBy())) {
|
||||
stmt.setString(paramIndex, filter.getFavouredBy());
|
||||
}
|
||||
try (ResultSet rs = stmt.executeQuery()) {
|
||||
return DAOUtil.loadApplications(rs);
|
||||
}
|
||||
@ -732,6 +742,95 @@ public class GenericApplicationDAOImpl extends AbstractDAOImpl implements Applic
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAppToFavourite(int appId, String userName, int tenantId) throws ApplicationManagementDAOException {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Request received in DAO Layer to add app with the id " + appId + " favourites");
|
||||
}
|
||||
String sql = "INSERT INTO AP_APP_FAVOURITES "
|
||||
+ "(AP_APP_ID, USER_NAME, "
|
||||
+ " TENANT_ID) "
|
||||
+ "VALUES (?, ?, ?)";
|
||||
try {
|
||||
Connection conn = this.getDBConnection();
|
||||
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setInt(1, appId);
|
||||
stmt.setString(2, userName);
|
||||
stmt.setInt(3, tenantId);
|
||||
stmt.addBatch();
|
||||
stmt.executeUpdate();
|
||||
}
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while obtaining the DB connection when adding app to favourites";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
} catch (SQLException e) {
|
||||
String msg = "SQL Error occurred while adding app with the id " + appId + " to favourites. Executed Query: " + sql;
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAppFromFavourite(int appId, String userName, int tenantId) throws ApplicationManagementDAOException {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Request received in DAO Layer to add app with the id " + appId + " favourites");
|
||||
}
|
||||
String sql = "DELETE FROM AP_APP_FAVOURITES "
|
||||
+ "WHERE AP_APP_ID = ? "
|
||||
+ "AND USER_NAME = ? "
|
||||
+ "AND TENANT_ID = ?";
|
||||
try {
|
||||
Connection conn = this.getDBConnection();
|
||||
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setInt(1, appId);
|
||||
stmt.setString(2, userName);
|
||||
stmt.setInt(3, tenantId);
|
||||
stmt.addBatch();
|
||||
stmt.executeUpdate();
|
||||
}
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while obtaining the DB connection when removing app from favourites";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
} catch (SQLException e) {
|
||||
String msg = "SQL Error occurred while removing app with the id " + appId + " from favourites. Executed Query: " + sql;
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFavouriteApp(int appId, String userName, int tenantId) throws ApplicationManagementDAOException {
|
||||
String sql = "SELECT AP_APP_ID "
|
||||
+ "FROM AP_APP_FAVOURITES "
|
||||
+ "WHERE "
|
||||
+ "AP_APP_ID = ? AND "
|
||||
+ "USER_NAME = ? AND "
|
||||
+ "TENANT_ID = ?";
|
||||
try {
|
||||
Connection conn = this.getDBConnection();
|
||||
try (PreparedStatement stmt = conn.prepareStatement(sql)){
|
||||
stmt.setInt(1, appId);
|
||||
stmt.setString(2, userName);
|
||||
stmt.setInt(3, tenantId);
|
||||
try (ResultSet rs = stmt.executeQuery()){
|
||||
return rs.next();
|
||||
}
|
||||
}
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while obtaining the DB connection to check whether the application with the id "
|
||||
+ appId + " is a favourite app";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
} catch (SQLException e) {
|
||||
String msg = "SQL Error occurred while checking whether the application with the id "
|
||||
+ appId + " is a favourite app. executed query " + sql;
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTags(List<String> tags, int tenantId) throws ApplicationManagementDAOException {
|
||||
if (log.isDebugEnabled()) {
|
||||
|
||||
@ -82,10 +82,14 @@ public class OracleApplicationDAOImpl extends GenericApplicationDAOImpl {
|
||||
+ "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, "
|
||||
+ "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, "
|
||||
+ "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE "
|
||||
+ "FROM AP_APP "
|
||||
+ "LEFT JOIN AP_APP_RELEASE ON "
|
||||
+ "FROM AP_APP ";
|
||||
if (StringUtils.isNotEmpty(filter.getFavouredBy())) {
|
||||
sql += "INNER JOIN AP_APP_FAVOURITES ON "
|
||||
+ "AP_APP.ID = AP_APP_FAVOURITES.AP_APP_ID ";
|
||||
}
|
||||
sql += "LEFT JOIN AP_APP_RELEASE ON "
|
||||
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "
|
||||
+ "INNER JOIN (SELECT AP_APP.ID FROM AP_APP ORDER BY ID ";
|
||||
+ "INNER JOIN (SELECT AP_APP.ID FROM AP_APP ";
|
||||
if (StringUtils.isNotEmpty(filter.getVersion()) || StringUtils.isNotEmpty(filter.getAppReleaseState())
|
||||
|| StringUtils.isNotEmpty(filter.getAppReleaseType())) {
|
||||
sql += "LEFT JOIN AP_APP_RELEASE ON AP_APP.ID = AP_APP_RELEASE.AP_APP_ID ";
|
||||
|
||||
@ -81,8 +81,12 @@ public class SQLServerApplicationDAOImpl extends GenericApplicationDAOImpl {
|
||||
+ "AP_APP_RELEASE.CURRENT_STATE AS RELEASE_CURRENT_STATE, "
|
||||
+ "AP_APP_RELEASE.RATED_USERS AS RATED_USER_COUNT, "
|
||||
+ "NEW_AP_APP_LIFECYCLE_STATE.UPDATED_AT AS LATEST_UPDATE "
|
||||
+ "FROM AP_APP "
|
||||
+ "LEFT JOIN AP_APP_RELEASE ON "
|
||||
+ "FROM AP_APP ";
|
||||
if (StringUtils.isNotEmpty(filter.getFavouredBy())) {
|
||||
sql += "INNER JOIN AP_APP_FAVOURITES ON "
|
||||
+ "AP_APP.ID = AP_APP_FAVOURITES.AP_APP_ID ";
|
||||
}
|
||||
sql += "LEFT JOIN AP_APP_RELEASE ON "
|
||||
+ "AP_APP.ID = AP_APP_RELEASE.AP_APP_ID "
|
||||
+ "INNER JOIN (SELECT AP_APP.ID FROM AP_APP ";
|
||||
if (StringUtils.isNotEmpty(filter.getVersion()) || StringUtils.isNotEmpty(filter.getAppReleaseState())
|
||||
|
||||
@ -691,6 +691,68 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeviceIdForSubId(int subId, int tenantId) throws ApplicationManagementDAOException {
|
||||
try {
|
||||
Connection conn = this.getDBConnection();
|
||||
String sql = "SELECT DM_DEVICE_ID "
|
||||
+ "FROM AP_DEVICE_SUBSCRIPTION "
|
||||
+ "WHERE ID = ? AND "
|
||||
+ "TENANT_ID = ?";
|
||||
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setInt(1, subId);
|
||||
stmt.setInt(2, tenantId);
|
||||
try (ResultSet rs = stmt.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
return rs.getInt("DM_DEVICE_ID");
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while obtaining the DB connection to get app operation ids for given "
|
||||
+ "subscription id.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
} catch (SQLException e) {
|
||||
String msg = "Error occurred when processing SQL to get operation ids for given subscription id.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getOperationIdsForSubId(int subId, int tenantId) throws ApplicationManagementDAOException {
|
||||
try {
|
||||
Connection conn = this.getDBConnection();
|
||||
List<Integer> operationIds = new ArrayList<>();
|
||||
String sql = "SELECT OPERATION_ID "
|
||||
+ "FROM AP_APP_SUB_OP_MAPPING "
|
||||
+ "WHERE AP_DEVICE_SUBSCRIPTION_ID = ? AND "
|
||||
+ "TENANT_ID = ?";
|
||||
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||
stmt.setInt(1, subId);
|
||||
stmt.setInt(2, tenantId);
|
||||
try (ResultSet rs = stmt.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
operationIds.add(rs.getInt("OPERATION_ID"));
|
||||
}
|
||||
}
|
||||
return operationIds;
|
||||
}
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while obtaining the DB connection to get app operation ids for given "
|
||||
+ "subscription id.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
} catch (SQLException e) {
|
||||
String msg = "Error occurred when processing SQL to get operation ids for given subscription id.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Integer> getDeviceSubIdsForOperation(int operationId, int deviceId, int tenantId)
|
||||
throws ApplicationManagementDAOException {
|
||||
@ -1204,7 +1266,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
||||
Connection conn = this.getDBConnection();
|
||||
List<String> subscribedGroups = new ArrayList<>();
|
||||
String sql = "SELECT "
|
||||
+ "GS.GROUP_NAME AS GROUPS "
|
||||
+ "GS.GROUP_NAME AS APP_GROUPS "
|
||||
+ "FROM AP_GROUP_SUBSCRIPTION GS "
|
||||
+ "WHERE "
|
||||
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ? LIMIT ? OFFSET ?";
|
||||
@ -1215,7 +1277,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
||||
ps.setInt(4, offsetValue);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
subscribedGroups.add(rs.getString("GROUPS"));
|
||||
subscribedGroups.add(rs.getString("APP_GROUPS"));
|
||||
}
|
||||
}
|
||||
return subscribedGroups;
|
||||
@ -1244,7 +1306,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
||||
try {
|
||||
Connection conn = this.getDBConnection();
|
||||
String sql = "SELECT "
|
||||
+ "COUNT(GS.GROUP_NAME) AS GROUPS "
|
||||
+ "COUNT(GS.GROUP_NAME) AS APP_GROUPS_COUNT "
|
||||
+ "FROM AP_GROUP_SUBSCRIPTION GS "
|
||||
+ "WHERE "
|
||||
+ "AP_APP_RELEASE_ID = ? AND TENANT_ID = ?";
|
||||
@ -1254,7 +1316,7 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
||||
|
||||
try (ResultSet rs = stmt.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
return rs.getInt("GROUPS");
|
||||
return rs.getInt("APP_GROUPS_COUNT");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -1311,4 +1373,66 @@ public class GenericSubscriptionDAOImpl extends AbstractDAOImpl implements Subsc
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer,String> getCurrentInstalledAppVersion(int appId, List<Integer> deviceIdList, String installedVersion ) throws ApplicationManagementDAOException {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Request received in DAO Layer to get current installed version of the app for " +
|
||||
"given app release id.");
|
||||
}
|
||||
try {
|
||||
|
||||
Map<Integer,String> installedVersionsMap = new HashMap<>();
|
||||
Connection conn = this.getDBConnection();
|
||||
int index = 1;
|
||||
boolean isInstalledVersionAvailable = false;
|
||||
StringJoiner joiner = new StringJoiner(",",
|
||||
" SELECT DM_DEVICE_ID AS DEVICE,VERSION FROM " +
|
||||
" (SELECT AP_APP.ID, VERSION FROM AP_APP_RELEASE AP_APP " +
|
||||
" WHERE ID IN (SELECT ID FROM AP_APP_RELEASE " +
|
||||
" WHERE AP_APP_ID = ?) " +
|
||||
" ) AP_APP_V" +
|
||||
" INNER JOIN " +
|
||||
" (SELECT AP_APP_RELEASE_ID, DM_DEVICE_ID FROM AP_DEVICE_SUBSCRIPTION AP_DEV_1 " +
|
||||
" INNER JOIN (" +
|
||||
" SELECT MAX(ID) AS ID FROM AP_DEVICE_SUBSCRIPTION " +
|
||||
" WHERE STATUS = 'COMPLETED' AND DM_DEVICE_ID IN (",
|
||||
") GROUP BY DM_DEVICE_ID " +
|
||||
") AP_DEV_2 " +
|
||||
"ON AP_DEV_2.ID = AP_DEV_1.ID ) AP_APP_R " +
|
||||
"ON AP_APP_R.AP_APP_RELEASE_ID = AP_APP_V.ID");
|
||||
deviceIdList.stream().map(ignored -> "?").forEach(joiner::add);
|
||||
String query = joiner.toString();
|
||||
if(installedVersion != null && !installedVersion.isEmpty()){
|
||||
query += " WHERE VERSION = ? ";
|
||||
isInstalledVersionAvailable = true;
|
||||
}
|
||||
try (PreparedStatement ps = conn.prepareStatement(query)) {
|
||||
ps.setInt(index++, appId);
|
||||
for (int deviceId : deviceIdList) {
|
||||
ps.setInt(index++, deviceId);
|
||||
}
|
||||
if(isInstalledVersionAvailable){
|
||||
ps.setString(index++, installedVersion);
|
||||
}
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
installedVersionsMap.put(rs.getInt("DEVICE"),rs.getString("VERSION"));
|
||||
}
|
||||
}
|
||||
return installedVersionsMap;
|
||||
}
|
||||
|
||||
}catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while obtaining the DB connection to get current installed version of the app for " +
|
||||
"given app id.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
} catch (SQLException e) {
|
||||
String msg = "SQL Error occurred while getting current installed version of the app for given " +
|
||||
"app id.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementDAOException(msg, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -316,6 +316,116 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
||||
return applicationDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAppToFavourites(int appId) throws ApplicationManagementException {
|
||||
validateAddAppToFavouritesRequest(appId);
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
|
||||
try {
|
||||
ConnectionManagerUtil.beginDBTransaction();
|
||||
applicationDAO.addAppToFavourite(appId, userName, tenantId);
|
||||
ConnectionManagerUtil.commitDBTransaction();
|
||||
} catch (TransactionManagementException e) {
|
||||
String msg = "Error occurred while staring transaction to add applicationId: "
|
||||
+ appId + " to favourites";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while adding application id " + appId + " to favourites ";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} catch (ApplicationManagementDAOException e) {
|
||||
ConnectionManagerUtil.rollbackDBTransaction();
|
||||
String msg = "Error occurred while adding application with the id: " + appId + " to favourites ";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} finally {
|
||||
ConnectionManagerUtil.closeDBConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAppFromFavourites(int appId) throws ApplicationManagementException {
|
||||
validateRemoveAppFromFavouritesRequest(appId);
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
|
||||
try {
|
||||
ConnectionManagerUtil.beginDBTransaction();
|
||||
applicationDAO.removeAppFromFavourite(appId, userName, tenantId);
|
||||
ConnectionManagerUtil.commitDBTransaction();
|
||||
} catch (TransactionManagementException e) {
|
||||
String msg = "Error occurred while staring transaction to remove applicationId: "
|
||||
+ appId + " from favourites";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while removing application id " + appId + " from favourites ";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} catch (ApplicationManagementDAOException e) {
|
||||
ConnectionManagerUtil.rollbackDBTransaction();
|
||||
String msg = "Error occurred while removing application with the id: " + appId + " from favourites ";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} finally {
|
||||
ConnectionManagerUtil.closeDBConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFavouriteApp(int appId) throws ApplicationManagementException{
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
|
||||
try {
|
||||
ConnectionManagerUtil.openDBConnection();
|
||||
return applicationDAO.isFavouriteApp(appId, userName, tenantId);
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while getting DB connection to check is app with the id " + appId
|
||||
+ " is a favourite app";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} catch (ApplicationManagementDAOException e) {
|
||||
String msg = "Error occurred while checking app with the id " + appId + " is a favourite app.";
|
||||
log.error(msg);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} finally {
|
||||
ConnectionManagerUtil.closeDBConnection();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to check if the requested application id is valid before removing from favourites
|
||||
*
|
||||
* @param appId ID of the application
|
||||
* @throws ApplicationManagementException if ID is not valid or errors while validating
|
||||
*/
|
||||
private void validateRemoveAppFromFavouritesRequest(int appId) throws ApplicationManagementException {
|
||||
if (!isFavouriteApp(appId)) {
|
||||
String msg = "Provided appId " + appId + " is not a favourite app in order remove from favourites";
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to check if the requested application id is valid before adding to favourites
|
||||
*
|
||||
* @param appId ID of the application
|
||||
* @throws ApplicationManagementException if ID is not valid or errors while validating
|
||||
*/
|
||||
private void validateAddAppToFavouritesRequest(int appId) throws ApplicationManagementException {
|
||||
try {
|
||||
getApplication(appId);
|
||||
} catch (NotFoundException e) {
|
||||
String msg = " No application exists for the provided appId " + appId;
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
if (isFavouriteApp(appId)) {
|
||||
String msg = "Provided appId " + appId + " is already a favourite app";
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload enterprise application release artifact into file system.
|
||||
*
|
||||
@ -817,9 +927,17 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
||||
return applicationReleaseDTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationList getFavouriteApplications(Filter filter) throws ApplicationManagementException {
|
||||
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
|
||||
filter.setFavouredBy(userName);
|
||||
return getApplications(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationList getApplications(Filter filter) throws ApplicationManagementException {
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
||||
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
|
||||
ApplicationList applicationList = new ApplicationList();
|
||||
List<Application> applications = new ArrayList<>();
|
||||
DeviceType deviceType;
|
||||
@ -845,6 +963,7 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
||||
.setUnrestrictedRoles(visibilityDAO.getUnrestrictedRoles(applicationDTO.getId(), tenantId));
|
||||
applicationDTO.setAppCategories(applicationDAO.getAppCategories(applicationDTO.getId(), tenantId));
|
||||
applicationDTO.setTags(applicationDAO.getAppTags(applicationDTO.getId(), tenantId));
|
||||
applicationDTO.setFavourite(applicationDAO.isFavouriteApp(applicationDTO.getId(), userName, tenantId));
|
||||
|
||||
if (isFilteringApp(applicationDTO, filter)) {
|
||||
boolean isHideableApp = isHideableApp(applicationDTO.getApplicationReleaseDTOs());
|
||||
@ -2020,6 +2139,61 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
||||
}
|
||||
}
|
||||
|
||||
public ApplicationRelease changeLifecycleState(ApplicationReleaseDTO applicationReleaseDTO, LifecycleChanger lifecycleChanger) throws ApplicationManagementException {
|
||||
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
String userName = PrivilegedCarbonContext.getThreadLocalCarbonContext().getUsername();
|
||||
if (lifecycleChanger == null || StringUtils.isEmpty(lifecycleChanger.getAction())) {
|
||||
String msg = "The Action is null or empty. Please verify the request.";
|
||||
log.error(msg);
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
|
||||
try{
|
||||
if (lifecycleStateManager
|
||||
.isValidStateChange(applicationReleaseDTO.getCurrentState(), lifecycleChanger.getAction(), userName,
|
||||
tenantId)) {
|
||||
if (lifecycleStateManager.isInstallableState(lifecycleChanger.getAction()) && applicationReleaseDAO
|
||||
.hasExistInstallableAppRelease(applicationReleaseDTO.getUuid(),
|
||||
lifecycleStateManager.getInstallableState(), tenantId)) {
|
||||
String msg = "Installable application release is already registered for the application. "
|
||||
+ "Therefore it is not permitted to change the lifecycle state from "
|
||||
+ applicationReleaseDTO.getCurrentState() + " to " + lifecycleChanger.getAction();
|
||||
log.error(msg);
|
||||
throw new ForbiddenException(msg);
|
||||
}
|
||||
LifecycleState lifecycleState = new LifecycleState();
|
||||
lifecycleState.setCurrentState(lifecycleChanger.getAction());
|
||||
lifecycleState.setPreviousState(applicationReleaseDTO.getCurrentState());
|
||||
lifecycleState.setUpdatedBy(userName);
|
||||
lifecycleState.setReasonForChange(lifecycleChanger.getReason());
|
||||
applicationReleaseDTO.setCurrentState(lifecycleChanger.getAction());
|
||||
if (this.applicationReleaseDAO.updateRelease(applicationReleaseDTO, tenantId) == null) {
|
||||
String msg = "Application release updating is failed/.";
|
||||
log.error(msg);
|
||||
throw new ApplicationManagementException(msg);
|
||||
}
|
||||
this.lifecycleStateDAO.addLifecycleState(lifecycleState, applicationReleaseDTO.getId(), tenantId);
|
||||
return APIUtil.releaseDtoToRelease(applicationReleaseDTO);
|
||||
} else {
|
||||
String msg = "Invalid lifecycle state transition from '" + applicationReleaseDTO.getCurrentState() + "'"
|
||||
+ " to '" + lifecycleChanger.getAction() + "'";
|
||||
log.error(msg);
|
||||
throw new ApplicationManagementException(msg);
|
||||
}
|
||||
} catch (ApplicationManagementDAOException e) {
|
||||
String msg = "Error occurred when accessing application release data of application release which has the "
|
||||
+ "application release UUID: " + applicationReleaseDTO.getUuid();
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} catch (LifeCycleManagementDAOException e) {
|
||||
String msg = "Failed to add lifecycle state for Application release UUID: " + applicationReleaseDTO.getUuid();
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addApplicationCategories(List<String> categories) throws ApplicationManagementException {
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
@ -3651,7 +3825,40 @@ public class ApplicationManagerImpl implements ApplicationManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSubsStatus (int deviceId, int operationId, String status) throws ApplicationManagementException {
|
||||
public void updateSubStatus(int deviceId, List<Integer> operationIds, String status) throws ApplicationManagementException {
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
||||
try {
|
||||
ConnectionManagerUtil.beginDBTransaction();
|
||||
for (int operationId : operationIds) {
|
||||
List<Integer> deviceSubIds = subscriptionDAO.getDeviceSubIdsForOperation(operationId, deviceId, tenantId);
|
||||
if (!subscriptionDAO.updateDeviceSubStatus(deviceId, deviceSubIds, status, tenantId)){
|
||||
ConnectionManagerUtil.rollbackDBTransaction();
|
||||
String msg = "Didn't update an any app subscription of device for operation Id: " + operationId;
|
||||
log.error(msg);
|
||||
throw new ApplicationManagementException(msg);
|
||||
}
|
||||
}
|
||||
ConnectionManagerUtil.commitDBTransaction();
|
||||
} catch (ApplicationManagementDAOException e) {
|
||||
String msg = "Error occured while updating app subscription status of the device.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while obersving the database connection to update aoo subscription status of "
|
||||
+ "device.";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} catch (TransactionManagementException e) {
|
||||
String msg = "Error occurred while executing database transaction";
|
||||
log.error(msg, e);
|
||||
throw new ApplicationManagementException(msg, e);
|
||||
} finally {
|
||||
ConnectionManagerUtil.closeDBConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSubsStatus(int deviceId, int operationId, String status) throws ApplicationManagementException {
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
|
||||
try {
|
||||
ConnectionManagerUtil.beginDBTransaction();
|
||||
|
||||
@ -20,6 +20,7 @@ package io.entgra.application.mgt.core.impl;
|
||||
import com.google.gson.Gson;
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
import org.apache.commons.httpclient.HttpException;
|
||||
import org.apache.commons.httpclient.HttpMethodBase;
|
||||
import org.apache.commons.httpclient.methods.PostMethod;
|
||||
import org.apache.commons.httpclient.methods.StringRequestEntity;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
@ -1189,18 +1190,62 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
||||
}
|
||||
}
|
||||
|
||||
public int installEnrollmentApplications(ApplicationPolicyDTO applicationPolicyDTO)
|
||||
throws ApplicationManagementException {
|
||||
|
||||
HttpClient httpClient;
|
||||
PostMethod request;
|
||||
@Override
|
||||
public void updateSubscriptionStatus(int deviceId, int subId, String status)
|
||||
throws SubscriptionManagementException {
|
||||
try {
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
List<Integer> operationIds = getOperationIdsForSubId(subId, tenantId);
|
||||
APIUtil.getApplicationManager().updateSubStatus(deviceId, operationIds, status);
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while observing the database connection to get operation Ids for " + subId;
|
||||
log.error(msg, e);
|
||||
throw new SubscriptionManagementException(msg, e);
|
||||
} catch (ApplicationManagementException e) {
|
||||
String msg = "Error occurred while updating subscription status with the id: "
|
||||
+ subId;
|
||||
log.error(msg, e);
|
||||
throw new SubscriptionManagementException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Integer> getOperationIdsForSubId(int subId, int tenantId) throws SubscriptionManagementException {
|
||||
try {
|
||||
ConnectionManagerUtil.openDBConnection();
|
||||
return subscriptionDAO.getOperationIdsForSubId(subId, tenantId);
|
||||
} catch (ApplicationManagementDAOException e) {
|
||||
String msg = "Error occurred while getting operation Ids for subId" + subId;
|
||||
log.error(msg, e);
|
||||
throw new SubscriptionManagementException(msg, e);
|
||||
} catch (DBConnectionException e) {
|
||||
String msg = "Error occurred while observing the database connection to get operation Ids for " + subId;
|
||||
log.error(msg, e);
|
||||
throw new SubscriptionManagementException(msg, e);
|
||||
} finally {
|
||||
ConnectionManagerUtil.closeDBConnection();
|
||||
}
|
||||
}
|
||||
|
||||
private int invokeIOTCoreAPI(HttpMethodBase request) throws UserStoreException, APIManagerException, IOException {
|
||||
HttpClient httpClient;
|
||||
String tenantDomain = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantDomain();
|
||||
ApiApplicationKey apiApplicationKey = OAuthUtils.getClientCredentials(tenantDomain);
|
||||
String username =
|
||||
PrivilegedCarbonContext.getThreadLocalCarbonContext().getUserRealm().getRealmConfiguration()
|
||||
.getAdminUserName() + Constants.ApplicationInstall.AT + tenantDomain;
|
||||
AccessTokenInfo tokenInfo = OAuthUtils.getOAuthCredentials(apiApplicationKey, username);
|
||||
request.addRequestHeader(Constants.ApplicationInstall.AUTHORIZATION,
|
||||
Constants.ApplicationInstall.AUTHORIZATION_HEADER_VALUE + tokenInfo.getAccessToken());
|
||||
httpClient = new HttpClient();
|
||||
httpClient.executeMethod(request);
|
||||
return request.getStatusCode();
|
||||
}
|
||||
|
||||
public int installEnrollmentApplications(ApplicationPolicyDTO applicationPolicyDTO)
|
||||
throws ApplicationManagementException {
|
||||
|
||||
PostMethod request;
|
||||
try {
|
||||
String requestUrl = Constants.ApplicationInstall.ENROLLMENT_APP_INSTALL_PROTOCOL + System
|
||||
.getProperty(Constants.ApplicationInstall.IOT_CORE_HOST) + Constants.ApplicationInstall.COLON
|
||||
+ System.getProperty(Constants.ApplicationInstall.IOT_CORE_PORT)
|
||||
@ -1210,14 +1255,9 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
||||
|
||||
StringRequestEntity requestEntity = new StringRequestEntity(payload, MediaType.APPLICATION_JSON,
|
||||
Constants.ApplicationInstall.ENCODING);
|
||||
httpClient = new HttpClient();
|
||||
request = new PostMethod(requestUrl);
|
||||
request.addRequestHeader(Constants.ApplicationInstall.AUTHORIZATION,
|
||||
Constants.ApplicationInstall.AUTHORIZATION_HEADER_VALUE + tokenInfo.getAccessToken());
|
||||
request.setRequestEntity(requestEntity);
|
||||
httpClient.executeMethod(request);
|
||||
return request.getStatusCode();
|
||||
|
||||
return invokeIOTCoreAPI(request);
|
||||
} catch (UserStoreException e) {
|
||||
String msg = "Error while accessing user store for user with Android device.";
|
||||
log.error(msg, e);
|
||||
@ -1240,6 +1280,13 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
||||
}
|
||||
}
|
||||
|
||||
private String getIOTCoreBaseUrl() {
|
||||
return Constants.HTTPS_PROTOCOL + Constants.SCHEME_SEPARATOR + System
|
||||
.getProperty(Constants.IOT_CORE_HOST) + Constants.COLON
|
||||
+ System.getProperty(Constants.IOT_CORE_HTTPS_PORT);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PaginationResult getAppInstalledDevices(PaginationRequest request, String appUUID)
|
||||
throws ApplicationManagementException {
|
||||
@ -1361,7 +1408,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
||||
|
||||
@Override
|
||||
public PaginationResult getAppSubscriptionDetails(PaginationRequest request, String appUUID, String actionStatus,
|
||||
String action) throws ApplicationManagementException {
|
||||
String action, String installedVersion) throws ApplicationManagementException {
|
||||
int limitValue = request.getRowCount();
|
||||
int offsetValue = request.getStartIndex();
|
||||
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(true);
|
||||
@ -1395,6 +1442,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
||||
}
|
||||
List<Integer> deviceIdList = deviceSubscriptionDTOS.stream().map(DeviceSubscriptionDTO::getDeviceId)
|
||||
.collect(Collectors.toList());
|
||||
Map<Integer,String> currentVersionsMap = subscriptionDAO.getCurrentInstalledAppVersion(applicationDTO.getId(),deviceIdList, installedVersion);
|
||||
try {
|
||||
//pass the device id list to device manager service method
|
||||
PaginationResult paginationResult = deviceManagementProviderService.getAppSubscribedDevices
|
||||
@ -1404,7 +1452,15 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
||||
if (!paginationResult.getData().isEmpty()) {
|
||||
List<Device> devices = (List<Device>) paginationResult.getData();
|
||||
for (Device device : devices) {
|
||||
if(installedVersion != null && !installedVersion.isEmpty() && !currentVersionsMap.containsKey(device.getId())){
|
||||
continue;
|
||||
}
|
||||
DeviceSubscriptionData deviceSubscriptionData = new DeviceSubscriptionData();
|
||||
if(currentVersionsMap.containsKey(device.getId())){
|
||||
deviceSubscriptionData.setCurrentInstalledVersion(currentVersionsMap.get(device.getId()));
|
||||
}else{
|
||||
deviceSubscriptionData.setCurrentInstalledVersion("-");
|
||||
}
|
||||
for (DeviceSubscriptionDTO subscription : deviceSubscriptionDTOS) {
|
||||
if (subscription.getDeviceId() == device.getId()) {
|
||||
deviceSubscriptionData.setDevice(device);
|
||||
@ -1421,6 +1477,7 @@ public class SubscriptionManagerImpl implements SubscriptionManager {
|
||||
}
|
||||
deviceSubscriptionData.setActionType(subscription.getActionTriggeredFrom());
|
||||
deviceSubscriptionData.setStatus(subscription.getStatus());
|
||||
deviceSubscriptionData.setSubId(subscription.getId());
|
||||
deviceSubscriptionDataList.add(deviceSubscriptionData);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -414,6 +414,7 @@ public class APIUtil {
|
||||
application.setTags(applicationDTO.getTags());
|
||||
application.setUnrestrictedRoles(applicationDTO.getUnrestrictedRoles());
|
||||
application.setRating(applicationDTO.getAppRating());
|
||||
application.setFavourite(applicationDTO.isFavourite());
|
||||
if (applicationDTO.getApplicationReleaseDTOs() != null && !applicationDTO.getApplicationReleaseDTOs().isEmpty()) {
|
||||
application.setInstallerName(applicationDTO.getApplicationReleaseDTOs().get(0).getInstallerName());
|
||||
}
|
||||
|
||||
@ -49,6 +49,9 @@ public class Constants {
|
||||
public static final String IOT_CORE_HTTPS_PORT = "iot.core.https.port";
|
||||
public static final String HTTPS_PROTOCOL = "https";
|
||||
public static final String HTTP_PROTOCOL = "http";
|
||||
public static final String SCHEME_SEPARATOR = "://";
|
||||
public static final String OPERATION_STATUS_UPDATE_API_BASE = "/api/device-mgt/v1.0/devices";
|
||||
public static final String OPERATION_STATUS_UPDATE_API_URI = "/operation";
|
||||
|
||||
public static final String LIMIT_QUERY_PARAM = "limit";
|
||||
public static final String OFFSET_QUERY_PARAM = "offset";
|
||||
@ -59,6 +62,7 @@ public class Constants {
|
||||
public static final String IS_APP_RELEASE_TYPE = "stable";
|
||||
public static final String IS_APP_DEFAULT_PAYMENT_CURRENCY = "$";
|
||||
public static final String IS_APP_DEFAULT_VERSION = "1.0";
|
||||
public static final String COLON = ":";
|
||||
public static final String FORWARD_SLASH = "/";
|
||||
public static final String URI_QUERY_SEPARATOR = "?";
|
||||
public static final String QUERY_STRING_SEPARATOR = "&";
|
||||
|
||||
@ -120,7 +120,6 @@ public class ApplicationManagementTest extends BaseTestCase {
|
||||
screenshots.put("shot3", new FileInputStream(new File("src/test/resources/samples/app1/shot3.png")));
|
||||
|
||||
applicationArtifact.setScreenshots(screenshots);
|
||||
|
||||
ApplicationManager manager = new ApplicationManagerImpl();
|
||||
manager.createApplication(applicationWrapper);
|
||||
}
|
||||
@ -140,6 +139,11 @@ public class ApplicationManagementTest extends BaseTestCase {
|
||||
return new Object[][] {{"TEST_APP_UUID"}};
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
public void createApplicationAndPublish(ApplicationWrapper applicationWrapper, ApplicationArtifact applicationArtifact, boolean isPublish) throws ApplicationManagementException {
|
||||
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
public void updateApplication(int applicationId, ApplicationUpdateWrapper applicationUpdateWrapper) throws ApplicationManagementException {
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>application-mgt</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>application-mgt</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
package io.entgra.application.mgt.store.api.beans;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
/**
|
||||
* This is used to map the status of subscription.
|
||||
*/
|
||||
@ApiModel(
|
||||
value = "SubscriptionStatusBean",
|
||||
description = "This class carries all information related map statuses of the subscription."
|
||||
)
|
||||
public class SubscriptionStatusBean {
|
||||
@ApiModelProperty(
|
||||
name = "sub id",
|
||||
value = "Subscription Id.",
|
||||
required = true
|
||||
)
|
||||
private int subId;
|
||||
|
||||
@ApiModelProperty(
|
||||
name = "status",
|
||||
value = "Status of the subscription.",
|
||||
required = true
|
||||
)
|
||||
private String status;
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public int getSubId() {
|
||||
return subId;
|
||||
}
|
||||
|
||||
public void setSubId(int subId) {
|
||||
this.subId = subId;
|
||||
}
|
||||
}
|
||||
@ -35,8 +35,10 @@ import io.entgra.application.mgt.common.ApplicationList;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
@ -70,6 +72,13 @@ import javax.ws.rs.core.Response;
|
||||
key = "perm:app:store:view",
|
||||
roles = {"Internal/devicemgt-user"},
|
||||
permissions = {"/app-mgt/store/application/view"}
|
||||
),
|
||||
@Scope(
|
||||
name = "Modify Application",
|
||||
description = "Modify application state",
|
||||
key = "perm:app:store:modify",
|
||||
roles = {"Internal/devicemgt-user"},
|
||||
permissions = {"/app-mgt/store/application/modify"}
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -81,6 +90,120 @@ public interface ApplicationManagementAPI {
|
||||
|
||||
String SCOPE = "scope";
|
||||
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/favourite/{appId}")
|
||||
@ApiOperation(
|
||||
consumes = MediaType.APPLICATION_JSON,
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "POST",
|
||||
value = "add application to favourites",
|
||||
notes = "This will add application to favourites",
|
||||
tags = "Application Management",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:app:store:modify")
|
||||
})
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
code = 200,
|
||||
message = "OK. \n Successfully added application to favourites.",
|
||||
response = ApplicationList.class),
|
||||
@ApiResponse(
|
||||
code = 400,
|
||||
message = "Bad Request. \n " +
|
||||
"Payload contains unacceptable or vulnerable data"),
|
||||
@ApiResponse(
|
||||
code = 500,
|
||||
message = "Internal Server Error. \n Error occurred while adding the application to favourites.",
|
||||
response = ErrorResponse.class)
|
||||
})
|
||||
Response addAppToFavourite(
|
||||
@ApiParam(
|
||||
name = "appId",
|
||||
value = "id of the application",
|
||||
required = true)
|
||||
@PathParam("appId") int appId);
|
||||
|
||||
@DELETE
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/favourite/{appId}")
|
||||
@ApiOperation(
|
||||
consumes = MediaType.APPLICATION_JSON,
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "DELETE",
|
||||
value = "remove application from favourites",
|
||||
notes = "This will removing an application from favourites",
|
||||
tags = "Application Management",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:app:store:modify")
|
||||
})
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
code = 200,
|
||||
message = "OK. \n Successfully removed application from favourites.",
|
||||
response = ApplicationList.class),
|
||||
@ApiResponse(
|
||||
code = 400,
|
||||
message = "Bad Request. \n " +
|
||||
"Payload contains unacceptable or vulnerable data"),
|
||||
@ApiResponse(
|
||||
code = 500,
|
||||
message = "Internal Server Error. \n Error occurred while removing the application from favourites.",
|
||||
response = ErrorResponse.class)
|
||||
})
|
||||
Response removeAppFromFavourite(
|
||||
@ApiParam(
|
||||
name = "appId",
|
||||
value = "id of the application",
|
||||
required = true)
|
||||
@PathParam("appId") int appId);
|
||||
|
||||
@POST
|
||||
@Path("/favourite")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(
|
||||
consumes = MediaType.APPLICATION_JSON,
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "GET",
|
||||
value = "get all favourite applications",
|
||||
notes = "This will get all favourite applications",
|
||||
tags = "Application Management",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:app:store:view")
|
||||
})
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
code = 200,
|
||||
message = "OK. \n Successfully got application list.",
|
||||
response = ApplicationList.class),
|
||||
@ApiResponse(
|
||||
code = 400,
|
||||
message = "Bad Request. \n " +
|
||||
"Application retrieving request payload contains unacceptable or vulnerable data"),
|
||||
@ApiResponse(
|
||||
code = 500,
|
||||
message = "Internal Server Error. \n Error occurred while getting the application list.",
|
||||
response = ErrorResponse.class)
|
||||
})
|
||||
Response getFavouriteApplications(
|
||||
@ApiParam(
|
||||
name = "filter",
|
||||
value = "Application filtering data",
|
||||
required = true)
|
||||
@Valid Filter filter);
|
||||
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
*/
|
||||
package io.entgra.application.mgt.store.api.services.admin;
|
||||
|
||||
import io.entgra.application.mgt.store.api.beans.SubscriptionStatusBean;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
@ -34,6 +35,7 @@ import io.entgra.application.mgt.common.ErrorResponse;
|
||||
import javax.validation.constraints.Size;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
@ -69,6 +71,13 @@ import java.util.List;
|
||||
key = "perm:admin:app:subscription:view",
|
||||
roles = {"Internal/devicemgt-admin"},
|
||||
permissions = {"/app-mgt/store/admin/subscription/view"}
|
||||
),
|
||||
@Scope(
|
||||
name = "View Application Subscriptions",
|
||||
description = "View Application Subscriptions.",
|
||||
key = "perm:admin:app:subscription:modify",
|
||||
roles = {"Internal/devicemgt-admin"},
|
||||
permissions = {"/app-mgt/store/admin/subscription/modify"}
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -79,6 +88,51 @@ public interface SubscriptionManagementAdminAPI {
|
||||
|
||||
String SCOPE = "scope";
|
||||
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/device/{deviceId}/status")
|
||||
@ApiOperation(
|
||||
consumes = MediaType.APPLICATION_JSON,
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
httpMethod = "PUT",
|
||||
value = "Update subscription status",
|
||||
notes = "This will update the subscription status that belongs to the given device id",
|
||||
tags = "Subscription Management",
|
||||
extensions = {
|
||||
@Extension(properties = {
|
||||
@ExtensionProperty(name = SCOPE, value = "perm:admin:app:subscription:modify")
|
||||
})
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(
|
||||
code = 200,
|
||||
message = "OK. \n Successfully updated subscription status.",
|
||||
response = List.class,
|
||||
responseContainer = "List"),
|
||||
@ApiResponse(
|
||||
code = 404,
|
||||
message = "Not Found. \n No Application found which has application release of UUID.",
|
||||
response = ErrorResponse.class),
|
||||
@ApiResponse(
|
||||
code = 500,
|
||||
message = "Internal Server Error. \n Error occurred while updating subscription status",
|
||||
response = ErrorResponse.class)
|
||||
})
|
||||
Response updateSubscription(
|
||||
@ApiParam(
|
||||
name = "deviceId",
|
||||
value = "Id of the device",
|
||||
required = true)
|
||||
@PathParam("deviceId") int deviceId,
|
||||
@ApiParam(
|
||||
name = "subscription status change bean",
|
||||
value = "this bean contains the information related to status change",
|
||||
required = true)
|
||||
SubscriptionStatusBean subscriptionStatusBean
|
||||
);
|
||||
|
||||
@GET
|
||||
@Path("/{uuid}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ -139,6 +193,10 @@ public interface SubscriptionManagementAdminAPI {
|
||||
name = "status",
|
||||
value = "Provide the device status details, such as active or inactive.")
|
||||
@QueryParam("status") List<String> status,
|
||||
@ApiParam(
|
||||
name = "installedVersion",
|
||||
value = "Provide the installed version of the application.")
|
||||
@QueryParam("installedVersion") String installedVersion,
|
||||
@ApiParam(
|
||||
name = "uuid",
|
||||
value = "uuid of the application release.",
|
||||
|
||||
@ -28,14 +28,15 @@ import io.entgra.application.mgt.core.exception.NotFoundException;
|
||||
import io.entgra.application.mgt.core.exception.UnexpectedServerErrorException;
|
||||
import io.entgra.application.mgt.core.util.APIUtil;
|
||||
import io.entgra.application.mgt.store.api.services.ApplicationManagementAPI;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
/**
|
||||
@ -47,30 +48,88 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI {
|
||||
|
||||
private static final Log log = LogFactory.getLog(ApplicationManagementAPIImpl.class);
|
||||
|
||||
@POST
|
||||
@Path("/favourite/{appId}")
|
||||
@Override
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Response addAppToFavourite(@PathParam("appId") int appId) {
|
||||
ApplicationManager applicationManager = APIUtil.getApplicationManager();
|
||||
try {
|
||||
applicationManager.addAppToFavourites(appId);
|
||||
return Response.status(Response.Status.OK).build();
|
||||
} catch (BadRequestException e) {
|
||||
String msg = "Invalid payload found in the request. Hence verify the request payload.";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
||||
} catch (ApplicationManagementException e) {
|
||||
String msg = "Error occurred while adding application to favourites";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||
}
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/favourite/{appId}")
|
||||
@Override
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Response removeAppFromFavourite(@PathParam("appId") int appId) {
|
||||
ApplicationManager applicationManager = APIUtil.getApplicationManager();
|
||||
try {
|
||||
applicationManager.removeAppFromFavourites(appId);
|
||||
return Response.status(Response.Status.OK).build();
|
||||
} catch (BadRequestException e) {
|
||||
String msg = "Invalid payload found in the request. Hence verify the request payload.";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
||||
} catch (ApplicationManagementException e) {
|
||||
String msg = "Error occurred while removing application from favourites";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/favourite")
|
||||
@Override
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Response getFavouriteApplications(@Valid Filter filter) {
|
||||
ApplicationManager applicationManager = APIUtil.getApplicationManager();
|
||||
try {
|
||||
validateFilter(filter);
|
||||
ApplicationList applications = applicationManager.getFavouriteApplications(filter);
|
||||
return Response.status(Response.Status.OK).entity(applications).build();
|
||||
} catch (BadRequestException e) {
|
||||
String msg = "Invalid filter payload found in the request. Hence verify the filter payload.";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
||||
} catch (ApplicationManagementException e) {
|
||||
String msg = "Error occurred while retrieving favourite applications";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Override
|
||||
@Consumes("application/json")
|
||||
public Response getApplications(@Valid Filter filter) {
|
||||
ApplicationManager applicationManager = APIUtil.getApplicationManager();
|
||||
try {
|
||||
if (filter == null) {
|
||||
String msg = "Request Payload is null";
|
||||
log.error(msg);
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
||||
}
|
||||
validateFilter(filter);
|
||||
filter.setAppReleaseState(applicationManager.getInstallableLifecycleState());
|
||||
ApplicationList applications = applicationManager.getApplications(filter);
|
||||
return Response.status(Response.Status.OK).entity(applications).build();
|
||||
} catch (BadRequestException e) {
|
||||
String msg = e.getMessage();
|
||||
String msg = "Invalid request payload found in the request. Hence verify the payload.";
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(msg).build();
|
||||
} catch (UnexpectedServerErrorException e) {
|
||||
String msg = e.getMessage();
|
||||
String msg = "Unexpected Error occurred while retrieving applications";
|
||||
log.error(msg);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||
} catch (ApplicationManagementException e) {
|
||||
String msg = e.getMessage();
|
||||
String msg = "Error occurred while retrieving applications";
|
||||
log.error(msg);
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||
}
|
||||
@ -101,4 +160,18 @@ public class ApplicationManagementAPIImpl implements ApplicationManagementAPI {
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method can be used to check & validate if {@link Filter} object exist.
|
||||
*
|
||||
* @param filter {@link Filter}
|
||||
* @throws BadRequestException if filter object doesn't exist
|
||||
*/
|
||||
private void validateFilter(Filter filter) throws BadRequestException {
|
||||
if (filter == null) {
|
||||
String msg = "Request Payload is null";
|
||||
log.error(msg);
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,8 @@
|
||||
|
||||
package io.entgra.application.mgt.store.api.services.impl.admin;
|
||||
|
||||
import io.entgra.application.mgt.common.exception.SubscriptionManagementException;
|
||||
import io.entgra.application.mgt.store.api.beans.SubscriptionStatusBean;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@ -34,10 +36,12 @@ import org.wso2.carbon.device.mgt.common.PaginationResult;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DefaultValue;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.List;
|
||||
|
||||
@ -50,6 +54,30 @@ public class SubscriptionManagementAdminAPIImpl implements SubscriptionManagemen
|
||||
|
||||
private static final Log log = LogFactory.getLog(SubscriptionManagementAdminAPIImpl.class);
|
||||
|
||||
@Override
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/device/{deviceId}/status")
|
||||
public Response updateSubscription(
|
||||
@PathParam("deviceId") int deviceId,
|
||||
SubscriptionStatusBean subscriptionStatusBean
|
||||
) {
|
||||
try {
|
||||
RequestValidationUtil.validateSubscriptionStatus(subscriptionStatusBean.getStatus());
|
||||
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
|
||||
subscriptionManager.updateSubscriptionStatus(deviceId, subscriptionStatusBean.getSubId(),
|
||||
subscriptionStatusBean.getStatus());
|
||||
return Response.status(Response.Status.OK).entity("Subscription status updated successfully").build();
|
||||
} catch (BadRequestException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
|
||||
} catch (SubscriptionManagementException e) {
|
||||
String msg = "Error occurred while changing subscription status of the subscription with the id "
|
||||
+ subscriptionStatusBean.getSubId();
|
||||
log.error(msg, e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(msg).build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Consumes("application/json")
|
||||
@Produces("application/json")
|
||||
@ -60,6 +88,7 @@ public class SubscriptionManagementAdminAPIImpl implements SubscriptionManagemen
|
||||
@QueryParam("action") String action,
|
||||
@QueryParam("actionStatus") String actionStatus,
|
||||
@QueryParam("status") List<String> status,
|
||||
@QueryParam("installedVersion") String installedVersion,
|
||||
@PathParam("uuid") String uuid,
|
||||
@DefaultValue("0")
|
||||
@QueryParam("offset") int offset,
|
||||
@ -97,7 +126,7 @@ public class SubscriptionManagementAdminAPIImpl implements SubscriptionManagemen
|
||||
}
|
||||
SubscriptionManager subscriptionManager = APIUtil.getSubscriptionManager();
|
||||
PaginationResult subscriptionData = subscriptionManager.getAppSubscriptionDetails
|
||||
(request, uuid, actionStatus, action);
|
||||
(request, uuid, actionStatus, action, installedVersion);
|
||||
return Response.status(Response.Status.OK).entity(subscriptionData).build();
|
||||
} catch (NotFoundException e) {
|
||||
String msg = "Application with application release UUID: " + uuid + " is not found";
|
||||
|
||||
@ -18,12 +18,16 @@
|
||||
*/
|
||||
package io.entgra.application.mgt.store.api.services.impl.util;
|
||||
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import io.entgra.application.mgt.core.exception.BadRequestException;
|
||||
import io.entgra.application.mgt.store.api.util.Constants;
|
||||
import org.wso2.carbon.device.mgt.common.operation.mgt.ActivityStatus;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class RequestValidationUtil {
|
||||
|
||||
@ -113,4 +117,18 @@ public class RequestValidationUtil {
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if user requested subscription status is valid.
|
||||
*
|
||||
*/
|
||||
public static void validateSubscriptionStatus(String status) throws BadRequestException{
|
||||
if (!EnumUtils.isValidEnum(ActivityStatus.Status.class, status)) {
|
||||
List<ActivityStatus.Status> validStatuses = EnumUtils.getEnumList(ActivityStatus.Status.class);
|
||||
String validStatusesString = StringUtils.join(validStatuses, " | ");
|
||||
String msg = "Invalid status type: " + status + ". \nValid status types are " + validStatusesString;
|
||||
log.error(msg);
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>carbon-devicemgt</artifactId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>certificate-mgt</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>certificate-mgt</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -310,8 +310,6 @@ public interface CertificateManagementAdminService {
|
||||
@HeaderParam("If-Modified-Since") String ifModifiedSince);
|
||||
|
||||
@DELETE
|
||||
@Path("/{serialNumber}")
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
@ApiOperation(
|
||||
consumes = MediaType.WILDCARD,
|
||||
produces = MediaType.APPLICATION_JSON,
|
||||
@ -348,7 +346,7 @@ public interface CertificateManagementAdminService {
|
||||
"NOTE: Make sure that a certificate with the serial number you provide exists in the server. If not, first add a certificate.",
|
||||
required = true,
|
||||
defaultValue = "12438035315552875930")
|
||||
@PathParam("serialNumber") String serialNumber);
|
||||
@QueryParam("serialNumber") String serialNumber);
|
||||
|
||||
/**
|
||||
* Verify Certificate for the API security filter
|
||||
|
||||
@ -151,9 +151,7 @@ public class CertificateManagementAdminServiceImpl implements CertificateManagem
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/{serialNumber}")
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
public Response removeCertificate(@PathParam("serialNumber") String serialNumber) {
|
||||
public Response removeCertificate(@QueryParam("serialNumber") String serialNumber) {
|
||||
RequestValidationUtil.validateSerialNumber(serialNumber);
|
||||
|
||||
CertificateManagementService certificateService = CertificateMgtAPIUtils.getCertificateManagementService();
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
<parent>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>certificate-mgt</artifactId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<artifactId>carbon-devicemgt</artifactId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>device-mgt-extensions</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>device-mgt-extensions</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>device-mgt-extensions</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>device-mgt-extensions</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
<parent>
|
||||
<artifactId>device-mgt-extensions</artifactId>
|
||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||
<version>5.0.1-SNAPSHOT</version>
|
||||
<version>5.0.6-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user