Segment & Rollbar Integration

This commit is contained in:
Trisha Anand 2019-09-25 16:20:51 +00:00
parent 3a3521a539
commit 566a245451
30 changed files with 552 additions and 368 deletions

View File

@ -1,7 +1,6 @@
package com.appsmith.external.plugins;
import com.appsmith.external.models.ActionConfiguration;
import com.appsmith.external.models.CommandParams;
import com.appsmith.external.models.Param;
import com.appsmith.external.models.ResourceConfiguration;
import org.pf4j.ExtensionPoint;

View File

@ -1,79 +1,79 @@
<?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">
<modelVersion>4.0.0</modelVersion>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.external.plugins</groupId>
<artifactId>postgresPlugin</artifactId>
<version>1.0-SNAPSHOT</version>
<groupId>com.external.plugins</groupId>
<artifactId>postgresPlugin</artifactId>
<version>1.0-SNAPSHOT</version>
<name>postgresPlugin</name>
<name>postgresPlugin</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<plugin.id>postgres-plugin</plugin.id>
<plugin.class>com.external.plugins.PostgresPlugin</plugin.class>
<plugin.version>1.0-SNAPSHOT</plugin.version>
<plugin.provider>tech@appsmith.com</plugin.provider>
<plugin.dependencies />
</properties>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<plugin.id>postgres-plugin</plugin.id>
<plugin.class>com.external.plugins.PostgresPlugin</plugin.class>
<plugin.version>1.0-SNAPSHOT</plugin.version>
<plugin.provider>tech@appsmith.com</plugin.provider>
<plugin.dependencies/>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.pf4j</groupId>
<artifactId>pf4j-spring</artifactId>
<version>0.5.0</version>
</dependency>
<dependency>
<groupId>org.pf4j</groupId>
<artifactId>pf4j-spring</artifactId>
<version>0.5.0</version>
</dependency>
<dependency>
<groupId>com.appsmith</groupId>
<artifactId>interfaces</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.appsmith</groupId>
<artifactId>interfaces</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifestEntries>
<Plugin-Id>${plugin.id}</Plugin-Id>
<Plugin-Class>${plugin.class}</Plugin-Class>
<Plugin-Version>${plugin.version}</Plugin-Version>
<Plugin-Provider>${plugin.provider}</Plugin-Provider>
<Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifestEntries>
<Plugin-Id>${plugin.id}</Plugin-Id>
<Plugin-Class>${plugin.class}</Plugin-Class>
<Plugin-Version>${plugin.version}</Plugin-Version>
<Plugin-Provider>${plugin.provider}</Plugin-Provider>
<Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,7 +1,6 @@
package com.external.plugins;
import com.appsmith.external.models.ActionConfiguration;
import com.appsmith.external.models.CommandParams;
import com.appsmith.external.models.Param;
import com.appsmith.external.models.ResourceConfiguration;
import com.appsmith.external.plugins.BasePlugin;
@ -13,7 +12,6 @@ import org.pf4j.PluginWrapper;
import org.springframework.util.Assert;
import reactor.core.publisher.Flux;
import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
@ -26,14 +24,14 @@ import java.util.List;
@Slf4j
public class PostgresPlugin extends BasePlugin {
static String JDBC_DRIVER="org.postgresql.Driver";
static String JDBC_DRIVER = "org.postgresql.Driver";
static String DB_URL="jdbc:postgresql://localhost/mobtools";
static String DB_URL = "jdbc:postgresql://localhost/mobtools";
// Database credentials
static String DB_USER="root";
static String DB_USER = "root";
static String DB_PASS="root";
static String DB_PASS = "root";
static Connection conn = null;
@ -61,7 +59,7 @@ public class PostgresPlugin extends BasePlugin {
public void stop() throws PluginException {
log.debug("PostgresPlugin.stop()");
try {
if(conn != null) {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {

View File

@ -1,20 +1,18 @@
package com.external.plugins;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
/**
* Unit test for simple App.
*/
public class PostgresPluginTest
{
public class PostgresPluginTest {
/**
* Rigorous Test :-)
*/
@Test
public void shouldAnswerWithTrue()
{
assertTrue( true );
public void shouldAnswerWithTrue() {
assertTrue(true);
}
}

View File

@ -1,85 +1,85 @@
<?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">
<modelVersion>4.0.0</modelVersion>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.external.plugins</groupId>
<artifactId>restApiPlugin</artifactId>
<version>1.0-SNAPSHOT</version>
<groupId>com.external.plugins</groupId>
<artifactId>restApiPlugin</artifactId>
<version>1.0-SNAPSHOT</version>
<name>restApiPlugin</name>
<name>restApiPlugin</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<plugin.id>restapi-plugin</plugin.id>
<plugin.class>com.external.plugins.RestApiPlugin</plugin.class>
<plugin.version>1.0-SNAPSHOT</plugin.version>
<plugin.provider>tech@appsmith.com</plugin.provider>
<plugin.dependencies />
</properties>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<plugin.id>restapi-plugin</plugin.id>
<plugin.class>com.external.plugins.RestApiPlugin</plugin.class>
<plugin.version>1.0-SNAPSHOT</plugin.version>
<plugin.provider>tech@appsmith.com</plugin.provider>
<plugin.dependencies/>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.pf4j</groupId>
<artifactId>pf4j-spring</artifactId>
<version>0.5.0</version>
</dependency>
<dependency>
<groupId>org.pf4j</groupId>
<artifactId>pf4j-spring</artifactId>
<version>0.5.0</version>
</dependency>
<dependency>
<groupId>com.appsmith</groupId>
<artifactId>interfaces</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.appsmith</groupId>
<artifactId>interfaces</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifestEntries>
<Plugin-Id>${plugin.id}</Plugin-Id>
<Plugin-Class>${plugin.class}</Plugin-Class>
<Plugin-Version>${plugin.version}</Plugin-Version>
<Plugin-Provider>${plugin.provider}</Plugin-Provider>
<Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifestEntries>
<Plugin-Id>${plugin.id}</Plugin-Id>
<Plugin-Class>${plugin.class}</Plugin-Class>
<Plugin-Version>${plugin.version}</Plugin-Version>
<Plugin-Provider>${plugin.provider}</Plugin-Provider>
<Plugin-Dependencies>${plugin.dependencies}</Plugin-Dependencies>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -37,16 +37,17 @@ public class RestApiPlugin extends BasePlugin {
ActionConfiguration actionConfiguration,
List<Param> params) {
JSONObject requestBody = actionConfiguration.getBody();
if(requestBody == null) {
if (requestBody == null) {
requestBody = new JSONObject();
}
//TODO: Substitue variables from params in all parts (actionConfig, resourceConfig etc) via JsonPath: https://github.com/json-path/JsonPath
Map<String, Param> propertyMap = params.stream()
.collect(Collectors.toMap(Param::getKey, param -> param));
String path = (actionConfiguration.getPath() == null) ? "" : actionConfiguration.getPath();
String url = resourceConfiguration.getUrl() + path;
HttpMethod httpMethod = actionConfiguration.getHttpMethod();
if(httpMethod == null) {
if (httpMethod == null) {
return Flux.error(new Exception("HttpMethod must not be null"));
}
@ -54,6 +55,7 @@ public class RestApiPlugin extends BasePlugin {
WebClient webClient = WebClient.builder()
.baseUrl(url)
// TODO: Ideally this should come from action / resource config
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
@ -63,6 +65,7 @@ public class RestApiPlugin extends BasePlugin {
Mono<ClientResponse> responseMono = request.exchange();
return responseMono.flatMapMany(response -> {
log.debug("Got response: {}", response);
// TODO: Refactor for better switch case
List<String> contentTypes = response.headers().header(HttpHeaders.CONTENT_TYPE);
Class clazz = String.class;
if (contentTypes != null && contentTypes.size() > 0) {

View File

@ -1,20 +1,18 @@
package com.external.plugins;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
/**
* Unit test for simple App.
*/
public class RestApiPluginTest
{
public class RestApiPluginTest {
/**
* Rigorous Test :-)
*/
@Test
public void shouldAnswerWithTrue()
{
assertTrue( true );
public void shouldAnswerWithTrue() {
assertTrue(true);
}
}

View File

@ -1,147 +1,167 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.appsmith</groupId>
<artifactId>integrated</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.appsmith</groupId>
<artifactId>integrated</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.appsmith</groupId>
<artifactId>server</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>server</name>
<description>This is the API server for the Appsmith project</description>
<name>server</name>
<description>This is the API server for the Appsmith project</description>
<properties>
<java.version>11</java.version>
</properties>
<properties>
<java.version>11</java.version>
</properties>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>jboss-maven2-release-repository</id>
<name>JBoss Spring Repository</name>
<url>https://repository.jboss.org/nexus/content/repositories/public/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>jboss-maven2-release-repository</id>
<name>JBoss Spring Repository</name>
<url>https://repository.jboss.org/nexus/content/repositories/public/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.17.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
<version>0.9.6</version>
</dependency>
<dependency>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.17.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
<version>0.9.6</version>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.segment.analytics.java</groupId>
<artifactId>analytics</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.1-jre</version>
</dependency>
<!-- Plugin dependencies -->
<dependency>
<groupId>org.pf4j</groupId>
<artifactId>pf4j-spring</artifactId>
<version>0.5.0</version>
</dependency>
<!-- Plugin dependencies -->
<dependency>
<groupId>org.pf4j</groupId>
<artifactId>pf4j-spring</artifactId>
<version>0.5.0</version>
</dependency>
<!-- Appsmith dependencies -->
<dependency>
<groupId>com.appsmith</groupId>
<artifactId>interfaces</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Appsmith dependencies -->
<dependency>
<groupId>com.appsmith</groupId>
<artifactId>interfaces</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<version>3.2.11.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.segment.analytics.java</groupId>
<artifactId>analytics</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>com.rollbar</groupId>
<artifactId>rollbar-java</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<version>3.2.11.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,20 @@
package com.appsmith.server.configurations;
import com.rollbar.notifier.Rollbar;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static com.rollbar.notifier.config.ConfigBuilder.withAccessToken;
@Configuration
public class RollbarConfig {
@Value("${com.rollbar.access-token}")
String rollbarAccessToken;
@Bean
Rollbar rollbarConfiguration() {
return Rollbar.init(withAccessToken(rollbarAccessToken).build());
}
}

View File

@ -0,0 +1,17 @@
package com.appsmith.server.configurations;
import com.segment.analytics.Analytics;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SegmentConfig {
@Value("${segment.writeKey}")
private String writeKey;
@Bean
public Analytics analyticsRunner() {
return Analytics.builder(writeKey).build();
}
}

View File

@ -1,7 +1,7 @@
package com.appsmith.server.controllers;
import com.appsmith.server.domains.User;
import com.appsmith.server.services.UserService;
import com.appsmith.server.services.SessionUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@ -16,10 +16,10 @@ import java.security.Principal;
@RequestMapping("")
public class IndexController {
private final UserService service;
private final SessionUserService service;
@Autowired
public IndexController(UserService service) {
public IndexController(SessionUserService service) {
this.service = service;
}

View File

@ -18,5 +18,4 @@ public class PropertyPane extends BaseDomain {
Map<String, List<WidgetSectionProperty>> config;
String configVersion;
}

View File

@ -1,7 +1,10 @@
package com.appsmith.server.exceptions;
import com.appsmith.server.dtos.ResponseDTO;
import com.rollbar.notifier.Rollbar;
import com.segment.analytics.Analytics;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ -16,6 +19,14 @@ import reactor.core.publisher.Mono;
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
private final Analytics analytics;
private final Rollbar rollbar;
@Autowired
public GlobalExceptionHandler(Analytics analytics, Rollbar rollbar) {
this.analytics = analytics;
this.rollbar = rollbar;
}
/**
* This function only catches the AppsmithException type and formats it into ResponseEntity<ErrorDTO> object
@ -31,6 +42,7 @@ public class GlobalExceptionHandler {
public Mono<ResponseDTO<ErrorDTO>> catchAppsmithException(AppsmithException e, ServerWebExchange exchange) {
exchange.getResponse().setStatusCode(HttpStatus.resolve(e.getHttpStatus()));
log.error("", e);
rollbar.log(e);
return Mono.just(new ResponseDTO<>(e.getHttpStatus(), new ErrorDTO(e.getAppErrorCode(), e.getMessage())));
}
@ -47,6 +59,7 @@ public class GlobalExceptionHandler {
public Mono<ResponseDTO<ErrorDTO>> catchException(Exception e, ServerWebExchange exchange) {
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
log.error("", e);
rollbar.log(e);
return Mono.just(new ResponseDTO<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), new ErrorDTO(AppsmithError.INTERNAL_SERVER_ERROR.getHttpErrorCode(),
AppsmithError.INTERNAL_SERVER_ERROR.getMessage())));
}

View File

@ -6,10 +6,12 @@ import com.appsmith.server.domains.Page;
import com.appsmith.server.domains.PageAction;
import com.appsmith.server.domains.Plugin;
import com.appsmith.server.domains.Resource;
import com.appsmith.server.domains.User;
import com.appsmith.server.dtos.ExecuteActionDTO;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import com.appsmith.server.repositories.ActionRepository;
import com.segment.analytics.Analytics;
import lombok.extern.slf4j.Slf4j;
import org.pf4j.PluginManager;
import org.springframework.beans.factory.annotation.Autowired;
@ -44,8 +46,10 @@ public class ActionServiceImpl extends BaseService<ActionRepository, Action, Str
ResourceService resourceService,
PluginService pluginService,
PageService pageService,
PluginManager pluginManager) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository);
PluginManager pluginManager,
Analytics analytics,
SessionUserService sessionUserService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analytics, sessionUserService);
this.repository = repository;
this.resourceService = resourceService;
this.pluginService = pluginService;
@ -63,6 +67,7 @@ public class ActionServiceImpl extends BaseService<ActionRepository, Action, Str
return Mono.error(new AppsmithException(AppsmithError.PAGE_ID_NOT_GIVEN));
}
Mono<User> userMono = super.sessionUserService.getCurrentUser();
Mono<Resource> resourceMono = resourceService.findById(action.getResourceId());
Mono<Plugin> pluginMono = resourceMono.flatMap(resource -> pluginService.findById(resource.getPluginId()));
Mono<Page> pageMono = pageService.findById(action.getPageId());
@ -96,7 +101,9 @@ public class ActionServiceImpl extends BaseService<ActionRepository, Action, Str
return page;
})
.flatMap(pageService::save)
.then(Mono.just(action1));
.then(Mono.just(action1))
//Now publish this event
.flatMap(this::segmentTrackCreate);
});
}
@ -129,7 +136,7 @@ public class ActionServiceImpl extends BaseService<ActionRepository, Action, Str
return actionMono.flatMap(action -> resourceMono.zipWith(pluginExecutorMono, (resource, pluginExecutor) ->
{
log.debug("*** About to invoke the plugin**");
// TODO: The CommandParams is being passed as null here. Move it to interfaces.CommandParams
// TODO: The CommandParams is being passed as null here. Move it to interfaces.CommandParams - N/A
return pluginExecutor.execute(resource.getResourceConfiguration(), action.getActionConfiguration(), executeActionDTO.getParams());
}))
.flatMapIterable(Flux::toIterable);

View File

@ -6,6 +6,7 @@ import com.appsmith.server.domains.User;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import com.appsmith.server.repositories.ApplicationRepository;
import com.segment.analytics.Analytics;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
@ -22,12 +23,12 @@ import javax.validation.Validator;
@Service
public class ApplicationServiceImpl extends BaseService<ApplicationRepository, Application, String> implements ApplicationService {
private final UserService userService;
private final Analytics analytics;
@Autowired
public ApplicationServiceImpl(Scheduler scheduler, Validator validator, MongoConverter mongoConverter, ReactiveMongoTemplate reactiveMongoTemplate, ApplicationRepository repository, UserService userService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository);
this.userService = userService;
public ApplicationServiceImpl(Scheduler scheduler, Validator validator, MongoConverter mongoConverter, ReactiveMongoTemplate reactiveMongoTemplate, ApplicationRepository repository, SessionUserService sessionUserService, Analytics analytics) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analytics, sessionUserService);
this.analytics = analytics;
}
@Override
@ -36,7 +37,7 @@ public class ApplicationServiceImpl extends BaseService<ApplicationRepository, A
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.NAME));
}
Mono<User> userMono = userService.getCurrentUser();
Mono<User> userMono = super.sessionUserService.getCurrentUser();
return userMono
.map(user -> user.getOrganizationId())
@ -44,12 +45,14 @@ public class ApplicationServiceImpl extends BaseService<ApplicationRepository, A
application.setOrganizationId(orgId);
return application;
})
.flatMap(repository::save);
.flatMap(repository::save)
//Log the event to Segment
.flatMap(this::segmentTrackCreate);
}
@Override
public Flux<Application> get() {
Mono<User> userMono = userService.getCurrentUser();
Mono<User> userMono = super.sessionUserService.getCurrentUser();
return userMono
.map(user -> user.getOrganizationId())
@ -62,7 +65,7 @@ public class ApplicationServiceImpl extends BaseService<ApplicationRepository, A
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ID));
}
Mono<User> userMono = userService.getCurrentUser();
Mono<User> userMono = super.sessionUserService.getCurrentUser();
return userMono
.map(user -> user.getOrganizationId())

View File

@ -2,11 +2,14 @@ package com.appsmith.server.services;
import com.appsmith.server.constants.FieldName;
import com.appsmith.server.domains.BaseDomain;
import com.appsmith.server.domains.User;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import com.appsmith.server.repositories.BaseRepository;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.segment.analytics.Analytics;
import com.segment.analytics.messages.TrackMessage;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.query.Criteria;
@ -17,6 +20,7 @@ import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
import javax.validation.Validator;
import java.util.HashMap;
import java.util.Map;
public abstract class BaseService<R extends BaseRepository, T extends BaseDomain, ID> implements CrudService<T, ID> {
@ -31,16 +35,22 @@ public abstract class BaseService<R extends BaseRepository, T extends BaseDomain
protected final Validator validator;
protected final Analytics analytics;
protected final SessionUserService sessionUserService;
public BaseService(Scheduler scheduler,
Validator validator,
MongoConverter mongoConverter,
ReactiveMongoTemplate reactiveMongoTemplate,
R repository) {
R repository, Analytics analytics, SessionUserService sessionUserService) {
this.scheduler = scheduler;
this.validator = validator;
this.mongoConverter = mongoConverter;
this.mongoTemplate = reactiveMongoTemplate;
this.repository = repository;
this.analytics = analytics;
this.sessionUserService = sessionUserService;
}
@Override
@ -78,9 +88,11 @@ public abstract class BaseService<R extends BaseRepository, T extends BaseDomain
@Override
public Mono<T> create(T object) {
Mono<User> userMono = sessionUserService.getCurrentUser();
return Mono.just(object)
.flatMap(this::validateObject)
.flatMap(repository::save);
.flatMap(repository::save)
.flatMap(this::segmentTrackCreate);
}
private DBObject getDbObject(Object o) {
@ -106,4 +118,21 @@ public abstract class BaseService<R extends BaseRepository, T extends BaseDomain
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, constraint.stream().findFirst().get().getPropertyPath()));
});
}
protected Mono<T> segmentTrackCreate(Object savedObject) {
Mono<User> userMono = sessionUserService.getCurrentUser();
return userMono
.map(user -> {
HashMap<String, String> analyticsProperties = new HashMap<>();
analyticsProperties.put("id", ((BaseDomain) savedObject).getId());
analyticsProperties.put("organizationId", user.getOrganizationId());
analytics.enqueue(
TrackMessage.builder("MONGO_DB_CREATE_" + savedObject.getClass())
.userId(user.getId())
.properties(analyticsProperties)
);
return (T) savedObject;
})
.switchIfEmpty(Mono.just((T) savedObject));
}
}

View File

@ -4,9 +4,11 @@ import com.appsmith.server.constants.FieldName;
import com.appsmith.server.domains.Organization;
import com.appsmith.server.domains.OrganizationSetting;
import com.appsmith.server.domains.Setting;
import com.appsmith.server.domains.User;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import com.appsmith.server.repositories.OrganizationRepository;
import com.segment.analytics.Analytics;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
@ -33,8 +35,10 @@ public class OrganizationServiceImpl extends BaseService<OrganizationRepository,
MongoConverter mongoConverter,
ReactiveMongoTemplate reactiveMongoTemplate,
OrganizationRepository repository,
SettingService settingService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository);
SettingService settingService,
Analytics analytics,
SessionUserService sessionUserService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analytics, sessionUserService);
this.repository = repository;
this.settingService = settingService;
}
@ -55,13 +59,13 @@ public class OrganizationServiceImpl extends BaseService<OrganizationRepository,
if (organization == null) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.ORGANIZATION));
}
return Mono.just(organization)
.flatMap(this::validateObject)
//transform the organization data to embed setting object in each object in organizationSetting list.
.flatMap(this::enhanceOrganizationSettingList)
//Call the library function to save the updated organization
.flatMap(repository::save);
.flatMap(repository::save)
.flatMap(this::segmentTrackCreate);
}
private Mono<Organization> enhanceOrganizationSettingList(Organization organization) {

View File

@ -7,6 +7,7 @@ import com.appsmith.server.domains.User;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import com.appsmith.server.repositories.PageRepository;
import com.segment.analytics.Analytics;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
@ -24,13 +25,12 @@ import java.util.List;
@Slf4j
public class PageServiceImpl extends BaseService<PageRepository, Page, String> implements PageService {
private final UserService userService;
private final ApplicationService applicationService;
@Autowired
public PageServiceImpl(Scheduler scheduler, Validator validator, MongoConverter mongoConverter, ReactiveMongoTemplate reactiveMongoTemplate, PageRepository repository, UserService userService, ApplicationService applicationService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository);
this.userService = userService;
public PageServiceImpl(Scheduler scheduler, Validator validator, MongoConverter mongoConverter, ReactiveMongoTemplate reactiveMongoTemplate, PageRepository repository, ApplicationService applicationService,
Analytics analytics, SessionUserService sessionUserService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analytics, sessionUserService);
this.applicationService = applicationService;
}
@ -43,6 +43,9 @@ public class PageServiceImpl extends BaseService<PageRepository, Page, String> i
} else if (page.getApplicationId() == null) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.APPLICATIONID));
}
Mono<User> userMono = super.sessionUserService.getCurrentUser();
List<Layout> layoutList = page.getLayouts();
if (layoutList == null) {
layoutList = new ArrayList<>();
@ -51,7 +54,9 @@ public class PageServiceImpl extends BaseService<PageRepository, Page, String> i
layoutList.add(createDefaultLayout());
page.setLayouts(layoutList);
}
return repository.save(page);
return repository
.save(page)
.flatMap(this::segmentTrackCreate);
}
@ -72,7 +77,7 @@ public class PageServiceImpl extends BaseService<PageRepository, Page, String> i
@Override
public Mono<Page> doesPageIdBelongToCurrentUserOrganization(Page page) {
Mono<User> userMono = userService.getCurrentUser();
Mono<User> userMono = super.sessionUserService.getCurrentUser();
final String[] username = {null};
return userMono

View File

@ -10,6 +10,7 @@ import com.appsmith.server.dtos.PluginOrgDTO;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import com.appsmith.server.repositories.PluginRepository;
import com.segment.analytics.Analytics;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@ -30,7 +31,6 @@ public class PluginServiceImpl extends BaseService<PluginRepository, Plugin, Str
private final PluginRepository pluginRepository;
private final ApplicationContext applicationContext;
private final OrganizationService organizationService;
private final UserService userService;
@Autowired
public PluginServiceImpl(Scheduler scheduler,
@ -39,12 +39,13 @@ public class PluginServiceImpl extends BaseService<PluginRepository, Plugin, Str
ReactiveMongoTemplate reactiveMongoTemplate,
PluginRepository repository,
ApplicationContext applicationContext,
OrganizationService organizationService, UserService userService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository);
OrganizationService organizationService,
Analytics analytics,
SessionUserService sessionUserService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analytics, sessionUserService);
this.applicationContext = applicationContext;
pluginRepository = repository;
this.organizationService = organizationService;
this.userService = userService;
}
public OldPluginExecutor getPluginExecutor(PluginType pluginType, String className) {
@ -64,8 +65,12 @@ public class PluginServiceImpl extends BaseService<PluginRepository, Plugin, Str
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, "id"));
}
Mono<User> userMono = super.sessionUserService.getCurrentUser();
plugin.setDeleted(false);
return pluginRepository.save(plugin);
return pluginRepository
.save(plugin)
.flatMap(this::segmentTrackCreate);
}
@Override
@ -86,7 +91,7 @@ public class PluginServiceImpl extends BaseService<PluginRepository, Plugin, Str
}
//Find the organization using id and plugin id -> This is to find if the organization has the plugin installed
Mono<User> userMono = userService.getCurrentUser();
Mono<User> userMono = super.sessionUserService.getCurrentUser();
Mono<Organization> organizationMono = userMono.flatMap(user ->
organizationService.findByIdAndPluginsPluginId(user.getOrganizationId(), pluginDTO.getPluginId()));
@ -107,7 +112,7 @@ public class PluginServiceImpl extends BaseService<PluginRepository, Plugin, Str
private Mono<Organization> storeOrganizationPlugin(PluginOrgDTO pluginDTO, OrganizationPluginStatus status) {
//Find the organization using id and plugin id -> This is to find if the organization already has the plugin installed
Mono<User> userMono = userService.getCurrentUser();
Mono<User> userMono = super.sessionUserService.getCurrentUser();
Mono<Organization> organizationMono = userMono.flatMap(user ->
organizationService.findByIdAndPluginsPluginId(user.getOrganizationId(), pluginDTO.getPluginId()));

View File

@ -6,6 +6,7 @@ import com.appsmith.server.domains.WidgetSectionProperty;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import com.appsmith.server.repositories.PropertyPaneRepository;
import com.segment.analytics.Analytics;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
@ -15,19 +16,18 @@ import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
import javax.validation.Validator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
public class PropertyPaneServiceImpl extends BaseService<PropertyPaneRepository, PropertyPane, String> implements PropertyPaneService {
public PropertyPaneServiceImpl(Scheduler scheduler, Validator validator, MongoConverter mongoConverter, ReactiveMongoTemplate reactiveMongoTemplate, PropertyPaneRepository repository) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository);
public PropertyPaneServiceImpl(Scheduler scheduler, Validator validator, MongoConverter mongoConverter, ReactiveMongoTemplate reactiveMongoTemplate, PropertyPaneRepository repository, Analytics analytics, SessionUserService sessionUserService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analytics, sessionUserService);
}
@Override
public Mono<PropertyPane> create (PropertyPane propertyPane) {
public Mono<PropertyPane> create(PropertyPane propertyPane) {
if (propertyPane.getId() != null) {
return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, "id"));
}
@ -49,9 +49,6 @@ public class PropertyPaneServiceImpl extends BaseService<PropertyPaneRepository,
}
return repository
.save(propertyPane)
.flatMap(savedPropertyPane -> {
savedPropertyPane.setConfigVersion(savedPropertyPane.getId());
return repository.save(savedPropertyPane);
});
.flatMap(this::segmentTrackCreate);
}
}

View File

@ -6,6 +6,7 @@ import com.appsmith.server.domains.User;
import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import com.appsmith.server.repositories.ResourceRepository;
import com.segment.analytics.Analytics;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
@ -23,14 +24,13 @@ public class ResourceServiceImpl extends BaseService<ResourceRepository, Resourc
private final ResourceRepository repository;
private final OrganizationService organizationService;
private final UserService userService;
@Autowired
public ResourceServiceImpl(Scheduler scheduler, Validator validator, MongoConverter mongoConverter, ReactiveMongoTemplate reactiveMongoTemplate, ResourceRepository repository, OrganizationService organizationService, PluginService pluginService, UserService userService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository);
public ResourceServiceImpl(Scheduler scheduler, Validator validator, MongoConverter mongoConverter, ReactiveMongoTemplate reactiveMongoTemplate, ResourceRepository repository, OrganizationService organizationService, PluginService pluginService, Analytics analytics,
SessionUserService sessionUserService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analytics, sessionUserService);
this.repository = repository;
this.organizationService = organizationService;
this.userService = userService;
}
@Override
@ -41,7 +41,7 @@ public class ResourceServiceImpl extends BaseService<ResourceRepository, Resourc
return Mono.error(new AppsmithException(AppsmithError.PLUGIN_ID_NOT_GIVEN));
}
Mono<User> userMono = userService.getCurrentUser();
Mono<User> userMono = super.sessionUserService.getCurrentUser();
Mono<Organization> organizationMono = userMono.flatMap(user -> organizationService.findByIdAndPluginsPluginId(user.getOrganizationId(), resource.getPluginId()));
@ -55,7 +55,8 @@ public class ResourceServiceImpl extends BaseService<ResourceRepository, Resourc
return organizationMono
.switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.PLUGIN_NOT_INSTALLED, resource.getPluginId())))
.then(updatedResourceMono)
.flatMap(repository::save);
.flatMap(repository::save)
.flatMap(this::segmentTrackCreate);
}
@Override

View File

@ -0,0 +1,8 @@
package com.appsmith.server.services;
import com.appsmith.server.domains.User;
import reactor.core.publisher.Mono;
public interface SessionUserService {
public Mono<User> getCurrentUser();
}

View File

@ -0,0 +1,41 @@
package com.appsmith.server.services;
import com.appsmith.server.domains.User;
import com.appsmith.server.repositories.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
@Slf4j
@Service
public class SessionUserServiceImpl implements SessionUserService {
private final UserRepository repository;
public SessionUserServiceImpl(UserRepository userRepository) {
this.repository = userRepository;
}
@Override
public Mono<User> getCurrentUser() {
return ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication)
.map(Authentication::getPrincipal)
.flatMap(principal -> {
String email;
if (principal instanceof org.springframework.security.core.userdetails.User) {
org.springframework.security.core.userdetails.User user = (org.springframework.security.core.userdetails.User) principal;
//Assumption that the user has inputted an email as username during user creation and not english passport name
email = user.getUsername();
} else {
DefaultOidcUser defaultOidcUser = (DefaultOidcUser) principal;
email = defaultOidcUser.getEmail();
}
return repository.findByEmail(email);
});
}
}

View File

@ -2,6 +2,7 @@ package com.appsmith.server.services;
import com.appsmith.server.domains.Setting;
import com.appsmith.server.repositories.SettingRepository;
import com.segment.analytics.Analytics;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
@ -21,8 +22,10 @@ public class SettingServiceImpl extends BaseService<SettingRepository, Setting,
Validator validator,
MongoConverter mongoConverter,
ReactiveMongoTemplate reactiveMongoTemplate,
SettingRepository repository) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository);
SettingRepository repository,
Analytics analytics,
SessionUserService sessionUserService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analytics, sessionUserService);
this.repository = repository;
}

View File

@ -11,5 +11,4 @@ public interface UserService extends CrudService<User, String> {
Mono<User> save(User newUser);
Mono<User> getCurrentUser();
}

View File

@ -5,22 +5,22 @@ import com.appsmith.server.exceptions.AppsmithError;
import com.appsmith.server.exceptions.AppsmithException;
import com.appsmith.server.helpers.BeanCopyUtils;
import com.appsmith.server.repositories.UserRepository;
import com.segment.analytics.Analytics;
import com.segment.analytics.messages.IdentifyMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
import javax.validation.Validator;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
@ -28,16 +28,21 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
private UserRepository repository;
private final OrganizationService organizationService;
private final Analytics analytics;
@Autowired
public UserServiceImpl(Scheduler scheduler,
Validator validator,
MongoConverter mongoConverter,
ReactiveMongoTemplate reactiveMongoTemplate,
UserRepository repository, OrganizationService organizationService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository);
UserRepository repository,
OrganizationService organizationService,
Analytics analytics,
SessionUserService sessionUserService) {
super(scheduler, validator, mongoConverter, reactiveMongoTemplate, repository, analytics, sessionUserService);
this.repository = repository;
this.organizationService = organizationService;
this.analytics = analytics;
}
@Override
@ -52,7 +57,20 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
@Override
public Mono<User> save(User user) {
return repository.save(user);
Mono<User> savedUserMono = repository.save(user);
return savedUserMono
.map(savedUser -> {
Map<String, String> traitsMap = new HashMap<>();
traitsMap.put("name", savedUser.getName());
traitsMap.put("email", savedUser.getEmail());
analytics.enqueue(IdentifyMessage.builder()
.userId(savedUser.getId())
.traits(traitsMap)
);
analytics.flush();
return savedUser;
});
}
@Override
@ -60,25 +78,6 @@ public class UserServiceImpl extends BaseService<UserRepository, User, String> i
return repository.findByName(username).block();
}
@Override
public Mono<User> getCurrentUser() {
return ReactiveSecurityContextHolder.getContext()
.map(SecurityContext::getAuthentication)
.map(Authentication::getPrincipal)
.flatMap(principal -> {
String email;
if (principal instanceof org.springframework.security.core.userdetails.User) {
org.springframework.security.core.userdetails.User user = (org.springframework.security.core.userdetails.User) principal;
//Assumption that the user has inputted an email as username during user creation and not english passport name
email = user.getUsername();
} else {
DefaultOidcUser defaultOidcUser = (DefaultOidcUser) principal;
email = defaultOidcUser.getEmail();
}
return repository.findByEmail(email);
});
}
@Override
public Mono<User> update(String id, User userUpdate) {
Mono<User> userFromRepository = repository.findById(id);

View File

@ -2,6 +2,7 @@ package com.appsmith.server.services;
import com.appsmith.server.domains.Widget;
import com.appsmith.server.repositories.WidgetRepository;
import com.segment.analytics.Analytics;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
@ -23,8 +24,10 @@ public class WidgetServiceImpl extends BaseService<WidgetRepository, Widget, Str
Validator validator,
MongoConverter mongoConverter,
ReactiveMongoTemplate mongoTemplate,
WidgetRepository widgetRepository) {
super(scheduler, validator, mongoConverter, mongoTemplate, widgetRepository);
WidgetRepository widgetRepository,
Analytics analytics,
SessionUserService sessionUserService) {
super(scheduler, validator, mongoConverter, mongoTemplate, widgetRepository, analytics, sessionUserService);
this.widgetRepository = widgetRepository;
}

View File

@ -4,12 +4,14 @@ spring.datasource.username=postgres
spring.datasource.password=root
spring.datasource.hikari.pool-name=Hikari-Eval-Pool
spring.datasource.hikari.maximum-pool-size=16
# JPA Properties
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
spring.jpa.show-sql=true
# Jackson Properties
spring.jackson.default-property-inclusion=non_null
spring.jackson.default-property-inclusion=non_null
# Segment Properties
segment.writeKey=FIRLqUgMYuTlyS6yqOE2hBGZs5umkWhr
com.rollbar.access-token=b91c4d5b9cac444088f4db9216ed6f42
com.rollbar.environment=development

View File

@ -0,0 +1,4 @@
dsn=https://5c388a93407a45a5886a941842e28d29@sentry.io/1758051
release=0.0.1
environment=local
stacktrace.hidecommon=false

View File

@ -9,6 +9,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import reactor.core.publisher.Mono;
@ -37,6 +38,7 @@ public class OrganizationServiceTest {
/* Tests for the Create Organization Flow */
@Test
@WithMockUser(username = "api_user")
public void nullCreateOrganization() {
Mono<Organization> organizationResponse = organizationService.create(null);
StepVerifier.create(organizationResponse)
@ -46,6 +48,7 @@ public class OrganizationServiceTest {
}
@Test
@WithMockUser(username = "api_user")
public void nullName() {
organization.setName(null);
Mono<Organization> organizationResponse = organizationService.create(organization);
@ -56,8 +59,10 @@ public class OrganizationServiceTest {
}
@Test
@WithMockUser(username = "api_user")
public void validCreateOrganizationTest() {
Mono<Organization> organizationResponse = organizationService.create(organization);
Mono<Organization> organizationResponse = organizationService.create(organization)
.switchIfEmpty(Mono.error(new Exception("create is returning empty!!")));
StepVerifier.create(organizationResponse)
.assertNext(organization1 -> {
assertThat(organization1.getName()).isEqualTo("Test Name");
@ -68,6 +73,7 @@ public class OrganizationServiceTest {
/* Tests for Get Organization Flow */
@Test
@WithMockUser(username = "api_user")
public void getOrganizationInvalidId() {
Mono<Organization> organizationMono = organizationService.getById("random-id");
StepVerifier.create(organizationMono)
@ -77,6 +83,7 @@ public class OrganizationServiceTest {
}
@Test
@WithMockUser(username = "api_user")
public void getOrganizationNullId() {
Mono<Organization> organizationMono = organizationService.getById(null);
StepVerifier.create(organizationMono)
@ -86,6 +93,7 @@ public class OrganizationServiceTest {
}
@Test
@WithMockUser(username = "api_user")
public void validGetOrganizationByName() {
Mono<Organization> createOrganization = organizationService.create(organization);
Mono<Organization> getOrganization = createOrganization.flatMap(t -> organizationService.getById(t.getId()));
@ -100,6 +108,7 @@ public class OrganizationServiceTest {
/* Tests for Update Organization Flow */
@Test
@WithMockUser(username = "api_user")
public void validUpdateOrganization() {
Organization organization = new Organization();
organization.setName("Test Name");