Merge branch 'master' into bug5221

This commit is contained in:
Dennis Aulenbacher committed 2020-07-29 20:10:26 +02:00
commit 1168bc43b0
17 files changed
+49 -27

No files matched your search

@@ -804,7 +804,7 @@ public class SensorFixStoreAndLoadTest {
trackedRace.attachRegattaLog(regattaLog);
trackedRace.waitForLoadingToFinish();
fixLoaderAndTracker.stop(true, /* willBeRemoved */ false);
statusTransitionListener.assertTransitions(TrackedRaceStatusEnum.PREPARED, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.FINISHED);
statusTransitionListener.assertTransitions(TrackedRaceStatusEnum.PREPARED, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.FINISHED);
}
@Test
@@ -820,7 +820,7 @@ public class SensorFixStoreAndLoadTest {
device, new MillisecondsTimePoint(START_OF_TRACKING), new MillisecondsTimePoint(END_OF_TRACKING)));
trackedRace.waitForLoadingToFinish();
fixLoaderAndTracker.stop(true, /* willBeRemoved */ false);
statusTransitionListener.assertTransitions(TrackedRaceStatusEnum.PREPARED, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.FINISHED);
statusTransitionListener.assertTransitions(TrackedRaceStatusEnum.PREPARED, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.FINISHED);
}
@Test
@@ -837,7 +837,7 @@ public class SensorFixStoreAndLoadTest {
trackedRace.setStartOfTrackingReceived(new MillisecondsTimePoint(START_OF_TRACKING));
trackedRace.waitForLoadingToFinish();
fixLoaderAndTracker.stop(true, /* willBeRemoved */ false);
statusTransitionListener.assertTransitions(TrackedRaceStatusEnum.PREPARED, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.FINISHED);
statusTransitionListener.assertTransitions(TrackedRaceStatusEnum.PREPARED, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.FINISHED);
}
@Test
@@ -856,7 +856,7 @@ public class SensorFixStoreAndLoadTest {
trackedRace.setStartOfTrackingReceived(new MillisecondsTimePoint(START_OF_TRACKING));
trackedRace.waitForLoadingToFinish();
fixLoaderAndTracker.stop(true, /* willBeRemoved */ false);
statusTransitionListener.assertTransitions(TrackedRaceStatusEnum.PREPARED, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.FINISHED);
statusTransitionListener.assertTransitions(TrackedRaceStatusEnum.PREPARED, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.FINISHED);
}
private class StatusTransitionListener extends AbstractRaceChangeListener {
@@ -697,11 +697,13 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
}
private void startTracking() {
setStatusAndProgress(TrackedRaceStatusEnum.TRACKING, 0.0);
// start out LOADING; if no mappings are found, the final updateStatusAndProgress() will recognize and switch to TRACKING
setStatusAndProgress(TrackedRaceStatusEnum.LOADING, 0.0);
this.deviceMappings = new FixLoaderDeviceMappings(trackedRace.getAttachedRegattaLogs(),
trackedRace.getRace().getName());
trackedRace.addListener(raceChangeListener);
this.deviceMappings.updateMappings();
updateStatusAndProgress(); // will switch to TRACKING immediately if no loading jobs are running based on the device mappings found
}
private void loadFixesForExtendedTimeRange(final TimeRange extendedTimeRange) {
@@ -261,30 +261,27 @@ public abstract class RegattaLogDeviceMappings<ItemT extends WithID> {
} finally {
LockUtil.unlockAfterWrite(mappingsLock);
}
calculateDiff(oldMappings, newMappings, oldDeviceIds, newDeviceIds);
calculateAndApplyDiff(oldMappings, newMappings, oldDeviceIds, newDeviceIds);
}
/**
* Calculates <em>and applies</em> the mapping changes by removing listeners no longer needed for the mappings removed,
* and by loading and adding the fixes for extended or added mappings.
*/
private void calculateDiff(Map<ItemT, ? extends Iterable<DeviceMappingWithRegattaLogEvent<ItemT>>> previousMappings,
private void calculateAndApplyDiff(Map<ItemT, ? extends Iterable<DeviceMappingWithRegattaLogEvent<ItemT>>> previousMappings,
Map<ItemT, ? extends Iterable<DeviceMappingWithRegattaLogEvent<ItemT>>> newMappings,
Set<DeviceIdentifier> oldDeviceIds, Set<DeviceIdentifier> newDeviceIds) {
final Set<DeviceIdentifier> removedDeviceIds = new HashSet<>(oldDeviceIds);
removedDeviceIds.removeAll(newDeviceIds);
removedDeviceIds.forEach(this::deviceIdRemovedInternal);
final Set<DeviceIdentifier> addedDeviceIds = new HashSet<>(newDeviceIds);
addedDeviceIds.removeAll(oldDeviceIds);
addedDeviceIds.forEach(this::deviceIdAddedInternal);
// Only deviceIdentifier and mappingTypes are covered that are contained in newMappings.
// Those that are only found in oldMappings won't lead to new covered TimeRanges.
// DeviceIdentifiers, that aren't needed at all are already handled above.
newMappings.forEach((item, mappingsForItem) -> {
final Map<RegattaLogDeviceMappingEvent<ItemT>, MultiTimeRange> newlyCoveredTimeRanges = new HashMap<>();
// The mappings are processes grouped by DeviceIdentifier and mapping type
// to build a consistent overall mapping update without the risk of fixes
// to get loaded multiple times
@@ -293,7 +290,6 @@ public abstract class RegattaLogDeviceMappings<ItemT extends WithID> {
newMappingsForDeviceIdAndMappingType) -> {
assert (newMappingsForDeviceIdAndMappingType != null);
assert (!Util.isEmpty(newMappingsForDeviceIdAndMappingType));
final MultiTimeRange newCoveredTimeRanges = getCoveredTimeRange(
newMappingsForDeviceIdAndMappingType)
.subtract(getCoveredTimeRange(oldMappingsForDeviceIdAndMappingType));
@@ -199,8 +199,8 @@ public abstract class NonPerformanceCurveRankingMetric extends AbstractRankingMe
// when "who" has sailed (or is extrapolated) beyond the end of the leg without having received a mark passing.
// In this case we want to assume that it will take "who" approximately that long again to reach back to
// the waypoint to actually pass it; so we use the absolute duration instead.
final Duration toEndOfLegOrTo = getPredictedDurationToEndOfLegOrTo(timePoint, legWho, legWho.getTrackedLeg().getTrackedLeg(to), cache).
abs();
final Duration signedDuration = getPredictedDurationToEndOfLegOrTo(timePoint, legWho, legWho.getTrackedLeg().getTrackedLeg(to), cache);
final Duration toEndOfLegOrTo = signedDuration == null ? null : signedDuration.abs();
if (toEndOfLegOrTo == null) {
result = null;
} else {
@@ -3018,7 +3018,9 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
addListener(new AbstractRaceChangeListener() {
@Override
public void statusChanged(TrackedRaceStatus newStatus, TrackedRaceStatus oldStatus) {
logger.info("race "+this+" went from "+oldStatus+" to "+newStatus);
if (hasFinishedLoading(newStatus.getStatus())) {
logger.info("race "+this+" is considered having finished loading; running "+runnable);
removeListener(this);
runnable.run();
}
@@ -8,6 +8,7 @@
<ul class="bulletList">
<li>Fixed a problem with cross-track error calculations in case no track can be found for a competitor</li>
<li>New menu entries in the header of the SAP Sailing home. Depending on the currently logged in users rights a link to the Administration Console and/or Data Mining is shown.</li>
<li>Fixed an issue with ToT/ToD handicap ranking in case a duration to the end of a leg cannot be computed based on missing data.</li>
</ul>
<h5 class="articleSubheadline">June 2020</h5>
<ul class="bulletList">
@@ -35,7 +35,7 @@ public class FileUploadServlet extends AbstractFileUploadServlet {
/**
* The maximum size of an image uploaded by a user as a team image, in megabytes (1024*1024 bytes)
*/
private static final int MAX_SIZE_IN_MB = 8192;
private static final long MAX_SIZE_IN_MB = 8192;
@Override
protected void process(List<FileItem> fileItems, HttpServletRequest req, HttpServletResponse resp) throws UnsupportedEncodingException, IOException {
@@ -65,7 +65,7 @@ public class FileUploadServlet extends AbstractFileUploadServlet {
}
}
try {
if (fileItem.getSize() > 1024 * 1024 * MAX_SIZE_IN_MB) {
if (fileItem.getSize() > 1024l * 1024l * MAX_SIZE_IN_MB) {
final String errorMessage = "Image is larger than " + MAX_SIZE_IN_MB + "MB";
logger.warning("Ignoring file storage request because file "+fileName+" is larger than "+MAX_SIZE_IN_MB+"MB");
result.put(FileUploadConstants.STATUS, Status.INTERNAL_SERVER_ERROR.name());
@@ -66,6 +66,7 @@
behavior.</li>
<li>Based on user input, the "selected" marker in rows supporting multiple selection now uses
a stronger "SAP Blue" color so that selected rows can be recognized even easier.</li>
<li>Passwords or secret access keys of file storage configuration are no longer displayed after submitting.</li>
</ul>
<h2 class="articleSubheadline">June 2020</h2>
<ul class="bulletList">
@@ -10,6 +10,7 @@ import java.util.Locale;
*/
public interface FileStorageServiceProperty extends Serializable {
boolean isRequired();
boolean isPassword();
String getName();
/**
@@ -49,11 +49,11 @@ public class AmazonS3FileStorageServiceImpl extends BaseFileStorageServiceImpl i
private static final String regionRetrievalHost = "s3-eu-west-1.amazonaws.com";
private final FileStorageServicePropertyImpl accessId = new FileStorageServicePropertyImpl("accessId", false,
"s3AccessIdDesc");
/* isPassword */ false, "s3AccessIdDesc");
private final FileStorageServicePropertyImpl accessKey = new FileStorageServicePropertyImpl("accessKey", false,
"s3AccessKeyDesc");
/* isPassword */ true, "s3AccessKeyDesc");
private final FileStorageServicePropertyImpl bucketName = new FileStorageServicePropertyImpl("bucketName", true,
"s3BucketNameDesc");
/* isPassword */ false, "s3BucketNameDesc");
public AmazonS3FileStorageServiceImpl(BundleContext bundleContext) {
super(NAME, "s3Desc", bundleContext);
@@ -7,14 +7,16 @@ import com.sap.sse.filestorage.FileStorageServiceProperty;
public class FileStorageServicePropertyImpl implements FileStorageServiceProperty {
private static final long serialVersionUID = -8418630141746910125L;
private final boolean isRequired;
private final boolean isPassword;
private final String name;
private final String descriptionKey;
private String value;
public FileStorageServicePropertyImpl(String name, boolean isRequired, String descriptionKey) {
public FileStorageServicePropertyImpl(String name, boolean isRequired, boolean isPassword, String descriptionKey) {
this.name = name;
this.descriptionKey = descriptionKey;
this.isRequired = isRequired;
this.isPassword = isPassword;
}
@Override
@@ -22,6 +24,11 @@ public class FileStorageServicePropertyImpl implements FileStorageServicePropert
return isRequired;
}
@Override
public boolean isPassword() {
return isPassword;
}
@Override
public String getName() {
return name;
@@ -50,8 +50,8 @@ public class LocalFileStorageServiceImpl extends BaseFileStorageServiceImpl impl
private static final Logger logger = Logger.getLogger(LocalFileStorageServiceImpl.class.getName());
private final FileStorageServicePropertyImpl baseURL = new FileStorageServicePropertyImpl("baseURL", true, "localBaseUrlDesc");
private final FileStorageServicePropertyImpl localPath = new FileStorageServicePropertyImpl("localPath", true, "localLocalPathDesc");
private final FileStorageServicePropertyImpl baseURL = new FileStorageServicePropertyImpl("baseURL", true, /* isPassword */ false, "localBaseUrlDesc");
private final FileStorageServicePropertyImpl localPath = new FileStorageServicePropertyImpl("localPath", true, /* isPassword */ false, "localLocalPathDesc");
protected LocalFileStorageServiceImpl(BundleContext bundleContext) {
@@ -16,7 +16,7 @@ import com.sap.sse.filestorage.impl.FileStorageServicePropertyImpl;
public class DummyFileStorageService extends BaseFileStorageServiceImpl implements FileStorageService {
public static final String NAME = "dummy";
public static final String PROPERTY_NAME = "p";
public final FileStorageServicePropertyImpl property = new FileStorageServicePropertyImpl(PROPERTY_NAME, false, "");
public final FileStorageServicePropertyImpl property = new FileStorageServicePropertyImpl(PROPERTY_NAME, false, /* isPassword */ false, "");
private static final long serialVersionUID = -3871744982404841496L;
File mode changed.
@@ -60,6 +60,7 @@ public class FileStoragePanel extends FlowPanel {
private final Map<String, FileStorageServiceDTO> availableServices = new HashMap<>();
private final Map<FileStorageServicePropertyDTO, String> perPropertyErrors = new HashMap<>();
private final ListDataProvider<FileStorageServicePropertyDTO> propertiesListDataProvider;
private final TabbingTextInputCell valueCell;
public FileStoragePanel(FileStorageManagementGwtServiceAsync sailingService, ErrorReporter errorReporter) {
this.sailingService = sailingService;
@@ -90,7 +91,7 @@ public class FileStoragePanel extends FlowPanel {
serviceDescriptionLabel = new Label();
editServicePanelContent.add(serviceDescriptionLabel);
propertiesTable = new BaseCelltable<>();
propertiesTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.DISABLED); //allow for default tabbing behaviour
propertiesTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.DISABLED); // allow for default tabbing behaviour
propertiesListDataProvider = new ListDataProvider<>(new ArrayList<FileStorageServicePropertyDTO>());
properties = propertiesListDataProvider.getList();
propertiesListDataProvider.addDataDisplay(propertiesTable);
@@ -101,8 +102,8 @@ public class FileStoragePanel extends FlowPanel {
}
};
propertiesTable.addColumn(nameColumn, stringMessages.name());
Column<FileStorageServicePropertyDTO, String> inputColumn = new Column<FileStorageServicePropertyDTO, String>(
new TabbingTextInputCell()) {
valueCell = new TabbingTextInputCell();
Column<FileStorageServicePropertyDTO, String> inputColumn = new Column<FileStorageServicePropertyDTO, String>(valueCell) {
@Override
public String getValue(FileStorageServicePropertyDTO object) {
return object.value;
@@ -180,6 +181,14 @@ public class FileStoragePanel extends FlowPanel {
if (callback != null) {
callback.onSuccess(null);
}
// clear all password properties:
for (int i=0; i<properties.size(); i++) {
final FileStorageServicePropertyDTO p = properties.get(i);
if (p.isPassword) {
p.value = null;
valueCell.clearViewData(p);
}
}
propertiesListDataProvider.refresh();
}
@@ -16,7 +16,7 @@ import com.sap.sse.gwt.shared.filestorage.FileStorageServicePropertyErrorsDTO;
public class FileStorageServiceDTOUtils {
public static FileStorageServicePropertyDTO convert(FileStorageServiceProperty p, Locale locale) {
return new FileStorageServicePropertyDTO(p.isRequired(), p.getName(), p.getValue(), p.getDescription(locale));
return new FileStorageServicePropertyDTO(p.isRequired(), p.isPassword(), p.getName(), p.isPassword() ? null : p.getValue(), p.getDescription(locale));
}
public static FileStorageServicePropertyErrorsDTO convert(InvalidPropertiesException e, Locale locale) {
@@ -7,14 +7,17 @@ public class FileStorageServicePropertyDTO implements Serializable {
public boolean isRequired;
public String name;
public String value;
public boolean isPassword;
public String description;
// for GWT
@Deprecated
FileStorageServicePropertyDTO() {
}
public FileStorageServicePropertyDTO(boolean isRequired, String name, String value, String description) {
public FileStorageServicePropertyDTO(boolean isRequired, boolean isPassword, String name, String value, String description) {
this.isRequired = isRequired;
this.isPassword = isPassword;
this.name = name;
this.value = value;
this.description = description;