From 100b54e764b88bfe537e87337f6240b111e53e1b Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Mon, 4 Nov 2024 09:21:35 -0800 Subject: [PATCH 01/24] comment to start branch --- .../java/gov/hhs/cdc/trustedintermediary/context/Reflection.java | 1 + 1 file changed, 1 insertion(+) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/Reflection.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/Reflection.java index 482dade7a..9e77c1533 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/Reflection.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/Reflection.java @@ -25,6 +25,7 @@ public static Set> getImplementors(Class interfaze) { } public static Set getFieldsAnnotatedWith(Class annotation) { + // todo: return non-singleton classes that use the inject annotation return REFLECTIONS.get(FieldsAnnotated.with(annotation).as(Field.class)); } } From b5ddf868bcc47dd3ff464da0a4beec47aedbceaa Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Sun, 24 Nov 2024 21:56:19 -0800 Subject: [PATCH 02/24] getFieldsAnnotatedWithInstance helper method --- .../hhs/cdc/trustedintermediary/context/Reflection.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/Reflection.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/Reflection.java index 9e77c1533..449cabc2e 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/Reflection.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/Reflection.java @@ -3,8 +3,11 @@ import static org.reflections.scanners.Scanners.FieldsAnnotated; import static org.reflections.scanners.Scanners.SubTypes; +import java.lang.annotation.Annotation; import java.lang.reflect.Field; +import java.util.Arrays; import java.util.Set; +import java.util.stream.Collectors; import org.reflections.Reflections; /** @@ -28,4 +31,10 @@ public static Set getFieldsAnnotatedWith(Class annotation) { // todo: return non-singleton classes that use the inject annotation return REFLECTIONS.get(FieldsAnnotated.with(annotation).as(Field.class)); } + + public static Set getFieldsAnnotatedWithInstance(Class clazz, Class annotation) { + return Arrays.stream(clazz.getDeclaredFields()) + .filter(field -> field.isAnnotationPresent(annotation.asSubclass(Annotation.class))) + .collect(Collectors.toSet()); + } } From c0bd2214ef80d96bb6fccd692b71d3172166fff4 Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Sun, 24 Nov 2024 21:56:55 -0800 Subject: [PATCH 03/24] todo comment deleted --- .../java/gov/hhs/cdc/trustedintermediary/context/Reflection.java | 1 - 1 file changed, 1 deletion(-) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/Reflection.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/Reflection.java index 449cabc2e..de6d58176 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/Reflection.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/Reflection.java @@ -28,7 +28,6 @@ public static Set> getImplementors(Class interfaze) { } public static Set getFieldsAnnotatedWith(Class annotation) { - // todo: return non-singleton classes that use the inject annotation return REFLECTIONS.get(FieldsAnnotated.with(annotation).as(Field.class)); } From 4ddefce0c3a190133fafaff97560b761ca7b2c5f Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Sun, 24 Nov 2024 22:11:57 -0800 Subject: [PATCH 04/24] injectIntoField overloaded method --- .../context/ApplicationContext.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java index 04de60817..0a1d03993 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java @@ -62,6 +62,24 @@ protected static void injectRegisteredImplementations(boolean skipMissingImpleme fields.forEach(field -> injectIntoField(field, skipMissingImplementations)); } + private static void injectIntoField( + Field field, Object instance, boolean skipMissingImplementations) { + var fieldType = field.getType(); + + Object fieldImplementation = getFieldImplementation(fieldType, skipMissingImplementations); + if (fieldImplementation == null) { + return; + } + + field.trySetAccessible(); + try { + field.set(instance, fieldImplementation); + } catch (IllegalAccessException | IllegalArgumentException exception) { + throw new IllegalArgumentException( + "unable to inject " + fieldType + " into " + instance.getClass(), exception); + } + } + private static void injectIntoField(Field field, boolean skipMissingImplementations) { var fieldType = field.getType(); var declaringClass = field.getDeclaringClass(); From ee807ea38607ede8a789e485d660cf0adbed0191 Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Sun, 24 Nov 2024 22:18:12 -0800 Subject: [PATCH 05/24] injectIntoNonSingleton --- .../cdc/trustedintermediary/context/ApplicationContext.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java index 0a1d03993..73d2c0b0c 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java @@ -62,6 +62,12 @@ protected static void injectRegisteredImplementations(boolean skipMissingImpleme fields.forEach(field -> injectIntoField(field, skipMissingImplementations)); } + public static void injectIntoNonSingleton(Object instance) { + var fields = Reflection.getFieldsAnnotatedWithInstance(instance.getClass(), Inject.class); + + fields.forEach(field -> injectIntoField(field, instance, false)); + } + private static void injectIntoField( Field field, Object instance, boolean skipMissingImplementations) { var fieldType = field.getType(); From 740f79da5be4488e9801b9ec2f8d29ece65dc9e7 Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Mon, 25 Nov 2024 14:44:44 -0800 Subject: [PATCH 06/24] access modifier protected to public --- .../hhs/cdc/trustedintermediary/context/ApplicationContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java index 73d2c0b0c..eda17829a 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java @@ -56,7 +56,7 @@ public static void injectRegisteredImplementations() { injectRegisteredImplementations(false); } - protected static void injectRegisteredImplementations(boolean skipMissingImplementations) { + public static void injectRegisteredImplementations(boolean skipMissingImplementations) { var fields = Reflection.getFieldsAnnotatedWith(Inject.class); fields.forEach(field -> injectIntoField(field, skipMissingImplementations)); From 006212e0e9d19bca94c823c593667838a964ccd0 Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Mon, 25 Nov 2024 14:46:11 -0800 Subject: [PATCH 07/24] revert access modifier change --- .../hhs/cdc/trustedintermediary/context/ApplicationContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java index eda17829a..73d2c0b0c 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java @@ -56,7 +56,7 @@ public static void injectRegisteredImplementations() { injectRegisteredImplementations(false); } - public static void injectRegisteredImplementations(boolean skipMissingImplementations) { + protected static void injectRegisteredImplementations(boolean skipMissingImplementations) { var fields = Reflection.getFieldsAnnotatedWith(Inject.class); fields.forEach(field -> injectIntoField(field, skipMissingImplementations)); From 067eba4596d11293bd48499939addbd6309c109d Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Mon, 25 Nov 2024 15:59:20 -0800 Subject: [PATCH 08/24] changes: added logger to HapiFhirResource in order to test a non-singleton class created HapiFhirResourceTest in order to test the changes to HapiFhirResource --- .../external/hapi/HapiFhirResource.java | 6 +++++ .../external/hapi/HapiFhirResourceTest.groovy | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResourceTest.groovy diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResource.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResource.java index 45fdb874e..c29844848 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResource.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResource.java @@ -1,19 +1,25 @@ package gov.hhs.cdc.trustedintermediary.external.hapi; +import gov.hhs.cdc.trustedintermediary.context.ApplicationContext; import gov.hhs.cdc.trustedintermediary.wrappers.HealthData; +import gov.hhs.cdc.trustedintermediary.wrappers.Logger; +import javax.inject.Inject; import org.hl7.fhir.instance.model.api.IBaseResource; /** An implementation of {@link HealthData} to use as a wrapper around HAPI FHIR IBaseResource */ public class HapiFhirResource implements HealthData { + @Inject private Logger logger; private final IBaseResource innerResource; public HapiFhirResource(IBaseResource innerResource) { + ApplicationContext.injectIntoNonSingleton(this); this.innerResource = innerResource; } @Override public IBaseResource getUnderlyingData() { + this.logger.logDebug("testing @Inject"); return innerResource; } } diff --git a/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResourceTest.groovy b/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResourceTest.groovy new file mode 100644 index 000000000..129ec4bfe --- /dev/null +++ b/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResourceTest.groovy @@ -0,0 +1,26 @@ +package gov.hhs.cdc.trustedintermediary.external.hapi + +import gov.hhs.cdc.trustedintermediary.context.TestApplicationContext +import gov.hhs.cdc.trustedintermediary.wrappers.Logger +import org.hl7.fhir.r4.model.Bundle +import spock.lang.Specification + +class HapiFhirResourceTest extends Specification { + + def mockLogger = Mock(Logger) + def setup() { + TestApplicationContext.reset() + TestApplicationContext.init() + TestApplicationContext.register(Logger, mockLogger) + } + + def "sample test run to see if logger is injected"() { + given: + def expectedBundle = new Bundle() + when: + def resource = new HapiFhirResource(expectedBundle) + def actualBundle = resource.getUnderlyingData() + then: + expectedBundle == actualBundle + } +} From 3d9c4f104bbfa6faf78f0e6d473abfcbebd1cba1 Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Mon, 25 Nov 2024 17:43:09 -0800 Subject: [PATCH 09/24] Added implementors unit test to ApplicationContextTest --- .../context/ApplicationContextTest.groovy | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy b/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy index 59902b4f8..8d8c767f6 100644 --- a/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy +++ b/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy @@ -8,6 +8,28 @@ import java.nio.file.Paths class ApplicationContextTest extends Specification { + interface TestingInterface { + void test() + } + + static class DogCow implements TestingInterface { + + @Override + void test() { + print("test()") + } + } + + static class DogCowTwo implements TestingInterface { + + @Override + void test() { + print("testTwo()") + } + } + def DOGCOW = new DogCow() + def DOGCOWTWO = new DogCowTwo() + def setup() { TestApplicationContext.reset() } @@ -21,6 +43,18 @@ class ApplicationContextTest extends Specification { result == ApplicationContext.getImplementation(String.class) } + def "implementors retrieval test"() { + setup: + def dogCow = DOGCOW + def dogCowTwo = DOGCOWTWO + def implementors = new HashSet() + implementors.add(DogCow) + implementors.add(DogCowTwo) + + expect: + implementors == ApplicationContext.getImplementors(TestingInterface) + } + def "implementation injection test"() { given: def injectedValue = "DogCow" From 875b86bb29a09fdc048dcb5e280e7a08512e80e7 Mon Sep 17 00:00:00 2001 From: Luis Pabon Date: Tue, 26 Nov 2024 14:24:54 -0500 Subject: [PATCH 10/24] Minor refactoring on some AppContext injection methods --- .../context/ApplicationContext.java | 27 +++++++++---------- .../context/TestApplicationContext.groovy | 3 ++- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java index 73d2c0b0c..809f6108a 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java @@ -31,6 +31,8 @@ public class ApplicationContext { protected static final Map TEST_ENV_VARS = new ConcurrentHashMap<>(); protected static final Set IMPLEMENTATIONS = new HashSet<>(); + protected static boolean skipMissingImplementations = false; + protected ApplicationContext() {} public static void register(Class clazz, Object implementation) { @@ -53,26 +55,25 @@ public static Set> getImplementors(Class interfaze) { } public static void injectRegisteredImplementations() { - injectRegisteredImplementations(false); + doInjectRegisteredImplementations(); } - protected static void injectRegisteredImplementations(boolean skipMissingImplementations) { + protected static void doInjectRegisteredImplementations() { var fields = Reflection.getFieldsAnnotatedWith(Inject.class); - fields.forEach(field -> injectIntoField(field, skipMissingImplementations)); + fields.forEach(ApplicationContext::injectIntoField); } public static void injectIntoNonSingleton(Object instance) { var fields = Reflection.getFieldsAnnotatedWithInstance(instance.getClass(), Inject.class); - fields.forEach(field -> injectIntoField(field, instance, false)); + fields.forEach(field -> injectIntoField(field, instance)); } - private static void injectIntoField( - Field field, Object instance, boolean skipMissingImplementations) { + private static void injectIntoField(Field field, Object instance) { var fieldType = field.getType(); - Object fieldImplementation = getFieldImplementation(fieldType, skipMissingImplementations); + Object fieldImplementation = getFieldImplementation(fieldType); if (fieldImplementation == null) { return; } @@ -86,7 +87,7 @@ private static void injectIntoField( } } - private static void injectIntoField(Field field, boolean skipMissingImplementations) { + private static void injectIntoField(Field field) { var fieldType = field.getType(); var declaringClass = field.getDeclaringClass(); @@ -100,13 +101,13 @@ private static void injectIntoField(Field field, boolean skipMissingImplementati declaringClassesToTry.add(declaringClass); declaringClassesToTry.addAll(Arrays.asList(declaringClass.getInterfaces())); - Object fieldImplementation = getFieldImplementation(fieldType, skipMissingImplementations); + Object fieldImplementation = getFieldImplementation(fieldType); if (fieldImplementation == null) { return; } Object declaringClassImplementation = - getDeclaringClassImplementation(declaringClassesToTry, skipMissingImplementations); + getDeclaringClassImplementation(declaringClassesToTry); if (declaringClassImplementation == null) { return; } @@ -121,8 +122,7 @@ private static void injectIntoField(Field field, boolean skipMissingImplementati } } - private static Object getFieldImplementation( - Class fieldType, boolean skipMissingImplementations) { + private static Object getFieldImplementation(Class fieldType) { Object fieldImplementation; try { @@ -140,8 +140,7 @@ private static Object getFieldImplementation( return fieldImplementation; } - private static Object getDeclaringClassImplementation( - List> declaringClassesToTry, boolean skipMissingImplementations) { + private static Object getDeclaringClassImplementation(List> declaringClassesToTry) { Object declaringClassImplementation = declaringClassesToTry.stream() .map( diff --git a/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy b/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy index 24c37e2a8..53600307c 100644 --- a/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy +++ b/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy @@ -20,7 +20,8 @@ class TestApplicationContext extends ApplicationContext { } def static injectRegisteredImplementations() { - injectRegisteredImplementations(true) + skipMissingImplementations = true + doInjectRegisteredImplementations() } def static addEnvironmentVariable(String key, String value) { From 4adaa27fe115c81b0b1c74c3a94da8f09800dd4a Mon Sep 17 00:00:00 2001 From: Luis Pabon Date: Tue, 26 Nov 2024 16:22:40 -0500 Subject: [PATCH 11/24] Make the skip flag on TestApplicationContext switchable from the test classes --- .../trustedintermediary/context/TestApplicationContext.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy b/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy index 53600307c..ac036be5a 100644 --- a/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy +++ b/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy @@ -19,8 +19,8 @@ class TestApplicationContext extends ApplicationContext { TEST_ENV_VARS.clear() } - def static injectRegisteredImplementations() { - skipMissingImplementations = true + def static injectRegisteredImplementations(def skip = true) { + skipMissingImplementations = skip doInjectRegisteredImplementations() } From ff4781a09e83a51011bc529b4464aa195e90f9eb Mon Sep 17 00:00:00 2001 From: Luis Pabon Date: Tue, 3 Dec 2024 11:00:41 -0500 Subject: [PATCH 12/24] Update ApplicationContext.java Remove unreachable if statement --- .../cdc/trustedintermediary/context/ApplicationContext.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java index 809f6108a..740bc66e3 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java @@ -108,9 +108,6 @@ private static void injectIntoField(Field field) { Object declaringClassImplementation = getDeclaringClassImplementation(declaringClassesToTry); - if (declaringClassImplementation == null) { - return; - } field.trySetAccessible(); From e5d184db86a33934bd88afc1ddedb3f52143d9a3 Mon Sep 17 00:00:00 2001 From: Luis Pabon Date: Tue, 3 Dec 2024 11:01:28 -0500 Subject: [PATCH 13/24] Update TestApplicationContext.groovy Add additional line in coverage --- .../trustedintermediary/context/TestApplicationContext.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy b/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy index ac036be5a..3c038413b 100644 --- a/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy +++ b/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy @@ -21,7 +21,7 @@ class TestApplicationContext extends ApplicationContext { def static injectRegisteredImplementations(def skip = true) { skipMissingImplementations = skip - doInjectRegisteredImplementations() + ApplicationContext.injectRegisteredImplementations() } def static addEnvironmentVariable(String key, String value) { From 083ddb4e53d06674f04f1ff263d73ab47f126a91 Mon Sep 17 00:00:00 2001 From: Luis Pabon Date: Tue, 3 Dec 2024 12:24:10 -0500 Subject: [PATCH 14/24] Update TestApplicationContext.groovy Remove parameter from injectRegisteredImplementations --- .../trustedintermediary/context/TestApplicationContext.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy b/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy index 3c038413b..735e78fc7 100644 --- a/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy +++ b/shared/src/testFixtures/groovy/gov/hhs/cdc/trustedintermediary/context/TestApplicationContext.groovy @@ -19,8 +19,8 @@ class TestApplicationContext extends ApplicationContext { TEST_ENV_VARS.clear() } - def static injectRegisteredImplementations(def skip = true) { - skipMissingImplementations = skip + def static injectRegisteredImplementations() { + skipMissingImplementations = true ApplicationContext.injectRegisteredImplementations() } From 0ac729e3fabe57f01f92dcff87efc77fa2c1e855 Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Wed, 4 Dec 2024 09:40:50 -0800 Subject: [PATCH 15/24] added unit tests to cover new code --- .../context/ApplicationContextTest.groovy | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy b/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy index 8d8c767f6..cf3a3e889 100644 --- a/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy +++ b/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy @@ -1,5 +1,7 @@ package gov.hhs.cdc.trustedintermediary.context +import gov.hhs.cdc.trustedintermediary.ruleengine.RuleEngine +import gov.hhs.cdc.trustedintermediary.wrappers.Logger import spock.lang.Specification import javax.inject.Inject @@ -12,6 +14,12 @@ class ApplicationContextTest extends Specification { void test() } + class NonSingletonClazz { + @Inject + Logger logger + void test() {} + } + static class DogCow implements TestingInterface { @Override @@ -55,6 +63,36 @@ class ApplicationContextTest extends Specification { implementors == ApplicationContext.getImplementors(TestingInterface) } + def "injectIntoNonSingleton unhappy path"() { + given: + def nonSingletonClass = new NonSingletonClazz() + def object = new Object() + ApplicationContext.register(Logger, object) + when: + ApplicationContext.injectIntoNonSingleton(nonSingletonClass) + then: + thrown(IllegalArgumentException) + } + + def "injectIntoNonSingleton unhappy path when fieldImplementation runs into an error"() { + given: + def nonSingletonClass = new NonSingletonClazz() + when: + ApplicationContext.injectIntoNonSingleton(nonSingletonClass) + then: + thrown(IllegalArgumentException) + } + + def "injectIntoNonSingleton unhappy path when fieldImplementation is null"() { + given: + def nonSingletonClass = new NonSingletonClazz() + when: + ApplicationContext.skipMissingImplementations = true + ApplicationContext.injectIntoNonSingleton(nonSingletonClass) + then: + noExceptionThrown() + } + def "implementation injection test"() { given: def injectedValue = "DogCow" From 18c2f48d96737e57454a99b33666e185e8c8e560 Mon Sep 17 00:00:00 2001 From: Luis Pabon Date: Thu, 5 Dec 2024 13:00:43 -0500 Subject: [PATCH 16/24] Update ApplicationContextTest.groovy Added test case for unsupported injection classes --- .../context/ApplicationContextTest.groovy | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy b/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy index cf3a3e889..4bb8f349c 100644 --- a/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy +++ b/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy @@ -1,6 +1,5 @@ package gov.hhs.cdc.trustedintermediary.context -import gov.hhs.cdc.trustedintermediary.ruleengine.RuleEngine import gov.hhs.cdc.trustedintermediary.wrappers.Logger import spock.lang.Specification @@ -205,6 +204,25 @@ class ApplicationContextTest extends Specification { Files.deleteIfExists(directoryPath) } + def "registering an unsupported injection class"() { + given: + def injectedValue = "DogCow" + def injectionInstantiation = new InjectionDeclaringClass() + + TestApplicationContext.register(List.class, injectionInstantiation) + // notice above that I'm registering the injectionInstantiation object as a List class. + // injectionInstantiation is of class InjectionDeclaringClass, + // and InjectionDeclaringClass doesn't implement List (it only implements AFieldInterface). + TestApplicationContext.register(String.class, injectedValue) + + when: + TestApplicationContext.injectRegisteredImplementations() + injectionInstantiation.getAField() + + then: + thrown(NullPointerException) + } + class InjectionDeclaringClass { @Inject private String aField From 51af9aba3a9ce8e6f408a2a853743a421c9b4240 Mon Sep 17 00:00:00 2001 From: Luis Pabon Date: Mon, 9 Dec 2024 13:23:47 -0500 Subject: [PATCH 17/24] Update ApplicationContext.java Print an error message if the class implementation is not found --- .../cdc/trustedintermediary/context/ApplicationContext.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java index 740bc66e3..c65c28bd2 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java @@ -108,6 +108,9 @@ private static void injectIntoField(Field field) { Object declaringClassImplementation = getDeclaringClassImplementation(declaringClassesToTry); + if (declaringClassImplementation == null) { + System.err.println("No class implementation found"); + } field.trySetAccessible(); From a1ab8992c8704bcf6b47b1ba348e8998cd9dd164 Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Thu, 12 Dec 2024 08:59:54 -0800 Subject: [PATCH 18/24] use return instead of System.err --- .../hhs/cdc/trustedintermediary/context/ApplicationContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java index c65c28bd2..809f6108a 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java @@ -109,7 +109,7 @@ private static void injectIntoField(Field field) { Object declaringClassImplementation = getDeclaringClassImplementation(declaringClassesToTry); if (declaringClassImplementation == null) { - System.err.println("No class implementation found"); + return; } field.trySetAccessible(); From 5672dccc2980523a093cda080a7eb147cc46accd Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Thu, 12 Dec 2024 09:25:43 -0800 Subject: [PATCH 19/24] refactoring - dry --- .../context/ApplicationContext.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java index 809f6108a..467ce0d38 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java @@ -101,10 +101,10 @@ private static void injectIntoField(Field field) { declaringClassesToTry.add(declaringClass); declaringClassesToTry.addAll(Arrays.asList(declaringClass.getInterfaces())); - Object fieldImplementation = getFieldImplementation(fieldType); - if (fieldImplementation == null) { - return; - } + // Object fieldImplementation = getFieldImplementation(fieldType); + // if (fieldImplementation == null) { + // return; + // } Object declaringClassImplementation = getDeclaringClassImplementation(declaringClassesToTry); @@ -112,14 +112,17 @@ private static void injectIntoField(Field field) { return; } - field.trySetAccessible(); + injectIntoField(field, declaringClassImplementation); - try { - field.set(declaringClassImplementation, fieldImplementation); - } catch (IllegalAccessException | IllegalArgumentException exception) { - throw new IllegalArgumentException( - "Unable to inject " + fieldType + " into " + declaringClass, exception); - } + // field.trySetAccessible(); + + // try { + // field.set(declaringClassImplementation, fieldImplementation); + // } catch (IllegalAccessException | IllegalArgumentException exception) { + // throw new IllegalArgumentException( + // "Unable to inject " + fieldType + " into " + declaringClass, + // exception); + // } } private static Object getFieldImplementation(Class fieldType) { From e9f6e02cdf6d73a4625b6db0f2f57bd91f40e565 Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Thu, 12 Dec 2024 09:31:46 -0800 Subject: [PATCH 20/24] thown(NullPointerException) -> noExceptionThrown() --- .../context/ApplicationContextTest.groovy | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy b/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy index 4bb8f349c..fe606965c 100644 --- a/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy +++ b/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy @@ -210,9 +210,6 @@ class ApplicationContextTest extends Specification { def injectionInstantiation = new InjectionDeclaringClass() TestApplicationContext.register(List.class, injectionInstantiation) - // notice above that I'm registering the injectionInstantiation object as a List class. - // injectionInstantiation is of class InjectionDeclaringClass, - // and InjectionDeclaringClass doesn't implement List (it only implements AFieldInterface). TestApplicationContext.register(String.class, injectedValue) when: @@ -220,7 +217,7 @@ class ApplicationContextTest extends Specification { injectionInstantiation.getAField() then: - thrown(NullPointerException) + noExceptionThrown() } class InjectionDeclaringClass { From ba81073377d78dd88f50aa578b92895f2e7e0466 Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Thu, 12 Dec 2024 09:32:54 -0800 Subject: [PATCH 21/24] added comments to indicate changes that will be deleted --- .../external/hapi/HapiFhirResource.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResource.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResource.java index c29844848..be8933e08 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResource.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResource.java @@ -9,17 +9,18 @@ /** An implementation of {@link HealthData} to use as a wrapper around HAPI FHIR IBaseResource */ public class HapiFhirResource implements HealthData { - @Inject private Logger logger; + @Inject private Logger logger; // this line will get deleted once PR is apporved. private final IBaseResource innerResource; public HapiFhirResource(IBaseResource innerResource) { - ApplicationContext.injectIntoNonSingleton(this); + ApplicationContext.injectIntoNonSingleton( + this); // this line will get deleted once PR is apporved. this.innerResource = innerResource; } @Override public IBaseResource getUnderlyingData() { - this.logger.logDebug("testing @Inject"); + this.logger.logDebug("testing @Inject"); // this line will get deleted once PR is apporved. return innerResource; } } From c3cce16dc6a831053b71044484a6a27f0f0f34cb Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Thu, 12 Dec 2024 09:34:39 -0800 Subject: [PATCH 22/24] deleted commented out code --- .../context/ApplicationContext.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java index 467ce0d38..61b261c72 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/context/ApplicationContext.java @@ -88,7 +88,6 @@ private static void injectIntoField(Field field, Object instance) { } private static void injectIntoField(Field field) { - var fieldType = field.getType(); var declaringClass = field.getDeclaringClass(); if (!IMPLEMENTATIONS.contains(declaringClass)) { @@ -101,11 +100,6 @@ private static void injectIntoField(Field field) { declaringClassesToTry.add(declaringClass); declaringClassesToTry.addAll(Arrays.asList(declaringClass.getInterfaces())); - // Object fieldImplementation = getFieldImplementation(fieldType); - // if (fieldImplementation == null) { - // return; - // } - Object declaringClassImplementation = getDeclaringClassImplementation(declaringClassesToTry); if (declaringClassImplementation == null) { @@ -113,16 +107,6 @@ private static void injectIntoField(Field field) { } injectIntoField(field, declaringClassImplementation); - - // field.trySetAccessible(); - - // try { - // field.set(declaringClassImplementation, fieldImplementation); - // } catch (IllegalAccessException | IllegalArgumentException exception) { - // throw new IllegalArgumentException( - // "Unable to inject " + fieldType + " into " + declaringClass, - // exception); - // } } private static Object getFieldImplementation(Class fieldType) { From f8f6e5b6755c0ab89433a2984e60df0abfedf1bb Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Thu, 12 Dec 2024 11:32:19 -0800 Subject: [PATCH 23/24] reinstated comments for test case --- .../trustedintermediary/context/ApplicationContextTest.groovy | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy b/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy index fe606965c..72c45dca7 100644 --- a/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy +++ b/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/context/ApplicationContextTest.groovy @@ -210,6 +210,9 @@ class ApplicationContextTest extends Specification { def injectionInstantiation = new InjectionDeclaringClass() TestApplicationContext.register(List.class, injectionInstantiation) + // notice above that I'm registering the injectionInstantiation object as a List class. + // injectionInstantiation is of class InjectionDeclaringClass, + // and InjectionDeclaringClass doesn't implement List (it only implements AFieldInterface). TestApplicationContext.register(String.class, injectedValue) when: From 37a57fa48812bcb99da2b3806cdb04e6721c29b8 Mon Sep 17 00:00:00 2001 From: jorge Lopez Date: Thu, 12 Dec 2024 11:35:12 -0800 Subject: [PATCH 24/24] deleted test changes: in HapiFhirResource and deleted file HapifhirResourceTest.groovy --- .../external/hapi/HapiFhirResource.java | 7 ----- .../external/hapi/HapiFhirResourceTest.groovy | 26 ------------------- 2 files changed, 33 deletions(-) delete mode 100644 shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResourceTest.groovy diff --git a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResource.java b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResource.java index be8933e08..45fdb874e 100644 --- a/shared/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResource.java +++ b/shared/src/main/java/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResource.java @@ -1,26 +1,19 @@ package gov.hhs.cdc.trustedintermediary.external.hapi; -import gov.hhs.cdc.trustedintermediary.context.ApplicationContext; import gov.hhs.cdc.trustedintermediary.wrappers.HealthData; -import gov.hhs.cdc.trustedintermediary.wrappers.Logger; -import javax.inject.Inject; import org.hl7.fhir.instance.model.api.IBaseResource; /** An implementation of {@link HealthData} to use as a wrapper around HAPI FHIR IBaseResource */ public class HapiFhirResource implements HealthData { - @Inject private Logger logger; // this line will get deleted once PR is apporved. private final IBaseResource innerResource; public HapiFhirResource(IBaseResource innerResource) { - ApplicationContext.injectIntoNonSingleton( - this); // this line will get deleted once PR is apporved. this.innerResource = innerResource; } @Override public IBaseResource getUnderlyingData() { - this.logger.logDebug("testing @Inject"); // this line will get deleted once PR is apporved. return innerResource; } } diff --git a/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResourceTest.groovy b/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResourceTest.groovy deleted file mode 100644 index 129ec4bfe..000000000 --- a/shared/src/test/groovy/gov/hhs/cdc/trustedintermediary/external/hapi/HapiFhirResourceTest.groovy +++ /dev/null @@ -1,26 +0,0 @@ -package gov.hhs.cdc.trustedintermediary.external.hapi - -import gov.hhs.cdc.trustedintermediary.context.TestApplicationContext -import gov.hhs.cdc.trustedintermediary.wrappers.Logger -import org.hl7.fhir.r4.model.Bundle -import spock.lang.Specification - -class HapiFhirResourceTest extends Specification { - - def mockLogger = Mock(Logger) - def setup() { - TestApplicationContext.reset() - TestApplicationContext.init() - TestApplicationContext.register(Logger, mockLogger) - } - - def "sample test run to see if logger is injected"() { - given: - def expectedBundle = new Bundle() - when: - def resource = new HapiFhirResource(expectedBundle) - def actualBundle = resource.getUnderlyingData() - then: - expectedBundle == actualBundle - } -}