diff --git a/.github/workflows/run_tests.yaml b/.github/workflows/run_tests.yaml
index a632bc95..8bd87a47 100644
--- a/.github/workflows/run_tests.yaml
+++ b/.github/workflows/run_tests.yaml
@@ -4,15 +4,51 @@ on:
pull_request:
branches:
- master
+ - milestone/*
+
env:
ENVIRONMENT: test
- AWS_ACCESS_KEY_ID: local
- AWS_SECRET_ACCESS_KEY: local
+ AWS_ACCESS_KEY_ID: ${{ secrets.PLG_PROD_ACCESS_KEY }}
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.PLG_PROD_SECRET_KEY }}
AWS_REGION: us-east-1
jobs:
test:
runs-on: ubuntu-latest
+ services:
+ memcached:
+ image: memcached:1.6.21
+ ports:
+ - 11211:11211
+
+ dynamodb:
+ image: amazon/dynamodb-local:latest
+ ports:
+ - 8000:8000
+
steps:
+ - uses: actions/checkout@v3
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v2
+ with:
+ java-version: '17'
+ distribution: 'adopt'
+
+ - name: Build Custom docker file for KMS
+ run: |
+ echo "Building docker image"
+ docker build -t local-kms -f Dockerfile.github .
+ echo "Starting docker container for local-kms"
+ docker run -d --name localkms -p 4599:8080 -e AWS_ACCESS_KEY_ID=${{ env.AWS_ACCESS_KEY_ID }} -e AWS_SECRET_ACCESS_KEY=${{ env.AWS_SECRET_ACCESS_KEY }} -e AWS_REGION=us-east-1 -e KMS_ACCOUNT_ID=111122223333 -e KMS_REGION=us-east-1 -e KMS_SEED_PATH=seed.yaml local-kms
+
+ - name: Log into Docker Container
+ run: |
+ echo "Checking seed path"
+ seed_path=$(docker exec localkms ls /init)
+ echo "Seed path: $seed_path"
+
- run: |-
- echo "Running test cases"
\ No newline at end of file
+ echo "Start: run test cases"
+ sh ./mvnw clean test
+ echo "Done: run test cases"
diff --git a/.gitignore b/.gitignore
index 4bee3dd4..7b369379 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,6 +38,8 @@ build/
### Environment Variables ###
.env
set*_env_vars.sh
+secrets.json
+test.secrets.json
### Logs files ###
*.log
diff --git a/Dockerfile.github b/Dockerfile.github
new file mode 100644
index 00000000..613afe5e
--- /dev/null
+++ b/Dockerfile.github
@@ -0,0 +1,7 @@
+FROM nsmithuk/local-kms
+
+EXPOSE 8080
+
+# Add a file to the image
+WORKDIR /init
+COPY init/seed.yaml /init
diff --git a/Dockerfile.local b/Dockerfile.local
index a2cf669e..1d9ad1e9 100644
--- a/Dockerfile.local
+++ b/Dockerfile.local
@@ -1,14 +1,19 @@
-FROM openjdk:17-jdk-alpine
-# Set working directory
+# Use the openjdk 17 with alpine as a base image
+FROM openjdk:17-jdk-alpine as builder
+# Create and set the working directory inside the container
RUN mkdir -p /app
WORKDIR /app
-COPY . /app
+# Install bash for Alpine and other necessary tools
+RUN apk add --no-cache bash maven
-# Expose port 8080 for the app to listen on
-EXPOSE 8080
-# Start the app
-RUN apk add --no-cache bash
+# Copy the pom.xml and download dependencies
+COPY ./pom.xml ./pom.xml
+RUN mvn dependency:go-offline
-CMD ["sh", "-c", "start_local.sh"]
\ No newline at end of file
+# Copy the rest of the application
+COPY ./ ./
+
+# Expose the port 8080 for the application
+EXPOSE 8080
\ No newline at end of file
diff --git a/LOCAL_SETUP.md b/LOCAL_SETUP.md
deleted file mode 100644
index 6161cf16..00000000
--- a/LOCAL_SETUP.md
+++ /dev/null
@@ -1,60 +0,0 @@
-### Prerequisites and System Requirements
-
-Before using the *Sales Sparrow* apis, make sure your development environment meets the following prerequisites and system requirements:
-* For Docker **(Recommended)**
- - Docker version 4.19.0 or newer
-* Without Docker
- - Java 17
- - You can download it from [here](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html).
- - Dynamo DB Local Setup
- - Download the dynamodb local jar(noSQL Workbench) from [here](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.settingup.html)
- - Install and run the noSQL Workbench on your local machine
- - Toggle *DDB local* option from bottom of the left sidemenu to turn it on.
- - Add a local connection from the operation builder tab
-
-## Getting Started
-To clone the project and install dependencies, follow these steps:
-
-### Clone the project
-
-```
-$ git clone git@github.com:TrueSparrowSystems/AI-SalesSparrow-API.git
-$ cd AI-SalesSparrow-API
-```
-
-### Clone the AI-SalesSparrow-Docs submodule ###
-```
-$ git submodule update --init
-```
-
-### Set Environment Variables
-1. Copy the contents of set_env_vars-sample.sh to set_env_vars.sh
-2. Update the values of the environment variables in set_env_vars.sh
- - Salesforce credentials needs to be copied from the salesforce connected app
- - Aws credentials needs to be copied from the aws account
-
-### Start servers with docker
-```
-$ docker-compose up
-```
-
-### Start servers without docker
-```
-$ source set_env_vars.sh
-$ ./mvnw spring-boot:run
- ```
-
- **To install new dependencies**
- ```
- $ ./mvnw clean install -Dmaven.test.skip
- ```
-
- **To run test cases**
- ```
- $ ./mvnw clean test
- ```
-
- **To run test cases and generate coverage report**
- ```
- $ ./mvnw clean test jacoco:report
- ```
\ No newline at end of file
diff --git a/README.md b/README.md
index b6474fd3..ceca2573 100644
--- a/README.md
+++ b/README.md
@@ -3,17 +3,26 @@
This repository contains salessparrow apis.
## Local Setup
-Please follow the steps in [LOCAL_SETUP](LOCAL_SETUP.md) to setup the project locally.
+Follow the steps in [LOCAL_SETUP](repo-docs/LOCAL_SETUP.md) to setup the project locally.
+
+## Environment Variables
+Refer to [ENVIRONMENT_VARS](repo-docs/ENVIRONMENT_VARS.md) for detailed descriptions for the environment variables.
## Project Structure
-Please refer to [PROJECT_STRUCTURE](PROJECT_STRUCTURE.md) for details on the project structure.
+Refer to [PROJECT_STRUCTURE](repo-docs/PROJECT_STRUCTURE.md) for details on the project structure.
+
+## Changelog
+Stay up-to-date with the latest changes and improvements in our API by referring to our [CHANGELOG](repo-docs/CHANGELOG.md).
+
+## Release Process
+Refer to [RELEASE_PROCESS](repo-docs/RELEASE_PROCESS.md) to ensure smooth and consistent software releases. This process outlines the steps to prepare, package, and distribute new versions of our software.
## License
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
## Contributing
-Contributions to the project are welcome! Please see our guidelines on how to [CONTRIBUTE](CONTRIBUTING.md).
+Contributions to the project are welcome! Please see our guidelines on how to [CONTRIBUTE](repo-docs/CONTRIBUTING.md).
## Code of Conduct
-This project has a code of conduct that outlines expected behavior for contributors and users. Please read the [CODE_OF_CONDUCT](CODE_OF_CONDUCT.md) file before getting involved.
\ No newline at end of file
+This project has a code of conduct that outlines expected behavior for contributors and users. Please read the [CODE_OF_CONDUCT](repo-docs/CODE_OF_CONDUCT.md) file before getting involved.
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 10902f9e..4b410fe6 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,38 +1,83 @@
-version: '3'
+version: "3"
services:
- # App server provisioning
api:
build:
context: .
dockerfile: Dockerfile.local
ports:
- - '8080:8080'
+ - "8080:8080"
networks:
- localdev
volumes:
- - './:/app'
- command: bash -c 'sh start_local.sh'
+ - "./:/app"
+ - "~/.m2:/root/.m2"
+ environment:
+ - ENVIRONMENT=development
+ - AWS_ACCESS_KEY_ID=local
+ - AWS_SECRET_ACCESS_KEY=local
+ - AWS_REGION=us-east-1
+ command: ["./mvnw", "spring-boot:run"]
+ depends_on:
+ - dynamodb
+ - localkms
+ - memcached
+
+ test:
+ build:
+ context: .
+ dockerfile: Dockerfile.local
+ ports:
+ - "8080:8080"
+ networks:
+ - localdev
+ volumes:
+ - "./:/app"
+ - "~/.m2:/root/.m2"
+ environment:
+ - ENVIRONMENT=local-test
+ - AWS_ACCESS_KEY_ID=local
+ - AWS_SECRET_ACCESS_KEY=local
+ - AWS_REGION=us-east-1
+ command: ["./mvnw", "clean", "test", "jacoco:report"]
+ depends_on:
+ - dynamodb
+ - localkms
+ - memcached
- # Memcached provisioning
memcached:
image: memcached
ports:
- - '11211:11211'
+ - "11211:11211"
networks:
- localdev
-
- # DynamoDB provisioning
+
+ localkms:
+ image: nsmithuk/local-kms
+ ports:
+ - "4599:8080"
+ volumes:
+ - ./init:/init
+ networks:
+ - localdev
+ environment:
+ - AWS_ACCESS_KEY_ID='local'
+ - AWS_SECRET_ACCESS_KEY='local'
+ - AWS_REGION='us-east-1'
+ - KMS_ACCOUNT_ID='111122223333'
+ - KMS_REGION='us-east-1'
+ - KMS_SEED_PATH=init/seed.yaml
+
dynamodb:
image: amazon/dynamodb-local:latest
ports:
- - '8000:8000'
+ - "8000:8000"
networks:
- localdev
volumes:
- - "./docker/dynamodb:/home/dynamodblocal/data"
+ - "./docker/dynamodb:/home/dynamodblocal/data"
working_dir: /home/dynamodblocal
- command: '-jar DynamoDBLocal.jar -sharedDb -dbPath ./data'
+ command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data"
networks:
localdev:
- driver: bridge
\ No newline at end of file
+ driver: bridge
diff --git a/docs b/docs
index 17628f44..8e2977e2 160000
--- a/docs
+++ b/docs
@@ -1 +1 @@
-Subproject commit 17628f44f8389830e4f4290064ba539c1863d385
+Subproject commit 8e2977e29d59a9858d78369ea267bd86259bc839
diff --git a/init/seed.yaml b/init/seed.yaml
new file mode 100644
index 00000000..9e4ff9d1
--- /dev/null
+++ b/init/seed.yaml
@@ -0,0 +1,17 @@
+# This file is used to seed the local KMS instance with keys and aliases.
+# The keys and aliases defined here will be created when the KMS instance is
+# first started. If the keys or aliases already exist, they will not be
+# modified.
+# This is for testing purposes only.
+
+Keys:
+ Symmetric:
+ Aes:
+ - Metadata:
+ KeyId: bc436485-5092-42b8-92a3-0aa8b93536dc
+ BackingKeys:
+ - 5cdaead27fe7da2de47945d73cd6d79e36494e73802f3cd3869f1d2cb0b5d7a9
+
+Aliases:
+ - AliasName: alias/testing
+ TargetKeyId: bc436485-5092-42b8-92a3-0aa8b93536dc
diff --git a/pom.xml b/pom.xml
index 17f637e0..c9e70ecb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -12,9 +12,9 @@
com.salessparrow
- salessparrow-api
- 0.0.1
- api
+ salessparrow-api
+ 0.2.0
+ api
Salessparrow apis
@@ -30,22 +30,33 @@
3.1.1
-
- org.springframework.boot
- spring-boot-starter-webflux
+
+ org.springframework.boot
+ spring-boot-starter-webflux
3.1.1
-
-
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+ 3.1.1
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
+
org.modelmapper
modelmapper
3.1.1
-
+
- com.fasterxml.jackson.core
- jackson-databind
- 2.15.2
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.15.2
@@ -56,10 +67,16 @@
- org.springframework.boot
- spring-boot-starter-validation
+ org.springframework.boot
+ spring-boot-starter-validation
3.1.1
-
+
+
+
+ javax.xml.bind
+ jaxb-api
+ 2.4.0-b180830.0359
+
com.amazonaws
@@ -67,35 +84,35 @@
1.12.523
-
- com.amazonaws
- aws-java-sdk-elasticache
- 1.12.531
-
+
+ com.amazonaws
+ aws-java-sdk-elasticache
+ 1.12.531
+
-
- org.hibernate.validator
- hibernate-validator
- 8.0.1.Final
-
+
+ org.hibernate.validator
+ hibernate-validator
+ 8.0.1.Final
+
-
- org.springframework.boot
- spring-boot-starter-cache
+
+ org.springframework.boot
+ spring-boot-starter-cache
3.1.1
-
+
-
- net.spy
- spymemcached
- 2.12.3
-
+
+ net.spy
+ spymemcached
+ 2.12.3
+
- org.slf4j
- slf4j-nop
- 2.0.6
-
+ org.slf4j
+ slf4j-nop
+ 2.0.6
+
net.logstash.logback
@@ -128,6 +145,30 @@
0.6
+
+ com.amazonaws.secretsmanager
+ aws-secretsmanager-caching-java
+ 2.0.0
+
+
+
+ software.amazon.awssdk
+ secretsmanager
+ 2.20.132
+
+
+
+ io.spring.javaformat
+ spring-javaformat-maven-plugin
+ 0.0.39
+
+
+
+ org.jsoup
+ jsoup
+ 1.16.1
+
+
@@ -137,28 +178,40 @@
spring-boot-maven-plugin
-
- org.jacoco
- jacoco-maven-plugin
- 0.8.9
-
-
-
- prepare-agent
-
-
-
-
- report
- test
-
- report
-
-
-
-
-
+
+ io.spring.javaformat
+ spring-javaformat-maven-plugin
+ 0.0.39
+
+
+
+ validate
+ apply
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.9
+
+
+
+ prepare-agent
+
+
+
+
+ report
+ test
+
+ report
+
+
+
+
+
-
diff --git a/repo-docs/CHANGELOG.md b/repo-docs/CHANGELOG.md
new file mode 100644
index 00000000..50bd86b5
--- /dev/null
+++ b/repo-docs/CHANGELOG.md
@@ -0,0 +1,58 @@
+# SalesSparrow APIs
+
+## 0.2.0
+
+### New Features and Enhancements:
+
+- API - Disconnect Salesforce Endpoint [#9](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/9)
+- API - Get Recommended Actions from Text Endpoint [#13](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/13)
+- API - Delete Note Endpoint [#28](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/28)
+- API - Get a list of Tasks in an account [#33](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/33)
+- API - Create Task in an Account Endpoint [#34](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/34)
+- API - Get a list of CRM Organization Users Endpoint [#35](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/35)
+- Load Secrets from AWS during app initialization [#39](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/39)
+- API - Get Accounts Feed Endpoint [#45](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/45)
+- Enhance Code Security with Spring Boot [#53](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/53)
+- API - Delete Task in an Account Endpoint [#59](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/59)
+- Add CHANGELOG.md [#62](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/62)
+- Add RELEASE_PROCESS.md [#63](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/63)
+- Add Sanitization Filter for Request Params, Request Body, and Headers [#87](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/87)
+
+### Bug Fixes:
+
+- Bug: DynamoDB Upsert Behavior Updates All Fields Instead of Specific Ones [#41](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/41)
+
+### Miscellaneous:
+
+- Various code optimizations, refactoring, and improvements for better performance and maintainability.
+
+---
+
+## 0.1.0
+
+### Features:
+
+- Salesforce Connected App Setup [#1](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/1)
+- API - Get Salesforce OAuth URL Endpoint [#2](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/2)
+- Initial Project Setup [#3](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/3)
+- Sequence Diagram - Salesforce OAuth Flow [#4](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/4)
+- API - Post Salesforce Connect Endpoint [#5](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/5)
+- Initial Setup - Add Support for DynamoDB [#6](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/6)
+- API - Get Current User Endpoint [#7](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/7)
+- API - User Logout Endpoint [#8](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/8)
+- Initial Documentation [#10](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/10)
+- API - Implement Salesforce Composite API [#11](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/11)
+- API - Get Content Notes of an Account Endpoint [#12](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/12)
+- API - Search Accounts Endpoint [#15](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/15)
+- API - Create Note Endpoint [#16](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/16)
+- API - Get Note By Id Endpoint [#17](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/issues/17)
+- Updated status enum values [#27](https://github.com/TrueSparrowSystems/AI-SalesSparrow-API/pull/27)
+
+---
+
+Please feel free to provide feedback, report issues, and contribute to the SalesSparrow project!
+
+Thank you for using SalesSparrow.
+
+
+
diff --git a/CODE_OF_CONDUCT.md b/repo-docs/CODE_OF_CONDUCT.md
similarity index 100%
rename from CODE_OF_CONDUCT.md
rename to repo-docs/CODE_OF_CONDUCT.md
diff --git a/CONTRIBUTING.md b/repo-docs/CONTRIBUTING.md
similarity index 100%
rename from CONTRIBUTING.md
rename to repo-docs/CONTRIBUTING.md
diff --git a/repo-docs/ENVIRONMENT_VARS.md b/repo-docs/ENVIRONMENT_VARS.md
new file mode 100644
index 00000000..474686d2
--- /dev/null
+++ b/repo-docs/ENVIRONMENT_VARS.md
@@ -0,0 +1,88 @@
+# Environment Variables Description
+
+This document provides descriptions for the environment variables used in the configuration of the Sales Sparrow api. These variables are essential for configuring and customizing the behavior of the application.
+
+## ENCRYPTION_KEY
+
+- **Description:** A key used for encryption purposes. This is a random string with alphanumeric values.
+- **Example Value:** `7Fh9E2jRwDpV6gYcBqXsL`
+
+## API_COOKIE_SECRET
+
+- **Description:** Secret key for encrypting API cookies. This is a random string with alphanumeric values.
+- **Example Value:** `7Fh9E2jRwDpV6gYcBqXsL`
+
+## AWS_IAM_REGION
+
+- **Description:** The AWS region for IAM (Identity and Access Management) services.
+- **Example Value:** `us-east-1`
+
+## KMS_KEY_ID
+
+- **Description:** Amazon Resource Name (ARN) of the KMS (Key Management Service) key used for encryption.
+- **Example Value:** `arn:aws:kms:'us-east-1':'111122223333':key/bc436485-5092-42b8-92a3-0aa8b93536dc`
+
+## SALESFORCE_CLIENT_ID
+
+- **Description:** Client ID for authenticating with Salesforce APIs.
+- **Example Value:** `12345asdf`
+
+## SALESFORCE_CLIENT_SECRET
+
+- **Description:** Client secret for authenticating with Salesforce APIs.
+- **Example Value:** `12345asdf`
+
+## SALESFORCE_AUTH_URL
+
+- **Description:** URL for Salesforce authentication.
+- **Example Value:** `https://test.salesforce.com`
+
+## SALESFORCE_WHITELISTED_REDIRECT_URIS
+
+- **Description:** Comma-separated list of URIs allowed as redirect URIs for Salesforce authentication.
+- **Example Value:** `http://localhost:3000,example://oauth/success`
+
+## MEMCACHED_CACHE_HOST
+
+- **Description:** Hostname of the Memcached cache server.
+- **Example Value:** `memcached`
+
+## MEMCACHED_CACHE_PORT
+
+- **Description:** Port number for connecting to the Memcached cache server.
+- **Example Value:** `11211`
+
+## DYNAMO_DB_URL
+
+- **Description:** URL for connecting to the DynamoDB server.
+- **Example Value:** `http://dynamodb:8000`
+
+## LOCAL_KMS_ENDPOINT
+
+- **Description:** Endpoint for the local KMS (Key Management Service) server.
+- **Example Value:** `http://localkms:8080`
+
+## ERROR_MAIL_FROM
+
+- **Description:** Email address used as the sender for error notifications.
+- **Example Value:** `fromtest@test.com`
+
+## ERROR_MAIL_TO
+
+- **Description:** Email address where error notifications are sent.
+- **Example Value:** `totest@test.com`
+
+## LOG_LEVEL
+
+- **Description:** Logging level for the application.
+- **Example Value:** `debug`
+
+## COOKIE_DOMAIN
+
+- **Description:** Domain for the API cookies.
+- **Example Value:** `localhost`
+
+## OPENAI_API_KEY
+
+- **Description:** API key for the OpenAI API.
+- **Example Value:** `sk-12345asdf`
\ No newline at end of file
diff --git a/repo-docs/LOCAL_SETUP.md b/repo-docs/LOCAL_SETUP.md
new file mode 100644
index 00000000..b17e3d94
--- /dev/null
+++ b/repo-docs/LOCAL_SETUP.md
@@ -0,0 +1,90 @@
+# Sales Sparrow APIs: Getting Started Guide
+
+## Prerequisites and System Requirements
+
+Before using the *Sales Sparrow* APIs, make sure your development environment meets the following prerequisites and system requirements:
+
+### Docker
+
+- Docker version 4.19.0 or newer
+
+## Getting Started
+
+To clone the project and install dependencies, follow these steps:
+
+### Clone the Project
+
+```sh
+$ git clone git@github.com:TrueSparrowSystems/AI-SalesSparrow-API.git
+
+$ cd AI-SalesSparrow-API
+```
+
+### Clone the AI-SalesSparrow-Docs Submodule
+
+```sh
+$ git submodule update --init
+```
+
+### Set Environment Variables
+
+1. Copy the contents of `sample.secrets.json` to `secrets.json`.
+2. Update the values of the environment variables in secrets.json:
+ - Copy Salesforce credentials from the Salesforce connected app and update `SALESFORCE_CLIENT_ID`, `SALESFORCE_CLIENT_SECRET`, `SALESFORCE_AUTH_URL`.
+ - Update `KMS_KEY_ID` with value `arn:aws:kms:'us-east-1':'111122223333':key/bc436485-5092-42b8-92a3-0aa8b93536dc`. This local Docker setup uses the [local-kms](https://hub.docker.com/r/nsmithuk/local-kms) Docker image, and the key is already configured using [seed](init/seed.yaml).
+
+### Start the API Server with Docker
+
+```sh
+$ docker-compose up api
+```
+
+### Run Test Cases with Docker
+
+#### Set Test-Related Environment Variables
+
+1. Create a `test.secrets.json` file:
+
+```sh
+$ touch test.secrets.json
+```
+
+2. Add the following environment variables to `test.secrets.json`:
+
+```json
+{
+ "ENCRYPTION_KEY": "1234567890",
+ "API_COOKIE_SECRET": "1234567890",
+ "AWS_IAM_REGION": "us-east-1",
+ "KMS_KEY_ID": "arn:aws:kms:'us-east-1':'111122223333':key/bc436485-5092-42b8-92a3-0aa8b93536dc",
+ "SALESFORCE_CLIENT_ID": "12345",
+ "SALESFORCE_CLIENT_SECRET": "12345",
+ "SALESFORCE_AUTH_URL": "https://test.salesforce.com",
+ "SALESFORCE_WHITELISTED_REDIRECT_URIS": "http://localhost:3000",
+ "MEMCACHED_CACHE_HOST": "memcached",
+ "MEMCACHED_CACHE_PORT": "11211",
+ "LOG_LEVEL": "debug",
+ "DYNAMO_DB_URL": "http://dynamodb:8000",
+ "LOCAL_KMS_ENDPOINT": "http://localkms:8080",
+ "ERROR_MAIL_FROM": "",
+ "ERROR_MAIL_TO": "",
+ "COOKIE_DOMAIN": "",
+ "OPENAI_API_KEY": ""
+}
+```
+
+#### Apply Spring Java Format
+
+Before committing the changes, it's good practice to apply the Spring Java format to your code to ensure it adheres to a consistent style.
+
+```sh
+$ ./mvnw spring-javaformat:apply
+```
+
+#### Run Test Cases
+
+```sh
+$ docker-compose up test
+```
+
+To view the test coverage, simply open the target/site/index.html file in a web browser.
diff --git a/PROJECT_STRUCTURE.md b/repo-docs/PROJECT_STRUCTURE.md
similarity index 95%
rename from PROJECT_STRUCTURE.md
rename to repo-docs/PROJECT_STRUCTURE.md
index 71eb05d4..1523242f 100644
--- a/PROJECT_STRUCTURE.md
+++ b/repo-docs/PROJECT_STRUCTURE.md
@@ -29,6 +29,9 @@ This is a Markdown file that usually contains important information about your p
This directory serves as a submodule linked to [ai-salesparrow-docs](https://github.com/TrueSparrowSystems/AI-SalesSparrow-docs) repository that holds comprehensive documentation for the project. Instead of duplicating documentation within the main repository, this submodule approach allows you to maintain documentation separately, ensuring consistency and easier management.
+### repo-docs/
+This directory contains documentation that serves as a reference for various aspects of the project. This directory is intended to store informative documents that provide insights, explanations, and guidelines related to the project.
+
## src/ Directory:
```
diff --git a/repo-docs/RELEASE_PROCESS.md b/repo-docs/RELEASE_PROCESS.md
new file mode 100644
index 00000000..f2c6e780
--- /dev/null
+++ b/repo-docs/RELEASE_PROCESS.md
@@ -0,0 +1,95 @@
+# SalesSparrow APIs Release Process
+
+## Introduction
+
+**Objective:** Ensure that our open source backend repository is consistently and effectively updated, with full transparency to our community. Our agile approach, combined with a unique milestone branch system and continuous integration, strives to deliver high-quality updates in a structured manner.
+
+---
+
+## **1. Pre-Release Planning**
+
+### **1.1 Sprint Planning**
+
+- At the beginning of each sprint, prioritize the GitHub issues to be addressed.
+- Label issues with milestones corresponding to the anticipated release version (e.g., `v1.2.0`).
+- Whenever a bug is discovered or a new feature needs to be implemented, an issue is created on GitHub.
+- Issues are tagged appropriately (e.g., `bug`, `enhancement`, `documentation`) and are assigned to the relevant team members.
+
+### **1.2 Continuous Integration (CI)**
+
+- Ensure that any code pushed to the main branch passes through a CI pipeline, which includes lint checks, unit tests, integration tests, and other relevant checks.
+- For each issue team members work on, they create a new branch from the `milestone` branch created for that milestone. e.g. `milestone/v1.2.0`
+---
+
+## **2. Release Candidate (RC)**
+
+### **2.1 Branching**
+
+- Create a release branch off the main branch named `release/vX.Y.Z` (where `X.Y.Z` is the release version) or use the `milestone` branch approach based on project conventions.
+- Developers raise PRs against this branch (or the `milestone` branch if using that approach). PR titles and descriptions should be detailed, linking back to the original issue.
+
+### **2.2 Version Update**
+
+- Update the version in the project configuration or metadata files.
+
+### **2.3 Testing**
+
+- PRs will automatically trigger the CI workflow, ensuring that the combined changes from the entire milestone don't introduce any issues when integrated.
+- Ensure that the release candidate is thoroughly tested. This may include:
+ - Regression Testing
+ - Performance Testing
+ - Security Scanning
+ - User Acceptance Testing (UAT) for significant features or changes
+
+### **2.4 Documentation**
+
+- Update the `CHANGELOG.md` or equivalent file with the details of the changes, enhancements, fixes, and any potential breaking changes.
+- Ensure that all new features, enhancements, or changes are documented appropriately.
+
+---
+
+## **3. Release**
+
+### **3.1 Merging**
+
+- Once the release candidate is deemed stable, merge the `release/vX.Y.Z` branch (or the `milestone` branch) into the `main` branch.
+
+### **3.2 GitHub Release**
+
+- On the GitHub repository, navigate to the "Releases" tab.
+- Draft a new release, inputting the tag version, release title, and the notes from the `CHANGELOG.md`.
+- Publish the release. This action will notify watchers and those who have starred the repository.
+
+### **3.3 Announcements**
+
+- Announce the new release on any relevant communication channels, such as the project's mailing list, Twitter, Discord, or other community platforms.
+
+---
+
+## **4. Post-Release**
+
+### **4.1 Monitoring**
+
+- Monitor any feedback or issues reported by users related to the new release.
+
+### **4.2 Hotfixes**
+
+- If any critical issues or bugs are reported, prioritize and address them immediately.
+- For significant bugs, create a hotfix branch off the main branch, apply the fix, and then merge it back into the main branch.
+- Tag a new minor release version (e.g., `v1.2.1`) and follow the release steps as mentioned above.
+
+### **4.3 Sprint Retrospective**
+
+- At the end of the sprint or after the release, review the process and any feedback.
+- Identify areas of improvement or optimization for the next release cycle.
+
+---
+
+## **5. Best Practices**
+
+- **Transparency:** Ensure all decisions, issues, and discussions related to the release are public and transparent.
+- **Communication:** Keep the community informed about release dates, anticipated changes, and any delays.
+- **Documentation:** All features and changes should be well-documented to assist users and contributors.
+- **Feedback Loop:** Encourage users to report bugs, issues, or provide feedback about the release.
+
+---
\ No newline at end of file
diff --git a/sample.secrets.json b/sample.secrets.json
new file mode 100644
index 00000000..f3be477d
--- /dev/null
+++ b/sample.secrets.json
@@ -0,0 +1,18 @@
+{
+ "ENCRYPTION_KEY": "",
+ "API_COOKIE_SECRET": "",
+ "AWS_IAM_REGION": "",
+ "KMS_KEY_ID": "",
+ "SALESFORCE_CLIENT_ID": "",
+ "SALESFORCE_CLIENT_SECRET": "",
+ "SALESFORCE_AUTH_URL": "",
+ "SALESFORCE_WHITELISTED_REDIRECT_URIS": "",
+ "MEMCACHED_CACHE_HOST": "",
+ "MEMCACHED_CACHE_PORT": "",
+ "LOG_LEVEL": "",
+ "DYNAMO_DB_URL": "",
+ "ERROR_MAIL_FROM": "",
+ "ERROR_MAIL_TO": "",
+ "COOKIE_DOMAIN": "",
+ "OPENAI_API_KEY": ""
+}
\ No newline at end of file
diff --git a/set_env_vars-sample.sh b/set_env_vars-sample.sh
deleted file mode 100644
index fa928f46..00000000
--- a/set_env_vars-sample.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-# Application
-export ENVIRONMENT='development'
-export SALESFORCE_WHITELISTED_REDIRECT_URIS=''
-
-# Authentication
-export ENCRYPTION_KEY='1234567890'
-export API_COOKIE_SECRET='1234567890'
-
-# AWS
-export AWS_IAM_ACCESS_KEY_ID=''
-export AWS_IAM_SECRET_ACCESS_KEY=''
-export AWS_IAM_REGION=''
-export KMS_KEY_ID=''
-
-# Dynamo DB
-export DYNAMO_DB_URL='http://dynamodb:8000'
-
-# Salesforce
-export SALESFORCE_AUTH_URL='https://test.salesforce.com'
-export SALESFORCE_CLIENT_ID=''
-export SALESFORCE_CLIENT_SECRET=''
-
-# Memcached
-export MEMCACHED_CACHE_HOST='localhost'
-export MEMCACHED_CACHE_PORT='11211'
-
-# Error Email
-export ERROR_MAIL_FROM=''
-export ERROR_MAIL_TO=''
-
-# Logging
-export LOG_LEVEL='info'
diff --git a/set_testing_env_vars-sample.sh b/set_testing_env_vars-sample.sh
deleted file mode 100644
index 929c6d4b..00000000
--- a/set_testing_env_vars-sample.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-# Application
-export ENVIRONMENT='test'
-export SALESFORCE_WHITELISTED_REDIRECT_URIS=''
-
-# Authentication
-export ENCRYPTION_KEY='1234567890'
-export API_COOKIE_SECRET='1234567890'
-
-# AWS
-export AWS_IAM_ACCESS_KEY_ID='accessKeyId'
-export AWS_IAM_SECRET_ACCESS_KEY='secretAccessKey'
-export AWS_IAM_REGION='region'
-export KMS_KEY_ID=''
-
-# Database
-export DYNAMO_DB_URL='http://localhost:8000'
-
-# Salesforce
-export SALESFORCE_CLIENT_ID=''
-export SALESFORCE_CLIENT_SECRET=''
-export SALESFORCE_AUTH_URL=''
-
-# Memcached
-export MEMCACHED_CACHE_HOST='localhost'
-export MEMCACHED_CACHE_PORT='11211'
-
-# Error Email
-export ERROR_MAIL_FROM=''
-export ERROR_MAIL_TO=''
-
-# Logging
-export LOG_LEVEL='info'
\ No newline at end of file
diff --git a/src/main/java/com/salessparrow/api/SalesSparrowApi.java b/src/main/java/com/salessparrow/api/SalesSparrowApi.java
index 63981bc6..1fe1c6e5 100644
--- a/src/main/java/com/salessparrow/api/SalesSparrowApi.java
+++ b/src/main/java/com/salessparrow/api/SalesSparrowApi.java
@@ -2,11 +2,11 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync;
-
-@SpringBootApplication
+@SpringBootApplication(exclude = { UserDetailsServiceAutoConfiguration.class })
@EnableCaching // This enables caching
@EnableAsync // This enables asynchronous processing in Spring
public class SalesSparrowApi {
@@ -14,4 +14,5 @@ public class SalesSparrowApi {
public static void main(String[] args) {
SpringApplication.run(SalesSparrowApi.class, args);
}
+
}
diff --git a/src/main/java/com/salessparrow/api/changelogs/DatabaseChangelog.java b/src/main/java/com/salessparrow/api/changelogs/DatabaseChangelog.java
index 595aa24e..2896b5dc 100644
--- a/src/main/java/com/salessparrow/api/changelogs/DatabaseChangelog.java
+++ b/src/main/java/com/salessparrow/api/changelogs/DatabaseChangelog.java
@@ -15,6 +15,7 @@
@ChangeLog
public class DatabaseChangelog {
+
Logger logger = LoggerFactory.getLogger(DatabaseChangelog.class);
@ChangeSet(order = "001", id = "001", author = "testAuthor")
@@ -22,14 +23,10 @@ public void createSalesforceOrganizationsTable(AmazonDynamoDB db) {
String tableName = DynamoDbTableNameConstants.salesforceOrganizationsTableName();
logger.info("Creating table: " + tableName);
- CreateTableRequest request = new CreateTableRequest()
- .withTableName(tableName)
- .withAttributeDefinitions(
- new AttributeDefinition("external_organization_id",
- ScalarAttributeType.S))
- .withKeySchema(
- new KeySchemaElement("external_organization_id", KeyType.HASH))
- .withBillingMode("PAY_PER_REQUEST");
+ CreateTableRequest request = new CreateTableRequest().withTableName(tableName)
+ .withAttributeDefinitions(new AttributeDefinition("external_organization_id", ScalarAttributeType.S))
+ .withKeySchema(new KeySchemaElement("external_organization_id", KeyType.HASH))
+ .withBillingMode("PAY_PER_REQUEST");
db.createTable(request);
logger.info("Done creating table: " + tableName);
@@ -40,13 +37,10 @@ public void createSalesforceOAuthTokensTable(AmazonDynamoDB db) {
String tableName = DynamoDbTableNameConstants.salesforceOauthTokensTableName();
logger.info("Creating table:" + tableName);
- CreateTableRequest request = new CreateTableRequest()
- .withTableName(tableName)
- .withAttributeDefinitions(
- new AttributeDefinition("external_user_id", ScalarAttributeType.S))
- .withKeySchema(
- new KeySchemaElement("external_user_id", KeyType.HASH))
- .withBillingMode("PAY_PER_REQUEST");
+ CreateTableRequest request = new CreateTableRequest().withTableName(tableName)
+ .withAttributeDefinitions(new AttributeDefinition("external_user_id", ScalarAttributeType.S))
+ .withKeySchema(new KeySchemaElement("external_user_id", KeyType.HASH))
+ .withBillingMode("PAY_PER_REQUEST");
db.createTable(request);
@@ -58,16 +52,14 @@ public void createSalesforceUsersTable(AmazonDynamoDB db) {
String tableName = DynamoDbTableNameConstants.salesforceUsersTableName();
logger.info("Creating table:" + tableName);
- CreateTableRequest request = new CreateTableRequest()
- .withTableName(tableName)
- .withAttributeDefinitions(
- new AttributeDefinition("external_user_id", ScalarAttributeType.S))
- .withKeySchema(
- new KeySchemaElement("external_user_id", KeyType.HASH))
- .withBillingMode("PAY_PER_REQUEST");
+ CreateTableRequest request = new CreateTableRequest().withTableName(tableName)
+ .withAttributeDefinitions(new AttributeDefinition("external_user_id", ScalarAttributeType.S))
+ .withKeySchema(new KeySchemaElement("external_user_id", KeyType.HASH))
+ .withBillingMode("PAY_PER_REQUEST");
db.createTable(request);
logger.info("Done creating table: " + tableName);
}
+
}
\ No newline at end of file
diff --git a/src/main/java/com/salessparrow/api/config/AwsConfig.java b/src/main/java/com/salessparrow/api/config/AwsConfig.java
index 7e175e74..ba1268fd 100644
--- a/src/main/java/com/salessparrow/api/config/AwsConfig.java
+++ b/src/main/java/com/salessparrow/api/config/AwsConfig.java
@@ -1,7 +1,6 @@
package com.salessparrow.api.config;
-import com.amazonaws.auth.AWSStaticCredentialsProvider;
-import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.kms.AWSKMS;
import com.amazonaws.services.kms.AWSKMSClientBuilder;
@@ -10,45 +9,47 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+
/**
* Configuration class for AWS-related beans and settings.
- *
+ *
*/
@Configuration
public class AwsConfig {
- /**
- * Creates and configures an AWS KMS (Key Management Service) client.
- *
- * @return An instance of AWSKMS that allows access to AWS KMS operations.
- */
- @Bean
- public AWSKMS kmsClient() {
- BasicAWSCredentials awsCredentials = new BasicAWSCredentials(
- CoreConstants.awsAccessKeyId(),
- CoreConstants.awsSecretAccessKey());
-
- return AWSKMSClientBuilder.standard()
- .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
- .withRegion(CoreConstants.awsRegion())
- .build();
- }
-
- /**
- * Creates and configures an AWS SES (Simple Email Service) client.
- *
- * @return An instance of AmazonSimpleEmailService that allows access to AWS SES operations.
- */
- @Bean
- public AmazonSimpleEmailService sesClient() {
- BasicAWSCredentials awsCredentials = new BasicAWSCredentials(
- CoreConstants.awsAccessKeyId(),
- CoreConstants.awsSecretAccessKey());
-
- return AmazonSimpleEmailServiceClientBuilder.standard()
- .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
- .withRegion(CoreConstants.awsRegion())
- .build();
- }
+ /**
+ * Returns an instance of the AWS Key Management Service (KMS) client based on the
+ * environment.
+ *
+ * @implNote - Client is configured to use the local KMS endpoint for following
+ * environments - development - test - local-test For test and production
+ * environments, the client is configured to use the AWS KMS endpoint
+ * @return An instance of the AWSKMS client configured for the appropriate
+ * environment.
+ *
+ */
+ @Bean
+ public AWSKMS kmsClient() {
+ if (CoreConstants.isDevEnvironment() || CoreConstants.isTestEnvironment()
+ || CoreConstants.isLocalTestEnvironment()) {
+
+ AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(
+ CoreConstants.localKmsEndpoint(), CoreConstants.awsRegion());
+
+ return AWSKMSClientBuilder.standard().withEndpointConfiguration(endpointConfiguration).build();
+ }
+
+ return AWSKMSClientBuilder.standard().withRegion(CoreConstants.awsRegion()).build();
+ }
+
+ /**
+ * Creates and configures an AWS SES (Simple Email Service) client.
+ * @return An instance of AmazonSimpleEmailService that allows access to AWS SES
+ * operations.
+ */
+ @Bean
+ public AmazonSimpleEmailService sesClient() {
+ return AmazonSimpleEmailServiceClientBuilder.standard().withRegion(CoreConstants.awsRegion()).build();
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/salessparrow/api/config/CoreConstants.java b/src/main/java/com/salessparrow/api/config/CoreConstants.java
index b381cbe6..270174d2 100644
--- a/src/main/java/com/salessparrow/api/config/CoreConstants.java
+++ b/src/main/java/com/salessparrow/api/config/CoreConstants.java
@@ -1,95 +1,117 @@
package com.salessparrow.api.config;
+import com.salessparrow.api.lib.globalConstants.SecretConstants;
+
/**
* Class to get the environment variables.
*/
public class CoreConstants {
- public static String encryptionKey() {
- return System.getenv("ENCRYPTION_KEY");
- }
-
- public static String apiCookieSecret() {
- return System.getenv("API_COOKIE_SECRET");
- }
-
- public static String environment() {
- return System.getenv("ENVIRONMENT");
- }
-
- public static Boolean isDevEnvironment() {
- return environment().equals("development");
- }
-
- public static Boolean isTestEnvironment() {
- return environment().equals("test");
- }
-
- public static String awsAccessKeyId() {
- return System.getenv("AWS_IAM_ACCESS_KEY_ID");
- }
-
- public static String awsSecretAccessKey() {
- return System.getenv("AWS_IAM_SECRET_ACCESS_KEY");
- }
-
- public static String awsRegion() {
- return System.getenv("AWS_IAM_REGION");
- }
-
- public static String kmsKeyId() {
- return System.getenv("KMS_KEY_ID");
- }
-
- public static String salesforceAuthUrl() {
- return System.getenv("SALESFORCE_AUTH_URL");
- }
-
- public static String salesforceClientId() {
- return System.getenv("SALESFORCE_CLIENT_ID");
- }
-
- public static String salesforceClientSecret() {
- return System.getenv("SALESFORCE_CLIENT_SECRET");
- }
-
- /**
- * This method returns the memcached address that is going to be used for locals
- *
- * @return String
- */
- public static String memcachedAddress() {
- return System.getenv("MEMCACHED_CACHE_HOST") + ":" + System.getenv("MEMCACHED_CACHE_PORT");
- }
-
- /**
- * This method returns the list of redirect URIs that are whitelisted in
- * Salesforce connected app for oAuth.
- *
- * @return String[]
- */
- public static String[] getWhitelistedRedirectUris() {
- String redirectUrisJson = System.getenv("SALESFORCE_WHITELISTED_REDIRECT_URIS");
- return redirectUrisJson.split(",");
- }
-
- /**
- * This method returns the email address that will be used to send error emails.
- * This email address or its domain must be verified in AWS SES.
- *
- * @return String
- */
- public static String errorEmailFrom() {
- return System.getenv("ERROR_MAIL_FROM");
- }
-
- /**
- * This method returns the email address that will receive the error emails.
- *
- * @return String
- */
- public static String errorEmailTo() {
- return System.getenv("ERROR_MAIL_TO");
- }
+ /* Start: Env variables required before spring application context is initialized */
+
+ public static String environment() {
+ return System.getenv("ENVIRONMENT");
+ }
+
+ public static Boolean isDevEnvironment() {
+ return environment().equals("development");
+ }
+
+ public static Boolean isTestEnvironment() {
+ return environment().equals("test");
+ }
+
+ public static Boolean isLocalTestEnvironment() {
+ return environment().equals("local-test");
+ }
+
+ /* End: Env variables required before spring application context is initialized */
+
+ public static String cookieDomain() {
+ return SecretConstants.cookieDomain();
+ }
+
+ public static String awsRegion() {
+ return SecretConstants.awsRegion();
+ }
+
+ public static String encryptionKey() {
+ return SecretConstants.encryptionKey();
+ }
+
+ public static String apiCookieSecret() {
+ return SecretConstants.apiCookieSecret();
+ }
+
+ public static String kmsKeyId() {
+ return SecretConstants.kmsKeyId();
+ }
+
+ public static String salesforceAuthUrl() {
+ return SecretConstants.salesforceAuthUrl();
+ }
+
+ public static String salesforceClientId() {
+ return SecretConstants.salesforceClientId();
+ }
+
+ public static String salesforceClientSecret() {
+ return SecretConstants.salesforceClientSecret();
+ }
+
+ public static String localKmsEndpoint() {
+ return SecretConstants.localKmsEndpoint();
+ }
+
+ /**
+ * This method returns the memcached address that is going to be used for locals
+ * @return String
+ */
+ public static String memcachedAddress() {
+ return SecretConstants.memcachedHost() + ":" + SecretConstants.memcachedPort();
+ }
+
+ /**
+ * This method returns the list of redirect URIs that are whitelisted in Salesforce
+ * connected app for oAuth.
+ * @return String[]
+ */
+ public static String[] getWhitelistedRedirectUris() {
+ String redirectUrisJson = SecretConstants.salesforceWhitelistedRedirectUris();
+ return redirectUrisJson.split(",");
+ }
+
+ /**
+ * This method returns api key for OpenAI.
+ * @return String
+ */
+ public static String openAiApiKey() {
+ return SecretConstants.openAiApiKey();
+ }
+
+ /**
+ * This method returns the email address that will be used to send error emails. This
+ * email address or its domain must be verified in AWS SES.
+ * @return String
+ */
+ public static String errorEmailFrom() {
+ return SecretConstants.errorEmailFrom();
+ }
+
+ /**
+ * This method returns the email address that will receive the error emails.
+ * @return String
+ */
+ public static String errorEmailTo() {
+ return SecretConstants.errorEmailTo();
+ }
+
+ /**
+ * This method returns the dynamodb url.
+ * @return
+ */
+ public static String dynamoDbUrl() {
+ return SecretConstants.dynamoDbUrl();
+ }
}
diff --git a/src/main/java/com/salessparrow/api/config/CorsConfig.java b/src/main/java/com/salessparrow/api/config/CorsConfig.java
index 64b4a8d9..d378d8a2 100644
--- a/src/main/java/com/salessparrow/api/config/CorsConfig.java
+++ b/src/main/java/com/salessparrow/api/config/CorsConfig.java
@@ -1,4 +1,5 @@
package com.salessparrow.api.config;
+
import org.springframework.context.annotation.Profile;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@@ -13,15 +14,16 @@
@Profile("!production")
public class CorsConfig implements WebMvcConfigurer {
- @Override
- public void addCorsMappings(CorsRegistry registry) {
- Logger logger = LoggerFactory.getLogger(CorsConfig.class);
- logger.info("Add Cors config for localhost:3000");
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ Logger logger = LoggerFactory.getLogger(CorsConfig.class);
+ logger.info("Add Cors config for localhost:3000");
+
+ registry.addMapping("/**")
+ .allowedOrigins("http://localhost:3000")
+ .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
+ .allowCredentials(true)
+ .maxAge(3600);
+ }
- registry.addMapping("/**")
- .allowedOrigins("http://localhost:3000")
- .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
- .allowCredentials(true)
- .maxAge(3600);
- }
}
diff --git a/src/main/java/com/salessparrow/api/config/DynamoBeeConfig.java b/src/main/java/com/salessparrow/api/config/DynamoBeeConfig.java
index b11738e9..e1eff2aa 100644
--- a/src/main/java/com/salessparrow/api/config/DynamoBeeConfig.java
+++ b/src/main/java/com/salessparrow/api/config/DynamoBeeConfig.java
@@ -13,16 +13,19 @@
*/
@Configuration
public class DynamoBeeConfig {
- @Autowired
- private AmazonDynamoDB db;
- @Autowired
- private dynamoBeeConfigConstants dynamoBeeConfigConstants;
+ @Autowired
+ private AmazonDynamoDB db;
+
+ @Autowired
+ private dynamoBeeConfigConstants dynamoBeeConfigConstants;
+
+ @Bean
+ public Dynamobee dynamobee() {
+ Dynamobee runner = new Dynamobee(db);
+ runner.setChangeLogsScanPackage(dynamoBeeConfigConstants.getChangeLogScanPackage())
+ .setChangelogTableName(dynamoBeeConfigConstants.getChangelogTableName());
+ return runner;
+ }
- @Bean
- public Dynamobee dynamobee(){
- Dynamobee runner = new Dynamobee(db);
- runner.setChangeLogsScanPackage(dynamoBeeConfigConstants.getChangeLogScanPackage()).setChangelogTableName(dynamoBeeConfigConstants.getChangelogTableName());
- return runner;
- }
}
diff --git a/src/main/java/com/salessparrow/api/config/DynamoDBConfiguration.java b/src/main/java/com/salessparrow/api/config/DynamoDBConfiguration.java
index 16052285..c0951f8c 100644
--- a/src/main/java/com/salessparrow/api/config/DynamoDBConfiguration.java
+++ b/src/main/java/com/salessparrow/api/config/DynamoDBConfiguration.java
@@ -1,77 +1,96 @@
package com.salessparrow.api.config;
-import com.amazonaws.auth.AWSStaticCredentialsProvider;
-import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig;
+import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.SaveBehavior;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DynamoDBConfiguration {
- Logger logger = LoggerFactory.getLogger(DynamoDBConfiguration.class);
-
-
- @Value("${aws.dynamodb.endpoint}")
- private String dynamodbEndpoint;
-
- @Value("${aws.region}")
- private String awsRegion;
-
- @Value("${aws.dynamodb.accessKey}")
- private String dynamodbAccessKey;
-
- @Value("${aws.dynamodb.secretKey}")
- private String dynamodbSecretKey;
-
-
- @Bean
- public DynamoDBMapper dynamoDBMapper() {
- DynamoDBMapper defaultMapper = new DynamoDBMapper(buildAmazonDynamoDB(), dynamoDBMapperConfig());
-
- //Override DynamoDb operations to add logging.
- return new DynamoDBMapper(buildAmazonDynamoDB(), dynamoDBMapperConfig()) {
-
- @Override
- public T load(Class clazz, Object hashKey) {
- logger.debug("DBQuery:Load: table-{} hashKey-{}", clazz.getSimpleName(), hashKey);
- return defaultMapper.load(clazz, hashKey);
- }
-
- @Override
- public void save(T object) {
- logger.debug("DBQuery:Save: table-{}", object.getClass().getSimpleName());
- defaultMapper.save(object);
- }
- // Similarly, you can override other used methods like delete, batchSave, etc. similarly
- };
- }
-
- @Bean
- public AmazonDynamoDB buildAmazonDynamoDB() {
- return AmazonDynamoDBClientBuilder
- .standard()
- .withEndpointConfiguration(
- new AwsClientBuilder.EndpointConfiguration(dynamodbEndpoint,awsRegion))
- .withCredentials(new AWSStaticCredentialsProvider(
- new BasicAWSCredentials(dynamodbAccessKey,dynamodbSecretKey)))
- .build();
- }
-
- @Bean
- DynamoDBMapperConfig dynamoDBMapperConfig() {
- String prefix = CoreConstants.environment() + "_";
- return new DynamoDBMapperConfig.Builder()
- .withTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNamePrefix(prefix))
- .build();
- }
-}
-
+ Logger logger = LoggerFactory.getLogger(DynamoDBConfiguration.class);
+
+ @Bean
+ public DynamoDBMapper dynamoDBMapper() {
+ DynamoDBMapper defaultMapper = new DynamoDBMapper(buildAmazonDynamoDB(), dynamoDBMapperConfig());
+ // Override DynamoDb operations to add logging.
+ return new DynamoDBMapper(buildAmazonDynamoDB(), dynamoDBMapperConfig()) {
+ @Override
+ public T load(Class clazz, Object hashKey) {
+ T response = null;
+ long startTimestamp = System.currentTimeMillis();
+ try {
+ response = defaultMapper.load(clazz, hashKey);
+ }
+ catch (Exception e) {
+ logger.debug("DBQuery:Load: table-{} hashKey-{}", clazz.getSimpleName(), hashKey);
+ logger.error("DBQuery:Load: exception-{}", e);
+ throw new RuntimeException("Error during load database operation", e);
+ }
+
+ long duration = System.currentTimeMillis() - startTimestamp;
+ logger.debug("({} ms)DBQuery:Load: table-{} hashKey-{}", duration, clazz.getSimpleName(), hashKey);
+ return response;
+ }
+
+ @Override
+ public void save(T object) {
+ long startTimestamp = System.currentTimeMillis();
+ try {
+ defaultMapper.save(object);
+ }
+ catch (Exception e) {
+ logger.debug("DBQuery:Save: table-{}", object.getClass().getSimpleName());
+ logger.error("DBQuery:Save: exception-{}", e);
+ throw new RuntimeException("Error during save database operation", e);
+ }
+
+ long duration = System.currentTimeMillis() - startTimestamp;
+ logger.debug("({} ms)DBQuery:Save: table-{}", duration, object.getClass().getSimpleName());
+ }
+
+ @Override
+ public void save(T object, DynamoDBMapperConfig config) {
+ long startTimestamp = System.currentTimeMillis();
+ try {
+ defaultMapper.save(object, config);
+ }
+ catch (Exception e) {
+ logger.debug("DBQuery:Save: table-{}", object.getClass().getSimpleName());
+ logger.error("DBQuery:Save: exception-{}", e);
+ throw new RuntimeException("Error during save database operation", e);
+ }
+
+ long duration = System.currentTimeMillis() - startTimestamp;
+ logger.debug("({} ms)DBQuery:Save: table-{}", duration, object.getClass().getSimpleName());
+ }
+
+ // Similarly, you can override other used methods like delete, batchSave, etc.
+ };
+ }
+
+ @Bean
+ public AmazonDynamoDB buildAmazonDynamoDB() {
+ return AmazonDynamoDBClientBuilder.standard()
+ .withEndpointConfiguration(
+ new AwsClientBuilder.EndpointConfiguration(CoreConstants.dynamoDbUrl(), CoreConstants.awsRegion()))
+ .build();
+ }
+
+ @Bean
+ DynamoDBMapperConfig dynamoDBMapperConfig() {
+ String prefix = CoreConstants.environment() + "_";
+ return new DynamoDBMapperConfig.Builder()
+ .withTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNamePrefix(prefix))
+ .withSaveBehavior(SaveBehavior.UPDATE_SKIP_NULL_ATTRIBUTES)
+ .build();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/salessparrow/api/config/FilterConfig.java b/src/main/java/com/salessparrow/api/config/FilterConfig.java
new file mode 100644
index 00000000..8ba64fc8
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/config/FilterConfig.java
@@ -0,0 +1,39 @@
+package com.salessparrow.api.config;
+
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.salessparrow.api.filter.SameSiteCookieFilter;
+import com.salessparrow.api.filter.SanitizationFilter;
+
+@Configuration
+public class FilterConfig {
+
+ /**
+ * Register SanitizationFilter
+ * @return FilterRegistrationBean
+ */
+ @Bean
+ public FilterRegistrationBean sanitizationFilter() {
+ FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
+ registrationBean.setFilter(new SanitizationFilter());
+ registrationBean.addUrlPatterns("/*");
+ registrationBean.setOrder(1);
+ return registrationBean;
+ }
+
+ /**
+ * Register SameSiteCookieFilter
+ * @return FilterRegistrationBean
+ */
+ @Bean
+ public FilterRegistrationBean sameSiteCookieFilter() {
+ FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
+ registrationBean.setFilter(new SameSiteCookieFilter());
+ registrationBean.addUrlPatterns("/*"); // or specific URL patterns
+ registrationBean.setOrder(2);
+ return registrationBean;
+ }
+
+}
diff --git a/src/main/java/com/salessparrow/api/config/InterceptorConfig.java b/src/main/java/com/salessparrow/api/config/InterceptorConfig.java
index c82c0026..a0e939ea 100644
--- a/src/main/java/com/salessparrow/api/config/InterceptorConfig.java
+++ b/src/main/java/com/salessparrow/api/config/InterceptorConfig.java
@@ -6,37 +6,49 @@
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.salessparrow.api.interceptors.LoggerInterceptor;
+import com.salessparrow.api.interceptors.JsonOnlyInterceptor;
import com.salessparrow.api.interceptors.UserAuthInterceptor;
import com.salessparrow.api.interceptors.V1Interceptor;
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
-
- @Autowired
- private final LoggerInterceptor loggerInterceptor;
-
- @Autowired
- private final V1Interceptor V1Interceptor;
-
- @Autowired
- private final UserAuthInterceptor userAuthInterceptor;
-
- public InterceptorConfig(UserAuthInterceptor userAuthInterceptor, LoggerInterceptor loggerInterceptor, V1Interceptor V1Interceptor) {
- this.userAuthInterceptor = userAuthInterceptor;
- this.loggerInterceptor = loggerInterceptor;
- this.V1Interceptor = V1Interceptor;
- }
-
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(loggerInterceptor)
- .addPathPatterns("/**");
-
- registry.addInterceptor(V1Interceptor)
- .addPathPatterns("/api/v1/**");
-
- registry.addInterceptor(userAuthInterceptor)
- .addPathPatterns("/**")
- .excludePathPatterns("/api/v1/auth/salesforce/**");
- }
+
+ @Autowired
+ private final LoggerInterceptor loggerInterceptor;
+
+ @Autowired
+ private final JsonOnlyInterceptor jsonOnlyInterceptor;
+
+ @Autowired
+ private final V1Interceptor V1Interceptor;
+
+ @Autowired
+ private final UserAuthInterceptor userAuthInterceptor;
+
+ public InterceptorConfig(UserAuthInterceptor userAuthInterceptor, JsonOnlyInterceptor jsonOnlyInterceptor,
+ LoggerInterceptor loggerInterceptor, V1Interceptor V1Interceptor) {
+ this.userAuthInterceptor = userAuthInterceptor;
+ this.loggerInterceptor = loggerInterceptor;
+ this.V1Interceptor = V1Interceptor;
+ this.jsonOnlyInterceptor = jsonOnlyInterceptor;
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ /* Add logger interceptor to all the routes */
+ registry.addInterceptor(loggerInterceptor).addPathPatterns("/**");
+
+ /* Add json only interceptor to all the routes */
+ registry.addInterceptor(jsonOnlyInterceptor).addPathPatterns("/**");
+
+ /* Add v1 interceptor only to all the routes */
+ registry.addInterceptor(V1Interceptor).addPathPatterns("/api/v1/**");
+
+ /* Add user auth interceptor to all the routes except the ones below */
+ registry.addInterceptor(userAuthInterceptor)
+ .addPathPatterns("/**")
+ .excludePathPatterns("/api/v1/auth/salesforce/**")
+ .excludePathPatterns("/api/v1/health-check");
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/com/salessparrow/api/config/MemcachedConfig.java b/src/main/java/com/salessparrow/api/config/MemcachedConfig.java
index 1dc3738a..6d0e6ce1 100644
--- a/src/main/java/com/salessparrow/api/config/MemcachedConfig.java
+++ b/src/main/java/com/salessparrow/api/config/MemcachedConfig.java
@@ -7,6 +7,7 @@
import com.salessparrow.api.exception.CustomException;
import com.salessparrow.api.lib.errorLib.ErrorObject;
import com.salessparrow.api.lib.globalConstants.CacheConstants;
+import com.salessparrow.api.utility.CacheKeyGenerator;
import com.salessparrow.api.utility.Memcached;
import net.spy.memcached.AddrUtil;
@@ -22,7 +23,6 @@
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.interceptor.SimpleCacheErrorHandler;
-import org.springframework.cache.interceptor.SimpleKeyGenerator;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -33,94 +33,77 @@
@Configuration
public class MemcachedConfig implements CachingConfigurer {
- private MemcachedClient cache;
-
- private static final Logger logger = LoggerFactory.getLogger(MemcachedConfig.class);
-
- /**
- * Cache Manager Bean to initialize the cache client.
- *
- * @return CacheManager
- */
- @Override
- @Bean
- public CacheManager cacheManager() {
- SimpleCacheManager cacheManager = new SimpleCacheManager();
-
- setMemcachedClient();
-
- cacheManager.setCaches(internalCaches(this.cache));
- return cacheManager;
- }
-
- /**
- * Internal Caches
- * All caches needs to be added here along with their expiry time.
- *
- * @return Collection
- */
- private Collection internalCaches(MemcachedClient cache) {
- final Collection caches = new ArrayList<>();
-
- caches.add(new Memcached(
- CacheConstants.SS_SALESFORCE_USER_CACHE,
- CacheConstants.SS_SALESFORCE_USER_CACHE_EXP,
- cache
- ));
- caches.add(
- new Memcached(
- CacheConstants.SS_SALESFORCE_OAUTH_TOKEN_CACHE,
- CacheConstants.SS_SALESFORCE_OAUTH_TOKEN_CACHE_EXP,
- cache
- ));
- return caches;
- }
-
- public void setMemcachedClient() {
- logger.info("Memcached Client Initialized");
- try {
- this.cache = new MemcachedClient(
- new ConnectionFactoryBuilder()
- .setTranscoder(new SerializingTranscoder())
- .setProtocol(ConnectionFactoryBuilder.Protocol.BINARY)
- .build(),
- AddrUtil.getAddresses(CoreConstants.memcachedAddress()));
- } catch (Exception e) {
- throw new CustomException(
- new ErrorObject(
- "a_c_mc_mc_1",
- "something_went_wrong",
- e.getMessage()));
- }
- }
-
- /**
- * Key Generator
- *
- * @return KeyGenerator
- */
- @Override
- public KeyGenerator keyGenerator() {
- return new SimpleKeyGenerator();
- }
-
- /**
- * Error Handler
- *
- * @return CacheErrorHandler
- */
- @Override
- public CacheErrorHandler errorHandler() {
- return new SimpleCacheErrorHandler();
- }
-
- /**
- * Cache Resolver
- *
- * @return CacheResolver
- */
- @Override
- public CacheResolver cacheResolver() {
- return null;
- }
+ private MemcachedClient cache;
+
+ private static final Logger logger = LoggerFactory.getLogger(MemcachedConfig.class);
+
+ /**
+ * Cache Manager Bean to initialize the cache client.
+ * @return CacheManager
+ */
+ @Override
+ @Bean
+ public CacheManager cacheManager() {
+ SimpleCacheManager cacheManager = new SimpleCacheManager();
+
+ setMemcachedClient();
+
+ cacheManager.setCaches(internalCaches(this.cache));
+ return cacheManager;
+ }
+
+ /**
+ * Internal Caches All caches needs to be added here along with their expiry time.
+ * @return Collection
+ */
+ private Collection internalCaches(MemcachedClient cache) {
+ final Collection caches = new ArrayList<>();
+
+ caches.add(new Memcached(CacheConstants.SS_SALESFORCE_USER_CACHE, CacheConstants.SS_SALESFORCE_USER_CACHE_EXP,
+ cache));
+ caches.add(new Memcached(CacheConstants.SS_SALESFORCE_OAUTH_TOKEN_CACHE,
+ CacheConstants.SS_SALESFORCE_OAUTH_TOKEN_CACHE_EXP, cache));
+ return caches;
+ }
+
+ public void setMemcachedClient() {
+ logger.info("Memcached Client Initialized");
+ try {
+ this.cache = new MemcachedClient(new ConnectionFactoryBuilder().setTranscoder(new SerializingTranscoder())
+ .setProtocol(ConnectionFactoryBuilder.Protocol.BINARY)
+ .build(), AddrUtil.getAddresses(CoreConstants.memcachedAddress()));
+ }
+ catch (Exception e) {
+ throw new CustomException(new ErrorObject("a_c_mc_mc_1", "something_went_wrong", e.getMessage()));
+ }
+ }
+
+ /**
+ * Key Generator is overriden to include a prefix that can be different for different
+ * environments.
+ * @return KeyGenerator
+ */
+ @Override
+ public KeyGenerator keyGenerator() {
+ return new CacheKeyGenerator();
+ }
+
+ /**
+ * Error Handler
+ * @return CacheErrorHandler
+ */
+ @Override
+ public CacheErrorHandler errorHandler() {
+ return new SimpleCacheErrorHandler();
+ }
+
+ /**
+ * Cache Resolver
+ * @return CacheResolver
+ */
+ @Override
+ public CacheResolver cacheResolver() {
+ return null;
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/com/salessparrow/api/config/SecurityConfig.java b/src/main/java/com/salessparrow/api/config/SecurityConfig.java
new file mode 100644
index 00000000..d8d55c72
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/config/SecurityConfig.java
@@ -0,0 +1,80 @@
+package com.salessparrow.api.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.header.writers.XXssProtectionHeaderWriter;
+import org.springframework.security.web.header.writers.ReferrerPolicyHeaderWriter.ReferrerPolicy;
+
+@Configuration
+@EnableWebSecurity
+public class SecurityConfig {
+
+ @Bean
+ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+
+ http
+ // disable authorization for all routes
+ .authorizeHttpRequests(authorizeRequests -> authorizeRequests.anyRequest().permitAll())
+ // Disable authentication for all routes
+ .httpBasic(httpBasic -> httpBasic.disable())
+ // Disable form login
+ .formLogin(formLogin -> formLogin.disable())
+ // Remove csrf in app routes
+ .csrf((csrf) -> csrf.ignoringRequestMatchers("/api/v1/**"))
+
+ /**
+ * Cache-Control header - applied by default in spring security The
+ * Cache-Control header is the most important header to set as it effectively
+ * disables caching on the client side.
+ *
+ * Pragma header - applied by default in spring security The Pragma directive
+ * is an older directive meant for HTTP/1.0 clients where the Cache-Control
+ * header wasn't defined.
+ *
+ * Expires header - applied by default in spring security The Expires header
+ * is another older way to prevent caching, especially in HTTP/1.0.
+ *
+ * X-Content-Type-Options header - applied by default in spring security The
+ * X-Content-Type-Options header is a security feature that prevents pages
+ * from loading when they detect incorrect MIME types. By setting the value to
+ * "nosniff", you're instructing the browser not to override the provided
+ * Content-Type
+ *
+ * HSTS header The Strict-Transport-Security header is a security feature
+ * implemented by web browsers to ensure that websites are only accessed using
+ * HTTPS.
+ *
+ * X-Frame-Options header The X-Frame-Options header is a security feature
+ * that prevents your web page from being put in a frame.
+ *
+ * X-XSS-Protection header - applied by default in spring security The
+ * X-XSS-Protection header is a security feature that prevents pages from
+ * loading when they detect reflected cross-site scripting (XSS) attacks.
+ *
+ * It is not needed for rest api's as they are not rendered in the browser.
+ * But it is no harm and is a good practice to have it.The value "1;
+ * mode=block" instructs the browser to block the response if it detects an
+ * attack.
+ *
+ * Referrer-Policy header The Referrer-Policy header is a security feature
+ * that prevents pages from leaking information about the user's browsing
+ * behavior.The value "same-origin" instructs the browser to send the referrer
+ * header only when the request is originating from the same origin as the
+ * target resource.
+ */
+ .headers(headers -> headers.frameOptions(frameOptions -> frameOptions.deny())
+ .httpStrictTransportSecurity(
+ hsts -> hsts.includeSubDomains(true).preload(true).maxAgeInSeconds(31536000))
+ .xssProtection(xss -> xss.headerValue(XXssProtectionHeaderWriter.HeaderValue.ENABLED_MODE_BLOCK))
+ .referrerPolicy(referrer -> referrer.policy(ReferrerPolicy.SAME_ORIGIN)));
+
+ // http redirect to https is handled by the reverse proxy server (nginx). So no
+ // need to handle it here.
+
+ return http.build();
+ }
+
+}
diff --git a/src/main/java/com/salessparrow/api/controllers/AccountController.java b/src/main/java/com/salessparrow/api/controllers/AccountController.java
index 44058227..9bce08a7 100644
--- a/src/main/java/com/salessparrow/api/controllers/AccountController.java
+++ b/src/main/java/com/salessparrow/api/controllers/AccountController.java
@@ -6,22 +6,15 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import com.salessparrow.api.dto.formatter.CreateNoteFormatterDto;
-import com.salessparrow.api.dto.formatter.GetAccountsFormatterDto;
-import com.salessparrow.api.dto.formatter.GetNoteDetailsFormatterDto;
-import com.salessparrow.api.dto.formatter.GetNotesListFormatterDto;
import com.salessparrow.api.dto.requestMapper.GetAccountsDto;
-import com.salessparrow.api.dto.requestMapper.NoteDto;
-import com.salessparrow.api.services.accounts.CreateNoteService;
+import com.salessparrow.api.dto.requestMapper.GetAccountsFeedDto;
+import com.salessparrow.api.dto.responseMapper.GetAccountListResponseDto;
+import com.salessparrow.api.dto.responseMapper.GetAccountsFeedResponseDto;
import com.salessparrow.api.services.accounts.GetAccountListService;
-import com.salessparrow.api.services.accounts.GetNoteDetailsService;
-import com.salessparrow.api.services.accounts.GetNotesListService;
+import com.salessparrow.api.services.accounts.GetAccountsFeedService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
@@ -31,59 +24,33 @@
@Validated
public class AccountController {
- private Logger logger = org.slf4j.LoggerFactory.getLogger(AccountController.class);
+ private Logger logger = org.slf4j.LoggerFactory.getLogger(AccountController.class);
- @Autowired
- private GetAccountListService getAccountListService;
+ @Autowired
+ private GetAccountListService getAccountListService;
- @Autowired
- private GetNotesListService getNotesListService;
+ @Autowired
+ private GetAccountsFeedService getAccountsFeedService;
- @Autowired
- private GetNoteDetailsService getNoteDetailsService;
+ @GetMapping("")
+ public ResponseEntity getAccounts(HttpServletRequest request,
+ @Valid @ModelAttribute GetAccountsDto getAccountsDto) {
+ logger.info("Request received");
- @Autowired
- private CreateNoteService createNoteService;
+ GetAccountListResponseDto getAccountsResponse = getAccountListService.getAccounts(request, getAccountsDto);
- @PostMapping("/{account_id}/notes")
- public ResponseEntity addNoteToAccount(
- HttpServletRequest request,
- @PathVariable("account_id") String accountId,
- @Valid @RequestBody NoteDto note
- ) {
- CreateNoteFormatterDto createNoteFormatterDto = createNoteService.createNote(request, accountId, note);
+ return ResponseEntity.ok().body(getAccountsResponse);
+ }
- return ResponseEntity.ok().body(createNoteFormatterDto);
- }
+ @GetMapping("/feed")
+ public ResponseEntity getFeed(HttpServletRequest request,
+ @Valid @ModelAttribute GetAccountsFeedDto getAccountsFeedDto) {
+ logger.info("Request received");
- @GetMapping("")
- public ResponseEntity getAccounts(
- HttpServletRequest request,
- @Valid @ModelAttribute GetAccountsDto getAccountsDto) {
- logger.info("Request received");
+ GetAccountsFeedResponseDto getAccountsFeedResponse = getAccountsFeedService.getAccountsFeed(request,
+ getAccountsFeedDto);
- GetAccountsFormatterDto getAccountsResponse = getAccountListService.getAccounts(request, getAccountsDto);
+ return ResponseEntity.ok().body(getAccountsFeedResponse);
+ }
- return ResponseEntity.ok().body(getAccountsResponse);
- }
-
- @GetMapping("/{account_id}/notes")
- public ResponseEntity getNotesList(HttpServletRequest request,@PathVariable("account_id") String accountId) {
-
- GetNotesListFormatterDto getNotesListResponse = getNotesListService.getNotesList(request, accountId);
-
- return ResponseEntity.ok().body(getNotesListResponse);
- }
-
- @GetMapping("/{account_id}/notes/{note_id}")
- public ResponseEntity getNoteFromAccount(
- HttpServletRequest request,
- @PathVariable("account_id") String accountId,
- @PathVariable("note_id") String noteId
- ) {
-
- GetNoteDetailsFormatterDto getNoteDetailsResponse = getNoteDetailsService.getNoteDetails(request, noteId);
-
- return ResponseEntity.ok().body(getNoteDetailsResponse);
- }
}
diff --git a/src/main/java/com/salessparrow/api/controllers/AccountNoteController.java b/src/main/java/com/salessparrow/api/controllers/AccountNoteController.java
new file mode 100644
index 00000000..ff6d4d6c
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/controllers/AccountNoteController.java
@@ -0,0 +1,86 @@
+package com.salessparrow.api.controllers;
+
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.salessparrow.api.dto.formatter.CreateNoteFormatterDto;
+import com.salessparrow.api.dto.formatter.GetNoteDetailsFormatterDto;
+import com.salessparrow.api.dto.formatter.GetNotesListFormatterDto;
+import com.salessparrow.api.dto.requestMapper.NoteDto;
+import com.salessparrow.api.services.accountNotes.CreateAccountNoteService;
+import com.salessparrow.api.services.accountNotes.DeleteAccountNoteService;
+import com.salessparrow.api.services.accountNotes.GetAccountNoteDetailsService;
+import com.salessparrow.api.services.accountNotes.GetAccountNotesListService;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.Valid;
+
+@RestController
+@RequestMapping("/api/v1/accounts/{account_id}/notes")
+@Validated
+public class AccountNoteController {
+
+ private Logger logger = org.slf4j.LoggerFactory.getLogger(AccountNoteController.class);
+
+ @Autowired
+ private GetAccountNotesListService getNotesListService;
+
+ @Autowired
+ private GetAccountNoteDetailsService getNoteDetailsService;
+
+ @Autowired
+ private CreateAccountNoteService createNoteService;
+
+ @Autowired
+ private DeleteAccountNoteService deleteAccountNoteService;
+
+ @PostMapping("")
+ public ResponseEntity addNoteToAccount(HttpServletRequest request,
+ @PathVariable("account_id") String accountId, @Valid @RequestBody NoteDto note) {
+ logger.info("Create Note request received");
+
+ CreateNoteFormatterDto createNoteFormatterDto = createNoteService.createNote(request, accountId, note);
+
+ return ResponseEntity.ok().body(createNoteFormatterDto);
+ }
+
+ @GetMapping("")
+ public ResponseEntity getNotesList(HttpServletRequest request,
+ @PathVariable("account_id") String accountId) {
+ logger.info("Get Note List request received");
+
+ GetNotesListFormatterDto getNotesListResponse = getNotesListService.getNotesList(request, accountId);
+
+ return ResponseEntity.ok().body(getNotesListResponse);
+ }
+
+ @GetMapping("/{note_id}")
+ public ResponseEntity getNoteFromAccount(HttpServletRequest request,
+ @PathVariable("account_id") String accountId, @PathVariable("note_id") String noteId) {
+ logger.info("Get Note request received");
+
+ GetNoteDetailsFormatterDto getNoteDetailsResponse = getNoteDetailsService.getNoteDetails(request, noteId);
+
+ return ResponseEntity.ok().body(getNoteDetailsResponse);
+ }
+
+ @DeleteMapping("/{note_id}")
+ public ResponseEntity deleteNote(HttpServletRequest request,
+ @PathVariable("account_id") String accountId, @PathVariable("note_id") String noteId) {
+ logger.info("Delete Note request received");
+
+ deleteAccountNoteService.deleteAccountNote(request, accountId, noteId);
+
+ return ResponseEntity.noContent().build();
+ }
+
+}
diff --git a/src/main/java/com/salessparrow/api/controllers/AccountTaskController.java b/src/main/java/com/salessparrow/api/controllers/AccountTaskController.java
new file mode 100644
index 00000000..7cab58dc
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/controllers/AccountTaskController.java
@@ -0,0 +1,73 @@
+package com.salessparrow.api.controllers;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.salessparrow.api.dto.formatter.CreateTaskFormatterDto;
+import com.salessparrow.api.dto.requestMapper.CreateAccountTaskDto;
+import com.salessparrow.api.services.accountTask.CreateTaskService;
+import com.salessparrow.api.services.accountTask.DeleteTaskService;
+import com.salessparrow.api.dto.formatter.GetTasksListFormatterDto;
+import com.salessparrow.api.services.accountTask.GetAccountTasksListService;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.Valid;
+
+@RestController
+@RequestMapping("/api/v1/accounts")
+@Validated
+public class AccountTaskController {
+
+ Logger logger = LoggerFactory.getLogger(AccountTaskController.class);
+
+ @Autowired
+ private CreateTaskService createTaskService;
+
+ @Autowired
+ private DeleteTaskService deleteTaskService;
+
+ @Autowired
+ private GetAccountTasksListService getAccountTasksListService;
+
+ @PostMapping("/{account_id}/tasks")
+ public ResponseEntity createTask(HttpServletRequest request,
+ @PathVariable("account_id") String accountId, @Valid @RequestBody CreateAccountTaskDto task) {
+ logger.info("Create task request received");
+
+ CreateTaskFormatterDto createTaskFormatterDto = createTaskService.createAccountTask(request, accountId, task);
+
+ return ResponseEntity.status(HttpStatus.CREATED).body(createTaskFormatterDto);
+ }
+
+ @GetMapping("/{account_id}/tasks")
+ public ResponseEntity getTasksList(HttpServletRequest request,
+ @PathVariable("account_id") String accountId) {
+ logger.info("Get tasks list request received");
+
+ GetTasksListFormatterDto getTasksListFormatterDto = getAccountTasksListService.getAccountTasksList(request,
+ accountId);
+ return ResponseEntity.status(HttpStatus.OK).body(getTasksListFormatterDto);
+ }
+
+ @DeleteMapping("/{account_id}/tasks/{task_id}")
+ public ResponseEntity deleteTask(HttpServletRequest request, @PathVariable("account_id") String accountId,
+ @PathVariable("task_id") String taskId) {
+ logger.info("Delete task request received");
+
+ deleteTaskService.deleteAccountTask(request, accountId, taskId);
+
+ return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
+ }
+
+}
diff --git a/src/main/java/com/salessparrow/api/controllers/AuthController.java b/src/main/java/com/salessparrow/api/controllers/AuthController.java
index f533719b..0056ac1b 100644
--- a/src/main/java/com/salessparrow/api/controllers/AuthController.java
+++ b/src/main/java/com/salessparrow/api/controllers/AuthController.java
@@ -19,6 +19,7 @@
import com.salessparrow.api.dto.requestMapper.SalesforceConnectDto;
import com.salessparrow.api.dto.requestMapper.SalesforceRedirectUrlDto;
import com.salessparrow.api.lib.CookieHelper;
+import com.salessparrow.api.services.auth.DisconnectUserService;
import com.salessparrow.api.services.salesforce.AuthService;
import com.salessparrow.api.services.salesforce.AuthService.AuthServiceDto;
@@ -30,49 +31,68 @@
@Validated
public class AuthController {
- Logger logger = LoggerFactory.getLogger(AuthController.class);
+ Logger logger = LoggerFactory.getLogger(AuthController.class);
- @Autowired
- private RedirectUrlService redirectUrlService;
+ @Autowired
+ private RedirectUrlService redirectUrlService;
- @Autowired
- private AuthService authService;
+ @Autowired
+ private AuthService authService;
- @Autowired
- private CookieHelper cookieHelper;
+ @Autowired
+ private DisconnectUserService disconnectUserService;
- @GetMapping("/salesforce/redirect-url")
- public ResponseEntity getSalesforceRedirectUrl(
- @Valid @ModelAttribute SalesforceRedirectUrlDto salesforceRedirectUrlDto) {
-
- RedirectUrlFormatterDto redirectUrlFormatterDto = redirectUrlService.getSalesforceOauthUrl(salesforceRedirectUrlDto);
+ @Autowired
+ private CookieHelper cookieHelper;
- return ResponseEntity.ok().body(redirectUrlFormatterDto);
- }
+ @GetMapping("/salesforce/redirect-url")
+ public ResponseEntity getSalesforceRedirectUrl(
+ @Valid @ModelAttribute SalesforceRedirectUrlDto salesforceRedirectUrlDto) {
- @PostMapping("/salesforce/connect")
- public ResponseEntity connectToSalesforce(
- @Valid @RequestBody SalesforceConnectDto salesforceConnectDto) {
- logger.info("Salesforce connection request received");
+ RedirectUrlFormatterDto redirectUrlFormatterDto = redirectUrlService
+ .getSalesforceOauthUrl(salesforceRedirectUrlDto);
- AuthServiceDto authServiceResponse = authService.connectToSalesforce(salesforceConnectDto);
+ return ResponseEntity.ok().body(redirectUrlFormatterDto);
+ }
- HttpHeaders headers = new HttpHeaders();
- headers = cookieHelper.setUserCookie(authServiceResponse.getCurrentUserLoginCookie(), headers);
+ @PostMapping("/salesforce/connect")
+ public ResponseEntity connectToSalesforce(HttpServletRequest request,
+ @Valid @RequestBody SalesforceConnectDto salesforceConnectDto) {
+ logger.info("Salesforce connection request received");
- SalesforceConnectFormatterDto salesforceConnectResponse = new SalesforceConnectFormatterDto();
- salesforceConnectResponse.setCurrentUser(authServiceResponse.getCurrentUser());
+ AuthServiceDto authServiceResponse = authService.connectToSalesforce(salesforceConnectDto, request);
- return ResponseEntity.ok().headers(headers).body(salesforceConnectResponse);
- }
+ HttpHeaders headers = new HttpHeaders();
+ headers = cookieHelper.setUserCookie(authServiceResponse.getCurrentUserLoginCookie(), headers);
- @PostMapping("/logout")
- public ResponseEntity logout(HttpServletRequest request) {
- logger.info("User logout request received");
+ SalesforceConnectFormatterDto salesforceConnectResponse = new SalesforceConnectFormatterDto();
+ salesforceConnectResponse.setCurrentUser(authServiceResponse.getCurrentUser());
- HttpHeaders headers = new HttpHeaders();
- headers = cookieHelper.clearUserCookie(headers);
+ return ResponseEntity.ok().headers(headers).body(salesforceConnectResponse);
+ }
+
+ @PostMapping("/logout")
+ public ResponseEntity logout(HttpServletRequest request) {
+ logger.info("User logout request received");
+
+ HttpHeaders headers = new HttpHeaders();
+ headers = cookieHelper.clearUserCookie(headers);
+
+ return ResponseEntity.ok().headers(headers).body(null);
+ }
+
+ @PostMapping("/disconnect")
+ public ResponseEntity disconnect(HttpServletRequest request) {
+ logger.info("User disconnect request received");
+
+ disconnectUserService.disconnect(request);
+
+ logger.info("Clearing user cookie");
+ HttpHeaders headers = new HttpHeaders();
+ headers = cookieHelper.clearUserCookie(headers);
+
+ logger.info("User disconnected successfully");
+ return ResponseEntity.noContent().headers(headers).build();
+ }
- return ResponseEntity.ok().headers(headers).body(null);
- }
}
diff --git a/src/main/java/com/salessparrow/api/controllers/CrmOrganizationUserController.java b/src/main/java/com/salessparrow/api/controllers/CrmOrganizationUserController.java
new file mode 100644
index 00000000..53fce632
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/controllers/CrmOrganizationUserController.java
@@ -0,0 +1,40 @@
+package com.salessparrow.api.controllers;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.salessparrow.api.dto.formatter.GetCrmOrganizationUsersFormatterDto;
+import com.salessparrow.api.dto.requestMapper.GetCrmOrganizationUsersDto;
+import com.salessparrow.api.services.crmOrganizationUsers.GetCrmOrganizationUsersList;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.validation.Valid;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ModelAttribute;
+
+@RestController
+@RequestMapping("/api/v1/crm-organization-users")
+public class CrmOrganizationUserController {
+
+ Logger logger = LoggerFactory.getLogger(CrmOrganizationUserController.class);
+
+ @Autowired
+ private GetCrmOrganizationUsersList getCrmOrganizationUsersList;
+
+ @GetMapping("")
+ public ResponseEntity getCrmOrganizationUsers(HttpServletRequest request,
+ @Valid @ModelAttribute GetCrmOrganizationUsersDto CrmOrganizationUsersDto) {
+ logger.info("Get list of crm organization users request received");
+
+ GetCrmOrganizationUsersFormatterDto getCrmOrganizationUsersFormatterDto = getCrmOrganizationUsersList
+ .getCrmOrganizationUsers(request, CrmOrganizationUsersDto);
+
+ return ResponseEntity.ok().body(getCrmOrganizationUsersFormatterDto);
+ }
+
+}
diff --git a/src/main/java/com/salessparrow/api/controllers/HealthCheck.java b/src/main/java/com/salessparrow/api/controllers/HealthCheck.java
new file mode 100644
index 00000000..e848c85b
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/controllers/HealthCheck.java
@@ -0,0 +1,17 @@
+package com.salessparrow.api.controllers;
+
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/api/v1/health-check")
+public class HealthCheck {
+
+ @GetMapping("")
+ public ResponseEntity HealthCheck() {
+ return ResponseEntity.ok().body("OK");
+ }
+
+}
diff --git a/src/main/java/com/salessparrow/api/controllers/SuggestionsController.java b/src/main/java/com/salessparrow/api/controllers/SuggestionsController.java
new file mode 100644
index 00000000..0bef0c1e
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/controllers/SuggestionsController.java
@@ -0,0 +1,35 @@
+package com.salessparrow.api.controllers;
+
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.salessparrow.api.dto.formatter.CrmActionSuggestionsFormatterDto;
+import com.salessparrow.api.dto.requestMapper.CrmActionsSuggestionsDto;
+import com.salessparrow.api.services.suggestions.CrmActionsSuggestionsService;
+
+import jakarta.validation.Valid;
+
+@RestController
+@RequestMapping("/api/v1/suggestions")
+@Validated
+public class SuggestionsController {
+
+ private Logger logger = org.slf4j.LoggerFactory.getLogger(SuggestionsController.class);
+
+ @Autowired
+ private CrmActionsSuggestionsService crmActionsSuggestionsService;
+
+ @PostMapping("/crm-actions")
+ public CrmActionSuggestionsFormatterDto getCrmActionSuggestions(
+ @Valid @RequestBody CrmActionsSuggestionsDto crmActionsSuggestionsDto) {
+ logger.info("Crm actions suggestions request received");
+
+ return crmActionsSuggestionsService.getSuggestions(crmActionsSuggestionsDto);
+ }
+
+}
diff --git a/src/main/java/com/salessparrow/api/controllers/UserController.java b/src/main/java/com/salessparrow/api/controllers/UserController.java
index cad29cdc..7d4385f1 100644
--- a/src/main/java/com/salessparrow/api/controllers/UserController.java
+++ b/src/main/java/com/salessparrow/api/controllers/UserController.java
@@ -15,15 +15,16 @@
@RequestMapping("/api/v1/users")
public class UserController {
- @Autowired
- private GetCurrentUserService getCurrentUserService;
+ @Autowired
+ private GetCurrentUserService getCurrentUserService;
- @GetMapping("/current")
- public ResponseEntity GetCurrentUser(HttpServletRequest request) {
+ @GetMapping("/current")
+ public ResponseEntity GetCurrentUser(HttpServletRequest request) {
- GetCurrentUserFormatterDto getCurrentUserFormatterDto = new GetCurrentUserFormatterDto();
- getCurrentUserFormatterDto.setCurrentUser(getCurrentUserService.getCurrentUser(request));
+ GetCurrentUserFormatterDto getCurrentUserFormatterDto = new GetCurrentUserFormatterDto();
+ getCurrentUserFormatterDto.setCurrentUser(getCurrentUserService.getCurrentUser(request));
+
+ return ResponseEntity.ok().body(getCurrentUserFormatterDto);
+ }
- return ResponseEntity.ok().body(getCurrentUserFormatterDto);
- }
}
diff --git a/src/main/java/com/salessparrow/api/domain/SalesforceOauthToken.java b/src/main/java/com/salessparrow/api/domain/SalesforceOauthToken.java
index b130f0b0..2916fcc6 100644
--- a/src/main/java/com/salessparrow/api/domain/SalesforceOauthToken.java
+++ b/src/main/java/com/salessparrow/api/domain/SalesforceOauthToken.java
@@ -18,90 +18,94 @@
/**
* SalesforceOauthToken model.
- *
+ *
* Cached data is serialized into bytes and stored in cache and deserialize when
- * retrieved.
- * Hence, the class must implement Serializable.
+ * retrieved. Hence, the class must implement Serializable.
*/
@Data
@NoArgsConstructor
@DynamoDBTable(tableName = "salesforce_oauth_tokens")
public class SalesforceOauthToken implements Serializable {
- public enum Status {
- ACTIVE(1),
- DELETED(2);
+ public enum Status {
- private final int value;
- private static final Map map = new HashMap<>();
+ ACTIVE(1), DELETED(2);
- static {
- for (Status status : Status.values()) {
- map.put(status.value, status);
- }
- }
+ private final int value;
- Status(int value) {
- this.value = value;
- }
+ private static final Map map = new HashMap<>();
- public int getValue() {
- return value;
- }
+ static {
+ for (Status status : Status.values()) {
+ map.put(status.value, status);
+ }
+ }
- public static Status valueOf(int value) {
- return map.get(value);
- }
- }
+ Status(int value) {
+ this.value = value;
+ }
- @DynamoDBHashKey(attributeName = "external_user_id")
- private String externalUserId;
+ public int getValue() {
+ return value;
+ }
- @DynamoDBAttribute(attributeName = "identity_url")
- private String identityUrl;
+ public static Status valueOf(int value) {
+ return map.get(value);
+ }
- @DynamoDBAttribute(attributeName = "access_token")
- private String accessToken;
+ }
- @DynamoDBAttribute(attributeName = "refresh_token")
- private String refreshToken;
+ @DynamoDBHashKey(attributeName = "external_user_id")
+ private String externalUserId;
- @DynamoDBAttribute(attributeName = "signature")
- private String signature;
+ @DynamoDBAttribute(attributeName = "identity_url")
+ private String identityUrl;
- @DynamoDBAttribute(attributeName = "id_token")
- private String idToken;
+ @DynamoDBAttribute(attributeName = "access_token")
+ private String accessToken;
- @DynamoDBAttribute(attributeName = "instance_url")
- private String instanceUrl;
+ @DynamoDBAttribute(attributeName = "refresh_token")
+ private String refreshToken;
- @DynamoDBTypeConverted(converter = StatusEnumConverter.class)
- @DynamoDBAttribute(attributeName = "status")
- private Status status;
+ @DynamoDBAttribute(attributeName = "signature")
+ private String signature;
- @DynamoDBAttribute(attributeName = "issued_at")
- private Long issuedAt;
+ @DynamoDBAttribute(attributeName = "id_token")
+ private String idToken;
- @DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.CREATE)
- @DynamoDBAttribute(attributeName = "created_at")
- private Date createdAt;
+ @DynamoDBAttribute(attributeName = "instance_url")
+ private String instanceUrl;
- @DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.ALWAYS)
- @DynamoDBAttribute(attributeName = "updated_at")
- private Date updatedAt;
+ @DynamoDBTypeConverted(converter = StatusEnumConverter.class)
+ @DynamoDBAttribute(attributeName = "status")
+ private Status status;
- /**
- * Converts Status enum to Integer and vice versa.
- */
- public static class StatusEnumConverter implements DynamoDBTypeConverter {
- @Override
- public Integer convert(Status status) {
- return status.getValue();
- }
+ @DynamoDBAttribute(attributeName = "issued_at")
+ private Long issuedAt;
+
+ @DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.CREATE)
+ @DynamoDBAttribute(attributeName = "created_at")
+ private Date createdAt;
+
+ @DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.ALWAYS)
+ @DynamoDBAttribute(attributeName = "updated_at")
+ private Date updatedAt;
+
+ /**
+ * Converts Status enum to Integer and vice versa.
+ */
+ public static class StatusEnumConverter implements DynamoDBTypeConverter {
+
+ @Override
+ public Integer convert(Status status) {
+ return status.getValue();
+ }
+
+ @Override
+ public Status unconvert(Integer value) {
+ return Status.valueOf(value);
+ }
+
+ }
- @Override
- public Status unconvert(Integer value) {
- return Status.valueOf(value);
- }
- }
}
diff --git a/src/main/java/com/salessparrow/api/domain/SalesforceOrganization.java b/src/main/java/com/salessparrow/api/domain/SalesforceOrganization.java
index 97209234..97297a21 100644
--- a/src/main/java/com/salessparrow/api/domain/SalesforceOrganization.java
+++ b/src/main/java/com/salessparrow/api/domain/SalesforceOrganization.java
@@ -1,5 +1,6 @@
package com.salessparrow.api.domain;
+import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@@ -18,61 +19,66 @@
@Data
@NoArgsConstructor
@DynamoDBTable(tableName = "salesforce_organizations")
-public class SalesforceOrganization {
-
- public enum Status {
- ACTIVE(1),
- DELETED(2);
-
- private final int value;
- private static final Map map = new HashMap<>();
-
- static {
- for (Status status : Status.values()) {
- map.put(status.value, status);
- }
- }
-
- Status(int value) {
- this.value = value;
- }
-
- public int getValue() {
- return value;
- }
-
- public static Status valueOf(int value) {
- return map.get(value);
- }
- }
-
- @DynamoDBHashKey(attributeName = "external_organization_id")
- private String externalOrganizationId;
-
- @DynamoDBTypeConverted(converter = StatusEnumConverter.class)
- @DynamoDBAttribute(attributeName = "status")
- private Status status;
-
- @DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.CREATE)
- @DynamoDBAttribute(attributeName = "created_at")
- private Date createdAt;
-
- @DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.ALWAYS)
- @DynamoDBAttribute(attributeName = "updated_at")
- private Date updatedAt;
-
- /**
- * Converts Status enum to Integer and vice versa.
- */
- public static class StatusEnumConverter implements DynamoDBTypeConverter {
- @Override
- public Integer convert(Status status) {
- return status.getValue();
- }
-
- @Override
- public Status unconvert(Integer value) {
- return Status.valueOf(value);
- }
- }
+public class SalesforceOrganization implements Serializable {
+
+ public enum Status {
+
+ ACTIVE(1), DELETED(2);
+
+ private final int value;
+
+ private static final Map map = new HashMap<>();
+
+ static {
+ for (Status status : Status.values()) {
+ map.put(status.value, status);
+ }
+ }
+
+ Status(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public static Status valueOf(int value) {
+ return map.get(value);
+ }
+
+ }
+
+ @DynamoDBHashKey(attributeName = "external_organization_id")
+ private String externalOrganizationId;
+
+ @DynamoDBTypeConverted(converter = StatusEnumConverter.class)
+ @DynamoDBAttribute(attributeName = "status")
+ private Status status;
+
+ @DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.CREATE)
+ @DynamoDBAttribute(attributeName = "created_at")
+ private Date createdAt;
+
+ @DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.ALWAYS)
+ @DynamoDBAttribute(attributeName = "updated_at")
+ private Date updatedAt;
+
+ /**
+ * Converts Status enum to Integer and vice versa.
+ */
+ public static class StatusEnumConverter implements DynamoDBTypeConverter {
+
+ @Override
+ public Integer convert(Status status) {
+ return status.getValue();
+ }
+
+ @Override
+ public Status unconvert(Integer value) {
+ return Status.valueOf(value);
+ }
+
+ }
+
}
diff --git a/src/main/java/com/salessparrow/api/domain/SalesforceUser.java b/src/main/java/com/salessparrow/api/domain/SalesforceUser.java
index 89934262..6a5f84dd 100644
--- a/src/main/java/com/salessparrow/api/domain/SalesforceUser.java
+++ b/src/main/java/com/salessparrow/api/domain/SalesforceUser.java
@@ -19,94 +19,98 @@
/**
* SalesforceUser model.
- *
+ *
* Cached data is serialized into bytes and stored in cache and deserialize when
- * retrieved.
- * Hence, the class must implement Serializable.
+ * retrieved. Hence, the class must implement Serializable.
*/
@Data
@NoArgsConstructor
@DynamoDBTable(tableName = "salesforce_users")
public class SalesforceUser implements User, Serializable {
- public enum Status {
- ACTIVE(1),
- DELETED(2);
+ public enum Status {
- private final int value;
- private static final Map map = new HashMap<>();
+ ACTIVE(1), DELETED(2);
- static {
- for (Status status : Status.values()) {
- map.put(status.value, status);
- }
- }
+ private final int value;
- Status(int value) {
- this.value = value;
- }
+ private static final Map map = new HashMap<>();
- public int getValue() {
- return value;
- }
+ static {
+ for (Status status : Status.values()) {
+ map.put(status.value, status);
+ }
+ }
- public static Status valueOf(int value) {
- return map.get(value);
- }
- }
+ Status(int value) {
+ this.value = value;
+ }
- @DynamoDBHashKey(attributeName = "external_user_id")
- private String externalUserId;
+ public int getValue() {
+ return value;
+ }
- @DynamoDBAttribute(attributeName = "identity_url")
- private String identityUrl;
+ public static Status valueOf(int value) {
+ return map.get(value);
+ }
- @DynamoDBAttribute(attributeName = "external_organization_id")
- private String externalOrganizationId;
+ }
- @DynamoDBAttribute(attributeName = "name")
- private String name;
+ @DynamoDBHashKey(attributeName = "external_user_id")
+ private String externalUserId;
- @DynamoDBAttribute(attributeName = "email")
- private String email;
+ @DynamoDBAttribute(attributeName = "identity_url")
+ private String identityUrl;
- @DynamoDBAttribute(attributeName = "user_kind")
- private String userKind;
+ @DynamoDBAttribute(attributeName = "external_organization_id")
+ private String externalOrganizationId;
- @DynamoDBAttribute(attributeName = "cookie_token")
- private String cookieToken;
+ @DynamoDBAttribute(attributeName = "name")
+ private String name;
- @DynamoDBAttribute(attributeName = "encryption_salt")
- private String encryptionSalt;
+ @DynamoDBAttribute(attributeName = "email")
+ private String email;
- @DynamoDBTypeConverted(converter = StatusEnumConverter.class)
- @DynamoDBAttribute(attributeName = "status")
- private Status status;
+ @DynamoDBAttribute(attributeName = "user_kind")
+ private String userKind;
- @DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.CREATE)
- @DynamoDBAttribute(attributeName = "created_at")
- private Date createdAt;
+ @DynamoDBAttribute(attributeName = "cookie_token")
+ private String cookieToken;
- @DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.ALWAYS)
- @DynamoDBAttribute(attributeName = "updated_at")
- private Date updatedAt;
+ @DynamoDBAttribute(attributeName = "encryption_salt")
+ private String encryptionSalt;
- /**
- * Converts Status enum to Integer and vice versa.
- */
- public static class StatusEnumConverter implements DynamoDBTypeConverter {
- @Override
- public Integer convert(Status status) {
- return status.getValue();
- }
+ @DynamoDBTypeConverted(converter = StatusEnumConverter.class)
+ @DynamoDBAttribute(attributeName = "status")
+ private Status status;
- @Override
- public Status unconvert(Integer value) {
- return Status.valueOf(value);
- }
- }
+ @DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.CREATE)
+ @DynamoDBAttribute(attributeName = "created_at")
+ private Date createdAt;
+
+ @DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.ALWAYS)
+ @DynamoDBAttribute(attributeName = "updated_at")
+ private Date updatedAt;
+
+ /**
+ * Converts Status enum to Integer and vice versa.
+ */
+ public static class StatusEnumConverter implements DynamoDBTypeConverter {
+
+ @Override
+ public Integer convert(Status status) {
+ return status.getValue();
+ }
+
+ @Override
+ public Status unconvert(Integer value) {
+ return Status.valueOf(value);
+ }
+
+ }
+
+ public String getId(String externalUserId) {
+ return UserConstants.SALESFORCE_USER_KIND + "-" + externalUserId;
+ }
- public String getId(String externalUserId) {
- return UserConstants.SALESFORCE_USER_KIND + "-" + externalUserId;
- }
}
\ No newline at end of file
diff --git a/src/main/java/com/salessparrow/api/domain/User.java b/src/main/java/com/salessparrow/api/domain/User.java
index cfcfa90c..a141ea4d 100644
--- a/src/main/java/com/salessparrow/api/domain/User.java
+++ b/src/main/java/com/salessparrow/api/domain/User.java
@@ -5,16 +5,16 @@
*/
public interface User {
- String getExternalUserId();
+ String getExternalUserId();
- String getEmail();
+ String getEmail();
- String getName();
+ String getName();
- String getUserKind();
+ String getUserKind();
- String getCookieToken();
+ String getCookieToken();
- String getEncryptionSalt();
+ String getEncryptionSalt();
}
diff --git a/src/main/java/com/salessparrow/api/dto/entities/AccountContactAssociationsEntity.java b/src/main/java/com/salessparrow/api/dto/entities/AccountContactAssociationsEntity.java
new file mode 100644
index 00000000..5c4219b1
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/entities/AccountContactAssociationsEntity.java
@@ -0,0 +1,16 @@
+package com.salessparrow.api.dto.entities;
+
+import java.util.List;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+
+import lombok.Data;
+
+@Data
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class AccountContactAssociationsEntity {
+
+ private List contactIds;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/entities/AccountEntity.java b/src/main/java/com/salessparrow/api/dto/entities/AccountEntity.java
index 49b615f9..ae03764d 100644
--- a/src/main/java/com/salessparrow/api/dto/entities/AccountEntity.java
+++ b/src/main/java/com/salessparrow/api/dto/entities/AccountEntity.java
@@ -1,9 +1,22 @@
package com.salessparrow.api.dto.entities;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+
import lombok.Data;
@Data
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class AccountEntity {
- private String id;
- private String name;
+
+ private String id;
+
+ private String name;
+
+ private Map additionalFields;
+
+ private String accountContactAssociationsId;
+
}
\ No newline at end of file
diff --git a/src/main/java/com/salessparrow/api/dto/entities/AddTaskSuggestionEntityDto.java b/src/main/java/com/salessparrow/api/dto/entities/AddTaskSuggestionEntityDto.java
new file mode 100644
index 00000000..6f631232
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/entities/AddTaskSuggestionEntityDto.java
@@ -0,0 +1,19 @@
+package com.salessparrow.api.dto.entities;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+
+import lombok.Data;
+
+/**
+ * Add Task Suggestion Entity is a DTO class for the Add Task Suggestion Entity.
+ */
+@Data
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class AddTaskSuggestionEntityDto {
+
+ private String description;
+
+ private String dueDate;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/entities/ContactEntity.java b/src/main/java/com/salessparrow/api/dto/entities/ContactEntity.java
new file mode 100644
index 00000000..cbd0e200
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/entities/ContactEntity.java
@@ -0,0 +1,20 @@
+package com.salessparrow.api.dto.entities;
+
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+
+import lombok.Data;
+
+@Data
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class ContactEntity {
+
+ private String id;
+
+ private String name;
+
+ private Map additionalFields;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/entities/CrmOrganizationUserEntity.java b/src/main/java/com/salessparrow/api/dto/entities/CrmOrganizationUserEntity.java
new file mode 100644
index 00000000..bb2d65b9
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/entities/CrmOrganizationUserEntity.java
@@ -0,0 +1,12 @@
+package com.salessparrow.api.dto.entities;
+
+import lombok.Data;
+
+@Data
+public class CrmOrganizationUserEntity {
+
+ private String id;
+
+ private String name;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/entities/CurrentUserEntityDto.java b/src/main/java/com/salessparrow/api/dto/entities/CurrentUserEntityDto.java
index a7a5aedb..77412bd5 100644
--- a/src/main/java/com/salessparrow/api/dto/entities/CurrentUserEntityDto.java
+++ b/src/main/java/com/salessparrow/api/dto/entities/CurrentUserEntityDto.java
@@ -2,39 +2,40 @@
/**
* Salesforce connect formatter DTO.
- *
+ *
* @param current_user
- *
* @return SalesforceConnectFormatterDto
*/
public class CurrentUserEntityDto {
- private String id;
- private String name;
- private String email;
+ private String id;
- public String getId() {
- return id;
- }
+ private String name;
- public void setId(String id) {
- this.id = id;
- }
+ private String email;
- public String getName() {
- return name;
- }
+ public String getId() {
+ return id;
+ }
- public void setName(String name) {
- this.name = name;
- }
+ public void setId(String id) {
+ this.id = id;
+ }
- public String getEmail() {
- return email;
- }
+ public String getName() {
+ return name;
+ }
- public void setEmail(String email) {
- this.email = email;
- }
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
}
diff --git a/src/main/java/com/salessparrow/api/dto/entities/NextPagePayloadEntity.java b/src/main/java/com/salessparrow/api/dto/entities/NextPagePayloadEntity.java
new file mode 100644
index 00000000..12636819
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/entities/NextPagePayloadEntity.java
@@ -0,0 +1,14 @@
+package com.salessparrow.api.dto.entities;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+
+import lombok.Data;
+
+@Data
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class NextPagePayloadEntity {
+
+ private String paginationIdentifier;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/entities/NoteDetailEntity.java b/src/main/java/com/salessparrow/api/dto/entities/NoteDetailEntity.java
index 34794e18..bc327da1 100644
--- a/src/main/java/com/salessparrow/api/dto/entities/NoteDetailEntity.java
+++ b/src/main/java/com/salessparrow/api/dto/entities/NoteDetailEntity.java
@@ -13,18 +13,23 @@
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class NoteDetailEntity {
- private String id;
- private String creator;
- private String text;
- private Date lastModifiedTime;
-
- public NoteDetailEntity(){
- }
-
- public NoteDetailEntity(String id, String creator, String text, Date lastModifiedTime){
- this.id = id;
- this.creator = creator;
- this.text = text;
- this.lastModifiedTime = lastModifiedTime;
- }
+
+ private String id;
+
+ private String creator;
+
+ private String text;
+
+ private Date lastModifiedTime;
+
+ public NoteDetailEntity() {
+ }
+
+ public NoteDetailEntity(String id, String creator, String text, Date lastModifiedTime) {
+ this.id = id;
+ this.creator = creator;
+ this.text = text;
+ this.lastModifiedTime = lastModifiedTime;
+ }
+
}
diff --git a/src/main/java/com/salessparrow/api/dto/entities/NoteEntity.java b/src/main/java/com/salessparrow/api/dto/entities/NoteEntity.java
index 77897761..747cd761 100644
--- a/src/main/java/com/salessparrow/api/dto/entities/NoteEntity.java
+++ b/src/main/java/com/salessparrow/api/dto/entities/NoteEntity.java
@@ -13,19 +13,23 @@
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class NoteEntity {
- private String id;
- private String creator;
- private String textPreview;
- private Date lastModifiedTime;
-
- public NoteEntity() {
- }
-
- public NoteEntity(String id, String creator, String text_preview, Date last_modified_time) {
- this.id = id;
- this.creator = creator;
- this.textPreview = text_preview;
- this.lastModifiedTime = last_modified_time;
- }
+
+ private String id;
+
+ private String creator;
+
+ private String textPreview;
+
+ private Date lastModifiedTime;
+
+ public NoteEntity() {
+ }
+
+ public NoteEntity(String id, String creator, String text_preview, Date last_modified_time) {
+ this.id = id;
+ this.creator = creator;
+ this.textPreview = text_preview;
+ this.lastModifiedTime = last_modified_time;
+ }
}
diff --git a/src/main/java/com/salessparrow/api/dto/entities/TaskEntity.java b/src/main/java/com/salessparrow/api/dto/entities/TaskEntity.java
new file mode 100644
index 00000000..ba1a199e
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/entities/TaskEntity.java
@@ -0,0 +1,29 @@
+package com.salessparrow.api.dto.entities;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+
+import lombok.Data;
+
+/**
+ * TaskEntity is a DTO class for the Task List.
+ */
+@Data
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class TaskEntity {
+
+ private String id;
+
+ private String creatorName;
+
+ private String description;
+
+ private String dueDate;
+
+ private String crmOrganizationUserName;
+
+ private Date lastModifiedTime;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/formatter/CreateNoteFormatterDto.java b/src/main/java/com/salessparrow/api/dto/formatter/CreateNoteFormatterDto.java
index 1cfc1cd4..7faa1ebd 100644
--- a/src/main/java/com/salessparrow/api/dto/formatter/CreateNoteFormatterDto.java
+++ b/src/main/java/com/salessparrow/api/dto/formatter/CreateNoteFormatterDto.java
@@ -11,5 +11,7 @@
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class CreateNoteFormatterDto {
- private String noteId;
+
+ private String noteId;
+
}
\ No newline at end of file
diff --git a/src/main/java/com/salessparrow/api/dto/formatter/CreateTaskFormatterDto.java b/src/main/java/com/salessparrow/api/dto/formatter/CreateTaskFormatterDto.java
new file mode 100644
index 00000000..2dabdab6
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/formatter/CreateTaskFormatterDto.java
@@ -0,0 +1,14 @@
+package com.salessparrow.api.dto.formatter;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+
+import lombok.Data;
+
+@Data
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class CreateTaskFormatterDto {
+
+ private String taskId;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/formatter/CrmActionSuggestionsFormatterDto.java b/src/main/java/com/salessparrow/api/dto/formatter/CrmActionSuggestionsFormatterDto.java
new file mode 100644
index 00000000..36d39ad7
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/formatter/CrmActionSuggestionsFormatterDto.java
@@ -0,0 +1,21 @@
+package com.salessparrow.api.dto.formatter;
+
+import java.util.List;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import com.salessparrow.api.dto.entities.AddTaskSuggestionEntityDto;
+
+import lombok.Data;
+
+/**
+ * CrmActionSuggestionsFormatterDto is a class for the formatter of the crm action
+ * suggestions.
+ */
+@Data
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class CrmActionSuggestionsFormatterDto {
+
+ private List addTaskSuggestions;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/formatter/GetAccountsFormatterDto.java b/src/main/java/com/salessparrow/api/dto/formatter/GetAccountsFormatterDto.java
index 7a0db924..9ccecd4c 100644
--- a/src/main/java/com/salessparrow/api/dto/formatter/GetAccountsFormatterDto.java
+++ b/src/main/java/com/salessparrow/api/dto/formatter/GetAccountsFormatterDto.java
@@ -7,11 +7,20 @@
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import com.salessparrow.api.dto.entities.AccountContactAssociationsEntity;
import com.salessparrow.api.dto.entities.AccountEntity;
+import com.salessparrow.api.dto.entities.ContactEntity;
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class GetAccountsFormatterDto {
- private List accountIds;
- private Map accountMapById;
+
+ private List accountIds;
+
+ private Map accountMapById;
+
+ private Map contactMapById;
+
+ private Map accountContactAssociationsMapById;
+
}
\ No newline at end of file
diff --git a/src/main/java/com/salessparrow/api/dto/formatter/GetCrmOrganizationUsersFormatterDto.java b/src/main/java/com/salessparrow/api/dto/formatter/GetCrmOrganizationUsersFormatterDto.java
new file mode 100644
index 00000000..2f5f9841
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/formatter/GetCrmOrganizationUsersFormatterDto.java
@@ -0,0 +1,20 @@
+package com.salessparrow.api.dto.formatter;
+
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import com.salessparrow.api.dto.entities.CrmOrganizationUserEntity;
+
+import lombok.Data;
+
+@Data
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class GetCrmOrganizationUsersFormatterDto {
+
+ private List crmOrganizationUserIds;
+
+ private Map crmOrganizationUserMapById;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/formatter/GetCurrentUserFormatterDto.java b/src/main/java/com/salessparrow/api/dto/formatter/GetCurrentUserFormatterDto.java
index bf422cfe..b135be02 100644
--- a/src/main/java/com/salessparrow/api/dto/formatter/GetCurrentUserFormatterDto.java
+++ b/src/main/java/com/salessparrow/api/dto/formatter/GetCurrentUserFormatterDto.java
@@ -8,13 +8,14 @@
/**
* Get current user formatter DTO.
- *
+ *
* @param current_user
- *
* @return GetCurrentUserFormatterDto
*/
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class GetCurrentUserFormatterDto {
- private CurrentUserEntityDto currentUser;
+
+ private CurrentUserEntityDto currentUser;
+
}
\ No newline at end of file
diff --git a/src/main/java/com/salessparrow/api/dto/formatter/GetNoteDetailsFormatterDto.java b/src/main/java/com/salessparrow/api/dto/formatter/GetNoteDetailsFormatterDto.java
index 92425e03..3424b6ae 100644
--- a/src/main/java/com/salessparrow/api/dto/formatter/GetNoteDetailsFormatterDto.java
+++ b/src/main/java/com/salessparrow/api/dto/formatter/GetNoteDetailsFormatterDto.java
@@ -10,9 +10,10 @@
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class GetNoteDetailsFormatterDto {
- private NoteDetailEntity noteDetail;
-
- public GetNoteDetailsFormatterDto(NoteDetailEntity noteDetail){
- this.noteDetail = noteDetail;
- }
+ private NoteDetailEntity noteDetail;
+
+ public GetNoteDetailsFormatterDto(NoteDetailEntity noteDetail) {
+ this.noteDetail = noteDetail;
+ }
+
}
diff --git a/src/main/java/com/salessparrow/api/dto/formatter/GetNotesListFormatterDto.java b/src/main/java/com/salessparrow/api/dto/formatter/GetNotesListFormatterDto.java
index e9390d75..884f1cd0 100644
--- a/src/main/java/com/salessparrow/api/dto/formatter/GetNotesListFormatterDto.java
+++ b/src/main/java/com/salessparrow/api/dto/formatter/GetNotesListFormatterDto.java
@@ -15,14 +15,17 @@
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class GetNotesListFormatterDto {
- private List noteIds;
- private Map noteMapById;
- public GetNotesListFormatterDto(){
- }
+ private List noteIds;
+
+ private Map noteMapById;
+
+ public GetNotesListFormatterDto() {
+ }
+
+ public GetNotesListFormatterDto(List noteIds, Map noteMapById) {
+ this.noteIds = noteIds;
+ this.noteMapById = noteMapById;
+ }
- public GetNotesListFormatterDto(List noteIds, Map noteMapById){
- this.noteIds = noteIds;
- this.noteMapById = noteMapById;
- }
}
diff --git a/src/main/java/com/salessparrow/api/dto/formatter/GetTasksListFormatterDto.java b/src/main/java/com/salessparrow/api/dto/formatter/GetTasksListFormatterDto.java
new file mode 100644
index 00000000..51e100e5
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/formatter/GetTasksListFormatterDto.java
@@ -0,0 +1,23 @@
+package com.salessparrow.api.dto.formatter;
+
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import com.salessparrow.api.dto.entities.TaskEntity;
+
+import lombok.Data;
+
+/**
+ * GetTasksListFormatterDto is a DTO class for the GetTasksListFormatterDto response.
+ */
+@Data
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class GetTasksListFormatterDto {
+
+ private List taskIds;
+
+ private Map taskMapById;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/formatter/PaginationIdentifierFormatterDto.java b/src/main/java/com/salessparrow/api/dto/formatter/PaginationIdentifierFormatterDto.java
new file mode 100644
index 00000000..06728a94
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/formatter/PaginationIdentifierFormatterDto.java
@@ -0,0 +1,10 @@
+package com.salessparrow.api.dto.formatter;
+
+import lombok.Data;
+
+@Data
+public class PaginationIdentifierFormatterDto {
+
+ private Integer pageNumber;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/formatter/RedirectUrlFormatterDto.java b/src/main/java/com/salessparrow/api/dto/formatter/RedirectUrlFormatterDto.java
index 42e7c4e7..f2b1db26 100644
--- a/src/main/java/com/salessparrow/api/dto/formatter/RedirectUrlFormatterDto.java
+++ b/src/main/java/com/salessparrow/api/dto/formatter/RedirectUrlFormatterDto.java
@@ -7,13 +7,14 @@
/**
* Redirect url formatter DTO.
- *
+ *
* @param url
- *
* @return RedirectUrlFormatterDto
*/
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class RedirectUrlFormatterDto {
- private String url;
+
+ private String url;
+
}
diff --git a/src/main/java/com/salessparrow/api/dto/formatter/SalesforceConnectFormatterDto.java b/src/main/java/com/salessparrow/api/dto/formatter/SalesforceConnectFormatterDto.java
index bfdfb918..e25bf0a9 100644
--- a/src/main/java/com/salessparrow/api/dto/formatter/SalesforceConnectFormatterDto.java
+++ b/src/main/java/com/salessparrow/api/dto/formatter/SalesforceConnectFormatterDto.java
@@ -8,17 +8,17 @@
/**
* Salesforce connect formatter DTO.
- *
+ *
* @param current_user
- *
* @return SalesforceConnectFormatterDto
*/
@Data
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class SalesforceConnectFormatterDto {
- public SalesforceConnectFormatterDto() {
- }
- private CurrentUserEntityDto currentUser;
+ public SalesforceConnectFormatterDto() {
+ }
+
+ private CurrentUserEntityDto currentUser;
}
diff --git a/src/main/java/com/salessparrow/api/dto/requestMapper/CreateAccountTaskDto.java b/src/main/java/com/salessparrow/api/dto/requestMapper/CreateAccountTaskDto.java
new file mode 100644
index 00000000..dc432867
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/requestMapper/CreateAccountTaskDto.java
@@ -0,0 +1,25 @@
+package com.salessparrow.api.dto.requestMapper;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import com.salessparrow.api.lib.customAnnotations.ValidDateFormat;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+
+@Data
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class CreateAccountTaskDto {
+
+ @NotBlank(message = "missing_crm_organization_user_id")
+ private String crmOrganizationUserId;
+
+ @NotBlank(message = "missing_description")
+ @Size(max = 32000, message = "description_too_long")
+ private String description;
+
+ @ValidDateFormat(message = "invalid_due_date")
+ private String dueDate;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/requestMapper/CrmActionsSuggestionsDto.java b/src/main/java/com/salessparrow/api/dto/requestMapper/CrmActionsSuggestionsDto.java
new file mode 100644
index 00000000..a38fab64
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/requestMapper/CrmActionsSuggestionsDto.java
@@ -0,0 +1,18 @@
+package com.salessparrow.api.dto.requestMapper;
+
+import org.hibernate.validator.constraints.Length;
+
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+/**
+ * CrmActionsSuggestionsDto is a dto class for the crm actions suggestions.
+ */
+@Data
+public class CrmActionsSuggestionsDto {
+
+ @NotBlank(message = "missing_text")
+ @Length(max = 12000, message = "text_too_long")
+ private String text;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/requestMapper/GetAccountsDto.java b/src/main/java/com/salessparrow/api/dto/requestMapper/GetAccountsDto.java
index 573faf67..a9c434d3 100644
--- a/src/main/java/com/salessparrow/api/dto/requestMapper/GetAccountsDto.java
+++ b/src/main/java/com/salessparrow/api/dto/requestMapper/GetAccountsDto.java
@@ -5,6 +5,8 @@
@Data
public class GetAccountsDto {
- @Size(max = 200, message = "search_term_too_long")
- private String q;
+
+ @Size(max = 200, message = "search_term_too_long")
+ private String q;
+
}
diff --git a/src/main/java/com/salessparrow/api/dto/requestMapper/GetAccountsFeedDto.java b/src/main/java/com/salessparrow/api/dto/requestMapper/GetAccountsFeedDto.java
new file mode 100644
index 00000000..bec24967
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/requestMapper/GetAccountsFeedDto.java
@@ -0,0 +1,16 @@
+package com.salessparrow.api.dto.requestMapper;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies.LowerCamelCaseStrategy;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+
+import jakarta.validation.constraints.Pattern;
+import lombok.Data;
+
+@Data
+@JsonNaming(LowerCamelCaseStrategy.class)
+public class GetAccountsFeedDto {
+
+ @Pattern(regexp = "^[A-Za-z0-9+/]*={0,2}$", message = "invalid_pagination_identifier")
+ private String pagination_identifier;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/requestMapper/GetCrmOrganizationUsersDto.java b/src/main/java/com/salessparrow/api/dto/requestMapper/GetCrmOrganizationUsersDto.java
new file mode 100644
index 00000000..7d3ee84e
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/requestMapper/GetCrmOrganizationUsersDto.java
@@ -0,0 +1,12 @@
+package com.salessparrow.api.dto.requestMapper;
+
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+
+@Data
+public class GetCrmOrganizationUsersDto {
+
+ @Size(max = 200, message = "search_term_too_long")
+ private String q;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/requestMapper/NoteDto.java b/src/main/java/com/salessparrow/api/dto/requestMapper/NoteDto.java
index e2a3646c..44ca28f6 100644
--- a/src/main/java/com/salessparrow/api/dto/requestMapper/NoteDto.java
+++ b/src/main/java/com/salessparrow/api/dto/requestMapper/NoteDto.java
@@ -1,13 +1,15 @@
package com.salessparrow.api.dto.requestMapper;
+import org.hibernate.validator.constraints.Length;
+
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class NoteDto {
- @NotBlank(message = "missing_text")
- private String text;
-}
-
+ @NotBlank(message = "missing_text")
+ @Length(max = 12000, message = "text_too_long")
+ private String text;
+}
diff --git a/src/main/java/com/salessparrow/api/dto/requestMapper/SalesforceConnectDto.java b/src/main/java/com/salessparrow/api/dto/requestMapper/SalesforceConnectDto.java
index 5b5dec38..efc21d0f 100644
--- a/src/main/java/com/salessparrow/api/dto/requestMapper/SalesforceConnectDto.java
+++ b/src/main/java/com/salessparrow/api/dto/requestMapper/SalesforceConnectDto.java
@@ -6,40 +6,39 @@
/**
* Salesforce connect DTO.
- *
+ *
* @param code
* @param redirect_uri
- *
* @return SalesforceConnectDto
*/
public class SalesforceConnectDto {
- @NotBlank(message = "missing_code")
- private String code;
+ @NotBlank(message = "missing_code")
+ private String code;
- @NotBlank(message = "missing_redirect_uri")
- @ValidRedirectUri(message = "invalid_redirect_uri")
- private String redirect_uri;
+ @NotBlank(message = "missing_redirect_uri")
+ @ValidRedirectUri(message = "invalid_redirect_uri")
+ private String redirect_uri;
- public String getCode() {
- return code;
- }
+ public String getCode() {
+ return code;
+ }
- public void setCode(String code) {
- this.code = code;
- }
+ public void setCode(String code) {
+ this.code = code;
+ }
- public String getRedirect_uri() {
- return redirect_uri;
- }
+ public String getRedirect_uri() {
+ return redirect_uri;
+ }
- public void setRedirect_uri(String redirect_uri) {
- this.redirect_uri = redirect_uri;
- }
+ public void setRedirect_uri(String redirect_uri) {
+ this.redirect_uri = redirect_uri;
+ }
- @Override
- public String toString() {
- return "SalesforceConnectDto [code=" + code + ", redirect_uri=" + redirect_uri + "]";
- }
+ @Override
+ public String toString() {
+ return "SalesforceConnectDto [code=" + code + ", redirect_uri=" + redirect_uri + "]";
+ }
}
diff --git a/src/main/java/com/salessparrow/api/dto/requestMapper/SalesforceRedirectUrlDto.java b/src/main/java/com/salessparrow/api/dto/requestMapper/SalesforceRedirectUrlDto.java
index 8ddf1824..670e6890 100644
--- a/src/main/java/com/salessparrow/api/dto/requestMapper/SalesforceRedirectUrlDto.java
+++ b/src/main/java/com/salessparrow/api/dto/requestMapper/SalesforceRedirectUrlDto.java
@@ -7,18 +7,18 @@
/**
* Redirect url DTO.
- *
+ *
* @param redirect_uri
* @param state
- *
* @return SalesforceRedirectUrlDto
*/
@Data
public class SalesforceRedirectUrlDto {
- @NotBlank(message = "missing_redirect_uri")
- @ValidRedirectUri(message = "invalid_redirect_uri")
- private String redirect_uri;
+ @NotBlank(message = "missing_redirect_uri")
+ @ValidRedirectUri(message = "invalid_redirect_uri")
+ private String redirect_uri;
+
+ private String state;
- private String state;
}
diff --git a/src/main/java/com/salessparrow/api/dto/responseMapper/GetAccountListResponseDto.java b/src/main/java/com/salessparrow/api/dto/responseMapper/GetAccountListResponseDto.java
new file mode 100644
index 00000000..3c4b4c16
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/responseMapper/GetAccountListResponseDto.java
@@ -0,0 +1,20 @@
+package com.salessparrow.api.dto.responseMapper;
+
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import com.salessparrow.api.dto.entities.AccountEntity;
+
+import lombok.Data;
+
+@Data
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class GetAccountListResponseDto {
+
+ private List accountIds;
+
+ private Map accountMapById;
+
+}
diff --git a/src/main/java/com/salessparrow/api/dto/responseMapper/GetAccountsFeedResponseDto.java b/src/main/java/com/salessparrow/api/dto/responseMapper/GetAccountsFeedResponseDto.java
new file mode 100644
index 00000000..b3868931
--- /dev/null
+++ b/src/main/java/com/salessparrow/api/dto/responseMapper/GetAccountsFeedResponseDto.java
@@ -0,0 +1,29 @@
+package com.salessparrow.api.dto.responseMapper;
+
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.databind.annotation.JsonNaming;
+import com.salessparrow.api.dto.entities.AccountContactAssociationsEntity;
+import com.salessparrow.api.dto.entities.AccountEntity;
+import com.salessparrow.api.dto.entities.ContactEntity;
+import com.salessparrow.api.dto.entities.NextPagePayloadEntity;
+
+import lombok.Data;
+
+@Data
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
+public class GetAccountsFeedResponseDto {
+
+ private List accountIds;
+
+ private Map accountMapById;
+
+ private Map contactMapById;
+
+ private Map accountContactAssociationsMapById;
+
+ private NextPagePayloadEntity nextPagePayload;
+
+}
diff --git a/src/main/java/com/salessparrow/api/exception/CustomException.java b/src/main/java/com/salessparrow/api/exception/CustomException.java
index 928c5bdb..4ddcd91b 100644
--- a/src/main/java/com/salessparrow/api/exception/CustomException.java
+++ b/src/main/java/com/salessparrow/api/exception/CustomException.java
@@ -4,22 +4,25 @@
import com.salessparrow.api.lib.errorLib.ParamErrorObject;
public class CustomException extends RuntimeException {
- private ErrorObject errorObject;
- private ParamErrorObject paramErrorObject;
- public CustomException(ErrorObject errorObject) {
- this.errorObject = errorObject;
- }
+ private ErrorObject errorObject;
- public CustomException(ParamErrorObject paramErrorObject) {
- this.paramErrorObject = paramErrorObject;
- }
+ private ParamErrorObject paramErrorObject;
- public ParamErrorObject getParamErrorObject() {
- return paramErrorObject;
- }
+ public CustomException(ErrorObject errorObject) {
+ this.errorObject = errorObject;
+ }
+
+ public CustomException(ParamErrorObject paramErrorObject) {
+ this.paramErrorObject = paramErrorObject;
+ }
+
+ public ParamErrorObject getParamErrorObject() {
+ return paramErrorObject;
+ }
+
+ public ErrorObject getErrorObject() {
+ return errorObject;
+ }
- public ErrorObject getErrorObject() {
- return errorObject;
- }
}
\ No newline at end of file
diff --git a/src/main/java/com/salessparrow/api/exception/ErrorResponse.java b/src/main/java/com/salessparrow/api/exception/ErrorResponse.java
index f69d0ba8..b31be450 100644
--- a/src/main/java/com/salessparrow/api/exception/ErrorResponse.java
+++ b/src/main/java/com/salessparrow/api/exception/ErrorResponse.java
@@ -21,105 +21,97 @@
@Component
public class ErrorResponse {
- @Autowired
- private ResourceLoader resourceLoader;
-
- /**
- * Get error response
- *
- * @param apiIdentifier
- * @param internalErrorIdentifier
- *
- * @return ErrorResponseObject
- */
- protected ErrorResponseObject getErrorResponse(String apiIdentifier, String internalErrorIdentifier, String message) {
-
- String errorConfigPath = "classpath:config/ApiErrorConfig.json";
- Resource resource = resourceLoader.getResource(errorConfigPath);
- ObjectMapper objectMapper = new ObjectMapper();
- Map errorDataMap = new HashMap<>();
- try {
- errorDataMap = objectMapper.readValue(resource.getInputStream(),
- new TypeReference>() {
- });
- } catch (Exception e) {
- e.printStackTrace();
- throw new RuntimeException("Error while reading error config file:" + e.getMessage());
- }
-
- ErrorConfig errorInfo = errorDataMap.get(apiIdentifier);
-
- if (errorInfo == null) {
- errorInfo = errorDataMap.get("something_went_wrong");
- }
-
-
- ErrorResponseObject errorResponseObject = new ErrorResponseObject(
- Integer.parseInt(errorInfo.getHttpCode()),
- errorInfo.getMessage(),
- errorInfo.getCode(),
- internalErrorIdentifier,
- new ArrayList());
-
- return errorResponseObject;
- }
-
- /**
- * Get error response
- *
- * @param internalErrorIdentifier
- * @param message
- * @param paramErrorIdentifiers
- *
- * @return ErrorResponseObject
- */
- protected ErrorResponseObject getParamErrorResponse(String internalErrorIdentifier, String message,
- List paramErrorIdentifiers) {
-
- String paramsErrorPath = "classpath:config/ParamErrorConfig.json";
- Resource resource = resourceLoader.getResource(paramsErrorPath);
- ObjectMapper objectMapper = new ObjectMapper();
- Map paramErrorDataMap = new HashMap<>();
- try {
- paramErrorDataMap = objectMapper.readValue(resource.getInputStream(),
- new TypeReference>() {
- });
- } catch (Exception e) {
- e.printStackTrace();
- throw new RuntimeException("Error while reading param error config file:" + e.getMessage());
- }
-
- List paramErrorConfigList = new ArrayList();
-
- for (String paramErrorIdentifier : paramErrorIdentifiers) {
- ParamErrorConfig paramErrorConfig = null;
-
- Pattern pattern = Pattern.compile("^missing_(.*)$");
- Matcher matcher = pattern.matcher(paramErrorIdentifier);
-
- if (matcher.matches()) {
- String paramName = matcher.group(1);
- String messageString = paramName + " is required parameter. Please provide " + paramName + ".";
-
- paramErrorConfig = new ParamErrorConfig(paramName, paramErrorIdentifier, messageString);
- paramErrorConfigList.add(paramErrorConfig);
- }
- else {
- paramErrorConfig = paramErrorDataMap.get(paramErrorIdentifier);
- if (paramErrorConfig != null) {
- paramErrorConfigList.add(paramErrorConfig);
- }
- }
- }
-
- ErrorResponseObject errorResponseObject = new ErrorResponseObject(
- 400,
- "At least one parameter is invalid or missing.",
- "INVALID_PARAMS",
- internalErrorIdentifier,
- paramErrorConfigList);
-
- return errorResponseObject;
- }
+ @Autowired
+ private ResourceLoader resourceLoader;
+
+ /**
+ * Get error response
+ * @param apiIdentifier
+ * @param internalErrorIdentifier
+ * @return ErrorResponseObject
+ */
+ protected ErrorResponseObject getErrorResponse(String apiIdentifier, String internalErrorIdentifier,
+ String message) {
+
+ String errorConfigPath = "classpath:config/ApiErrorConfig.json";
+ Resource resource = resourceLoader.getResource(errorConfigPath);
+ ObjectMapper objectMapper = new ObjectMapper();
+ Map errorDataMap = new HashMap<>();
+ try {
+ errorDataMap = objectMapper.readValue(resource.getInputStream(),
+ new TypeReference>() {
+ });
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException("Error while reading error config file:" + e.getMessage());
+ }
+
+ ErrorConfig errorInfo = errorDataMap.get(apiIdentifier);
+
+ if (errorInfo == null) {
+ errorInfo = errorDataMap.get("something_went_wrong");
+ }
+
+ ErrorResponseObject errorResponseObject = new ErrorResponseObject(Integer.parseInt(errorInfo.getHttpCode()),
+ errorInfo.getMessage(), errorInfo.getCode(), internalErrorIdentifier,
+ new ArrayList());
+
+ return errorResponseObject;
+ }
+
+ /**
+ * Get error response
+ * @param internalErrorIdentifier
+ * @param message
+ * @param paramErrorIdentifiers
+ * @return ErrorResponseObject
+ */
+ protected ErrorResponseObject getParamErrorResponse(String internalErrorIdentifier, String message,
+ List paramErrorIdentifiers) {
+
+ String paramsErrorPath = "classpath:config/ParamErrorConfig.json";
+ Resource resource = resourceLoader.getResource(paramsErrorPath);
+ ObjectMapper objectMapper = new ObjectMapper();
+ Map paramErrorDataMap = new HashMap<>();
+ try {
+ paramErrorDataMap = objectMapper.readValue(resource.getInputStream(),
+ new TypeReference>() {
+ });
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException("Error while reading param error config file:" + e.getMessage());
+ }
+
+ List paramErrorConfigList = new ArrayList();
+
+ for (String paramErrorIdentifier : paramErrorIdentifiers) {
+ ParamErrorConfig paramErrorConfig = null;
+
+ Pattern pattern = Pattern.compile("^missing_(.*)$");
+ Matcher matcher = pattern.matcher(paramErrorIdentifier);
+
+ if (matcher.matches()) {
+ String paramName = matcher.group(1);
+ String messageString = paramName + " is required parameter. Please provide " + paramName + ".";
+
+ paramErrorConfig = new ParamErrorConfig(paramName, paramErrorIdentifier, messageString);
+ paramErrorConfigList.add(paramErrorConfig);
+ }
+ else {
+ paramErrorConfig = paramErrorDataMap.get(paramErrorIdentifier);
+ if (paramErrorConfig != null) {
+ paramErrorConfigList.add(paramErrorConfig);
+ }
+ }
+ }
+
+ ErrorResponseObject errorResponseObject = new ErrorResponseObject(400,
+ "At least one parameter is invalid or missing.", "INVALID_PARAMS", internalErrorIdentifier,
+ paramErrorConfigList);
+
+ return errorResponseObject;
+ }
}
diff --git a/src/main/java/com/salessparrow/api/exception/GlobalExceptionHandler.java b/src/main/java/com/salessparrow/api/exception/GlobalExceptionHandler.java
index 9b87e84c..fe628eee 100644
--- a/src/main/java/com/salessparrow/api/exception/GlobalExceptionHandler.java
+++ b/src/main/java/com/salessparrow/api/exception/GlobalExceptionHandler.java
@@ -26,130 +26,110 @@
@ControllerAdvice
public class GlobalExceptionHandler {
- private Logger logger = org.slf4j.LoggerFactory.getLogger(GlobalExceptionHandler.class);
-
- @Autowired
- private ErrorResponse er;
-
- @Autowired
- private ErrorEmailService errorEmailService;
-
- @Autowired
- private CookieHelper cookieHelper;
-
- /**
- * Handle 404. Catches the exception for undefined endpoints
- *
- * @param NoHandlerFoundException
- *
- * @return ResponseEntity
- */
- @ExceptionHandler(NoHandlerFoundException.class)
- public ResponseEntity handleNoHandlerFoundException(NoHandlerFoundException ex, HttpServletRequest request) {
- // Logging all headers from the request
- String headerStr = Util.generateHeaderLogString(request);
- logger.info("headerStr: {}", headerStr);
-
- ErrorResponseObject errorResponse = null;
-
- errorResponse = er.getErrorResponse(
- "resource_not_found",
- "a_e_geh_nf_1",
- "handleNoHandlerFoundException");
-
- return ResponseEntity.status(errorResponse.getHttpCode())
- .body(errorResponse);
- }
-
-
- /**
- * Handle custom exception
- *
- * @param ex
- *
- * @return ResponseEntity