From f326249c067df0ea25e6bac654175b44dd6f4c15 Mon Sep 17 00:00:00 2001 From: Daniel Sagenschneider Date: Mon, 3 Jun 2024 14:19:57 +0800 Subject: [PATCH 1/9] Initial commit for cloud maven plugin --- officefloor/bom/pom.xml | 5 + .../officefloor-cloud-maven-plugin/.gitignore | 1 + .../officefloor-cloud-maven-plugin/pom.xml | 87 +++++++++ .../src/it/Cloud/pom.xml | 46 +++++ .../src/it/NoCloud/pom.xml | 29 +++ .../cloud/OfficeFloorCloudShadeMojo.java | 182 ++++++++++++++++++ .../cloud/AbstractCloudShadeMojoTestCase.java | 143 ++++++++++++++ .../net/officefloor/maven/cloud/CloudIT.java | 17 ++ .../officefloor/maven/cloud/NoCloudIT.java | 14 ++ .../src/test/verifier/verifications.xml | 9 + .../officefloor-sam-maven-plugin/pom.xml | 1 + officefloor/maven/pom.xml | 1 + .../maven/tycho-shade-maven-plugin/pom.xml | 2 +- officefloor/pom.xml | 8 +- 14 files changed, 542 insertions(+), 3 deletions(-) create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/.gitignore create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/pom.xml create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/src/it/Cloud/pom.xml create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/src/it/NoCloud/pom.xml create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AbstractCloudShadeMojoTestCase.java create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/CloudIT.java create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/NoCloudIT.java create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/src/test/verifier/verifications.xml diff --git a/officefloor/bom/pom.xml b/officefloor/bom/pom.xml index eb34809e9f..3fd906776f 100644 --- a/officefloor/bom/pom.xml +++ b/officefloor/bom/pom.xml @@ -1105,6 +1105,11 @@ woof-archetype ${revision} + + net.officefloor.maven + officefloor-cloud-maven-plugin + ${revision} + net.officefloor.maven officefloor-googlefunction-maven-plugin diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/.gitignore b/officefloor/maven/officefloor-cloud-maven-plugin/.gitignore new file mode 100644 index 0000000000..b83d22266a --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/pom.xml b/officefloor/maven/officefloor-cloud-maven-plugin/pom.xml new file mode 100644 index 0000000000..ff751c8242 --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/pom.xml @@ -0,0 +1,87 @@ + + + 4.0.0 + + net.officefloor.maven + maven + ${revision} + + officefloor-cloud-maven-plugin + maven-plugin + OfficeFloor Cloud Plugin + Maven plugin for building out cloud applications + + UTF-8 + + + + org.apache.maven.plugins + maven-shade-plugin + + + net.officefloor.cloud + officecloud_aws + test + + + net.officefloor.cloud + officecloud_google + test + + + org.apache.maven + maven-embedder + provided + + + org.apache.maven + maven-plugin-api + provided + + + org.apache.maven.plugin-tools + maven-plugin-annotations + provided + + + + + + org.apache.maven.plugins + maven-invoker-plugin + + ${project.build.directory}/it + ${settings.localRepository} + true + + clean + package + + + + + integration-test + + install + run + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + + + + \ No newline at end of file diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/it/Cloud/pom.xml b/officefloor/maven/officefloor-cloud-maven-plugin/src/it/Cloud/pom.xml new file mode 100644 index 0000000000..092a5a0aad --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/it/Cloud/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + net.officefloor.maven.test + Cloud + @project.version@ + + ${project.version} + + + + + net.officefloor + bom + ${officefloor-version} + pom + import + + + + + + net.officefloor.cloud + officecloud + + + + + + net.officefloor.maven + officefloor-cloud-maven-plugin + ${officefloor-version} + + + package + + shade + + + + + + + diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/it/NoCloud/pom.xml b/officefloor/maven/officefloor-cloud-maven-plugin/src/it/NoCloud/pom.xml new file mode 100644 index 0000000000..4e0782a932 --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/it/NoCloud/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + net.officefloor.maven.test + Cloud + @project.version@ + + ${project.version} + + + + + net.officefloor.maven + officefloor-cloud-maven-plugin + ${officefloor-version} + + + package + + shade + + + + + + + diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java new file mode 100644 index 0000000000..9459e712cd --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java @@ -0,0 +1,182 @@ +package net.officefloor.maven.cloud; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.inject.Inject; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.plugins.shade.ShadeRequest; +import org.apache.maven.plugins.shade.Shader; +import org.apache.maven.plugins.shade.mojo.ShadeMojo; +import org.apache.maven.plugins.shade.resource.ResourceTransformer; +import org.apache.maven.plugins.shade.resource.ServicesResourceTransformer; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.MavenProjectHelper; + +/** + * Builds the additional cloud specific jars attaching them with classifiers. + * + * @author Daniel Sagenschneider + */ +@Mojo(name = "shade", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.RUNTIME) +public class OfficeFloorCloudShadeMojo extends ShadeMojo { + + /** + * Parent {@link ShadeMojo} {@link Class}. + */ + private final Class shadeMojoClass = this.getClass().getSuperclass(); + + /** + * {@link MavenProject}. + */ + @Parameter(defaultValue = "${project}", readonly = true) + private MavenProject _project; + + /** + * {@link Shader}. + */ + @Component + private Shader shader; + + @Inject + private MavenProjectHelper projectHelper; + + /** + * Obtains the {@link Field} from {@link ShadeMojo} parent. + * + * @param fieldName Name of {@link Field}. + * @return {@link Field}. + * @throws MojoExecutionException If {@link Field} no longer in + * {@link ShadeMojo}. + */ + protected Field getShadeField(String fieldName) throws MojoExecutionException { + Field field; + try { + field = this.shadeMojoClass.getDeclaredField(fieldName); + } catch (NoSuchFieldException ex) { + throw new MojoExecutionException( + this.shadeMojoClass.getSimpleName() + " has changed and no longer has field " + fieldName); + } + field.setAccessible(true); + return field; + } + + /** + * Obtains the {@link ShadeMojo} {@link Field} value. + * + * @param {@link Field} type. + * @param fieldName Name of {@link Field}. + * @return {@link Field} value. + * @throws MojoExecutionException If unable to get {@link Field} value. + */ + protected V getShadeFieldValue(String fieldName) throws MojoExecutionException { + Field field = this.getShadeField(fieldName); + try { + return (V) field.get(this); + } catch (IllegalArgumentException | IllegalAccessException ex) { + throw new MojoExecutionException( + "Unable to get value for " + this.shadeMojoClass.getSimpleName() + "#" + fieldName, ex); + } + } + + /** + * Sets the {@link ShadeMojo} {@link Field} value. + * + * @param {@link Field} type. + * @param fieldName Name of {@link Field}. + * @return {@link Field} value. + * @throws MojoExecutionException If unable to get {@link Field} value. + */ + protected void setShadeFieldValue(String fieldName, V value) throws MojoExecutionException { + Field field = this.getShadeField(fieldName); + try { + field.set(this, value); + } catch (IllegalArgumentException | IllegalAccessException ex) { + throw new MojoExecutionException( + "Unable to set value for " + this.shadeMojoClass.getSimpleName() + "#" + fieldName, ex); + } + } + + @Override + public void execute() throws MojoExecutionException { + + // Ensure have services resource transformer + ResourceTransformer[] transformers = this.getShadeFieldValue("transformers"); + if (transformers == null) { + transformers = new ResourceTransformer[0]; + } + boolean isIncluded = Arrays.asList(transformers).stream() + .anyMatch((transformer) -> ServicesResourceTransformer.class.isAssignableFrom(transformer.getClass())); + if (!isIncluded) { + // Include services resource transfomer + transformers = Arrays.copyOf(transformers, transformers.length + 1); + transformers[transformers.length - 1] = new ServicesResourceTransformer(); + this.setShadeFieldValue("transformers", transformers); + } + + // Undertake shading of the component + this.getLog().info("Shading project"); + super.execute(); + + // Obtain the project attachments + for (Artifact artifact : this._project.getAttachedArtifacts()) { + this.getLog().info("ATTACHED ARTIFACT: " + artifact); + } + + // TODO REMOVE + if (true) + return; + + // Obtain the final jar + String finalName = this._project.getBuild().getFinalName(); + String targetDirectory = this._project.getBuild().getDirectory(); + File projectJar = new File(targetDirectory + "/" + finalName); + + // Obtain the test artifacts + List testClassPathEntries; + try { + testClassPathEntries = this._project.getTestClasspathElements(); + } catch (Exception ex) { + throw new MojoExecutionException(ex); + } + + // Iterate over class path entries finding cloud providers + for (String testClassPathEntry : testClassPathEntries) { + + // Determine the artifacts for test + + // Determine the cloud name + String cloudName = "test"; + + // Shade the jar + ShadeRequest request = new ShadeRequest(); + File shadeJar = null; + // request.setJars(jars); + request.setUberJar(shadeJar); + request.setFilters(Collections.emptyList()); + request.setResourceTransformers(Arrays.asList(new ServicesResourceTransformer())); + request.setRelocators(Collections.emptyList()); + try { + this.shader.shade(request); + } catch (IOException ex) { + throw new MojoExecutionException(ex.getMessage(), ex); + } + + // Attach the cloud jar + this.projectHelper.attachArtifact(this._project, this._project.getArtifact().getType(), cloudName, + shadeJar); + } + } + +} diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AbstractCloudShadeMojoTestCase.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AbstractCloudShadeMojoTestCase.java new file mode 100644 index 0000000000..044b8b8638 --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AbstractCloudShadeMojoTestCase.java @@ -0,0 +1,143 @@ +package net.officefloor.maven.cloud; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.io.File; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.junit.jupiter.api.Test; + +import net.officefloor.OfficeFloorMain; +import net.officefloor.cabinet.Cabinet; +import net.officefloor.cabinet.source.CabinetManagerManagedObjectSource; +import net.officefloor.cabinet.spi.CabinetManager; +import net.officefloor.woof.WoofLoaderImpl; + +/** + * Ensures the two cloud jars are created. + * + * @author Daniel Sagenschneider + */ +public abstract class AbstractCloudShadeMojoTestCase { + + protected static final Class[] OFFICEFLOOR_CLASSES = new Class[] { OfficeFloorMain.class }; + + protected static final Class[] WOOF_CLASSES = new Class[] { WoofLoaderImpl.class }; + + protected static final Class[] CABINET_CLASSES = new Class[] { Cabinet.class, CabinetManager.class }; + + protected static final Class[] CABINET_IMPL_CLASSES = new Class[] { CabinetManagerManagedObjectSource.class }; + + protected static final Class[] AWS_CLASSES = new Class[] {}; + + protected static final Class[] GOOGLE_CLASSES = new Class[] {}; + + protected class JarClasses { + public boolean isCreate = true; + public final List> required = new LinkedList<>(); + + public void required(Class[]... classLists) { + for (Class[] classList : classLists) { + this.required.addAll(Arrays.asList(classList)); + } + } + + public final List> notIncluded = new LinkedList<>(); + + public void notIncluded(Class[]... classLists) { + for (Class[] classList : classLists) { + this.notIncluded.addAll(Arrays.asList(classList)); + } + } + } + + protected final JarClasses SHADE = new JarClasses(); + + protected final JarClasses AWS = new JarClasses(); + + protected final JarClasses GOOGLE = new JarClasses(); + + public AbstractCloudShadeMojoTestCase() { + SHADE.notIncluded(AWS_CLASSES, GOOGLE_CLASSES); + AWS.notIncluded(GOOGLE_CLASSES); + GOOGLE.notIncluded(AWS_CLASSES); + } + + /** + * Ensure original shade JAR contains necessary classes. + */ + @Test + public void shade() throws Exception { + this.assertJar(null, SHADE.isCreate, SHADE.required, SHADE.notIncluded); + } + + /** + * Ensure additional AWS classes. + */ + @Test + public void aws() throws Exception { + this.assertJar("aws", AWS.isCreate, AWS.required, AWS.notIncluded); + } + + /** + * Ensure additional Google classes. + */ + @Test + public void google() throws Exception { + this.assertJar("google", GOOGLE.isCreate, GOOGLE.required, GOOGLE.notIncluded); + } + + private void assertJar(String classifier, boolean isCreateJar, List> requiredClasses, + List> notIncludedClasses) throws Exception { + + // Determine classifier + String classifierRegexPart = (classifier != null) ? "-" + classifier : ""; + + // Obtain test directory name + String testDirectoryName = this.getClass().getSimpleName(); + testDirectoryName = testDirectoryName.substring(0, testDirectoryName.length() - "IT".length()); + + // Search for created jar + File targetDir = new File("./target/it/" + testDirectoryName + "/target"); + File cloudJar = null; + for (File checkFile : targetDir.listFiles()) { + String fileName = checkFile.getName(); + if (fileName.matches("^Cloud-(\\d)+\\.(\\d)+\\.(\\d)+" + classifierRegexPart + "\\.jar")) { + cloudJar = checkFile; + } + } + if (isCreateJar) { + assertNotNull(cloudJar, "No JAR created for " + classifier + ".\nFiles were:\n\t" + + String.join("\n\t", targetDir.list()) + "\n"); + } else { + assertNull(cloudJar, "Should not create JAR for " + classifier); + return; // nothing further to test + } + + // Check the necessary classes are included + try (JarFile jar = new JarFile(cloudJar)) { + + // Ensure all the required classes are included + for (Class clazz : requiredClasses) { + assertNotNull(getJarEntry(jar, clazz), + "Missing required class " + clazz.getName() + " in JAR " + cloudJar.getAbsolutePath()); + } + + // Ensure all not included classes are not included + for (Class clazz : notIncludedClasses) { + assertNull(getJarEntry(jar, clazz), + "Should not include class " + clazz.getName() + " in JAR " + cloudJar.getAbsolutePath()); + } + } + } + + private static JarEntry getJarEntry(JarFile jar, Class clazz) { + return jar.getJarEntry(clazz.getName().replace('.', '/') + ".class"); + } + +} \ No newline at end of file diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/CloudIT.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/CloudIT.java new file mode 100644 index 0000000000..e26a86c0fe --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/CloudIT.java @@ -0,0 +1,17 @@ +package net.officefloor.maven.cloud; + +/** + * Tests no cloud configured. + * + * @author Daniel Sagenschneider + */ +public class CloudIT extends AbstractCloudShadeMojoTestCase { + + public CloudIT() { + SHADE.required(OFFICEFLOOR_CLASSES, WOOF_CLASSES, CABINET_CLASSES); + SHADE.notIncluded(CABINET_IMPL_CLASSES); + AWS.isCreate = false; + GOOGLE.isCreate = false; + } + +} diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/NoCloudIT.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/NoCloudIT.java new file mode 100644 index 0000000000..aabf38c3f2 --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/NoCloudIT.java @@ -0,0 +1,14 @@ +package net.officefloor.maven.cloud; + +/** + * Tests no cloud configured. + * + * @author Daniel Sagenschneider + */ +public class NoCloudIT extends AbstractCloudShadeMojoTestCase { + + public NoCloudIT() { + AWS.isCreate = false; + GOOGLE.isCreate = false; + } +} diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/verifier/verifications.xml b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/verifier/verifications.xml new file mode 100644 index 0000000000..6ad604a1d6 --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/verifier/verifications.xml @@ -0,0 +1,9 @@ + + + + + ${basedir}/../../pom.xml + [^;]*${project.artifactId}[^;]*]]> + + + diff --git a/officefloor/maven/officefloor-sam-maven-plugin/pom.xml b/officefloor/maven/officefloor-sam-maven-plugin/pom.xml index ab128d0037..645555a10c 100644 --- a/officefloor/maven/officefloor-sam-maven-plugin/pom.xml +++ b/officefloor/maven/officefloor-sam-maven-plugin/pom.xml @@ -94,6 +94,7 @@ ${settings.localRepository} true + clean verify diff --git a/officefloor/maven/pom.xml b/officefloor/maven/pom.xml index 13c951776e..ace4ac14aa 100644 --- a/officefloor/maven/pom.xml +++ b/officefloor/maven/pom.xml @@ -20,6 +20,7 @@ + officefloor-cloud-maven-plugin officefloor-googlefunction-maven officefloor-googlefunction-maven-plugin officefloor-sam-maven-plugin diff --git a/officefloor/maven/tycho-shade-maven-plugin/pom.xml b/officefloor/maven/tycho-shade-maven-plugin/pom.xml index 5a76bb75d9..e8417a0a89 100644 --- a/officefloor/maven/tycho-shade-maven-plugin/pom.xml +++ b/officefloor/maven/tycho-shade-maven-plugin/pom.xml @@ -25,7 +25,7 @@ org.apache.maven.plugins maven-shade-plugin - ${shade-version} + ${maven-shade-version} org.apache.maven diff --git a/officefloor/pom.xml b/officefloor/pom.xml index f777552189..7cd76983b0 100644 --- a/officefloor/pom.xml +++ b/officefloor/pom.xml @@ -72,7 +72,6 @@ 11 ${revision} UTF-8 - 3.5.0 4.0.3 @@ -273,6 +272,11 @@ officefloor-appengine-maven-plugin ${revision} + + net.officefloor.maven + officefloor-cloud-maven-plugin + ${revision} + net.officefloor.maven officefloor-googlefunction-maven-plugin @@ -488,7 +492,7 @@ org.apache.maven.plugins maven-shade-plugin - ${shade-version} + ${maven-shade-version} org.apache.maven.plugins From 3d063273024e1effacd07b6f5d0b67ce5d55e968 Mon Sep 17 00:00:00 2001 From: Daniel Sagenschneider Date: Thu, 13 Jun 2024 08:46:12 +0800 Subject: [PATCH 2/9] Designs to create the various cloud shaded jars for deployment --- .gitignore | 1 + .../resources/META-INF/cloud/cloud.properties | 2 + .../META-INF/cloud/cloud-artifact.properties | 4 ++ .../src/it/Aws/pom.xml | 50 +++++++++++++++++++ .../cloud/OfficeFloorCloudShadeMojo.java | 8 +-- .../cloud/AbstractCloudShadeMojoTestCase.java | 4 +- .../net/officefloor/maven/cloud/AwsIT.java | 18 +++++++ 7 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 officefloor/cloud/officecloud_aws/src/main/resources/META-INF/cloud/cloud.properties create mode 100644 officefloor/cloud/officecloud_aws_test/src/main/resources/META-INF/cloud/cloud-artifact.properties create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/src/it/Aws/pom.xml create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AwsIT.java diff --git a/.gitignore b/.gitignore index 30e72bb8e2..b9edc45844 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ **/*.jar **/*.zip **/*.log +/.java-version diff --git a/officefloor/cloud/officecloud_aws/src/main/resources/META-INF/cloud/cloud.properties b/officefloor/cloud/officecloud_aws/src/main/resources/META-INF/cloud/cloud.properties new file mode 100644 index 0000000000..90ff82d69f --- /dev/null +++ b/officefloor/cloud/officecloud_aws/src/main/resources/META-INF/cloud/cloud.properties @@ -0,0 +1,2 @@ +name=AWS +classifier=AWS \ No newline at end of file diff --git a/officefloor/cloud/officecloud_aws_test/src/main/resources/META-INF/cloud/cloud-artifact.properties b/officefloor/cloud/officecloud_aws_test/src/main/resources/META-INF/cloud/cloud-artifact.properties new file mode 100644 index 0000000000..175f76701d --- /dev/null +++ b/officefloor/cloud/officecloud_aws_test/src/main/resources/META-INF/cloud/cloud-artifact.properties @@ -0,0 +1,4 @@ +groupId=net.officefloor.cloud +artifactId=officecloud_aws +version=@VERSION@ +classifier= \ No newline at end of file diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/it/Aws/pom.xml b/officefloor/maven/officefloor-cloud-maven-plugin/src/it/Aws/pom.xml new file mode 100644 index 0000000000..67c2fa89d4 --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/it/Aws/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + net.officefloor.maven.test + Cloud + @project.version@ + + ${project.version} + + + + + net.officefloor + bom + ${officefloor-version} + pom + import + + + + + + net.officefloor.cloud + officecloud + + + net.officefloor.cloud + officecloud_aws_test + + + + + + net.officefloor.maven + officefloor-cloud-maven-plugin + ${officefloor-version} + + + package + + shade + + + + + + + diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java index 9459e712cd..305c881a77 100644 --- a/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java @@ -134,10 +134,6 @@ public void execute() throws MojoExecutionException { this.getLog().info("ATTACHED ARTIFACT: " + artifact); } - // TODO REMOVE - if (true) - return; - // Obtain the final jar String finalName = this._project.getBuild().getFinalName(); String targetDirectory = this._project.getBuild().getDirectory(); @@ -155,6 +151,10 @@ public void execute() throws MojoExecutionException { for (String testClassPathEntry : testClassPathEntries) { // Determine the artifacts for test + + + System.out.println("\t" + testClassPathEntry); + if (true) continue; // Determine the cloud name String cloudName = "test"; diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AbstractCloudShadeMojoTestCase.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AbstractCloudShadeMojoTestCase.java index 044b8b8638..9e60ce49cc 100644 --- a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AbstractCloudShadeMojoTestCase.java +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AbstractCloudShadeMojoTestCase.java @@ -14,6 +14,8 @@ import net.officefloor.OfficeFloorMain; import net.officefloor.cabinet.Cabinet; +import net.officefloor.cabinet.dynamo.DynamoOfficeStore; +import net.officefloor.cabinet.dynamo.DynamoOfficeStoreServiceFactory; import net.officefloor.cabinet.source.CabinetManagerManagedObjectSource; import net.officefloor.cabinet.spi.CabinetManager; import net.officefloor.woof.WoofLoaderImpl; @@ -33,7 +35,7 @@ public abstract class AbstractCloudShadeMojoTestCase { protected static final Class[] CABINET_IMPL_CLASSES = new Class[] { CabinetManagerManagedObjectSource.class }; - protected static final Class[] AWS_CLASSES = new Class[] {}; + protected static final Class[] AWS_CLASSES = new Class[] { DynamoOfficeStoreServiceFactory.class, DynamoOfficeStore.class }; protected static final Class[] GOOGLE_CLASSES = new Class[] {}; diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AwsIT.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AwsIT.java new file mode 100644 index 0000000000..da1db0a268 --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AwsIT.java @@ -0,0 +1,18 @@ +package net.officefloor.maven.cloud; + +/** + * Tests no cloud configured. + * + * @author Daniel Sagenschneider + */ +public class AwsIT extends AbstractCloudShadeMojoTestCase { + + public AwsIT() { + SHADE.required(OFFICEFLOOR_CLASSES, WOOF_CLASSES, CABINET_CLASSES); + SHADE.notIncluded(CABINET_IMPL_CLASSES); + AWS.isCreate = true; + AWS.required(OFFICEFLOOR_CLASSES, WOOF_CLASSES, CABINET_CLASSES, CABINET_IMPL_CLASSES, AWS_CLASSES); + GOOGLE.isCreate = false; + } + +} From 460147cef90e08eb6f3fcb2d6f10a90ec31bff6c Mon Sep 17 00:00:00 2001 From: Daniel Sagenschneider Date: Fri, 21 Jun 2024 00:03:02 +0800 Subject: [PATCH 3/9] Initial steps to build cloud specific shaded jar --- .../META-INF/cloud/cloud-artifact.properties | 2 +- .../cloud/OfficeFloorCloudShadeMojo.java | 215 ++++++++++++++++-- 2 files changed, 202 insertions(+), 15 deletions(-) diff --git a/officefloor/cloud/officecloud_aws_test/src/main/resources/META-INF/cloud/cloud-artifact.properties b/officefloor/cloud/officecloud_aws_test/src/main/resources/META-INF/cloud/cloud-artifact.properties index 175f76701d..5c342cdcaa 100644 --- a/officefloor/cloud/officecloud_aws_test/src/main/resources/META-INF/cloud/cloud-artifact.properties +++ b/officefloor/cloud/officecloud_aws_test/src/main/resources/META-INF/cloud/cloud-artifact.properties @@ -1,4 +1,4 @@ groupId=net.officefloor.cloud artifactId=officecloud_aws -version=@VERSION@ +version=${revision} classifier= \ No newline at end of file diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java index 305c881a77..aff67f0416 100644 --- a/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java @@ -1,15 +1,21 @@ package net.officefloor.maven.cloud; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.lang.reflect.Field; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; import javax.inject.Inject; -import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; @@ -23,6 +29,18 @@ import org.apache.maven.plugins.shade.resource.ServicesResourceTransformer; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.ArtifactResult; +import org.eclipse.aether.resolution.DependencyRequest; +import org.eclipse.aether.resolution.DependencyResolutionException; +import org.eclipse.aether.resolution.DependencyResult; /** * Builds the additional cloud specific jars attaching them with classifiers. @@ -31,7 +49,17 @@ */ @Mojo(name = "shade", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.RUNTIME) public class OfficeFloorCloudShadeMojo extends ShadeMojo { + + /** + * Path to cloud artifact properties in the test artifact dependency. + */ + public static final String CLOUD_ARTIFACT_PROPERTIES_PATH = "META-INF/cloud/cloud-artifact.properties"; + /** + * Path to cloud meta-data properties within the cloud artifact dependency. + */ + public static final String CLOUD_META_DATA_PROPERTIES_PATH = "META-INF/cloud/cloud.properties"; + /** * Parent {@link ShadeMojo} {@link Class}. */ @@ -49,6 +77,15 @@ public class OfficeFloorCloudShadeMojo extends ShadeMojo { @Component private Shader shader; + @Component + private RepositorySystem repositorySystem; + + @Parameter(defaultValue = "${repositorySystemSession}", readonly = true, required = true) + private RepositorySystemSession repositorySystemSession; + + @Parameter(defaultValue = "${project.remotePluginRepositories}", readonly = true) + private List remoteRepositories; + @Inject private MavenProjectHelper projectHelper; @@ -80,6 +117,7 @@ protected Field getShadeField(String fieldName) throws MojoExecutionException { * @return {@link Field} value. * @throws MojoExecutionException If unable to get {@link Field} value. */ + @SuppressWarnings("unchecked") protected V getShadeFieldValue(String fieldName) throws MojoExecutionException { Field field = this.getShadeField(fieldName); try { @@ -130,14 +168,18 @@ public void execute() throws MojoExecutionException { super.execute(); // Obtain the project attachments - for (Artifact artifact : this._project.getAttachedArtifacts()) { + for (org.apache.maven.artifact.Artifact artifact : this._project.getAttachedArtifacts()) { this.getLog().info("ATTACHED ARTIFACT: " + artifact); } // Obtain the final jar String finalName = this._project.getBuild().getFinalName(); + String packaging = this._project.getPackaging(); String targetDirectory = this._project.getBuild().getDirectory(); - File projectJar = new File(targetDirectory + "/" + finalName); + File projectJar = new File(targetDirectory + "/" + finalName + "." + packaging); + if (!projectJar.exists()) { + throw new MojoExecutionException("After shading project jar, failed to find it at " + projectJar.getAbsolutePath()); + } // Obtain the test artifacts List testClassPathEntries; @@ -151,19 +193,37 @@ public void execute() throws MojoExecutionException { for (String testClassPathEntry : testClassPathEntries) { // Determine the artifacts for test + Properties cloudArtifactProperties = this.getProperties(new File(testClassPathEntry), CLOUD_ARTIFACT_PROPERTIES_PATH); + if (cloudArtifactProperties == null) { + continue; // no artifact properties to create deployment + } + // Resolve dependency + String groupId = cloudArtifactProperties.getProperty("groupId"); + String artifactId = cloudArtifactProperties.getProperty("artifactId"); + String version = cloudArtifactProperties.getProperty("version"); + String classifier = cloudArtifactProperties.getProperty("classifier"); + String extension = cloudArtifactProperties.getProperty("extension"); + Artifact artifact = this.resolveArtifact(groupId, artifactId, version, classifier, extension); - System.out.println("\t" + testClassPathEntry); - if (true) continue; - - // Determine the cloud name - String cloudName = "test"; + // Obtain the cloud properties + File artifactFile = artifact.getFile(); + Properties cloudMetaDataProperties = this.getProperties(artifactFile, CLOUD_META_DATA_PROPERTIES_PATH); + String cloudClassifier = cloudMetaDataProperties.getProperty("classifier"); + + // Resolve dependencies for the cloud artifact + Set cloudJars = new HashSet<>(); + cloudJars.add(projectJar); // Include the project content + cloudJars.add(artifactFile); // Include cloud dependencies + cloudJars.addAll(this.resolveDependencies(artifact)); // Include further dependencies + + // Determine the Uber JAR file + File uberCloudJarFile = new File(targetDirectory, finalName + "-" + classifier + ".jar"); - // Shade the jar + // Shade the cloud specific jar ShadeRequest request = new ShadeRequest(); - File shadeJar = null; - // request.setJars(jars); - request.setUberJar(shadeJar); + request.setUberJar(uberCloudJarFile); + request.setJars(cloudJars); request.setFilters(Collections.emptyList()); request.setResourceTransformers(Arrays.asList(new ServicesResourceTransformer())); request.setRelocators(Collections.emptyList()); @@ -174,9 +234,136 @@ public void execute() throws MojoExecutionException { } // Attach the cloud jar - this.projectHelper.attachArtifact(this._project, this._project.getArtifact().getType(), cloudName, - shadeJar); + this.projectHelper.attachArtifact(this._project, this._project.getArtifact().getType(), cloudClassifier, + uberCloudJarFile); } } + protected Properties getProperties(File file, String propertiesPath) throws MojoExecutionException { + + // Obtain based on type of path + if (file.isDirectory()) { + + // Attempt to find in directory + File cloudArtifactProperties = new File(file, propertiesPath); + if (!cloudArtifactProperties.exists()) { + return null; // no properties file + } + + // Load and return the properties + try { + Properties properties = new Properties(); + properties.load(new FileInputStream(cloudArtifactProperties)); + return properties; + + } catch (Exception ex) { + this.getLog().warn("Failed to load properties from " + cloudArtifactProperties.getAbsolutePath(), ex); + return null; // no properties + } + + } else if (file.exists()) { + // Return properties from jar file + try (JarFile jarFile = new JarFile(file)) { + + // Attempt to find in JAR file + ZipEntry cloudArtifactPropertiesEntry = jarFile.getEntry(propertiesPath); + if (cloudArtifactPropertiesEntry == null) { + return null; // no properties file + } + + // Load and return the properties + try { + Properties properties = new Properties(); + properties.load(jarFile.getInputStream(cloudArtifactPropertiesEntry)); + return properties; + } catch (Exception ex) { + this.getLog().warn("Failed to load properties from " + file.getAbsolutePath(), ex); + return null; // no properties + } + + } catch (Exception ex) { + this.getLog().warn("Failed to read JAR file " + file.getAbsolutePath(), ex); + return null; // no properties + } + + } else { + // Path not exist + return null; + } + } + + protected Artifact resolveArtifact(String groupId, String artifactId, String version, String classifier, String extension) throws MojoExecutionException { + + // Create the artifact + DefaultArtifact searchArtifact = new DefaultArtifact(groupId, artifactId, classifier, extension, version); + + // Attempt to resolve the artifact + ArtifactResult result; + try { + ArtifactRequest request = new ArtifactRequest(); + request.setArtifact(searchArtifact); + request.setRepositories(this.remoteRepositories); + result = this.repositorySystem.resolveArtifact(this.repositorySystemSession, request); + } catch (ArtifactResolutionException ex) { + throw new MojoExecutionException("Failed to resolve artifact " + searchArtifact, ex); + } + + // Return the artifact + return this.getArtifact(result, "artifact"); + } + + protected List resolveDependencies(Artifact artifact) throws MojoExecutionException { + + // Attempt to resolve the dependencies + DependencyResult result; + try { + CollectRequest collectRequest = new CollectRequest(); + + collectRequest.setRepositories(this.remoteRepositories); + DependencyRequest dependencyRequest = new DependencyRequest(); + dependencyRequest.setCollectRequest(collectRequest); + result = this.repositorySystem.resolveDependencies(this.repositorySystemSession, dependencyRequest); + } catch (DependencyResolutionException ex) { + throw new MojoExecutionException("Failed to resolve dependencies for " + artifact, ex); + } + + // Determine if error + for (Exception ex : result.getCollectExceptions()) { + throw new MojoExecutionException("Failed to resolve dependencies for " + artifact, ex); + } + + // Load the list of artifact files + List artifactResults = result.getArtifactResults(); + List dependencies = new ArrayList<>(artifactResults.size()); + for (ArtifactResult artifactResult : artifactResults) { + dependencies.add(this.getArtifact(artifactResult, "dependency").getFile()); + } + + // Return the dependencies + return dependencies; + } + + protected Artifact getArtifact(ArtifactResult result, String type) throws MojoExecutionException { + + // Ensure have artifact + if (result.isMissing()) { + throw new MojoExecutionException("Did not find " + type + " " + result.getArtifact()); + } + + // Ensure resolved + if (!result.isResolved()) { + + // Log the exceptions in failing to resolve + for (Exception resolutionException : result.getExceptions()) { + this.getLog().error("Failure in resolving " + type + " " + result.getArtifact(), resolutionException); + } + + // Fail as must resolve artifact + throw new MojoExecutionException("Failed to resolve " + type + " " + result.getArtifact()); + } + + // Return the artifact + return result.getArtifact(); + } + } From 701cf71dcf67ff24e2d4c3fcec42bbe7eba72285 Mon Sep 17 00:00:00 2001 From: Daniel Sagenschneider Date: Sat, 22 Jun 2024 23:28:00 +0800 Subject: [PATCH 4/9] Able to build a cloud specific shaded jar --- .../resources/META-INF/cloud/cloud.properties | 2 +- .../cloud/officecloud_aws_test/pom.xml | 8 + .../META-INF/cloud/cloud-artifact.properties | 2 +- .../src/it/Aws/pom.xml | 1 + .../cloud/OfficeFloorCloudShadeMojo.java | 310 ++++++++---------- 5 files changed, 150 insertions(+), 173 deletions(-) diff --git a/officefloor/cloud/officecloud_aws/src/main/resources/META-INF/cloud/cloud.properties b/officefloor/cloud/officecloud_aws/src/main/resources/META-INF/cloud/cloud.properties index 90ff82d69f..85e691b71e 100644 --- a/officefloor/cloud/officecloud_aws/src/main/resources/META-INF/cloud/cloud.properties +++ b/officefloor/cloud/officecloud_aws/src/main/resources/META-INF/cloud/cloud.properties @@ -1,2 +1,2 @@ name=AWS -classifier=AWS \ No newline at end of file +classifier=aws \ No newline at end of file diff --git a/officefloor/cloud/officecloud_aws_test/pom.xml b/officefloor/cloud/officecloud_aws_test/pom.xml index 338439e24b..bbd7973cd4 100644 --- a/officefloor/cloud/officecloud_aws_test/pom.xml +++ b/officefloor/cloud/officecloud_aws_test/pom.xml @@ -27,4 +27,12 @@ officenosql_dynamodb_test + + + + src/main/resources + true + + + \ No newline at end of file diff --git a/officefloor/cloud/officecloud_aws_test/src/main/resources/META-INF/cloud/cloud-artifact.properties b/officefloor/cloud/officecloud_aws_test/src/main/resources/META-INF/cloud/cloud-artifact.properties index 5c342cdcaa..8c321d4310 100644 --- a/officefloor/cloud/officecloud_aws_test/src/main/resources/META-INF/cloud/cloud-artifact.properties +++ b/officefloor/cloud/officecloud_aws_test/src/main/resources/META-INF/cloud/cloud-artifact.properties @@ -1,4 +1,4 @@ groupId=net.officefloor.cloud artifactId=officecloud_aws -version=${revision} +version=${project.version} classifier= \ No newline at end of file diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/it/Aws/pom.xml b/officefloor/maven/officefloor-cloud-maven-plugin/src/it/Aws/pom.xml index 67c2fa89d4..74420922b0 100644 --- a/officefloor/maven/officefloor-cloud-maven-plugin/src/it/Aws/pom.xml +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/it/Aws/pom.xml @@ -28,6 +28,7 @@ net.officefloor.cloud officecloud_aws_test + test diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java index aff67f0416..66580a66b4 100644 --- a/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java @@ -2,11 +2,9 @@ import java.io.File; import java.io.FileInputStream; -import java.io.IOException; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Properties; @@ -14,26 +12,25 @@ import java.util.jar.JarFile; import java.util.zip.ZipEntry; -import javax.inject.Inject; - +import org.apache.maven.RepositoryUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; -import org.apache.maven.plugins.shade.ShadeRequest; -import org.apache.maven.plugins.shade.Shader; import org.apache.maven.plugins.shade.mojo.ShadeMojo; import org.apache.maven.plugins.shade.resource.ResourceTransformer; import org.apache.maven.plugins.shade.resource.ServicesResourceTransformer; import org.apache.maven.project.MavenProject; -import org.apache.maven.project.MavenProjectHelper; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.DependencyFilter; import org.eclipse.aether.repository.RemoteRepository; import org.eclipse.aether.resolution.ArtifactRequest; import org.eclipse.aether.resolution.ArtifactResolutionException; @@ -41,15 +38,17 @@ import org.eclipse.aether.resolution.DependencyRequest; import org.eclipse.aether.resolution.DependencyResolutionException; import org.eclipse.aether.resolution.DependencyResult; +import org.eclipse.aether.util.artifact.JavaScopes; +import org.eclipse.aether.util.filter.DependencyFilterUtils; /** * Builds the additional cloud specific jars attaching them with classifiers. * * @author Daniel Sagenschneider */ -@Mojo(name = "shade", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.RUNTIME) +@Mojo(name = "shade", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.TEST) public class OfficeFloorCloudShadeMojo extends ShadeMojo { - + /** * Path to cloud artifact properties in the test artifact dependency. */ @@ -59,23 +58,6 @@ public class OfficeFloorCloudShadeMojo extends ShadeMojo { * Path to cloud meta-data properties within the cloud artifact dependency. */ public static final String CLOUD_META_DATA_PROPERTIES_PATH = "META-INF/cloud/cloud.properties"; - - /** - * Parent {@link ShadeMojo} {@link Class}. - */ - private final Class shadeMojoClass = this.getClass().getSuperclass(); - - /** - * {@link MavenProject}. - */ - @Parameter(defaultValue = "${project}", readonly = true) - private MavenProject _project; - - /** - * {@link Shader}. - */ - @Component - private Shader shader; @Component private RepositorySystem repositorySystem; @@ -86,31 +68,114 @@ public class OfficeFloorCloudShadeMojo extends ShadeMojo { @Parameter(defaultValue = "${project.remotePluginRepositories}", readonly = true) private List remoteRepositories; - @Inject - private MavenProjectHelper projectHelper; + @Override + public void execute() throws MojoExecutionException { + + // Obtain the project + MavenProject project = this.getFieldValue(ShadeMojo.class, "project", this); + + // Ensure have services resource transformer + ResourceTransformer[] transformers = this.getFieldValue(ShadeMojo.class, "transformers", this); + if (transformers == null) { + transformers = new ResourceTransformer[0]; + } + if (!Arrays.asList(transformers).stream().anyMatch( + (transformer) -> ServicesResourceTransformer.class.isAssignableFrom(transformer.getClass()))) { + // Include services resource transformer + transformers = Arrays.copyOf(transformers, transformers.length + 1); + transformers[transformers.length - 1] = new ServicesResourceTransformer(); + this.setFieldValue(ShadeMojo.class, "transformers", this, transformers); + } + + // Obtain the resolved artifacts + Set originalResolvedArtifacts = this.getFieldValue(MavenProject.class, "resolvedArtifacts", project); + try { + + // Obtain the runtime resolved artifacts + ScopeArtifactFilter runtimeFilter = new ScopeArtifactFilter(Artifact.SCOPE_RUNTIME); + List runtimeResolvedArtifacts = originalResolvedArtifacts.stream().filter(runtimeFilter::include) + .toList(); + this.getLog().debug("Project runtime dependencies " + String.join(", ", runtimeResolvedArtifacts.stream() + .map((artifact) -> artifact.getFile().getAbsolutePath()).toList())); + + // Iterate over artifacts looking for cloud artifacts + for (Artifact projectDependency : originalResolvedArtifacts) { + + // Determine the artifacts for test + File projectDependencyFile = projectDependency.getFile(); + Properties cloudArtifactProperties = this.getProperties(projectDependencyFile, + CLOUD_ARTIFACT_PROPERTIES_PATH); + if (cloudArtifactProperties == null) { + continue; // no artifact properties to create deployment + } + this.getLog().debug("Found cloud configuration in " + projectDependencyFile.getAbsolutePath()); + + // Resolve dependency + String groupId = cloudArtifactProperties.getProperty("groupId"); + String artifactId = cloudArtifactProperties.getProperty("artifactId"); + String version = cloudArtifactProperties.getProperty("version"); + String classifier = cloudArtifactProperties.getProperty("classifier"); + String extension = cloudArtifactProperties.getProperty("extension"); + if ((extension == null) || (extension.isEmpty())) { + extension = "jar"; + } + DefaultArtifact unresolvedArtifact = new DefaultArtifact(groupId, artifactId, classifier, extension, + version); + this.getLog().debug("Providing cloud build from " + unresolvedArtifact); + org.eclipse.aether.artifact.Artifact cloudArtifact = this.resolveArtifact(unresolvedArtifact); + + // Obtain the cloud properties + File artifactFile = cloudArtifact.getFile(); + Properties cloudMetaDataProperties = this.getProperties(artifactFile, CLOUD_META_DATA_PROPERTIES_PATH); + String cloudName = cloudMetaDataProperties.getProperty("name"); + String cloudClassifier = cloudMetaDataProperties.getProperty("classifier"); + this.getLog().info("Shading " + cloudName + " cloud deployment with classifier " + cloudClassifier); + + // Resolve dependencies for the cloud artifact + List cloudResolvedDependencies = this.resolveDependencies(cloudArtifact).stream() + .map(RepositoryUtils::toArtifact).toList(); + this.getLog().debug("Cloud resolved dependencies " + String.join(", ", cloudResolvedDependencies + .stream().map((artifact) -> artifact.getFile().getAbsolutePath()).toList())); + + // Obtain the runtime artifacts for cloud implementation + Set cloudArtifacts = new HashSet<>(); + cloudArtifacts.addAll(runtimeResolvedArtifacts); + cloudArtifacts.addAll(cloudResolvedDependencies); + + // Undertaking shading for cloud solution + this.setFieldValue(MavenProject.class, "resolvedArtifacts", project, cloudArtifacts); + this.setFieldValue(ShadeMojo.class, "shadedArtifactAttached", this, true); + this.setFieldValue(ShadeMojo.class, "shadedClassifierName", this, cloudClassifier); + super.execute(); + } + + } finally { + // Reset the artifacts + this.setFieldValue(MavenProject.class, "resolvedArtifacts", project, originalResolvedArtifacts); + } + } /** - * Obtains the {@link Field} from {@link ShadeMojo} parent. + * Obtains the {@link Field}. * * @param fieldName Name of {@link Field}. * @return {@link Field}. - * @throws MojoExecutionException If {@link Field} no longer in - * {@link ShadeMojo}. + * @throws MojoExecutionException If {@link Field} no longer in {@link Class}. */ - protected Field getShadeField(String fieldName) throws MojoExecutionException { + protected Field getField(Class clazz, String fieldName) throws MojoExecutionException { Field field; try { - field = this.shadeMojoClass.getDeclaredField(fieldName); + field = clazz.getDeclaredField(fieldName); } catch (NoSuchFieldException ex) { throw new MojoExecutionException( - this.shadeMojoClass.getSimpleName() + " has changed and no longer has field " + fieldName); + clazz.getSimpleName() + " has changed and no longer has field " + fieldName); } field.setAccessible(true); return field; } /** - * Obtains the {@link ShadeMojo} {@link Field} value. + * Obtains the {@link Field} value. * * @param {@link Field} type. * @param fieldName Name of {@link Field}. @@ -118,13 +183,12 @@ protected Field getShadeField(String fieldName) throws MojoExecutionException { * @throws MojoExecutionException If unable to get {@link Field} value. */ @SuppressWarnings("unchecked") - protected V getShadeFieldValue(String fieldName) throws MojoExecutionException { - Field field = this.getShadeField(fieldName); + protected V getFieldValue(Class clazz, String fieldName, O target) throws MojoExecutionException { + Field field = this.getField(clazz, fieldName); try { - return (V) field.get(this); + return (V) field.get(target); } catch (IllegalArgumentException | IllegalAccessException ex) { - throw new MojoExecutionException( - "Unable to get value for " + this.shadeMojoClass.getSimpleName() + "#" + fieldName, ex); + throw new MojoExecutionException("Unable to get value for " + clazz.getSimpleName() + "#" + fieldName, ex); } } @@ -136,111 +200,18 @@ protected V getShadeFieldValue(String fieldName) throws MojoExecutionExcepti * @return {@link Field} value. * @throws MojoExecutionException If unable to get {@link Field} value. */ - protected void setShadeFieldValue(String fieldName, V value) throws MojoExecutionException { - Field field = this.getShadeField(fieldName); + protected void setFieldValue(Class clazz, String fieldName, O target, V value) + throws MojoExecutionException { + Field field = this.getField(clazz, fieldName); try { - field.set(this, value); + field.set(target, value); } catch (IllegalArgumentException | IllegalAccessException ex) { - throw new MojoExecutionException( - "Unable to set value for " + this.shadeMojoClass.getSimpleName() + "#" + fieldName, ex); - } - } - - @Override - public void execute() throws MojoExecutionException { - - // Ensure have services resource transformer - ResourceTransformer[] transformers = this.getShadeFieldValue("transformers"); - if (transformers == null) { - transformers = new ResourceTransformer[0]; - } - boolean isIncluded = Arrays.asList(transformers).stream() - .anyMatch((transformer) -> ServicesResourceTransformer.class.isAssignableFrom(transformer.getClass())); - if (!isIncluded) { - // Include services resource transfomer - transformers = Arrays.copyOf(transformers, transformers.length + 1); - transformers[transformers.length - 1] = new ServicesResourceTransformer(); - this.setShadeFieldValue("transformers", transformers); - } - - // Undertake shading of the component - this.getLog().info("Shading project"); - super.execute(); - - // Obtain the project attachments - for (org.apache.maven.artifact.Artifact artifact : this._project.getAttachedArtifacts()) { - this.getLog().info("ATTACHED ARTIFACT: " + artifact); - } - - // Obtain the final jar - String finalName = this._project.getBuild().getFinalName(); - String packaging = this._project.getPackaging(); - String targetDirectory = this._project.getBuild().getDirectory(); - File projectJar = new File(targetDirectory + "/" + finalName + "." + packaging); - if (!projectJar.exists()) { - throw new MojoExecutionException("After shading project jar, failed to find it at " + projectJar.getAbsolutePath()); - } - - // Obtain the test artifacts - List testClassPathEntries; - try { - testClassPathEntries = this._project.getTestClasspathElements(); - } catch (Exception ex) { - throw new MojoExecutionException(ex); - } - - // Iterate over class path entries finding cloud providers - for (String testClassPathEntry : testClassPathEntries) { - - // Determine the artifacts for test - Properties cloudArtifactProperties = this.getProperties(new File(testClassPathEntry), CLOUD_ARTIFACT_PROPERTIES_PATH); - if (cloudArtifactProperties == null) { - continue; // no artifact properties to create deployment - } - - // Resolve dependency - String groupId = cloudArtifactProperties.getProperty("groupId"); - String artifactId = cloudArtifactProperties.getProperty("artifactId"); - String version = cloudArtifactProperties.getProperty("version"); - String classifier = cloudArtifactProperties.getProperty("classifier"); - String extension = cloudArtifactProperties.getProperty("extension"); - Artifact artifact = this.resolveArtifact(groupId, artifactId, version, classifier, extension); - - // Obtain the cloud properties - File artifactFile = artifact.getFile(); - Properties cloudMetaDataProperties = this.getProperties(artifactFile, CLOUD_META_DATA_PROPERTIES_PATH); - String cloudClassifier = cloudMetaDataProperties.getProperty("classifier"); - - // Resolve dependencies for the cloud artifact - Set cloudJars = new HashSet<>(); - cloudJars.add(projectJar); // Include the project content - cloudJars.add(artifactFile); // Include cloud dependencies - cloudJars.addAll(this.resolveDependencies(artifact)); // Include further dependencies - - // Determine the Uber JAR file - File uberCloudJarFile = new File(targetDirectory, finalName + "-" + classifier + ".jar"); - - // Shade the cloud specific jar - ShadeRequest request = new ShadeRequest(); - request.setUberJar(uberCloudJarFile); - request.setJars(cloudJars); - request.setFilters(Collections.emptyList()); - request.setResourceTransformers(Arrays.asList(new ServicesResourceTransformer())); - request.setRelocators(Collections.emptyList()); - try { - this.shader.shade(request); - } catch (IOException ex) { - throw new MojoExecutionException(ex.getMessage(), ex); - } - - // Attach the cloud jar - this.projectHelper.attachArtifact(this._project, this._project.getArtifact().getType(), cloudClassifier, - uberCloudJarFile); + throw new MojoExecutionException("Unable to set value for " + clazz.getSimpleName() + "#" + fieldName, ex); } } protected Properties getProperties(File file, String propertiesPath) throws MojoExecutionException { - + // Obtain based on type of path if (file.isDirectory()) { @@ -255,7 +226,7 @@ protected Properties getProperties(File file, String propertiesPath) throws Mojo Properties properties = new Properties(); properties.load(new FileInputStream(cloudArtifactProperties)); return properties; - + } catch (Exception ex) { this.getLog().warn("Failed to load properties from " + cloudArtifactProperties.getAbsolutePath(), ex); return null; // no properties @@ -264,13 +235,13 @@ protected Properties getProperties(File file, String propertiesPath) throws Mojo } else if (file.exists()) { // Return properties from jar file try (JarFile jarFile = new JarFile(file)) { - + // Attempt to find in JAR file ZipEntry cloudArtifactPropertiesEntry = jarFile.getEntry(propertiesPath); if (cloudArtifactPropertiesEntry == null) { return null; // no properties file } - + // Load and return the properties try { Properties properties = new Properties(); @@ -284,44 +255,40 @@ protected Properties getProperties(File file, String propertiesPath) throws Mojo } catch (Exception ex) { this.getLog().warn("Failed to read JAR file " + file.getAbsolutePath(), ex); return null; // no properties - } - + } + } else { // Path not exist return null; } } - - protected Artifact resolveArtifact(String groupId, String artifactId, String version, String classifier, String extension) throws MojoExecutionException { - // Create the artifact - DefaultArtifact searchArtifact = new DefaultArtifact(groupId, artifactId, classifier, extension, version); - + protected org.eclipse.aether.artifact.Artifact resolveArtifact( + org.eclipse.aether.artifact.Artifact unresolvedArtifact) throws MojoExecutionException { + // Attempt to resolve the artifact ArtifactResult result; try { - ArtifactRequest request = new ArtifactRequest(); - request.setArtifact(searchArtifact); - request.setRepositories(this.remoteRepositories); + ArtifactRequest request = new ArtifactRequest(unresolvedArtifact, this.remoteRepositories, null); result = this.repositorySystem.resolveArtifact(this.repositorySystemSession, request); } catch (ArtifactResolutionException ex) { - throw new MojoExecutionException("Failed to resolve artifact " + searchArtifact, ex); + throw new MojoExecutionException("Failed to resolve artifact " + unresolvedArtifact, ex); } - + // Return the artifact return this.getArtifact(result, "artifact"); } - protected List resolveDependencies(Artifact artifact) throws MojoExecutionException { - + protected List resolveDependencies( + org.eclipse.aether.artifact.Artifact artifact) throws MojoExecutionException { + // Attempt to resolve the dependencies DependencyResult result; try { - CollectRequest collectRequest = new CollectRequest(); - - collectRequest.setRepositories(this.remoteRepositories); - DependencyRequest dependencyRequest = new DependencyRequest(); - dependencyRequest.setCollectRequest(collectRequest); + CollectRequest collectRequest = new CollectRequest(new Dependency(artifact, "runtime"), + this.remoteRepositories); + DependencyFilter filter = DependencyFilterUtils.classpathFilter(JavaScopes.RUNTIME); + DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, filter); result = this.repositorySystem.resolveDependencies(this.repositorySystemSession, dependencyRequest); } catch (DependencyResolutionException ex) { throw new MojoExecutionException("Failed to resolve dependencies for " + artifact, ex); @@ -331,33 +298,34 @@ protected List resolveDependencies(Artifact artifact) throws MojoExecution for (Exception ex : result.getCollectExceptions()) { throw new MojoExecutionException("Failed to resolve dependencies for " + artifact, ex); } - + // Load the list of artifact files List artifactResults = result.getArtifactResults(); - List dependencies = new ArrayList<>(artifactResults.size()); + List dependencies = new ArrayList<>(artifactResults.size()); for (ArtifactResult artifactResult : artifactResults) { - dependencies.add(this.getArtifact(artifactResult, "dependency").getFile()); + dependencies.add(this.getArtifact(artifactResult, "dependency")); } - + // Return the dependencies return dependencies; } - - protected Artifact getArtifact(ArtifactResult result, String type) throws MojoExecutionException { + + protected org.eclipse.aether.artifact.Artifact getArtifact(ArtifactResult result, String type) + throws MojoExecutionException { // Ensure have artifact if (result.isMissing()) { throw new MojoExecutionException("Did not find " + type + " " + result.getArtifact()); } - + // Ensure resolved if (!result.isResolved()) { - + // Log the exceptions in failing to resolve for (Exception resolutionException : result.getExceptions()) { this.getLog().error("Failure in resolving " + type + " " + result.getArtifact(), resolutionException); } - + // Fail as must resolve artifact throw new MojoExecutionException("Failed to resolve " + type + " " + result.getArtifact()); } From 0812e674d599d76f6ae7c491f0dc839c52255b5f Mon Sep 17 00:00:00 2001 From: Daniel Sagenschneider Date: Sun, 23 Jun 2024 00:02:07 +0800 Subject: [PATCH 5/9] Able to build cloud specific shaded jars --- .../resources/META-INF/cloud/cloud.properties | 2 + .../cloud/officecloud_google_test/pom.xml | 8 +++ .../META-INF/cloud/cloud-artifact.properties | 4 ++ .../src/it/AwsGoogle/pom.xml | 56 +++++++++++++++++++ .../src/it/Google/pom.xml | 51 +++++++++++++++++ .../cloud/OfficeFloorCloudShadeMojo.java | 5 +- .../cloud/AbstractCloudShadeMojoTestCase.java | 14 +++-- .../officefloor/maven/cloud/AwsGoogleIT.java | 17 ++++++ .../net/officefloor/maven/cloud/AwsIT.java | 4 +- .../net/officefloor/maven/cloud/CloudIT.java | 2 - .../net/officefloor/maven/cloud/GoogleIT.java | 16 ++++++ 11 files changed, 167 insertions(+), 12 deletions(-) create mode 100644 officefloor/cloud/officecloud_google/src/main/resources/META-INF/cloud/cloud.properties create mode 100644 officefloor/cloud/officecloud_google_test/src/main/resources/META-INF/cloud/cloud-artifact.properties create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/src/it/AwsGoogle/pom.xml create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/src/it/Google/pom.xml create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AwsGoogleIT.java create mode 100644 officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/GoogleIT.java diff --git a/officefloor/cloud/officecloud_google/src/main/resources/META-INF/cloud/cloud.properties b/officefloor/cloud/officecloud_google/src/main/resources/META-INF/cloud/cloud.properties new file mode 100644 index 0000000000..4fa2b2d9fc --- /dev/null +++ b/officefloor/cloud/officecloud_google/src/main/resources/META-INF/cloud/cloud.properties @@ -0,0 +1,2 @@ +name=Google +classifier=google \ No newline at end of file diff --git a/officefloor/cloud/officecloud_google_test/pom.xml b/officefloor/cloud/officecloud_google_test/pom.xml index a8e77bbc8f..5829e6729d 100644 --- a/officefloor/cloud/officecloud_google_test/pom.xml +++ b/officefloor/cloud/officecloud_google_test/pom.xml @@ -27,4 +27,12 @@ officenosql_firestore_test + + + + src/main/resources + true + + + \ No newline at end of file diff --git a/officefloor/cloud/officecloud_google_test/src/main/resources/META-INF/cloud/cloud-artifact.properties b/officefloor/cloud/officecloud_google_test/src/main/resources/META-INF/cloud/cloud-artifact.properties new file mode 100644 index 0000000000..55437d91f0 --- /dev/null +++ b/officefloor/cloud/officecloud_google_test/src/main/resources/META-INF/cloud/cloud-artifact.properties @@ -0,0 +1,4 @@ +groupId=net.officefloor.cloud +artifactId=officecloud_google +version=${project.version} +classifier= \ No newline at end of file diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/it/AwsGoogle/pom.xml b/officefloor/maven/officefloor-cloud-maven-plugin/src/it/AwsGoogle/pom.xml new file mode 100644 index 0000000000..5d9ab74b55 --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/it/AwsGoogle/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + net.officefloor.maven.test + Cloud + @project.version@ + + ${project.version} + + + + + net.officefloor + bom + ${officefloor-version} + pom + import + + + + + + net.officefloor.cloud + officecloud + + + net.officefloor.cloud + officecloud_aws_test + test + + + net.officefloor.cloud + officecloud_google_test + test + + + + + + net.officefloor.maven + officefloor-cloud-maven-plugin + ${officefloor-version} + + + package + + shade + + + + + + + diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/it/Google/pom.xml b/officefloor/maven/officefloor-cloud-maven-plugin/src/it/Google/pom.xml new file mode 100644 index 0000000000..275139260e --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/it/Google/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + net.officefloor.maven.test + Cloud + @project.version@ + + ${project.version} + + + + + net.officefloor + bom + ${officefloor-version} + pom + import + + + + + + net.officefloor.cloud + officecloud + + + net.officefloor.cloud + officecloud_google_test + test + + + + + + net.officefloor.maven + officefloor-cloud-maven-plugin + ${officefloor-version} + + + package + + shade + + + + + + + diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java index 66580a66b4..8b2e8998f8 100644 --- a/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/main/java/net/officefloor/maven/cloud/OfficeFloorCloudShadeMojo.java @@ -125,8 +125,8 @@ public void execute() throws MojoExecutionException { org.eclipse.aether.artifact.Artifact cloudArtifact = this.resolveArtifact(unresolvedArtifact); // Obtain the cloud properties - File artifactFile = cloudArtifact.getFile(); - Properties cloudMetaDataProperties = this.getProperties(artifactFile, CLOUD_META_DATA_PROPERTIES_PATH); + Properties cloudMetaDataProperties = this.getProperties(cloudArtifact.getFile(), + CLOUD_META_DATA_PROPERTIES_PATH); String cloudName = cloudMetaDataProperties.getProperty("name"); String cloudClassifier = cloudMetaDataProperties.getProperty("classifier"); this.getLog().info("Shading " + cloudName + " cloud deployment with classifier " + cloudClassifier); @@ -144,6 +144,7 @@ public void execute() throws MojoExecutionException { // Undertaking shading for cloud solution this.setFieldValue(MavenProject.class, "resolvedArtifacts", project, cloudArtifacts); + this.setFieldValue(MavenProject.class, "artifacts", project, null); // clear cache to recalculate this.setFieldValue(ShadeMojo.class, "shadedArtifactAttached", this, true); this.setFieldValue(ShadeMojo.class, "shadedClassifierName", this, cloudClassifier); super.execute(); diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AbstractCloudShadeMojoTestCase.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AbstractCloudShadeMojoTestCase.java index 9e60ce49cc..5853c4c6f9 100644 --- a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AbstractCloudShadeMojoTestCase.java +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AbstractCloudShadeMojoTestCase.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.File; import java.util.Arrays; @@ -16,6 +17,8 @@ import net.officefloor.cabinet.Cabinet; import net.officefloor.cabinet.dynamo.DynamoOfficeStore; import net.officefloor.cabinet.dynamo.DynamoOfficeStoreServiceFactory; +import net.officefloor.cabinet.firestore.FirestoreOfficeStore; +import net.officefloor.cabinet.firestore.FirestoreOfficeStoreServiceFactory; import net.officefloor.cabinet.source.CabinetManagerManagedObjectSource; import net.officefloor.cabinet.spi.CabinetManager; import net.officefloor.woof.WoofLoaderImpl; @@ -37,7 +40,7 @@ public abstract class AbstractCloudShadeMojoTestCase { protected static final Class[] AWS_CLASSES = new Class[] { DynamoOfficeStoreServiceFactory.class, DynamoOfficeStore.class }; - protected static final Class[] GOOGLE_CLASSES = new Class[] {}; + protected static final Class[] GOOGLE_CLASSES = new Class[] { FirestoreOfficeStoreServiceFactory.class, FirestoreOfficeStore.class }; protected class JarClasses { public boolean isCreate = true; @@ -58,14 +61,14 @@ public void notIncluded(Class[]... classLists) { } } - protected final JarClasses SHADE = new JarClasses(); + protected final JarClasses JAR = new JarClasses(); protected final JarClasses AWS = new JarClasses(); protected final JarClasses GOOGLE = new JarClasses(); public AbstractCloudShadeMojoTestCase() { - SHADE.notIncluded(AWS_CLASSES, GOOGLE_CLASSES); + JAR.notIncluded(OFFICEFLOOR_CLASSES, WOOF_CLASSES, CABINET_CLASSES, CABINET_IMPL_CLASSES, AWS_CLASSES, GOOGLE_CLASSES); AWS.notIncluded(GOOGLE_CLASSES); GOOGLE.notIncluded(AWS_CLASSES); } @@ -74,8 +77,8 @@ public AbstractCloudShadeMojoTestCase() { * Ensure original shade JAR contains necessary classes. */ @Test - public void shade() throws Exception { - this.assertJar(null, SHADE.isCreate, SHADE.required, SHADE.notIncluded); + public void jar() throws Exception { + this.assertJar(null, JAR.isCreate, JAR.required, JAR.notIncluded); } /** @@ -106,6 +109,7 @@ private void assertJar(String classifier, boolean isCreateJar, List> re // Search for created jar File targetDir = new File("./target/it/" + testDirectoryName + "/target"); + assertTrue(targetDir.exists(), "Can not find test directory " + targetDir.getPath()); File cloudJar = null; for (File checkFile : targetDir.listFiles()) { String fileName = checkFile.getName(); diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AwsGoogleIT.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AwsGoogleIT.java new file mode 100644 index 0000000000..3bd7edc195 --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AwsGoogleIT.java @@ -0,0 +1,17 @@ +package net.officefloor.maven.cloud; + +/** + * Tests AWS and Google configured. + * + * @author Daniel Sagenschneider + */ +public class AwsGoogleIT extends AbstractCloudShadeMojoTestCase { + + public AwsGoogleIT() { + AWS.isCreate = true; + AWS.required(OFFICEFLOOR_CLASSES, WOOF_CLASSES, CABINET_CLASSES, CABINET_IMPL_CLASSES, AWS_CLASSES); + GOOGLE.isCreate = true; + GOOGLE.required(OFFICEFLOOR_CLASSES, WOOF_CLASSES, CABINET_CLASSES, CABINET_IMPL_CLASSES, GOOGLE_CLASSES); + } + +} diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AwsIT.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AwsIT.java index da1db0a268..8cdaffdc72 100644 --- a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AwsIT.java +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/AwsIT.java @@ -1,15 +1,13 @@ package net.officefloor.maven.cloud; /** - * Tests no cloud configured. + * Tests AWS configured. * * @author Daniel Sagenschneider */ public class AwsIT extends AbstractCloudShadeMojoTestCase { public AwsIT() { - SHADE.required(OFFICEFLOOR_CLASSES, WOOF_CLASSES, CABINET_CLASSES); - SHADE.notIncluded(CABINET_IMPL_CLASSES); AWS.isCreate = true; AWS.required(OFFICEFLOOR_CLASSES, WOOF_CLASSES, CABINET_CLASSES, CABINET_IMPL_CLASSES, AWS_CLASSES); GOOGLE.isCreate = false; diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/CloudIT.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/CloudIT.java index e26a86c0fe..36ae62b65e 100644 --- a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/CloudIT.java +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/CloudIT.java @@ -8,8 +8,6 @@ public class CloudIT extends AbstractCloudShadeMojoTestCase { public CloudIT() { - SHADE.required(OFFICEFLOOR_CLASSES, WOOF_CLASSES, CABINET_CLASSES); - SHADE.notIncluded(CABINET_IMPL_CLASSES); AWS.isCreate = false; GOOGLE.isCreate = false; } diff --git a/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/GoogleIT.java b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/GoogleIT.java new file mode 100644 index 0000000000..c71aa7bcc0 --- /dev/null +++ b/officefloor/maven/officefloor-cloud-maven-plugin/src/test/java/net/officefloor/maven/cloud/GoogleIT.java @@ -0,0 +1,16 @@ +package net.officefloor.maven.cloud; + +/** + * Tests Google configured. + * + * @author Daniel Sagenschneider + */ +public class GoogleIT extends AbstractCloudShadeMojoTestCase { + + public GoogleIT() { + AWS.isCreate = false; + GOOGLE.isCreate = true; + GOOGLE.required(OFFICEFLOOR_CLASSES, WOOF_CLASSES, CABINET_CLASSES, CABINET_IMPL_CLASSES, GOOGLE_CLASSES); + } + +} From 49e1a92a58e5e8b9b04c3c6ae574e54c977aea36 Mon Sep 17 00:00:00 2001 From: Daniel Sagenschneider Date: Fri, 5 Jul 2024 08:20:02 +0800 Subject: [PATCH 6/9] Fixing for eclipse plugins to build in Eclipse --- officefloor/pom.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/officefloor/pom.xml b/officefloor/pom.xml index 7cd76983b0..b25660575a 100644 --- a/officefloor/pom.xml +++ b/officefloor/pom.xml @@ -599,6 +599,11 @@ tycho-maven-plugin ${tycho-version} + + org.eclipse.tycho + tycho-packaging-plugin + ${tycho-version} + org.eclipse.tycho target-platform-configuration @@ -790,6 +795,23 @@ + + + org.eclipse.tycho + tycho-packaging-plugin + + [1.3.41,) + + + build-qualifier + validate-id + validate-version + + + + + + From 30eabe776d6bb9707427f76d28448a257d20f57c Mon Sep 17 00:00:00 2001 From: Daniel Sagenschneider Date: Mon, 8 Jul 2024 09:46:51 +0800 Subject: [PATCH 7/9] Able to run Eclipse in Mac for cloud deployment configuration --- .../META-INF/MANIFEST.MF | 2 +- .../parts/OfficeFloorContentPartFactory.java | 2 +- officefloor/editor/pom.xml | 57 ++++++++++++++++++- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/officefloor/editor/net.officefloor.gef.editor/META-INF/MANIFEST.MF b/officefloor/editor/net.officefloor.gef.editor/META-INF/MANIFEST.MF index 6d68e65758..2a4c4a8d39 100644 --- a/officefloor/editor/net.officefloor.gef.editor/META-INF/MANIFEST.MF +++ b/officefloor/editor/net.officefloor.gef.editor/META-INF/MANIFEST.MF @@ -12,7 +12,7 @@ Import-Package: com.google.common.collect, com.google.inject, com.google.inject.binder;version="1.3.0", com.google.inject.multibindings, - javax.inject, + jakarta.inject;version="[2.0.0,3.0.0)", org.eclipse.core.commands, org.eclipse.core.commands.operations, org.eclipse.core.runtime, diff --git a/officefloor/editor/net.officefloor.gef.editor/src/main/java/net/officefloor/gef/editor/internal/parts/OfficeFloorContentPartFactory.java b/officefloor/editor/net.officefloor.gef.editor/src/main/java/net/officefloor/gef/editor/internal/parts/OfficeFloorContentPartFactory.java index 67668ec3b6..ccffb5bd90 100644 --- a/officefloor/editor/net.officefloor.gef.editor/src/main/java/net/officefloor/gef/editor/internal/parts/OfficeFloorContentPartFactory.java +++ b/officefloor/editor/net.officefloor.gef.editor/src/main/java/net/officefloor/gef/editor/internal/parts/OfficeFloorContentPartFactory.java @@ -32,7 +32,7 @@ import java.util.function.Consumer; import java.util.function.Function; -import javax.inject.Singleton; +import jakarta.inject.Singleton; import org.eclipse.gef.geometry.planar.Point; import org.eclipse.gef.mvc.fx.models.GridModel; diff --git a/officefloor/editor/pom.xml b/officefloor/editor/pom.xml index 5909231b34..33db778658 100644 --- a/officefloor/editor/pom.xml +++ b/officefloor/editor/pom.xml @@ -47,8 +47,8 @@ maven-dependency-plugin - - Provide linked dependencies for eclipse PDE projects + + Provide linked dependencies for eclipse PDE projects prepare-package copy-dependencies @@ -135,10 +135,61 @@ - 2023-06.target + 2024-06.target true + + + + org.eclipse.tycho + target-platform-configuration + + + + net.officefloor.editor + net.officefloor.gef.target + ${project.version} + 2024-06 + + + + require + + + + linux + gtk + x86_64 + + + linux + gtk + aarch64 + + + win32 + win32 + x86_64 + + + macosx + cocoa + x86_64 + + + macosx + cocoa + aarch64 + + + + + + + + + 2023-06.target From 044d9873f2f6d8e78b234f15afc42cc7e9231777 Mon Sep 17 00:00:00 2001 From: Daniel Sagenschneider Date: Mon, 8 Jul 2024 09:47:14 +0800 Subject: [PATCH 8/9] Including latest Eclipse configuration --- .../net.officefloor.gef.target/2024-06.target | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 officefloor/editor/net.officefloor.gef.target/2024-06.target diff --git a/officefloor/editor/net.officefloor.gef.target/2024-06.target b/officefloor/editor/net.officefloor.gef.target/2024-06.target new file mode 100644 index 0000000000..896d4ab014 --- /dev/null +++ b/officefloor/editor/net.officefloor.gef.target/2024-06.target @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file From 019202d6c4dabfd308d44638dd30a07475f9dd3d Mon Sep 17 00:00:00 2001 From: Daniel Sagenschneider Date: Tue, 9 Jul 2024 09:15:12 +0800 Subject: [PATCH 9/9] Fixing build to using latest Eclipse --- .../net.officefloor.feature/feature.xml | 39 ++------ .../net.officefloor.gef.target/2020-12.target | 16 ---- .../net.officefloor.gef.target/2023-06.target | 16 ---- .../editor/net.officefloor.gef.target/pom.xml | 37 +------- officefloor/editor/pom.xml | 92 ------------------- 5 files changed, 11 insertions(+), 189 deletions(-) delete mode 100644 officefloor/editor/net.officefloor.gef.target/2020-12.target delete mode 100644 officefloor/editor/net.officefloor.gef.target/2023-06.target diff --git a/officefloor/editor/eclipse/net.officefloor.feature/feature.xml b/officefloor/editor/eclipse/net.officefloor.feature/feature.xml index 18528a1899..e9d6bfed62 100644 --- a/officefloor/editor/eclipse/net.officefloor.feature/feature.xml +++ b/officefloor/editor/eclipse/net.officefloor.feature/feature.xml @@ -29,7 +29,6 @@ - @@ -55,61 +54,39 @@ + + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> + version="0.0.0"/> diff --git a/officefloor/editor/net.officefloor.gef.target/2020-12.target b/officefloor/editor/net.officefloor.gef.target/2020-12.target deleted file mode 100644 index 7e9f2546a3..0000000000 --- a/officefloor/editor/net.officefloor.gef.target/2020-12.target +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/officefloor/editor/net.officefloor.gef.target/2023-06.target b/officefloor/editor/net.officefloor.gef.target/2023-06.target deleted file mode 100644 index 982439b87c..0000000000 --- a/officefloor/editor/net.officefloor.gef.target/2023-06.target +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/officefloor/editor/net.officefloor.gef.target/pom.xml b/officefloor/editor/net.officefloor.gef.target/pom.xml index 4fc8fc94e0..f8eab81029 100644 --- a/officefloor/editor/net.officefloor.gef.target/pom.xml +++ b/officefloor/editor/net.officefloor.gef.target/pom.xml @@ -15,7 +15,7 @@ pom - 2023-06.target + 2024-06.target true @@ -36,40 +36,9 @@ - 2023-06.target + 2024-06.target target - 2023-06 - - - - - - - - - - - 2020-12.target - - - - org.codehaus.mojo - build-helper-maven-plugin - - - - attach-artifacts - package - - attach-artifact - - - - - - 2020-12.target - target - 2020-12 + 2024-06 diff --git a/officefloor/editor/pom.xml b/officefloor/editor/pom.xml index 33db778658..882f6f5f80 100644 --- a/officefloor/editor/pom.xml +++ b/officefloor/editor/pom.xml @@ -188,97 +188,5 @@ - - 2023-06.target - - - - org.eclipse.tycho - target-platform-configuration - - - - net.officefloor.editor - net.officefloor.gef.target - ${project.version} - 2023-06 - - - - require - - - - linux - gtk - x86_64 - - - win32 - win32 - x86_64 - - - macosx - cocoa - x86_64 - - - - - - - - - 2020-12.target - - - - org.eclipse.tycho - target-platform-configuration - - - - net.officefloor.editor - net.officefloor.gef.target - ${project.version} - 2020-12 - - - - require - - - - linux - gtk - x86 - - - linux - gtk - x86_64 - - - win32 - win32 - x86 - - - win32 - win32 - x86_64 - - - macosx - cocoa - x86_64 - - - - - - -