mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-13 22:15:26 +00:00
Merge branch 'master' into bug4319
This commit is contained in:
commit
55e2d9e718
9 files changed
+106
-33
No files matched your search
@@ -0,0 +1,38 @@
|
||||
// Taken from https://github.com/sirceljm/AWS-SES-simple-mail-forward/blob/master/mail_forward.js
|
||||
// Install as an AWS Lambda according to https://github.com/sirceljm/AWS-SES-simple-mail-forward
|
||||
// and configure the to_address environment variable as a JSON array of strings representing
|
||||
// the recipients' e-mail addresses. Subscribe the lambda to your SNS topic that receives the
|
||||
// notification messages about your inbound e-mail. Use mail_forward_policy.json for the IAM role's
|
||||
// security policy.
|
||||
var AWS = require("aws-sdk");
|
||||
var ses = new AWS.SES();
|
||||
|
||||
exports.handler = (event, context, callback) => {
|
||||
let data = JSON.parse(event.Records[0].Sns.Message);
|
||||
let source = data.content;
|
||||
|
||||
source = source.replace(/^DKIM-Signature/im, "X-Original-DKIM-Signature");
|
||||
// source = source.replace(/^From/im, "X-Original-From");
|
||||
// source = source.replace(/^Source/im, "X-Original-Source");
|
||||
// source = source.replace(/^Sender/im, "X-Original-Sender");
|
||||
// source = source.replace(/^Return-Path/im, "X-Original-Return-Path");
|
||||
source = source.replace(/^Domainkey-Signature/im, "X-Original-Domainkey-Signature");
|
||||
// source = `From: AWS SES Mail Forwarding <${data.mail.destination}>\n` + source;
|
||||
|
||||
if (!process.env.to_address) {
|
||||
console.log("You need to supply to_address enviromnent variable");
|
||||
} else if (data.mail.destination == process.env.to_address) {
|
||||
console.log("MAIL SEND ABORTED! - Forwarded mail address and to_address are the same - THIS CAN CAUSE AN INFINITE LOOP!");
|
||||
} else {
|
||||
ses.sendRawEmail({
|
||||
RawMessage: {
|
||||
Data: source,
|
||||
},
|
||||
Destinations: JSON.parse(process.env.to_address),
|
||||
}, function (err, data) {
|
||||
if (err) {
|
||||
console.error(err, err.stack);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"logs:CreateLogGroup",
|
||||
"logs:CreateLogStream",
|
||||
"logs:PutLogEvents"
|
||||
],
|
||||
"Resource": "arn:aws:logs:*:*:*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"ses:SendEmail",
|
||||
"ses:SendRawEmail"
|
||||
],
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -35,6 +35,7 @@ SAP is at the center of today’s technology revolution, developing innovations
|
||||
* [[Creating an EC2 image from scratch|wiki/info/landscape/creating-ec2-image-from-scratch]]
|
||||
* [[Creating a webserver EC2 image from scratch|wiki/info/landscape/creating-ec2-image-for-webserver-from-scratch]]
|
||||
* [[EC2 mail relaying vs. Amazon Simple E-Mail Service (SES)|wiki/info/landscape/mail-relaying]]
|
||||
* [[Establishing support@sapsailing.com with AWS SES, SNS, and Lambda|wiki/info/landscape/support-email]]
|
||||
* [[Creating an EC2 image for a MongoDB Replica Set from scratch|wiki/info/landscape/creating-ec2-mongodb-image-from-scratch]]
|
||||
* [[Setting up dedicated S3 buckets|wiki/info/landscape/s3-bucket-setup]]
|
||||
* [[Building and Deploying|wiki/info/landscape/building-and-deploying]]
|
||||
|
||||
+1
-1
@@ -1567,7 +1567,7 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
final TimePoint timePoint;
|
||||
// normalize the time point to get cache hits when asking for time points that are later than
|
||||
// the last time point affected by any event received for this tracked race
|
||||
if (Util.compareToWithNull(unadjustedTimePoint, getTimePointOfNewestEvent(), /* nullIsLess */ true) <= 0) {
|
||||
if (Util.compareToWithNull(unadjustedTimePoint, getTimePointOfNewestEvent(), /* nullIsLess */ false) <= 0) {
|
||||
timePoint = unadjustedTimePoint;
|
||||
} else {
|
||||
timePoint = getTimePointOfNewestEvent();
|
||||
|
||||
+1
@@ -133,6 +133,7 @@ public class LeaderboardConfigurationPanelPO extends PageArea {
|
||||
}
|
||||
|
||||
public LeaderboardDetailsPanelPO getLeaderboardDetails(String leaderboard) {
|
||||
waitForAjaxRequests();
|
||||
LeaderboardEntryPO entry = findLeaderboard(leaderboard);
|
||||
if (entry == null) {
|
||||
return null;
|
||||
|
||||
+2
-2
@@ -35,7 +35,7 @@ public class CompetitorAndBoatJsonSerializer implements JsonSerializer<Pair<Comp
|
||||
@Override
|
||||
public JSONObject serialize(Pair<Competitor, Boat> competitorAndBoat) {
|
||||
final JSONObject result;
|
||||
JSONObject serializedCompetitor = competitorJsonSerializer.serialize(competitorAndBoat.getA());
|
||||
final JSONObject serializedCompetitor = competitorJsonSerializer.serialize(competitorAndBoat.getA());
|
||||
// for compatibility, write a CompetitorWithBoat in the same format that a Competitor use to be
|
||||
// serialized; only if the competitor has no boat, use the new format. The de-serializer will be
|
||||
// able to distinguish based on the presence of the top-level FIELD_COMPETITOR field.
|
||||
@@ -56,7 +56,7 @@ public class CompetitorAndBoatJsonSerializer implements JsonSerializer<Pair<Comp
|
||||
if (compatibilityMode) {
|
||||
result = serializedCompetitor;
|
||||
} else {
|
||||
JSONObject serializedBoat = boatJsonSerializer.serialize(competitorAndBoat.getB());
|
||||
final JSONObject serializedBoat = competitorAndBoat.getB() == null ? null : boatJsonSerializer.serialize(competitorAndBoat.getB());
|
||||
result = new JSONObject();
|
||||
result.put(FIELD_COMPETITOR, serializedCompetitor);
|
||||
result.put(FIELD_BOAT, serializedBoat);
|
||||
|
||||
+19
-19
@@ -4,6 +4,17 @@ import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.KilometersPerHourSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
import slash.common.type.CompactCalendar;
|
||||
import slash.navigation.base.BaseNavigationPosition;
|
||||
import slash.navigation.base.NavigationFormat;
|
||||
@@ -83,17 +94,6 @@ import slash.navigation.wbt.WintecWbt201Tk1Format;
|
||||
import slash.navigation.wbt.WintecWbt201Tk2Format;
|
||||
import slash.navigation.zip.ZipFormat;
|
||||
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
/**
|
||||
* Only supports such navigation formats for which RouteConverter implements own parser.
|
||||
* Other formats are supported by RouteConverter via GPSBabel, for which there is a licensing
|
||||
@@ -202,18 +202,18 @@ public class RouteConverterGPSFixImporterImpl extends BaseRouteConverterGPSFixIm
|
||||
if (position instanceof Wgs84Position) {
|
||||
heading = ((Wgs84Position) position).getHeading();
|
||||
}
|
||||
Double speed = position.getSpeed();
|
||||
|
||||
final Double speedInKilometersPerHour = position.getSpeed();
|
||||
Position pos = new DegreePosition(position.getLatitude(), position.getLongitude());
|
||||
TimePoint timePoint = new MillisecondsTimePoint(t);
|
||||
|
||||
if (speed != null && heading != null) {
|
||||
SpeedWithBearing speedWithBearing = new KnotSpeedWithBearingImpl(
|
||||
speed, new DegreeBearingImpl(heading));
|
||||
return new GPSFixMovingImpl(pos, timePoint, speedWithBearing);
|
||||
final GPSFix result;
|
||||
if (speedInKilometersPerHour != null && heading != null) {
|
||||
SpeedWithBearing speedWithBearing = new KilometersPerHourSpeedWithBearingImpl(
|
||||
speedInKilometersPerHour, new DegreeBearingImpl(heading));
|
||||
result = new GPSFixMovingImpl(pos, timePoint, speedWithBearing);
|
||||
} else {
|
||||
return new GPSFixImpl(pos, timePoint);
|
||||
result = new GPSFixImpl(pos, timePoint);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
@Override
|
||||
|
||||
+7
-11
@@ -27,13 +27,12 @@ public class TimeUtils {
|
||||
/**
|
||||
* Formats your time to 'kk:mm:ss'.
|
||||
*
|
||||
* @param timePoint
|
||||
* timestamp to format
|
||||
* @param timePoint timestamp to format
|
||||
*/
|
||||
public static String formatTime(TimePoint timePoint, boolean includeSeconds) {
|
||||
if (includeSeconds) {
|
||||
return formatTime(timePoint, "kk:mm:ss");
|
||||
}else{
|
||||
} else {
|
||||
return formatTime(timePoint, "kk:mm");
|
||||
}
|
||||
}
|
||||
@@ -41,8 +40,7 @@ public class TimeUtils {
|
||||
/**
|
||||
* Formats your time to 'kk:mm:ss'.
|
||||
*
|
||||
* @param timePoint
|
||||
* timestamp to format
|
||||
* @param timePoint timestamp to format
|
||||
*/
|
||||
public static String formatTime(TimePoint timePoint) {
|
||||
return formatTime(timePoint, true);
|
||||
@@ -51,10 +49,8 @@ public class TimeUtils {
|
||||
/**
|
||||
* Formats your time with the help of {@link DateFormat}.
|
||||
*
|
||||
* @param timePoint
|
||||
* timestamp to format
|
||||
* @param format
|
||||
* format as defined by {@link DateFormat}
|
||||
* @param timePoint timestamp to format
|
||||
* @param format format as defined by {@link DateFormat}
|
||||
* @return timestamp formatted as {@link String}
|
||||
*/
|
||||
public static String formatTime(TimePoint timePoint, String format) {
|
||||
@@ -168,12 +164,12 @@ public class TimeUtils {
|
||||
}
|
||||
|
||||
public static void initDatePicker(Context context, NumberPicker datePicker, Calendar time, int pastDays,
|
||||
int futureDays) {
|
||||
int futureDays) {
|
||||
initDatePicker(context, datePicker, time, pastDays, futureDays, true);
|
||||
}
|
||||
|
||||
public static void initDatePicker(Context context, NumberPicker datePicker, Calendar time, int pastDays,
|
||||
int futureDays, boolean useWords) {
|
||||
int futureDays, boolean useWords) {
|
||||
java.text.DateFormat dateFormat = java.text.DateFormat.getDateInstance();
|
||||
ArrayList<String> dates = new ArrayList<>();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# Set Up of Support E Mail Address support@sapsailing.com with AWS SES/SNS/Lambda
|
||||
|
||||
We use AWS SES for all e-mail services, inbound and outbound. See also [Amazon Simple Email Service (SES) Set-Up](wiki/info/landscape/mail-relaying) for details on the general SES set-up. We have established ``support@sapsailing.com`` now as another inbound e-mail address that forwards to an SNS topic named ``Support-Mail``.
|
||||
|
||||
The messages forwarded from SES to SNS are JSON-formatted wrappers around the original e-mail message augmented with various meta-data. Forwarding these messages with a straight SNS subscription of type EMAIL results in human-unreadable e-mails in JSON format with all the metadata included.
|
||||
|
||||
Instead, we subscribe a Lambda function on the ``Support-Mail`` SNS topic that parses the original message from the JSON document and re-sends it through SES to a list of recipients that can be configured in the ``to_address`` environment variable used by the Lambda. The ``to_address`` environment variable needs to be a valid JSON array that contains the recipients' e-mail addresses as string objects.
|
||||
|
||||
The role that is created to execute the Lambda needs to have a policy set that can access SES and write logs. See also https://github.com/sirceljm/AWS-SES-simple-mail-forward/blob/master/mail_forward_policy.json.
|
||||
|
||||
The relevant files have been committed to our git as ``configuration/mail_forward.js`` for the Lambda's code, and as ``configuration/mail_forward_policy.json`` for the security policy for the IAM role used for the Lambda.
|
||||
|
||||
## Changing the List of Recipients
|
||||
|
||||
Go to [https://eu-west-1.console.aws.amazon.com/lambda/home?region=eu-west-1#/functions/email-forward?tab=configuration](https://eu-west-1.console.aws.amazon.com/lambda/home?region=eu-west-1#/functions/email-forward?tab=configuration) and edit the ``to_address`` environment variable accordingly.
|
||||
Reference in new issue
Block a user