Skip to content

Commit

Permalink
Refactor and Add CI Workflow (#17)
Browse files Browse the repository at this point in the history
- Remove hardcoded messages from `LoggingAspect`.
- Switch naming between `SmsService` and `OtpService`.
- Delete `InMemoryVerificationService` since Redis implementation is much better.
- Delete `CollectionConfig` class as it is never used with Redis implementation.
- Upgrade `validateUserToken` method to inform user of "invalid token" error before "expired token" error.
- Give Model and DTO classes a simpler names.
- Add test hook in pre-commit.
- Add CI workflow pipeline.
  • Loading branch information
Ahmad-AlDeeb authored Sep 28, 2024
1 parent ee4f8be commit 1fa23d5
Show file tree
Hide file tree
Showing 26 changed files with 244 additions and 214 deletions.
70 changes: 70 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: CI
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs:
Build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: maven

# Build
- name: Building
run: mvn -B package

Test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: maven

# # Install Docker Compose
# - name: Install Docker Compose
# run: |
# sudo apt-get update
# sudo apt-get install docker-compose -y

# Install Docker
- name: Install Docker
run: |
sudo apt-get update
sudo apt-get install docker.io -y
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER
# Test
- name: Testing
run: mvn test

Code-Quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: nikitasavinov/checkstyle-action@0.6.0
with:
checkstyle_config: config/checkstyle/sun_checks_custom.xml
15 changes: 5 additions & 10 deletions config/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,8 @@ repos:
language: system
types: [ java ]
pass_filenames: false
# - id: dependency-check # Scans the project for vulnerable dependencies.
# name: Dependency Check
# entry: mvn org.owasp:dependency-check-maven:check
# language: system
# pass_filenames: false
# - id: maven-test # Runs unit tests to ensure that your code changes don’t break any existing functionality.
# name: Maven Test
# entry: mvn test
# language: system
# pass_filenames: false
- id: maven-test
name: Maven Test
entry: mvn test
language: system
pass_filenames: false
14 changes: 7 additions & 7 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@
- Twilio Account (along with your verified number).

# ⚡ Running the Project
1. **Clone the repository**:
1. **Clone the repository**:
```bash
git clone https://github.com/ittovate/otp-service.git
```

2. **Navigate to the project directory**:
```bash
cd demo-otp-service
```

3. **Configure environment variables**:
1. Duplicate `src/main/resources/keys.env` file and rename the copy to `.env`.
2. Fill fields with values from your Twilio account and Redis account:
Expand All @@ -44,12 +44,12 @@
- `TWILIO_VERIFIED_NUMBER` is your verified number used in your Twilio account.
- `REDIS_HOST` & `REDIS_PORT` are "Public endpoint" under "General" section (in the database settings).
- `REDIS_PASSWORD` is under "Security" section (in the database settings).
-
4. **Build and run the project**:
-
4. **Build and run the project**:
```bash
mvn clean install spring-boot:run
mvn clean install spring-boot:run
```

5. [**Try it out!**](http://localhost:8080/swagger-ui/index.html)

6. **Stop the project**: After testing, stop both demos by pressing `CTRL + C` in each terminal.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import static com.ittovative.otpservice.constant.AspectConstant.AFTER_RETURN_MESSAGE;
import static com.ittovative.otpservice.constant.AspectConstant.AFTER_THROW_MESSAGE;
import static com.ittovative.otpservice.constant.AspectConstant.BEFORE_MESSAGE;
import static com.ittovative.otpservice.util.AspectUtil.getClassName;
import static com.ittovative.otpservice.util.AspectUtil.getMethodArgs;
import static com.ittovative.otpservice.util.AspectUtil.getMethodName;
Expand All @@ -30,14 +33,14 @@ public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
StringBuilder args = getMethodArgs(joinPoint);
Object returnVal = null;

LOGGER.info("Executing ===> {}.{} with arguments: [{}]", className, methodName, args);
LOGGER.info(BEFORE_MESSAGE, className, methodName, args);
try {
returnVal = joinPoint.proceed();
} catch (Throwable throwable) {
LOGGER.error("Exception {} in ===> {}.{} with arguments: [{}]", throwable, className, methodName, args);
LOGGER.error(AFTER_THROW_MESSAGE, throwable, className, methodName, args);
throw throwable;
}
LOGGER.info("Finished ===> {}.{} with arguments: [{}] and returned {}", className, methodName, args, returnVal);
LOGGER.info(AFTER_RETURN_MESSAGE, className, methodName, args, returnVal);

return returnVal;
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package com.ittovative.otpservice.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

@Configuration
public class RedisConfig {
@Value("${spring.data.redis.port}")
private static int port;

public static int getPort() {
return port;
}

/**
* Redis template.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package com.ittovative.otpservice.config;

import com.ittovative.otpservice.dto.OtpRequestDto;
import com.ittovative.otpservice.dto.VerifyTokenRequestDto;
import com.ittovative.otpservice.dto.TokenDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.validation.Valid;
import org.apache.coyote.BadRequestException;
import org.springframework.http.ResponseEntity;

Expand Down Expand Up @@ -112,5 +111,5 @@ public interface SwaggerConfig {
}
)
ResponseEntity<com.ittovative.otpservice.util.ApiResponse<String>> verify(
VerifyTokenRequestDto verifyTokenRequestDto) throws BadRequestException;
TokenDto tokenDto) throws BadRequestException;
}
12 changes: 6 additions & 6 deletions src/main/java/com/ittovative/otpservice/config/TwilioConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
public class TwilioConfig {
@Value("${twilio.sid}")
private String accountSid;

@Value("${twilio.auth-token}")
private String authToken;

public String getAccountSid() {
return accountSid;
}
@Value("${twilio.verified-number}")
private static String verifiedNumber;

public String getAuthToken() {
return authToken;
public static String getVerifiedNumber() {
return verifiedNumber;
}

/**
* Initialize.
* Initialize Twilio with account SID and auth token.
*/
@PostConstruct
public void initialize() {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package com.ittovative.otpservice.constant;

import static com.ittovative.otpservice.constant.ExceptionConstant.UTILITY_CLASS_INSTANTIATION;

public final class ApiResponseConstant {
public static final String OTP_SENT = "OTP sent successfully!";
public static final String TOKEN_VERIFIED = "Token verified successfully!";
public static final String VALIDATION_ERROR = "Validation error!";
public static final String INVALID_PHONE_NUMBER_FORMAT =
"Invalid phone number format! (only digits, plus-sign and dashes are allowed).";
public static final String INVALID_TOKEN_FORMAT = "Token must be a 6-digit number!";
public static final String INVALID_TOKEN = "Invalid token!";
public static final String TOKEN_EXPIRED = "Token has expired!";

private ApiResponseConstant() {
throw new IllegalStateException(UTILITY_CLASS_INSTANTIATION);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.ittovative.otpservice.constant;

import static com.ittovative.otpservice.constant.ExceptionConstant.UTILITY_CLASS_INSTANTIATION;

public final class AspectConstant {
public static final String BEFORE_MESSAGE = "Executing ===> {}.{} with arguments: [{}]";
public static final String AFTER_RETURN_MESSAGE = "Finished ===> {}.{} with arguments: [{}] and returned {}";
public static final String AFTER_THROW_MESSAGE = "Exception {} in ===> {}.{} with arguments: [{}]";

private AspectConstant() {
throw new IllegalStateException(UTILITY_CLASS_INSTANTIATION);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.ittovative.otpservice.constant;

public final class ExceptionConstant {
public static final String UTILITY_CLASS_INSTANTIATION = "Utility class should not be instantiated!";
public static final String VALIDATION_ERROR = "Validation error!";
public static final String INVALID_PHONE_NUMBER_FORMAT =
"Invalid phone number format! (only digits, plus-sign and dashes are allowed).";
public static final String INVALID_TOKEN_FORMAT = "Token must be a 6-digit number!";
public static final String INVALID_TOKEN = "Invalid token!";
public static final String TOKEN_EXPIRED = "Token has expired!";


private ExceptionConstant() {
throw new IllegalStateException(UTILITY_CLASS_INSTANTIATION);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.ittovative.otpservice.constant;

import static com.ittovative.otpservice.constant.ExceptionConstant.UTILITY_CLASS_INSTANTIATION;

public final class HttpConstant {
public static final String APPLICATION_JSON = "application/json";

Expand All @@ -17,5 +19,6 @@ public final class HttpConstant {
public static final String TOO_MANY_REQUESTS = "429";

private HttpConstant() {
throw new IllegalStateException(UTILITY_CLASS_INSTANTIATION);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

import org.springframework.beans.factory.annotation.Value;

import static com.ittovative.otpservice.constant.ExceptionConstant.UTILITY_CLASS_INSTANTIATION;

public final class RedisConstant {
public static final String VERIFICATION_OTP_HASH = "VerificationOtp";
public static final String VERIFICATION_TOKEN_HASH = "VerificationToken";

@Value("${spring.data.redis.expiry-date}")
public static final Integer EXPIRY_DATE_IN_MIN = 5;

private RedisConstant() {
throw new IllegalStateException(UTILITY_CLASS_INSTANTIATION);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.ittovative.otpservice.constant;

import static com.ittovative.otpservice.constant.ExceptionConstant.UTILITY_CLASS_INSTANTIATION;

public final class SwaggerConstant {
public static final String TITLE = "OTP Service API";
public static final String VERSION = "1.0";
Expand Down Expand Up @@ -84,5 +86,6 @@ public final class SwaggerConstant {
""";

private SwaggerConstant() {
throw new IllegalStateException(UTILITY_CLASS_INSTANTIATION);
}
}
Loading

0 comments on commit 1fa23d5

Please sign in to comment.