diff --git a/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/ActionBuilder.java b/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/builder/ActionBuilder.java similarity index 95% rename from adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/ActionBuilder.java rename to adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/builder/ActionBuilder.java index ef0610453..30a47fd96 100644 --- a/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/ActionBuilder.java +++ b/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/builder/ActionBuilder.java @@ -1,4 +1,4 @@ -package uk.gov.justice.services.adapters.test.utils; +package uk.gov.justice.services.adapters.test.utils.builder; import org.raml.model.Action; import org.raml.model.ActionType; diff --git a/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/RamlBuilder.java b/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/builder/RamlBuilder.java similarity index 88% rename from adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/RamlBuilder.java rename to adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/builder/RamlBuilder.java index e854d555c..66ddcd174 100644 --- a/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/RamlBuilder.java +++ b/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/builder/RamlBuilder.java @@ -1,11 +1,11 @@ -package uk.gov.justice.services.adapters.test.utils; +package uk.gov.justice.services.adapters.test.utils.builder; import org.raml.model.ActionType; import org.raml.model.Raml; import org.raml.model.Resource; -import static uk.gov.justice.services.adapters.test.utils.ActionBuilder.action; -import static uk.gov.justice.services.adapters.test.utils.ResourceBuilder.resource; +import static uk.gov.justice.services.adapters.test.utils.builder.ActionBuilder.action; +import static uk.gov.justice.services.adapters.test.utils.builder.ResourceBuilder.resource; import java.util.ArrayList; import java.util.HashMap; @@ -70,4 +70,4 @@ public Raml build() { raml.setResources(resources); return raml; } -} +} \ No newline at end of file diff --git a/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/ResourceBuilder.java b/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/builder/ResourceBuilder.java similarity index 87% rename from adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/ResourceBuilder.java rename to adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/builder/ResourceBuilder.java index 0eb46e48e..0fe90c82e 100644 --- a/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/ResourceBuilder.java +++ b/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/builder/ResourceBuilder.java @@ -1,4 +1,4 @@ -package uk.gov.justice.services.adapters.test.utils; +package uk.gov.justice.services.adapters.test.utils.builder; import org.raml.model.Action; import org.raml.model.ActionType; @@ -9,6 +9,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static uk.gov.justice.services.adapters.test.utils.builder.ActionBuilder.action; public class ResourceBuilder { private final List actionBuilders = new ArrayList<>(); @@ -61,4 +62,9 @@ public Resource build() { resource.setActions(actions); return resource; } + + public ResourceBuilder withDefaultAction() { + with(action().with(ActionType.POST)); + return this; + } } diff --git a/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/AllObjectsScanner.java b/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/compiler/AllObjectsScanner.java similarity index 91% rename from adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/AllObjectsScanner.java rename to adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/compiler/AllObjectsScanner.java index cb37d3cd5..df8e7b84c 100644 --- a/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/AllObjectsScanner.java +++ b/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/compiler/AllObjectsScanner.java @@ -1,4 +1,4 @@ -package uk.gov.justice.services.adapters.test.utils; +package uk.gov.justice.services.adapters.test.utils.compiler; import org.reflections.scanners.SubTypesScanner; diff --git a/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/CompilationException.java b/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/compiler/CompilationException.java similarity index 82% rename from adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/CompilationException.java rename to adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/compiler/CompilationException.java index 96e21460f..4d2695b81 100644 --- a/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/CompilationException.java +++ b/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/compiler/CompilationException.java @@ -1,4 +1,4 @@ -package uk.gov.justice.services.adapters.test.utils; +package uk.gov.justice.services.adapters.test.utils.compiler; public class CompilationException extends RuntimeException { private static final long serialVersionUID = 1L; diff --git a/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/JavaCompilerUtil.java b/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/compiler/JavaCompilerUtil.java similarity index 99% rename from adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/JavaCompilerUtil.java rename to adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/compiler/JavaCompilerUtil.java index 29525c4a7..eed02ef9e 100644 --- a/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/JavaCompilerUtil.java +++ b/adapters/adapters-test-utils/src/main/java/uk/gov/justice/services/adapters/test/utils/compiler/JavaCompilerUtil.java @@ -1,4 +1,4 @@ -package uk.gov.justice.services.adapters.test.utils; +package uk.gov.justice.services.adapters.test.utils.compiler; import com.google.common.collect.Sets; import org.apache.commons.io.FileUtils; diff --git a/adapters/jms-adapter-generator/pom.xml b/adapters/jms-adapter-generator/pom.xml new file mode 100644 index 000000000..e258c16fc --- /dev/null +++ b/adapters/jms-adapter-generator/pom.xml @@ -0,0 +1,56 @@ + + 4.0.0 + + adapters + uk.gov.justice.services + 0.1.0-SNAPSHOT + + jms-adapter-generator + + + javax + javaee-api + + + org.slf4j + slf4j-api + + + uk.gov.justice + raml-generator-core + ${raml-maven-plugin.version} + + + org.raml + raml-parser + + + uk.gov.justice.services + core + ${project.version} + + + junit + junit + test + + + org.hamcrest + hamcrest-library + test + + + org.mockito + mockito-core + test + + + uk.gov.justice.services + adapters-test-utils + ${project.version} + test + + + + \ No newline at end of file diff --git a/adapters/jms-adapter-generator/src/main/java/uk/gov/justice/raml/jms/core/JmsEndpointGenerator.java b/adapters/jms-adapter-generator/src/main/java/uk/gov/justice/raml/jms/core/JmsEndpointGenerator.java new file mode 100644 index 000000000..89e256e4b --- /dev/null +++ b/adapters/jms-adapter-generator/src/main/java/uk/gov/justice/raml/jms/core/JmsEndpointGenerator.java @@ -0,0 +1,189 @@ +package uk.gov.justice.raml.jms.core; + +import org.apache.commons.lang.StringUtils; +import org.raml.model.Action; +import org.raml.model.ActionType; +import org.raml.model.Raml; +import org.raml.model.Resource; +import uk.gov.justice.raml.core.Generator; +import uk.gov.justice.raml.core.GeneratorConfig; +import uk.gov.justice.services.core.annotation.Component; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static java.lang.String.format; +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.joining; +import static org.apache.commons.io.FileUtils.write; +import static uk.gov.justice.raml.jms.core.TemplateRenderer.render; + +/** + * Generates JMS endpoint classes out of RAML object + */ +public class JmsEndpointGenerator implements Generator { + + private static final String UTF_8 = "UTF-8"; + private static final String TEMPLATE_LOADING_ERROR = "Failed to load template resource JmsListenerTemplate.tpm"; + private static final String ACTIONS_EMPTY_ERROR = "No actions to process"; + private static final String OUTPUT_FILE_GENERATION_ERROR = "Failed to create output file for %s"; + private static final String FILENAME_POSTFIX = "JmsListener.java"; + private static final String JMS_TEMPLATE_RESOURCE = "JmsListenerTemplate.tpm"; + private static final Pattern MEDIA_TYPE_PATTERN = Pattern.compile("(application/vnd.)(\\S+)(\\+\\S+)"); + private static final String EMPTY = ""; + + /** + * Generates JMS endpoint classes out of RAML object + * + * @param raml - the RAML object + * @param configuration - contains package of generated sources, as well as source and + * destination folders + */ + @Override + public void run(final Raml raml, final GeneratorConfig configuration) { + final Collection ramlResourceModels = raml.getResources().values(); + ramlResourceModels.stream() + .map(resource -> templateAttributesFrom(resource, configuration)) + .forEach(attribute -> writeToTemplateFile(attribute, jmsListenerTemplate(), outputDirFrom(configuration))); + + } + + private File outputDirFrom(final GeneratorConfig configuration) { + return new File(format("%s/%s", configuration.getOutputDirectory(), + configuration.getBasePackageName().replace(".", "/"))); + } + + @SuppressWarnings("resource") + private String jmsListenerTemplate() { + try (final InputStream stream = getClass().getResourceAsStream(JMS_TEMPLATE_RESOURCE)) { + return new Scanner(stream, UTF_8).useDelimiter("\\A").next(); + } catch (IOException e) { + throw new JmsEndpointGeneratorException(TEMPLATE_LOADING_ERROR, e); + } + } + + private void writeToTemplateFile(final Attributes attributes, final String jmsTemplate, + final File outputDirectory) { + final File file = new File(outputDirectory, createJmsFilenameFrom(attributes.uri)); + try { + write(file, render(jmsTemplate, attributes.attributesMap)); + } catch (IOException e) { + throw new JmsEndpointGeneratorException(format(OUTPUT_FILE_GENERATION_ERROR, attributes.uri), e); + } + } + + private String createJmsFilenameFrom(final String uri) { + return classNameOf(uri) + FILENAME_POSTFIX; + } + + /** + * Create Template Attributes from the RAML Resource and Configuration + * + * @param resource RAML Resource + * @param configuration Configuration information + * @return template attributes + */ + private Attributes templateAttributesFrom(final Resource resource, final GeneratorConfig configuration) { + final String uri = resource.getUri(); + final HashMap data = new HashMap<>(); + + data.put("PACKAGE_NAME", configuration.getBasePackageName()); + data.put("CLASS_NAME", classNameOf(uri)); + data.put("ADAPTER_TYPE", componentOf(uri).name()); + data.put("DESTINATION_LOOKUP", destinationNameOf(uri)); + data.put("MESSAGE_SELECTOR", messageSelectorsFrom(resource.getActions())); + + return new Attributes(data, uri); + } + + /** + * Convert given URI to a camel cased class name + * + * @param uri URI String to convert + * @return camel case class name + */ + private String classNameOf(final String uri) { + return stream(uri.split("/|\\.")) + .map(StringUtils::capitalize) + .collect(joining(EMPTY)); + } + + /** + * Convert given URI to a valid Component + * + * Takes the last and second to last parts of the URI as the pillar and tier of the Component + * + * @param uri URI String to convert + * @return component the value of the pillar and tier parts of the uri + */ + private Component componentOf(final String uri) { + final String[] uriParts = uri.split("\\."); + return Component.valueOf(uriParts[uriParts.length - 1], uriParts[uriParts.length - 2]); + } + + /** + * Construct the destination name from the URI + * @param uri URI String to convert + * @return destination name + */ + private String destinationNameOf(final String uri) { + return uri.replaceAll("/", ""); + } + + /** + * Parse and format all the message selectors from the Post Action + * + * @param actions Map of ActionType to Action + * @return formatted message selector String + */ + private String messageSelectorsFrom(final Map actions) { + if (actions.isEmpty()) { + throw new JmsEndpointGeneratorException(ACTIONS_EMPTY_ERROR); + } + return format("'%s'", parse(actions.get(ActionType.POST))); + } + + /** + * Parse an Action into a message selectors String + * + * @param action Action to parse + * @return formatted message selectors String + */ + private String parse(final Action action) { + return action.getBody().keySet().stream() + .map(this::commandNameOf) + .collect(joining("','")); + } + + /** + * Converts media type String to a command name + * + * Command name is equal to everything between "application/vnd." and the first "+". + * + * @param mediaType String representation of the Media Type + * @return command name + */ + private String commandNameOf(final String mediaType) { + final Matcher m = MEDIA_TYPE_PATTERN.matcher(mediaType); + m.find(); + return m.group(2); + } + + private class Attributes { + final Map attributesMap; + final String uri; + + public Attributes(final Map attributesMap, final String uri) { + this.attributesMap = attributesMap; + this.uri = uri; + } + } + +} diff --git a/adapters/jms-adapter-generator/src/main/java/uk/gov/justice/raml/jms/core/JmsEndpointGeneratorException.java b/adapters/jms-adapter-generator/src/main/java/uk/gov/justice/raml/jms/core/JmsEndpointGeneratorException.java new file mode 100644 index 000000000..3a646f6d7 --- /dev/null +++ b/adapters/jms-adapter-generator/src/main/java/uk/gov/justice/raml/jms/core/JmsEndpointGeneratorException.java @@ -0,0 +1,13 @@ +package uk.gov.justice.raml.jms.core; + +public class JmsEndpointGeneratorException extends RuntimeException { + private static final long serialVersionUID = 1L; + + public JmsEndpointGeneratorException(final String message, final Throwable e) { + super(message, e); + } + + public JmsEndpointGeneratorException(final String message) { + super(message); + } +} diff --git a/adapters/jms-adapter-generator/src/main/java/uk/gov/justice/raml/jms/core/TemplateRenderer.java b/adapters/jms-adapter-generator/src/main/java/uk/gov/justice/raml/jms/core/TemplateRenderer.java new file mode 100644 index 000000000..a918df75d --- /dev/null +++ b/adapters/jms-adapter-generator/src/main/java/uk/gov/justice/raml/jms/core/TemplateRenderer.java @@ -0,0 +1,29 @@ +package uk.gov.justice.raml.jms.core; + +import static java.lang.String.format; + +import java.util.Map; + +import org.apache.commons.lang.text.StrBuilder; + +/** + * Basic template rendering class + * + */ +public class TemplateRenderer { + public static final String ATTRIBUTE_KEY_FORMAT = "${%s}"; + + private TemplateRenderer() { + } + + /** + * @param template - string containing template + * @param attributes - attribute keys and values to be used in rendering of the template + * @return - rendered template + */ + public static String render(final String template, final Map attributes) { + final StrBuilder stringBuilder = new StrBuilder(template); + attributes.entrySet().forEach(e -> stringBuilder.replaceAll(format(ATTRIBUTE_KEY_FORMAT, e.getKey()), e.getValue())); + return stringBuilder.toString(); + } +} diff --git a/adapters/jms-adapter-generator/src/main/resources/uk/gov/justice/raml/jms/core/JmsListenerTemplate.tpm b/adapters/jms-adapter-generator/src/main/resources/uk/gov/justice/raml/jms/core/JmsListenerTemplate.tpm new file mode 100644 index 000000000..0e53b23c8 --- /dev/null +++ b/adapters/jms-adapter-generator/src/main/resources/uk/gov/justice/raml/jms/core/JmsListenerTemplate.tpm @@ -0,0 +1,25 @@ +package ${PACKAGE_NAME}; + +import javax.inject.Inject; +import javax.ejb.MessageDriven; +import javax.ejb.ActivationConfigProperty; +import uk.gov.justice.services.core.annotation.Adapter; +import uk.gov.justice.services.core.dispatcher.Dispatcher; +import uk.gov.justice.services.core.jms.AbstractJMSListener; +import static uk.gov.justice.services.core.annotation.Component.*; + +@MessageDriven(activationConfig = { + @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "${DESTINATION_LOOKUP}"), + @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), + @ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "CPPNAME in(${MESSAGE_SELECTOR})") +}) +@Adapter(${ADAPTER_TYPE}) +public class ${CLASS_NAME}JmsListener extends AbstractJMSListener { + + @Inject + Dispatcher dispatcher; + + protected Dispatcher getDispatcher() { + return dispatcher; + } +} \ No newline at end of file diff --git a/adapters/jms-adapter-generator/src/test/java/uk/gov/justice/raml/jms/core/JmsEndpointGeneratorTest.java b/adapters/jms-adapter-generator/src/test/java/uk/gov/justice/raml/jms/core/JmsEndpointGeneratorTest.java new file mode 100644 index 000000000..c1c094951 --- /dev/null +++ b/adapters/jms-adapter-generator/src/test/java/uk/gov/justice/raml/jms/core/JmsEndpointGeneratorTest.java @@ -0,0 +1,385 @@ +package uk.gov.justice.raml.jms.core; + +import org.hamcrest.FeatureMatcher; +import org.hamcrest.Matcher; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.raml.model.ActionType; +import uk.gov.justice.raml.core.Generator; +import uk.gov.justice.raml.core.GeneratorConfig; +import uk.gov.justice.services.adapters.test.utils.compiler.JavaCompilerUtil; +import uk.gov.justice.services.core.annotation.Adapter; +import uk.gov.justice.services.core.dispatcher.Dispatcher; +import uk.gov.justice.services.core.jms.AbstractJMSListener; +import uk.gov.justice.services.messaging.Envelope; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.inject.Inject; +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import static java.util.Arrays.asList; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.CoreMatchers.sameInstance; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.arrayContainingInAnyOrder; +import static org.hamcrest.Matchers.arrayWithSize; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItemInArray; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.core.IsNot.not; +import static org.hamcrest.core.StringStartsWith.startsWith; +import static org.junit.Assert.assertThat; +import static org.raml.model.ActionType.DELETE; +import static org.raml.model.ActionType.GET; +import static org.raml.model.ActionType.HEAD; +import static org.raml.model.ActionType.OPTIONS; +import static org.raml.model.ActionType.PATCH; +import static org.raml.model.ActionType.POST; +import static org.raml.model.ActionType.TRACE; +import static uk.gov.justice.services.adapters.test.utils.builder.ActionBuilder.action; +import static uk.gov.justice.services.adapters.test.utils.builder.RamlBuilder.raml; +import static uk.gov.justice.services.adapters.test.utils.builder.ResourceBuilder.resource; +import static uk.gov.justice.services.core.annotation.Component.COMMAND_CONTROLLER; +import static uk.gov.justice.services.core.annotation.Component.COMMAND_HANDLER; + +public class JmsEndpointGeneratorTest { + + private static final String BASE_PACKAGE = "uk.test"; + private static final String BASE_PACKAGE_FOLDER = "/uk/test"; + + private Generator generator = new JmsEndpointGenerator(); + + @Rule + public TemporaryFolder outputFolder = new TemporaryFolder(); + private JavaCompilerUtil compiler; + + @Before + public void setup() throws Exception { + compiler = new JavaCompilerUtil(outputFolder.getRoot(), outputFolder.getRoot()); + } + + @Test + public void shouldCreateJmsClass() throws Exception { + generator.run( + raml() + .with(resource() + .withRelativeUri("/structure.controller.commands") + .withDefaultAction()) + .build(), + configurationWithBasePackage(BASE_PACKAGE)); + + File packageDir = new File(outputFolder.getRoot().getAbsolutePath() + BASE_PACKAGE_FOLDER); + File[] files = packageDir.listFiles(); + assertThat(files.length, is(1)); + assertThat(files[0].getName(), is("StructureControllerCommandsJmsListener.java")); + } + + @SuppressWarnings("unchecked") + @Test + public void shouldCreateMultipleJmsClasses() throws Exception { + generator.run( + raml() + .with(resource() + .withRelativeUri("/structure.controller.commands") + .withDefaultAction()) + .with(resource() + .withRelativeUri("/people.controller.commands") + .withDefaultAction()) + .build(), + configurationWithBasePackage(BASE_PACKAGE)); + + File packageDir = new File(outputFolder.getRoot().getAbsolutePath() + BASE_PACKAGE_FOLDER); + File[] files = packageDir.listFiles(); + assertThat(files.length, is(2)); + assertThat(files, + arrayContainingInAnyOrder(hasProperty("name", equalTo("PeopleControllerCommandsJmsListener.java")), + hasProperty("name", equalTo("StructureControllerCommandsJmsListener.java")))); + + } + + @Test + public void shouldOverwriteJmsClass() throws Exception { + String path = outputFolder.getRoot().getAbsolutePath() + BASE_PACKAGE_FOLDER; + File packageDir = new File(path); + packageDir.mkdirs(); + Files.write(Paths.get(path + "/StructureControllerCommandsJmsListener.java"), + asList("Old file content")); + + generator.run( + raml() + .with(resource() + .withRelativeUri("/structure.controller.commands") + .withDefaultAction()) + .build(), + configurationWithBasePackage(BASE_PACKAGE)); + + List lines = Files.readAllLines(Paths.get(path + "/StructureControllerCommandsJmsListener.java")); + assertThat(lines.get(0), not(containsString("Old file content"))); + } + + @Test + public void shouldCreateJmsEndpointNamedAfterResourceUri() throws Exception { + generator.run( + raml() + .with(resource() + .withRelativeUri("/structure.controller.commands") + .withDefaultAction()) + .build(), + configurationWithBasePackage("uk.somepackage")); + + Class compiledClass = compiler.compiledClassOf("uk.somepackage"); + assertThat(compiledClass.getName(), is("uk.somepackage.StructureControllerCommandsJmsListener")); + } + + @Test + public void shouldCreateJmsEndpointInADifferentPackage() throws Exception { + generator.run( + raml() + .with(resource() + .withRelativeUri("/structure.controller.commands") + .withDefaultAction()) + .build(), + configurationWithBasePackage("uk.package2")); + + Class clazz = compiler.compiledClassOf("uk.package2"); + assertThat(clazz.getName(), is("uk.package2.StructureControllerCommandsJmsListener")); + } + + @Test + public void shouldCreateJmsEndpointAnnotatedWithCommandHandlerAdapter() throws Exception { + generator.run( + raml() + .with(resource() + .withRelativeUri("/people.handler.commands") + .with(action().with(ActionType.POST))) + .build(), + configurationWithBasePackage(BASE_PACKAGE)); + Class clazz = compiler.compiledClassOf(BASE_PACKAGE); + Adapter adapterAnnotation = clazz.getAnnotation(Adapter.class); + assertThat(adapterAnnotation, not(nullValue())); + assertThat(adapterAnnotation.value(), is(COMMAND_HANDLER)); + + } + + @Test + public void shouldCreateJmsEndpointAnnotatedWithCommandControllerAdapter() throws Exception { + generator.run( + raml() + .with(resource() + .withRelativeUri("/people.controller.commands") + .with(action().with(ActionType.POST))) + .build(), + configurationWithBasePackage(BASE_PACKAGE)); + + Class clazz = compiler.compiledClassOf(BASE_PACKAGE); + Adapter adapterAnnotation = clazz.getAnnotation(Adapter.class); + assertThat(adapterAnnotation, not(nullValue())); + assertThat(adapterAnnotation.value(), is(COMMAND_CONTROLLER)); + + } + + @Test + public void shouldCreateJmsEndpointExtendingAbstractJmsListener() throws Exception { + generator.run(raml().withDefaults().build(), configurationWithBasePackage(BASE_PACKAGE)); + + Class clazz = compiler.compiledClassOf(BASE_PACKAGE); + assertThat(clazz.getSuperclass(), equalTo(AbstractJMSListener.class)); + } + + @Test + public void shouldCreateJmsEndpointWithAnnotatedDispatcherProperty() throws Exception { + generator.run(raml().withDefaults().build(), configurationWithBasePackage(BASE_PACKAGE)); + + Class clazz = compiler.compiledClassOf(BASE_PACKAGE); + Field dispatcherField = clazz.getDeclaredField("dispatcher"); + assertThat(dispatcherField, not(nullValue())); + assertThat(dispatcherField.getAnnotations(), arrayWithSize(1)); + assertThat(dispatcherField.getAnnotation(Inject.class), not(nullValue())); + } + + @Test + public void shouldCreateAnnotatedJmsEndpointWithDestinationLookupProperty() throws Exception { + generator.run( + raml() + .with(resource() + .withRelativeUri("/people.controller.commands") + .with(action().with(ActionType.POST))) + .build(), + configurationWithBasePackage(BASE_PACKAGE)); + + Class clazz = compiler.compiledClassOf(BASE_PACKAGE); + assertThat(clazz.getAnnotation(MessageDriven.class), is(notNullValue())); + assertThat(clazz.getAnnotation(MessageDriven.class).activationConfig(), + hasItemInArray(allOf(propertyName(equalTo("destinationLookup")), + propertyValue(equalTo("people.controller.commands"))))); + } + + @Test + public void shouldCreateAnnotatedJmsEndpointWithDestinationLookupProperty2() throws Exception { + generator.run( + raml() + .with(resource() + .withRelativeUri("/structure.controller.commands") + .with(action().with(ActionType.POST))) + .build(), + configurationWithBasePackage(BASE_PACKAGE)); + + Class clazz = compiler.compiledClassOf(BASE_PACKAGE); + assertThat(clazz.getAnnotation(MessageDriven.class), is(notNullValue())); + assertThat(clazz.getAnnotation(MessageDriven.class).activationConfig(), + hasItemInArray(allOf(propertyName(equalTo("destinationLookup")), + propertyValue(equalTo("structure.controller.commands"))))); + } + + @Test + public void shouldCreateAnnotatedJmsEndpointWithDestinationType() throws Exception { + generator.run(raml().withDefaults().build(), configurationWithBasePackage(BASE_PACKAGE)); + + Class clazz = compiler.compiledClassOf(BASE_PACKAGE); + assertThat(clazz.getAnnotation(MessageDriven.class), is(notNullValue())); + assertThat(clazz.getAnnotation(MessageDriven.class).activationConfig(), + hasItemInArray(allOf(propertyName(equalTo("destinationType")), + propertyValue(equalTo("javax.jms.Queue"))))); + } + + @Test + public void shouldCreateAnnotatedJmsEndpointWithMessageSelectorContainingOneCommandWithAPost() throws Exception { + generator.run( + raml() + .with(resource() + .with(action() + .with(ActionType.POST) + .withMediaType("application/vnd.structure.commands.test-cmd+json"))) + .build(), + configurationWithBasePackage(BASE_PACKAGE)); + + Class clazz = compiler.compiledClassOf(BASE_PACKAGE); + assertThat(clazz.getAnnotation(MessageDriven.class), is(notNullValue())); + assertThat(clazz.getAnnotation(MessageDriven.class).activationConfig(), + hasItemInArray(allOf(propertyName(equalTo("messageSelector")), + propertyValue(equalTo("CPPNAME in('structure.commands.test-cmd')"))))); + } + + @Test + public void shouldOnlyCreateMessageSelectorForPostActionAndIgnoreAllOtherActions() throws Exception { + generator.run( + raml() + .with(resource() + .with(action(POST, "application/vnd.structure.commands.test-cmd1+json")) + .with(action(GET, "application/vnd.structure.commands.test-cmd2+json")) + .with(action(DELETE, "application/vnd.structure.commands.test-cmd3+json")) + .with(action(HEAD, "application/vnd.structure.commands.test-cmd4+json")) + .with(action(OPTIONS, "application/vnd.structure.commands.test-cmd5+json")) + .with(action(PATCH, "application/vnd.structure.commands.test-cmd6+json")) + .with(action(TRACE, "application/vnd.structure.commands.test-cmd7+json"))) + .build(), + configurationWithBasePackage(BASE_PACKAGE)); + + Class clazz = compiler.compiledClassOf(BASE_PACKAGE); + assertThat(clazz.getAnnotation(MessageDriven.class), is(notNullValue())); + assertThat(clazz.getAnnotation(MessageDriven.class).activationConfig(), + hasItemInArray(allOf(propertyName(equalTo("messageSelector")), + propertyValue(equalTo("CPPNAME in('structure.commands.test-cmd1')"))))); + } + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Test + public void shouldThrowExceptionIfNoActionsInRaml() throws Exception { + + exception.expect(JmsEndpointGeneratorException.class); + exception.expectMessage("No actions to process"); + + generator.run( + raml() + .with(resource() + .withRelativeUri("/structure.controller.commands")) + .build(), + configurationWithBasePackage(BASE_PACKAGE)); + } + + @Test + public void shouldCreateAnnotatedJmsEndpointWithMessageSelectorContainingTwoCommands() throws Exception { + generator.run( + raml() + .with(resource() + .with(action() + .with(ActionType.POST) + .withMediaType("application/vnd.people.commands.command1+json") + .withMediaType("application/vnd.people.commands.command2+json"))) + .build(), + configurationWithBasePackage(BASE_PACKAGE)); + + Class clazz = compiler.compiledClassOf(BASE_PACKAGE); + assertThat(clazz.getAnnotation(MessageDriven.class), is(notNullValue())); + assertThat(clazz.getAnnotation(MessageDriven.class).activationConfig(), + hasItemInArray(allOf(propertyName(equalTo("messageSelector")), + propertyValue(startsWith("CPPNAME in")), + propertyValue(allOf(containsString("'people.commands.command1'"), + containsString("'people.commands.command2'")))))); + } + + @Test + public void shouldCreateJmsEndpointWithDispatcherGetter() throws Exception { + generator.run(raml().withDefaults().build(), configurationWithBasePackage(BASE_PACKAGE)); + + Class clazz = compiler.compiledClassOf(BASE_PACKAGE); + + Object endpointInstance = clazz.newInstance(); + Dispatcher dispatcher = new DummyDispatcher(); + Field dispatcherField = clazz.getDeclaredField("dispatcher"); + dispatcherField.setAccessible(true); + dispatcherField.set(endpointInstance, dispatcher); + + Method getDispatcherMethod = clazz.getDeclaredMethod("getDispatcher"); + getDispatcherMethod.setAccessible(true); + + Object getDispatcherResult = getDispatcherMethod.invoke(endpointInstance); + assertThat(getDispatcherResult, sameInstance(dispatcher)); + } + + private GeneratorConfig configurationWithBasePackage(String basePackageName) { + Path outputPath = Paths.get(outputFolder.getRoot().getAbsolutePath()); + return new GeneratorConfig(outputPath, outputPath, basePackageName); + } + + private FeatureMatcher propertyName(Matcher matcher) { + return new FeatureMatcher(matcher, "propertyName", "propertyName") { + @Override + protected String featureValueOf(ActivationConfigProperty actual) { + return actual.propertyName(); + } + }; + } + + private FeatureMatcher propertyValue(Matcher matcher) { + return new FeatureMatcher(matcher, "propertyValue", "propertyValue") { + @Override + protected String featureValueOf(ActivationConfigProperty actual) { + return actual.propertyValue(); + } + }; + } + + public static class DummyDispatcher implements Dispatcher { + @Override + public void dispatch(Envelope envelope) { + // do nothing + } + } + +} diff --git a/adapters/jms-adapter-generator/src/test/java/uk/gov/justice/raml/jms/core/TemplateMarkerTest.java b/adapters/jms-adapter-generator/src/test/java/uk/gov/justice/raml/jms/core/TemplateMarkerTest.java new file mode 100644 index 000000000..5dcace15e --- /dev/null +++ b/adapters/jms-adapter-generator/src/test/java/uk/gov/justice/raml/jms/core/TemplateMarkerTest.java @@ -0,0 +1,54 @@ +package uk.gov.justice.raml.jms.core; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.assertThat; + +public class TemplateMarkerTest { + + @Test + public void shouldReplaceMarkedPosition() throws Exception { + String template = "Test ${replace}"; + Map data = new HashMap<>(); + data.put("replace", "replacement"); + + String result = TemplateRenderer.render(template, data); + assertThat(result, equalTo("Test replacement")); + } + + @Test + public void shouldNotReplacePosition() throws Exception { + String template = "Test replace"; + Map data = new HashMap<>(); + data.put("replace", "replacement"); + + String result = TemplateRenderer.render(template, data); + assertThat(result, equalTo("Test replace")); + } + + @Test + public void shouldReplaceMultipleMarkedPositionsOfSameKey() throws Exception { + String template = "${replace} Test ${replace}"; + Map data = new HashMap<>(); + data.put("replace", "replacement"); + + String result = TemplateRenderer.render(template, data); + assertThat(result, equalTo("replacement Test replacement")); + } + + @Test + public void shouldReplaceMultipleMarkedPositionsOfDifferentKey() throws Exception { + String template = "${replace} Test ${different} ${replace} Test ${different}"; + Map data = new HashMap<>(); + data.put("replace", "replacement"); + data.put("different", "other"); + + String result = TemplateRenderer.render(template, data); + assertThat(result, equalTo("replacement Test other replacement Test other")); + } + +} diff --git a/adapters/jms-adapter-generator/src/test/resources/log4j.properties b/adapters/jms-adapter-generator/src/test/resources/log4j.properties new file mode 100644 index 000000000..6193d62fd --- /dev/null +++ b/adapters/jms-adapter-generator/src/test/resources/log4j.properties @@ -0,0 +1,9 @@ +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=WARN, A1 + +# A1 is set to be a ConsoleAppender. +log4j.appender.A1=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n \ No newline at end of file diff --git a/adapters/pom.xml b/adapters/pom.xml index d4c68cddb..243764c54 100644 --- a/adapters/pom.xml +++ b/adapters/pom.xml @@ -15,7 +15,7 @@ rest-adapter-core rest-adapter-generator + jms-adapter-generator adapters-test-utils - - + \ No newline at end of file diff --git a/adapters/rest-adapter-core/pom.xml b/adapters/rest-adapter-core/pom.xml index 7499d3ebb..d7e50ed99 100644 --- a/adapters/rest-adapter-core/pom.xml +++ b/adapters/rest-adapter-core/pom.xml @@ -49,7 +49,6 @@ org.glassfish javax.json - 1.0.4 test diff --git a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/generator/DefaultGenerator_ResourceCodeStructureTest.java b/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/generator/DefaultGenerator_ResourceCodeStructureTest.java index 9f5bfb0ad..bd0604f87 100644 --- a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/generator/DefaultGenerator_ResourceCodeStructureTest.java +++ b/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/generator/DefaultGenerator_ResourceCodeStructureTest.java @@ -1,15 +1,25 @@ package uk.gov.justice.services.adapters.rest.generator; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import uk.gov.justice.raml.core.GeneratorConfig; -import uk.gov.justice.services.adapter.rest.RestProcessor; -import uk.gov.justice.services.adapters.test.utils.JavaCompilerUtil; -import uk.gov.justice.services.core.annotation.Adapter; -import uk.gov.justice.services.core.annotation.Component; -import uk.gov.justice.services.core.dispatcher.Dispatcher; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.Matchers.arrayWithSize; +import static org.hamcrest.Matchers.emptyArray; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.raml.model.ActionType.POST; +import static uk.gov.justice.services.adapters.test.utils.builder.ActionBuilder.action; +import static uk.gov.justice.services.adapters.test.utils.builder.RamlBuilder.restRamlWithDefaults; +import static uk.gov.justice.services.adapters.test.utils.builder.ResourceBuilder.resource; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; import javax.ejb.Stateless; import javax.inject.Inject; @@ -20,26 +30,18 @@ import javax.ws.rs.PathParam; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Response; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Parameter; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.Matchers.arrayWithSize; -import static org.hamcrest.Matchers.emptyArray; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; -import static org.raml.model.ActionType.POST; -import static uk.gov.justice.services.adapters.test.utils.ActionBuilder.action; -import static uk.gov.justice.services.adapters.test.utils.RamlBuilder.restRamlWithDefaults; -import static uk.gov.justice.services.adapters.test.utils.ResourceBuilder.resource; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import uk.gov.justice.raml.core.GeneratorConfig; +import uk.gov.justice.services.adapter.rest.RestProcessor; +import uk.gov.justice.services.adapters.test.utils.compiler.JavaCompilerUtil; +import uk.gov.justice.services.core.annotation.Adapter; +import uk.gov.justice.services.core.annotation.Component; +import uk.gov.justice.services.core.dispatcher.Dispatcher; public class DefaultGenerator_ResourceCodeStructureTest { diff --git a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/generator/DefaultGenerator_ResourceMethodBodyTest.java b/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/generator/DefaultGenerator_ResourceMethodBodyTest.java index 6a6866e51..6035c8b66 100644 --- a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/generator/DefaultGenerator_ResourceMethodBodyTest.java +++ b/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/generator/DefaultGenerator_ResourceMethodBodyTest.java @@ -1,5 +1,34 @@ package uk.gov.justice.services.adapters.rest.generator; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.raml.model.ActionType.POST; +import static uk.gov.justice.services.adapters.test.utils.builder.ActionBuilder.action; +import static uk.gov.justice.services.adapters.test.utils.builder.RamlBuilder.restRamlWithDefaults; +import static uk.gov.justice.services.adapters.test.utils.builder.ResourceBuilder.resource; +import static uk.gov.justice.services.messaging.DefaultEnvelope.envelopeFrom; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import javax.json.Json; +import javax.json.JsonObject; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response; + import org.jboss.resteasy.specimpl.MultivaluedMapImpl; import org.jboss.resteasy.specimpl.ResteasyHttpHeaders; import org.junit.Before; @@ -11,39 +40,13 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; + import uk.gov.justice.raml.core.GeneratorConfig; import uk.gov.justice.services.adapter.rest.RestProcessor; -import uk.gov.justice.services.adapters.test.utils.JavaCompilerUtil; +import uk.gov.justice.services.adapters.test.utils.compiler.JavaCompilerUtil; import uk.gov.justice.services.core.dispatcher.Dispatcher; import uk.gov.justice.services.messaging.Envelope; -import javax.json.Json; -import javax.json.JsonObject; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.Response; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.raml.model.ActionType.POST; -import static uk.gov.justice.services.adapters.test.utils.ActionBuilder.action; -import static uk.gov.justice.services.adapters.test.utils.RamlBuilder.restRamlWithDefaults; -import static uk.gov.justice.services.adapters.test.utils.ResourceBuilder.resource; -import static uk.gov.justice.services.messaging.DefaultEnvelope.envelopeFrom; @RunWith(MockitoJUnitRunner.class) public class DefaultGenerator_ResourceMethodBodyTest { diff --git a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/generator/NamesTest.java b/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/generator/NamesTest.java new file mode 100644 index 000000000..af38586f0 --- /dev/null +++ b/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/generator/NamesTest.java @@ -0,0 +1,42 @@ +package uk.gov.justice.services.adapters.rest.generator; + +import org.junit.Test; +import org.raml.model.Action; +import org.raml.model.MimeType; +import org.raml.model.Resource; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +public class NamesTest { + + @Test + public void shouldConvertMimetypeToShortMimeTypeString() throws Exception { + String shortMimeType = Names.getShortMimeType(new MimeType("application/vnd.people.commands.create-user+json")); + assertThat(shortMimeType, is("vndPeopleCommandsCreateUserJson")); + } + + @Test + public void shouldBuildMimeTypeInfix() throws Exception { + String shortMimeType = Names.buildMimeTypeInfix(new MimeType("application/vnd.people.commands.create-user+json")); + assertThat(shortMimeType, is("VndPeopleCommandsCreateUserJson")); + } + + @Test + public void shouldBuildMethodResourceName() throws Exception { + String shortMimeType = Names.buildMimeTypeInfix(new MimeType("application/vnd.people.commands.create-user+json")); + assertThat(shortMimeType, is("VndPeopleCommandsCreateUserJson")); + } + + @Test + public void shouldBuildResourceMethodName() throws Exception { + Resource resource = new Resource(); + resource.setParentUri(""); + resource.setRelativeUri("test"); + Action action = new Action(); + action.setResource(resource); + String shortMimeType = Names.buildMimeTypeInfix(new MimeType("application/vnd.people.commands.create-user+json")); + assertThat(shortMimeType, is("VndPeopleCommandsCreateUserJson")); + } + +} \ No newline at end of file diff --git a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/FileBuilder.java b/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/FileBuilder.java deleted file mode 100644 index 4d7d31155..000000000 --- a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/FileBuilder.java +++ /dev/null @@ -1,37 +0,0 @@ -package uk.gov.justice.services.adapters.rest.util.builder; - -import org.apache.commons.io.FileUtils; - -import java.io.File; -import java.io.IOException; -import java.net.URL; - -import static org.junit.Assert.fail; - -public class FileBuilder { - - String relativePath; - - private FileBuilder(String relativePath) { - this.relativePath = relativePath; - } - - public static File aDirectory(String relativePath) { - return aFile(relativePath); - } - - public static File aFile(String relativePath) { - URL resource = FileBuilder.class.getClassLoader().getResource(relativePath); - return new File(resource.getFile()); - } - - public static String aStringFromFile(String relativePath) { - try { - return FileUtils.readFileToString(aFile(relativePath)); - } catch (IOException e) { - fail(e.getMessage()); - return null; - } - } - -} diff --git a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/HttpMethod.java b/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/HttpMethod.java deleted file mode 100644 index dbc5adbbd..000000000 --- a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/HttpMethod.java +++ /dev/null @@ -1,6 +0,0 @@ -package uk.gov.justice.services.adapters.rest.util.builder; - -public enum HttpMethod { - POST, GET - -} diff --git a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/RamlBuilder.java b/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/RamlBuilder.java deleted file mode 100644 index 02dd75a8a..000000000 --- a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/RamlBuilder.java +++ /dev/null @@ -1,43 +0,0 @@ -package uk.gov.justice.services.adapters.rest.util.builder; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.LinkedList; -import java.util.List; - -import static java.text.MessageFormat.format; -import static uk.gov.justice.services.adapters.rest.util.builder.RamlResourceBuilder.aResource; - -public class RamlBuilder { - private static final Logger LOG = LoggerFactory.getLogger(RamlBuilder.class); - private static String RAML_TEMPLATE = "#%RAML 0.8\r\n" + - "title: Example Service\r\n" + - "\r\n" + - "{0} "; - - private List resources = new LinkedList<>(); - - public static RamlBuilder aRaml() { - return new RamlBuilder(); - } - - public RamlBuilder withDefaults() { - return this.with(aResource()); - } - - public RamlBuilder with(RamlResourceBuilder resource) { - resources.add(resource); - return this; - } - - public String toString() { - StringBuilder resourcesRamlString = new StringBuilder(); - resources.forEach(r -> resourcesRamlString.append(r.toString())); - String raml = format(RAML_TEMPLATE, resourcesRamlString); - LOG.debug(System.lineSeparator() + raml); - return raml; - - } - -} diff --git a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/RamlResourceBuilder.java b/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/RamlResourceBuilder.java deleted file mode 100644 index 5d0762493..000000000 --- a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/RamlResourceBuilder.java +++ /dev/null @@ -1,34 +0,0 @@ -package uk.gov.justice.services.adapters.rest.util.builder; - -import java.util.LinkedList; -import java.util.List; - -import static java.text.MessageFormat.format; - -public class RamlResourceBuilder { - - private static String RAML_RESOURCE_STRING_TEMPLATE = "{0}:\r\n" + - "{1}"; - private String path = "/default/path"; - private List methods = new LinkedList<>(); - - public static RamlResourceBuilder aResource() { - return new RamlResourceBuilder(); - } - - public RamlResourceBuilder withPath(String path) { - this.path = path; - return this; - } - - public RamlResourceBuilder with(RamlResourceMethodBuilder method) { - methods.add(method); - return this; - } - - public String toString() { - StringBuilder methodsString = new StringBuilder(); - methods.forEach(m -> methodsString.append(m.toString())); - return format(RAML_RESOURCE_STRING_TEMPLATE, path, methodsString); - } -} diff --git a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/RamlResourceMethodBuilder.java b/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/RamlResourceMethodBuilder.java deleted file mode 100644 index 2ba6cf40b..000000000 --- a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/builder/RamlResourceMethodBuilder.java +++ /dev/null @@ -1,39 +0,0 @@ -package uk.gov.justice.services.adapters.rest.util.builder; - -import static java.text.MessageFormat.format; -import static java.util.Arrays.stream; - -public class RamlResourceMethodBuilder { - private static String METHOD_TEMPLATE = " {0}:\r\n" + - " body:\r\n" + - "{1}"; - private HttpMethod method; - private String[] mediaType = {"application/vnd.default+json"}; - - private RamlResourceMethodBuilder(HttpMethod method) { - this.method = method; - } - - public static RamlResourceMethodBuilder aResourceMethod(HttpMethod method) { - return new RamlResourceMethodBuilder(method); - } - - public RamlResourceMethodBuilder withConsumedMediaTypes(String... mediaType) { - this.mediaType = mediaType; - return this; - - } - - public String toString() { - StringBuilder mediaTypeString = new StringBuilder(); - if (mediaType != null) { - stream(mediaType).forEach(mt -> mediaTypeString.append(" ").append(mt).append(":\r\n")); - } - return format(METHOD_TEMPLATE, method.toString().toLowerCase(), mediaTypeString); - - } - - public static enum Method { - POST, GET; - } -} diff --git a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/compiler/CompilationException.java b/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/compiler/CompilationException.java deleted file mode 100644 index 3bab0c252..000000000 --- a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/compiler/CompilationException.java +++ /dev/null @@ -1,11 +0,0 @@ -package uk.gov.justice.services.adapters.rest.util.compiler; - -public class CompilationException extends RuntimeException { - private static final long serialVersionUID = 1L; - - public CompilationException(String string) { - super(string); - } - - -} diff --git a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/compiler/JavaCompilerUtil.java b/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/compiler/JavaCompilerUtil.java deleted file mode 100644 index 5a38c18b7..000000000 --- a/adapters/rest-adapter-generator/src/test/java/uk/gov/justice/services/adapters/rest/util/compiler/JavaCompilerUtil.java +++ /dev/null @@ -1,190 +0,0 @@ -package uk.gov.justice.services.adapters.rest.util.compiler; - -import org.apache.commons.io.FileUtils; -import org.reflections.Reflections; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.ejb.Stateless; -import javax.tools.Diagnostic; -import javax.tools.DiagnosticCollector; -import javax.tools.JavaCompiler; -import javax.tools.JavaCompiler.CompilationTask; -import javax.tools.JavaFileObject; -import javax.tools.StandardJavaFileManager; -import javax.tools.ToolProvider; -import javax.ws.rs.Path; -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import static java.text.MessageFormat.format; - -/** - * Compiles and loads classes and interfaces from the specified folders - */ -public class JavaCompilerUtil { - private static final Logger LOG = LoggerFactory.getLogger(JavaCompilerUtil.class); - private final File codegenOutputDir, compilationOutputDir; - - public JavaCompilerUtil(File codegenOutputDir, File compilationOutputDir) { - this.codegenOutputDir = codegenOutputDir; - this.compilationOutputDir = compilationOutputDir; - } - - /** - * Compiles and loads a single class - * - * @param classNames - * @param basePackage - * @return - * @throws MalformedURLException - * @throws IllegalStateException - if more or less than one classes found - */ - public Class compiledClassOf(Set classNames, String basePackage) - throws MalformedURLException { - Set> resourceClasses = compiledClassesOf(classNames, basePackage); - if (resourceClasses.size() != 1) { - throw new IllegalStateException(format("Expected to find single class but found {0}", resourceClasses)); - } - return resourceClasses.iterator().next(); - } - - /** - * Compiles and loads a single interface - * - * @param classNames - * @param basePackageName - * @return - * @throws MalformedURLException - * @throws IllegalStateException - if more or less than one interfaces found - */ - public Class compiledInterfaceOf(Set classNames, String basePackageName) - throws MalformedURLException { - Set> resourceInterfaces = compiledInterfacesOf(classNames, basePackageName); - if (resourceInterfaces.size() != 1) { - throw new IllegalStateException(format("Expected to find single interface but found {0}", resourceInterfaces)); - - } - return resourceInterfaces.iterator().next(); - } - - /** - * compiles and loads specified classes - * - * @param classNames - * @param basePackage - * @return - * @throws MalformedURLException - */ - public Set> compiledClassesOf(Set classNames, String basePackage) - throws MalformedURLException { - return compiledClassesAndInterfaces(classNames, c -> !c.isInterface(), basePackage); - } - - /** - * compiles and loads specified interfaces - * - * @param resourceClasses - * @param basePackage - * @return - * @throws MalformedURLException - */ - public Set> compiledInterfacesOf(Set resourceClasses, String basePackage) - throws MalformedURLException { - return compiledClassesAndInterfaces(resourceClasses, c -> c.isInterface(), basePackage); - } - - - private Set> compiledClassesAndInterfaces(Set classNames, - Predicate> predicate, String basePackage) - throws MalformedURLException { - return compile(classNames, basePackage).stream().filter(predicate).collect(Collectors.toSet()); - } - - private Set> compile(Set classNames, String basePackage) throws MalformedURLException { - compile(classNames); - return loadClasses(basePackage); - } - - private Set> loadClasses(String basePackage) throws MalformedURLException { - URLClassLoader resourceClassLoader = new URLClassLoader(new URL[]{compilationOutputDir.toURI().toURL()}); - - ClassLoader initialClassLoader = Thread.currentThread().getContextClassLoader(); - Set> rootResourceClasses = new HashSet<>(); - try { - Thread.currentThread().setContextClassLoader(resourceClassLoader); - Reflections reflections = new Reflections(basePackage); - rootResourceClasses.addAll(reflections.getTypesAnnotatedWith(Path.class)); - rootResourceClasses.addAll(reflections.getTypesAnnotatedWith(Stateless.class)); - } finally { - Thread.currentThread().setContextClassLoader(initialClassLoader); - } - return rootResourceClasses; - } - - private void compile(Set resourceClasses) { - - JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); - - DiagnosticCollector diagnostics = new DiagnosticCollector(); - StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, Locale.getDefault(), null); - List javaObjects = scanRecursivelyForJavaObjects(codegenOutputDir, fileManager); - - if (javaObjects.size() == 0) { - throw new CompilationException( - format("There are no source files to compile in {0}", codegenOutputDir.getAbsolutePath())); - } - String[] compileOptions = new String[]{"-d", compilationOutputDir.getAbsolutePath()}; - Iterable compilationOptions = Arrays.asList(compileOptions); - - CompilationTask compilerTask = compiler.getTask(null, fileManager, diagnostics, compilationOptions, null, - javaObjects); - - if (!compilerTask.call()) { - for (Diagnostic diagnostic : diagnostics.getDiagnostics()) { - LOG.error("Error on line {} in {}", diagnostic.getLineNumber(), diagnostic); - } - throw new CompilationException("Could not compile project"); - } - } - - private List scanRecursivelyForJavaObjects(File dir, StandardJavaFileManager fileManager) { - List javaObjects = new LinkedList(); - File[] files = dir.listFiles(); - for (File file : files) { - if (file.isDirectory()) { - javaObjects.addAll(scanRecursivelyForJavaObjects(file, fileManager)); - } else if (file.isFile() && file.getName().toLowerCase().endsWith(".java")) { - try { - LOG.debug(FileUtils.readFileToString(file)); - } catch (IOException e) { - LOG.warn("Could not read file", e); - } - javaObjects.add(readJavaObject(file, fileManager)); - } - } - return javaObjects; - } - - private JavaFileObject readJavaObject(File file, StandardJavaFileManager fileManager) { - Iterable javaFileObjects = fileManager.getJavaFileObjects(file); - Iterator it = javaFileObjects.iterator(); - if (it.hasNext()) { - return it.next(); - } - throw new CompilationException(format("Could not load {0} java file object", file.getAbsolutePath())); - } - -} diff --git a/adapters/rest-adapter-generator/src/test/resources/log4j.properties b/adapters/rest-adapter-generator/src/test/resources/log4j.properties new file mode 100644 index 000000000..db8a1d801 --- /dev/null +++ b/adapters/rest-adapter-generator/src/test/resources/log4j.properties @@ -0,0 +1,9 @@ +# Set root logger level to DEBUG and its only appender to A1. +log4j.rootLogger=WARN, A1 + +# A1 is set to be a ConsoleAppender. +log4j.appender.A1=org.apache.log4j.ConsoleAppender + +# A1 uses PatternLayout. +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n \ No newline at end of file diff --git a/core/src/main/java/uk/gov/justice/services/core/annotation/Component.java b/core/src/main/java/uk/gov/justice/services/core/annotation/Component.java index dc8501de2..d1f921de5 100644 --- a/core/src/main/java/uk/gov/justice/services/core/annotation/Component.java +++ b/core/src/main/java/uk/gov/justice/services/core/annotation/Component.java @@ -1,5 +1,9 @@ package uk.gov.justice.services.core.annotation; +import static java.util.Arrays.stream; + +import java.util.Optional; + /** * Enum representing all the service components. */ @@ -7,6 +11,7 @@ public enum Component { COMMAND_API("commands", "api"), COMMAND_CONTROLLER("commands", "controller"), COMMAND_HANDLER("commands", "handler"), EVENT_LISTENER("events", "listener"); + private final String pillar; private final String tier; @@ -15,10 +20,27 @@ public enum Component { this.tier = tier; } + /** + * Returns Component of the provided pillar and tier + * + * @param pillar + * @param tier + * @return the component of the provided pillar and tier + */ + public static Component valueOf(final String pillar, final String tier) { + Optional first = stream(Component.values()) + .filter(c -> c.pillar.equals(pillar) && c.tier.equals(tier)).findFirst(); + + return first.orElseThrow(() -> new IllegalArgumentException( + String.format("No enum constant for pillar: %s, tier: %s", pillar, tier))); + + } + /** * Retrieves the Component of the provided {@link ServiceComponent} * - * @param clazz The service component to be analysed. + * @param clazz + * The service component to be analysed. * @return the component from the provided {@link ServiceComponent}. */ public static Component getComponentFromServiceComponent(final Class clazz) { @@ -29,7 +51,8 @@ public static Component getComponentFromServiceComponent(final Class clazz) { @@ -44,5 +67,4 @@ public String pillar() { public String tier() { return tier; } - } diff --git a/core/src/test/java/uk/gov/justice/services/core/annotation/ComponentTest.java b/core/src/test/java/uk/gov/justice/services/core/annotation/ComponentTest.java index 1e8fcc107..30e6d316c 100644 --- a/core/src/test/java/uk/gov/justice/services/core/annotation/ComponentTest.java +++ b/core/src/test/java/uk/gov/justice/services/core/annotation/ComponentTest.java @@ -1,10 +1,14 @@ package uk.gov.justice.services.core.annotation; -import org.junit.Test; import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + public class ComponentTest { private static final String PILLAR_COMMANDS = "commands"; @@ -26,4 +30,34 @@ public void shouldReturnTier() throws Exception { assertThat(Component.COMMAND_HANDLER.tier(), equalTo(TIER_HANDLER)); } + @Test + public void shouldConstructComponentByTierAndPillar() { + assertThat(Component.valueOf("commands", "api"), is(Component.COMMAND_API)); + assertThat(Component.valueOf("commands", "controller"), is(Component.COMMAND_CONTROLLER)); + assertThat(Component.valueOf("commands", "handler"), is(Component.COMMAND_HANDLER)); + assertThat(Component.valueOf("events", "listener"), is(Component.EVENT_LISTENER)); + } + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Test + public void shouldThrowExceptionIfPillarInvalid() { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("No enum constant for pillar: invalidPillar, tier: api"); + + Component.valueOf("invalidPillar", "api"); + + } + + @Test + public void shouldThrowExceptionIfTierInvalid() { + exception.expect(IllegalArgumentException.class); + exception.expectMessage("No enum constant for pillar: commands, tier: invalidTier"); + + Component.valueOf("commands", "invalidTier"); + + } + + } \ No newline at end of file