diff --git a/core/client/pom.xml b/core/client/pom.xml
index 910ce33..60bab47 100644
--- a/core/client/pom.xml
+++ b/core/client/pom.xml
@@ -126,5 +126,9 @@
org.slf4j
slf4j-api
+
+ javax.ws.rs
+ jsr311-api
+
diff --git a/core/client/src/main/java/org/phenotips/remote/client/RemoteMatchingService.java b/core/client/src/main/java/org/phenotips/remote/client/RemoteMatchingService.java
index cecece4..15d32aa 100644
--- a/core/client/src/main/java/org/phenotips/remote/client/RemoteMatchingService.java
+++ b/core/client/src/main/java/org/phenotips/remote/client/RemoteMatchingService.java
@@ -17,6 +17,7 @@
*/
package org.phenotips.remote.client;
+import org.phenotips.matchingnotification.match.PatientMatch;
import org.phenotips.remote.api.OutgoingMatchRequest;
import org.phenotips.remote.common.internal.RemotePatientSimilarityView;
@@ -34,7 +35,8 @@
@Role
public interface RemoteMatchingService
{
- OutgoingMatchRequest sendRequest(String patientId, String remoteServerId, int addTopNGenes);
+ OutgoingMatchRequest sendRequest(String patientId, String remoteServerId, int addTopNGenes,
+ List matchesList);
OutgoingMatchRequest getLastRequestSent(String patientId, String remoteServerId);
diff --git a/core/client/src/main/java/org/phenotips/remote/client/internal/DefaultRemoteMatchingService.java b/core/client/src/main/java/org/phenotips/remote/client/internal/DefaultRemoteMatchingService.java
index 2196f60..5674447 100644
--- a/core/client/src/main/java/org/phenotips/remote/client/internal/DefaultRemoteMatchingService.java
+++ b/core/client/src/main/java/org/phenotips/remote/client/internal/DefaultRemoteMatchingService.java
@@ -24,6 +24,7 @@
import org.phenotips.data.similarity.PatientSimilarityViewFactory;
import org.phenotips.data.similarity.internal.DefaultAccessType;
import org.phenotips.matchingnotification.MatchingNotificationManager;
+import org.phenotips.matchingnotification.match.PatientMatch;
import org.phenotips.remote.api.ApiConfiguration;
import org.phenotips.remote.api.ApiDataConverter;
import org.phenotips.remote.api.ApiViolationException;
@@ -122,7 +123,8 @@ public class DefaultRemoteMatchingService implements RemoteMatchingService
private MatchingNotificationManager notificationManager;
@Override
- public OutgoingMatchRequest sendRequest(String patientId, String remoteServerId, int addTopNGenes)
+ public OutgoingMatchRequest sendRequest(String patientId, String remoteServerId, int addTopNGenes,
+ List matchesList)
{
DefaultOutgoingMatchRequest request =
new DefaultOutgoingMatchRequest(remoteServerId, ApiConfiguration.LATEST_API_VERSION_STRING, patientId);
@@ -209,7 +211,8 @@ public OutgoingMatchRequest sendRequest(String patientId, String remoteServerId,
if (ApiConfiguration.HTTP_OK.equals(httpStatus)) {
List parsedResults = this.getSimilarityResults(request);
- this.notificationManager.saveOutgoingMatches(parsedResults, patientId, request.getRemoteServerId());
+ matchesList.addAll(this.notificationManager.saveOutgoingMatches(parsedResults, patientId,
+ request.getRemoteServerId()));
}
return request;
diff --git a/core/client/src/main/java/org/phenotips/remote/client/internal/RemoteMatchFinder.java b/core/client/src/main/java/org/phenotips/remote/client/internal/RemoteMatchFinder.java
index 45a5d0f..3ac821a 100644
--- a/core/client/src/main/java/org/phenotips/remote/client/internal/RemoteMatchFinder.java
+++ b/core/client/src/main/java/org/phenotips/remote/client/internal/RemoteMatchFinder.java
@@ -22,12 +22,11 @@
import org.phenotips.matchingnotification.finder.MatchFinder;
import org.phenotips.matchingnotification.finder.internal.AbstractMatchFinder;
import org.phenotips.matchingnotification.match.PatientMatch;
-import org.phenotips.matchingnotification.match.internal.CurrentPatientMatch;
+import org.phenotips.remote.api.ApiConfiguration;
import org.phenotips.remote.api.OutgoingMatchRequest;
import org.phenotips.remote.client.RemoteMatchingService;
import org.phenotips.remote.common.ApplicationConfiguration;
import org.phenotips.remote.common.RemoteConfigurationManager;
-import org.phenotips.remote.common.internal.RemotePatientSimilarityView;
import org.xwiki.component.annotation.Component;
import org.xwiki.model.reference.DocumentReferenceResolver;
@@ -41,6 +40,7 @@
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;
+import javax.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
@@ -82,59 +82,65 @@ public int getPriority()
}
@Override
- protected Set getSupportedServerIdList()
+ public Set getSupportedServerIdList()
{
return this.getRemotesList();
}
@Override
- protected MatchRunStatus specificFindMatches(Patient patient, String remoteId, List matchesList)
+ protected Response specificFindMatches(Patient patient, String remoteId, List matchesList)
{
- // Checking if a patient has a consent for remote matching
- if (!this.consentManager.hasConsent(patient, REMOTE_MATCHING_CONSENT_ID)) {
- this.logger.debug("Skipping patient {}. No consent for remote matching", patient.getId());
- return MatchRunStatus.NOT_RUN;
- }
+ try {
+ // Checking if a patient has a consent for remote matching
+ if (!this.consentManager.hasConsent(patient, REMOTE_MATCHING_CONSENT_ID)) {
+ this.logger.debug("Skipping patient {}. No consent for remote matching", patient.getId());
+ return Response.status(Response.Status.FORBIDDEN).build();
+ }
- this.logger.debug("Finding remote matches for patient [{}] on server [{}]", patient.getId(), remoteId);
+ this.logger.debug("Finding remote matches for patient [{}] on server [{}]", patient.getId(), remoteId);
- OutgoingMatchRequest request =
- this.matchingService.sendRequest(patient.getId(), remoteId, ADD_TOP_N_GENES_PARAMETER);
+ OutgoingMatchRequest remoteResponse =
+ this.matchingService.sendRequest(patient.getId(), remoteId, ADD_TOP_N_GENES_PARAMETER, matchesList);
- MatchRunStatus status = checkRequestValidity(request, patient.getId(), remoteId);
- if (status != MatchRunStatus.OK) {
- return status;
- }
-
- List parsedResults = this.matchingService.getSimilarityResults(request);
- for (RemotePatientSimilarityView result : parsedResults) {
- PatientMatch match = new CurrentPatientMatch(result, null, remoteId);
- matchesList.add(match);
- }
- return MatchRunStatus.OK;
- }
+ // If the response is null, the request was never initiated.
+ if (remoteResponse == null) {
+ this.logger.warn("Remote match request to [{}] was never initiated for patient [{}]",
+ remoteId, patient.getId());
+ return Response.status(Response.Status.NO_CONTENT).build();
+ }
- private MatchRunStatus checkRequestValidity(OutgoingMatchRequest request, String patientId, String remoteId)
- {
- if (request != null && request.errorContactingRemoteServer()) {
- this.logger.error("Unable to connect to remote server [{}] to send a request for patient [{}]",
- remoteId, patientId);
- return MatchRunStatus.ERROR;
+ if (!remoteResponse.wasSent()) {
+ if (remoteResponse.errorContactingRemoteServer()) {
+ this.logger.error("Unable to connect to remote server [{}]", remoteId);
+ return Response.status(Response.Status.SERVICE_UNAVAILABLE).build();
+ } else {
+ this.logger.error("Could not initialte an MME match request for patient [{}]", patient.getId());
+ return Response.status(Response.Status.CONFLICT).build();
+ }
+ }
+ // If no valid reply, retrieve the request status code and the JSON.
+ if (!remoteResponse.gotValidReply()) {
+ if (remoteResponse.getRequestStatusCode().equals(ApiConfiguration.HTTP_UNAUTHORIZED)) {
+ this.logger.error("Not authorized to contact selected MME server [{}]", remoteId);
+ return Response.status(Response.Status.UNAUTHORIZED).build();
+ }
+ if (remoteResponse.getRequestStatusCode().equals(ApiConfiguration.HTTP_UNSUPPORTED_API_VERSION)) {
+ this.logger.error("Unsupported MME version when contacting MME server [{}]", remoteId);
+ return Response.status(Response.Status.UNSUPPORTED_MEDIA_TYPE).build();
+ }
+ this.logger.error("Remote MME server [{}] rejected match request with status code [{}]",
+ remoteId, remoteResponse.getRequestStatusCode());
+ this.logger.error(" ...and error details: [{}]", remoteResponse.getResponseJSON());
+ return Response.status(Response.Status.NOT_ACCEPTABLE).build();
}
- if (request == null || !request.wasSent()) {
- this.logger.error("Request for patientId [{}] was not sent to server [{}]", patientId, remoteId);
- return MatchRunStatus.NOT_RUN;
- }
+ return Response.status(Response.Status.OK).build();
- if (!request.gotValidReply()) {
- this.logger.error("Request for patientId {}, remoteId {} returned with status code: {}",
- patientId, remoteId, request.getRequestStatusCode());
- this.logger.error(" ...and error details: [{}]", request.getResponseJSON());
- return MatchRunStatus.ERROR;
+ } catch (final Exception e) {
+ this.logger.error("Unexpected exception while generating remote matches: {}", e.getMessage());
+ return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
- return MatchRunStatus.OK;
}
private Set getRemotesList()
diff --git a/core/pom.xml b/core/pom.xml
index bc550ea..05c60f7 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -35,7 +35,6 @@
common
server
client
- rest
metrics
diff --git a/core/rest/pom.xml b/core/rest/pom.xml
deleted file mode 100644
index fb9d7f6..0000000
--- a/core/rest/pom.xml
+++ /dev/null
@@ -1,147 +0,0 @@
-
-
-
-
-
- 4.0.0
-
- org.phenotips
- remote-matching-core
- 1.3-SNAPSHOT
-
-
- 0.94
-
- remote-matching-core-rest
- Remote Matching - Core - REST
-
-
- com.google.code.findbugs
- jsr305
-
-
- org.xwiki.platform
- xwiki-platform-store-api
- ${xwiki.version}
-
-
- org.xwiki.platform
- xwiki-platform-container-api
- ${xwiki.version}
-
-
- org.xwiki.platform
- xwiki-platform-rest-server
- ${xwiki.version}
-
-
- org.xwiki.commons
- xwiki-commons-component-api
- ${xwiki.version}
-
-
- org.xwiki.commons
- xwiki-commons-context
- ${xwiki.version}
-
-
- org.xwiki.platform
- xwiki-platform-oldcore
- ${xwiki.version}
-
-
- org.xwiki.platform
- xwiki-platform-model
- ${xwiki.version}
-
-
- ${project.groupId}
- remote-matching-core-api
- ${project.version}
-
-
- ${project.groupId}
- remote-matching-core-common
- ${project.version}
-
-
- ${project.groupId}
- remote-matching-core-client
- ${project.version}
-
-
- ${project.groupId}
- matching-notification-api
- ${patientNetwork.version}
-
-
- ${project.groupId}
- patient-data-api
- ${phenotips.version}
-
-
- ${project.groupId}
- patient-similarity-data-impl
- ${patientNetwork.version}
-
-
- ${project.groupId}
- phenotips-rest-commons
- ${phenotips.version}
-
-
- ${project.groupId}
- patient-data-rest
- ${phenotips.version}
-
-
- ${project.groupId}
- patient-similarity-data-api
- ${patientNetwork.version}
-
-
- javax.ws.rs
- jsr311-api
-
-
- org.json
- json
-
-
- org.slf4j
- slf4j-api
-
-
- org.apache.commons
- commons-lang3
-
-
-
- org.xwiki.commons
- xwiki-commons-tool-test-component
- ${xwiki.version}
- test
-
-
- javax.servlet
- javax.servlet-api
- test
-
-
-
diff --git a/core/rest/src/main/java/org/phenotips/remote/rest/RemotePatientMatchResource.java b/core/rest/src/main/java/org/phenotips/remote/rest/RemotePatientMatchResource.java
deleted file mode 100644
index 083f4c6..0000000
--- a/core/rest/src/main/java/org/phenotips/remote/rest/RemotePatientMatchResource.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/
- */
-package org.phenotips.remote.rest;
-
-import org.phenotips.data.rest.PatientResource;
-import org.phenotips.rest.ParentResource;
-import org.phenotips.rest.Relation;
-
-import org.xwiki.stability.Unstable;
-
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-/**
- * Resource for working with remote similar cases data.
- *
- * @version $Id$
- * @since 1.1
- */
-@Unstable("New API introduced in 1.1")
-@Path("/patients/{entity-id}/similar-remote-cases")
-@Relation("https://phenotips.org/rel/patientSimilarityRemote")
-@ParentResource(PatientResource.class)
-public interface RemotePatientMatchResource
-{
- /**
- * Finds matching patients for a provided reference patient. The following additional parameters may be
- * specified:
- *
- *
- * - patientId
- * - the internal identifier for a local reference patient; must be specified
- * - offset
- * - the offset for the returned match data (one-based), must be an int; default value is set to 1
- * - maxResults
- * - the maximum number of matches to return, must be an int; default is -1, which signifies "all matches"
- * - reqNo
- * - the request number, must be an integer; default value is set to 1
- * - server
- * - the remote server to be queried for matching patients; must be specified
- * - sendNewRequest
- * - true iff a new request should be sent to the remote matching server; default value is false
- *
- *
- * @param patientId the identifier of the patient to fetch matches for
- * @return a response containing the reference patient and matched patients data, or an error code if unsuccessful
- */
- @POST
- @Produces(MediaType.APPLICATION_JSON)
- Response findRemoteMatchingPatients(@PathParam("entity-id") String patientId);
-}
diff --git a/core/rest/src/main/java/org/phenotips/remote/rest/internal/DefaultRemotePatientMatchResource.java b/core/rest/src/main/java/org/phenotips/remote/rest/internal/DefaultRemotePatientMatchResource.java
deleted file mode 100644
index d2a1b29..0000000
--- a/core/rest/src/main/java/org/phenotips/remote/rest/internal/DefaultRemotePatientMatchResource.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/
- */
-package org.phenotips.remote.rest.internal;
-
-import org.phenotips.data.Patient;
-import org.phenotips.data.PatientRepository;
-import org.phenotips.data.similarity.MatchedPatientClusterView;
-import org.phenotips.data.similarity.PatientSimilarityView;
-import org.phenotips.matchingnotification.match.PatientMatch;
-import org.phenotips.matchingnotification.storage.MatchStorageManager;
-import org.phenotips.remote.api.ApiConfiguration;
-import org.phenotips.remote.api.OutgoingMatchRequest;
-import org.phenotips.remote.client.RemoteMatchingService;
-import org.phenotips.remote.common.internal.RemotePatientSimilarityView;
-import org.phenotips.remote.rest.RemotePatientMatchResource;
-import org.xwiki.component.annotation.Component;
-import org.xwiki.container.Container;
-import org.xwiki.container.Request;
-import org.xwiki.rest.XWikiResource;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Nonnull;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.apache.commons.lang3.BooleanUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
-import org.json.JSONObject;
-
-/**
- * Default implementation of the {@link RemotePatientMatchResource}.
- *
- * @version $Id$
- * @since 1.1
- */
-@Component
-@Named("org.phenotips.remote.rest.internal.DefaultRemotePatientMatchResource")
-@Singleton
-public class DefaultRemotePatientMatchResource extends XWikiResource implements RemotePatientMatchResource
-{
- private static final String REQ_NO = "reqNo";
-
- private static final String OFFSET = "offset";
-
- private static final String LIMIT = "maxResults";
-
- private static final String SERVER = "server";
-
- private static final String SEND_NEW_REQUEST = "sendNewRequest";
-
- /** The secure patient repository. */
- @Inject
- @Named("secure")
- private PatientRepository repository;
-
- /** The remote similar patients matching service. */
- @Inject
- private RemoteMatchingService matchingService;
-
- /** The XWiki container. */
- @Inject
- private Container container;
-
- @Inject
- private MatchStorageManager matchStorageManager;
-
- @Override
- public Response findRemoteMatchingPatients(final String patientId)
- {
- // Get the request container.
- final Request request = this.container.getRequest();
- // The patient ID must not be blank.
- if (StringUtils.isBlank(patientId)) {
- this.slf4Jlogger.error("Patient ID is not specified.");
- return Response.status(Response.Status.BAD_REQUEST).build();
- }
- // The server must not be blank.
- final String server = (String) request.getProperty(SERVER);
- if (StringUtils.isBlank(server)) {
- this.slf4Jlogger.error("Server is not specified.");
- return Response.status(Response.Status.BAD_REQUEST).build();
- }
- // Get the other parameters, if specified, or set the defaults.
- final int offset = NumberUtils.toInt((String) request.getProperty(OFFSET), 1);
- if (offset < 1) {
- this.slf4Jlogger.error("The requested offset is out of bounds: {}", offset);
- return Response.status(Response.Status.BAD_REQUEST).build();
- }
- final boolean newRequest = BooleanUtils.toBoolean((String) request.getProperty(SEND_NEW_REQUEST));
- final int limit = NumberUtils.toInt((String) request.getProperty(LIMIT), -1);
- final int reqNo = NumberUtils.toInt((String) request.getProperty(REQ_NO), 1);
- // Build the response.
- return buildResponse(patientId, server, offset, limit, newRequest, reqNo);
- }
-
- /**
- * Builds a response containing the reference patient and matched patients data, or an error code if unsuccessful.
- *
- * @param patientId the local reference patient identifier
- * @param server the remote server that will be queried for matches
- * @param offset the offset for the returned matches
- * @param limit the maximum number of matches to return after the offset
- * @param newRequest true iff a new match request should be made to the remote server
- * @param reqNo the current request number
- * @return a {@link Response} containing the matched patients data, or an error code if unsuccessful
- */
- @SuppressWarnings("ReturnCount")
- private Response buildResponse(
- @Nonnull final String patientId,
- @Nonnull final String server,
- final int offset,
- final int limit,
- final boolean newRequest,
- final int reqNo)
- {
- try {
- // Checks if the current user has access to the requested patient.
- final Patient patient = this.repository.get(patientId);
- // If patient with requested ID is not found, this is an error.
- if (patient == null) {
- this.slf4Jlogger.error("Patient with ID: {} could not be found.", patientId);
- return Response.status(Response.Status.BAD_REQUEST).build();
- }
- // don't send any top Exomiser genes in outgoing requests
- final OutgoingMatchRequest remoteResponse = newRequest
- ? this.matchingService.sendRequest(patientId, server, 0)
- : this.matchingService.getLastRequestSent(patientId, server);
-
- // If the response is null, the request was never initiated.
- if (remoteResponse == null) {
- this.slf4Jlogger.warn("Remote match request to [{}] was never initiated for patient [{}]",
- server, patientId);
- return Response.status(Response.Status.NO_CONTENT).build();
- }
-
- if (!remoteResponse.wasSent()) {
- if (remoteResponse.errorContactingRemoteServer()) {
- this.slf4Jlogger.error("Unable to connect to remote server [{}]", server);
- return Response.status(Response.Status.SERVICE_UNAVAILABLE).build();
- } else {
- this.slf4Jlogger.error("Could not initialte an MME match request for patient [{}]", patientId);
- return Response.status(Response.Status.CONFLICT).build();
- }
- }
- // If no valid reply, retrieve the request status code and the JSON.
- if (!remoteResponse.gotValidReply()) {
- if (remoteResponse.getRequestStatusCode().equals(ApiConfiguration.HTTP_UNAUTHORIZED)) {
- this.slf4Jlogger.error("Not authorized to contact selected MME server [{}]", server);
- return Response.status(Response.Status.FORBIDDEN).build();
- }
- if (remoteResponse.getRequestStatusCode().equals(ApiConfiguration.HTTP_UNSUPPORTED_API_VERSION)) {
- this.slf4Jlogger.error("Unsupported MME version when contacting MME server [{}]", server);
- return Response.status(Response.Status.UNSUPPORTED_MEDIA_TYPE).build();
- }
- this.slf4Jlogger.error("Remote MME server [{}] rejected match request with status code [{}]",
- server, remoteResponse.getRequestStatusCode());
- return Response.status(Response.Status.NOT_ACCEPTABLE).build();
- }
-
- return buildMatches(patient, remoteResponse, offset, limit, reqNo);
- } catch (final SecurityException e) {
- this.slf4Jlogger.error("Failed to retrieve patient with ID [{}]: {}", patientId, e.getMessage());
- return Response.status(Response.Status.UNAUTHORIZED).build();
- } catch (final IndexOutOfBoundsException e) {
- this.slf4Jlogger.error("The requested offset [{}] is out of bounds", offset);
- return Response.status(Response.Status.BAD_REQUEST).build();
- } catch (final Exception e) {
- this.slf4Jlogger.error("Unexpected exception while generating remote matches: {}", e.getMessage());
- return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
- }
- }
-
- /**
- * Builds a response containing the reference patient and matched patients data.
- *
- * @param patient the reference {@link Patient} object
- * @param mmeMatchRequest the response received from the remote server
- * @param offset the offset for the returned matches
- * @param limit the maximum number of matches to return after the offset
- * @param reqNo the current request number
- * @return a {@link Response} containing the matched patients data
- */
- private Response buildMatches(
- @Nonnull final Patient patient,
- @Nonnull final OutgoingMatchRequest mmeMatchRequest,
- final int offset,
- final int limit,
- final int reqNo)
- {
- final List matches = this.matchingService.getSimilarityResults(mmeMatchRequest);
-
- // FIXME saveRemoteMatches() is the most reliable way to get PatientMatch ids corresponding to
- // SimilarityViews. However this is inefficient (though with latest Pn code supposedly nothing will
- // be written to the DB if matches do not change), and in the future we need to combine
- // SimilarityView and PatientMatch and operate on a single entity, which would be obtained from
- // a single table.
-
- final Map matchMapping = this.matchStorageManager.saveRemoteMatches(
- matches, patient.getId(), mmeMatchRequest.getRemoteServerId(), false);
-
- final MatchedPatientClusterView matchedCluster =
- new RemoteMatchedPatientClusterView(patient, mmeMatchRequest, matches, matchMapping);
-
- final JSONObject matchesJson = matchedCluster.toJSON(offset - 1, limit);
- matchesJson.put(REQ_NO, reqNo);
- return Response.ok(matchesJson, MediaType.APPLICATION_JSON_TYPE).build();
- }
-}
diff --git a/core/rest/src/main/java/org/phenotips/remote/rest/internal/RemoteMatchedPatientClusterView.java b/core/rest/src/main/java/org/phenotips/remote/rest/internal/RemoteMatchedPatientClusterView.java
deleted file mode 100644
index 9df9a88..0000000
--- a/core/rest/src/main/java/org/phenotips/remote/rest/internal/RemoteMatchedPatientClusterView.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/
- */
-package org.phenotips.remote.rest.internal;
-
-import org.phenotips.data.Patient;
-import org.phenotips.data.similarity.MatchedPatientClusterView;
-import org.phenotips.data.similarity.PatientSimilarityView;
-import org.phenotips.data.similarity.internal.DefaultMatchedPatientClusterView;
-import org.phenotips.matchingnotification.match.PatientMatch;
-import org.phenotips.remote.api.OutgoingMatchRequest;
-import org.phenotips.remote.common.internal.RemotePatientSimilarityView;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.apache.commons.lang3.Validate;
-import org.json.JSONObject;
-
-/**
- * Remote matches implementation of {@link MatchedPatientClusterView} that provides access to the reference patient and
- * its remote matches.
- */
-public class RemoteMatchedPatientClusterView extends DefaultMatchedPatientClusterView implements MatchedPatientClusterView
-{
- private static final String RESPONSE = "response";
-
- private static final String REQUEST = "request";
-
- /** The response from remote server. */
- private final OutgoingMatchRequest mmeMatchRequest;
-
- /**
- * Default constructor that takes a local reference {@code patient}, and its {@code remoteMatches remote matches}.
- *
- * @param patient the local reference {@code patient}
- * @param response the response from the remote server, as {@link OutgoingMatchRequest}
- * @param remoteMatches a list of {@link PatientSimilarityView} objects representing remote matching patients
- * @param matchesIds a map of {@link PatientSimilarityView} objects to the IDs of corresponding matches saved in DB
- */
- public RemoteMatchedPatientClusterView(
- @Nonnull final Patient patient,
- @Nonnull final OutgoingMatchRequest mmeMatchRequest,
- @Nullable final List remoteMatches,
- @Nullable final Map matchesIds)
- {
- super(patient, remoteMatches, matchesIds);
-
- Validate.notNull(mmeMatchRequest, "The remote response must not be null.");
- this.mmeMatchRequest = mmeMatchRequest;
- }
-
- @Override
- public JSONObject toJSON(final int fromIndex, final int maxResults)
- throws IndexOutOfBoundsException
- {
- JSONObject result = super.toJSON(fromIndex, maxResults);
- result.put(REQUEST, this.mmeMatchRequest.getRequestJSON());
- result.put(RESPONSE, this.mmeMatchRequest.getResponseJSON());
- return result;
- }
-
- @Override
- public boolean equals(@Nullable final Object o)
- {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- final RemoteMatchedPatientClusterView that = (RemoteMatchedPatientClusterView) o;
- return Objects.equals(this.mmeMatchRequest, that.mmeMatchRequest) && super.equals(that);
- }
-
- @Override
- public int hashCode()
- {
- return Objects.hash(this.mmeMatchRequest, super.hashCode());
- }
-}
diff --git a/core/rest/src/main/resources/META-INF/components.txt b/core/rest/src/main/resources/META-INF/components.txt
deleted file mode 100644
index 098a595..0000000
--- a/core/rest/src/main/resources/META-INF/components.txt
+++ /dev/null
@@ -1 +0,0 @@
-org.phenotips.remote.rest.internal.DefaultRemotePatientMatchResource
diff --git a/core/rest/src/test/java/org/phenotips/remote/rest/internal/DefaultRemotePatientMatchResourceTest.java b/core/rest/src/test/java/org/phenotips/remote/rest/internal/DefaultRemotePatientMatchResourceTest.java
deleted file mode 100644
index fd270a3..0000000
--- a/core/rest/src/test/java/org/phenotips/remote/rest/internal/DefaultRemotePatientMatchResourceTest.java
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/
- */
-package org.phenotips.remote.rest.internal;
-
-import org.phenotips.data.Patient;
-import org.phenotips.data.PatientRepository;
-import org.phenotips.remote.api.ApiConfiguration;
-import org.phenotips.remote.api.OutgoingMatchRequest;
-import org.phenotips.remote.client.RemoteMatchingService;
-import org.phenotips.remote.common.internal.RemotePatientSimilarityView;
-import org.phenotips.remote.rest.RemotePatientMatchResource;
-import org.xwiki.component.manager.ComponentLookupException;
-import org.xwiki.component.manager.ComponentManager;
-import org.xwiki.container.Container;
-import org.xwiki.context.Execution;
-import org.xwiki.context.ExecutionContext;
-import org.xwiki.store.UnexpectedException;
-import org.xwiki.test.mockito.MockitoComponentMockingRule;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import javax.inject.Provider;
-import javax.ws.rs.core.Response;
-
-import org.apache.commons.lang3.StringUtils;
-import org.json.JSONArray;
-import org.json.JSONObject;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.slf4j.Logger;
-
-import com.xpn.xwiki.XWikiContext;
-
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-/**
- * Unit tests for {@link DefaultRemotePatientMatchResource}.
- */
-public class DefaultRemotePatientMatchResourceTest
-{
- private static final String REFERENCE = "reference";
-
- private static final String MATCH_1 = "match1";
-
- private static final String MATCH_2 = "match2";
-
- private static final String MATCH_3 = "match3";
-
- private static final String SECURE = "secure";
-
- private static final String ID = "id";
-
- private static final String QUERY = "query";
-
- private static final String TOTAL_SIZE = "resultsCount";
-
- private static final String RETURNED_SIZE = "returnedCount";
-
- private static final String RESULTS = "results";
-
- private static final String REQ_NO = "reqNo";
-
- private static final String UNAUTHORIZED_MSG = "User unauthorized";
-
- private static final String UNEXPECTED_MSG = "Unexpected exception";
-
- private static final String LIMIT = "maxResults";
-
- private static final String OFFSET = "offset";
-
- private static final String REMOTE_SERVER = "remoteServer";
-
- private static final String REQUEST_JSON = "requestJson";
-
- private static final String RESPONSE_JSON = "responseJson";
-
- private static final String REQUEST = "request";
-
- private static final String RESPONSE = "response";
-
- private static final String SEND_NEW_REQUEST = "sendNewRequest";
-
- private static final String SERVER = "server";
-
- private static final String ERROR = "error";
-
- @Rule
- public MockitoComponentMockingRule mocker =
- new MockitoComponentMockingRule(DefaultRemotePatientMatchResource.class);
-
- @Mock
- private Patient reference;
-
- @Mock
- private OutgoingMatchRequest response;
-
- @Mock
- private RemotePatientSimilarityView match1;
-
- @Mock
- private RemotePatientSimilarityView match2;
-
- @Mock
- private RemotePatientSimilarityView match3;
-
- @Mock
- private org.xwiki.container.Request request;
-
- private RemotePatientMatchResource component;
-
- private Logger logger;
-
- private PatientRepository repository;
-
- private RemoteMatchingService matchingService;
-
- private JSONObject expectedAll;
-
- @Before
- public void setUp() throws ComponentLookupException
- {
- MockitoAnnotations.initMocks(this);
- final Execution execution = mock(Execution.class);
- final ExecutionContext executionContext = mock(ExecutionContext.class);
- final ComponentManager compManager = this.mocker.getInstance(ComponentManager.class, "context");
- final Provider provider = this.mocker.getInstance(XWikiContext.TYPE_PROVIDER);
- final XWikiContext context = provider.get();
- when(compManager.getInstance(Execution.class)).thenReturn(execution);
- when(execution.getContext()).thenReturn(executionContext);
- when(executionContext.getProperty("xwikicontext")).thenReturn(context);
-
- this.component = this.mocker.getComponentUnderTest();
- // Set up all injected classes.
- this.logger = this.mocker.getMockedLogger();
- this.repository = this.mocker.getInstance(PatientRepository.class, SECURE);
- this.matchingService = this.mocker.getInstance(RemoteMatchingService.class);
-
- // Mock the reference patient.
- when(this.repository.get(REFERENCE)).thenReturn(this.reference);
- when(this.reference.toJSON()).thenReturn(new JSONObject().put(ID, REFERENCE));
-
- // Mock matches search.
- final List matches = Arrays.asList(this.match1, this.match2, this.match3);
- when(this.matchingService.sendRequest(REFERENCE, REMOTE_SERVER, 0)).thenReturn(this.response);
- when(this.matchingService.getLastRequestSent(REFERENCE, REMOTE_SERVER)).thenReturn(this.response);
- when(this.matchingService.getSimilarityResults(this.response)).thenReturn(matches);
-
- // Mock response interactions.
- when(this.response.getRequestJSON()).thenReturn(new JSONObject().put(REQUEST_JSON, REQUEST_JSON));
- when(this.response.getResponseJSON()).thenReturn(new JSONObject().put(RESPONSE_JSON, RESPONSE_JSON));
- when(this.response.gotValidReply()).thenReturn(true);
- when(this.response.wasSent()).thenReturn(true);
-
- final Container container = this.mocker.getInstance(Container.class);
- // Mock container interactions.
- when(container.getRequest()).thenReturn(this.request);
-
- // Mock request data.
- when(this.request.getProperty(SERVER)).thenReturn(REMOTE_SERVER);
- when(this.request.getProperty(SEND_NEW_REQUEST)).thenReturn("false");
- when(this.request.getProperty(OFFSET)).thenReturn("1");
- when(this.request.getProperty(LIMIT)).thenReturn("10");
- when(this.request.getProperty(REQ_NO)).thenReturn("1");
-
- // Mock individual match data.
- when(this.match1.toJSON()).thenReturn(new JSONObject().put(ID, MATCH_1));
- when(this.match2.toJSON()).thenReturn(new JSONObject().put(ID, MATCH_2));
- when(this.match3.toJSON()).thenReturn(new JSONObject().put(ID, MATCH_3));
-
- this.expectedAll = constructAllMatchesJSON();
- }
-
- @Test
- public void findRemoteMatchingPatientsNullPatientIdResultsInBadRequest()
- {
- final Response response = this.component.findRemoteMatchingPatients(null);
- verify(this.logger).error("Patient ID is not specified.");
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientsEmptyPatientIdResultsInBadRequest()
- {
- final Response response = this.component.findRemoteMatchingPatients(StringUtils.EMPTY);
- verify(this.logger).error("Patient ID is not specified.");
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientsBlankPatientIdResultsInBadRequest()
- {
- final Response response = this.component.findRemoteMatchingPatients(StringUtils.SPACE);
- verify(this.logger).error("Patient ID is not specified.");
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientsNullServerResultsInBadRequest()
- {
- when(this.request.getProperty(SERVER)).thenReturn(null);
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.logger).error("Server is not specified.");
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientsEmptyServerResultsInBadRequest()
- {
- when(this.request.getProperty(SERVER)).thenReturn(StringUtils.EMPTY);
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.logger).error("Server is not specified.");
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientsBlankServerResultsInBadRequest()
- {
- when(this.request.getProperty(SERVER)).thenReturn(StringUtils.SPACE);
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.logger).error("Server is not specified.");
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientsPatientDoesNotExistResultsInBadRequest()
- {
- when(this.repository.get(REFERENCE)).thenReturn(null);
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.logger).error("Patient with ID: {} could not be found.", REFERENCE);
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientsUserNotAuthorizedToSeeReferencePatientResultsInUnauthorized()
- {
- when(this.repository.get(REFERENCE)).thenThrow(new SecurityException(UNAUTHORIZED_MSG));
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.logger).error("Failed to retrieve patient with ID [{}]: {}", REFERENCE, UNAUTHORIZED_MSG);
- Assert.assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientRetrieveOldRequestButNoneStoredResultsInNoContent()
- {
- when(this.matchingService.getLastRequestSent(REFERENCE, REMOTE_SERVER)).thenReturn(null);
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.logger).warn("Remote match request to [{}] was never initiated for patient [{}]",
- REMOTE_SERVER, REFERENCE);
- Assert.assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientReturnsProperErrorWhenFailedToConnectToRemoteServer()
- {
- final String message = "I'm not valid.";
- final JSONObject errJSON = new JSONObject().put(ERROR, message);
- when(this.response.gotValidReply()).thenReturn(false);
- when(this.response.wasSent()).thenReturn(false);
- when(this.response.errorContactingRemoteServer()).thenReturn(true);
- when(this.response.getRequestJSON()).thenReturn(errJSON);
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.logger).error("Unable to connect to remote server [{}]", REMOTE_SERVER);
- Assert.assertEquals(Response.Status.SERVICE_UNAVAILABLE.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientReturnsProperErrorWhenNotAuthorizedOnRemoteServer()
- {
- final String message = "I'm not valid.";
- final JSONObject errJSON = new JSONObject().put(ERROR, message);
- when(this.response.gotValidReply()).thenReturn(false);
- when(this.response.getRequestStatusCode()).thenReturn(ApiConfiguration.HTTP_UNAUTHORIZED);
- when(this.response.getRequestJSON()).thenReturn(errJSON);
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.logger).error("Not authorized to contact selected MME server [{}]", REMOTE_SERVER);
- Assert.assertEquals(Response.Status.FORBIDDEN.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientReturnsProperErrorWhenRetrieveOldNonvalidRequest()
- {
- final String message = "I'm not valid.";
- final JSONObject errJSON = new JSONObject().put(ERROR, message);
- when(this.response.gotValidReply()).thenReturn(false);
- when(this.response.getRequestStatusCode()).thenReturn(-1);
- when(this.response.getRequestJSON()).thenReturn(errJSON);
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.logger).error("Remote MME server [{}] rejected match request with status code [{}]",
- REMOTE_SERVER, -1);
- Assert.assertEquals(Response.Status.NOT_ACCEPTABLE.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientsNoMatchesFoundResultsInValidResponse()
- {
- final List matches = Collections.emptyList();
- when(this.matchingService.getSimilarityResults(this.response)).thenReturn(matches);
- final JSONObject expected = new JSONObject()
- .put(QUERY, new JSONObject()
- .put(ID, REFERENCE))
- .put(TOTAL_SIZE, 0)
- .put(REQUEST, this.response.getRequestJSON())
- .put(RESPONSE, this.response.getResponseJSON())
- .put(RETURNED_SIZE, 0)
- .put(REQ_NO, 1)
- .put(OFFSET, 1)
- .put(RESULTS, new JSONArray());
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
- Assert.assertTrue(expected.similar(response.getEntity()));
- }
-
- @Test
- public void findRemoteMatchingPatientsLessThanOneOffsetResultsInBadRequest()
- {
- when(this.request.getProperty(OFFSET)).thenReturn("-1");
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.logger).error("The requested offset is out of bounds: {}", -1);
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientsTooLargeOffsetResultsInBadRequest()
- {
- when(this.request.getProperty(OFFSET)).thenReturn("60");
- when(this.request.getProperty(LIMIT)).thenReturn("80");
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.logger).error("The requested offset [{}] is out of bounds", 60);
- Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
- }
-
- @Test
- public void findRemoteMatchingPatientsOffsetNullDefaultsToOne()
- {
- when(this.request.getProperty(OFFSET)).thenReturn(null);
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
- Assert.assertTrue(this.expectedAll.similar(response.getEntity()));
- }
-
- @Test
- public void findRemoteMatchingPatientsLimitNullDefaultsToNegativeOne()
- {
- when(this.request.getProperty(LIMIT)).thenReturn(null);
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
- Assert.assertTrue(this.expectedAll.similar(response.getEntity()));
- }
-
- @Test
- public void findRemoteMatchingPatientsReqNoNullDefaultsToOne()
- {
- when(this.request.getProperty(REQ_NO)).thenReturn(null);
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
- Assert.assertTrue(this.expectedAll.similar(response.getEntity()));
- }
-
- @Test
- public void findRemoteMatchingPatientsSendNewRequestNullDefaultsToFalse()
- {
- when(this.request.getProperty(SEND_NEW_REQUEST)).thenReturn(null);
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.matchingService, never()).sendRequest(anyString(), anyString(), anyInt());
- verify(this.matchingService, times(1)).getLastRequestSent(REFERENCE, REMOTE_SERVER);
- Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
- Assert.assertTrue(this.expectedAll.similar(response.getEntity()));
- }
-
- @Test
- public void findRemoteMatchingPatientsSendNewRequestTrueWorksAsExpected()
- {
- when(this.request.getProperty(SEND_NEW_REQUEST)).thenReturn("true");
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.matchingService, times(1)).sendRequest(REFERENCE, REMOTE_SERVER, 0);
- verify(this.matchingService, never()).getLastRequestSent(anyString(), anyString());
- Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
- Assert.assertTrue(this.expectedAll.similar(response.getEntity()));
- }
-
- @Test
- public void findRemoteMatchingPatientsLimitBiggerThanMatchesNumberReturnsAllMatchesFromOffset()
- {
- when(this.request.getProperty(LIMIT)).thenReturn("80");
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
- Assert.assertTrue(this.expectedAll.similar(response.getEntity()));
- }
-
- @Test
- public void findRemoteMatchingPatientsLimitNegativeReturnsAllMatchesFromOffset()
- {
- when(this.request.getProperty(OFFSET)).thenReturn("2");
- when(this.request.getProperty(LIMIT)).thenReturn("-1");
- final JSONObject expected = new JSONObject()
- .put(QUERY, new JSONObject()
- .put(ID, REFERENCE))
- .put(TOTAL_SIZE, 3)
- .put(REQUEST, this.response.getRequestJSON())
- .put(RESPONSE, this.response.getResponseJSON())
- .put(RETURNED_SIZE, 2)
- .put(REQ_NO, 1)
- .put(OFFSET, 2)
- .put(RESULTS, new JSONArray()
- .put(this.match2.toJSON())
- .put(this.match3.toJSON()));
-
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
- Assert.assertTrue(expected.similar(response.getEntity()));
- }
-
- @Test
- public void findRemoteMatchingPatientsLimitLessThanLastResultReturnsCorrectSubset()
- {
- when(this.request.getProperty(OFFSET)).thenReturn("2");
- when(this.request.getProperty(LIMIT)).thenReturn("1");
- final JSONObject expected = new JSONObject()
- .put(QUERY, new JSONObject()
- .put(ID, REFERENCE))
- .put(TOTAL_SIZE, 3)
- .put(REQUEST, this.response.getRequestJSON())
- .put(RESPONSE, this.response.getResponseJSON())
- .put(RETURNED_SIZE, 1)
- .put(REQ_NO, 1)
- .put(OFFSET, 2)
- .put(RESULTS, new JSONArray()
- .put(this.match2.toJSON()));
-
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
- Assert.assertTrue(expected.similar(response.getEntity()));
- }
-
- @Test
- public void findRemoteMatchingPatientsUnexpectedExceptionIsThrown()
- {
- when(this.repository.get(REFERENCE)).thenThrow(new UnexpectedException(UNEXPECTED_MSG));
- final Response response = this.component.findRemoteMatchingPatients(REFERENCE);
- verify(this.logger).error("Unexpected exception while generating remote matches: {}", UNEXPECTED_MSG);
- Assert.assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
- }
- private JSONObject constructAllMatchesJSON()
- {
- return new JSONObject()
- .put(QUERY, new JSONObject()
- .put(ID, REFERENCE))
- .put(TOTAL_SIZE, 3)
- .put(REQUEST, this.response.getRequestJSON())
- .put(RESPONSE, this.response.getResponseJSON())
- .put(RETURNED_SIZE, 3)
- .put(REQ_NO, 1)
- .put(OFFSET, 1)
- .put(RESULTS, new JSONArray()
- .put(this.match1.toJSON())
- .put(this.match2.toJSON())
- .put(this.match3.toJSON()));
- }
-}
diff --git a/core/rest/src/test/java/org/phenotips/remote/rest/internal/RemoteMatchedPatientClusterViewTest.java b/core/rest/src/test/java/org/phenotips/remote/rest/internal/RemoteMatchedPatientClusterViewTest.java
deleted file mode 100644
index 21a98b6..0000000
--- a/core/rest/src/test/java/org/phenotips/remote/rest/internal/RemoteMatchedPatientClusterViewTest.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * See the NOTICE file distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/
- */
-package org.phenotips.remote.rest.internal;
-
-import org.phenotips.data.Patient;
-import org.phenotips.data.similarity.MatchedPatientClusterView;
-import org.phenotips.data.similarity.PatientSimilarityView;
-import org.phenotips.remote.api.OutgoingMatchRequest;
-import org.phenotips.remote.common.internal.RemotePatientSimilarityView;
-
-import org.xwiki.model.reference.DocumentReference;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.json.JSONArray;
-import org.json.JSONObject;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-/**
- * Unit tests for {@link RemoteMatchedPatientClusterView}.
- */
-public class RemoteMatchedPatientClusterViewTest
-{
- private static final String ID_LABEL = "id";
-
- private static final String REFERENCE = "reference";
-
- private static final String PATIENT_1 = "patient1";
-
- private static final String PATIENT_2 = "patient2";
-
- private static final String PATIENT_3 = "patient3";
-
- private static final String PATIENT_4 = "patient4";
-
- private static final String PATIENT_5 = "patient5";
-
- private static final String QUERY_LABEL = "query";
-
- private static final String TOTAL_LABEL = "resultsCount";
-
- private static final String RETURNED_LABEL = "returnedCount";
-
- private static final String RESULTS_LABEL = "results";
-
- private static final String OFFSET_LABEL = "offset";
-
- private static final String REQUEST_JSON = "requestJSON";
-
- private static final String RESPONSE_JSON = "responseJSON";
-
- private static final String REQUEST = "request";
-
- private static final String RESPONSE = "response";
-
- @Mock
- private Patient reference;
-
- @Mock
- private DocumentReference docRef;
-
- @Mock
- private RemotePatientSimilarityView patient1;
-
- @Mock
- private DocumentReference doc1;
-
- @Mock
- private RemotePatientSimilarityView patient2;
-
- @Mock
- private DocumentReference doc2;
-
- @Mock
- private RemotePatientSimilarityView patient3;
-
- @Mock
- private DocumentReference doc3;
-
- @Mock
- private RemotePatientSimilarityView patient4;
-
- @Mock
- private DocumentReference doc4;
-
- @Mock
- private RemotePatientSimilarityView patient5;
-
- @Mock
- private DocumentReference doc5;
-
- @Mock
- private OutgoingMatchRequest response;
-
- private RemoteMatchedPatientClusterView matches;
-
- private List matchList;
-
- @Before
- public void setUp()
- {
- MockitoAnnotations.initMocks(this);
-
- when(this.reference.toJSON()).thenReturn(new JSONObject().put(ID_LABEL, REFERENCE));
- when(this.reference.getDocumentReference()).thenReturn(this.docRef);
-
- when(this.patient1.toJSON()).thenReturn(new JSONObject().put(ID_LABEL, PATIENT_1));
- when(this.patient1.getDocumentReference()).thenReturn(this.doc1);
-
- when(this.patient2.toJSON()).thenReturn(new JSONObject().put(ID_LABEL, PATIENT_2));
- when(this.patient2.getDocumentReference()).thenReturn(this.doc2);
-
- when(this.patient3.toJSON()).thenReturn(new JSONObject().put(ID_LABEL, PATIENT_3));
- when(this.patient3.getDocumentReference()).thenReturn(this.doc3);
-
- when(this.patient4.toJSON()).thenReturn(new JSONObject().put(ID_LABEL, PATIENT_4));
- when(this.patient4.getDocumentReference()).thenReturn(this.doc4);
-
- when(this.patient5.toJSON()).thenReturn(new JSONObject().put(ID_LABEL, PATIENT_5));
- when(this.patient5.getDocumentReference()).thenReturn(this.doc5);
-
- when(this.response.getRequestJSON()).thenReturn(new JSONObject().put(REQUEST_JSON, REQUEST_JSON));
- when(this.response.getResponseJSON()).thenReturn(new JSONObject().put(RESPONSE_JSON, RESPONSE_JSON));
-
- this.matchList = Arrays.asList(this.patient1, this.patient2, this.patient3, this.patient4, this.patient5);
- this.matches = new RemoteMatchedPatientClusterView(this.reference, this.response, this.matchList, null);
- }
-
- @Test(expected = NullPointerException.class)
- public void instantiatingClassWithNullPatientThrowsException()
- {
- new RemoteMatchedPatientClusterView(null, this.response, this.matchList, null);
- }
-
- @Test(expected = NullPointerException.class)
- public void instantiatingClassWithNullResponseThrowsException()
- {
- new RemoteMatchedPatientClusterView(this.reference, null, this.matchList, null);
- }
-
- @Test
- public void getReferenceReturnsTheReferenceThatWasSet()
- {
- Assert.assertEquals(this.reference, this.matches.getReference());
- }
-
- @Test
- public void getMatchesReturnsEmptyListIfNoMatchesSet()
- {
- final MatchedPatientClusterView matches = new RemoteMatchedPatientClusterView(this.reference, this.response,
- Collections.emptyList(), null);
- Assert.assertTrue(matches.getMatches().isEmpty());
- }
-
- @Test
- public void getMatchesReturnsTheMatchesThatWereProvided()
- {
- Assert.assertEquals(this.matchList, this.matches.getMatches());
- }
-
- @Test(expected = UnsupportedOperationException.class)
- public void getMatchesReturnedMatchesCannotBeModified()
- {
- this.matches.getMatches().add(mock(PatientSimilarityView.class));
- }
-
- @Test
- public void sizeIsZeroIfMatchesIsEmpty()
- {
- final MatchedPatientClusterView matches = new RemoteMatchedPatientClusterView(this.reference, this.response,
- Collections.emptyList(), null);
- Assert.assertEquals(0, matches.size());
- }
-
- @Test
- public void sizeReturnsCorrectNumberOfMatches()
- {
- Assert.assertEquals(5, this.matches.size());
- }
-
- @Test(expected = IndexOutOfBoundsException.class)
- public void toJSONThrowsExceptionIfFromIndexInvalid()
- {
- this.matches.toJSON(-1, 3);
- }
-
- @Test(expected = IndexOutOfBoundsException.class)
- public void toJSONThrowsExceptionIfFromIndexIsGreaterThanDataSize()
- {
- this.matches.toJSON(300, 10);
- }
-
- @Test
- public void toJSONGetsCorrectDataForProvidedIndices()
- {
- final JSONObject result = this.matches.toJSON(1, 3);
- final JSONObject expected = new JSONObject()
- .put(QUERY_LABEL, new JSONObject()
- .put(ID_LABEL, REFERENCE))
- .put(TOTAL_LABEL, 5)
- .put(REQUEST, this.response.getRequestJSON())
- .put(RESPONSE, this.response.getResponseJSON())
- .put(RETURNED_LABEL, 3)
- .put(OFFSET_LABEL, 2)
- .put(RESULTS_LABEL, new JSONArray()
- .put(new JSONObject()
- .put(ID_LABEL, PATIENT_2))
- .put(new JSONObject()
- .put(ID_LABEL, PATIENT_3))
- .put(new JSONObject()
- .put(ID_LABEL, PATIENT_4)));
- Assert.assertTrue(expected.similar(result));
- }
-
- @Test
- public void toJSONGetsAllDataIfNoIndicesProvided()
- {
- final JSONObject result = this.matches.toJSON();
- final JSONObject expected = new JSONObject()
- .put(QUERY_LABEL, new JSONObject()
- .put(ID_LABEL, REFERENCE))
- .put(TOTAL_LABEL, 5)
- .put(REQUEST, this.response.getRequestJSON())
- .put(RESPONSE, this.response.getResponseJSON())
- .put(RETURNED_LABEL, 5)
- .put(OFFSET_LABEL, 1)
- .put(RESULTS_LABEL, new JSONArray()
- .put(new JSONObject()
- .put(ID_LABEL, PATIENT_1))
- .put(new JSONObject()
- .put(ID_LABEL, PATIENT_2))
- .put(new JSONObject()
- .put(ID_LABEL, PATIENT_3))
- .put(new JSONObject()
- .put(ID_LABEL, PATIENT_4))
- .put(new JSONObject()
- .put(ID_LABEL, PATIENT_5)));
- Assert.assertTrue(expected.similar(result));
- }
-
- @Test
- public void equalsReturnsTrueForTwoDifferentObjectsWithSameData()
- {
- final MatchedPatientClusterView v2 = new RemoteMatchedPatientClusterView(this.reference, this.response,
- this.matchList, null);
- Assert.assertTrue(v2.equals(this.matches));
- }
-
- @Test
- public void equalsReturnsTrueForTwoIdenticalObjects()
- {
- Assert.assertTrue(this.matches.equals(this.matches));
- }
-
- @Test
- public void equalsReturnsFalseForTwoDifferentObjectsWithDifferentResponses()
- {
- final OutgoingMatchRequest response2 = mock(OutgoingMatchRequest.class);
- final MatchedPatientClusterView v2 = new RemoteMatchedPatientClusterView(this.reference, response2,
- this.matchList, null);
- Assert.assertFalse(v2.equals(this.matches));
- }
-
- @Test
- public void equalsReturnsFalseForTwoDifferentObjectsWithDifferentReference()
- {
- final MatchedPatientClusterView v2 = new RemoteMatchedPatientClusterView(mock(Patient.class), this.response,
- this.matchList, null);
- Assert.assertFalse(v2.equals(this.matches));
- }
-
- @Test
- public void equalsReturnsFalseForTwoDifferentObjectsWithDifferentMatchList()
- {
- final List m2 = Arrays.asList(this.patient1, this.patient2, this.patient3);
- final MatchedPatientClusterView v2 = new RemoteMatchedPatientClusterView(this.reference, this.response, m2, null);
- Assert.assertFalse(v2.equals(this.matches));
- }
-
- @Test
- public void hashCodeIsTheSameForTwoObjectsWithSameData()
- {
- final MatchedPatientClusterView v2 = new RemoteMatchedPatientClusterView(this.reference, this.response,
- this.matchList, null);
- Assert.assertEquals(v2.hashCode(), this.matches.hashCode());
- }
-}