Skip to content

Commit

Permalink
Merge pull request #1511 from libris/feature/bulk-real-preview
Browse files Browse the repository at this point in the history
Move BulkChangePreviewAPI from rest to housekeeping
  • Loading branch information
olovy authored Nov 8, 2024
2 parents 019a32d + 14d2e19 commit 5f1b296
Show file tree
Hide file tree
Showing 25 changed files with 110 additions and 79 deletions.
2 changes: 2 additions & 0 deletions housekeeping/src/main/groovy/whelk/HouseKeepingServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.eclipse.jetty.ee8.servlet.ServletContextHandler;
import org.eclipse.jetty.ee8.servlet.ServletHolder;
import org.eclipse.jetty.server.Server;
import whelk.housekeeping.BulkChangePreviewAPI;
import whelk.housekeeping.WebInterface;

public class HouseKeepingServer extends XlServer {
Expand All @@ -16,6 +17,7 @@ protected void configureHandlers(Server server) {
ServletHolder holder = new ServletHolder(WebInterface.class);
holder.setInitOrder(0);
context.addServlet(holder, "/");
context.addServlet(BulkChangePreviewAPI.class, "/_bulk-change/*");

serveStaticContent(context);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package whelk.rest.api;
package whelk.housekeeping;

import whelk.Document;
import whelk.JsonLd;
Expand All @@ -11,6 +11,10 @@
import whelk.history.History;
import whelk.util.DocumentUtil;
import whelk.util.WhelkFactory;
import whelk.util.http.BadRequestException;
import whelk.util.http.HttpTools;
import whelk.util.http.MimeTypes;
import whelk.util.http.NotFoundException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
Expand Down Expand Up @@ -49,7 +53,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
throw new BadRequestException("@id parameter is required");
}
if (!id.startsWith(Document.getBASE_URI().toString())) {
throw new Crud.NotFoundException("Document not found");
throw new NotFoundException("Document not found");
}
var systemId = stripPrefix(id, Document.getBASE_URI().toString());

Expand Down Expand Up @@ -215,7 +219,7 @@ private static <T> List<T> slice(List<T> l, int from, int to) {
private BulkJobDocument load(String id) {
Document doc = whelk.getDocument(id);
if (doc == null) {
throw new Crud.NotFoundException("Document not found");
throw new NotFoundException("Document not found");
}
try {
return new BulkJobDocument(doc.data);
Expand Down
2 changes: 1 addition & 1 deletion rest/src/main/groovy/whelk/rest/api/ConverterAPI.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import org.apache.http.entity.ContentType
import whelk.Document
import whelk.Whelk
import whelk.converter.marc.MarcFrameConverter
import whelk.util.Tools
import whelk.util.Unicode
import whelk.util.WhelkFactory
import whelk.util.http.HttpTools

import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
Expand Down
7 changes: 4 additions & 3 deletions rest/src/main/groovy/whelk/rest/api/ConverterUtils.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import whelk.converter.JsonLD2N3Converter
import whelk.converter.JsonLD2RdfXml
import whelk.converter.JsonLDTrigConverter
import whelk.converter.JsonLDTurtleConverter
import whelk.util.http.MimeTypes

@Log
class ConverterUtils {
Expand All @@ -18,10 +19,10 @@ class ConverterUtils {
this.whelk = whelk

converters = [
(MimeTypes.RDF): new JsonLD2RdfXml(whelk),
(MimeTypes.RDF) : new JsonLD2RdfXml(whelk),
(MimeTypes.TURTLE): new JsonLDTurtleConverter(null, whelk),
(MimeTypes.TRIG): new JsonLDTrigConverter(null, whelk),
(MimeTypes.N3): new JsonLD2N3Converter(whelk),
(MimeTypes.TRIG) : new JsonLDTrigConverter(null, whelk),
(MimeTypes.N3) : new JsonLD2N3Converter(whelk),
]
}

Expand Down
45 changes: 9 additions & 36 deletions rest/src/main/groovy/whelk/rest/api/Crud.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,21 @@ import whelk.history.History
import whelk.rest.api.CrudGetRequest.Lens
import whelk.rest.security.AccessControl
import whelk.util.WhelkFactory
import whelk.util.http.BadRequestException
import whelk.util.http.HttpTools
import whelk.util.http.MimeTypes
import whelk.util.http.NotFoundException
import whelk.util.http.OtherStatusException
import whelk.util.http.RedirectException

import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import java.lang.management.ManagementFactory

import static whelk.rest.api.CrudUtils.ETag
import static whelk.rest.api.HttpTools.getBaseUri
import static whelk.rest.api.HttpTools.sendResponse
import static whelk.util.http.HttpTools.getBaseUri
import static whelk.util.http.HttpTools.sendResponse
import static whelk.util.Jackson.mapper

/**
Expand Down Expand Up @@ -620,7 +626,7 @@ class Crud extends HttpServlet {
String location = docAndLoc.v2

if (!existingDoc && !location) {
throw new Crud.NotFoundException("Document not found.")
throw new NotFoundException("Document not found.")
} else if (!existingDoc && location) {
sendRedirect(request, response, location)
return
Expand Down Expand Up @@ -847,38 +853,5 @@ class Crud extends HttpServlet {
HttpTools.sendError(response, code, e.getMessage(), e)
}

static class NotFoundException extends NoStackTraceException {
NotFoundException(String msg) {
super(msg)
}
}

static class OtherStatusException extends NoStackTraceException {
int code
OtherStatusException(String msg, int code, Throwable cause = null) {
super(msg, cause)
this.code = code
}
}

/** "Don't use exceptions for flow control" in part comes from that exceptions in Java are
* expensive to create because building the stack trace is expensive. But in the context of
* sending error responses in this API exceptions are pretty useful for flow control.
* This is a base class for stack trace-less exceptions for common error flows.
*/
static class NoStackTraceException extends RuntimeException {
protected NoStackTraceException(String msg) {
super(msg, null, true, false)
}

protected NoStackTraceException(String msg, Throwable cause) {
super(msg, cause, true, false)
}
}

static class RedirectException extends NoStackTraceException {
RedirectException(String msg) {
super(msg)
}
}
}
6 changes: 5 additions & 1 deletion rest/src/main/groovy/whelk/rest/api/CrudGetRequest.groovy
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package whelk.rest.api

import whelk.util.http.BadRequestException
import whelk.util.http.MimeTypes
import whelk.util.http.NotFoundException

import javax.servlet.http.HttpServletRequest

import static whelk.rest.api.CrudUtils.*
Expand Down Expand Up @@ -90,7 +94,7 @@ class CrudGetRequest {
dataLeaf = matcher[0][2]
view = View.fromString(matcher[0][3])
} else {
throw new Crud.NotFoundException("Not found:" + path)
throw new NotFoundException("Not found:" + path)
}
}

Expand Down
8 changes: 6 additions & 2 deletions rest/src/main/groovy/whelk/rest/api/CrudUtils.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import org.apache.commons.io.FilenameUtils
import org.apache.http.HeaderElement
import org.apache.http.NameValuePair
import org.apache.http.message.BasicHeaderValueParser
import whelk.util.http.BadRequestException
import whelk.util.http.MimeTypes
import whelk.util.http.NotFoundException
import whelk.util.http.UnsupportedContentTypeException

import javax.servlet.http.HttpServletRequest
import java.lang.management.ManagementFactory
Expand Down Expand Up @@ -75,9 +79,9 @@ class CrudUtils {
return ALLOWED_MEDIA_TYPES_BY_EXT.get(extension)
} else {
if (extension) {
throw new Crud.NotFoundException('.' + extension)
throw new NotFoundException('.' + extension)
} else {
throw new Crud.NotFoundException("${mediaTypeIntersect}")
throw new NotFoundException("${mediaTypeIntersect}")
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion rest/src/main/groovy/whelk/rest/api/MarcframeData.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

import static whelk.rest.api.HttpTools.sendResponse
import static whelk.util.http.HttpTools.sendResponse

@CompileStatic
class MarcframeData extends HttpServlet {
Expand Down
1 change: 1 addition & 0 deletions rest/src/main/groovy/whelk/rest/api/RemoteSearchAPI.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import whelk.filter.LinkFinder
import whelk.util.LegacyIntegrationTools
import whelk.util.PropertyLoader
import whelk.util.WhelkFactory
import whelk.util.http.HttpTools

import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
Expand Down
5 changes: 3 additions & 2 deletions rest/src/main/groovy/whelk/rest/api/SearchUtils2.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import whelk.search2.Spell;
import whelk.search2.Stats;
import whelk.search2.querytree.QueryTree;
import whelk.util.http.RedirectException;

import java.io.IOException;
import java.util.*;
Expand Down Expand Up @@ -43,7 +44,7 @@ Map<String, Object> doSearch(Map<String, String[]> queryParameters) throws Inval
if (queryParams.object == null) {
throw new InvalidQueryException("Missing required query parameter: _q");
} else {
throw new Crud.RedirectException(QueryUtil.makeFindUrl("", "*", queryParams.getNonQueryParams()));
throw new RedirectException(QueryUtil.makeFindUrl("", "*", queryParams.getNonQueryParams()));
}
}

Expand All @@ -54,7 +55,7 @@ Map<String, Object> doSearch(Map<String, String[]> queryParameters) throws Inval
QueryTree iTree = new QueryTree(queryParams.i, disambiguate, appParams.siteFilters.aliasToFilter());

if (!iTree.isEmpty() && !iTree.isFreeText()) {
throw new Crud.RedirectException(QueryUtil.makeFindUrl(qTree, queryParams.getNonQueryParams()));
throw new RedirectException(QueryUtil.makeFindUrl(qTree, queryParams.getNonQueryParams()));
}

qTree.addFilters(queryParams, appParams);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package whelk.rest.api

import groovy.util.logging.Log4j2 as Log
import whelk.Whelk
import whelk.util.Romanizer
import whelk.util.WhelkFactory
import whelk.util.http.HttpTools

import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
Expand Down
1 change: 1 addition & 0 deletions rest/src/main/groovy/whelk/rest/api/UserDataAPI.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import groovy.util.logging.Log4j2 as Log
import groovy.json.JsonSlurper
import whelk.Whelk
import whelk.util.WhelkFactory
import whelk.util.http.HttpTools

import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
Expand Down
3 changes: 0 additions & 3 deletions rest/src/main/java/whelk/RestServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.eclipse.jetty.rewrite.handler.RewriteHandler;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import whelk.rest.api.BulkChangePreviewAPI;
import whelk.rest.api.ConverterAPI;
import whelk.rest.api.Crud;
import whelk.rest.api.DuplicatesAPI;
Expand Down Expand Up @@ -102,8 +101,6 @@ protected void configureHandlers(Server server) {
context.addServlet(RecordRelationAPI.class, "/_dependencies");
context.addServlet(DuplicatesAPI.class, "/_duplicates");

context.addServlet(BulkChangePreviewAPI.class, "/_bulk-change/*");

context.addServlet(se.kb.libris.digi.DigitalReproductionAPI.class, "/_reproduction");

serveStaticContent(context);
Expand Down
4 changes: 2 additions & 2 deletions rest/src/test/groovy/whelk/rest/api/CrudSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND
import static javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED
import static javax.servlet.http.HttpServletResponse.SC_OK
import static whelk.rest.api.MimeTypes.JSON
import static whelk.rest.api.MimeTypes.JSONLD
import static whelk.util.http.MimeTypes.JSON
import static whelk.util.http.MimeTypes.JSONLD
import static whelk.util.Jackson.mapper

/**
Expand Down
5 changes: 3 additions & 2 deletions rest/src/test/groovy/whelk/rest/api/CrudUtilsSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package whelk.rest.api

import com.google.common.net.MediaType
import spock.lang.Specification
import whelk.rest.api.CrudUtils
import whelk.util.http.BadRequestException
import whelk.util.http.NotFoundException

class CrudUtilsSpec extends Specification {

Expand Down Expand Up @@ -55,7 +56,7 @@ class CrudUtilsSpec extends Specification {
CrudUtils.getBestContentType(acceptHeader, requestPath)

then:
thrown(Crud.NotFoundException)
thrown(NotFoundException)

where:
suffix << ['.invalid']
Expand Down
2 changes: 2 additions & 0 deletions server-common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ dependencies {
implementation "org.eclipse.jetty:jetty-server:${jettyVersion}"
implementation "org.eclipse.jetty.ee8:jetty-ee8-servlet:${jettyVersion}"

implementation "org.apache.httpcomponents:httpclient:${httpComponentsClientVersion}"

// Logging
implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: "${log4jVersion}"
implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: "${log4jVersion}"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package whelk.rest.api
package whelk.util.http

class BadRequestException extends Crud.NoStackTraceException {
class BadRequestException extends NoStackTraceException {
Map extraInfo
BadRequestException(String msg, Map extraInfo = null) {
super(msg)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package whelk.rest.api
package whelk.util.http

import groovy.util.logging.Log4j2 as Log
import org.apache.commons.lang3.exception.ExceptionUtils
Expand Down Expand Up @@ -110,7 +110,7 @@ class HttpTools {
case LinkValidationException:
return HttpServletResponse.SC_BAD_REQUEST

case Crud.NotFoundException:
case NotFoundException:
return HttpServletResponse.SC_NOT_FOUND

case UnsupportedContentTypeException:
Expand All @@ -123,8 +123,8 @@ class HttpTools {
case StorageCreateFailedException:
return HttpServletResponse.SC_CONFLICT

case Crud.OtherStatusException:
return ((Crud.OtherStatusException) e).code
case OtherStatusException:
return ((OtherStatusException) e).code

default:
return HttpServletResponse.SC_INTERNAL_SERVER_ERROR
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package whelk.rest.api
package whelk.util.http

class MimeTypes {
static final JSONLD = "application/ld+json"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package whelk.util.http

/** "Don't use exceptions for flow control" in part comes from that exceptions in Java are
* expensive to create because building the stack trace is expensive. But in the context of
* sending error responses in this API exceptions are pretty useful for flow control.
* This is a base class for stack trace-less exceptions for common error flows.
*/
class NoStackTraceException extends RuntimeException {
protected NoStackTraceException(String msg) {
super(msg, null, true, false)
}

protected NoStackTraceException(String msg, Throwable cause) {
super(msg, cause, true, false)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package whelk.util.http

class NotFoundException extends NoStackTraceException {
NotFoundException(String msg) {
super(msg)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package whelk.util.http

class OtherStatusException extends NoStackTraceException {
int code

OtherStatusException(String msg, int code, Throwable cause = null) {
super(msg, cause)
this.code = code
}
}
Loading

0 comments on commit 5f1b296

Please sign in to comment.