diff --git a/ui-backend/catalog-ui-search/pom.xml b/ui-backend/catalog-ui-search/pom.xml
index c4c85cf8d65..e63437fc9ca 100644
--- a/ui-backend/catalog-ui-search/pom.xml
+++ b/ui-backend/catalog-ui-search/pom.xml
@@ -390,6 +390,11 @@
catalog-rest-api
${ddf.version}
+
+ ddf.catalog.rest
+ catalog-rest-endpoint
+ ${ddf.version}
+
com.google.guava
guava
@@ -492,7 +497,8 @@
ows-v_1_1_0-schema,
jaxb2-basics-runtime,
catalog-rest-service,
- owasp-java-html-sanitizer
+ owasp-java-html-sanitizer,
+ catalog-rest-endpoint
${project.artifactId}
diff --git a/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/catalog/CatalogApplication.java b/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/catalog/CatalogApplication.java
index a70bd38719e..52fa1b68b09 100644
--- a/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/catalog/CatalogApplication.java
+++ b/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/catalog/CatalogApplication.java
@@ -35,15 +35,23 @@
import javax.servlet.MultipartConfigElement;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.InternalServerErrorException;
+import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
import org.apache.commons.codec.CharEncoding;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.cxf.jaxrs.impl.UriBuilderImpl;
import org.apache.http.HttpStatus;
+import org.codice.ddf.catalog.ui.config.ConfigurationApplication;
+import org.codice.ddf.catalog.ui.util.jaxrs.JaxRsHttpHeaders;
+import org.codice.ddf.catalog.ui.util.jaxrs.JaxRsUriInfo;
+import org.codice.ddf.catalog.ui.util.multipart.CleanableMultipartBody;
+import org.codice.ddf.catalog.ui.util.multipart.CleanableMultipartBodyFactory;
+import org.codice.ddf.endpoints.rest.RESTEndpoint;
import org.codice.ddf.rest.api.CatalogService;
import org.codice.ddf.rest.api.CatalogServiceException;
import org.slf4j.Logger;
@@ -66,16 +74,27 @@ public class CatalogApplication implements SparkApplication {
private static final String HEADER_ACCEPT_RANGES = "Accept-Ranges";
+ private static final String HEADER_ID = "id";
+
private static final String BYTES = "bytes";
+ private static final String CATALOG_PATH = "/catalog/";
+
private static final String CATALOG_ID_PATH = "/catalog/:id";
private static final String TRANSFORM = "transform";
+ private final ConfigurationApplication config;
+
private CatalogService catalogService;
- public CatalogApplication(CatalogService catalogService) {
+ private RESTEndpoint restEndpoint;
+
+ public CatalogApplication(
+ CatalogService catalogService, RESTEndpoint restEndpoint, ConfigurationApplication config) {
this.catalogService = catalogService;
+ this.restEndpoint = restEndpoint;
+ this.config = config;
}
@Override
@@ -141,35 +160,52 @@ public void init() {
});
post(
- "/catalog/",
+ CATALOG_PATH,
(req, res) -> {
- if (req.contentType().startsWith("multipart/")) {
- req.attribute(
- ECLIPSE_MULTIPART_CONFIG,
- new MultipartConfigElement(System.getProperty(JAVA_IO_TMPDIR)));
+ try {
+ LOGGER.debug("POST Path: {}", CATALOG_PATH);
+ String contentType = req.contentType();
+
+ // Convert req and res for RESTEndpoint
+ HttpServletRequest httpRequest = req.raw();
+ HttpHeaders headers = new JaxRsHttpHeaders(req);
+ UriInfo uriInfo = new JaxRsUriInfo(req);
+ String transformerParam = req.queryParams(TRANSFORM);
+ InputStream inputStream = httpRequest.getInputStream();
+
+ if (contentType.startsWith("multipart/")) {
+ LOGGER.debug("POST Path: {} multipart", CATALOG_PATH);
+ CleanableMultipartBody multipartBody =
+ CleanableMultipartBodyFactory.create(
+ httpRequest, config.getMaximumUploadSize(), config.getMaxFileSizeInMemory());
+
+ javax.ws.rs.core.Response response =
+ restEndpoint.addDocument(
+ headers, uriInfo, httpRequest, multipartBody, transformerParam, inputStream);
+
+ multipartBody.cleanup();
+
+ return setResponse(
+ res, httpRequest.getRequestURL(), response.getHeaderString(HEADER_ID));
+ }
- return addDocument(
- res,
- req.raw().getRequestURL(),
- req.contentType(),
- req.queryParams(TRANSFORM),
- req.raw(),
- new ByteArrayInputStream(req.bodyAsBytes()));
- }
+ if (contentType.startsWith("text/") || contentType.startsWith("application/")) {
+ LOGGER.debug("POST Path: {} text/application", CATALOG_PATH);
+ javax.ws.rs.core.Response response =
+ restEndpoint.addDocument(
+ headers, uriInfo, httpRequest, transformerParam, inputStream);
- if (req.contentType().startsWith("text/")
- || req.contentType().startsWith("application/")) {
- return addDocument(
- res,
- req.raw().getRequestURL(),
- req.contentType(),
- req.queryParams(TRANSFORM),
- null,
- new ByteArrayInputStream(req.bodyAsBytes()));
- }
+ return setResponse(
+ res, httpRequest.getRequestURL(), response.getHeaderString(HEADER_ID));
+ }
- res.status(HttpStatus.SC_NOT_FOUND);
- return res;
+ res.status(HttpStatus.SC_NOT_FOUND);
+ return "Not Found";
+ } catch (Exception e) {
+ LOGGER.error("Unexpected error in request handler", e);
+ res.status(HttpStatus.SC_INTERNAL_SERVER_ERROR);
+ return "Internal Server Error";
+ }
});
put(
@@ -373,19 +409,8 @@ private String updateDocument(
}
}
- private String addDocument(
- Response res,
- StringBuffer requestUrl,
- String contentType,
- String transformerParam,
- HttpServletRequest httpServletRequest,
- InputStream inputStream) {
+ private String setResponse(Response res, StringBuffer requestUrl, String id) {
try {
- List contentTypeList = ImmutableList.of(contentType);
- String id =
- catalogService.addDocument(
- contentTypeList, httpServletRequest, transformerParam, inputStream);
-
URI uri = new URI(requestUrl.toString());
UriBuilder uriBuilder = new UriBuilderImpl(uri).path("/" + id);
@@ -394,7 +419,7 @@ private String addDocument(
res.header(Metacard.ID, id);
return "";
- } catch (CatalogServiceException | URISyntaxException e) {
+ } catch (URISyntaxException e) {
return createBadRequestResponse(res, e.getMessage());
}
}
diff --git a/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/config/ConfigurationApplication.java b/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/config/ConfigurationApplication.java
index 439b030e8f2..e8884299963 100644
--- a/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/config/ConfigurationApplication.java
+++ b/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/config/ConfigurationApplication.java
@@ -168,7 +168,8 @@ public class ConfigurationApplication implements SparkApplication {
private String mapHome = "";
- private int maximumUploadSize = 1_048_576;
+ private long maximumUploadSize = 1_048_576;
+ private int maxFileSizeInMemory = 50 * 1024 * 1024; // 50 MB
private List readOnly =
ImmutableList.of(
@@ -402,11 +403,11 @@ public void setResultShow(List resultShow) {
this.resultShow = resultShow;
}
- public void setMaximumUploadSize(int size) {
+ public void setMaximumUploadSize(long size) {
this.maximumUploadSize = size;
}
- public int getMaximumUploadSize() {
+ public long getMaximumUploadSize() {
return maximumUploadSize;
}
@@ -573,6 +574,8 @@ public Map getConfig() {
config.put("menuIconSrc", menuIconSrc);
config.put("customBranding", customBranding);
config.put("extra", extra);
+ config.put("maximumUploadSize", maximumUploadSize);
+ config.put("maxFileSizeInMemory", maxFileSizeInMemory);
return config;
}
@@ -1264,4 +1267,12 @@ public String getMenuIconSrc() {
public void setMenuIconSrc(String menuIconSrc) {
this.menuIconSrc = menuIconSrc;
}
+
+ public void setMaxFileSizeInMemory(int size) {
+ this.maxFileSizeInMemory = size;
+ }
+
+ public int getMaxFileSizeInMemory() {
+ return maxFileSizeInMemory;
+ }
}
diff --git a/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/util/jaxrs/JaxRsHttpHeaders.java b/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/util/jaxrs/JaxRsHttpHeaders.java
new file mode 100644
index 00000000000..2e7c61e5658
--- /dev/null
+++ b/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/util/jaxrs/JaxRsHttpHeaders.java
@@ -0,0 +1,80 @@
+package org.codice.ddf.catalog.ui.util.jaxrs;
+
+import java.util.*;
+import javax.ws.rs.core.Cookie;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import spark.Request;
+
+public class JaxRsHttpHeaders implements HttpHeaders {
+ private static final Logger LOGGER = LoggerFactory.getLogger(JaxRsHttpHeaders.class);
+ private final Request sparkRequest;
+
+ public JaxRsHttpHeaders(Request sparkRequest) {
+ this.sparkRequest = sparkRequest;
+ }
+
+ @Override
+ public List getRequestHeader(String name) {
+ String header = sparkRequest.headers(name);
+ return header != null ? Collections.singletonList(header) : Collections.emptyList();
+ }
+
+ @Override
+ public String getHeaderString(String s) {
+ LOGGER.warn("Not implemented: JaxRsHttpHeaders.getHeaderString()");
+ return "";
+ }
+
+ @Override
+ public MultivaluedMap getRequestHeaders() {
+ LOGGER.warn("Not implemented: JaxRsHttpHeaders.getRequestHeaders()");
+ return new MultivaluedHashMap<>();
+ }
+
+ @Override
+ public List getAcceptableMediaTypes() {
+ LOGGER.warn("Not implemented: JaxRsHttpHeaders.getAcceptableMediaTypes()");
+ return List.of();
+ }
+
+ @Override
+ public List getAcceptableLanguages() {
+ LOGGER.warn("Not implemented: JaxRsHttpHeaders.getAcceptableLanguages()");
+ return List.of();
+ }
+
+ @Override
+ public MediaType getMediaType() {
+ LOGGER.warn("Not implemented: JaxRsHttpHeaders.getMediaType()");
+ return null;
+ }
+
+ @Override
+ public Locale getLanguage() {
+ LOGGER.warn("Not implemented: JaxRsHttpHeaders.getLanguage()");
+ return null;
+ }
+
+ @Override
+ public Map getCookies() {
+ LOGGER.warn("Not implemented: JaxRsHttpHeaders.getCookies()");
+ return Map.of();
+ }
+
+ @Override
+ public Date getDate() {
+ LOGGER.warn("Not implemented: JaxRsHttpHeaders.getDate()");
+ return null;
+ }
+
+ @Override
+ public int getLength() {
+ LOGGER.warn("Not implemented: JaxRsHttpHeaders.getLength()");
+ return 0;
+ }
+}
diff --git a/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/util/jaxrs/JaxRsUriInfo.java b/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/util/jaxrs/JaxRsUriInfo.java
new file mode 100644
index 00000000000..a9e5f3b5646
--- /dev/null
+++ b/ui-backend/catalog-ui-search/src/main/java/org/codice/ddf/catalog/ui/util/jaxrs/JaxRsUriInfo.java
@@ -0,0 +1,129 @@
+package org.codice.ddf.catalog.ui.util.jaxrs;
+
+import java.net.URI;
+import java.util.*;
+import javax.ws.rs.core.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import spark.Request;
+
+public class JaxRsUriInfo implements UriInfo {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(JaxRsUriInfo.class);
+ private final Request sparkRequest;
+
+ public JaxRsUriInfo(Request sparkRequest) {
+ this.sparkRequest = sparkRequest;
+ }
+
+ @Override
+ public URI getAbsolutePath() {
+ return URI.create(sparkRequest.url());
+ }
+
+ @Override
+ public UriBuilder getAbsolutePathBuilder() {
+ return UriBuilder.fromUri(getAbsolutePath());
+ }
+
+ @Override
+ public URI getRequestUri() {
+ return URI.create(sparkRequest.url());
+ }
+
+ @Override
+ public String getPath() {
+ LOGGER.warn("Not implemented: JaxRsUriInfo.getPath()");
+ return "";
+ }
+
+ @Override
+ public String getPath(boolean decode) {
+ LOGGER.warn("Not implemented: JaxRsUriInfo.getPath(boolean)");
+ return "";
+ }
+
+ @Override
+ public List getPathSegments() {
+ LOGGER.warn("Not implemented: JaxRsUriInfo.getPathSegments()");
+ return List.of();
+ }
+
+ @Override
+ public List getPathSegments(boolean b) {
+ LOGGER.warn("Not implemented: JaxRsUriInfo.getPathSegments(boolean)");
+ return List.of();
+ }
+
+ @Override
+ public MultivaluedMap getQueryParameters() {
+ LOGGER.warn("Not implemented: JaxRsUriInfo.getQueryParameters()");
+ return new MultivaluedHashMap<>();
+ }
+
+ @Override
+ public MultivaluedMap getQueryParameters(boolean b) {
+ LOGGER.warn("Not implemented: JaxRsUriInfo.getQueryParameters(boolean)");
+ return new MultivaluedHashMap<>();
+ }
+
+ @Override
+ public List getMatchedURIs() {
+ LOGGER.warn("Not implemented: JaxRsUriInfo.getMatchedURIs()");
+ return List.of();
+ }
+
+ @Override
+ public List getMatchedURIs(boolean b) {
+ LOGGER.warn("Not implemented: JaxRsUriInfo.getMatchedURIs(boolean)");
+ return List.of();
+ }
+
+ @Override
+ public List