Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ep extensions merge #402

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions gsrs-module-substance-example/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -329,13 +329,6 @@
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>io.burt</groupId>
<artifactId>jmespath</artifactId>
<version>0.4.0</version>
<type>pom</type>
</dependency>

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
Expand Down
10 changes: 10 additions & 0 deletions gsrs-module-substances-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,16 @@
<artifactId>batik-svg-dom</artifactId>
<version>1.17</version>
</dependency>
<dependency>
<groupId>io.burt</groupId>
<artifactId>jmespath-core</artifactId>
<version>0.6.0</version>
</dependency>
<dependency>
<groupId>io.burt</groupId>
<artifactId>jmespath-jackson</artifactId>
<version>0.6.0</version>
</dependency>
<dependency>
<groupId>gov.fda.gsrs</groupId>
<artifactId>Featureize-Nitrosamines</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package gsrs.module.substance.exporters;

import com.fasterxml.jackson.databind.ObjectWriter;
import ix.core.controllers.EntityFactory;
import ix.core.validator.GinasProcessingMessage;
import ix.core.validator.ValidationResponse;
import ix.ginas.exporters.Exporter;
import ix.ginas.models.v1.Substance;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import lombok.extern.slf4j.Slf4j;

/**
* Created by Egor Puzanov on 10/18/22.
*/
@Slf4j
public class GsrsApiExporter implements Exporter<Substance> {

private final HttpHeaders headers;
private final BufferedWriter out;
private final RestTemplate restTemplate;
private final boolean allowedExport;
private final boolean validate;
private final String newAuditor;
private final String changeReason;
private final ObjectWriter writer = EntityFactory.EntityMapper.FULL_ENTITY_MAPPER().writer();
private final Pattern AUDIT_PAT = Pattern.compile("edBy\":\"[^\"]*\"");

public GsrsApiExporter(OutputStream out, RestTemplate restTemplate, Map<String, String> headers, boolean allowedExport, boolean validate, String newAuditor, String changeReason) throws IOException {
Objects.requireNonNull(out);
this.out = new BufferedWriter(new OutputStreamWriter(out));
Objects.requireNonNull(restTemplate);
this.restTemplate = restTemplate;
HttpHeaders h = new HttpHeaders();
h.setContentType(MediaType.APPLICATION_JSON);
for (Map.Entry<String, String> entry : headers.entrySet()) {
h.set(entry.getKey(), entry.getValue());
}
this.headers = h;
this.allowedExport = allowedExport;
this.validate = validate;
this.newAuditor = newAuditor != null ? "edBy\":\"" + newAuditor + "\"" : null;
this.changeReason = changeReason;
log.debug("BaseUrl: " + restTemplate.getUriTemplateHandler().expand("/") + " Headers: " + h.toString());
}

private HttpEntity<String> makeRequest(Substance obj) throws Exception {
String jsonStr = writer.writeValueAsString(obj);
if (newAuditor != null) {
jsonStr = AUDIT_PAT.matcher(jsonStr).replaceAll(newAuditor);
}
HttpEntity<String> request = new HttpEntity<String>(jsonStr, headers);
if (validate) {
ValidationResponse vr = restTemplate.postForObject("/@validate", request, ValidationResponse.class);
if (vr.getValidationMessages().isEmpty()) throw new Exception("GSRS API not found");
if (vr.hasError()) throw new Exception(vr.toString());
}
return request;
}

@Override
public void export(Substance obj) throws IOException {
HttpEntity<String> request;
Date date = new Date();
try {
if (!allowedExport) {
throw new Exception("Export denied");
}
if (changeReason != null && obj.version != null) {
obj.changeReason = changeReason.replace("{{version}}", obj.version).replace("{{changeReason}}", obj.changeReason != null ? obj.changeReason : "").trim();
}
try {
obj.version = restTemplate.getForObject("/{uuid}/version", String.class, obj.getUuid().toString()).replace("\"", "");
request = makeRequest(obj);
restTemplate.put("/", request);
} catch (HttpClientErrorException.NotFound ex) {
if (!ex.getMessage().contains("{\"message\":\"not found\",\"status\":404}")) {
throw new Exception(ex.getMessage());
}
obj.version = "1";
String approvalID = obj.getApprovalID();
if (approvalID != null) {
obj.approvalID = null;
}
request = makeRequest(obj);
Substance newObj = restTemplate.postForObject("/", request, Substance.class);
if (newObj.getUuid() == null) throw new Exception("GSRS API not found");
if (approvalID != null) {
obj.approvalID = approvalID;
request = makeRequest(obj);
restTemplate.put("/", request);
}
}
out.write(String.format("%tF %tT Substance: %s %s - SUCCESS", date, date, obj.getUuid().toString(), obj.getName()));
} catch (Exception ex) {
out.write(String.format("%tF %tT Substance: %s %s - ERROR: %s", date, date, obj.getUuid().toString(), obj.getName(), ex.getMessage()));
}
out.newLine();
}

@Override
public void close() throws IOException {
out.close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package gsrs.module.substance.exporters;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;

import gsrs.repository.UserProfileRepository;
import ix.core.models.Role;
import ix.core.models.UserProfile;
import ix.ginas.exporters.Exporter;
import ix.ginas.exporters.ExporterFactory;
import ix.ginas.exporters.OutputFormat;
import ix.ginas.models.v1.Substance;

import java.io.IOException;
import java.io.OutputStream;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.DefaultUriBuilderFactory;


/**
* Created by Egor Puzanov on 10/18/22.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class GsrsApiExporterFactory implements ExporterFactory {

@Autowired
private UserProfileRepository userProfileRepository;

private OutputFormat format = new OutputFormat("gsrsapi", "Send to ...");
private int timeout = 120000;
private boolean trustAllCerts = false;
private boolean validate = true;
private Role allowedRole = null;
private String newAuditor = null;
private String changeReason = null;
private String baseUrl = "http://localhost:8080/api/v1/substances";
private Map<String, String> headers = new HashMap<String, String>();
private final TrustManager[] trustAllCertificates = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
X509Certificate[] certs, String authType) {
}
}
};

private Map<String, String> getHeaders(UserProfile profile) {
Map<String, String> userHeaders = new HashMap<String, String>();
for (Map.Entry<String, String> entry : headers.entrySet()) {
String value = entry.getValue();
switch(value) {
case "{{user.name}}":
value = profile.getIdentifier();
break;
case "{{user.email}}":
value = profile.user.email;
break;
case "{{user.apikey}}":
value = profile.getKey();
break;
default:
break;
}
userHeaders.put(entry.getKey(), value);
}
return userHeaders;
}

public void setFormat(Map<String, String> m) {
this.format = new OutputFormat(m.get("extension"), m.get("displayName"));
}

public void setTimeout(Integer timeout) {
this.timeout = timeout.intValue();
}

public void setTrustAllCerts(boolean trustAllCerts) {
this.trustAllCerts = trustAllCerts;
}

public void setValidate(boolean validate) {
this.validate = validate;
}

public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}

public void setHeaders(Map<String, String> headers) {
this.headers = headers;
}

public void setAllowedRole(String allowedRole) {
this.allowedRole = Role.valueOf(allowedRole);
}

public void setNewAuditor(String newAuditor) {
this.newAuditor = newAuditor;
}

public void setChangeReason(String changeReason) {
this.changeReason = changeReason;
}

@Override
public boolean supports(Parameters params) {
return params.getFormat().equals(format);
}

@Override
public Set<OutputFormat> getSupportedFormats() {
return Collections.singleton(format);
}

@Override
public Exporter<Substance> createNewExporter(OutputStream out, Parameters params) throws IOException {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(timeout)
.build();
HttpClientBuilder client = HttpClients.custom()
.useSystemProperties()
.setDefaultRequestConfig(requestConfig);
if (trustAllCerts) {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCertificates, new SecureRandom());
SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
client = client.setSSLSocketFactory(connectionFactory);
} catch (Exception ex) {
}
}
ClientHttpRequestFactory clientFactory = new HttpComponentsClientHttpRequestFactory(client.build());
RestTemplate restTemplate = new RestTemplate(clientFactory);
restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(baseUrl));
UserProfile profile = userProfileRepository.findByUser_UsernameIgnoreCase(params.getUsername());
boolean allowedExport = (allowedRole == null || profile.hasRole(allowedRole)) ? true : false;
return new GsrsApiExporter(out, restTemplate, getHeaders(profile), allowedExport, validate, newAuditor, changeReason);
}

@Override
public JsonNode getSchema() {
ObjectNode parameters = JsonNodeFactory.instance.objectNode();
return parameters;
}
}
Loading