Summary Table
Categories |
Total Count |
PII |
0 |
URL |
0 |
DNS |
0 |
EKL |
0 |
IP |
0 |
PORT |
0 |
VsID |
0 |
CF |
0 |
AI |
0 |
VPD |
0 |
PL |
0 |
Other |
0 |
File Content
package gov.va.med.pbm.ampl.fhir.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.gclient.ICriterion;
import ca.uhn.fhir.rest.gclient.StringClientParam;
import gov.va.med.pbm.ampl.configuration.FhirConfiguration;
import gov.va.med.pbm.ampl.utility.ESAPIValidator;
import gov.va.med.pbm.ampl.utility.ESAPIValidationType;
import gov.va.med.pbm.ampl.constant.AmplConstants;
/**
* This abstract class is the template for AMPL FHIR clients.
*
* @author Ian Meinert
* @since 1.0
*/
public abstract class AbstractFhirClient {
/**
* The application logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFhirClient.class);
@SuppressWarnings("unused")
private static String sessionId;
private IGenericClient client;
private FhirContext context;
private FhirConfiguration fhirConfiguration;
/**
* The AbstractFhirClient constructor which initializes the {@link IGenericClient}, {@link FhirContext}, and
* {@link FhirConfiguration}.
*
* @param context the {@link FhirContext}
* @param fhirConfiguration the {@link FhirConfiguration}
* @throws IOException thrown by the generateIscSessionId method
*/
public AbstractFhirClient(FhirContext context, FhirConfiguration fhirConfiguration) {
this.fhirConfiguration = fhirConfiguration;
this.context = context;
try {
AbstractFhirClient.sessionId = generateIscSessionId();
this.client = this.context.newRestfulGenericClient(generateFhirServerUrl());
} catch (IOException e) {
LOGGER.error("Unable to instantiate controller", e);
}
}
/**
* The getter for the client.
*
*
* @return IGenericClient
*/
public IGenericClient getClient() {
return client;
}
/**
* The setter for the client.
*
* @param client the FHIR client
*
*/
public void setClient(IGenericClient client) {
this.client = client;
}
/**
* The getter for the context.
*
*
* @return FhirContext
*/
public FhirContext getContext() {
return context;
}
/**
* The setter for the context.
*
* @param context the FHIR context
*
*/
public void setContext(FhirContext context) {
this.context = context;
}
/**
* The getter for the sessionId.
*
* @return the sessionId
*/
public String getSessionId() {
String session = new String();
try {
session = this.generateIscSessionId();
} catch (IOException e) {
LOGGER.error("Error getting the session: " + e);
}
return session;
}
/**
* The setter for the sessionId.
*
* @param sessionId the sessionId to set
*/
public void setSessionId(String sessionId) {
AbstractFhirClient.sessionId = sessionId;
}
/**
* This method generates the {@link StringClientParam} map as required by the FHIR server.
*
* @return a map of {@link StringClientParam}
*/
public ICriterion<StringClientParam> generateSessionParameterMap() {
ICriterion<StringClientParam> parameter = new StringClientParam("iscSessionId").matches().value(this.getSessionId());
return parameter;
}
/**
* This method generates a session Id by opening a connection and requesting a session from the FHIR server.
*
* @deprecated Future session Id's will be provided by the client during OAuth.
*
* @return a FHIR server generated session Id
* @throws IOException when URL is malformed or unable to connect. Also is thrown by buffered reader
*/
private String generateIscSessionId() throws IOException {
BufferedReader br = null;
URL url = new URL(fhirConfiguration.getProtocol(), fhirConfiguration.getHost(),
fhirConfiguration.getPath() + fhirConfiguration.getIscSessionPath());
LOGGER.debug("Generated the url: " + ESAPIValidator.validateLogParam(url.toString()));
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("accept", "text/json");
Optional<InputStream> inputStream = Optional.of(conn.getInputStream());
final StringBuilder sb = new StringBuilder();
try {
br = new BufferedReader(new InputStreamReader(inputStream.get()));
int intChar;
while ((intChar = br.read()) != -1) {
char c = (char) intChar;
try {
// Check the length to mitigate Fortify denial of service vulnerability
if (sb.length() >= AmplConstants.MAX_STR_LEN) {
throw new RuntimeException("Session ID exceeded string buffer length check. "
+ "Fortify has identified this as a possible denial of service attack.");
}
sb.append(c);
} catch (RuntimeException e) {
LOGGER.error("Session ID exceeded string buffer length check. "
+ "Fortify has identified this as a possible denial of service attack.");
}
}
LOGGER.info("Generated the IscSessionId: " + sb.toString());
} finally {
try {
if (inputStream.isPresent()) {
inputStream.get().close();
}
} catch (IOException e) {
LOGGER.error("Error closing Input Stream: " + e);
}
}
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(sb.toString());
JsonNode parameterNode = rootNode.path("parameter");
JsonNode idNode = parameterNode.get(0).path("valueString");
String iscSessionId = idNode.asText();
LOGGER.debug("The id of this session is: " + iscSessionId);
return iscSessionId;
}
/**
* This method generates the URL for FHIR server.
*
* @return generated URL string
* @throws MalformedURLException when the required params are not valid
*/
private String generateFhirServerUrl() throws MalformedURLException {
String url = new URL(fhirConfiguration.getProtocol(), fhirConfiguration.getHost(), fhirConfiguration.getPath())
.toString();
return ESAPIValidator.validateStringInput(url, ESAPIValidationType.URL);
}
}