Skip to content

Commit

Permalink
Issue #2504 - Check affectsState
Browse files Browse the repository at this point in the history
Signed-off-by: Troy Biesterfeld <tbieste@us.ibm.com>
  • Loading branch information
tbieste committed Sep 7, 2021
1 parent c91bd58 commit aceffbd
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
import com.ibm.fhir.model.resource.OperationDefinition;
import com.ibm.fhir.model.resource.OperationOutcome;
import com.ibm.fhir.model.resource.Parameters;
import com.ibm.fhir.model.resource.Parameters.Parameter;
import com.ibm.fhir.model.resource.Resource;
import com.ibm.fhir.model.type.code.IssueType;
import com.ibm.fhir.model.type.code.OperationParameterUse;
import com.ibm.fhir.model.type.code.ResourceType;
import com.ibm.fhir.model.util.FHIRUtil;
import com.ibm.fhir.model.util.ModelSupport;
import com.ibm.fhir.server.util.FHIROperationUtil;

public abstract class AbstractOperation implements FHIROperation {
protected final OperationDefinition definition;
Expand Down Expand Up @@ -51,7 +53,7 @@ public final Parameters invoke(
String logicalId, String versionId,
Parameters parameters,
FHIRResourceHelpers resourceHelper) throws FHIROperationException {
validateOperationContext(operationContext, resourceType);
validateOperationContext(operationContext, resourceType, parameters);
validateInputParameters(operationContext, resourceType, logicalId, versionId, parameters);
Parameters result = doInvoke(operationContext, resourceType, logicalId, versionId, parameters, resourceHelper);
validateOutputParameters(result);
Expand Down Expand Up @@ -129,8 +131,17 @@ protected void validateInputParameters(
validateParameters(parameters, OperationParameterUse.IN);
}

protected void validateOperationContext(FHIROperationContext operationContext, Class<? extends Resource> resourceType) throws FHIROperationException {
protected void validateOperationContext(FHIROperationContext operationContext, Class<? extends Resource> resourceType, Parameters parameters) throws FHIROperationException {
OperationDefinition definition = getDefinition();

// Check which methods are allowed
String method = (String) operationContext.getProperty(FHIROperationContext.PROPNAME_METHOD_TYPE);
if (!"POST".equalsIgnoreCase(method)
&& (!"GET".equalsIgnoreCase(method) || !isGetMethodAllowed(definition, parameters))
&& !isAdditionalMethodAllowed(method)) {
throw FHIROperationUtil.buildExceptionWithIssue("HTTP method not supported: " + method, IssueType.NOT_SUPPORTED);
}

switch (operationContext.getType()) {
case INSTANCE:
if (definition.getInstance().getValue() == false) {
Expand All @@ -157,6 +168,45 @@ protected void validateOperationContext(FHIROperationContext operationContext, C
}
}

/**
* Determines if the operation disallows the GET method.
* This is determined by the affectsState value of the OperatorDefinition and whether the
* OperatorDefinition contains any non-primitive parameters.
* @param operationDefinition the operation definition
* @param parameters the parameters
* @return true or false
*/
private boolean isGetMethodAllowed(OperationDefinition operationDefinition, Parameters parameters) {
// Check if affectState is true
if (operationDefinition.getAffectsState() != null && operationDefinition.getAffectsState().getValue() == Boolean.TRUE) {
return false;
}
// Check for any non-primitive parameters passed in
if (parameters != null && operationDefinition.getParameter() != null) {
for (Parameter parameter : parameters.getParameter()) {
// Determine if parameter is non-primative by checking the operation definition for the parameter type
for (OperationDefinition.Parameter odParameter : operationDefinition.getParameter()) {
if (parameter.getName().getValue() != null && odParameter.getName() != null
&& parameter.getName().getValue().equals(odParameter.getName().getValue())
&& (odParameter.getType() == null || !ModelSupport.isPrimitiveType(ModelSupport.getDataType(odParameter.getType().getValue()))
|| (odParameter.getPart() != null && !odParameter.getPart().isEmpty()))) {
return false;
}
}
}
}
return true;
}

/**
* Determines if any methods (except GET and POST) are allowed for the operation.
* This can be overridden by an operation to allow additional methods.
* @return true or false
*/
protected boolean isAdditionalMethodAllowed(String method) {
return false;
}

/**
* Determines if the operation disallows abstract resource types, Resource and DomainResource.
* TODO: Remove this method when Issue #2526 is implemented, at which time, abstract resource types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,6 @@ protected Parameters doInvoke(FHIROperationContext operationContext, Class<? ext
common.checkEnabled();
common.checkAllowed(operationContext, true);

if (!"POST".equals(operationContext.getProperty(FHIROperationContext.PROPNAME_METHOD_TYPE))) {
throw buildExceptionWithIssue("Invalid call $import operation only POST allowed",
IssueType.INVALID);
}

// Checks the Import Type
checkImportType(operationContext.getType());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,10 @@ protected Parameters doInvoke(FHIROperationContext operationContext, Class<? ext
throw buildExceptionWithIssue("Invalid call $bulkdata-status operation call", IssueType.INVALID);
}
}

@Override
protected boolean isAdditionalMethodAllowed(String method) {
return "DELETE".equalsIgnoreCase(method);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
}
],
"description": "Pre ballot version of Bulk Data Import using the Parameters Object",
"affectsState": true,
"code": "import",
"system": true,
"type": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,6 @@ protected Parameters doInvoke(FHIROperationContext operationContext, Class<? ext
String logicalId, String versionId, Parameters parameters, FHIRResourceHelpers resourceHelper)
throws FHIROperationException {

// Allow only POST because we're changing the state of the database
String method = (String) operationContext.getProperty(FHIROperationContext.PROPNAME_METHOD_TYPE);
if (!"POST".equalsIgnoreCase(method)) {
throw FHIROperationUtil.buildExceptionWithIssue("HTTP method not supported: " + method, IssueType.NOT_SUPPORTED);
}

try {
Instant tstamp = Instant.now();
List<Long> indexIds = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import com.ibm.fhir.model.resource.OperationDefinition;
import com.ibm.fhir.model.resource.Parameters;
import com.ibm.fhir.model.resource.Resource;
import com.ibm.fhir.model.type.code.IssueType;
import com.ibm.fhir.server.operation.spi.AbstractOperation;
import com.ibm.fhir.server.operation.spi.FHIROperationContext;
import com.ibm.fhir.server.operation.spi.FHIRResourceHelpers;
Expand Down Expand Up @@ -74,12 +73,6 @@ protected Parameters doInvoke(FHIROperationContext operationContext, Class<? ext
String logicalId, String versionId, Parameters parameters, FHIRResourceHelpers resourceHelper)
throws FHIROperationException {

// Only GET or POST is allowed
String method = (String) operationContext.getProperty(FHIROperationContext.PROPNAME_METHOD_TYPE);
if (!"GET".equalsIgnoreCase(method) && !"POST".equalsIgnoreCase(method)) {
throw FHIROperationUtil.buildExceptionWithIssue("HTTP method not supported: " + method, IssueType.NOT_SUPPORTED);
}

try {
String indexIdsString = "";
int count = MAX_COUNT;
Expand Down

0 comments on commit aceffbd

Please sign in to comment.