Skip to content

Commit

Permalink
feat: Allow annotation GrpcClient for target type 'annotation'
Browse files Browse the repository at this point in the history
Add testcases with usage of GrpcClientWrapper meta-annotation.
  • Loading branch information
313hemant313 committed Nov 18, 2023
1 parent 162b717 commit f7fcc9e
Show file tree
Hide file tree
Showing 3 changed files with 234 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
*
* @see GrpcClientBean Add as bean to the {@link ApplicationContext}.
*/
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/*
* Copyright (c) 2016-2021 Michael Zhang <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package net.devh.boot.grpc.test.inject;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

import io.grpc.stub.AbstractStub;
import java.lang.reflect.Field;
import javax.annotation.PostConstruct;
import net.devh.boot.grpc.test.inject.metaannotation.GrpcClientWrapper;
import net.devh.boot.grpc.client.stubfactory.StandardJavaGrpcStubFactory;
import net.devh.boot.grpc.client.stubfactory.StubFactory;
import net.devh.boot.grpc.test.config.BaseAutoConfiguration;
import net.devh.boot.grpc.test.config.InProcessConfiguration;
import net.devh.boot.grpc.test.config.ServiceConfiguration;
import net.devh.boot.grpc.test.inject.CustomGrpc.ConstructorAccessibleStub;
import net.devh.boot.grpc.test.inject.CustomGrpc.CustomAccessibleStub;
import net.devh.boot.grpc.test.inject.CustomGrpc.FactoryMethodAccessibleStub;
import net.devh.boot.grpc.test.inject.GrpcClientInjectionTest.TestConfig;
import net.devh.boot.grpc.test.proto.TestServiceGrpc.TestServiceBlockingStub;
import net.devh.boot.grpc.test.proto.TestServiceGrpc.TestServiceFutureStub;
import net.devh.boot.grpc.test.proto.TestServiceGrpc.TestServiceStub;
import org.junit.jupiter.api.Test;
import org.opentest4j.AssertionFailedError;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

/**
* A test checking that the client injection works.
*
* @author Daniel Theuke ([email protected])
*/
@SpringBootTest
@SpringJUnitConfig(classes = {TestConfig.class, InProcessConfiguration.class,
ServiceConfiguration.class,
BaseAutoConfiguration.class})
@DirtiesContext
class GrpcClientMetaAnnotationTest {

@GrpcClientWrapper(value = "test", extraParamString = "testExtraParamString", extraParamBoolean = true)
TestServiceStub stub;
@GrpcClientWrapper(value = "test", extraParamString = "testExtraParamString", extraParamBoolean = true)
TestServiceBlockingStub blockingStub;
@GrpcClientWrapper(value = "test", extraParamString = "testExtraParamString", extraParamBoolean = true)
TestServiceFutureStub futureStub;
@GrpcClientWrapper(value = "test", extraParamString = "testExtraParamString", extraParamBoolean = true)
ConstructorAccessibleStub constructorStub;
@GrpcClientWrapper(value = "test", extraParamString = "testExtraParamString", extraParamBoolean = true)
FactoryMethodAccessibleStub factoryMethodStub;
@GrpcClientWrapper(value = "test", extraParamString = "testExtraParamString", extraParamBoolean = true)
CustomAccessibleStub customStub;

TestServiceStub stubSetted;
TestServiceBlockingStub blockingStubSetted;
TestServiceFutureStub futureStubSetted;
ConstructorAccessibleStub constructorStubSetted;
FactoryMethodAccessibleStub factoryMethodStubSetted;
CustomAccessibleStub customStubSetted;

@PostConstruct
public void init() {
// Test injection
assertNotNull(this.stub, "stub");
assertNotNull(this.blockingStub, "blockingStub");
assertNotNull(this.futureStub, "futureStub");
assertNotNull(this.constructorStub, "constructorStub");
assertNotNull(this.factoryMethodStub, "factoryMethodStub");
assertNotNull(this.customStub, "customStub");

assertAnnotationExtraParams("testExtraParamString", true);
}

@GrpcClientWrapper(value = "test", extraParamString = "testExtraParamString", extraParamBoolean = true)
void inject(final TestServiceStub stub) {
assertNotNull(stub, "stub");
this.stubSetted = stub;
}

@GrpcClientWrapper(value = "test", extraParamString = "testExtraParamString", extraParamBoolean = true)
void inject(final TestServiceBlockingStub stub) {
assertNotNull(stub, "stub");
this.blockingStubSetted = stub;
}

@GrpcClientWrapper(value = "test", extraParamString = "testExtraParamString", extraParamBoolean = true)
void inject(final TestServiceFutureStub stub) {
assertNotNull(stub, "stub");
this.futureStubSetted = stub;
}

@GrpcClientWrapper(value = "test", extraParamString = "testExtraParamString", extraParamBoolean = true)
void inject(final ConstructorAccessibleStub stub) {
assertNotNull(stub, "stub");
this.constructorStubSetted = stub;
}

@GrpcClientWrapper(value = "test", extraParamString = "testExtraParamString", extraParamBoolean = true)
void inject(final FactoryMethodAccessibleStub stub) {
assertNotNull(stub, "stub");
this.factoryMethodStubSetted = stub;
}

@GrpcClientWrapper(value = "test", extraParamString = "testExtraParamString", extraParamBoolean = true)
void inject(final CustomAccessibleStub stub) {
assertNotNull(stub, "stub");
this.customStubSetted = stub;
}

@Test
void testAllSet() {
// Field injection
assertNotNull(this.stub, "stub");
assertNotNull(this.blockingStub, "blockingStub");
assertNotNull(this.futureStub, "futureStub");
assertNotNull(this.constructorStub, "constructorStub");
assertNotNull(this.factoryMethodStub, "factoryMethodStub");
assertNotNull(this.customStub, "customStub");
// Setter injection
assertNotNull(this.stubSetted, "stubSetted");
assertNotNull(this.blockingStubSetted, "blockingStubSetted");
assertNotNull(this.futureStubSetted, "futureStubSetted");
assertNotNull(this.constructorStubSetted, "constructorStubSetted");
assertNotNull(this.factoryMethodStubSetted, "factoryMethodStubSetted");
assertNotNull(this.customStubSetted, "customStubSetted");
}

@Test
void AnnotationExtraParamsNegativeTest() {

AssertionFailedError exceptionA = assertThrows(
AssertionFailedError.class,
() -> assertAnnotationExtraParams("INCORRECT_VALUE", true),
"failed"
);

AssertionFailedError exceptionB = assertThrows(
AssertionFailedError.class,
() -> assertAnnotationExtraParams("testExtraParamString", false),
"failed"
);

assertNotNull(exceptionA);
assertNotNull(exceptionB);
}

private void assertAnnotationExtraParams(String extraParamStringValue,
boolean extraParamBooleanValue) {
final Field[] fields = this.getClass().getDeclaredFields();
for (final Field field : fields) {
if (field.isAnnotationPresent(GrpcClientWrapper.class)) {
final GrpcClientWrapper annotation = field.getAnnotation(GrpcClientWrapper.class);
assertEquals(extraParamStringValue, annotation.extraParamString());
assertEquals(extraParamBooleanValue, annotation.extraParamBoolean());
}
}
}

@TestConfiguration
public static class TestConfig {

@Bean
StubFactory customStubFactory() {
return new StandardJavaGrpcStubFactory() {

@Override
public boolean isApplicable(final Class<? extends AbstractStub<?>> stubType) {
return CustomStub.class.isAssignableFrom(stubType);
}

@Override
protected String getFactoryMethodName() {
return "custom";
}

};
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package net.devh.boot.grpc.test.inject.metaannotation;


import io.grpc.ClientInterceptor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.core.annotation.AliasFor;

@GrpcClient(value = "")
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface GrpcClientWrapper {

@AliasFor(annotation = GrpcClient.class, attribute = "value")
String value();

@AliasFor(annotation = GrpcClient.class, attribute = "interceptors")
Class<? extends ClientInterceptor>[] interceptors() default {};

@AliasFor(annotation = GrpcClient.class, attribute = "interceptorNames")
String[] interceptorNames() default {};

@AliasFor(annotation = GrpcClient.class, attribute = "sortInterceptors")
boolean sortInterceptors() default false;

String extraParamString();

boolean extraParamBoolean() default false;

}

0 comments on commit f7fcc9e

Please sign in to comment.