Skip to content

Commit 0674e0f

Browse files
committed
Restructure proxy server and write Ratpack part in Java to get JDK11 compatibility (#364)
1 parent e6a8255 commit 0674e0f

File tree

3 files changed

+261
-172
lines changed

3 files changed

+261
-172
lines changed
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
package com.github.jrubygradle.internal.core
2+
3+
import com.github.jrubygradle.api.core.ApiException
4+
import com.github.jrubygradle.api.core.IvyXmlProxyServer
5+
import com.github.jrubygradle.api.core.RubyGemQueryRestApi
6+
import com.github.jrubygradle.api.gems.GemInfo
7+
import com.github.jrubygradle.api.gems.GemVersion
8+
import com.github.jrubygradle.internal.gems.GemToIvy
9+
import groovy.transform.CompileStatic
10+
import groovy.transform.InheritConstructors
11+
import groovy.transform.Synchronized
12+
import groovy.util.logging.Slf4j
13+
import org.ysb33r.grolifant.api.ExclusiveFileAccess
14+
15+
import java.nio.file.Files
16+
import java.nio.file.Path
17+
18+
import static com.github.jrubygradle.api.gems.GemVersion.gemVersionFromGradleIvyRequirement
19+
import static com.github.jrubygradle.internal.core.IvyUtils.revisionsAsHtmlDirectoryListing
20+
import static java.nio.file.Files.move
21+
import static java.nio.file.StandardCopyOption.ATOMIC_MOVE
22+
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING
23+
24+
/** Base class for implementing a proxy IvyXML server.
25+
*
26+
* @author Schalk W. Cronjé
27+
*
28+
* @since 2.0
29+
*/
30+
@CompileStatic
31+
@Slf4j
32+
abstract class AbstractIvyXmlProxyServer implements IvyXmlProxyServer {
33+
34+
@InheritConstructors
35+
static class NotFound extends Exception {
36+
}
37+
38+
/** Tell the server to refresh dependencies upon a next run.
39+
*
40+
* @param refresh {@code true} to reload dependencies.
41+
*/
42+
@Override
43+
void setRefreshDependencies(boolean refresh) {
44+
refreshDependencies = refresh ? 1 : 0
45+
}
46+
47+
/** Get the address of the local proxy.
48+
*
49+
* @return Local address as a URI.
50+
*/
51+
@Override
52+
URI getBindAddress() {
53+
"http://localhost:${bindPort}".toURI()
54+
}
55+
56+
/** Returns the cache location for a specific GEM.
57+
*
58+
* @param group Group associated with GEM.
59+
* @param name GEM name.
60+
* @param revision GEM revision.
61+
* @return Location of {@code ivy.xml} file.
62+
*/
63+
@SuppressWarnings('UnusedMethodParameter')
64+
Path ivyFile(String group, String name, String revision) {
65+
new File(localCachePath, "${name}/${revision}/ivy.xml").toPath()
66+
}
67+
68+
/** Implementation of a proxy server.
69+
*
70+
* @param cache Root directory for local Ivy XML cache.
71+
* @param serverUri URI of remote Rubygems proxy.
72+
* @param group Group that will be associated with the Rubygems proxy.
73+
*/
74+
protected AbstractIvyXmlProxyServer(File cache, URI serverUri, String group) {
75+
localCachePath = cache
76+
gemToIvy = new GemToIvy(serverUri)
77+
api = new DefaultRubyGemRestApi(serverUri)
78+
this.group = group
79+
}
80+
81+
@Synchronized
82+
@SuppressWarnings('BuilderMethodWithSideEffects')
83+
protected void createIvyXml(Path ivyXml, String name, String revision) {
84+
ExclusiveFileAccess efa = new ExclusiveFileAccess(120000, 20)
85+
efa.access(ivyXml.toFile()) {
86+
GemInfo gemInfo = api.metadata(name, revision)
87+
ivyXml.parent.toFile().mkdirs()
88+
Path tmp = ivyXml.resolveSibling("${ivyXml.toFile().name}.tmp")
89+
tmp.withWriter { writer ->
90+
gemToIvy.writeTo(writer, gemInfo)
91+
}
92+
move(tmp, ivyXml, ATOMIC_MOVE, REPLACE_EXISTING)
93+
gemToIvy.writeSha1(ivyXml.toFile())
94+
}
95+
}
96+
97+
protected File getLocalCachePath() {
98+
this.localCachePath
99+
}
100+
101+
protected String getGroup() {
102+
this.group
103+
}
104+
105+
private boolean inGroups(String grp) {
106+
grp == this.group
107+
}
108+
109+
protected Path getIvyXml(String grp, String name, String version) throws NotFound {
110+
if (inGroups(grp)) {
111+
String revision = getGemQueryRevisionFromIvy(name, version)
112+
Path ivyXml = ivyFile(grp, name, revision)
113+
debug "Requested ${group}:${name}:${version} translated to GEM with version ${revision}"
114+
if (Files.notExists(ivyXml) || refreshDependencies) {
115+
try {
116+
createIvyXml(ivyXml, name, revision)
117+
} catch (ApiException e) {
118+
debug(e.message, e)
119+
throw new NotFound()
120+
}
121+
}
122+
debug "Cached file is ${ivyXml.toAbsolutePath()}"
123+
debug "Cached file contains ${ivyXml.text}"
124+
ivyXml
125+
} else {
126+
throw new NotFound()
127+
}
128+
}
129+
130+
protected Path getIvyXmlSha1(String grp, String name, String version) throws NotFound {
131+
if (inGroups(grp)) {
132+
Path ivyXml = getIvyXml(grp, name, version)
133+
ivyXml.resolveSibling("${ivyXml.toFile().name}.sha1")
134+
}
135+
}
136+
137+
protected String getDirectoryListing(String grp, String name) throws NotFound {
138+
if (inGroups(grp)) {
139+
debug "Request to find all versions for ${grp}:${name}"
140+
List<String> versions = api.allVersions(name)
141+
debug "Got versions ${versions.join(', ')}"
142+
revisionsAsHtmlDirectoryListing(versions)
143+
} else {
144+
throw new NotFound()
145+
}
146+
}
147+
/** Get port the proxy server has bound to.
148+
*
149+
* @return Bind port
150+
*/
151+
abstract protected int getBindPort()
152+
153+
private String getGemQueryRevisionFromIvy(String gemName, String revisionPattern) {
154+
GemVersion version = gemVersionFromGradleIvyRequirement(revisionPattern)
155+
version.highOpenEnded ? api.latestVersion(gemName) : version.high
156+
}
157+
158+
private void debug(String text) {
159+
log.debug(text)
160+
}
161+
162+
private void debug(String text, Object context) {
163+
log.debug(text, context)
164+
}
165+
166+
private volatile int refreshDependencies = 0
167+
private final File localCachePath
168+
private final GemToIvy gemToIvy
169+
private final RubyGemQueryRestApi api
170+
private final String group
171+
}

core-plugin/src/main/groovy/com/github/jrubygradle/internal/core/IvyXmlRatpackProxyServer.groovy

Lines changed: 0 additions & 172 deletions
This file was deleted.

0 commit comments

Comments
 (0)