Skip to content

Commit 1a6aeac

Browse files
committed
TIKA-4809: Remove TikaResource's static singleton
1 parent 0df56b8 commit 1a6aeac

34 files changed

Lines changed: 165 additions & 130 deletions

tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/TikaServerProcess.java

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -192,13 +192,13 @@ private static ServerDetails initServer(TikaServerConfig tikaServerConfig) throw
192192
LOG.info("Pipes-based parsing enabled for /tika and /rmeta endpoints");
193193
}
194194

195-
TikaResource.init(tikaLoader, serverStatus, pipesParsingHelper,
195+
TikaResource tikaResource = new TikaResource(tikaLoader, serverStatus, pipesParsingHelper,
196196
tikaServerConfig.isAllowPerRequestConfig());
197197
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
198198

199199
List<ResourceProvider> resourceProviders = new ArrayList<>();
200200
List<Object> providers = new ArrayList<>();
201-
loadAllProviders(tikaServerConfig, serverStatus, resourceProviders, providers);
201+
loadAllProviders(tikaServerConfig, serverStatus, tikaResource, resourceProviders, providers);
202202

203203
sf.setResourceProviders(resourceProviders);
204204

@@ -296,9 +296,10 @@ private static TLSServerParameters getTlsParams(TlsConfig tlsConfig)
296296
return parameters;
297297
}
298298

299-
private static void loadAllProviders(TikaServerConfig tikaServerConfig, ServerStatus serverStatus, List<ResourceProvider> resourceProviders, List<Object> writers)
299+
private static void loadAllProviders(TikaServerConfig tikaServerConfig, ServerStatus serverStatus,
300+
TikaResource tikaResource, List<ResourceProvider> resourceProviders, List<Object> writers)
300301
throws TikaException, SAXException, IOException {
301-
List<ResourceProvider> tmpCoreProviders = loadCoreProviders(tikaServerConfig, serverStatus);
302+
List<ResourceProvider> tmpCoreProviders = loadCoreProviders(tikaServerConfig, serverStatus, tikaResource);
302303

303304
resourceProviders.addAll(tmpCoreProviders);
304305
resourceProviders.add(new SingletonResourceProvider(new TikaWelcome(tmpCoreProviders)));
@@ -345,23 +346,24 @@ private static void loadAllProviders(TikaServerConfig tikaServerConfig, ServerSt
345346
}
346347

347348
// package-private so the pipes/async start-guard can be exercised directly in tests
348-
static List<ResourceProvider> loadCoreProviders(TikaServerConfig tikaServerConfig, ServerStatus serverStatus) throws TikaException, IOException, SAXException {
349+
static List<ResourceProvider> loadCoreProviders(TikaServerConfig tikaServerConfig, ServerStatus serverStatus,
350+
TikaResource tikaResource) throws TikaException, IOException, SAXException {
349351
List<ResourceProvider> resourceProviders = new ArrayList<>();
350352
boolean addAsyncResource = false;
351353
boolean addPipesResource = false;
352354
if (tikaServerConfig
353355
.getEndpoints()
354356
.size() == 0) {
355-
resourceProviders.add(new SingletonResourceProvider(new MetadataResource()));
356-
resourceProviders.add(new SingletonResourceProvider(new RecursiveMetadataResource()));
357-
resourceProviders.add(new SingletonResourceProvider(new DetectorResource(serverStatus)));
357+
resourceProviders.add(new SingletonResourceProvider(new MetadataResource(tikaResource)));
358+
resourceProviders.add(new SingletonResourceProvider(new RecursiveMetadataResource(tikaResource)));
359+
resourceProviders.add(new SingletonResourceProvider(new DetectorResource(serverStatus, tikaResource)));
358360
resourceProviders.add(new SingletonResourceProvider(new LanguageResource()));
359361
resourceProviders.add(new SingletonResourceProvider(new TranslateResource(serverStatus)));
360-
resourceProviders.add(new SingletonResourceProvider(new TikaResource()));
361-
resourceProviders.add(new SingletonResourceProvider(new UnpackerResource()));
362-
resourceProviders.add(new SingletonResourceProvider(new TikaMimeTypes()));
363-
resourceProviders.add(new SingletonResourceProvider(new TikaDetectors()));
364-
resourceProviders.add(new SingletonResourceProvider(new TikaParsers()));
362+
resourceProviders.add(new SingletonResourceProvider(tikaResource));
363+
resourceProviders.add(new SingletonResourceProvider(new UnpackerResource(tikaResource)));
364+
resourceProviders.add(new SingletonResourceProvider(new TikaMimeTypes(tikaResource)));
365+
resourceProviders.add(new SingletonResourceProvider(new TikaDetectors(tikaResource)));
366+
resourceProviders.add(new SingletonResourceProvider(new TikaParsers(tikaResource)));
365367
resourceProviders.add(new SingletonResourceProvider(new TikaVersion()));
366368
if (tikaServerConfig.isAllowPipes()) {
367369
addAsyncResource = true;
@@ -373,25 +375,25 @@ static List<ResourceProvider> loadCoreProviders(TikaServerConfig tikaServerConfi
373375
} else {
374376
for (String endPoint : tikaServerConfig.getEndpoints()) {
375377
if ("meta".equals(endPoint)) {
376-
resourceProviders.add(new SingletonResourceProvider(new MetadataResource()));
378+
resourceProviders.add(new SingletonResourceProvider(new MetadataResource(tikaResource)));
377379
} else if ("rmeta".equals(endPoint)) {
378-
resourceProviders.add(new SingletonResourceProvider(new RecursiveMetadataResource()));
380+
resourceProviders.add(new SingletonResourceProvider(new RecursiveMetadataResource(tikaResource)));
379381
} else if ("detect".equals(endPoint)) {
380-
resourceProviders.add(new SingletonResourceProvider(new DetectorResource(serverStatus)));
382+
resourceProviders.add(new SingletonResourceProvider(new DetectorResource(serverStatus, tikaResource)));
381383
} else if ("language".equals(endPoint)) {
382384
resourceProviders.add(new SingletonResourceProvider(new LanguageResource()));
383385
} else if ("translate".equals(endPoint)) {
384386
resourceProviders.add(new SingletonResourceProvider(new TranslateResource(serverStatus)));
385387
} else if ("tika".equals(endPoint)) {
386-
resourceProviders.add(new SingletonResourceProvider(new TikaResource()));
388+
resourceProviders.add(new SingletonResourceProvider(tikaResource));
387389
} else if ("unpack".equals(endPoint)) {
388-
resourceProviders.add(new SingletonResourceProvider(new UnpackerResource()));
390+
resourceProviders.add(new SingletonResourceProvider(new UnpackerResource(tikaResource)));
389391
} else if ("mime".equals(endPoint)) {
390-
resourceProviders.add(new SingletonResourceProvider(new TikaMimeTypes()));
392+
resourceProviders.add(new SingletonResourceProvider(new TikaMimeTypes(tikaResource)));
391393
} else if ("detectors".equals(endPoint)) {
392-
resourceProviders.add(new SingletonResourceProvider(new TikaDetectors()));
394+
resourceProviders.add(new SingletonResourceProvider(new TikaDetectors(tikaResource)));
393395
} else if ("parsers".equals(endPoint)) {
394-
resourceProviders.add(new SingletonResourceProvider(new TikaParsers()));
396+
resourceProviders.add(new SingletonResourceProvider(new TikaParsers(tikaResource)));
395397
} else if ("version".equals(endPoint)) {
396398
resourceProviders.add(new SingletonResourceProvider(new TikaVersion()));
397399
} else if ("pipes".equals(endPoint)) {

tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/DetectorResource.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,19 @@
4141
public class DetectorResource {
4242
private static final Logger LOG = LoggerFactory.getLogger(DetectorResource.class);
4343
private final ServerStatus serverStatus;
44+
private final TikaResource tikaResource;
4445

45-
public DetectorResource(ServerStatus serverStatus) {
46+
public DetectorResource(ServerStatus serverStatus, TikaResource tikaResource) {
4647
this.serverStatus = serverStatus;
48+
this.tikaResource = tikaResource;
4749
}
4850

4951
@PUT
5052
@Path("stream")
5153
@Consumes("*/*")
5254
@Produces("text/plain")
5355
public String detect(final InputStream is, @Context HttpHeaders httpHeaders, @Context final UriInfo info) {
54-
ParseContext parseContext = TikaResource.createParseContext();
56+
ParseContext parseContext = tikaResource.createParseContext();
5557
Metadata met = Metadata.newInstance(parseContext);
5658

5759
String filename = TikaResource.detectFilename(httpHeaders.getRequestHeaders());
@@ -60,7 +62,7 @@ public String detect(final InputStream is, @Context HttpHeaders httpHeaders, @Co
6062
long taskId = serverStatus.start(ServerStatus.TASK.DETECT, filename);
6163

6264
try (TikaInputStream tis = TikaInputStream.get(is)) {
63-
return TikaResource
65+
return tikaResource
6466
.getTikaLoader()
6567
.loadDetectors()
6668
.detect(tis, met, parseContext)

tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/MetadataResource.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.apache.tika.server.core.resource;
1818

1919
import static org.apache.tika.server.core.resource.TikaResource.fillMetadata;
20-
import static org.apache.tika.server.core.resource.TikaResource.setupMultipartConfig;
2120

2221
import java.io.IOException;
2322
import java.io.InputStream;
@@ -51,12 +50,18 @@
5150
public class MetadataResource {
5251
private static final Logger LOG = LoggerFactory.getLogger(MetadataResource.class);
5352

53+
private final TikaResource tikaResource;
54+
55+
public MetadataResource(TikaResource tikaResource) {
56+
this.tikaResource = tikaResource;
57+
}
58+
5459
@POST
5560
@Consumes("multipart/form-data")
5661
@Produces({"text/csv", "application/json"})
5762
@Path("form")
5863
public Response getMetadataFromMultipart(Attachment att, @Context UriInfo info) throws Exception {
59-
ParseContext context = TikaResource.createParseContext();
64+
ParseContext context = tikaResource.createParseContext();
6065
try (TikaInputStream tis = TikaInputStream.get(att.getObject(InputStream.class))) {
6166
return Response
6267
.ok(parseMetadata(tis, Metadata.newInstance(context), att.getHeaders(), info))
@@ -78,15 +83,15 @@ public Response getMetadataWithConfig(
7883
@Context UriInfo info) throws Exception {
7984

8085
// Load default context from config, then overlay with request config
81-
ParseContext context = TikaResource.createParseContext();
86+
ParseContext context = tikaResource.createParseContext();
8287
Metadata metadata = Metadata.newInstance(context);
83-
try (TikaInputStream tis = setupMultipartConfig(attachments, metadata, context)) {
88+
try (TikaInputStream tis = tikaResource.setupMultipartConfig(attachments, metadata, context)) {
8489
// No need to parse embedded docs for metadata-only extraction
8590
context.set(DocumentSelector.class, metadata1 -> false);
8691

87-
Parser parser = TikaResource.createParser();
92+
Parser parser = tikaResource.createParser();
8893
TikaResource.logRequest(LOG, "/meta/config", metadata);
89-
TikaResource.parse(parser, LOG, info.getPath(), tis, new LanguageHandler() {
94+
tikaResource.parse(parser, LOG, info.getPath(), tis, new LanguageHandler() {
9095
public void endDocument() {
9196
metadata.set("language", getLanguage().getLanguage());
9297
}
@@ -99,7 +104,7 @@ public void endDocument() {
99104
@PUT
100105
@Produces({"text/csv", "application/json"})
101106
public Response getMetadata(InputStream is, @Context HttpHeaders httpHeaders, @Context UriInfo info) throws Exception {
102-
ParseContext context = TikaResource.createParseContext();
107+
ParseContext context = tikaResource.createParseContext();
103108
Metadata metadata = Metadata.newInstance(context);
104109
try (TikaInputStream tis = TikaInputStream.get(is)) {
105110
return Response
@@ -139,7 +144,7 @@ public Response getMetadataField(InputStream is, @Context HttpHeaders httpHeader
139144
// use BAD request to indicate that we may not have had enough data to
140145
// process the request
141146
Response.Status defaultErrorResponse = Response.Status.BAD_REQUEST;
142-
ParseContext context = TikaResource.createParseContext();
147+
ParseContext context = tikaResource.createParseContext();
143148
Metadata metadata = Metadata.newInstance(context);
144149
boolean success = false;
145150
try (TikaInputStream tis = TikaInputStream.get(is)) {
@@ -173,14 +178,14 @@ public Response getMetadataField(InputStream is, @Context HttpHeaders httpHeader
173178
protected Metadata parseMetadata(TikaInputStream tis, Metadata metadata, MultivaluedMap<String, String> httpHeaders, UriInfo info)
174179
throws IOException, TikaConfigException {
175180
// Load default context from config (includes DigesterFactory from parse-context)
176-
final ParseContext context = TikaResource.createParseContext();
177-
Parser parser = TikaResource.createParser();
181+
final ParseContext context = tikaResource.createParseContext();
182+
Parser parser = tikaResource.createParser();
178183
fillMetadata(parser, metadata, httpHeaders);
179184
//no need to parse embedded docs
180185
context.set(DocumentSelector.class, metadata1 -> false);
181186

182187
TikaResource.logRequest(LOG, "/meta", metadata);
183-
TikaResource.parse(parser, LOG, info.getPath(), tis, new LanguageHandler() {
188+
tikaResource.parse(parser, LOG, info.getPath(), tis, new LanguageHandler() {
184189
public void endDocument() {
185190
metadata.set("language", getLanguage().getLanguage());
186191
}

tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/PipesParsingHelper.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,11 @@ private List<Metadata> processResult(PipesResult result) {
260260
LOG.debug("Parse returned empty result, status: {}", result.status());
261261
String message = result.message();
262262
if (message != null && !message.isEmpty()) {
263-
ParseContext context = TikaResource.createParseContext();
263+
// Plain ParseContext, not TikaResource.createParseContext() -- this class is
264+
// constructed before TikaResource (which takes it as a constructor arg), so
265+
// depending back on TikaResource here would be circular. Only used to build
266+
// an error-result Metadata object; no actual parsing happens on this path.
267+
ParseContext context = new ParseContext();
264268
Metadata errorMetadata = Metadata.newInstance(context);
265269
errorMetadata.add(TikaCoreProperties.CONTAINER_EXCEPTION, message);
266270
return Collections.singletonList(errorMetadata);

tika-server/tika-server-core/src/main/java/org/apache/tika/server/core/resource/RecursiveMetadataResource.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import static org.apache.tika.server.core.resource.TikaResource.getWriteLimit;
2121
import static org.apache.tika.server.core.resource.TikaResource.setupContentHandlerFactory;
2222
import static org.apache.tika.server.core.resource.TikaResource.setupContentHandlerFactoryIfNeeded;
23-
import static org.apache.tika.server.core.resource.TikaResource.setupMultipartConfig;
2423

2524
import java.io.InputStream;
2625
import java.util.List;
@@ -54,16 +53,22 @@ public class RecursiveMetadataResource {
5453
protected static final BasicContentHandlerFactory.HANDLER_TYPE DEFAULT_HANDLER_TYPE = BasicContentHandlerFactory.HANDLER_TYPE.MARKDOWN;
5554
private static final Logger LOG = LoggerFactory.getLogger(RecursiveMetadataResource.class);
5655

56+
private final TikaResource tikaResource;
57+
58+
public RecursiveMetadataResource(TikaResource tikaResource) {
59+
this.tikaResource = tikaResource;
60+
}
61+
5762
/**
5863
* Parses content and returns metadata list.
5964
* Metadata filtering is done in the child process, so no filtering needed here.
6065
*/
61-
public static List<Metadata> parseMetadata(TikaInputStream tis, Metadata metadata,
66+
public List<Metadata> parseMetadata(TikaInputStream tis, Metadata metadata,
6267
MultivaluedMap<String, String> httpHeaders,
6368
ServerHandlerConfig handlerConfig)
6469
throws Exception {
6570

66-
final ParseContext context = TikaResource.createParseContext();
71+
final ParseContext context = tikaResource.createParseContext();
6772

6873
fillMetadata(null, metadata, httpHeaders);
6974
TikaResource.logRequest(LOG, "/rmeta", metadata);
@@ -80,7 +85,7 @@ public static List<Metadata> parseMetadata(TikaInputStream tis, Metadata metadat
8085
}
8186

8287
// Filtering is done in child process, no need to filter again
83-
return TikaResource.parseWithPipes(tis, metadata, context, ParseMode.RMETA);
88+
return tikaResource.parseWithPipes(tis, metadata, context, ParseMode.RMETA);
8489
}
8590

8691
static ServerHandlerConfig buildHandlerConfig(MultivaluedMap<String, String> httpHeaders, String handlerTypeName, ParseMode parseMode) {
@@ -125,7 +130,7 @@ static ServerHandlerConfig buildHandlerConfig(MultivaluedMap<String, String> htt
125130
@Produces({"application/json"})
126131
@Path("form{" + HANDLER_TYPE_PARAM + " : (\\w+)?}")
127132
public Response getMetadataFromMultipart(Attachment att, @PathParam(HANDLER_TYPE_PARAM) String handlerTypeName) throws Exception {
128-
ParseContext context = TikaResource.createParseContext();
133+
ParseContext context = tikaResource.createParseContext();
129134
try (TikaInputStream tis = TikaInputStream.get(att.getObject(InputStream.class))) {
130135
tis.getPath(); // Spool to temp file for pipes-based parsing
131136
List<Metadata> metadataList = parseMetadata(tis, Metadata.newInstance(context), att.getHeaders(),
@@ -147,9 +152,9 @@ public Response getMetadataWithConfig(
147152
List<Attachment> attachments,
148153
@Context HttpHeaders httpHeaders) throws Exception {
149154

150-
ParseContext context = TikaResource.createParseContext();
155+
ParseContext context = tikaResource.createParseContext();
151156
Metadata metadata = Metadata.newInstance(context);
152-
try (TikaInputStream tis = setupMultipartConfig(attachments, metadata, context)) {
157+
try (TikaInputStream tis = tikaResource.setupMultipartConfig(attachments, metadata, context)) {
153158

154159
TikaResource.logRequest(LOG, "/rmeta/config", metadata);
155160

@@ -168,7 +173,7 @@ private MetadataList parseMetadataWithContext(TikaInputStream tis, Metadata meta
168173
handlerConfig.writeLimit(), handlerConfig.throwOnWriteLimitReached());
169174

170175
// Filtering is done in child process, no need to filter again
171-
List<Metadata> metadataList = TikaResource.parseWithPipes(tis, metadata, context, ParseMode.RMETA);
176+
List<Metadata> metadataList = tikaResource.parseWithPipes(tis, metadata, context, ParseMode.RMETA);
172177
return new MetadataList(metadataList);
173178
}
174179

@@ -200,7 +205,7 @@ private MetadataList parseMetadataWithContext(TikaInputStream tis, Metadata meta
200205
@Produces("application/json")
201206
@Path("{" + HANDLER_TYPE_PARAM + " : (\\w+)?}")
202207
public Response getMetadata(InputStream is, @Context HttpHeaders httpHeaders, @PathParam(HANDLER_TYPE_PARAM) String handlerTypeName) throws Exception {
203-
ParseContext context = TikaResource.createParseContext();
208+
ParseContext context = tikaResource.createParseContext();
204209
Metadata metadata = Metadata.newInstance(context);
205210
try (TikaInputStream tis = TikaInputStream.get(is)) {
206211
tis.getPath(); // Spool to temp file for pipes-based parsing

0 commit comments

Comments
 (0)