Issue #2000 Subscription duplication/overlap detection
Change-Id: If43818e854e69ab756f4e96a05fce664e28262a5 Former-commit-id:fdf3ac7897
[formerly 95df3d38914f451471f10d6095ad2bc6badbab72] Former-commit-id:db2e3cd9bb
This commit is contained in:
parent
7683bfd122
commit
3447a3726b
22 changed files with 1677 additions and 91 deletions
|
@ -22,6 +22,7 @@
|
||||||
<constructor-arg ref="subscriptionNotificationService" />
|
<constructor-arg ref="subscriptionNotificationService" />
|
||||||
<constructor-arg ref="bandwidthService" />
|
<constructor-arg ref="bandwidthService" />
|
||||||
<constructor-arg ref="permissionsService" />
|
<constructor-arg ref="permissionsService" />
|
||||||
|
<constructor-arg ref="subscriptionOverlapService" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean name="dataDeliveryServices"
|
<bean name="dataDeliveryServices"
|
||||||
|
|
|
@ -116,6 +116,7 @@ import com.raytheon.viz.ui.presenter.IDisplay;
|
||||||
* remove race condition of GUI thread updating the table after notification.
|
* remove race condition of GUI thread updating the table after notification.
|
||||||
* Jan 22, 2013 1520 mpduff Removed menu accelerators.
|
* Jan 22, 2013 1520 mpduff Removed menu accelerators.
|
||||||
* Mar 29, 2013 1841 djohnson Subscription implementations now provide a copy method.
|
* Mar 29, 2013 1841 djohnson Subscription implementations now provide a copy method.
|
||||||
|
* May 29, 2013 2000 djohnson Copy subscription now requires editing first to prevent duplicates, and remove duplicate code.
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author mpduff
|
* @author mpduff
|
||||||
|
@ -680,31 +681,12 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements
|
||||||
* Handle the copy action.
|
* Handle the copy action.
|
||||||
*/
|
*/
|
||||||
private void handleCopy() {
|
private void handleCopy() {
|
||||||
if (tableComp.getTable().getSelectionCount() == 0) {
|
if (!tableComp.verifySingleRowSelected()) {
|
||||||
DataDeliveryUtils.showMessage(shell, SWT.ERROR, "No Rows Selected",
|
|
||||||
"Please select a row to Copy");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tableComp.getTable().getSelectionCount() > 1) {
|
|
||||||
int choice = DataDeliveryUtils
|
|
||||||
.showMessage(
|
|
||||||
shell,
|
|
||||||
SWT.ERROR | SWT.YES | SWT.NO,
|
|
||||||
"Single Selection Only",
|
|
||||||
"Multiple subscriptions are selected.\n"
|
|
||||||
+ "Only the first selected item will be copied.\n\n"
|
|
||||||
+ "Continue with Copy?");
|
|
||||||
if (choice == SWT.NO) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the subscription data
|
// Get the subscription data
|
||||||
int idx = tableComp.getTable().getSelectionIndices()[0];
|
Subscription sub = tableComp.getSelectedSubscription();
|
||||||
SubscriptionManagerRowData row = tableComp.getSubscriptionData()
|
|
||||||
.getDataRow(idx);
|
|
||||||
Subscription sub = row.getSubscription();
|
|
||||||
|
|
||||||
FileNameDlg fnd = new FileNameDlg(getShell(), sub.getName());
|
FileNameDlg fnd = new FileNameDlg(getShell(), sub.getName());
|
||||||
String newName = (String) fnd.open();
|
String newName = (String) fnd.open();
|
||||||
|
@ -713,17 +695,8 @@ public class SubscriptionManagerDlg extends CaveSWTDialog implements
|
||||||
&& !newName.equals(sub.getName())) {
|
&& !newName.equals(sub.getName())) {
|
||||||
Subscription newSub = sub.copy(newName);
|
Subscription newSub = sub.copy(newName);
|
||||||
|
|
||||||
// Object is copied, now store it
|
// Object is copied, now bring up the edit screen with the copy
|
||||||
try {
|
tableComp.editSubscription(newSub);
|
||||||
DataDeliveryServices.getSubscriptionService().store(
|
|
||||||
newSub,
|
|
||||||
new CancelForceApplyAndIncreaseLatencyDisplayText(
|
|
||||||
"create", getShell()));
|
|
||||||
handleRefresh();
|
|
||||||
} catch (RegistryHandlerException e) {
|
|
||||||
statusHandler.handle(Priority.PROBLEM,
|
|
||||||
"Error saving subscription data to the registry.", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ package com.raytheon.uf.viz.datadelivery.subscription;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -30,9 +31,11 @@ import java.util.TimeZone;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.widgets.Shell;
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.raytheon.uf.common.auth.user.IUser;
|
import com.raytheon.uf.common.auth.user.IUser;
|
||||||
import com.raytheon.uf.common.datadelivery.bandwidth.IBandwidthService;
|
import com.raytheon.uf.common.datadelivery.bandwidth.IBandwidthService;
|
||||||
import com.raytheon.uf.common.datadelivery.bandwidth.IProposeScheduleResponse;
|
import com.raytheon.uf.common.datadelivery.bandwidth.IProposeScheduleResponse;
|
||||||
|
@ -44,6 +47,8 @@ import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandler
|
||||||
import com.raytheon.uf.common.datadelivery.registry.handlers.IPendingSubscriptionHandler;
|
import com.raytheon.uf.common.datadelivery.registry.handlers.IPendingSubscriptionHandler;
|
||||||
import com.raytheon.uf.common.datadelivery.registry.handlers.ISubscriptionHandler;
|
import com.raytheon.uf.common.datadelivery.registry.handlers.ISubscriptionHandler;
|
||||||
import com.raytheon.uf.common.datadelivery.service.ISubscriptionNotificationService;
|
import com.raytheon.uf.common.datadelivery.service.ISubscriptionNotificationService;
|
||||||
|
import com.raytheon.uf.common.datadelivery.service.subscription.ISubscriptionOverlapService;
|
||||||
|
import com.raytheon.uf.common.datadelivery.service.subscription.ISubscriptionOverlapService.ISubscriptionOverlapResponse;
|
||||||
import com.raytheon.uf.common.registry.handler.RegistryHandlerException;
|
import com.raytheon.uf.common.registry.handler.RegistryHandlerException;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
@ -73,6 +78,7 @@ import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils;
|
||||||
* Jan 04, 2013 1441 djohnson Separated out notification methods into their own service.
|
* Jan 04, 2013 1441 djohnson Separated out notification methods into their own service.
|
||||||
* Jan 28, 2013 1530 djohnson Reset unscheduled flag with each update.
|
* Jan 28, 2013 1530 djohnson Reset unscheduled flag with each update.
|
||||||
* Mar 29, 2013 1841 djohnson Subscription is now UserSubscription.
|
* Mar 29, 2013 1841 djohnson Subscription is now UserSubscription.
|
||||||
|
* May 14, 2013 2000 djohnson Check for subscription overlap/duplication.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -120,6 +126,22 @@ public class SubscriptionService implements ISubscriptionService {
|
||||||
return forceApplyPromptResponse;
|
return forceApplyPromptResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void displayMessage(
|
||||||
|
IForceApplyPromptDisplayText displayTextStrategy,
|
||||||
|
final String message) {
|
||||||
|
final Shell shell = displayTextStrategy.getShell();
|
||||||
|
shell.getDisplay().syncExec(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
DataDeliveryUtils.showMessage(shell, SWT.OK,
|
||||||
|
"Shared Subscription", message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final IUFStatusHandler statusHandler = UFStatus
|
private final IUFStatusHandler statusHandler = UFStatus
|
||||||
|
@ -136,6 +158,8 @@ public class SubscriptionService implements ISubscriptionService {
|
||||||
|
|
||||||
private final IDisplayForceApplyPrompt forceApplyPrompt;
|
private final IDisplayForceApplyPrompt forceApplyPrompt;
|
||||||
|
|
||||||
|
private final ISubscriptionOverlapService subscriptionOverlapService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link ISubscriptionServiceResult}.
|
* Implementation of {@link ISubscriptionServiceResult}.
|
||||||
*/
|
*/
|
||||||
|
@ -248,6 +272,15 @@ public class SubscriptionService implements ISubscriptionService {
|
||||||
Set<String> wouldBeUnscheduledSubscriptions);
|
Set<String> wouldBeUnscheduledSubscriptions);
|
||||||
|
|
||||||
ForceApplyPromptResponse getForceApplyPromptResponse();
|
ForceApplyPromptResponse getForceApplyPromptResponse();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a popup message to the user.
|
||||||
|
*
|
||||||
|
* @param displayTextStrategy
|
||||||
|
* @param message
|
||||||
|
*/
|
||||||
|
void displayMessage(IForceApplyPromptDisplayText displayTextStrategy,
|
||||||
|
String message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -291,15 +324,18 @@ public class SubscriptionService implements ISubscriptionService {
|
||||||
* the subscription notification service
|
* the subscription notification service
|
||||||
* @param bandwidthService
|
* @param bandwidthService
|
||||||
* the bandwidth service
|
* the bandwidth service
|
||||||
|
* @param subscriptionOverlapService
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
SubscriptionService(ISubscriptionNotificationService notificationService,
|
SubscriptionService(ISubscriptionNotificationService notificationService,
|
||||||
IBandwidthService bandwidthService,
|
IBandwidthService bandwidthService,
|
||||||
IPermissionsService permissionsService,
|
IPermissionsService permissionsService,
|
||||||
|
ISubscriptionOverlapService subscriptionOverlapService,
|
||||||
IDisplayForceApplyPrompt displayForceApplyPrompt) {
|
IDisplayForceApplyPrompt displayForceApplyPrompt) {
|
||||||
this.notificationService = notificationService;
|
this.notificationService = notificationService;
|
||||||
this.bandwidthService = bandwidthService;
|
this.bandwidthService = bandwidthService;
|
||||||
this.permissionsService = permissionsService;
|
this.permissionsService = permissionsService;
|
||||||
|
this.subscriptionOverlapService = subscriptionOverlapService;
|
||||||
this.forceApplyPrompt = displayForceApplyPrompt;
|
this.forceApplyPrompt = displayForceApplyPrompt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,16 +345,19 @@ public class SubscriptionService implements ISubscriptionService {
|
||||||
* tying specifically to the implementation class.
|
* tying specifically to the implementation class.
|
||||||
*
|
*
|
||||||
* @param notificationService
|
* @param notificationService
|
||||||
* @param permissionsService
|
|
||||||
* @param bandwidthService
|
* @param bandwidthService
|
||||||
|
* @param permissionsService
|
||||||
|
* @param
|
||||||
* @return the subscription service
|
* @return the subscription service
|
||||||
*/
|
*/
|
||||||
public static ISubscriptionService newInstance(
|
public static ISubscriptionService newInstance(
|
||||||
ISubscriptionNotificationService notificationService,
|
ISubscriptionNotificationService notificationService,
|
||||||
IBandwidthService bandwidthService,
|
IBandwidthService bandwidthService,
|
||||||
IPermissionsService permissionsService) {
|
IPermissionsService permissionsService,
|
||||||
|
ISubscriptionOverlapService subscriptionOverlapService) {
|
||||||
return new SubscriptionService(notificationService, bandwidthService,
|
return new SubscriptionService(notificationService, bandwidthService,
|
||||||
permissionsService, new DisplayForceApplyPrompt());
|
permissionsService, subscriptionOverlapService,
|
||||||
|
new DisplayForceApplyPrompt());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -546,6 +585,39 @@ public class SubscriptionService implements ISubscriptionService {
|
||||||
final IForceApplyPromptDisplayText displayTextStrategy)
|
final IForceApplyPromptDisplayText displayTextStrategy)
|
||||||
throws RegistryHandlerException {
|
throws RegistryHandlerException {
|
||||||
|
|
||||||
|
for (Subscription subscription : subscriptions) {
|
||||||
|
final ISubscriptionHandler subscriptionHandler = DataDeliveryHandlers
|
||||||
|
.getSubscriptionHandler();
|
||||||
|
final List<Subscription> potentialDuplicates = subscriptionHandler
|
||||||
|
.getActiveByDataSetAndProvider(
|
||||||
|
subscription.getDataSetName(),
|
||||||
|
subscription.getProvider());
|
||||||
|
List<String> overlappingSubscriptions = Lists.newArrayList();
|
||||||
|
for (Subscription potentialDuplicate : potentialDuplicates) {
|
||||||
|
final ISubscriptionOverlapResponse overlapResponse = subscriptionOverlapService
|
||||||
|
.isOverlapping(potentialDuplicate, subscription);
|
||||||
|
final String potentialDuplicateName = potentialDuplicate
|
||||||
|
.getName();
|
||||||
|
if (overlapResponse.isDuplicate()) {
|
||||||
|
return new SubscriptionServiceResult(true,
|
||||||
|
"This subscription would be an exact duplicate of "
|
||||||
|
+ potentialDuplicateName);
|
||||||
|
}
|
||||||
|
if (overlapResponse.isOverlapping()) {
|
||||||
|
overlappingSubscriptions.add(potentialDuplicateName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!overlappingSubscriptions.isEmpty()) {
|
||||||
|
Collections.sort(overlappingSubscriptions);
|
||||||
|
forceApplyPrompt.displayMessage(
|
||||||
|
displayTextStrategy,
|
||||||
|
StringUtil
|
||||||
|
.createMessage(
|
||||||
|
ISubscriptionOverlapService.OVERLAPPING_SUBSCRIPTIONS,
|
||||||
|
overlappingSubscriptions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final ProposeResult result = proposeScheduleAndAction(
|
final ProposeResult result = proposeScheduleAndAction(
|
||||||
subscriptions, action);
|
subscriptions, action);
|
||||||
|
|
|
@ -99,6 +99,7 @@ import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils.TABLE_TYPE;
|
||||||
* Jan 07, 2013 1437 bgonzale Added sort column direction updates.
|
* Jan 07, 2013 1437 bgonzale Added sort column direction updates.
|
||||||
* Jan 28, 2013 1529 djohnson Disable menu items if no subscriptions are selected.
|
* Jan 28, 2013 1529 djohnson Disable menu items if no subscriptions are selected.
|
||||||
* Apr 08, 2013 1826 djohnson Remove delivery options, move column value parsing to the columns themselves.
|
* Apr 08, 2013 1826 djohnson Remove delivery options, move column value parsing to the columns themselves.
|
||||||
|
* May 29, 2013 2000 djohnson Consolidate and remove duplicate code.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -197,26 +198,21 @@ public class SubscriptionTableComp extends TableComp implements IGroupAction {
|
||||||
* Handle subscription editing.
|
* Handle subscription editing.
|
||||||
*/
|
*/
|
||||||
public void handleEdit() {
|
public void handleEdit() {
|
||||||
if (table.getSelectionCount() == 0) {
|
if (!verifySingleRowSelected()) {
|
||||||
DataDeliveryUtils.showMessage(this.getShell(), SWT.ERROR,
|
|
||||||
"No Rows Selected", "Please select a row to Edit");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.getSelectionCount() > 1) {
|
editSubscription(getSelectedSubscription());
|
||||||
int choice = DataDeliveryUtils
|
|
||||||
.showMessage(
|
|
||||||
this.getShell(),
|
|
||||||
SWT.ERROR | SWT.YES | SWT.NO,
|
|
||||||
"Single Selection Only",
|
|
||||||
"Multiple subscriptions are selected.\n"
|
|
||||||
+ "Only the first selected item will be edited.\n\n"
|
|
||||||
+ "Continue with Edit?");
|
|
||||||
if (choice == SWT.NO) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bring up the edit screen with the given subscription. The user
|
||||||
|
* permissions will be verified prior to launching the dialog.
|
||||||
|
*
|
||||||
|
* @param subscription
|
||||||
|
* the subscription
|
||||||
|
*/
|
||||||
|
public void editSubscription(Subscription subscription) {
|
||||||
final DataDeliveryPermission permission = DataDeliveryPermission.SUBSCRIPTION_CREATE;
|
final DataDeliveryPermission permission = DataDeliveryPermission.SUBSCRIPTION_CREATE;
|
||||||
IUser user = UserController.getUserObject();
|
IUser user = UserController.getUserObject();
|
||||||
String msg = user.uniqueId()
|
String msg = user.uniqueId()
|
||||||
|
@ -226,12 +222,8 @@ public class SubscriptionTableComp extends TableComp implements IGroupAction {
|
||||||
try {
|
try {
|
||||||
if (DataDeliveryServices.getPermissionsService()
|
if (DataDeliveryServices.getPermissionsService()
|
||||||
.checkPermissions(user, msg, permission).isAuthorized()) {
|
.checkPermissions(user, msg, permission).isAuthorized()) {
|
||||||
// Get the subscription data
|
|
||||||
int idx = table.getSelectionIndex();
|
|
||||||
SubscriptionManagerRowData row = subManagerData.getDataRow(idx);
|
|
||||||
SubsetManagerDlg<?, ?, ?> dlg = SubsetManagerDlg
|
SubsetManagerDlg<?, ?, ?> dlg = SubsetManagerDlg
|
||||||
.fromSubscription(this.getShell(), true,
|
.fromSubscription(this.getShell(), true, subscription);
|
||||||
row.getSubscription());
|
|
||||||
|
|
||||||
dlg.open();
|
dlg.open();
|
||||||
}
|
}
|
||||||
|
@ -242,15 +234,15 @@ public class SubscriptionTableComp extends TableComp implements IGroupAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the Add To Group dialog.
|
* Verifies a single row is selected.
|
||||||
|
*
|
||||||
|
* @return true if a single row is selected
|
||||||
*/
|
*/
|
||||||
private void handleGroupAdd() {
|
public boolean verifySingleRowSelected() {
|
||||||
|
|
||||||
// Ensure a row is selected
|
|
||||||
if (table.getSelectionCount() == 0) {
|
if (table.getSelectionCount() == 0) {
|
||||||
DataDeliveryUtils.showMessage(this.getShell(), SWT.ERROR,
|
DataDeliveryUtils.showMessage(this.getShell(), SWT.ERROR,
|
||||||
"No Rows Selected", "Please select a row to Edit");
|
"No Rows Selected", "Please select a row.");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table.getSelectionCount() > 1) {
|
if (table.getSelectionCount() > 1) {
|
||||||
|
@ -260,11 +252,21 @@ public class SubscriptionTableComp extends TableComp implements IGroupAction {
|
||||||
SWT.ERROR | SWT.YES | SWT.NO,
|
SWT.ERROR | SWT.YES | SWT.NO,
|
||||||
"Single Selection Only",
|
"Single Selection Only",
|
||||||
"Multiple subscriptions are selected.\n"
|
"Multiple subscriptions are selected.\n"
|
||||||
+ "Only the first selected item will be edited.\n\n"
|
+ "Only the first selected item will be used.\n\n"
|
||||||
+ "Continue with Edit?");
|
+ "Continue?");
|
||||||
if (choice == SWT.NO) {
|
return choice != SWT.NO;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the Add To Group dialog.
|
||||||
|
*/
|
||||||
|
private void handleGroupAdd() {
|
||||||
|
|
||||||
|
if (!verifySingleRowSelected()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check permissions
|
// Check permissions
|
||||||
|
@ -277,11 +279,9 @@ public class SubscriptionTableComp extends TableComp implements IGroupAction {
|
||||||
try {
|
try {
|
||||||
if (DataDeliveryServices.getPermissionsService()
|
if (DataDeliveryServices.getPermissionsService()
|
||||||
.checkPermissions(user, msg, permission).isAuthorized()) {
|
.checkPermissions(user, msg, permission).isAuthorized()) {
|
||||||
// Get the subscription data
|
|
||||||
int idx = table.getSelectionIndex();
|
|
||||||
SubscriptionManagerRowData row = subManagerData.getDataRow(idx);
|
|
||||||
GroupAddDlg groupAdd = new GroupAddDlg(this.getShell(),
|
GroupAddDlg groupAdd = new GroupAddDlg(this.getShell(),
|
||||||
row.getSubscription(), this);
|
getSelectedSubscription(), this);
|
||||||
groupAdd.open();
|
groupAdd.open();
|
||||||
}
|
}
|
||||||
} catch (VizException e) {
|
} catch (VizException e) {
|
||||||
|
@ -827,4 +827,16 @@ public class SubscriptionTableComp extends TableComp implements IGroupAction {
|
||||||
public void setSubscriptionNameList(List<String> subscriptionNameList) {
|
public void setSubscriptionNameList(List<String> subscriptionNameList) {
|
||||||
this.subscriptionNameList = subscriptionNameList;
|
this.subscriptionNameList = subscriptionNameList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the selected subscription.
|
||||||
|
*
|
||||||
|
* @return the subscription
|
||||||
|
*/
|
||||||
|
public Subscription getSelectedSubscription() {
|
||||||
|
int idx = this.getTable().getSelectionIndices()[0];
|
||||||
|
SubscriptionManagerRowData row = this.getSubscriptionData().getDataRow(
|
||||||
|
idx);
|
||||||
|
return row.getSubscription();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,15 @@ Require-Bundle:
|
||||||
com.raytheon.uf.common.status;bundle-version="1.12.1174",
|
com.raytheon.uf.common.status;bundle-version="1.12.1174",
|
||||||
com.raytheon.uf.common.datadelivery.request;bundle-version="1.0.0",
|
com.raytheon.uf.common.datadelivery.request;bundle-version="1.0.0",
|
||||||
com.raytheon.uf.common.registry.ebxml;bundle-version="1.0.0",
|
com.raytheon.uf.common.registry.ebxml;bundle-version="1.0.0",
|
||||||
com.raytheon.uf.common.auth;bundle-version="1.12.1174"
|
com.raytheon.uf.common.auth;bundle-version="1.12.1174",
|
||||||
|
org.geotools;bundle-version="2.6.4",
|
||||||
|
com.raytheon.uf.common.util;bundle-version="1.12.1174",
|
||||||
|
org.springframework;bundle-version="2.5.6",
|
||||||
|
com.raytheon.uf.common.localization;bundle-version="1.12.1174",
|
||||||
|
com.google.guava;bundle-version="1.0.0",
|
||||||
|
com.raytheon.uf.common.geospatial;bundle-version="1.12.1174"
|
||||||
Export-Package:
|
Export-Package:
|
||||||
com.raytheon.uf.common.datadelivery.service
|
com.raytheon.uf.common.datadelivery.service,
|
||||||
|
com.raytheon.uf.common.datadelivery.service.subscription
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,4 +7,10 @@
|
||||||
<bean id="subscriptionNotificationService"
|
<bean id="subscriptionNotificationService"
|
||||||
class="com.raytheon.uf.common.datadelivery.service.SendToServerSubscriptionNotificationService" />
|
class="com.raytheon.uf.common.datadelivery.service.SendToServerSubscriptionNotificationService" />
|
||||||
|
|
||||||
|
<bean id="subscriptionDuplicateChecker" class="com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionDuplicateChecker" />
|
||||||
|
|
||||||
|
<bean id="subscriptionOverlapService" class="com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapService">
|
||||||
|
<constructor-arg ref="subscriptionDuplicateChecker" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
|
@ -0,0 +1,85 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.datadelivery.service.subscription;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.Subscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for duplication among subscriptions.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* May 02, 2013 2000 djohnson Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author djohnson
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface ISubscriptionDuplicateChecker {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the percent, 0-100, of how many parameters from sub2 are
|
||||||
|
* satisfied by sub1.
|
||||||
|
*
|
||||||
|
* @param sub1
|
||||||
|
* @param sub2
|
||||||
|
*
|
||||||
|
* @return 0-100
|
||||||
|
*/
|
||||||
|
int getParameterDuplicationPercent(Subscription sub1, Subscription sub2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the percent, 0-100, of how many forecast hours from sub2 are
|
||||||
|
* satisfied by sub1.
|
||||||
|
*
|
||||||
|
* @param sub1
|
||||||
|
* @param sub2
|
||||||
|
*
|
||||||
|
* @return 0-100
|
||||||
|
*/
|
||||||
|
int getForecastHourDuplicationPercent(Subscription sub1, Subscription sub2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the percent, 0-100, of how many cycle hours from sub2 are
|
||||||
|
* satisfied by sub1.
|
||||||
|
*
|
||||||
|
* @param sub1
|
||||||
|
* @param sub2
|
||||||
|
*
|
||||||
|
* @return 0-100
|
||||||
|
*/
|
||||||
|
int getCycleDuplicationPercent(Subscription sub2, Subscription sub1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the percent, 0-100, of how much spatial coverage from sub2 is
|
||||||
|
* satisfied by sub1.
|
||||||
|
*
|
||||||
|
* @param sub1
|
||||||
|
* @param sub2
|
||||||
|
*
|
||||||
|
* @return 0-100
|
||||||
|
*/
|
||||||
|
int getSpatialDuplicationPercent(Subscription sub1, Subscription sub2);
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.datadelivery.service.subscription;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.Subscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks subscriptions to see if they would be considered duplicates.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* May 09, 2013 2000 djohnson Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author djohnson
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface ISubscriptionOverlapService {
|
||||||
|
|
||||||
|
int ONE_HUNDRED_PERCENT = 100;
|
||||||
|
|
||||||
|
String OVERLAPPING_SUBSCRIPTIONS = "The following subscriptions overlap with this one "
|
||||||
|
+ "and are candidates for a shared subscription: ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response interface for a subscription overlap check.
|
||||||
|
*/
|
||||||
|
public static interface ISubscriptionOverlapResponse {
|
||||||
|
/**
|
||||||
|
* Check whether the two subscriptions were exact duplicates.
|
||||||
|
*
|
||||||
|
* @return true if the subscriptions are duplicates
|
||||||
|
*/
|
||||||
|
boolean isDuplicate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the two subscriptions were determined to overlap.
|
||||||
|
*
|
||||||
|
* @return true if the subscriptions should be considered as overlapping
|
||||||
|
* according to the configuration
|
||||||
|
*/
|
||||||
|
boolean isOverlapping();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether sub2 exceeds configured overlap criteria to sub1
|
||||||
|
* according to the configuration.
|
||||||
|
*
|
||||||
|
* @param sub1
|
||||||
|
* @param sub2
|
||||||
|
*
|
||||||
|
* @return the overlap check response
|
||||||
|
*/
|
||||||
|
ISubscriptionOverlapResponse isOverlapping(Subscription sub1,
|
||||||
|
Subscription sub2);
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.datadelivery.service.subscription;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.geotools.geometry.jts.ReferencedEnvelope;
|
||||||
|
import org.opengis.referencing.operation.TransformException;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.Coverage;
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.Subscription;
|
||||||
|
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||||
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
import com.raytheon.uf.common.util.CollectionUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for duplication among subscriptions.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* May 02, 2013 2000 djohnson Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author djohnson
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class SubscriptionDuplicateChecker implements
|
||||||
|
ISubscriptionDuplicateChecker {
|
||||||
|
|
||||||
|
private static final IUFStatusHandler statusHandler = UFStatus
|
||||||
|
.getHandler(SubscriptionDuplicateChecker.class);
|
||||||
|
|
||||||
|
private static final String UNABLE_TO_DETERMINE_SPATIAL_OVERLAP = "Unable to determine spatial overlap. "
|
||||||
|
+ "Subscriptions will not be considered to be overlapping spatially.";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getParameterDuplicationPercent(Subscription sub1,
|
||||||
|
Subscription sub2) {
|
||||||
|
return getDuplicationPercent(sub1.getParameter(), sub2.getParameter());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getForecastHourDuplicationPercent(Subscription sub1,
|
||||||
|
Subscription sub2) {
|
||||||
|
return getDuplicationPercent(sub1.getTime().getSelectedTimeIndices(),
|
||||||
|
sub2.getTime().getSelectedTimeIndices());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getCycleDuplicationPercent(Subscription sub1, Subscription sub2) {
|
||||||
|
return getDuplicationPercent(sub1.getTime().getCycleTimes(), sub2
|
||||||
|
.getTime().getCycleTimes());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getSpatialDuplicationPercent(Subscription sub1, Subscription sub2) {
|
||||||
|
final Coverage sub1Coverage = sub1.getCoverage();
|
||||||
|
final Coverage sub2Coverage = sub2.getCoverage();
|
||||||
|
|
||||||
|
if (sub1Coverage != null && sub2Coverage != null) {
|
||||||
|
final ReferencedEnvelope sub1Envelope = sub1Coverage
|
||||||
|
.getRequestEnvelope();
|
||||||
|
final ReferencedEnvelope sub2Envelope = sub2Coverage
|
||||||
|
.getRequestEnvelope();
|
||||||
|
|
||||||
|
if (sub1Envelope != null && sub2Envelope != null) {
|
||||||
|
try {
|
||||||
|
ReferencedEnvelope intersection = MapUtil
|
||||||
|
.reprojectAndIntersect(sub1Envelope, sub2Envelope);
|
||||||
|
final double intersectionArea = intersection.getArea();
|
||||||
|
return (int) ((intersectionArea * 100) / sub2Envelope
|
||||||
|
.getArea());
|
||||||
|
} catch (TransformException e) {
|
||||||
|
statusHandler.handle(Priority.PROBLEM,
|
||||||
|
UNABLE_TO_DETERMINE_SPATIAL_OVERLAP, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> int getDuplicationPercent(Collection<T> coll1,
|
||||||
|
Collection<T> coll2) {
|
||||||
|
|
||||||
|
int numberSatisfiedByFirstCollection = 0;
|
||||||
|
if (!CollectionUtil.isNullOrEmpty(coll1)
|
||||||
|
&& !CollectionUtil.isNullOrEmpty(coll2)) {
|
||||||
|
for (T entry : coll2) {
|
||||||
|
if (coll1.contains(entry)) {
|
||||||
|
numberSatisfiedByFirstCollection++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Convert percent to 0-100
|
||||||
|
return (numberSatisfiedByFirstCollection * 100) / (coll2.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,191 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.datadelivery.service.subscription;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration for the {@link ISubscriptionOverlapService}.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* May 08, 2013 2000 djohnson Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author djohnson
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@XmlRootElement
|
||||||
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
|
public class SubscriptionOverlapConfig {
|
||||||
|
|
||||||
|
public static final SubscriptionOverlapConfig NEVER_OVERLAPS = new SubscriptionOverlapConfig(
|
||||||
|
ISubscriptionOverlapService.ONE_HUNDRED_PERCENT,
|
||||||
|
ISubscriptionOverlapService.ONE_HUNDRED_PERCENT,
|
||||||
|
ISubscriptionOverlapService.ONE_HUNDRED_PERCENT,
|
||||||
|
ISubscriptionOverlapService.ONE_HUNDRED_PERCENT,
|
||||||
|
SubscriptionOverlapMatchStrategy.MATCH_ALL);
|
||||||
|
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private int maxAllowedParameterDuplication;
|
||||||
|
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private int maxAllowedForecastHourDuplication;
|
||||||
|
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private int maxAllowedCycleDuplication;
|
||||||
|
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private int maxAllowedSpatialDuplication;
|
||||||
|
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private SubscriptionOverlapMatchStrategy matchStrategy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public SubscriptionOverlapConfig() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param maxAllowedParameterDuplication
|
||||||
|
* @param maxAllowedForecastHourDuplication
|
||||||
|
* @param maxAllowedCycleDuplication
|
||||||
|
* @param maxAllowedSpatialDuplication
|
||||||
|
* @param matchStrategy
|
||||||
|
*/
|
||||||
|
public SubscriptionOverlapConfig(int maxAllowedParameterDuplication,
|
||||||
|
int maxAllowedForecastHourDuplication,
|
||||||
|
int maxAllowedCycleDuplication, int maxAllowedSpatialDuplication,
|
||||||
|
SubscriptionOverlapMatchStrategy matchStrategy) {
|
||||||
|
this.maxAllowedParameterDuplication = maxAllowedParameterDuplication;
|
||||||
|
this.maxAllowedForecastHourDuplication = maxAllowedForecastHourDuplication;
|
||||||
|
this.maxAllowedCycleDuplication = maxAllowedCycleDuplication;
|
||||||
|
this.maxAllowedSpatialDuplication = maxAllowedSpatialDuplication;
|
||||||
|
this.matchStrategy = matchStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maxAllowedParameterDuplication
|
||||||
|
*/
|
||||||
|
public int getMaxAllowedParameterDuplication() {
|
||||||
|
return maxAllowedParameterDuplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param maxAllowedParameterDuplication
|
||||||
|
* the maxAllowedParameterDuplication to set
|
||||||
|
*/
|
||||||
|
public void setMaxAllowedParameterDuplication(
|
||||||
|
int maxAllowedParameterDuplication) {
|
||||||
|
this.maxAllowedParameterDuplication = maxAllowedParameterDuplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maxAllowedForecastHourDuplication
|
||||||
|
*/
|
||||||
|
public int getMaxAllowedForecastHourDuplication() {
|
||||||
|
return maxAllowedForecastHourDuplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param maxAllowedForecastHourDuplication
|
||||||
|
* the maxAllowedForecastHourDuplication to set
|
||||||
|
*/
|
||||||
|
public void setMaxAllowedForecastHourDuplication(
|
||||||
|
int maxAllowedForecastHourDuplication) {
|
||||||
|
this.maxAllowedForecastHourDuplication = maxAllowedForecastHourDuplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maxAllowedCycleDuplication
|
||||||
|
*/
|
||||||
|
public int getMaxAllowedCycleDuplication() {
|
||||||
|
return maxAllowedCycleDuplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param maxAllowedCycleDuplication
|
||||||
|
* the maxAllowedCycleDuplication to set
|
||||||
|
*/
|
||||||
|
public void setMaxAllowedCycleDuplication(int maxAllowedCycleDuplication) {
|
||||||
|
this.maxAllowedCycleDuplication = maxAllowedCycleDuplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maxAllowedSpatialDuplication
|
||||||
|
*/
|
||||||
|
public int getMaxAllowedSpatialDuplication() {
|
||||||
|
return maxAllowedSpatialDuplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param maxAllowedSpatialDuplication
|
||||||
|
* the maxAllowedSpatialDuplication to set
|
||||||
|
*/
|
||||||
|
public void setMaxAllowedSpatialDuplication(int maxAllowedSpatialDuplication) {
|
||||||
|
this.maxAllowedSpatialDuplication = maxAllowedSpatialDuplication;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the matchStrategy
|
||||||
|
*/
|
||||||
|
public SubscriptionOverlapMatchStrategy getMatchStrategy() {
|
||||||
|
return matchStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param matchStrategy
|
||||||
|
* the matchStrategy to set
|
||||||
|
*/
|
||||||
|
public void setMatchStrategy(SubscriptionOverlapMatchStrategy matchStrategy) {
|
||||||
|
this.matchStrategy = matchStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the given duplication percents indicate an overlapping
|
||||||
|
* subscription.
|
||||||
|
*
|
||||||
|
* @param parameterDuplicationPercent
|
||||||
|
* @param forecastHourDuplicationPercent
|
||||||
|
* @param cycleDuplicationPercent
|
||||||
|
* @param spatialDuplicationPercent
|
||||||
|
* @return true if the subscription should be considered overlapping
|
||||||
|
*/
|
||||||
|
public boolean isOverlapping(int parameterDuplicationPercent,
|
||||||
|
int forecastHourDuplicationPercent, int cycleDuplicationPercent,
|
||||||
|
int spatialDuplicationPercent) {
|
||||||
|
|
||||||
|
// Pass through to the match strategy
|
||||||
|
return this.matchStrategy.isOverlapping(this,
|
||||||
|
parameterDuplicationPercent, forecastHourDuplicationPercent,
|
||||||
|
cycleDuplicationPercent, spatialDuplicationPercent);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,138 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.datadelivery.service.subscription;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlEnum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strategy for how to apply the rules in the subscription overlap
|
||||||
|
* configuration.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* May 14, 2013 2000 djohnson Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author djohnson
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@XmlEnum
|
||||||
|
public enum SubscriptionOverlapMatchStrategy {
|
||||||
|
MATCH_ANY {
|
||||||
|
@Override
|
||||||
|
public boolean isOverlapping(SubscriptionOverlapConfig config,
|
||||||
|
int parameterDuplicationPercent,
|
||||||
|
int forecastHourDuplicationPercent,
|
||||||
|
int cycleDuplicationPercent, int spatialDuplicationPercent) {
|
||||||
|
|
||||||
|
final boolean exceedsAllowedParameterDuplication = parameterDuplicationPercent > config
|
||||||
|
.getMaxAllowedParameterDuplication();
|
||||||
|
final boolean exceedsAllowedForecastHourDuplication = forecastHourDuplicationPercent > config
|
||||||
|
.getMaxAllowedForecastHourDuplication();
|
||||||
|
final boolean exceedsAllowedCycleDuplication = cycleDuplicationPercent > config
|
||||||
|
.getMaxAllowedCycleDuplication();
|
||||||
|
final boolean exceedsAllowedSpatialDuplication = spatialDuplicationPercent > config
|
||||||
|
.getMaxAllowedSpatialDuplication();
|
||||||
|
|
||||||
|
return exceedsAllowedParameterDuplication
|
||||||
|
|| exceedsAllowedForecastHourDuplication
|
||||||
|
|| exceedsAllowedCycleDuplication
|
||||||
|
|| exceedsAllowedSpatialDuplication;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MATCH_ALL {
|
||||||
|
@Override
|
||||||
|
public boolean isOverlapping(SubscriptionOverlapConfig config,
|
||||||
|
int parameterDuplicationPercent,
|
||||||
|
int forecastHourDuplicationPercent,
|
||||||
|
int cycleDuplicationPercent, int spatialDuplicationPercent) {
|
||||||
|
|
||||||
|
final boolean exceedsAllowedParameterDuplication = parameterDuplicationPercent > config
|
||||||
|
.getMaxAllowedParameterDuplication();
|
||||||
|
final boolean exceedsAllowedForecastHourDuplication = forecastHourDuplicationPercent > config
|
||||||
|
.getMaxAllowedForecastHourDuplication();
|
||||||
|
final boolean exceedsAllowedCycleDuplication = cycleDuplicationPercent > config
|
||||||
|
.getMaxAllowedCycleDuplication();
|
||||||
|
final boolean exceedsAllowedSpatialDuplication = spatialDuplicationPercent > config
|
||||||
|
.getMaxAllowedSpatialDuplication();
|
||||||
|
|
||||||
|
return exceedsAllowedParameterDuplication
|
||||||
|
&& exceedsAllowedForecastHourDuplication
|
||||||
|
&& exceedsAllowedCycleDuplication
|
||||||
|
&& exceedsAllowedSpatialDuplication;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
AT_LEAST_HALF {
|
||||||
|
@Override
|
||||||
|
public boolean isOverlapping(SubscriptionOverlapConfig config,
|
||||||
|
int parameterDuplicationPercent,
|
||||||
|
int forecastHourDuplicationPercent,
|
||||||
|
int cycleDuplicationPercent, int spatialDuplicationPercent) {
|
||||||
|
final boolean exceedsAllowedParameterDuplication = parameterDuplicationPercent > config
|
||||||
|
.getMaxAllowedParameterDuplication();
|
||||||
|
final boolean exceedsAllowedForecastHourDuplication = forecastHourDuplicationPercent > config
|
||||||
|
.getMaxAllowedForecastHourDuplication();
|
||||||
|
final boolean exceedsAllowedCycleDuplication = cycleDuplicationPercent > config
|
||||||
|
.getMaxAllowedCycleDuplication();
|
||||||
|
final boolean exceedsAllowedSpatialDuplication = spatialDuplicationPercent > config
|
||||||
|
.getMaxAllowedSpatialDuplication();
|
||||||
|
|
||||||
|
boolean[] toCheck = new boolean[] {
|
||||||
|
exceedsAllowedParameterDuplication,
|
||||||
|
exceedsAllowedForecastHourDuplication,
|
||||||
|
exceedsAllowedCycleDuplication,
|
||||||
|
exceedsAllowedSpatialDuplication };
|
||||||
|
final int numBooleans = toCheck.length;
|
||||||
|
final int halfNumBooleans = numBooleans / 2;
|
||||||
|
|
||||||
|
int exceeded = 0;
|
||||||
|
for (boolean check : toCheck) {
|
||||||
|
if (check) {
|
||||||
|
exceeded++;
|
||||||
|
if (exceeded >= halfNumBooleans) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the given duplication percents indicate an overlapping
|
||||||
|
* subscription.
|
||||||
|
*
|
||||||
|
* @param config
|
||||||
|
* @param parameterDuplicationPercent
|
||||||
|
* @param forecastHourDuplicationPercent
|
||||||
|
* @param cycleDuplicationPercent
|
||||||
|
* @param spatialDuplicationPercent
|
||||||
|
* @return true if the subscription should be considered overlapping
|
||||||
|
*/
|
||||||
|
public abstract boolean isOverlapping(SubscriptionOverlapConfig config,
|
||||||
|
int parameterDuplicationPercent,
|
||||||
|
int forecastHourDuplicationPercent, int cycleDuplicationPercent,
|
||||||
|
int spatialDuplicationPercent);
|
||||||
|
}
|
|
@ -0,0 +1,194 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.datadelivery.service.subscription;
|
||||||
|
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBException;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.Subscription;
|
||||||
|
import com.raytheon.uf.common.localization.IPathManager;
|
||||||
|
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||||
|
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||||
|
import com.raytheon.uf.common.serialization.JAXBManager;
|
||||||
|
import com.raytheon.uf.common.serialization.SerializationException;
|
||||||
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks subscriptions to see if they would be considered duplicates.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* May 07, 2013 2000 djohnson Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author djohnson
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SubscriptionOverlapService implements ISubscriptionOverlapService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base response object implementing {@link ISubscriptionOverlapResponse}.
|
||||||
|
*/
|
||||||
|
public class SubscriptionOverlapResponse implements
|
||||||
|
ISubscriptionOverlapResponse {
|
||||||
|
|
||||||
|
private final boolean duplicate;
|
||||||
|
|
||||||
|
private final boolean overlapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param duplicate
|
||||||
|
* @param overlapping
|
||||||
|
*/
|
||||||
|
public SubscriptionOverlapResponse(boolean duplicate,
|
||||||
|
boolean overlapping) {
|
||||||
|
this.duplicate = duplicate;
|
||||||
|
this.overlapping = overlapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isDuplicate() {
|
||||||
|
return duplicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isOverlapping() {
|
||||||
|
return overlapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final IUFStatusHandler statusHandler = UFStatus
|
||||||
|
.getHandler(SubscriptionOverlapService.class);
|
||||||
|
|
||||||
|
private static final String UNABLE_TO_UNMARSHAL = "Unable to unmarshal the configuration file. "
|
||||||
|
+ "No subscriptions will be considered to overlap!";
|
||||||
|
|
||||||
|
private static final String SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH = "datadelivery/subscriptionOverlapRules.xml";
|
||||||
|
|
||||||
|
private final ISubscriptionDuplicateChecker duplicateChecker;
|
||||||
|
|
||||||
|
private final JAXBManager jaxbManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param duplicateChecker
|
||||||
|
*/
|
||||||
|
public SubscriptionOverlapService(
|
||||||
|
ISubscriptionDuplicateChecker duplicateChecker) {
|
||||||
|
this.duplicateChecker = duplicateChecker;
|
||||||
|
|
||||||
|
try {
|
||||||
|
jaxbManager = new JAXBManager(SubscriptionOverlapConfig.class);
|
||||||
|
} catch (JAXBException e) {
|
||||||
|
throw new ExceptionInInitializerError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ISubscriptionOverlapResponse isOverlapping(Subscription sub1,
|
||||||
|
Subscription sub2) {
|
||||||
|
// Ignore requests to compare with itself
|
||||||
|
if (sub1.getName().equals(sub2.getName())) {
|
||||||
|
return new SubscriptionOverlapResponse(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
final IPathManager pathManager = PathManagerFactory.getPathManager();
|
||||||
|
|
||||||
|
final LocalizationFile localizationFile = pathManager
|
||||||
|
.getStaticLocalizationFile(SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH);
|
||||||
|
|
||||||
|
SubscriptionOverlapConfig config;
|
||||||
|
try {
|
||||||
|
if (!localizationFile.exists()) {
|
||||||
|
throw new MissingResourceException(localizationFile.getName()
|
||||||
|
+ " does not exist.",
|
||||||
|
SubscriptionOverlapConfig.class.getName(), "");
|
||||||
|
}
|
||||||
|
config = localizationFile.jaxbUnmarshal(
|
||||||
|
SubscriptionOverlapConfig.class, jaxbManager);
|
||||||
|
} catch (Exception e) {
|
||||||
|
statusHandler.handle(Priority.PROBLEM, UNABLE_TO_UNMARSHAL, e);
|
||||||
|
config = SubscriptionOverlapConfig.NEVER_OVERLAPS;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int parameterDuplicationPercent = duplicateChecker
|
||||||
|
.getParameterDuplicationPercent(sub1, sub2);
|
||||||
|
final int forecastHourDuplicationPercent = duplicateChecker
|
||||||
|
.getForecastHourDuplicationPercent(sub1, sub2);
|
||||||
|
final int cycleDuplicationPercent = duplicateChecker
|
||||||
|
.getCycleDuplicationPercent(sub1, sub2);
|
||||||
|
final int spatialDuplicationPercent = duplicateChecker
|
||||||
|
.getSpatialDuplicationPercent(sub1, sub2);
|
||||||
|
|
||||||
|
final boolean overlaps = config.isOverlapping(
|
||||||
|
parameterDuplicationPercent, forecastHourDuplicationPercent,
|
||||||
|
cycleDuplicationPercent, spatialDuplicationPercent);
|
||||||
|
|
||||||
|
final boolean duplicate = (parameterDuplicationPercent == ONE_HUNDRED_PERCENT)
|
||||||
|
&& (forecastHourDuplicationPercent == ONE_HUNDRED_PERCENT)
|
||||||
|
&& (cycleDuplicationPercent == ONE_HUNDRED_PERCENT)
|
||||||
|
&& (spatialDuplicationPercent == ONE_HUNDRED_PERCENT);
|
||||||
|
|
||||||
|
return new SubscriptionOverlapResponse(duplicate, overlaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the new configuration.
|
||||||
|
*
|
||||||
|
* @param config
|
||||||
|
* the configuration
|
||||||
|
* @throws SerializationException
|
||||||
|
* on error serializing the configuration
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
void writeNewConfig(SubscriptionOverlapConfig config)
|
||||||
|
throws SerializationException {
|
||||||
|
final LocalizationFile configFile = PathManagerFactory
|
||||||
|
.getPathManager()
|
||||||
|
.getStaticLocalizationFile(
|
||||||
|
SubscriptionOverlapService.SUBSCRIPTION_OVERLAP_CONFIG_FILE_PATH);
|
||||||
|
this.jaxbManager.jaxbMarshalToXmlFile(config, configFile.getFile()
|
||||||
|
.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<subscriptionOverlapConfig>
|
||||||
|
<!-- Each value is represented by a percent, 0-100 -->
|
||||||
|
<maxAllowedParameterDuplication>65</maxAllowedParameterDuplication>
|
||||||
|
<maxAllowedForecastHourDuplication>65</maxAllowedForecastHourDuplication>
|
||||||
|
<maxAllowedCycleDuplication>65</maxAllowedCycleDuplication>
|
||||||
|
<maxAllowedSpatialDuplication>65</maxAllowedSpatialDuplication>
|
||||||
|
<!--
|
||||||
|
Available options:
|
||||||
|
MATCH_ANY: Any of the maxAllowed options will
|
||||||
|
cause the subscription to be considered overlapping.
|
||||||
|
|
||||||
|
MATCH_ALL: All maxAllowed options must be exceeded
|
||||||
|
to cause the subscription to be considered overlapping.
|
||||||
|
|
||||||
|
AT_LEAST_HALF: At least half of the maxAllowed options
|
||||||
|
must be exceeded to cause the subscription to be considered
|
||||||
|
overlapping.
|
||||||
|
-->
|
||||||
|
<matchStrategy>MATCH_ANY</matchStrategy>
|
||||||
|
</subscriptionOverlapConfig>
|
|
@ -34,6 +34,7 @@ import com.raytheon.uf.common.registry.handler.RegistryHandlerException;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
import com.raytheon.uf.common.util.CollectionUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs subscription integrity verification.
|
* Performs subscription integrity verification.
|
||||||
|
@ -47,6 +48,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
* Dec 7, 2012 1104 djohnson Initial creation
|
* Dec 7, 2012 1104 djohnson Initial creation
|
||||||
* Feb 05, 2013 1580 mpduff EventBus refactor.
|
* Feb 05, 2013 1580 mpduff EventBus refactor.
|
||||||
* 3/18/2013 1802 bphillip Modified to use proper transaction boundaries
|
* 3/18/2013 1802 bphillip Modified to use proper transaction boundaries
|
||||||
|
* May 08, 2013 2000 djohnson Shortcut out if no subscriptions are returned for the dataset.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -171,6 +173,10 @@ public class SubscriptionIntegrityVerifier {
|
||||||
.getActiveByDataSetAndProvider(dataSet.getDataSetName(),
|
.getActiveByDataSetAndProvider(dataSet.getDataSetName(),
|
||||||
dataSet.getProviderName());
|
dataSet.getProviderName());
|
||||||
|
|
||||||
|
if (CollectionUtil.isNullOrEmpty(subscriptions)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (Subscription subscription : subscriptions) {
|
for (Subscription subscription : subscriptions) {
|
||||||
|
|
||||||
if (!subscription.isValid()) {
|
if (!subscription.isValid()) {
|
||||||
|
|
|
@ -38,6 +38,7 @@ import java.util.TimeZone;
|
||||||
import javax.xml.bind.JAXBContext;
|
import javax.xml.bind.JAXBContext;
|
||||||
import javax.xml.bind.Unmarshaller;
|
import javax.xml.bind.Unmarshaller;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.raytheon.edex.esb.Headers;
|
import com.raytheon.edex.esb.Headers;
|
||||||
|
@ -46,7 +47,6 @@ import com.raytheon.edex.plugin.redbook.common.RedbookRecord;
|
||||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||||
import com.raytheon.uf.common.localization.PathManagerFactoryTest;
|
import com.raytheon.uf.common.localization.PathManagerFactoryTest;
|
||||||
import com.raytheon.uf.common.util.FileUtil;
|
import com.raytheon.uf.common.util.FileUtil;
|
||||||
import com.sun.xml.internal.ws.util.ByteArrayBuffer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regression Test RedbookRecords decoded by the RedbookDecoder against known
|
* Regression Test RedbookRecords decoded by the RedbookDecoder against known
|
||||||
|
@ -59,13 +59,14 @@ import com.sun.xml.internal.ws.util.ByteArrayBuffer;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Apr 22, 2013 1958 bgonzale Initial creation
|
* Apr 22, 2013 1958 bgonzale Initial creation
|
||||||
|
* May 08, 2013 2000 djohnson Ignore broken test.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bgonzale
|
* @author bgonzale
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
|
@Ignore("Test is broken")
|
||||||
public class RedbookDecoderTest {
|
public class RedbookDecoderTest {
|
||||||
|
|
||||||
final static String DataDir = "./data/Redbook";
|
final static String DataDir = "./data/Redbook";
|
||||||
|
@ -160,14 +161,13 @@ public class RedbookDecoderTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<RedbookTest> tests;
|
private final Collection<RedbookTest> tests;
|
||||||
|
|
||||||
public RedbookDecoderTest() throws IOException {
|
public RedbookDecoderTest() throws IOException {
|
||||||
PathManagerFactoryTest.initLocalization();
|
PathManagerFactoryTest.initLocalization();
|
||||||
tests = new ArrayList<RedbookDecoderTest.RedbookTest>();
|
tests = new ArrayList<RedbookDecoderTest.RedbookTest>();
|
||||||
// load test byte arrays, test header data, and result objects.
|
// load test byte arrays, test header data, and result objects.
|
||||||
InputStream inStrm = null;
|
InputStream inStrm = null;
|
||||||
ByteArrayBuffer outStrm = null;
|
|
||||||
|
|
||||||
for (RedbookInput redbookInput : RedbookInput.getInputs()) {
|
for (RedbookInput redbookInput : RedbookInput.getInputs()) {
|
||||||
byte[] rawMessage = null;
|
byte[] rawMessage = null;
|
||||||
|
@ -267,7 +267,7 @@ public class RedbookDecoderTest {
|
||||||
assertEquals(test.id
|
assertEquals(test.id
|
||||||
+ " Failure, incorrect number of results returned for "
|
+ " Failure, incorrect number of results returned for "
|
||||||
+ test.id, expectedNumberOfResults, result.length);
|
+ test.id, expectedNumberOfResults, result.length);
|
||||||
RedbookRecord expectedResult = (RedbookRecord) (test.hasResults() ? test.result
|
RedbookRecord expectedResult = (test.hasResults() ? test.result
|
||||||
: null);
|
: null);
|
||||||
RedbookRecord actualResult = (RedbookRecord) (result.length > 0 ? result[0]
|
RedbookRecord actualResult = (RedbookRecord) (result.length > 0 ? result[0]
|
||||||
: null);
|
: null);
|
||||||
|
|
|
@ -61,8 +61,8 @@ public class GriddedCoverageFixture extends AbstractFixture<GriddedCoverage> {
|
||||||
public GriddedCoverage getInstance(long seedValue, Random random) {
|
public GriddedCoverage getInstance(long seedValue, Random random) {
|
||||||
LatLonGridCoverage gridCoverage = new LatLonGridCoverage();
|
LatLonGridCoverage gridCoverage = new LatLonGridCoverage();
|
||||||
gridCoverage.setCrsWKT("Polygon");
|
gridCoverage.setCrsWKT("Polygon");
|
||||||
gridCoverage.setLa1(10);
|
gridCoverage.setLa1(10 + seedValue);
|
||||||
gridCoverage.setLo1(-10);
|
gridCoverage.setLo1(-10 - seedValue);
|
||||||
gridCoverage.setDx(1.0);
|
gridCoverage.setDx(1.0);
|
||||||
gridCoverage.setDy(1.0);
|
gridCoverage.setDy(1.0);
|
||||||
gridCoverage.setNx(21);
|
gridCoverage.setNx(21);
|
||||||
|
|
|
@ -0,0 +1,234 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.datadelivery.service.subscription;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.geotools.geometry.jts.ReferencedEnvelope;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.opengis.referencing.operation.TransformException;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage;
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.Parameter;
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.ParameterFixture;
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.SubscriptionFixture;
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.UserSubscription;
|
||||||
|
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||||
|
import com.vividsolutions.jts.geom.Coordinate;
|
||||||
|
import com.vividsolutions.jts.geom.Envelope;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TesT {@link SubscriptionDuplicateChecker}.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* May 02, 2013 2000 djohnson Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author djohnson
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class SubscriptionDuplicateCheckerTest {
|
||||||
|
|
||||||
|
private static final ISubscriptionDuplicateChecker dupeChecker = new SubscriptionDuplicateChecker();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void returnsPercentOfParametersThatAreTheSame() {
|
||||||
|
final UserSubscription sub1 = SubscriptionFixture.INSTANCE.get(1);
|
||||||
|
final UserSubscription sub2 = SubscriptionFixture.INSTANCE.get(2);
|
||||||
|
|
||||||
|
sub1.getParameter().clear();
|
||||||
|
sub1.addParameter(ParameterFixture.INSTANCE.get(1));
|
||||||
|
|
||||||
|
sub2.getParameter().clear();
|
||||||
|
sub2.addParameter(sub1.getParameter().iterator().next());
|
||||||
|
sub2.addParameter(ParameterFixture.INSTANCE.get(2));
|
||||||
|
|
||||||
|
assertThat(dupeChecker.getParameterDuplicationPercent(sub1, sub2),
|
||||||
|
is(50));
|
||||||
|
assertThat(dupeChecker.getParameterDuplicationPercent(sub2, sub1),
|
||||||
|
is(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void returnsZeroPercentOfParametersForNullsOrEmpties() {
|
||||||
|
final UserSubscription sub1 = SubscriptionFixture.INSTANCE.get(1);
|
||||||
|
final UserSubscription sub2 = SubscriptionFixture.INSTANCE.get(2);
|
||||||
|
|
||||||
|
sub1.setParameter(null);
|
||||||
|
|
||||||
|
sub2.getParameter().clear();
|
||||||
|
sub2.addParameter(ParameterFixture.INSTANCE.get(2));
|
||||||
|
|
||||||
|
assertThat(dupeChecker.getParameterDuplicationPercent(sub1, sub2),
|
||||||
|
is(0));
|
||||||
|
assertThat(dupeChecker.getParameterDuplicationPercent(sub2, sub1),
|
||||||
|
is(0));
|
||||||
|
|
||||||
|
sub1.setParameter(Collections.<Parameter> emptyList());
|
||||||
|
assertThat(dupeChecker.getParameterDuplicationPercent(sub1, sub2),
|
||||||
|
is(0));
|
||||||
|
assertThat(dupeChecker.getParameterDuplicationPercent(sub2, sub1),
|
||||||
|
is(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void returnsPercentOfForecastHoursThatAreTheSame() {
|
||||||
|
final UserSubscription sub1 = SubscriptionFixture.INSTANCE.get(1);
|
||||||
|
final UserSubscription sub2 = SubscriptionFixture.INSTANCE.get(2);
|
||||||
|
|
||||||
|
final List<Integer> sub1SelectedTimes = Arrays.asList(0, 1);
|
||||||
|
sub1.getTime().setSelectedTimeIndices(sub1SelectedTimes);
|
||||||
|
final List<Integer> sub2SelectedTimes = Arrays.asList(0, 3, 4);
|
||||||
|
sub2.getTime().setSelectedTimeIndices(sub2SelectedTimes);
|
||||||
|
|
||||||
|
assertThat(dupeChecker.getForecastHourDuplicationPercent(sub1, sub2),
|
||||||
|
is(33));
|
||||||
|
assertThat(dupeChecker.getForecastHourDuplicationPercent(sub2, sub1),
|
||||||
|
is(50));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void returnsZeroPercentOfForecastHoursForNullsOrEmpties() {
|
||||||
|
final UserSubscription sub1 = SubscriptionFixture.INSTANCE.get(1);
|
||||||
|
final UserSubscription sub2 = SubscriptionFixture.INSTANCE.get(2);
|
||||||
|
|
||||||
|
sub1.getTime().setSelectedTimeIndices(null);
|
||||||
|
final List<Integer> sub2SelectedTimes = Arrays.asList(0, 3, 4);
|
||||||
|
sub2.getTime().setSelectedTimeIndices(sub2SelectedTimes);
|
||||||
|
|
||||||
|
assertThat(dupeChecker.getForecastHourDuplicationPercent(sub1, sub2),
|
||||||
|
is(0));
|
||||||
|
assertThat(dupeChecker.getForecastHourDuplicationPercent(sub2, sub1),
|
||||||
|
is(0));
|
||||||
|
|
||||||
|
sub1.getTime()
|
||||||
|
.setSelectedTimeIndices(Collections.<Integer> emptyList());
|
||||||
|
assertThat(dupeChecker.getForecastHourDuplicationPercent(sub1, sub2),
|
||||||
|
is(0));
|
||||||
|
assertThat(dupeChecker.getForecastHourDuplicationPercent(sub2, sub1),
|
||||||
|
is(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void returnsPercentOfCyclesThatAreTheSame() {
|
||||||
|
final UserSubscription sub1 = SubscriptionFixture.INSTANCE.get(1);
|
||||||
|
final UserSubscription sub2 = SubscriptionFixture.INSTANCE.get(2);
|
||||||
|
|
||||||
|
final List<Integer> sub1CycleTimes = Arrays.asList(0, 6);
|
||||||
|
sub1.getTime().setCycleTimes(sub1CycleTimes);
|
||||||
|
final List<Integer> sub2CycleTimes = Arrays.asList(0, 12, 18);
|
||||||
|
sub2.getTime().setCycleTimes(sub2CycleTimes);
|
||||||
|
|
||||||
|
assertThat(dupeChecker.getCycleDuplicationPercent(sub1, sub2),
|
||||||
|
is(33));
|
||||||
|
assertThat(dupeChecker.getCycleDuplicationPercent(sub2, sub1),
|
||||||
|
is(50));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void returnsZeroPercentOfCyclesForNullsOrEmpties() {
|
||||||
|
final UserSubscription sub1 = SubscriptionFixture.INSTANCE.get(1);
|
||||||
|
final UserSubscription sub2 = SubscriptionFixture.INSTANCE.get(2);
|
||||||
|
|
||||||
|
sub1.getTime().setCycleTimes(null);
|
||||||
|
final List<Integer> cycleTimes = Arrays.asList(0, 3, 4);
|
||||||
|
sub2.getTime().setCycleTimes(cycleTimes);
|
||||||
|
|
||||||
|
assertThat(dupeChecker.getCycleDuplicationPercent(sub1, sub2), is(0));
|
||||||
|
assertThat(dupeChecker.getCycleDuplicationPercent(sub2, sub1), is(0));
|
||||||
|
|
||||||
|
sub1.getTime().setCycleTimes(Collections.<Integer> emptyList());
|
||||||
|
assertThat(dupeChecker.getCycleDuplicationPercent(sub1, sub2), is(0));
|
||||||
|
assertThat(dupeChecker.getCycleDuplicationPercent(sub2, sub1), is(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void returnsPercentOfSpatialThatIsTheSame()
|
||||||
|
throws TransformException {
|
||||||
|
final UserSubscription sub1 = SubscriptionFixture.INSTANCE.get(1);
|
||||||
|
final UserSubscription sub2 = SubscriptionFixture.INSTANCE.get(2);
|
||||||
|
|
||||||
|
ReferencedEnvelope envelope1 = new ReferencedEnvelope(new Envelope(
|
||||||
|
new Coordinate(-5, 0), new Coordinate(0, 5)),
|
||||||
|
MapUtil.LATLON_PROJECTION);
|
||||||
|
|
||||||
|
// dx = 6, dy = 3, area = 18
|
||||||
|
ReferencedEnvelope envelope2 = new ReferencedEnvelope(new Envelope(
|
||||||
|
new Coordinate(-3, 3), new Coordinate(3, 6)),
|
||||||
|
MapUtil.LATLON_PROJECTION);
|
||||||
|
|
||||||
|
// The intersection should have coordinates: (-3, 3) (0, 5)
|
||||||
|
// dx = 3, dy = 2, area = 6
|
||||||
|
|
||||||
|
sub1.getCoverage().setRequestEnvelope(envelope1);
|
||||||
|
sub2.getCoverage().setRequestEnvelope(envelope2);
|
||||||
|
|
||||||
|
// The expected percent overlap: 6 / 18 = .33
|
||||||
|
assertThat(dupeChecker.getSpatialDuplicationPercent(sub1, sub2), is(33));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void returnsZeroPercentOfSpatialWhenNoOverlap()
|
||||||
|
throws TransformException {
|
||||||
|
final UserSubscription sub1 = SubscriptionFixture.INSTANCE.get(1);
|
||||||
|
final UserSubscription sub2 = SubscriptionFixture.INSTANCE.get(2);
|
||||||
|
|
||||||
|
ReferencedEnvelope envelope1 = new ReferencedEnvelope(new Envelope(
|
||||||
|
new Coordinate(-5, 0), new Coordinate(0, 5)),
|
||||||
|
MapUtil.LATLON_PROJECTION);
|
||||||
|
|
||||||
|
ReferencedEnvelope envelope2 = new ReferencedEnvelope(new Envelope(
|
||||||
|
new Coordinate(-10, -20), new Coordinate(-6, -15)),
|
||||||
|
MapUtil.LATLON_PROJECTION);
|
||||||
|
|
||||||
|
sub1.getCoverage().setRequestEnvelope(envelope1);
|
||||||
|
sub2.getCoverage().setRequestEnvelope(envelope2);
|
||||||
|
|
||||||
|
assertThat(dupeChecker.getSpatialDuplicationPercent(sub1, sub2), is(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void returnsZeroPercentOfSpatialForNulls() throws TransformException {
|
||||||
|
final UserSubscription sub1 = SubscriptionFixture.INSTANCE.get(1);
|
||||||
|
final UserSubscription sub2 = SubscriptionFixture.INSTANCE.get(2);
|
||||||
|
|
||||||
|
sub1.setCoverage(null);
|
||||||
|
|
||||||
|
assertThat(dupeChecker.getSpatialDuplicationPercent(sub1, sub2), is(0));
|
||||||
|
assertThat(dupeChecker.getSpatialDuplicationPercent(sub2, sub1), is(0));
|
||||||
|
|
||||||
|
// No envelope set
|
||||||
|
sub1.setCoverage(new GriddedCoverage());
|
||||||
|
assertThat(dupeChecker.getSpatialDuplicationPercent(sub1, sub2), is(0));
|
||||||
|
assertThat(dupeChecker.getSpatialDuplicationPercent(sub2, sub1), is(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.datadelivery.service.subscription;
|
||||||
|
|
||||||
|
import static com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy.AT_LEAST_HALF;
|
||||||
|
import static com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy.MATCH_ALL;
|
||||||
|
import static com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy.MATCH_ANY;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test {@link SubscriptionOverlapMatchStrategy}.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* May 14, 2013 2000 djohnson Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author djohnson
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class SubscriptionOverlapMatchStrategyTest {
|
||||||
|
|
||||||
|
private static final SubscriptionOverlapConfig MUST_EXCEED_FIFTY_PERCENT = new SubscriptionOverlapConfig(
|
||||||
|
50, 50, 50, 50, null);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void matchAnyReturnsTrueIfAnyExceedMaxAllowed() {
|
||||||
|
|
||||||
|
assertThat(MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55, 45,
|
||||||
|
45, 45), is(true));
|
||||||
|
assertThat(MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45, 55,
|
||||||
|
45, 45), is(true));
|
||||||
|
assertThat(MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45, 45,
|
||||||
|
55, 45), is(true));
|
||||||
|
assertThat(MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45, 45,
|
||||||
|
45, 55), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void matchAnyReturnsFalseIfNoneExceedMaxAllowed() {
|
||||||
|
|
||||||
|
assertThat(MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 50, 50,
|
||||||
|
50, 50), is(false));
|
||||||
|
assertThat(
|
||||||
|
MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 0, 0, 0, 0),
|
||||||
|
is(false));
|
||||||
|
assertThat(MATCH_ANY.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 25, 25,
|
||||||
|
25, 25), is(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void matchAllReturnsTrueIfAllExceedMaxAllowed() {
|
||||||
|
|
||||||
|
assertThat(MATCH_ALL.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55, 55,
|
||||||
|
55, 55), is(true));
|
||||||
|
assertThat(MATCH_ALL.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 100, 100,
|
||||||
|
100, 100), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void matchAllReturnsFalseIfNotAllExceedMaxAllowed() {
|
||||||
|
|
||||||
|
assertThat(MATCH_ALL.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55, 55,
|
||||||
|
55, 45), is(false));
|
||||||
|
assertThat(MATCH_ALL.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55, 55,
|
||||||
|
45, 55), is(false));
|
||||||
|
assertThat(MATCH_ALL.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55, 45,
|
||||||
|
55, 55), is(false));
|
||||||
|
assertThat(MATCH_ALL.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45, 55,
|
||||||
|
55, 55), is(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void atLeastHalfReturnsTrueIfAllExceedMaxAllowed() {
|
||||||
|
|
||||||
|
assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55,
|
||||||
|
55, 55, 55), is(true));
|
||||||
|
assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 100,
|
||||||
|
100, 100, 100), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void atLeastHalfReturnsTrueIfHalfExceedMaxAllowed() {
|
||||||
|
|
||||||
|
assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45,
|
||||||
|
45, 55, 55), is(true));
|
||||||
|
assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55,
|
||||||
|
55, 45, 45), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void atLeastHalfReturnsFalseIfLessThanHalfExceedMaxAllowed() {
|
||||||
|
|
||||||
|
assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45,
|
||||||
|
45, 45, 55), is(false));
|
||||||
|
assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45,
|
||||||
|
45, 55, 45), is(false));
|
||||||
|
assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 45,
|
||||||
|
55, 45, 45), is(false));
|
||||||
|
assertThat(AT_LEAST_HALF.isOverlapping(MUST_EXCEED_FIFTY_PERCENT, 55,
|
||||||
|
45, 45, 45), is(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,229 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.datadelivery.service.subscription;
|
||||||
|
|
||||||
|
import static com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy.MATCH_ALL;
|
||||||
|
import static com.raytheon.uf.common.datadelivery.service.subscription.SubscriptionOverlapMatchStrategy.MATCH_ANY;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.opengis.referencing.operation.TransformException;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.Subscription;
|
||||||
|
import com.raytheon.uf.common.datadelivery.registry.SubscriptionFixture;
|
||||||
|
import com.raytheon.uf.common.localization.PathManagerFactoryTest;
|
||||||
|
import com.raytheon.uf.common.serialization.SerializationException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test {@link SubscriptionOverlapService}.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* May 07, 2013 2000 djohnson Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author djohnson
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SubscriptionOverlapServiceTest {
|
||||||
|
|
||||||
|
private static final SubscriptionOverlapConfig ANY_MUST_EXCEED_65_PERCENT = new SubscriptionOverlapConfig(
|
||||||
|
65, 65, 65, 65, MATCH_ANY);
|
||||||
|
|
||||||
|
private static final SubscriptionOverlapConfig ALL_MUST_EXCEED_65_PERCENT = new SubscriptionOverlapConfig(
|
||||||
|
65, 65, 65, 65, MATCH_ALL);
|
||||||
|
|
||||||
|
private final ISubscriptionDuplicateChecker duplicateChecker = mock(ISubscriptionDuplicateChecker.class);
|
||||||
|
|
||||||
|
private final SubscriptionOverlapService service = new SubscriptionOverlapService(
|
||||||
|
duplicateChecker);
|
||||||
|
|
||||||
|
private final Subscription sub1 = SubscriptionFixture.INSTANCE.get(1);
|
||||||
|
|
||||||
|
private final Subscription sub2 = SubscriptionFixture.INSTANCE.get(2);
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
PathManagerFactoryTest.initLocalization();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void moreParametersInCommonThanAllowedOverlaps() {
|
||||||
|
when(duplicateChecker.getParameterDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lessParametersInCommonThanAllowedDoesNotOverlap() {
|
||||||
|
when(duplicateChecker.getParameterDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(64);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void moreForecastHoursInCommonThanAllowedOverlaps() {
|
||||||
|
when(duplicateChecker.getForecastHourDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lessForecastHoursInCommonThanAllowedDoesNotOverlap() {
|
||||||
|
when(duplicateChecker.getForecastHourDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(64);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void moreCyclesInCommonThanAllowedOverlaps() {
|
||||||
|
when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lessCyclesInCommonThanAllowedDoesNotOverlap() {
|
||||||
|
when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(64);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void moreSpatialInCommonThanAllowedOverlaps()
|
||||||
|
throws TransformException {
|
||||||
|
when(duplicateChecker.getSpatialDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lessSpatialInCommonThanAllowedDoesNotOverlap()
|
||||||
|
throws TransformException {
|
||||||
|
when(duplicateChecker.getSpatialDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(64);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void matchesAnyTrueWillConsiderOneExceededValueAsOverlaps()
|
||||||
|
throws SerializationException {
|
||||||
|
service.writeNewConfig(ANY_MUST_EXCEED_65_PERCENT);
|
||||||
|
|
||||||
|
when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void matchesAnyFalseWillNotConsiderOneExceededValueAsOverlaps()
|
||||||
|
throws SerializationException {
|
||||||
|
service.writeNewConfig(ALL_MUST_EXCEED_65_PERCENT);
|
||||||
|
|
||||||
|
when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void matchesAnyTrueWillConsiderAllExceededValuesAsOverlaps()
|
||||||
|
throws SerializationException, TransformException {
|
||||||
|
service.writeNewConfig(ANY_MUST_EXCEED_65_PERCENT);
|
||||||
|
|
||||||
|
when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
when(duplicateChecker.getForecastHourDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
when(duplicateChecker.getParameterDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
when(duplicateChecker.getSpatialDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void matchesAnyFalseWillConsiderAllExceededValuesAsOverlaps()
|
||||||
|
throws SerializationException, TransformException {
|
||||||
|
service.writeNewConfig(ALL_MUST_EXCEED_65_PERCENT);
|
||||||
|
|
||||||
|
when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
when(duplicateChecker.getForecastHourDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
when(duplicateChecker.getParameterDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
when(duplicateChecker.getSpatialDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(66);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isOverlapping(), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAllComparisonsReturnOneHundredPercentReturnsDuplicate()
|
||||||
|
throws SerializationException, TransformException {
|
||||||
|
when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(100);
|
||||||
|
when(duplicateChecker.getForecastHourDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(100);
|
||||||
|
when(duplicateChecker.getParameterDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(100);
|
||||||
|
when(duplicateChecker.getSpatialDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(100);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isDuplicate(), is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenAllComparisonsDontReturnOneHundredPercentReturnsNotDuplicate()
|
||||||
|
throws SerializationException, TransformException {
|
||||||
|
when(duplicateChecker.getCycleDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(100);
|
||||||
|
when(duplicateChecker.getForecastHourDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(100);
|
||||||
|
when(duplicateChecker.getParameterDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(100);
|
||||||
|
when(duplicateChecker.getSpatialDuplicationPercent(sub1, sub2))
|
||||||
|
.thenReturn(99);
|
||||||
|
|
||||||
|
assertThat(service.isOverlapping(sub1, sub2).isDuplicate(), is(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,10 +25,12 @@ import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
import static org.mockito.Matchers.anyListOf;
|
import static org.mockito.Matchers.anyListOf;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -49,8 +51,11 @@ import com.raytheon.uf.common.datadelivery.registry.SubscriptionFixture;
|
||||||
import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandlers;
|
import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandlers;
|
||||||
import com.raytheon.uf.common.datadelivery.registry.handlers.ISubscriptionHandler;
|
import com.raytheon.uf.common.datadelivery.registry.handlers.ISubscriptionHandler;
|
||||||
import com.raytheon.uf.common.datadelivery.service.ISubscriptionNotificationService;
|
import com.raytheon.uf.common.datadelivery.service.ISubscriptionNotificationService;
|
||||||
|
import com.raytheon.uf.common.datadelivery.service.subscription.ISubscriptionOverlapService;
|
||||||
|
import com.raytheon.uf.common.datadelivery.service.subscription.ISubscriptionOverlapService.ISubscriptionOverlapResponse;
|
||||||
import com.raytheon.uf.common.registry.handler.RegistryHandlerException;
|
import com.raytheon.uf.common.registry.handler.RegistryHandlerException;
|
||||||
import com.raytheon.uf.common.registry.handler.RegistryObjectHandlersUtil;
|
import com.raytheon.uf.common.registry.handler.RegistryObjectHandlersUtil;
|
||||||
|
import com.raytheon.uf.common.util.FileUtil;
|
||||||
import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionService.ISubscriptionServiceResult;
|
import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionService.ISubscriptionServiceResult;
|
||||||
import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionService.ForceApplyPromptResponse;
|
import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionService.ForceApplyPromptResponse;
|
||||||
import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionService.IDisplayForceApplyPrompt;
|
import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionService.IDisplayForceApplyPrompt;
|
||||||
|
@ -70,6 +75,7 @@ import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionService.IForceA
|
||||||
* Nov 7, 2012 1286 djohnson Initial creation
|
* Nov 7, 2012 1286 djohnson Initial creation
|
||||||
* Nov 20, 2012 1286 djohnson Rewrite to support proposing subscription stores/updates and force applying.
|
* Nov 20, 2012 1286 djohnson Rewrite to support proposing subscription stores/updates and force applying.
|
||||||
* Jan 02, 2012 1345 djohnson Fix broken tests from using VizApp to move work off the UI thread.
|
* Jan 02, 2012 1345 djohnson Fix broken tests from using VizApp to move work off the UI thread.
|
||||||
|
* May 08, 2000 2013 djohnson Allow checks for duplicate subscriptions.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -105,18 +111,20 @@ public abstract class AbstractSubscriptionServiceTest {
|
||||||
|
|
||||||
final IPermissionsService permissionsService = mock(IPermissionsService.class);
|
final IPermissionsService permissionsService = mock(IPermissionsService.class);
|
||||||
|
|
||||||
|
final ISubscriptionOverlapService subscriptionOverlapService = mock(ISubscriptionOverlapService.class);
|
||||||
|
|
||||||
final IDisplayForceApplyPrompt mockDisplay = mock(IDisplayForceApplyPrompt.class);
|
final IDisplayForceApplyPrompt mockDisplay = mock(IDisplayForceApplyPrompt.class);
|
||||||
|
|
||||||
final SubscriptionService service = new SubscriptionService(
|
final SubscriptionService service = new SubscriptionService(
|
||||||
notificationService, mockBandwidthService, permissionsService,
|
notificationService, mockBandwidthService, permissionsService,
|
||||||
mockDisplay);
|
subscriptionOverlapService, mockDisplay);
|
||||||
|
|
||||||
final IProposeScheduleResponse mockProposeScheduleResponse = mock(IProposeScheduleResponse.class);
|
final IProposeScheduleResponse mockProposeScheduleResponse = mock(IProposeScheduleResponse.class);
|
||||||
|
|
||||||
final IForceApplyPromptDisplayText mockPromptDisplayText = mock(IForceApplyPromptDisplayText.class);
|
final IForceApplyPromptDisplayText mockPromptDisplayText = mock(IForceApplyPromptDisplayText.class);
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() throws RegistryHandlerException {
|
||||||
RegistryObjectHandlersUtil.initMemory();
|
RegistryObjectHandlersUtil.initMemory();
|
||||||
|
|
||||||
when(
|
when(
|
||||||
|
@ -126,6 +134,14 @@ public abstract class AbstractSubscriptionServiceTest {
|
||||||
when(mockBandwidthService.proposeSchedule(any(Subscription.class)))
|
when(mockBandwidthService.proposeSchedule(any(Subscription.class)))
|
||||||
.thenReturn(mockProposeScheduleResponse);
|
.thenReturn(mockProposeScheduleResponse);
|
||||||
|
|
||||||
|
// By default all tests will not find duplicate/overlapping
|
||||||
|
// subscriptions
|
||||||
|
final ISubscriptionOverlapResponse response = mock(ISubscriptionOverlapResponse.class);
|
||||||
|
when(
|
||||||
|
subscriptionOverlapService.isOverlapping(
|
||||||
|
any(Subscription.class), any(Subscription.class)))
|
||||||
|
.thenReturn(response);
|
||||||
|
|
||||||
setupForceApplyPromptDisplayTextValues();
|
setupForceApplyPromptDisplayTextValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +174,7 @@ public abstract class AbstractSubscriptionServiceTest {
|
||||||
|
|
||||||
performServiceInteraction();
|
performServiceInteraction();
|
||||||
|
|
||||||
verifyZeroInteractions(DataDeliveryHandlers.getSubscriptionHandler());
|
verifyOnlyCheckingForDuplicateSubscriptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -295,9 +311,7 @@ public abstract class AbstractSubscriptionServiceTest {
|
||||||
|
|
||||||
performServiceInteraction();
|
performServiceInteraction();
|
||||||
|
|
||||||
final ISubscriptionHandler subscriptionHandler = DataDeliveryHandlers
|
verifyOnlyCheckingForDuplicateSubscriptions();
|
||||||
.getSubscriptionHandler();
|
|
||||||
verifyZeroInteractions(subscriptionHandler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -330,6 +344,45 @@ public abstract class AbstractSubscriptionServiceTest {
|
||||||
verifyBandwidthManagerReinitializeInvoked();
|
verifyBandwidthManagerReinitializeInvoked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOverlappingSubscriptionsNotifiesUser()
|
||||||
|
throws RegistryHandlerException {
|
||||||
|
final ISubscriptionHandler subscriptionHandler = DataDeliveryHandlers
|
||||||
|
.getSubscriptionHandler();
|
||||||
|
|
||||||
|
// Store a duplicate subscription
|
||||||
|
Subscription duplicateSub = sub1.copy("duplicateSub");
|
||||||
|
subscriptionHandler.store(duplicateSub);
|
||||||
|
|
||||||
|
final ISubscriptionOverlapResponse response = mock(ISubscriptionOverlapResponse.class);
|
||||||
|
when(subscriptionOverlapService.isOverlapping(duplicateSub, sub1))
|
||||||
|
.thenReturn(response);
|
||||||
|
when(response.isOverlapping()).thenReturn(true);
|
||||||
|
|
||||||
|
performServiceInteraction();
|
||||||
|
|
||||||
|
verify(mockDisplay).displayMessage(
|
||||||
|
mockPromptDisplayText,
|
||||||
|
ISubscriptionOverlapService.OVERLAPPING_SUBSCRIPTIONS
|
||||||
|
+ FileUtil.EOL
|
||||||
|
+ duplicateSub.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies that the only interactions with the subscription handler are to
|
||||||
|
* check for duplicate/overlapping subscriptions.
|
||||||
|
*
|
||||||
|
* @throws RegistryHandlerException
|
||||||
|
*/
|
||||||
|
protected void verifyOnlyCheckingForDuplicateSubscriptions()
|
||||||
|
throws RegistryHandlerException {
|
||||||
|
final ISubscriptionHandler subscriptionHandler = DataDeliveryHandlers
|
||||||
|
.getSubscriptionHandler();
|
||||||
|
verify(subscriptionHandler, atLeastOnce())
|
||||||
|
.getActiveByDataSetAndProvider(anyString(), anyString());
|
||||||
|
verifyNoMoreInteractions(subscriptionHandler);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that the bandwidth manager was requested to reinitialize itself
|
* Verifies that the bandwidth manager was requested to reinitialize itself
|
||||||
* from the persistent store.
|
* from the persistent store.
|
||||||
|
|
|
@ -28,7 +28,6 @@ import static org.mockito.Matchers.same;
|
||||||
import static org.mockito.Mockito.doThrow;
|
import static org.mockito.Mockito.doThrow;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -60,6 +59,7 @@ import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionService.ISubsc
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Nov 21, 2012 1286 djohnson Initial creation
|
* Nov 21, 2012 1286 djohnson Initial creation
|
||||||
|
* May 08, 2000 2013 djohnson Allow checks for duplicate subscriptions.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -86,7 +86,7 @@ public class SubscriptionServiceMassUpdateTest extends
|
||||||
|
|
||||||
service.updateWithPendingCheck(subs, mockPromptDisplayText);
|
service.updateWithPendingCheck(subs, mockPromptDisplayText);
|
||||||
|
|
||||||
verifyZeroInteractions(DataDeliveryHandlers.getSubscriptionHandler());
|
verifyOnlyCheckingForDuplicateSubscriptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<subscriptionOverlapConfig>
|
||||||
|
<!-- Each value is represented by a percent, 0-100 -->
|
||||||
|
<maxAllowedParameterDuplication>65</maxAllowedParameterDuplication>
|
||||||
|
<maxAllowedForecastHourDuplication>65</maxAllowedForecastHourDuplication>
|
||||||
|
<maxAllowedCycleDuplication>65</maxAllowedCycleDuplication>
|
||||||
|
<maxAllowedSpatialDuplication>65</maxAllowedSpatialDuplication>
|
||||||
|
<!--
|
||||||
|
Available options:
|
||||||
|
MATCH_ANY: Any of the maxAllowed options will
|
||||||
|
cause the subscription to be considered overlapping.
|
||||||
|
|
||||||
|
MATCH_ALL: All maxAllowed options must be exceeded
|
||||||
|
to cause the subscription to be considered overlapping.
|
||||||
|
|
||||||
|
AT_LEAST_HALF: At least half of the maxAllowed options
|
||||||
|
must be exceeded to cause the subscription to be considered
|
||||||
|
overlapping.
|
||||||
|
-->
|
||||||
|
<matchStrategy>MATCH_ANY</matchStrategy>
|
||||||
|
</subscriptionOverlapConfig>
|
Loading…
Add table
Reference in a new issue