nidi3 / raml-tester

Test if a request/response matches a given raml definition
Apache License 2.0
71 stars 14 forks source link

SimpleUrlFetcher locks with multiple !includes #35

Closed Deadleg closed 9 years ago

Deadleg commented 9 years ago

I have the following raml file:

title: raml with links 
baseUri: http://deadleg.github.io/bugs
version: v0.6

/first:
  get:
    body:
      application/json:
        schema: !include json1.json
/second:
  get:
    body:
      application/json:
        schema: !include json2.json
/thrid:
  get:
    body:
      application/json:
        schema: !include json3.json

When using a UrlLoader or GithubLoader, the thread get stuck in a WAITING state when trying to grab the last !include:

Raml raml = new RamlDocumentBuilder(new RamlLoaderRamlParserResourceLoader(new UriRamlLoader(new UrlRamlLoader("http://deadleg.github.io/bugs")))).build("test.raml");
Raml raml = new RamlDocumentBuilder(new RamlLoaderRamlParserResourceLoader(new UriRamlLoader(new GithubRamlLoader("Deadleg/Deadleg.github.io")))).build("bugs/test.raml");

With thread dump:

java.lang.Thread.State: WAITING
      at sun.misc.Unsafe.park(Unsafe.java:-1)
      at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
      at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
      at org.apache.http.pool.PoolEntryFuture.await(PoolEntryFuture.java:138)
      at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:306)
      at org.apache.http.pool.AbstractConnPool.access$000(AbstractConnPool.java:64)
      at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:192)
      at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:185)
      at org.apache.http.pool.PoolEntryFuture.get(PoolEntryFuture.java:107)
      at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:276)
      at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:263)
      at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:190)
      at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
      at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
      at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
      at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
      at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
      at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
      at guru.nidi.ramltester.loader.SimpleUrlFetcher.fetchFromUrl(SimpleUrlFetcher.java:43)
      at guru.nidi.ramltester.loader.GithubRamlLoader.fetchResource(GithubRamlLoader.java:62)
      at guru.nidi.ramltester.loader.UriRamlLoader.fetchResource(UriRamlLoader.java:70)
      at guru.nidi.ramltester.loader.RamlLoaderRamlParserResourceLoader.fetchResource(RamlLoaderRamlParserResourceLoader.java:34)
      at org.raml.parser.tagresolver.IncludeResolver.resolve(IncludeResolver.java:64)
      at org.raml.parser.visitor.NodeVisitor.resolveTag(NodeVisitor.java:162)
      at org.raml.parser.visitor.NodeVisitor.doVisitMappingNode(NodeVisitor.java:139)
      at org.raml.parser.visitor.NodeVisitor.visitMappingNode(NodeVisitor.java:86)
      at org.raml.parser.visitor.NodeVisitor.visit(NodeVisitor.java:218)
      at org.raml.parser.visitor.NodeVisitor.visitResolvedNode(NodeVisitor.java:180)
      at org.raml.parser.visitor.NodeVisitor.doVisitMappingNode(NodeVisitor.java:151)
      at org.raml.parser.visitor.NodeVisitor.visitMappingNode(NodeVisitor.java:86)
      at org.raml.parser.visitor.NodeVisitor.visit(NodeVisitor.java:218)
      at org.raml.parser.visitor.NodeVisitor.visitResolvedNode(NodeVisitor.java:180)
      at org.raml.parser.visitor.NodeVisitor.doVisitMappingNode(NodeVisitor.java:151)
      at org.raml.parser.visitor.NodeVisitor.visitMappingNode(NodeVisitor.java:86)
      at org.raml.parser.visitor.NodeVisitor.visit(NodeVisitor.java:218)
      at org.raml.parser.visitor.NodeVisitor.visitResolvedNode(NodeVisitor.java:180)
      at org.raml.parser.visitor.NodeVisitor.doVisitMappingNode(NodeVisitor.java:151)
      at org.raml.parser.visitor.NodeVisitor.visitMappingNode(NodeVisitor.java:86)
      at org.raml.parser.visitor.NodeVisitor.visit(NodeVisitor.java:218)
      at org.raml.parser.visitor.NodeVisitor.visitResolvedNode(NodeVisitor.java:180)
      at org.raml.parser.visitor.NodeVisitor.doVisitMappingNode(NodeVisitor.java:151)
      at org.raml.parser.visitor.NodeVisitor.visitDocument(NodeVisitor.java:209)
      at org.raml.parser.visitor.YamlDocumentBuilder.build(YamlDocumentBuilder.java:90)
      at org.raml.parser.visitor.YamlDocumentBuilder.build(YamlDocumentBuilder.java:102)
      at org.raml.parser.visitor.YamlDocumentBuilder.build(YamlDocumentBuilder.java:78)

From what I can see, the issue isn't with this library, but rather with the raml-java-parser IncludeResolver.resolve method. The resolver grabs the input stream for each include, but as far as I can see it doesn't close it (nor consume the response contents). If I explicitly call for the input stream to close, the issue goes away.

Since raml-java-parser doesn't have a dependency on HttpComponents, it may be easier (and safer) to switch out this projects dependency on it to something else.

nidi3 commented 9 years ago

I'd rather wait for raml-java-parser to fix the problem

nidi3 commented 9 years ago

Added an AutoClosingInputStream. Should do the trick until raml parser is fixed.