From 2de4d672638bfe52cfc3f419f9910c61f1bfda11 Mon Sep 17 00:00:00 2001
From: bintang433 <13521003@std.stei.itb.ac.id>
Date: Fri, 17 Nov 2023 06:56:17 +0700
Subject: [PATCH] feat: Driver, logger

---
 travelution-soap.sql                          |  14 ++
 travelution/config.properties                 |   6 +
 travelution/pom.xml                           |  67 ++++++
 .../main/java/com/example/travelution/DB.java |  27 +++
 .../java/com/example/travelution/Web.java     |  26 +++
 .../travelution/driver/ISubscription.java     |  33 +++
 .../travelution/driver/Subscription.java      | 193 ++++++++++++++++++
 .../com/example/travelution/log/Logger.java   |  82 ++++++++
 .../request/SubscriptionApprovalReq.java      |   2 +-
 .../request/ValidateSubscriptionReq.java      |   2 +-
 .../travelution/response/Response.java        |   3 +
 .../response/SubscriptionApprovalResp.java    |   3 +
 .../response/SubscriptionListResp.java        |   3 +
 .../response/SubscriptionListWrapper.java     |   3 +
 .../response/SubscriptionResp.java            |   3 +
 .../response/ValidateSubscriptionResp.java    |   3 +
 16 files changed, 468 insertions(+), 2 deletions(-)
 create mode 100644 travelution-soap.sql
 create mode 100644 travelution/config.properties
 create mode 100644 travelution/pom.xml
 create mode 100644 travelution/src/main/java/com/example/travelution/DB.java
 create mode 100644 travelution/src/main/java/com/example/travelution/Web.java
 create mode 100644 travelution/src/main/java/com/example/travelution/driver/ISubscription.java
 create mode 100644 travelution/src/main/java/com/example/travelution/driver/Subscription.java
 create mode 100644 travelution/src/main/java/com/example/travelution/log/Logger.java

diff --git a/travelution-soap.sql b/travelution-soap.sql
new file mode 100644
index 0000000..57de2ff
--- /dev/null
+++ b/travelution-soap.sql
@@ -0,0 +1,14 @@
+CREATE TABLE logging (
+    id INT AUTO_INCREMENT PRIMARY KEY,
+    description VARCHAR(256) NOT NULL,
+    IP VARCHAR(16) NOT NULL,
+    endpoint VARCHAR(256) NOT NULL,
+    req_time TIMESTAMP NOT NULL
+);
+
+CREATE TABLE subscription (
+    creator_id INT NOT NULL,
+    subscriber_id INT NOT NULL,
+    status ENUM ('PENDING', 'ACCEPTED', 'REJECTED') NOT NULL DEFAULT 'PENDING',
+    PRIMARY KEY (creator_id, subscriber_id)
+);
\ No newline at end of file
diff --git a/travelution/config.properties b/travelution/config.properties
new file mode 100644
index 0000000..88e93ae
--- /dev/null
+++ b/travelution/config.properties
@@ -0,0 +1,6 @@
+DB_URL="jdbc:mysql://host:port/databaseName"
+DB_USERNAME=
+DB_PASSWORD=
+
+BASE_URL=
+API_KEY=
\ No newline at end of file
diff --git a/travelution/pom.xml b/travelution/pom.xml
new file mode 100644
index 0000000..9bb5f01
--- /dev/null
+++ b/travelution/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>com.example</groupId>
+  <artifactId>travelution</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <name>travelution</name>
+  <packaging>war</packaging>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <maven.compiler.target>1.8</maven.compiler.target>
+    <maven.compiler.source>1.8</maven.compiler.source>
+    <junit.version>5.9.2</junit.version>
+  </properties>
+
+<repositories>
+    <repository>
+        <id>central</id>
+        <url>https://repo.maven.apache.org/maven2</url>
+    </repository>
+</repositories>
+
+  <dependencies>
+<dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+      <version>4.0.1</version>
+      <scope>provided</scope>
+    </dependency><dependency>
+      <groupId>javax.xml.ws</groupId>
+      <artifactId>jaxws-api</artifactId>
+      <version>2.3.1</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.jws</groupId>
+      <artifactId>javax.jws-api</artifactId>
+      <version>1.1</version>
+      <scope>provided</scope>
+    </dependency>
+<dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-api</artifactId>
+      <version>${junit.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-engine</artifactId>
+      <version>${junit.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+    <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>3.3.2</version>
+      </plugin>    </plugins>
+  </build>
+</project>
\ No newline at end of file
diff --git a/travelution/src/main/java/com/example/travelution/DB.java b/travelution/src/main/java/com/example/travelution/DB.java
new file mode 100644
index 0000000..5661bf8
--- /dev/null
+++ b/travelution/src/main/java/com/example/travelution/DB.java
@@ -0,0 +1,27 @@
+package com.example.travelution;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+
+public class DB {
+    private Connection connection;
+
+    public DB() {
+        try {
+            System.out.println("Connecting to MySQL Database");
+            this.connection = DriverManager.getConnection(
+                    System.getProperty("DB_URL"),
+                    System.getProperty("DB_USERNAME"),
+                    System.getProperty("DB_PASSWORD")
+            );
+            System.out.println("Database connected!");
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("Error on connecting to database");
+        }
+    }
+
+    public Connection getConnection() {
+        return this.connection;
+    }
+}
diff --git a/travelution/src/main/java/com/example/travelution/Web.java b/travelution/src/main/java/com/example/travelution/Web.java
new file mode 100644
index 0000000..f7d4d78
--- /dev/null
+++ b/travelution/src/main/java/com/example/travelution/Web.java
@@ -0,0 +1,26 @@
+package com.example.travelution;
+
+import com.example.travelution.driver.Subscription;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.sql.Connection;
+import java.util.Properties;
+
+import javax.xml.ws.Endpoint;
+
+public class Web {
+    public static void main( String[] args ) throws IOException, InterruptedException {
+        Properties properties = new Properties();
+        try (InputStream input = Files.newInputStream(Paths.get("../../../../../../../config.properties"))) {
+            properties.load(input);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        DB db = new DB();
+        Connection db_conn = db.getConnection();
+
+        Endpoint.publish(properties.getProperty("BASE_URL") + "/subscription", new Subscription(db_conn));
+    }
+}
\ No newline at end of file
diff --git a/travelution/src/main/java/com/example/travelution/driver/ISubscription.java b/travelution/src/main/java/com/example/travelution/driver/ISubscription.java
new file mode 100644
index 0000000..0ea8a33
--- /dev/null
+++ b/travelution/src/main/java/com/example/travelution/driver/ISubscription.java
@@ -0,0 +1,33 @@
+package com.example.travelution.driver;
+
+import com.example.travelution.request.*;
+import com.example.travelution.response.*;
+
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+
+@WebService
+@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
+public interface ISubscription {
+    @WebMethod(action = "\"requestSubscription\"")
+    SubscriptionResp requestSubscription(
+            @WebParam(name="request") SubscriptionReq subReq
+    );
+
+    @WebMethod(action = "\"approveOrRejectSubscription\"")
+    SubscriptionApprovalResp approveOrRejectSubscription(
+            @WebParam(name="request") SubscriptionApprovalReq subApprovalReq
+    );
+
+    @WebMethod(action = "\"listRequestSubscription\"")
+    SubscriptionListResp listRequestSubscription(
+            @WebParam(name="request") SubscriptionListReq subListReq
+    );
+
+    @WebMethod(action = "\"validateSubscription\"")
+    ValidateSubscriptionResp validateSubscription(
+            @WebParam(name="request") ValidateSubscriptionReq valSub
+    );
+}
diff --git a/travelution/src/main/java/com/example/travelution/driver/Subscription.java b/travelution/src/main/java/com/example/travelution/driver/Subscription.java
new file mode 100644
index 0000000..f16b142
--- /dev/null
+++ b/travelution/src/main/java/com/example/travelution/driver/Subscription.java
@@ -0,0 +1,193 @@
+package com.example.travelution.driver;
+
+
+import com.example.travelution.log.Logger;
+import com.example.travelution.request.*;
+import com.example.travelution.response.*;
+
+import javax.annotation.Resource;
+import javax.jws.WebService;
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.ws.WebServiceContext;
+import javax.xml.ws.handler.MessageContext;
+
+
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.time.LocalDateTime;
+import java.util.*;
+
+@WebService(endpointInterface = "travelution.driver.ISubscription")
+public class Subscription implements ISubscription{
+    @Resource
+    WebServiceContext wsContext;
+
+    private Connection db_conn;
+    private Logger logger;
+
+    private final Properties properties = new Properties();
+
+    public Subscription() {
+
+    }
+    public Subscription(Connection db_conn) {
+        this.db_conn = db_conn;
+        this.logger = new Logger(db_conn);
+        try (InputStream input = Files.newInputStream(Paths.get("../../../../../../../config.properties"))) {
+            properties.load(input);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public SubscriptionResp requestSubscription(SubscriptionReq reqSub) {
+        LocalDateTime timestamp = LocalDateTime.now();
+        String IPAddress = this.getRequestIPAddress();
+
+        SubscriptionResp resp;
+
+        if (!properties.getProperty("API_KEY").equals(reqSub.API_KEY)) {
+            resp = new SubscriptionResp(false, "Not Authorized", null, null);
+        } else {
+            try {
+                Statement statement = this.db_conn.createStatement();
+                String sql = "INSERT INTO subscription(subscriber_id, status) "
+                        + "VALUES (%d, '%s')";
+                String formattedSql = String.format(sql, reqSub.subscriberId, "PENDING");
+                int count = statement.executeUpdate(formattedSql);
+                if (count == 1) {
+                    resp = new SubscriptionResp(true, "Added new subscription request", reqSub.subscriberId, "PENDING");
+                } else {
+                    resp = new SubscriptionResp(true, "Subscription request failed", reqSub.subscriberId, null);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+                resp = new SubscriptionResp(false, e.getMessage(), null, null);
+            }
+        }
+
+        this.logger.generateLogging(timestamp, IPAddress, reqSub, resp);
+        return resp;
+    }
+
+    @Override
+    public SubscriptionApprovalResp approveOrRejectSubscription(SubscriptionApprovalReq appOrRej) {
+        LocalDateTime timestamp = LocalDateTime.now();
+        String IPAddress = this.getRequestIPAddress();
+
+        SubscriptionApprovalResp resp;
+
+        if (!properties.getProperty("API_KEY").equals(appOrRej.API_KEY)) {
+            resp = new SubscriptionApprovalResp(false, "Not Authorized", null, null);
+        } else {
+            try {
+                Statement statement = this.db_conn.createStatement();
+                String sql =
+                        "UPDATE subscription " +
+                                "SET status = '%s' " +
+                                "WHERE " +
+                                "subscriber_id = %d";
+
+                String appOrRejString = appOrRej.approve ? "ACCEPTED": "REJECTED";
+                String formattedSql = String.format(sql, appOrRejString, appOrRej.subscriberId);
+                int count = statement.executeUpdate(formattedSql);
+                if (count == 1) {
+                    String message = appOrRejString + " subscription successfully";
+                    resp = new SubscriptionApprovalResp(true, message, appOrRej.subscriberId, appOrRejString);
+                } else {
+                    String message = appOrRejString + " subscription failed";
+                    resp = new SubscriptionApprovalResp(false, message, appOrRej.subscriberId, null);
+                }
+
+            } catch (Exception e) {
+                e.printStackTrace();
+                resp = new SubscriptionApprovalResp(false, e.getMessage(), null, null);
+            }
+        }
+
+        this.logger.generateLogging(timestamp, IPAddress, appOrRej, resp);
+        return resp;
+    }
+
+    @Override
+    public SubscriptionListResp listRequestSubscription(SubscriptionListReq listReqSub) {
+        LocalDateTime timestamp = LocalDateTime.now();
+        String IPAddress = this.getRequestIPAddress();
+
+        SubscriptionListResp resp;
+
+        if (!properties.getProperty("API_KEY").equals(listReqSub.API_KEY)) {
+            resp = new SubscriptionListResp(false, "Not Authorized", null);
+        } else {
+            try {
+                Statement statement = this.db_conn.createStatement();
+                String sql = "SELECT * FROM subscription WHERE status = 'PENDING'";
+                ResultSet resultSet = statement.executeQuery(sql);
+                List<Subscriber> listResp = new ArrayList<>();
+                while (resultSet.next()) {
+                    listResp.add(new Subscriber(
+                            resultSet.getInt("subscriber_id"),
+                            resultSet.getString("status")
+                    ));
+                }
+                String message = "Subscription request list fetched successfully";
+                resp = new SubscriptionListResp(true, message, listResp);
+
+            } catch (Exception e) {
+                e.printStackTrace();
+                resp = new SubscriptionListResp(false, e.getMessage(), null);
+            }
+        }
+
+        this.logger.generateLogging(timestamp, IPAddress, listReqSub, resp);
+        return resp;
+    }
+
+    @Override
+    public ValidateSubscriptionResp validateSubscription(ValidateSubscriptionReq valSub) {
+        LocalDateTime timestamp = LocalDateTime.now();
+        String IPAddress = this.getRequestIPAddress();
+
+        ValidateSubscriptionResp resp;
+
+        if (!properties.getProperty("API_KEY").equals(valSub.API_KEY)) {
+            resp = new ValidateSubscriptionResp(false, "Not Authorized", null, null);
+        } else {
+            try {
+                Statement statement = this.db_conn.createStatement();
+                String sql = "SELECT * FROM subscription WHERE subscriber_id = " + valSub.subscriberId;
+                ResultSet resultSet = statement.executeQuery(sql);
+
+                Subscriber subscription = null;
+                if (resultSet.next()) {
+                    subscription = new Subscriber(
+                            resultSet.getInt("subscriber_id"),
+                            resultSet.getString("status")
+                    );
+                }
+                String message = "Subscription validation fetched successfully";
+                boolean subscribed = subscription != null && subscription.status.equals("ACCEPTED");
+
+                resp = new ValidateSubscriptionResp(true, message, valSub.subscriberId, subscribed);
+
+            } catch (Exception e) {
+                e.printStackTrace();
+                resp = new ValidateSubscriptionResp(false, e.getMessage(), null, null);
+            }
+        }
+
+        this.logger.generateLogging(timestamp, IPAddress, valSub, resp);
+        return resp;
+    }
+
+    public String getRequestIPAddress() {
+        MessageContext messageContext = wsContext.getMessageContext();
+        HttpServletRequest httpServletRequest = (HttpServletRequest) messageContext.get(MessageContext.SERVLET_REQUEST);
+        return httpServletRequest.getRemoteAddr();
+    }
+}
diff --git a/travelution/src/main/java/com/example/travelution/log/Logger.java b/travelution/src/main/java/com/example/travelution/log/Logger.java
new file mode 100644
index 0000000..d3322e5
--- /dev/null
+++ b/travelution/src/main/java/com/example/travelution/log/Logger.java
@@ -0,0 +1,82 @@
+package com.example.travelution.log;
+
+import com.example.travelution.request.*;
+import com.example.travelution.response.*;
+
+import java.sql.Connection;
+import java.sql.Statement;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+public class Logger {
+    private Connection db_conn;
+
+    public Logger(Connection db_conn) {
+        this.db_conn = db_conn;
+    }
+
+    public void generateLogging(LocalDateTime timestamp, String IPAddress, Request req, Response resp) {
+        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        StringBuilder descriptionBuilder = new StringBuilder();
+        String endpoint = "";
+
+        if (!resp.success && resp.message.equals("Not Authorized")) {
+            descriptionBuilder.append("request rejected");
+        } else {
+            if (req instanceof SubscriptionReq && resp instanceof SubscriptionResp) {
+                SubscriptionReq reqCasted = (SubscriptionReq) req;
+                descriptionBuilder.append("Request subscription for subscriber_id = " + reqCasted.subscriberId);
+                endpoint = "Subscription Request ";
+
+            } else if (req instanceof SubscriptionListReq && resp instanceof SubscriptionListResp) {
+                descriptionBuilder.append("Request list of all subscription with status \"PENDING\"");
+                endpoint = "Subscription List";
+
+            } else if (req instanceof ValidateSubscriptionReq && resp instanceof ValidateSubscriptionResp) {
+                ValidateSubscriptionReq reqCasted = (ValidateSubscriptionReq) req;
+                ValidateSubscriptionResp respCasted = (ValidateSubscriptionResp) resp;
+                descriptionBuilder.append(
+                        "Request validate subscription for subscriber_id = " + reqCasted.subscriberId
+                                + ", validation result is " + respCasted.subscribed
+                );
+                endpoint = "Validate Subscription";
+
+            } else if (req instanceof SubscriptionApprovalReq && resp instanceof SubscriptionApprovalResp) {
+                SubscriptionApprovalReq reqCasted = (SubscriptionApprovalReq) req;
+                SubscriptionApprovalResp respCasted = (SubscriptionApprovalResp) resp;
+                descriptionBuilder.append(
+                        "Request to " + (reqCasted.approve ? "approve" : "reject") + " subscription request for subscriber_id = " + reqCasted.subscriberId
+                                + ", subscription request " + respCasted.status
+                );
+                endpoint = "Subscription Approval";
+
+            } else {
+                descriptionBuilder.append("Invalid request format");
+            }
+
+            if (resp.success) {
+                descriptionBuilder.append(", successful");
+            } else {
+                descriptionBuilder.append(", failed");
+            }
+        }
+        try {
+            String description = descriptionBuilder.toString();
+            String timestampString = dtf.format(timestamp);
+            Statement statement = this.db_conn.createStatement();
+            String sql = "INSERT INTO logging(description, IP, endpoint, req_time) "
+                    + "VALUES ('%s', '%s', '%s', '%s')";
+
+            String formattedSql = String.format(sql, description, IPAddress, endpoint, timestampString);
+            int count = statement.executeUpdate(formattedSql);
+            if (count == 1) {
+                System.out.println("Log added");
+            } else {
+                System.out.println("Failed to add log");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.out.println("Failed to add log");
+        }
+    }
+}
diff --git a/travelution/src/main/java/com/example/travelution/request/SubscriptionApprovalReq.java b/travelution/src/main/java/com/example/travelution/request/SubscriptionApprovalReq.java
index d27c5f9..1f97126 100644
--- a/travelution/src/main/java/com/example/travelution/request/SubscriptionApprovalReq.java
+++ b/travelution/src/main/java/com/example/travelution/request/SubscriptionApprovalReq.java
@@ -1,6 +1,6 @@
 package com.example.travelution.request;
 
-public class SubscriptionApprovalReq {
+public class SubscriptionApprovalReq extends Request{
     public int subscriberId;
     public boolean approve;
 }
diff --git a/travelution/src/main/java/com/example/travelution/request/ValidateSubscriptionReq.java b/travelution/src/main/java/com/example/travelution/request/ValidateSubscriptionReq.java
index aaa8d00..061bc65 100644
--- a/travelution/src/main/java/com/example/travelution/request/ValidateSubscriptionReq.java
+++ b/travelution/src/main/java/com/example/travelution/request/ValidateSubscriptionReq.java
@@ -1,5 +1,5 @@
 package com.example.travelution.request;
 
-public class ValidateSubscriptionReq {
+public class ValidateSubscriptionReq extends Request{
     public int subscriberId;
 }
diff --git a/travelution/src/main/java/com/example/travelution/response/Response.java b/travelution/src/main/java/com/example/travelution/response/Response.java
index 289ddb7..149b2d8 100644
--- a/travelution/src/main/java/com/example/travelution/response/Response.java
+++ b/travelution/src/main/java/com/example/travelution/response/Response.java
@@ -5,6 +5,9 @@ public class Response {
     public boolean success;
     public String message;
 
+    public Response() {
+    }
+
     public Response(boolean success, String message) {
         this.success = success;
         this.message = message;
diff --git a/travelution/src/main/java/com/example/travelution/response/SubscriptionApprovalResp.java b/travelution/src/main/java/com/example/travelution/response/SubscriptionApprovalResp.java
index 9c71bcf..f48f93f 100644
--- a/travelution/src/main/java/com/example/travelution/response/SubscriptionApprovalResp.java
+++ b/travelution/src/main/java/com/example/travelution/response/SubscriptionApprovalResp.java
@@ -5,6 +5,9 @@ public class SubscriptionApprovalResp extends Response{
     public Integer subscriberId;
     public String status;
 
+    public SubscriptionApprovalResp() {
+        super();
+    }
     public SubscriptionApprovalResp(boolean success, String message, Integer subscriberId, String status) {
         super(success, message);
         this.subscriberId = subscriberId;
diff --git a/travelution/src/main/java/com/example/travelution/response/SubscriptionListResp.java b/travelution/src/main/java/com/example/travelution/response/SubscriptionListResp.java
index f2b2f04..b43eeda 100644
--- a/travelution/src/main/java/com/example/travelution/response/SubscriptionListResp.java
+++ b/travelution/src/main/java/com/example/travelution/response/SubscriptionListResp.java
@@ -5,6 +5,9 @@ import java.util.List;
 public class SubscriptionListResp extends Response{
     public SubscriptionListWrapper list;
 
+    public SubscriptionListResp() {
+        super();
+    }
     public SubscriptionListResp(boolean success, String message, List<Subscriber> list) {
         super(success, message);
         this.list = new SubscriptionListWrapper(list);
diff --git a/travelution/src/main/java/com/example/travelution/response/SubscriptionListWrapper.java b/travelution/src/main/java/com/example/travelution/response/SubscriptionListWrapper.java
index 6ba9dbb..422f1f7 100644
--- a/travelution/src/main/java/com/example/travelution/response/SubscriptionListWrapper.java
+++ b/travelution/src/main/java/com/example/travelution/response/SubscriptionListWrapper.java
@@ -4,6 +4,9 @@ import java.util.List;
 public class SubscriptionListWrapper {
 
     public List<Subscriber> elements;
+    public SubscriptionListWrapper(){
+
+    }
     public SubscriptionListWrapper(List<Subscriber> elements) {
         this.elements = elements;
     }
diff --git a/travelution/src/main/java/com/example/travelution/response/SubscriptionResp.java b/travelution/src/main/java/com/example/travelution/response/SubscriptionResp.java
index b5a0505..ae5d7be 100644
--- a/travelution/src/main/java/com/example/travelution/response/SubscriptionResp.java
+++ b/travelution/src/main/java/com/example/travelution/response/SubscriptionResp.java
@@ -5,6 +5,9 @@ public class SubscriptionResp extends Response{
     public Integer subscriberId;
     public String status;
 
+    public SubscriptionResp() {
+        super();
+    }
     public SubscriptionResp(boolean success, String message, Integer subscriberId, String status) {
         super(success, message);
         this.subscriberId = subscriberId;
diff --git a/travelution/src/main/java/com/example/travelution/response/ValidateSubscriptionResp.java b/travelution/src/main/java/com/example/travelution/response/ValidateSubscriptionResp.java
index 95a57ee..ca0cf85 100644
--- a/travelution/src/main/java/com/example/travelution/response/ValidateSubscriptionResp.java
+++ b/travelution/src/main/java/com/example/travelution/response/ValidateSubscriptionResp.java
@@ -5,6 +5,9 @@ public class ValidateSubscriptionResp extends Response{
     public Integer subscriberId;
     public Boolean subscribed;
 
+    public ValidateSubscriptionResp(){
+        super();
+    }
     public ValidateSubscriptionResp(boolean success, String message, Integer subscriberId, Boolean subscribed) {
         super(success, message);
         this.subscriberId = subscriberId;
-- 
GitLab