Browse Source

- Add AWS CloudWatch logging & IC Scan log

- Added build flavors
hbw_build
Wong Joon Hui 2 years ago
parent
commit
61ad84724d
  1. 26
      app/build.gradle
  2. 25
      app/src/main/java/com/cst/im30/MainApplication.java
  3. 11
      app/src/main/java/com/cst/im30/activity/MainActivity.java
  4. 2
      app/src/main/java/com/cst/im30/model/EventLogDetailed.java
  5. 6
      app/src/main/java/com/cst/im30/service/IDVerificationService.java
  6. 148
      app/src/main/java/com/cst/im30/utility/CloudWatchLogger.java
  7. 9
      app/src/main/java/com/cst/im30/utility/Logger.java
  8. 16
      gradle.properties

26
app/build.gradle

@ -15,24 +15,26 @@ android {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// Echo Socket
buildConfigField("String", "SERVER_URL", SERVER_URL)
buildConfigField("String", "CLIENT_ID", CLIENT_ID)
buildConfigField("String", "CLIENT_SECRET", CLIENT_SECRET)
buildConfigField("String", "ECHO_SERVER_URL", ECHO_SERVER_URL)
buildConfigField("String", "ECHO_SERVER_PORT", ECHO_SERVER_PORT)
buildConfigField("String", "KIOSK_CODE", KIOSK_CODE)
buildConfigField("String", "SOCKET_PREFIX", SOCKET_PREFIX)
buildConfigField("String", "PAYMENT_CHANNEL_ID", PAYMENT_CHANNEL_ID)
buildConfigField("String", "PAYMENT_EVENT_TYPE", PAYMENT_EVENT_TYPE)
buildConfigField("String", "IC_CHANNEL_ID", IC_CHANNEL_ID)
buildConfigField("String", "IC_EVENT_TYPE", IC_EVENT_TYPE)
// Bugfendder
buildConfigField("String", "BUGFENDER_TOKEN", BUGFENDER_TOKEN)
// AWS
buildConfigField("String", "AWS_ACCESS_KEY", AWS_ACCESS_KEY)
buildConfigField("String", "AWS_SECRET_KEY", AWS_SECRET_KEY)
buildConfigField("String", "LOG_GROUP_NAME", LOG_GROUP_NAME)
}
buildTypes {
@ -41,6 +43,20 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
flavorDimensions "deployment"
productFlavors {
build {
dimension "deployment"
}
staging {
dimension "deployment"
}
live {
dimension "deployment"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8

25
app/src/main/java/com/cst/im30/MainApplication.java

@ -26,14 +26,21 @@ import com.cst.im30.model.SaleRequest;
import com.cst.im30.model.SaleResponse;
import com.cst.im30.model.VoidRequest;
import com.cst.im30.model.VoidResponse;
import com.cst.im30.utility.CloudWatchLogger;
import com.cst.im30.utility.Logger;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class MainApplication extends Application {
public static MainApplication instance;
public static AppCompatActivity currentActivity;
private CloudWatchLogger cloudWatchLogger;
public static EchoClient paymentClient;
public static EchoClient icClient;
public static boolean paymentIsConnected = false;
@ -95,17 +102,29 @@ public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
instance = this;
this.cloudWatchLogger = new CloudWatchLogger();
//Logger.logV("Application Start");
initializeBugfender();
initializeCrashHandler();
}
public void log(String logStreamName, String message) {
this.cloudWatchLogger.log(BuildConfig.LOG_GROUP_NAME, logStreamName, message);
}
public void logICScan(String message) {
this.cloudWatchLogger.log(BuildConfig.LOG_GROUP_NAME, "IcScanLog", message);
}
public void logError(String message) {
this.cloudWatchLogger.log(BuildConfig.LOG_GROUP_NAME, "Error", message);
}
@SuppressLint("MissingPermission")
private void initializeBugfender() {
//Logger.logD("Attaching Bugfender");
Bugfender.init(this, BuildConfig.BUGFENDER_TOKEN, BuildConfig.DEBUG);
String serialNumber;

11
app/src/main/java/com/cst/im30/activity/MainActivity.java

@ -36,17 +36,7 @@ import com.cst.im30.PaymentHandler;
import com.cst.im30.R;
import com.cst.im30.common.CallableInterface;
import com.cst.im30.common.Constants;
import com.cst.im30.model.CancelRequest;
import com.cst.im30.model.CancelResponse;
import com.cst.im30.model.EventLogDetailed;
import com.cst.im30.model.PreAuthRequest;
import com.cst.im30.model.PreAuthResponse;
import com.cst.im30.model.SaleCompletionRequest;
import com.cst.im30.model.SaleCompletionResponse;
import com.cst.im30.model.SaleRequest;
import com.cst.im30.model.SaleResponse;
import com.cst.im30.model.VoidRequest;
import com.cst.im30.model.VoidResponse;
import com.cst.im30.service.IDVerificationService;
import com.cst.im30.service.PaymentService;
import com.cst.im30.service.UploadTransactionPreAuthPaymentService;
@ -57,7 +47,6 @@ import com.cst.im30.utility.PaymentUtils;
import com.daimajia.slider.library.SliderLayout;
import com.daimajia.slider.library.SliderTypes.BaseSliderView;
import com.daimajia.slider.library.SliderTypes.TextSliderView;
import com.jakewharton.processphoenix.ProcessPhoenix;
import net.mrbin99.laravelechoandroid.EchoCallback;

2
app/src/main/java/com/cst/im30/model/EventLogDetailed.java

@ -13,6 +13,8 @@ public class EventLogDetailed implements Serializable {
private String remark;
private String profileIdOpera;
// IC Verification
private String documentType, documentNumber, firstName, lastName, action;

6
app/src/main/java/com/cst/im30/service/IDVerificationService.java

@ -184,6 +184,9 @@ public class IDVerificationService {
String documentNumber = jsonObject.getJSONObject("data").getJSONObject("content").getString("document_number");
String firstName = jsonObject.getJSONObject("data").getJSONObject("content").getString("first_name");
String lastName = jsonObject.getJSONObject("data").getJSONObject("content").getString("last_name");
String id = jsonObject.getJSONObject("data").getJSONObject("content").getString("id");
String confirmationNumber = jsonObject.getJSONObject("data").getJSONObject("content").getString("confirmation_number");
String profileOperaId = jsonObject.getJSONObject("data").getJSONObject("content").getString("profile_id_opera");
EventLogDetailed eventLogDetailed = new EventLogDetailed();
eventLogDetailed.setAction(action);
@ -193,6 +196,9 @@ public class IDVerificationService {
eventLogDetailed.setDocumentNumber(documentNumber);
eventLogDetailed.setFirstName(firstName);
eventLogDetailed.setLastName(lastName);
eventLogDetailed.setId(Integer.parseInt(id));
eventLogDetailed.setConfirmationNumber(confirmationNumber);
eventLogDetailed.setProfileIdOpera(profileOperaId);
return eventLogDetailed;
}

148
app/src/main/java/com/cst/im30/utility/CloudWatchLogger.java

@ -0,0 +1,148 @@
package com.cst.im30.utility;
import android.os.Build;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.logs.AmazonCloudWatchLogsClient;
import com.amazonaws.services.logs.model.CreateLogGroupRequest;
import com.amazonaws.services.logs.model.CreateLogStreamRequest;
import com.amazonaws.services.logs.model.DescribeLogStreamsRequest;
import com.amazonaws.services.logs.model.InputLogEvent;
import com.amazonaws.services.logs.model.LogStream;
import com.amazonaws.services.logs.model.PutLogEventsRequest;
import com.amazonaws.services.logs.model.PutLogEventsResult;
import com.amazonaws.services.logs.model.ResourceAlreadyExistsException;
import com.cst.im30.BuildConfig;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class CloudWatchLogger {
private AmazonCloudWatchLogsClient client;
private PutLogEventsResult putLogEventsResult; // if you want to view the results of the put I guess
public CloudWatchLogger() {
// Can connect right away if you bundle the credentials in the Application.
// If you use another method, just call connect() AFTER you have your credentials.
connect();
}
private void connect() {
String accessKey = BuildConfig.AWS_ACCESS_KEY;
String secretKey = BuildConfig.AWS_SECRET_KEY;
BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials(accessKey, secretKey);
AmazonCloudWatchLogsClient client = new AmazonCloudWatchLogsClient(basicAWSCredentials);
Regions regions = Regions.AP_SOUTHEAST_1; // Singapore
client.setRegion(Region.getRegion(regions));
this.client = client;
}
/**
* As you can see, the code is put into a Thread to run in background.
* The actual calls to CloudWatch have to be run in a background thread unless we turn off the checking.
*/
public void log(String logGroupName, String logStreamName, String message) {
String fullLogStreamName = getPrefix() + logStreamName;
try {
Thread t = new Thread(() -> {
// Create LogGroup / LogStream (Will ignore if already created)
createCloudWatchGroups(logGroupName, fullLogStreamName);
// Prepare the LogMessage that you will send
List<InputLogEvent> logEvents = new ArrayList<>();
InputLogEvent log = new InputLogEvent();
Calendar calendar = Calendar.getInstance();
log.setTimestamp(calendar.getTimeInMillis());
log.setMessage(message);
logEvents.add(log);
// Check Cloudwatch for logStream if exist, to get the uploadSequenceToken.
// Without this token you can still push events, but cannot push additional events to the an existing logGroup/logStream.
// With the token, you can "append" the logStream (which we want).
// https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_DescribeLogStreams.html
DescribeLogStreamsRequest logStreamsRequest = new DescribeLogStreamsRequest(logGroupName);
logStreamsRequest.withLimit(10); // Up to 50. Increase/Decrease depending on how many different streamNames you maintain
//logStreamsRequest.setLogStreamNamePrefix(getPrefix());
List<LogStream> logStreamList = client.describeLogStreams(logStreamsRequest).getLogStreams();
String token = null;
for (LogStream logStream : logStreamList) {
if (logStream.getLogStreamName().equalsIgnoreCase(fullLogStreamName)) {
token = logStream.getUploadSequenceToken();
}
}
PutLogEventsRequest putLogEventsRequest = new PutLogEventsRequest();
putLogEventsRequest.setLogGroupName(logGroupName);
putLogEventsRequest.setLogStreamName(fullLogStreamName);
putLogEventsRequest.setLogEvents(logEvents);
if (token != null) {
putLogEventsRequest.setSequenceToken(token);
}
putLogEventsResult = client.putLogEvents(putLogEventsRequest);
Logger.logD("Pushed log to AWS Cloudwatch");
});
t.start();
t.join();
} catch (InterruptedException ignored) {
}
}
private void createCloudWatchGroups(String logGroupName, String logStreamName) {
try {
Thread t = new Thread(() -> {
CreateLogGroupRequest createLogGroupRequest = new CreateLogGroupRequest(logGroupName);
try {
client.createLogGroup(createLogGroupRequest);
} catch (Exception e) {
if (e instanceof ResourceAlreadyExistsException) {
assert true; // do nothing
} else {
e.printStackTrace();
}
}
CreateLogStreamRequest createLogStreamRequest = new CreateLogStreamRequest(logGroupName, logStreamName);
try {
client.createLogStream(createLogStreamRequest);
} catch (Exception e) {
if (e instanceof ResourceAlreadyExistsException) {
assert true; // do nothing
} else {
e.printStackTrace();
}
}
});
t.start();
t.join();
} catch (InterruptedException ignored) {
}
}
private String getPrefix() {
String dateString = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH).format(new Date());
String kioskCode = BuildConfig.KIOSK_CODE;
if (BuildConfig.FLAVOR != null && !BuildConfig.FLAVOR.isEmpty()) {
return dateString + "_IM30_" + kioskCode + "_" + BuildConfig.FLAVOR + "_";
} else {
return dateString + "_IM30_" + kioskCode + "_";
}
}
}

9
app/src/main/java/com/cst/im30/utility/Logger.java

@ -4,6 +4,8 @@ import android.os.Environment;
import android.util.Log;
import com.bugfender.sdk.Bugfender;
import com.cst.im30.MainApplication;
import com.cst.im30.model.EventLogDetailed;
import java.io.File;
import java.io.FileOutputStream;
@ -94,7 +96,10 @@ public class Logger {
logDirectory.mkdir();
}
String dataToWrite = "[" + getTimeStamp() + "] - " + data + "\n";
EventLogDetailed eventLogDetailed = MainApplication.currentEventLogDetailed;
String extra = "ID:" + eventLogDetailed.getId() + ", C/N:" + eventLogDetailed.getConfirmationNumber() + ", OperaID:" + eventLogDetailed.getProfileIdOpera();
String dataToWrite = "[" + getTimeStamp() + "] - " + data + " - " + extra + "\n";
FileOutputStream out = new FileOutputStream(logFile, true);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(out);
@ -104,6 +109,8 @@ public class Logger {
Logger.logD("Recorded to " + logFile.getName());
Bugfender.i("IC SCAN", dataToWrite);
MainApplication.getInstance().logICScan(dataToWrite);
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());

16
gradle.properties

@ -20,21 +20,25 @@ android.enableJetifier=true
# Terminal Specific Config
# Echo Socket
SERVER_URL="http://hello-booking-api-build.testpigeon.net"
CLIENT_ID="3"
CLIENT_SECRET="w5RJ7bMF6NH39aDVyJJV0M1gOg0nZQcO2atVcXyF"
ECHO_SERVER_URL="http://hello-booking-api-build.testpigeon.net"
ECHO_SERVER_PORT="6001"
KIOSK_CODE="KIOSK002"
SOCKET_PREFIX="HelloBookingApi_"
PAYMENT_CHANNEL_ID="payment#"
PAYMENT_EVENT_TYPE=".makepayment"
IC_CHANNEL_ID="verification#"
IC_EVENT_TYPE=".guestverification"
BUGFENDER_TOKEN="rocgWcZ0aLZH7s1XqK6PpV3WeyBVb0w0"
# Bugfender
BUGFENDER_TOKEN="rocgWcZ0aLZH7s1XqK6PpV3WeyBVb0w0"
# AWS
AWS_ACCESS_KEY="AKIAXHWEPPPSPOMSLL5R"
AWS_SECRET_KEY="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"
LOG_GROUP_NAME="hotel-kiosk"
Loading…
Cancel
Save