Skip to content

Commit a08f482

Browse files
committed
Merge branch '6.1.x'
2 parents 02163dd + d44b7eb commit a08f482

File tree

10 files changed

+174
-25
lines changed

10 files changed

+174
-25
lines changed

build.gradle

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,13 @@ task test(dependsOn: getTasksByName("test", true)) {
287287
}
288288
}
289289
}
290+
291+
project.afterEvaluate {
292+
allprojects.repositories.each { handler ->
293+
handler.each {
294+
if (it.url.toString().startsWith("http://")) {
295+
throw new RuntimeException("Build should not define insecure HTTP-based Maven repostories")
296+
}
297+
}
298+
}
299+
}

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ grailsAsyncVersion=3.3.2
1818
slf4jVersion=1.7.22
1919
junitVersion=4.12
2020
javassistVersion=3.21.0-GA
21-
groovyVersion=2.5.6
21+
groovyVersion=2.5.6

grails-datastore-gorm-test/src/test/groovy/grails/gorm/tests/CurrentTenantTransformSpec.groovy

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import org.grails.datastore.mapping.multitenancy.MultiTenancySettings
1313
import org.grails.datastore.mapping.multitenancy.exceptions.TenantNotFoundException
1414
import org.grails.datastore.mapping.multitenancy.resolvers.SystemPropertyTenantResolver
1515
import org.grails.datastore.mapping.simple.SimpleMapDatastore
16-
import org.springframework.beans.factory.annotation.Autowired
1716
import org.springframework.transaction.TransactionStatus
1817
import spock.lang.AutoCleanup
1918
import spock.lang.Shared
@@ -38,6 +37,30 @@ class CurrentTenantTransformSpec extends Specification {
3837
System.setProperty(SystemPropertyTenantResolver.PROPERTY_NAME, "")
3938
}
4039

40+
void "Test parsing of @WithoutTenant"() {
41+
Class testServiceClass = new GroovyShell().evaluate('''
42+
import grails.gorm.multitenancy.WithoutTenant
43+
import grails.gorm.transactions.Transactional
44+
45+
@Transactional
46+
@WithoutTenant
47+
class TestService {
48+
49+
Integer count() {
50+
return 10;
51+
}
52+
53+
}
54+
55+
return TestService
56+
''')
57+
PlayService playService = new PlayService()
58+
59+
expect:
60+
testServiceClass.getDeclaredMethod('$mt__count')
61+
playService.countPlays() == 10
62+
}
63+
4164
void "Test parsing of @CurrentTenant"() {
4265
given:
4366
Class testServiceClass = new GroovyShell().evaluate('''
@@ -140,6 +163,14 @@ return TestService
140163
}
141164
}
142165

166+
@WithoutTenant
167+
class PlayService {
168+
int countPlays() {
169+
return 10;
170+
}
171+
172+
}
173+
143174
@CurrentTenant
144175
class TeamService {
145176

grails-datastore-gorm/src/main/groovy/grails/gorm/multitenancy/Tenants.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ class Tenants {
199199
if (multiTenantCapableDatastore.getMultiTenancyMode().isSharedConnection()) {
200200
def i = callable.parameterTypes.length
201201
if(i == 0 ) {
202-
throw new IllegalArgumentException("Provided closure accepts too many arguments")
202+
return callable.call()
203203
} else {
204204
return multiTenantCapableDatastore.withSession { session ->
205205
return callable.call(session)
@@ -272,7 +272,7 @@ class Tenants {
272272

273273
}
274274
}
275-
}
275+
} as T
276276
}
277277

278278
/**

grails-datastore-gorm/src/main/groovy/org/grails/datastore/gorm/jdbc/connections/DataSourceConnectionSource.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.grails.datastore.mapping.core.connections.DefaultConnectionSource;
44
import org.slf4j.Logger;
55
import org.slf4j.LoggerFactory;
6+
import org.springframework.jdbc.datasource.DelegatingDataSource;
67
import org.springframework.util.ReflectionUtils;
78

89
import javax.sql.DataSource;
@@ -26,10 +27,18 @@ public DataSourceConnectionSource(String name, DataSource source, DataSourceSett
2627
public void close() throws IOException {
2728
super.close();
2829
if(!closed) {
29-
Method closeMethod = ReflectionUtils.findMethod(getSource().getClass(), "close");
30+
31+
DataSource source = getSource();
32+
Method closeMethod = ReflectionUtils.findMethod(source.getClass(), "close");
33+
34+
while (closeMethod == null && source instanceof DelegatingDataSource) {
35+
source = ((DelegatingDataSource) source).getTargetDataSource();
36+
closeMethod = ReflectionUtils.findMethod(source.getClass(), "close");
37+
}
38+
3039
if(closeMethod != null) {
3140
try {
32-
ReflectionUtils.invokeMethod(closeMethod, getSource());
41+
ReflectionUtils.invokeMethod(closeMethod, source);
3342
this.closed = true;
3443
} catch (Throwable e) {
3544
LOG.warn("Error closing JDBC connection [{}]: {}", getName(), e.getMessage());

grails-datastore-gorm/src/main/groovy/org/grails/datastore/gorm/multitenancy/transform/TenantTransform.groovy

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ import static org.codehaus.groovy.ast.ClassHelper.CLOSURE_TYPE
4141
import static org.codehaus.groovy.ast.ClassHelper.make
4242
import static org.codehaus.groovy.ast.tools.GeneralUtils.*
4343
import static org.grails.datastore.gorm.transform.AstMethodDispatchUtils.callD
44-
import static org.grails.datastore.mapping.reflect.AstUtils.ZERO_PARAMETERS
4544
import static org.grails.datastore.mapping.reflect.AstUtils.copyParameters
4645
import static org.grails.datastore.mapping.reflect.AstUtils.varThis
4746

@@ -70,6 +69,8 @@ class TenantTransform extends AbstractDatastoreMethodDecoratingTransformation im
7069
*/
7170
public static final int POSITION = TransactionalTransform.POSITION - 100
7271

72+
private static final Parameter[] N0_PARAMETER = null
73+
7374
@Override
7475
protected String getRenamedMethodPrefix() {
7576
return RENAMED_METHOD_PREFIX
@@ -87,13 +88,11 @@ class TenantTransform extends AbstractDatastoreMethodDecoratingTransformation im
8788

8889
ClassNode serializableClassNode = make(Serializable)
8990
ClassNode annotationClassNode = annotationNode.classNode
90-
if(CURRENT_TENANT_ANNOTATION_TYPE.equals(annotationClassNode)) {
91-
return makeDelegatingClosureCall( tenantServiceVar, "withCurrent", params( param(serializableClassNode, VAR_TENANT_ID)), originalMethodCallExpr, variableScope)
92-
}
93-
else if(WITHOUT_TENANT_ANNOTATION_TYPE.equals(annotationClassNode)) {
94-
return makeDelegatingClosureCall( tenantServiceVar, "withoutId", ZERO_PARAMETERS, originalMethodCallExpr, variableScope)
95-
}
96-
else {
91+
if (CURRENT_TENANT_ANNOTATION_TYPE.equals(annotationClassNode)) {
92+
return makeDelegatingClosureCall(tenantServiceVar, "withCurrent", params(param(serializableClassNode, VAR_TENANT_ID)), originalMethodCallExpr, variableScope)
93+
} else if (WITHOUT_TENANT_ANNOTATION_TYPE.equals(annotationClassNode)) {
94+
return makeDelegatingClosureCall(tenantServiceVar, "withoutId", N0_PARAMETER, originalMethodCallExpr, variableScope)
95+
} else {
9796
// must be @Tenant
9897
Expression annValue = annotationNode.getMember("value")
9998
if(annValue instanceof ClosureExpression) {
@@ -126,8 +125,8 @@ class TenantTransform extends AbstractDatastoreMethodDecoratingTransformation im
126125
}
127126

128127
@Override
129-
protected Parameter[] prepareNewMethodParameters(MethodNode methodNode, Map<String, ClassNode> genericsSpec) {
130-
if(methodNode.getAnnotations(WITHOUT_TENANT_ANNOTATION_TYPE).isEmpty()) {
128+
protected Parameter[] prepareNewMethodParameters(MethodNode methodNode, Map<String, ClassNode> genericsSpec, ClassNode classNode = null) {
129+
if(methodNode.getAnnotations(WITHOUT_TENANT_ANNOTATION_TYPE).isEmpty() && (!classNode || classNode.getAnnotations(WITHOUT_TENANT_ANNOTATION_TYPE).isEmpty())) {
131130
final Parameter tenantIdParameter = param(make(Serializable), VAR_TENANT_ID)
132131
Parameter[] parameters = methodNode.getParameters()
133132
Parameter[] newParameters = parameters.length > 0 ? (copyParameters(((parameters as List) + [tenantIdParameter]) as Parameter[], genericsSpec)) : [tenantIdParameter] as Parameter[]
@@ -137,6 +136,7 @@ class TenantTransform extends AbstractDatastoreMethodDecoratingTransformation im
137136
return copyParameters(methodNode.getParameters())
138137
}
139138
}
139+
140140
@Override
141141
protected boolean isValidAnnotation(AnnotationNode annotationNode, AnnotatedNode classNode) {
142142
ClassNode annotationClassNode = annotationNode.getClassNode()

grails-datastore-gorm/src/main/groovy/org/grails/datastore/gorm/transactions/transform/TransactionalTransform.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class TransactionalTransform extends AbstractDatastoreMethodDecoratingTransforma
157157
}
158158

159159
@Override
160-
protected Parameter[] prepareNewMethodParameters(MethodNode methodNode, Map<String, ClassNode> genericsSpec) {
160+
protected Parameter[] prepareNewMethodParameters(MethodNode methodNode, Map<String, ClassNode> genericsSpec, ClassNode classNode = null) {
161161
final Parameter transactionStatusParameter = param(make(TransactionStatus), "transactionStatus")
162162
Parameter[] parameters = methodNode.getParameters()
163163
Parameter[] newParameters = parameters.length > 0 ? (copyParameters(((parameters as List) + [transactionStatusParameter]) as Parameter[], genericsSpec)) : [transactionStatusParameter] as Parameter[]

grails-datastore-gorm/src/main/groovy/org/grails/datastore/gorm/transform/AbstractMethodDecoratingTransformation.groovy

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ import static org.grails.datastore.mapping.reflect.AstUtils.*
4848
@CompileStatic
4949
abstract class AbstractMethodDecoratingTransformation extends AbstractGormASTTransformation {
5050

51-
private static final Set<String> METHOD_NAME_EXCLUDES = new HashSet<String>(Arrays.asList("afterPropertiesSet", "destroy"));
52-
private static final Set<String> ANNOTATION_NAME_EXCLUDES = new HashSet<String>(Arrays.asList(PostConstruct.class.getName(), PreDestroy.class.getName(), "grails.web.controllers.ControllerMethod"));
51+
private static final Set<String> METHOD_NAME_EXCLUDES = new HashSet<String>(Arrays.asList("afterPropertiesSet", "destroy"))
52+
private static final Set<String> ANNOTATION_NAME_EXCLUDES = new HashSet<String>(Arrays.asList(PostConstruct.class.getName(), PreDestroy.class.getName(), "grails.web.controllers.ControllerMethod"))
5353
/**
5454
* Key used to store within the original method node metadata, all previous decorated methods
5555
*/
@@ -181,7 +181,7 @@ abstract class AbstractMethodDecoratingTransformation extends AbstractGormASTTra
181181
renamedMethodName = getRenamedMethodPrefix() + methodNode.getName()
182182
}
183183

184-
Parameter[] newParameters = prepareNewMethodParameters(methodNode, GenericsUtils.addMethodGenerics(methodNode, genericsSpec) )
184+
Parameter[] newParameters = prepareNewMethodParameters(methodNode, GenericsUtils.addMethodGenerics(methodNode, genericsSpec), classNode)
185185
MethodNode renamedMethod = moveOriginalCodeToNewMethod(methodNode, renamedMethodName, newParameters, classNode, sourceUnit, genericsSpec)
186186
MethodCallExpression originalMethodCall = buildCallToOriginalMethod(classNode, renamedMethod)
187187

@@ -226,7 +226,7 @@ abstract class AbstractMethodDecoratingTransformation extends AbstractGormASTTra
226226
}
227227
}
228228

229-
protected Parameter[] prepareNewMethodParameters(MethodNode methodNode, Map<String, ClassNode> genericsSpec) {
229+
protected Parameter[] prepareNewMethodParameters(MethodNode methodNode, Map<String, ClassNode> genericsSpec, ClassNode classNode = null) {
230230
return copyParameters(methodNode.getParameters(), genericsSpec)
231231
}
232232

grails-datastore-gorm/src/test/groovy/grails/gorm/annotation/multitenancy/CurrentTenantTransformSpec.groovy

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package grails.gorm.annotation.multitenancy
22

3-
import grails.gorm.multitenancy.TenantService
4-
import org.grails.datastore.mapping.core.Datastore
53
import spock.lang.Specification
64

75
/**
@@ -21,6 +19,103 @@ class BookService {
2119
}
2220
new BookService()
2321
22+
''')
23+
when:"the list books method is invoked"
24+
def result = bookService.listBooks()
25+
26+
then:"An exception was thrown because GORM is not setup"
27+
thrown(IllegalStateException)
28+
29+
}
30+
31+
void "test @CurrentTenant transforms a service class and makes a method in current tenant handling"() {
32+
given:"A service with @CurrentTenant applied as the class level"
33+
def bookService = new GroovyShell().evaluate('''
34+
import grails.gorm.multitenancy.CurrentTenant
35+
36+
@CurrentTenant
37+
class BookService {
38+
39+
List listBooks() {
40+
return ["The Stand"]
41+
}
42+
}
43+
new BookService()
44+
45+
''')
46+
when:"the list books method is invoked"
47+
def result = bookService.listBooks()
48+
49+
then:"An exception was thrown because GORM is not setup"
50+
thrown(IllegalStateException)
51+
52+
}
53+
54+
void "test @CurrentTenant transforms a service class and a method marked with @WithoutTenant in no tenant handling"() {
55+
given:"A service with @CurrentTenant applied as the class level"
56+
def bookService = new GroovyShell().evaluate('''
57+
import grails.gorm.multitenancy.CurrentTenant
58+
import grails.gorm.multitenancy.WithoutTenant
59+
60+
@CurrentTenant
61+
class BookService {
62+
63+
@WithoutTenant
64+
List listBooks() {
65+
return ["The Stand"]
66+
}
67+
}
68+
new BookService()
69+
70+
''')
71+
when:"the list books method is invoked"
72+
def result = bookService.listBooks()
73+
74+
then:"An exception was thrown because GORM is not setup"
75+
thrown(IllegalStateException)
76+
77+
}
78+
79+
void "test @WithoutTenant transforms a service class and makes a method that is wrapped in without tenant handling"() {
80+
given:"A service with @CurrentTenant applied as the class level"
81+
def bookService = new GroovyShell().evaluate('''
82+
import grails.gorm.multitenancy.CurrentTenant
83+
import grails.gorm.multitenancy.WithoutTenant
84+
85+
@WithoutTenant
86+
class BookService {
87+
88+
List listBooks() {
89+
return ["The Stand"]
90+
}
91+
}
92+
new BookService()
93+
94+
''')
95+
when:"the list books method is invoked"
96+
def result = bookService.listBooks()
97+
98+
then:"An exception was thrown because GORM is not setup"
99+
thrown(IllegalStateException)
100+
101+
}
102+
103+
void "test @WithoutTenant transforms a service class and a method marked with @CurrentTenant in current tenant handling"() {
104+
given:"A service with @CurrentTenant applied as the class level"
105+
def bookService = new GroovyShell().evaluate('''
106+
import grails.gorm.multitenancy.CurrentTenant
107+
import grails.gorm.multitenancy.WithoutTenant
108+
109+
@WithoutTenant
110+
class BookService {
111+
112+
@CurrentTenant
113+
List listBooks() {
114+
return ["The Stand"]
115+
}
116+
}
117+
new BookService()
118+
24119
''')
25120
when:"the list books method is invoked"
26121
def result = bookService.listBooks()

travis-publish.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ if [[ $TRAVIS_REPO_SLUG == "grails/grails-data-mapping" && $TRAVIS_PULL_REQUEST
6464
# If there is a tag present then this becomes the latest
6565
if [[ $TRAVIS_TAG =~ ^v[[:digit:]] ]]; then
6666
echo "Triggering documentation build"
67-
git clone https://${GH_TOKEN}@github.com/grails/gorm-docs.git gorm-docs
67+
git clone -b 6.1.x https://${GH_TOKEN}@github.com/grails/gorm-docs.git gorm-docs
6868
cd gorm-docs
6969

7070
if [[ $TRAVIS_TAG =~ [M\d|RC\d] ]]; then
@@ -79,6 +79,10 @@ if [[ $TRAVIS_REPO_SLUG == "grails/grails-data-mapping" && $TRAVIS_PULL_REQUEST
7979
git push --tags
8080
git push
8181
cd ..
82+
83+
if [[ $EXIT_STATUS -eq 0 ]]; then
84+
./gradlew synchronizeWithMavenCentral --no-daemon
85+
fi
8286
fi
8387

8488
else
@@ -90,4 +94,4 @@ fi
9094
if [[ $EXIT_STATUS -eq 0 ]]; then
9195
echo "Publishing Successful."
9296
fi
93-
exit $EXIT_STATUS
97+
exit $EXIT_STATUS

0 commit comments

Comments
 (0)