Merge remote-tracking branch 'origin/master' into aaron-branch

This commit is contained in:
Aaron Sun 2020-10-05 19:37:10 -07:00
commit d5cd854dc9
36 changed files with 1192 additions and 117 deletions

View File

@ -0,0 +1,124 @@
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
public class Item {
Integer productID;
Integer chainID;
String upc;
String description;
BigDecimal price;
String imageURL;
String department;
LocalDateTime retrievedDate;
Integer fetchCounts;
Item(ResultSet itemRow) throws SQLException {
this.productID = itemRow.getInt(1);
System.out.println(this.productID);
this.chainID = itemRow.getInt(2);
System.out.println(this.chainID);
this.upc = itemRow.getString(3);
System.out.println(this.upc);
this.description = itemRow.getString(4);
System.out.println(this.description);
this.price = itemRow.getBigDecimal(5);
System.out.println(this.price);
this.imageURL = itemRow.getString(6);
System.out.println(imageURL);
this.department = itemRow.getString(7);
System.out.println(department);
this.retrievedDate = itemRow.getObject(8, LocalDateTime.class);
System.out.println(retrievedDate);
this.fetchCounts = itemRow.getInt(9);
System.out.println(fetchCounts);
}
@Override
public String toString() {
return "Item{" +
"productID=" + productID +
", chainID=" + chainID +
", upc='" + upc + '\'' +
", description='" + description + '\'' +
", price=" + price +
", imageURL='" + imageURL + '\'' +
", department='" + department + '\'' +
", retrievedDate=" + retrievedDate +
", fetchCounts=" + fetchCounts +
'}';
}
public Integer getProductID() {
return productID;
}
public void setProductID(Integer productID) {
this.productID = productID;
}
public Integer getChainID() {
return chainID;
}
public void setChainID(Integer chainID) {
this.chainID = chainID;
}
public String getUpc() {
return upc;
}
public void setUpc(String upc) {
this.upc = upc;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public LocalDateTime getRetrievedDate() {
return retrievedDate;
}
public void setRetrievedDate(LocalDateTime retrievedDate) {
this.retrievedDate = retrievedDate;
}
public Integer getFetchCounts() {
return fetchCounts;
}
public void setFetchCounts(Integer fetchCounts) {
this.fetchCounts = fetchCounts;
}
}

View File

@ -0,0 +1,11 @@
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Map;
public class ItemGET implements RequestHandler<Map<String,Object>, Object> {
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
return BasicHandler.handleRequest(inputMap, unfilled, ItemGetter.class);
}
}

View File

@ -0,0 +1,36 @@
import com.google.gson.Gson;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public class ItemGetter implements CallHandler{
private final DBConnector connector;
private final String GET_ITEM = "SELECT * FROM Product WHERE productID = ?;";
public ItemGetter(DBConnector connector, String cognitoID) {
this.connector = connector;
}
@Override
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryMap, String cognitoID) throws SQLException {
Connection connection = connector.getConnection();
try {
PreparedStatement statement = connection.prepareStatement(GET_ITEM);
statement.setInt(1, Integer.parseInt(queryMap.get("id")));
System.out.println(statement);
ResultSet queryResults = statement.executeQuery();
queryResults.first();
System.out.println(queryResults);
Item retrievedItem = new Item(queryResults);
System.out.println(retrievedItem);
return retrievedItem;
} finally {
connection.close();
}
}
}

View File

@ -0,0 +1,50 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
public class ItemEntry {
Integer listID;
Integer productID;
Integer quantity;
LocalDateTime addedDate;
Boolean purchased;
public ItemEntry(Integer listID, ResultSet listRow) throws SQLException {
this.listID = listID;
productID = listRow.getInt(1);
quantity = listRow.getInt(2);
addedDate = listRow.getObject(3, LocalDateTime.class);
purchased = listRow.getBoolean(4);
}
public Integer getProductID() {
return productID;
}
public void setProductID(Integer productID) {
this.productID = productID;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public LocalDateTime getAddedDate() {
return addedDate;
}
public void setAddedDate(LocalDateTime addedDate) {
this.addedDate = addedDate;
}
public Boolean getPurchased() {
return purchased;
}
public void setPurchased(Boolean purchased) {
this.purchased = purchased;
}
}

View File

@ -0,0 +1,72 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.ArrayList;
public class List {
Integer itemID;
String name;
String owner;
long lastUpdated;
ArrayList<ItemEntry> entries;
public List(ResultSet listRow) throws SQLException {
itemID = listRow.getInt("listID");
name = listRow.getString("name");
owner = listRow.getString("owner");
lastUpdated = listRow.getTimestamp("lastUpdated").toInstant().toEpochMilli();
entries = new ArrayList<>();
}
public void addItemEntry(ItemEntry entry) {
entries.add(entry);
}
@Override
public String toString() {
return "List{" +
"itemID=" + itemID +
", name='" + name + '\'' +
", owner='" + owner + '\'' +
", lastUpdated=" + lastUpdated +
", entries=" + entries +
'}';
}
public ItemEntry[] getEntries() {
return entries.toArray(new ItemEntry[entries.size()]);
}
public Integer getItemID() {
return itemID;
}
public void setItemID(Integer itemID) {
this.itemID = itemID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public long getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(long lastUpdated) {
this.lastUpdated = lastUpdated;
}
}

View File

@ -0,0 +1,33 @@
import java.sql.*;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.Map;
public class ListAdder implements CallHandler {
private DBConnector connector;
private String cognitoID;
private final String LIST_CREATE = "INSERT INTO List (name, owner, lastUpdated) VALUES (?, ?, ?)";
public ListAdder(DBConnector connector, String cognitoID) {
this.connector = connector;
this.cognitoID = cognitoID;
}
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryString, String cognitoID) throws SQLException {
Connection connection = connector.getConnection();
PreparedStatement statement = connection.prepareStatement(LIST_CREATE, Statement.RETURN_GENERATED_KEYS);
statement.setString(1, bodyMap.get("name").toString());//Needs safe checking
statement.setString(2, cognitoID);
statement.setTimestamp(3, Timestamp.from(Instant.now()));
System.out.println(statement);
statement.executeUpdate();
ResultSet newIDRS = statement.getGeneratedKeys();
newIDRS.first();
Integer newID = newIDRS.getInt(1);
connection.commit();
return newID;
}
}

View File

@ -0,0 +1,12 @@
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Map;
public class ListGET implements RequestHandler<Map<String,Object>, Object> {
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
return BasicHandler.handleRequest(inputMap, unfilled, ListGetter.class);
}
}

View File

@ -0,0 +1,58 @@
import com.google.gson.Gson;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class ListGetter implements CallHandler{
private final DBConnector connector;
private final String cognitoID;
private final String GET_LIST = "SELECT * FROM List WHERE listID = ?;";
private final String GET_LISTS = "SELECT listID FROM List WHERE owner = ?;";
private final String GET_ENTRIES = "SELECT * FROM ListProduct WHERE listID = ?;";
public ListGetter(DBConnector connector, String cognitoID) {
this.connector = connector;
this.cognitoID = cognitoID;
}
@Override
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryMap, String cognitoID) throws SQLException {
try (Connection connection = connector.getConnection()) {
Integer id = Integer.parseInt(queryMap.get("id"));
if (id == -1) {
PreparedStatement getLists = connection.prepareStatement(GET_LISTS);
getLists.setString(1, cognitoID);
System.out.println(getLists);
ResultSet getListsResults = getLists.executeQuery();
System.out.println(getListsResults);
ArrayList<Integer> listIds = new ArrayList<>();
while (getListsResults.next()) {
listIds.add(getListsResults.getInt(1));
}
return listIds;
}
PreparedStatement getList = connection.prepareStatement(GET_LIST);
getList.setInt(1, id);
System.out.println(getList);
ResultSet getListResults = getList.executeQuery();
getListResults.first();
System.out.println(getListResults);
List retrievedList = new List(getListResults);
System.out.println(retrievedList);
PreparedStatement getListEntries = connection.prepareStatement(GET_ENTRIES);
getListEntries.setInt(1, id);
ResultSet getEntryResults = getListEntries.executeQuery();
while (getEntryResults.next()) {
retrievedList.addItemEntry(new ItemEntry(id, getEntryResults));
}
System.out.println(retrievedList);
return retrievedList;
}
}
}

View File

@ -0,0 +1,11 @@
import java.util.Map;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class ListPOST implements RequestHandler<Map<String,Object>, Object>{
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
return BasicHandler.handleRequest(inputMap, unfilled, ListAdder.class);
}
}

View File

@ -0,0 +1,38 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.Map;
public class ListEntryAdder implements CallHandler {
private DBConnector connector;
private String cognitoID;
private final String ITEM_TO_LIST = "INSERT INTO ListProduct (productID, listID, quantity, addedDate, purchased) VALUES (?, ?, ?, ?, ?)";
public ListEntryAdder(DBConnector connector, String cognitoID) {
this.connector = connector;
this.cognitoID = cognitoID;
}
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryString, String cognitoID) throws SQLException {
Connection connection = connector.getConnection();
try {
PreparedStatement statement = connection.prepareStatement(ITEM_TO_LIST);
statement.setInt(1, (Integer) bodyMap.get("productID"));
statement.setInt(2, (Integer) bodyMap.get("listID"));
statement.setInt(3, (Integer) bodyMap.get("quantity"));
statement.setObject(4, Instant.now().atZone(ZoneOffset.UTC).toLocalDateTime());
statement.setBoolean(5, (Boolean) bodyMap.get("purchased"));
System.out.println(statement);
statement.executeUpdate();
connection.commit();
} finally {
connection.close();
}
return null;
}
}

View File

@ -0,0 +1,11 @@
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Map;
public class ListEntryDELETE implements RequestHandler<Map<String,Object>, Object> {
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
return BasicHandler.handleRequest(inputMap, unfilled, ListEntryDeleter.class);
}
}

View File

@ -0,0 +1,33 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public class ListEntryDeleter implements CallHandler {
private DBConnector connector;
private String cognitoID;
private final String REMOVE_FROM_LIST = "DELETE FROM ListProduct WHERE (ProductID = ? AND ListID = ?);";
public ListEntryDeleter(DBConnector connector, String cognitoID) {
this.connector = connector;
this.cognitoID = cognitoID;
}
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryString, String cognitoID) throws SQLException {
Connection connection = connector.getConnection();
try {
PreparedStatement statement = connection.prepareStatement(REMOVE_FROM_LIST);
statement.setInt(1, (Integer) bodyMap.get("ProductID"));
statement.setInt(2, (Integer) bodyMap.get("ListID"));
System.out.println(statement);
statement.executeUpdate();
connection.commit();
} finally {
connection.close();
}
return null;
}
}

View File

@ -0,0 +1,11 @@
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Map;
public class ListEntryPOST implements RequestHandler<Map<String,Object>, Object> {
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
return BasicHandler.handleRequest(inputMap, unfilled, ListEntryAdder.class);
}
}

View File

@ -0,0 +1,3 @@
{
"userPoolId": "us-east-2_MFgSVKQMd",
}

View File

@ -0,0 +1,11 @@
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import java.util.Map;
public class UserDELETE implements RequestHandler<Map<String,Object>, Object> {
public Object handleRequest(Map<String, Object> inputMap, Context unfilled) {
return BasicHandler.handleRequest(inputMap, unfilled, UserDeleter.class);
}
}

View File

@ -0,0 +1,58 @@
import com.amazonaws.services.cognitoidp.AWSCognitoIdentityProvider;
import com.amazonaws.services.cognitoidp.AWSCognitoIdentityProviderClientBuilder;
import com.amazonaws.services.cognitoidp.model.AdminDeleteUserRequest;
import com.amazonaws.services.cognitoidp.model.AdminUserGlobalSignOutRequest;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class UserDeleter implements CallHandler {
private DBConnector connector;
private String cognitoID;
//private final String REMOVE_FROM_LIST = "DELETE FROM ListProduct WHERE (ProductID = ? AND ListID = ?);";
public UserDeleter(DBConnector connector, String cognitoID) {
this.connector = connector;
this.cognitoID = cognitoID;
}
public Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryString, String cognitoID) throws SQLException {
AWSCognitoIdentityProvider awsCognitoIdentityProvider = AWSCognitoIdentityProviderClientBuilder.defaultClient();
Properties cognitoProperties;
try {
cognitoProperties = DBConnector.loadProperties("cognitoProperties.json");
} catch (IOException e) {
e.printStackTrace();
return null;
}
String userPoolId = cognitoProperties.get("userPoolId").toString();
System.out.println(userPoolId);
AdminUserGlobalSignOutRequest adminUserGlobalSignOutRequest = new AdminUserGlobalSignOutRequest().withUserPoolId(userPoolId);
adminUserGlobalSignOutRequest.setUsername(cognitoID);
System.out.println(adminUserGlobalSignOutRequest);
awsCognitoIdentityProvider.adminUserGlobalSignOut(adminUserGlobalSignOutRequest);
AdminDeleteUserRequest adminDeleteUserRequest = new AdminDeleteUserRequest().withUserPoolId(userPoolId);
adminDeleteUserRequest.setUsername(cognitoID);
System.out.println(adminDeleteUserRequest);
awsCognitoIdentityProvider.adminDeleteUser(adminDeleteUserRequest);
return null;
// Connection connection = connector.getConnection();
// try {
// PreparedStatement statement = connection.prepareStatement(REMOVE_FROM_LIST);
// statement.setInt(1, (Integer) bodyMap.get("ProductID"));
// statement.setInt(2, (Integer) bodyMap.get("ListID"));
// System.out.println(statement);
// statement.executeUpdate();
// connection.commit();
// } finally {
// connection.close();
// }
// return null;
}
}

View File

@ -39,6 +39,56 @@
<artifactId>mariadb-java-client</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-cognitoidentity</artifactId>
<version>1.11.875</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-cognitoidp</artifactId>
<version>1.11.875</version>
</dependency>
<dependency>
<groupId>software.amazon.ion</groupId>
<artifactId>ion-java</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.6</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-cbor</artifactId>
<version>2.11.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.3</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>1.11</maven.compiler.source>

View File

@ -0,0 +1,31 @@
import com.amazonaws.services.lambda.runtime.Context;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public class BasicHandler {
public static <T extends CallHandler> Object handleRequest(Map<String, Object> inputMap, Context unfilled, Class<T> toCall) {
String cognitoID = InputUtils.getCognitoIDFromBody(inputMap);
HashMap<String, String> queryMap = InputUtils.getQueryParams(inputMap);
try {
DBConnector connector = new DBConnector();
try {
Constructor<T> constructor = toCall.getConstructor(DBConnector.class, String.class);
CallHandler callHandler = constructor.newInstance(connector, cognitoID);
return callHandler.conductAction(InputUtils.getBody(inputMap), queryMap, cognitoID);
} catch (SQLException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
} finally {
connector.close();
}
} catch (IOException |SQLException|ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e.getLocalizedMessage());
}
return null;
}
}

View File

@ -0,0 +1,7 @@
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public interface CallHandler {
Object conductAction(Map<String, Object> bodyMap, HashMap<String, String> queryString, String cognitoID) throws SQLException;
}

View File

@ -12,11 +12,11 @@ public class DBConnector {
Connection connection;
DBConnector() throws IOException, SQLException, ClassNotFoundException {
public DBConnector() throws IOException, SQLException, ClassNotFoundException {
this(loadProperties("dbProperties.json"));
}
DBConnector(Properties dbProperties) throws SQLException, ClassNotFoundException {
public DBConnector(Properties dbProperties) throws SQLException, ClassNotFoundException {
Class.forName("org.mariadb.jdbc.Driver");
System.out.println(dbProperties);
System.out.println(DBConnector.buildURL(dbProperties));

View File

@ -1,3 +1,9 @@
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class InputUtils {
@ -19,6 +25,24 @@ public class InputUtils {
return getMap(inputMap, "body");
}
private static String getQueryString(Map<String, Object> inputMap) {
return (String) (getMap(inputMap, "params").get("querystring"));
}
public static HashMap<String, String> getQueryParams(Map<String, Object> inputMap) {
return (HashMap<String, String>) (getMap(inputMap, "params").get("querystring"));
// String queryString = getQueryString(inputMap);
// List<NameValuePair> queryparams = URLEncodedUtils.parse(queryString, StandardCharsets.UTF_8);
// HashMap<String, String> mappedParams = new HashMap<>();
// for (NameValuePair param : queryparams) {
// mappedParams.put(param.getName(), param.getValue());
// }
// return mappedParams;
}
public static Map<String, Object> getMap(Map<String, Object> parentMap, String childKey) {
if ((parentMap.get(childKey) != null) && (parentMap.get(childKey) instanceof Map<?, ?>)) {
return ((Map<String, Object>) parentMap.get(childKey));

View File

@ -1,27 +0,0 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
public class ListAdder {
private DBConnector connector;
private String cognitoID;
private final String LIST_CREATE = "INSERT INTO Lists (Name, Owner) VALUES (?, ?)";
ListAdder(DBConnector connector, String cognitoID) {
this.connector = connector;
this.cognitoID = cognitoID;
}
public void add(Map<String, Object> bodyMap) throws SQLException {
Connection connection = connector.getConnection();
PreparedStatement statement = connection.prepareStatement(LIST_CREATE);
statement.setString(1, bodyMap.get("name").toString());//Needs safe checking
statement.setString(2, cognitoID);
System.out.println(statement);
statement.executeUpdate();
connection.commit();
}
}

View File

@ -1,28 +0,0 @@
import java.io.IOException;
import java.sql.SQLException;
import java.util.Map;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class ListPOST implements RequestHandler<Map<String,Object>, String>{
public String handleRequest(Map<String, Object> inputMap, Context unfilled) {
String cognitoID = InputUtils.getCognitoIDFromBody(inputMap);
try {
DBConnector connector = new DBConnector();
try {
new ListAdder(connector, cognitoID).add(InputUtils.getBody(inputMap));
} catch (SQLException e) {
e.printStackTrace();
} finally {
connector.close();
}
} catch (IOException|SQLException|ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
return null;
}
}

Binary file not shown.

View File

@ -0,0 +1,5 @@
#Generated by Maven
#Mon Oct 05 10:19:24 EDT 2020
groupId=groupId
artifactId=Lists
version=1.0-SNAPSHOT

View File

@ -0,0 +1,4 @@
/Users/MNM/Documents/GitHub/Listify/Lambdas/Lists/src/main/java/CallHandler.java
/Users/MNM/Documents/GitHub/Listify/Lambdas/Lists/src/main/java/DBConnector.java
/Users/MNM/Documents/GitHub/Listify/Lambdas/Lists/src/main/java/BasicHandler.java
/Users/MNM/Documents/GitHub/Listify/Lambdas/Lists/src/main/java/InputUtils.java

View File

@ -50,5 +50,6 @@ dependencies {
implementation 'org.json:json:20200518'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.squareup.okhttp3:okhttp:4.8.1'
}

View File

@ -8,6 +8,7 @@ import com.amplifyframework.auth.options.AuthSignUpOptions;
import com.amplifyframework.auth.result.AuthSignInResult;
import com.amplifyframework.auth.result.AuthSignUpResult;
import com.amplifyframework.core.Amplify;
import com.example.listify.data.User;
import org.json.JSONException;
import org.json.JSONObject;
@ -44,6 +45,17 @@ public class AuthManager {
}
public String getUserToken() {
if (authSession == null) {
try {
fetchAuthSession();
} catch (AuthException e) {
e.printStackTrace();
return "";
}
}
if (authSession.isSignedIn() == false) {
return "";
}
return authSession.getUserPoolTokens().getValue().getIdToken();
}
@ -78,6 +90,10 @@ public class AuthManager {
waiting = false;
}
public void signOutSuccess() {
waiting = false;
}
public void startSignUp(String email, String password) throws AuthException {
this.email = email;
this.password = password;
@ -117,7 +133,17 @@ public class AuthManager {
throwIfAuthError();
}
public void deleteUser(Requestor requestor) throws AuthException {
requestor.deleteObject("N/A", User.class);
signOutUser();
}
public void signOutUser() throws AuthException {
authSession = null;
waiting = true;
Amplify.Auth.signOut(this::signOutSuccess, error -> setAuthError(error));
throwIfAuthError();
}
public static Properties loadProperties(Context context, String path) throws IOException, JSONException {
Properties toReturn = new Properties();

View File

@ -13,11 +13,18 @@ import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.amplifyframework.auth.AuthException;
import com.example.listify.data.Item;
import com.example.listify.data.List;
import com.example.listify.data.ListEntry;
import com.google.android.material.navigation.NavigationView;
import org.json.JSONException;
import java.io.IOException;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.Properties;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
private AppBarConfiguration mAppBarConfiguration;
@ -25,15 +32,20 @@ public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//------------------------------Auth Testing---------------------------------------------//
/*AuthManager authManager = new AuthManager();
boolean testAuth = false;
if (testAuth) {
AuthManager authManager = new AuthManager();
try {
authManager.signIn("merzn@purdue.edu", "Password123");
Log.i("Authentication", authManager.getAuthSession().toString());
Log.i("Token", authManager.getAuthSession().getUserPoolTokens().getValue().getIdToken());
}
catch (AuthException e) {
} catch (AuthException e) {
Log.i("Authentication", "Login failed. User probably needs to register. Exact error: " + e.getMessage());
try {
authManager.startSignUp("merzn@purdue.edu", "Password123");
@ -41,26 +53,63 @@ public class MainActivity extends AppCompatActivity {
} catch (AuthException signUpError) {
Log.e("Authentication", "SignUp error: " + signUpError.getMessage());
}
}*/
}
}
//NOTE: deleteUser is slightly unusual in that it requires a Requestor. See below for building one
//authManager.deleteUser(requestor);
//------------------------------------------------------------------------------------------//
boolean testAPI = false;
//----------------------------------API Testing---------------------------------------------//
/*Properties configs = new Properties();
if (testAPI) {
AuthManager authManager = new AuthManager();
try {
authManager.signIn("merzn@purdue.edu", "Password123");
} catch (AuthException e) {
e.printStackTrace();
}
Properties configs = new Properties();
try {
configs = AuthManager.loadProperties(this, "android.resource://" + getPackageName() + "/raw/auths.json");
}
catch (IOException|JSONException e) {
} catch (IOException | JSONException e) {
e.printStackTrace();
}*/
}
/*Requestor requestor = new Requestor(this, authManager,configs.getProperty("apiKey"));
List testList = new List("IAmATestList");
Requestor requestor = new Requestor(authManager, configs.getProperty("apiKey"));
//The name is the only part of this that is used, the rest is generated by the Lambda.
List testList = new List(-1, "New List", "user filled by lambda", Instant.now().toEpochMilli());
//Everything except addedDate is used for ItemEntry
ListEntry entry = new ListEntry(1, 1, new Random().nextInt(), Instant.now().atZone(ZoneOffset.UTC).toLocalDateTime(),false);
SynchronousReceiver<Integer> idReceiver = new SynchronousReceiver<>();
try {
requestor.postObject(testList);
}
catch (JSONException e) {
requestor.postObject(testList, idReceiver, idReceiver);
System.out.println(idReceiver.await());
requestor.postObject(entry);
} catch (Exception e) {
e.printStackTrace();
}*/
}
SynchronousReceiver<Item> itemReceiver = new SynchronousReceiver<>();
requestor.getObject("1", Item.class, itemReceiver, itemReceiver);
SynchronousReceiver<List> listReceiver = new SynchronousReceiver<>();
requestor.getObject("39", List.class, listReceiver, listReceiver);
SynchronousReceiver<Integer[]> listIdsReceiver = new SynchronousReceiver<>();
requestor.getListOfIds(List.class, listIdsReceiver, listIdsReceiver);
try {
System.out.println(itemReceiver.await());
System.out.println(listReceiver.await());
System.out.println(Arrays.toString(listIdsReceiver.await()));
} catch (Exception receiverError) {
receiverError.printStackTrace();
}
}
//------------------------------------------------------------------------------------------//
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);

View File

@ -1,66 +1,130 @@
package com.example.listify;
import android.content.Context;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import okhttp3.*;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
import java.io.IOException;
public class Requestor {
private final String DEV_BASEURL = "https://datoh7woc9.execute-api.us-east-2.amazonaws.com/Development";
AuthManager authManager;
RequestQueue queue;
String apiKey;
OkHttpClient client;
Requestor(Context context, AuthManager authManager, String apiKey) {
queue = Volley.newRequestQueue(context);
Requestor(AuthManager authManager, String apiKey) {
this.authManager = authManager;
this.apiKey = apiKey;
client = new OkHttpClient();
}
public <T> void getListOfIds(Class<T> ofType, Receiver<Integer[]> successHandler, RequestErrorHandler failureHandler) {
String getURL = DEV_BASEURL + "/" + ofType.getSimpleName() + "?id=-1";
Request postRequest = buildBaseRequest(getURL, "GET", null);
launchCall(postRequest, successHandler, Integer[].class, failureHandler);
}
public <T> void getObject(String id, Class<T> classType, Receiver<T> receiver) {
String getURL = DEV_BASEURL + "/" + classType.getSimpleName() + "?id=" + id;
getObject(id, classType, receiver, null);
}
public void postObject(Object toPost, Response.ErrorListener failureHandler) throws JSONException {
String postURL = DEV_BASEURL + "/" + toPost.getClass().getSimpleName();
queue.add(buildRequest(postURL, toPost, null, failureHandler));
public <T> void getObject(String id, Class<T> classType, Receiver<T> successHandler, RequestErrorHandler failureHandler) {
String getURL = DEV_BASEURL + "/" + classType.getSimpleName() + "?id=" + id;
Request getRequest = buildBaseRequest(getURL, "GET", null);
launchCall(getRequest, successHandler, classType, failureHandler);
}
public void deleteObject(String id, Class classType) {
deleteObject(id, classType, null);
}
public void deleteObject(String id, Class classType, RequestErrorHandler failureHandler) {
String deleteURL = DEV_BASEURL + "/" + classType.getSimpleName() + "?id=" + id;
Request deleteRequest = buildBaseRequest(deleteURL, "DELETE", "{}");
launchCall(deleteRequest, null, classType, failureHandler);
}
public void postObject(Object toPost) throws JSONException {
postObject(toPost, null);
postObject(toPost, (RequestErrorHandler) null);
}
private JsonObjectRequest buildRequest(String url, Object toJSONify, Response.Listener<JSONObject> successHandler, Response.ErrorListener failureHandler) throws JSONException {
return buildRequest(url, new JSONObject(new Gson().toJson(toJSONify)), successHandler, failureHandler);
public void postObject(Object toPost, RequestErrorHandler failureHandler) throws JSONException {
postObject(toPost, null, failureHandler);
}
private JsonObjectRequest buildRequest(String url, JSONObject jsonBody, Response.Listener<JSONObject> successHandler, Response.ErrorListener failureHandler) {
return new JsonObjectRequest(url, jsonBody, successHandler, failureHandler) {
public void postObject(Object toPost, Receiver<Integer> idReceiver) throws JSONException {
postObject(toPost, idReceiver, null);
}
public void postObject(Object toPost, Receiver<Integer> idReceiver, RequestErrorHandler failureHandler) throws JSONException {
String postURL = DEV_BASEURL + "/" + toPost.getClass().getSimpleName();
Request postRequest = buildBaseRequest(postURL, "POST", new Gson().toJson(toPost));
launchCall(postRequest, idReceiver, Integer.class, failureHandler);
}
private void launchCall(Request toLaunch, Receiver receiver, Class classType, RequestErrorHandler failureHandler) {
client.newCall(toLaunch).enqueue(new Callback() {
@Override
public Map<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<>();
System.out.println(authManager.getUserToken());
headers.put("Authorization", authManager.getUserToken());
headers.put("Content-Type", "application/json");
headers.put("X-API-Key", apiKey);
return headers;
public void onResponse(@NotNull Call call, @NotNull okhttp3.Response response) throws IOException {
String responseString = response.body().string();
if (receiver != null) {
if (classType == null) {
Log.e("Requestor Contract Error", "classType while receiver populated");
}
};
try {
receiver.acceptDelivery(new Gson().fromJson(responseString, classType));
} catch (JsonSyntaxException e) {
System.out.println(e);
Log.e("API response was not proper JSON", responseString);
if (failureHandler != null) {
failureHandler.acceptError(e);
}
//throw new JsonSyntaxException(e);
}
}
Log.d("API Response", responseString);
}
@Override
public void onFailure(@NotNull Call call, IOException e) {
if (failureHandler != null) {
failureHandler.acceptError(e);
} else {
Log.e("Network Error", e.getLocalizedMessage());
}
}
});
}
public class Receiver<T> {
public void acceptDelivery(T delivered) {
public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
private Request buildBaseRequest(String url, String method, String bodyJSON) {
Request.Builder requestBase = addAuthHeaders(new Request.Builder().url(url));
if (method == "GET") {
requestBase.get();
} else {
requestBase.method(method, RequestBody.create(bodyJSON, JSON));
}
return requestBase.build();
}
private Request.Builder addAuthHeaders(Request.Builder toAuthorize) {
toAuthorize.addHeader("Authorization", authManager.getUserToken());
toAuthorize.addHeader("X-API-Key", apiKey);
return toAuthorize;
}
public interface Receiver<T> {
void acceptDelivery(T delivered);
}
public interface RequestErrorHandler {
void acceptError(Exception error);
}
}

View File

@ -0,0 +1,37 @@
package com.example.listify;
public class SynchronousReceiver<T> implements Requestor.Receiver<T>, Requestor.RequestErrorHandler {
private volatile boolean waiting;
private volatile Exception error;
private T toReturn;
public SynchronousReceiver() {
waiting = true;
error = null;
}
public T await() throws Exception {
while (waiting) {
Thread.yield();
}
waiting = true;
if (error != null) {
Exception toThrow = error;
error = null;
throw toThrow;
}
return toReturn;
}
@Override
public void acceptDelivery(Object delivered) {
toReturn = (T) delivered;
waiting = false;
}
@Override
public void acceptError(Exception error) {
waiting = false;
this.error = error;
}
}

View File

@ -0,0 +1,116 @@
package com.example.listify.data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
public class Item {
Integer productID;
Integer chainID;
String upc;
String description;
BigDecimal price;
String imageURL;
String department;
LocalDateTime retrievedDate;
Integer fetchCounts;
public Item(Integer productID, Integer chainID, String upc, String description, BigDecimal price,
String imageURL, String department, LocalDateTime retrievedDate, Integer fetchCounts) {
this.productID = productID;
this.chainID = chainID;
this.upc = upc;
this.description = description;
this.price = price;
this.imageURL = imageURL;
this.department = department;
this.retrievedDate = retrievedDate;
this.fetchCounts = fetchCounts;
}
@Override
public String toString() {
return "Item{" +
"productID=" + productID +
", chainID=" + chainID +
", upc='" + upc + '\'' +
", description='" + description + '\'' +
", price=" + price +
", imageURL='" + imageURL + '\'' +
", department='" + department + '\'' +
", retrievedDate=" + (retrievedDate == null ? null : retrievedDate) +
", fetchCounts=" + fetchCounts +
'}';
}
public Integer getProductID() {
return productID;
}
public void setProductID(Integer productID) {
this.productID = productID;
}
public Integer getChainID() {
return chainID;
}
public void setChainID(Integer chainID) {
this.chainID = chainID;
}
public String getUpc() {
return upc;
}
public void setUpc(String upc) {
this.upc = upc;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public LocalDateTime getRetrievedDate() {
return retrievedDate;
}
public void setRetrievedDate(LocalDateTime retrievedDate) {
this.retrievedDate = retrievedDate;
}
public Integer getFetchCounts() {
return fetchCounts;
}
public void setFetchCounts(Integer fetchCounts) {
this.fetchCounts = fetchCounts;
}
}

View File

@ -0,0 +1,70 @@
package com.example.listify.data;
import java.util.Arrays;
public class List {
Integer itemID;
String name;
String owner;
long lastUpdated;
final ListEntry[] entries;
public List(Integer itemID, String name, String owner, long lastUpdated, ListEntry[] entries) {
this.itemID = itemID;
this.name = name;
this.owner = owner;
this.lastUpdated = lastUpdated;
this.entries = entries;
}
public List(Integer itemID, String name, String owner, long lastUpdated) {
this(itemID, name, owner, lastUpdated, null);
}
@Override
public String toString() {
return "List{" +
"itemID=" + itemID +
", name='" + name + '\'' +
", owner='" + owner + '\'' +
", lastUpdated=" + lastUpdated +
", entries=" + Arrays.toString(entries) +
'}';
}
public Integer getItemID() {
return itemID;
}
public void setItemID(Integer itemID) {
this.itemID = itemID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public long getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(long lastUpdated) {
this.lastUpdated = lastUpdated;
}
public ListEntry[] getEntries() {
return entries;
}
}

View File

@ -0,0 +1,70 @@
package com.example.listify.data;
import java.time.LocalDateTime;
public class ListEntry {
Integer listID;
Integer productID;
Integer quantity;
LocalDateTime addedDate;
Boolean purchased;
public ListEntry(Integer listID, Integer productID, Integer quantity, LocalDateTime addedDate, Boolean purchased) {
this.listID = listID;
this.productID = productID;
this.quantity = quantity;
this.addedDate = addedDate;
this.purchased = purchased;
}
@Override
public String toString() {
return "ListEntry{" +
"listID=" + listID +
", productID=" + productID +
", quantity=" + quantity +
", addedDate=" + addedDate +
", purchased=" + purchased +
'}';
}
public Integer getListID() {
return listID;
}
public void setListID(Integer listID) {
this.listID = listID;
}
public Integer getProductID() {
return productID;
}
public void setProductID(Integer productID) {
this.productID = productID;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public LocalDateTime getAddedDate() {
return addedDate;
}
public void setAddedDate(LocalDateTime addedDate) {
this.addedDate = addedDate;
}
public Boolean getPurchased() {
return purchased;
}
public void setPurchased(Boolean purchased) {
this.purchased = purchased;
}
}

View File

@ -0,0 +1,4 @@
package com.example.listify.data;
public class User {
}

View File

@ -11,7 +11,7 @@ REL_SCRIPT_DIR=$(dirname "${BASH_SOURCE[0]}")
source ${REL_SCRIPT_DIR}/VarSetup.sh
RAWLAMBDA=$(aws lambda create-function --function-name ${functionName}${method} --zip-file fileb://${jarPath} --runtime ${LANGUAGE} --role ${LAMBDAROLE} --handler ${functionName}${method} 2>${DEBUGFILE})
RAWLAMBDA=$(aws lambda create-function --function-name ${functionName}${method} --zip-file fileb://${jarPath} --runtime ${LANGUAGE} --role ${LAMBDAROLE} --handler ${functionName}${method} --memory-size 512 2>${DEBUGFILE})
if [[ $? -ne 0 ]]; then