diff --git a/.github/workflows/cloud_code_scan.yml b/.github/workflows/cloud_code_scan.yml new file mode 100644 index 000000000..9a6da4aec --- /dev/null +++ b/.github/workflows/cloud_code_scan.yml @@ -0,0 +1,22 @@ +name: Alipay Cloud Devops Codescan +on: + pull_request_target: +jobs: + stc: # Code security scanning + runs-on: ubuntu-latest + steps: + - name: codeScan + uses: layotto/alipay-cloud-devops-codescan@main + with: + parent_uid: ${{ secrets.ALI_PID }} + private_key: ${{ secrets.ALI_PK }} + scan_type: stc + sca: # Open source compliance scanning + runs-on: ubuntu-latest + steps: + - name: codeScan + uses: layotto/alipay-cloud-devops-codescan@main + with: + parent_uid: ${{ secrets.ALI_PID }} + private_key: ${{ secrets.ALI_PK }} + scan_type: sca diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml deleted file mode 100644 index e89a375db..000000000 --- a/.github/workflows/codecov.yml +++ /dev/null @@ -1,53 +0,0 @@ -- name: Codecov - # You may pin to the exact commit or the version. - # uses: codecov/codecov-action@f32b3a3741e1053eb607407145bc9619351dc93b - uses: codecov/codecov-action@v4.0.0-beta.3 - with: - # Repository upload token - get it from codecov.io. Required only for private repositories - token: # optional - # Comma-separated list of files to upload - files: # optional - # Directory to search for coverage reports. - directory: # optional - # Flag upload to group coverage metrics (e.g. unittests | integration | ui,chrome) - flags: # optional - # The commit SHA of the parent for which you are uploading coverage. If not present, the parent will be determined using the API of your repository provider. When using the repository providers API, the parent is determined via finding the closest ancestor to the commit. - commit_parent: # optional - # Don't upload files to Codecov - dry_run: # optional - # Environment variables to tag the upload with (e.g. PYTHON | OS,PYTHON) - env_vars: # optional - # Specify whether or not CI build should fail if Codecov runs into an error during upload - fail_ci_if_error: # optional - # Path to coverage file to upload - file: # optional - # Comma-separated list, see the README for options and their usage - functionalities: # optional - # Move discovered coverage reports to the trash - move_coverage_to_trash: # optional - # User defined upload name. Visible in Codecov UI - name: # optional - # Specify the branch name - override_branch: # optional - # Specify the build number - override_build: # optional - # Specify the commit SHA - override_commit: # optional - # Specify the pull request number - override_pr: # optional - # Specify the git tag - override_tag: # optional - # Override the assumed OS. Options are alpine | linux | macos | windows. - os: # optional - # Used when not in git/hg project to identify project root directory - root_dir: # optional - # Specify the slug manually (Enterprise use) - slug: # optional - # Change the upload host (Enterprise use) - url: # optional - # Specify whether the Codecov output should be verbose - verbose: # optional - # Specify which version of the Codecov Uploader should be used. Defaults to `latest` - version: # optional - # Directory in which to execute codecov.sh - working-directory: # optional diff --git a/.github/workflows/inactive_issues_robot.yml b/.github/workflows/inactive_issues_robot.yml index f3714e995..bae95abcd 100644 --- a/.github/workflows/inactive_issues_robot.yml +++ b/.github/workflows/inactive_issues_robot.yml @@ -31,6 +31,6 @@ jobs: activity in the last 37 days. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! stale-issue-label: 'stale' - exempt-issue-labels: 'pinned,good first issue,help wanted' + exempt-issue-labels: 'pinned,good first issue,help wanted,backlog' stale-pr-label: 'stale' exempt-pr-labels: 'pinned' diff --git a/.github/workflows/linux_unit_test.yml b/.github/workflows/linux_unit_test.yml index 8a519abad..678f9c6d7 100644 --- a/.github/workflows/linux_unit_test.yml +++ b/.github/workflows/linux_unit_test.yml @@ -5,9 +5,9 @@ name: Test for linux on: push: - branches: [ master ] + branches: [ springboot3-master ] pull_request: - branches: [ master ] + branches: [ springboot3-master ] jobs: unit_test_for_jdk17: @@ -27,4 +27,4 @@ jobs: && sh ./check_format.sh && mvn test -DargLine="-Djdk.util.zip.disableZip64ExtraFieldValidation=true" - name: Codecov - uses: codecov/codecov-action@v4.0.0-beta.3 \ No newline at end of file + uses: codecov/codecov-action@v3.1.4 diff --git a/.github/workflows/windows_unit_test.yml b/.github/workflows/windows_unit_test.yml index 4493f99e3..bcfe088c4 100644 --- a/.github/workflows/windows_unit_test.yml +++ b/.github/workflows/windows_unit_test.yml @@ -10,9 +10,9 @@ name: Test for windows on: push: - branches: [ "master" ] + branches: [ springboot3-master ] pull_request: - branches: [ "master" ] + branches: [ springboot3-master ] jobs: unit_test_for_jdk17: @@ -32,4 +32,4 @@ jobs: && sh ./check_format.sh && mvn test -DargLine="-Djdk.util.zip.disableZip64ExtraFieldValidation=true" - name: Codecov - uses: codecov/codecov-action@v4.0.0-beta.3 \ No newline at end of file + uses: codecov/codecov-action@v3.1.4 diff --git a/.gitignore b/.gitignore index 1ce3e2b5e..d89490567 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ sofa-ark-parent/support/ark-plugin-maven-plugin/com/alipay/sofa/ark/plugin/mark sofa-ark-parent/support/ark-plugin-maven-plugin/null.ark.plugin sofa-ark-parent/support/ark-plugin-maven-plugin/null.ark.plugin.bak sofa-ark-parent/support/ark-plugin-maven-plugin/xxx.ark.plugin +sofa-ark-parent/core/common/C/\temp dir\b\c/test.txt diff --git a/pom.xml b/pom.xml index 532a817fa..4262dadba 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,7 @@ sofa-ark-parent sofa-ark-plugin/config-ark-plugin sofa-ark-plugin/web-ark-plugin + sofa-ark-plugin/netty-ark-plugin @@ -22,10 +23,10 @@ 0.4 3.1 3.0.0 - 3.2.0 + 3.6.2 1.6.13 1.6 - 0.8.4 + 0.8.11 1.5.0 @@ -174,6 +175,7 @@ UTF-8 UTF-8 UTF-8 + none diff --git a/sofa-ark-bom/pom.xml b/sofa-ark-bom/pom.xml index 5ed1278a3..a74c8e8dc 100644 --- a/sofa-ark-bom/pom.xml +++ b/sofa-ark-bom/pom.xml @@ -13,11 +13,12 @@ pom - 2.0.7 - 3.2.0 - 1.2.9 + 2.0.11 + 3.9.1 + 2.0.3 + 1.4.14 - 5.1.0 + 6.0.0 9.4 2.7 3.3.1 @@ -46,7 +47,7 @@ 2.4 3.6.1 2.22.2 - 4.1.90.Final + 4.1.94.Final 3.0.9 @@ -190,9 +191,9 @@ - com.google.inject.extensions - guice-multibindings - 4.2.3 + com.google.guava + guava + 32.1.3-jre @@ -249,6 +250,11 @@ + + com.alipay.sofa.common + sofa-common-tools + ${sofa.common.tools.version} + diff --git a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/bootstrap/BaseExecutableArchiveLauncher.java b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/bootstrap/BaseExecutableArchiveLauncher.java index 08fd4b186..045dd663c 100644 --- a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/bootstrap/BaseExecutableArchiveLauncher.java +++ b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/bootstrap/BaseExecutableArchiveLauncher.java @@ -16,6 +16,7 @@ */ package com.alipay.sofa.ark.bootstrap; +import com.alipay.sofa.ark.common.util.FileUtils; import com.alipay.sofa.ark.loader.ExecutableArkBizJar; import com.alipay.sofa.ark.loader.archive.ExplodedArchive; import com.alipay.sofa.ark.loader.archive.JarFileArchive; @@ -66,7 +67,7 @@ protected ExecutableArchive createArchive() throws Exception { if (path == null) { throw new IllegalStateException("Unable to determine code source archive"); } - File root = new File(path); + File root = FileUtils.file(path); if (!root.exists()) { throw new IllegalStateException("Unable to determine code source archive from " + root); } diff --git a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/bootstrap/ClasspathLauncher.java b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/bootstrap/ClasspathLauncher.java index 93b642c23..50540a5ce 100644 --- a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/bootstrap/ClasspathLauncher.java +++ b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/bootstrap/ClasspathLauncher.java @@ -16,10 +16,7 @@ */ package com.alipay.sofa.ark.bootstrap; -import com.alipay.sofa.ark.common.util.AssertUtils; -import com.alipay.sofa.ark.common.util.ClassLoaderUtils; -import com.alipay.sofa.ark.common.util.ClassUtils; -import com.alipay.sofa.ark.common.util.StringUtils; +import com.alipay.sofa.ark.common.util.*; import com.alipay.sofa.ark.exception.ArkRuntimeException; import com.alipay.sofa.ark.loader.*; import com.alipay.sofa.ark.loader.archive.JarFileArchive; @@ -115,7 +112,8 @@ protected ContainerArchive getJarContainerArchive() throws Exception { throw new ArkRuntimeException("Duplicate Container Jar File Found."); } - return new JarContainerArchive(new JarFileArchive(new File(urlList.get(0).getFile()))); + return new JarContainerArchive(new JarFileArchive(FileUtils.file(urlList.get(0) + .getFile()))); } @Override @@ -128,7 +126,8 @@ public List getBizArchives() throws Exception { } for (URL url : urlList) { - bizArchives.add(new JarBizArchive(new JarFileArchive(new File(url.getFile())))); + bizArchives + .add(new JarBizArchive(new JarFileArchive(FileUtils.file(url.getFile())))); } return bizArchives; @@ -140,8 +139,8 @@ public List getPluginArchives() throws Exception { List pluginArchives = new ArrayList<>(); for (URL url : urlList) { - pluginArchives - .add(new JarPluginArchive(new JarFileArchive(new File(url.getFile())))); + pluginArchives.add(new JarPluginArchive(new JarFileArchive(FileUtils.file(url + .getFile())))); } return pluginArchives; @@ -177,9 +176,10 @@ private File deduceArkConfBaseDir() { if (classLocation.startsWith("file:")) { classLocation = classLocation.substring("file:".length()); } - File file = classLocation == null ? null : new File(classLocation); + File file = classLocation == null ? null : FileUtils.file(classLocation); while (file != null) { - arkConfDir = new File(file.getPath() + File.separator + ARK_CONF_BASE_DIR); + arkConfDir = FileUtils + .file(file.getPath() + File.separator + ARK_CONF_BASE_DIR); if (arkConfDir.exists() && arkConfDir.isDirectory()) { break; } diff --git a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/DirectoryContainerArchive.java b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/DirectoryContainerArchive.java index 785c03351..1b7818c60 100644 --- a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/DirectoryContainerArchive.java +++ b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/DirectoryContainerArchive.java @@ -41,11 +41,12 @@ public class DirectoryContainerArchive implements ContainerArchive { private final URL[] urls; private final static String[] AKR_CONTAINER_JAR = { "aopalliance-1.0", "commons-io-2.7", - "guava-30.1-jre", "guice-5.1.0", "guice-multibindings-4.2.3", "failureaccess-1.0.1", - "javax.inject-1", "logback-core-1.3.5", "logback-classic-1.3.5", "slf4j-api-2.0.7", - "sofa-common-tools", "netty-all-4.1.90.Final", "netty-transport-4.1.90.Final", - "netty-common-4.1.90.Final", "netty-handler-4.1.90.Final", "netty-codec-4.1.90.Final", - "netty-buffer-4.1.90.Final", "sofa-ark-parent/core-impl/container/target/classes", + "guava-32.1.3-jre", "guice-6.0.0", "failureaccess-1.0.1", "javax.inject-1", + "jakarta.inject-api-2.0.1", "logback-core-1.4.14", "logback-classic-1.4.14", + "slf4j-api-2.0.11", "sofa-common-tools", "netty-all-4.1.94.Final", + "netty-transport-4.1.94.Final", "netty-common-4.1.94.Final", + "netty-handler-4.1.94.Final", "netty-codec-4.1.94.Final", "netty-buffer-4.1.94.Final", + "sofa-ark-parent/core-impl/container/target/classes", "sofa-ark-parent/core-impl/archive/target/classes", "sofa-ark-parent/core/spi/target/classes", "sofa-ark-parent/core/common/target/classes", @@ -94,4 +95,4 @@ public InputStream getInputStream(ZipEntry zipEntry) { public Iterator iterator() { throw new RuntimeException("unreachable invocation."); } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/EmbedClassPathArchive.java b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/EmbedClassPathArchive.java index 45577856c..8fcd2b4fb 100644 --- a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/EmbedClassPathArchive.java +++ b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/EmbedClassPathArchive.java @@ -17,6 +17,7 @@ package com.alipay.sofa.ark.loader; import com.alipay.sofa.ark.bootstrap.ClasspathLauncher; +import com.alipay.sofa.ark.common.util.FileUtils; import com.alipay.sofa.ark.exception.ArkRuntimeException; import com.alipay.sofa.ark.loader.archive.JarFileArchive; import com.alipay.sofa.ark.spi.archive.Archive; @@ -73,7 +74,8 @@ public List getBizArchives() throws Exception { } } else { - bizArchives.add(new JarBizArchive(new JarFileArchive(new File(url.getFile())))); + bizArchives + .add(new JarBizArchive(new JarFileArchive(FileUtils.file(url.getFile())))); } } return bizArchives; @@ -88,7 +90,7 @@ public List getBizArchives() throws Exception { private Archive getArchiveFromJarEntry(URL jarUrl) throws IOException { String jarPath = jarUrl.getPath().substring(0, jarUrl.getPath().indexOf("!")); String bizPath = jarUrl.getPath().substring(jarUrl.getPath().indexOf("!") + 2); - List nestedArchives = new JarFileArchive(new File(jarPath)) + List nestedArchives = new JarFileArchive(FileUtils.file(jarPath)) .getNestedArchives(entry -> entry.getName().equals(bizPath)); if (nestedArchives.isEmpty()) { return null; @@ -127,13 +129,13 @@ protected JarFileArchive getUrlJarFileArchive(URL url) throws IOException { String file = url.getFile(); if (file.contains(FILE_IN_JAR)) { int pos = file.indexOf(FILE_IN_JAR); - File fatJarFile = new File(file.substring(0, pos)); + File fatJarFile = FileUtils.file(file.substring(0, pos)); String nestedJar = file.substring(file.lastIndexOf("/") + 1); JarFileArchive fatJarFileArchive = new JarFileArchive(fatJarFile); List matched = fatJarFileArchive.getNestedArchives(entry -> entry.getName().contains(nestedJar)); return (JarFileArchive) matched.get(0); } else { - return new JarFileArchive(new File(file)); + return new JarFileArchive(FileUtils.file(file)); } } } diff --git a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/archive/JarFileArchive.java b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/archive/JarFileArchive.java index 153dcf089..ed076ff9e 100644 --- a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/archive/JarFileArchive.java +++ b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/archive/JarFileArchive.java @@ -24,6 +24,7 @@ import java.util.jar.Manifest; import java.util.zip.ZipEntry; +import com.alipay.sofa.ark.common.util.FileUtils; import com.alipay.sofa.ark.loader.jar.JarFile; import com.alipay.sofa.ark.loader.data.RandomAccessData.ResourceAccess; import com.alipay.sofa.ark.spi.archive.Archive; @@ -125,7 +126,7 @@ private Archive getUnpackedNestedArchive(JarEntry jarEntry) throws IOException { private File getTempUnpackFolder() { if (this.tempUnpackFolder == null) { - File tempFolder = new File(System.getProperty("java.io.tmpdir")); + File tempFolder = FileUtils.file(System.getProperty("java.io.tmpdir")); this.tempUnpackFolder = createUnpackFolder(tempFolder); } return this.tempUnpackFolder; @@ -134,7 +135,7 @@ private File getTempUnpackFolder() { private File createUnpackFolder(File parent) { int attempts = 0; while (attempts++ < 1000) { - String fileName = new File(this.jarFile.getName()).getName(); + String fileName = FileUtils.file(this.jarFile.getName()).getName(); File unpackFolder = new File(parent, fileName + "-spring-boot-libs-" + UUID.randomUUID()); if (unpackFolder.mkdirs()) { diff --git a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/jar/Handler.java b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/jar/Handler.java index 5843691dc..09866e1a0 100644 --- a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/jar/Handler.java +++ b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/jar/Handler.java @@ -16,6 +16,7 @@ */ package com.alipay.sofa.ark.loader.jar; +import com.alipay.sofa.ark.common.util.FileUtils; import com.alipay.sofa.ark.common.util.StringUtils; import java.io.File; @@ -201,7 +202,7 @@ private String normalize(String file) { .append(file.substring(0, afterLastSeparatorIndex)).append(afterSeparator).toString(); } - private String replaceParentDir(String file) { + String replaceParentDir(String file) { int parentDirIndex; while ((parentDirIndex = file.indexOf("/../")) >= 0) { int precedingSlashIndex = file.lastIndexOf('/', parentDirIndex - 1); @@ -289,7 +290,7 @@ private JarFile getRootJarFile(String name) throws IOException { throw new IllegalStateException("Not a file URL"); } String path = name.substring(FILE_PROTOCOL.length()); - File file = new File(URLDecoder.decode(path, "UTF-8")); + File file = FileUtils.file(path); Map cache = rootFileCache.get(); JarFile result = (cache == null ? null : cache.get(file)); if (result == null) { diff --git a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/jar/JarUtils.java b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/jar/JarUtils.java index 3379f6068..93c0491da 100644 --- a/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/jar/JarUtils.java +++ b/sofa-ark-parent/core-impl/archive/src/main/java/com/alipay/sofa/ark/loader/jar/JarUtils.java @@ -16,6 +16,7 @@ */ package com.alipay.sofa.ark.loader.jar; +import com.alipay.sofa.ark.common.util.FileUtils; import com.alipay.sofa.ark.common.util.StringUtils; import com.alipay.sofa.ark.loader.archive.JarFileArchive; import com.alipay.sofa.ark.spi.archive.Archive; @@ -61,7 +62,7 @@ public class JarUtils { private static final Map> artifactIdCacheMap = new ConcurrentHashMap<>(); - private static File searchPomProperties(File dirOrFile) { + static File searchPomProperties(File dirOrFile) { if (dirOrFile == null || !dirOrFile.exists()) { return null; } @@ -83,8 +84,8 @@ private static File searchPomProperties(File dirOrFile) { return null; } - private static String getArtifactIdFromLocalClassPath(String fileClassPath) { - // file:/Users/youji.zzl/Documents/workspace/iexpprodbase/app/bootstrap/target/classes/spring/ + static String getArtifactIdFromLocalClassPath(String fileClassPath) { + String libraryFile = fileClassPath.replace("file:", ""); // 1. search pom.properties int classesRootIndex = libraryFile.endsWith(CLASSPATH_ROOT_IDENTITY) ? libraryFile @@ -107,7 +108,7 @@ private static String getArtifactIdFromLocalClassPath(String fileClassPath) { } else { // is not from test classpath, for example install uncompressed modules, just return null // search for pom.properties - File pomPropertiesFile = searchPomProperties(new File(libraryFile)); + File pomPropertiesFile = searchPomProperties(FileUtils.file(libraryFile)); if (pomPropertiesFile != null && pomPropertiesFile.exists()) { pomPropertiesPath = pomPropertiesFile.getAbsolutePath(); } else { @@ -118,7 +119,7 @@ private static String getArtifactIdFromLocalClassPath(String fileClassPath) { String artifactId = null; if (!StringUtils.isEmpty(pomPropertiesPath)) { - try (InputStream inputStream = Files.newInputStream(new File(pomPropertiesPath) + try (InputStream inputStream = Files.newInputStream(FileUtils.file(pomPropertiesPath) .toPath())) { Properties properties = new Properties(); properties.load(inputStream); @@ -227,7 +228,7 @@ private static String doGetArtifactIdFromFileName(String jarLocation) { private static String parseArtifactIdFromJarInJar(String jarLocation) throws IOException { String rootPath = jarLocation.substring(0, jarLocation.lastIndexOf(JAR_SEPARATOR)); String subNestedPath = jarLocation.substring(jarLocation.lastIndexOf(JAR_SEPARATOR) + 2); - com.alipay.sofa.ark.loader.jar.JarFile jarFile = new com.alipay.sofa.ark.loader.jar.JarFile(new File(rootPath)); + com.alipay.sofa.ark.loader.jar.JarFile jarFile = new com.alipay.sofa.ark.loader.jar.JarFile(FileUtils.file(rootPath)); JarFileArchive jarFileArchive = new JarFileArchive(jarFile); List archives = jarFileArchive.getNestedArchives(entry -> !StringUtils.isEmpty(entry.getName()) && entry.getName().equals(subNestedPath)); @@ -241,20 +242,20 @@ private static String parseArtifactIdFromJarInJar(String jarLocation) throws IOE private static String parseArtifactIdFromJarInJarInJarMore(String jarLocation) throws IOException { - com.alipay.sofa.ark.loader.jar.JarFile jarFile = getTemporaryRootJarFromJarLocation(jarLocation); + com.alipay.sofa.ark.loader.jar.JarFile jarFile = getNestedRootJarFromJarLocation(jarLocation); JarFileArchive jarFileArchive = new JarFileArchive(jarFile); return jarFileArchive.getPomProperties().getProperty(JAR_ARTIFACT_ID); } - public static com.alipay.sofa.ark.loader.jar.JarFile getTemporaryRootJarFromJarLocation(String jarLocation) - throws IOException { + public static com.alipay.sofa.ark.loader.jar.JarFile getNestedRootJarFromJarLocation(String jarLocation) + throws IOException { // /xxx/xxx/xxx-starter-1.0.0-SNAPSHOT.jar!/BOOT-INF/lib/xxx2-starter-1.1.4-SNAPSHOT-ark-biz.jar!/lib/xxx3-230605-sofa.jar String[] js = jarLocation.split(JAR_SEPARATOR, -1); com.alipay.sofa.ark.loader.jar.JarFile rJarFile = new com.alipay.sofa.ark.loader.jar.JarFile( - new File(js[0])); + FileUtils.file(js[0])); for (int i = 1; i < js.length; i++) { String jPath = js[i]; - if (jPath == null || jPath.isEmpty()) { + if (StringUtils.isEmpty(jPath) || !jPath.endsWith(".jar")) { break; } try { @@ -269,7 +270,7 @@ public static com.alipay.sofa.ark.loader.jar.JarFile getTemporaryRootJarFromJarL } private static String parseArtifactIdFromJar(String jarLocation) throws IOException { - jarLocation = URLDecoder.decode(jarLocation, "UTF-8"); + jarLocation = FileUtils.decodePath(jarLocation); try (JarFile jarFile = new JarFile(jarLocation)) { Enumeration entries = jarFile.entries(); while (entries.hasMoreElements()) { diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/bootstrap/ArkLauncherTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/bootstrap/ArkLauncherTest.java index 4b99d4bd6..9eb28ef34 100644 --- a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/bootstrap/ArkLauncherTest.java +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/bootstrap/ArkLauncherTest.java @@ -21,7 +21,6 @@ import com.alipay.sofa.ark.loader.archive.JarFileArchive; import com.alipay.sofa.ark.spi.archive.Archive; import org.junit.AfterClass; -import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.MockedStatic; @@ -35,6 +34,9 @@ import java.util.Arrays; import java.util.List; +import static com.alipay.sofa.ark.bootstrap.ArkLauncher.main; +import static org.junit.Assert.*; +import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.when; /** @@ -46,7 +48,8 @@ public class ArkLauncherTest { static MockedStatic managementFactoryMockedStatic; @BeforeClass - public static void setup(){ + public static void setup() { + List mockArguments = new ArrayList<>(); String filePath = ClasspathLauncherTest.class.getClassLoader() .getResource("SampleClass.class").getPath(); @@ -56,9 +59,8 @@ public static void setup(){ RuntimeMXBean runtimeMXBean = Mockito.mock(RuntimeMXBean.class); when(runtimeMXBean.getInputArguments()).thenReturn(mockArguments); - managementFactoryMockedStatic = Mockito.mockStatic(ManagementFactory.class); + managementFactoryMockedStatic = mockStatic(ManagementFactory.class); managementFactoryMockedStatic.when(ManagementFactory::getRuntimeMXBean).thenReturn(runtimeMXBean); - } @AfterClass @@ -68,9 +70,10 @@ public static void tearDown() { @Test public void testContainerClassLoader() throws Exception { + URL url = this.getClass().getClassLoader().getResource("sample-springboot-fat-biz.jar"); URL[] agentUrl = ClassLoaderUtils.getAgentClassPath(); - Assert.assertEquals(1, agentUrl.length); + assertEquals(1, agentUrl.length); List urls = new ArrayList<>(); JarFileArchive jarFileArchive = new JarFileArchive(new File(url.getFile())); @@ -80,25 +83,31 @@ public void testContainerClassLoader() throws Exception { } urls.addAll(Arrays.asList(agentUrl)); - EmbedClassPathArchive classPathArchive = new EmbedClassPathArchive( - this.getClass().getCanonicalName(), null, urls.toArray(new URL[] {})); + this.getClass().getCanonicalName(), null, urls.toArray(new URL[]{})); ArkLauncher arkLauncher = new ArkLauncher(classPathArchive); ClassLoader classLoader = arkLauncher.createContainerClassLoader(classPathArchive.getContainerArchive()); - Assert.assertNotNull(classLoader); + assertNotNull(classLoader); + try { Class clazz = classLoader.loadClass("com.alipay.sofa.ark.bootstrap.ArkLauncher"); - Assert.assertNotNull(clazz); + assertNotNull(clazz); clazz = classLoader.loadClass("SampleClass"); - Assert.assertNotNull(clazz); - } catch (Exception e){ - Assert.assertTrue("loadClass class failed ",false); + assertNotNull(clazz); + } catch (Exception e) { + assertTrue("loadClass class failed ", false); } - Assert.assertThrows(ClassNotFoundException.class, () -> classLoader.loadClass("NotExistClass")); + + assertThrows(ClassNotFoundException.class, () -> classLoader.loadClass("NotExistClass")); } protected boolean isNestedArchive(Archive.Entry entry) { return entry.isDirectory() ? entry.getName().equals("BOOT-INF/classes/") : entry.getName() .startsWith("BOOT-INF/lib/"); } -} \ No newline at end of file + + @Test(expected = Exception.class) + public void testMain() throws Exception { + main(null); + } +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/bootstrap/ClasspathLauncherTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/bootstrap/ClasspathLauncherTest.java index 984b90886..b62fd1d8c 100644 --- a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/bootstrap/ClasspathLauncherTest.java +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/bootstrap/ClasspathLauncherTest.java @@ -16,19 +16,20 @@ */ package com.alipay.sofa.ark.bootstrap; +import com.alipay.sofa.ark.bootstrap.ClasspathLauncher.ClassPathArchive; import com.alipay.sofa.ark.common.util.ClassLoaderUtils; +import com.alipay.sofa.ark.common.util.FileUtils; +import com.alipay.sofa.ark.loader.DirectoryBizArchive; import com.alipay.sofa.ark.loader.EmbedClassPathArchive; import com.alipay.sofa.ark.loader.archive.JarFileArchive; import com.alipay.sofa.ark.spi.archive.Archive; import com.alipay.sofa.ark.spi.archive.BizArchive; import org.junit.AfterClass; -import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.MockedStatic; import org.mockito.Mockito; -import java.io.File; import java.io.IOException; import java.lang.management.ManagementFactory; import java.lang.management.RuntimeMXBean; @@ -38,6 +39,8 @@ import java.util.Arrays; import java.util.List; +import static com.alipay.sofa.ark.common.util.ClassLoaderUtils.getAgentClassPath; +import static org.junit.Assert.*; import static org.mockito.Mockito.when; /** @@ -45,22 +48,22 @@ * @since 0.6.0 */ public class ClasspathLauncherTest { + static MockedStatic managementFactoryMockedStatic; @BeforeClass - public static void setup(){ + public static void setup() { + List mockArguments = new ArrayList<>(); String filePath = ClasspathLauncherTest.class.getClassLoader() - .getResource("SampleClass.class").getPath(); - String workingPath = new File(filePath).getParent(); + .getResource("SampleClass.class").getPath(); + String workingPath = FileUtils.file(filePath).getParent(); mockArguments.add(String.format("-javaagent:%s", workingPath)); RuntimeMXBean runtimeMXBean = Mockito.mock(RuntimeMXBean.class); when(runtimeMXBean.getInputArguments()).thenReturn(mockArguments); - managementFactoryMockedStatic = Mockito.mockStatic(ManagementFactory.class); managementFactoryMockedStatic.when(ManagementFactory::getRuntimeMXBean).thenReturn(runtimeMXBean); - } @AfterClass @@ -70,50 +73,52 @@ public static void tearDown() { @Test public void testFilterAgentClasspath() throws Exception { + URL url = this.getClass().getClassLoader().getResource("sample-biz.jar"); - URL[] agentUrl = ClassLoaderUtils.getAgentClassPath(); - Assert.assertEquals(1, agentUrl.length); + URL[] agentUrl = getAgentClassPath(); + assertEquals(1, agentUrl.length); List urls = new ArrayList<>(); urls.add(url); urls.addAll(Arrays.asList(agentUrl)); - ClasspathLauncher.ClassPathArchive classPathArchive = new ClasspathLauncher.ClassPathArchive( + ClassPathArchive classPathArchive = new ClassPathArchive( this.getClass().getCanonicalName(), null, urls.toArray(new URL[] {})); List bizArchives = classPathArchive.getBizArchives(); - Assert.assertEquals(1, bizArchives.size()); - Assert.assertEquals(2, urls.size()); + assertEquals(1, bizArchives.size()); + assertEquals(2, urls.size()); } @Test public void testSpringBootFatJar() throws Exception { + URL url = this.getClass().getClassLoader().getResource("sample-springboot-fat-biz.jar"); - URL[] agentUrl = ClassLoaderUtils.getAgentClassPath(); - Assert.assertEquals(1, agentUrl.length); + URL[] agentUrl = getAgentClassPath(); + assertEquals(1, agentUrl.length); List urls = new ArrayList<>(); - JarFileArchive jarFileArchive = new JarFileArchive(new File(url.getFile())); + JarFileArchive jarFileArchive = new JarFileArchive(FileUtils.file(url.getFile())); List archives = jarFileArchive.getNestedArchives(this::isNestedArchive); for (Archive archive : archives) { urls.add(archive.getUrl()); } urls.addAll(Arrays.asList(agentUrl)); - EmbedClassPathArchive classPathArchive = new EmbedClassPathArchive( - this.getClass().getCanonicalName(), null, urls.toArray(new URL[] {})); + this.getClass().getCanonicalName(), null, urls.toArray(new URL[]{})); List bizArchives = classPathArchive.getBizArchives(); - Assert.assertEquals(0, bizArchives.size()); - Assert.assertNotNull(classPathArchive.getContainerArchive()); - Assert.assertEquals(1, classPathArchive.getPluginArchives().size()); - Assert.assertEquals(archives.size() + 1, urls.size()); - Assert.assertEquals(3, classPathArchive.getConfClasspath().size()); + assertEquals(0, bizArchives.size()); + assertNotNull(classPathArchive.getContainerArchive()); + assertEquals(1, classPathArchive.getPluginArchives().size()); + assertEquals(archives.size() + 1, urls.size()); + assertEquals(3, classPathArchive.getConfClasspath().size()); + URLClassLoader classLoader = new URLClassLoader(classPathArchive.getContainerArchive().getUrls()); try { Class clazz = classLoader.loadClass("com.alipay.sofa.ark.bootstrap.ArkLauncher"); - Assert.assertNotNull(clazz); - } catch (Exception e){ - Assert.assertTrue("loadClass class failed ",false); + assertNotNull(clazz); + } catch (Exception e) { + assertTrue("loadClass class failed ", false); } } @@ -125,16 +130,17 @@ protected boolean isNestedArchive(Archive.Entry entry) { @Test public void testConfClasspath() throws IOException { ClassLoader classLoader = this.getClass().getClassLoader(); - ClasspathLauncher.ClassPathArchive classPathArchive = new ClasspathLauncher.ClassPathArchive( + ClassPathArchive classPathArchive = new ClassPathArchive( this.getClass().getCanonicalName(), null, ClassLoaderUtils.getURLs(classLoader)); List confClasspath = classPathArchive.getConfClasspath(); - Assert.assertEquals(3, confClasspath.size()); + assertEquals(3, confClasspath.size()); } @Test public void testFromSurefire() throws IOException { + ClassLoader classLoader = this.getClass().getClassLoader(); - ClasspathLauncher.ClassPathArchive classPathArchive = new ClasspathLauncher.ClassPathArchive( + ClassPathArchive classPathArchive = new ClassPathArchive( this.getClass().getCanonicalName(), null, ClassLoaderUtils.getURLs(classLoader)); URL url1 = Mockito.mock(URL.class); @@ -144,14 +150,75 @@ public void testFromSurefire() throws IOException { when(url1.getFile()).thenReturn("surefirebooter17233117990150815938.jar"); when(url2.getFile()).thenReturn("org.jacoco.agent-0.8.4-runtime.jar"); when(url3.getFile()).thenReturn("byte-buddy-agent-1.10.15.jar"); - - Assert.assertTrue(classPathArchive.fromSurefire(new URL[] { url1, url2, url3 })); + assertTrue(classPathArchive.fromSurefire(new URL[] { url1, url2, url3 })); List urls2 = classPathArchive.getConfClasspath(); urls2.add(url2); urls2.add(url3); + assertFalse(classPathArchive.fromSurefire(urls2.toArray(new URL[0]))); + } + + @Test + public void testOtherMethods() throws IOException { + + URL url = this.getClass().getClassLoader().getResource("sample-biz.jar"); + URL[] agentUrl = getAgentClassPath(); + assertEquals(1, agentUrl.length); - Assert.assertFalse(classPathArchive.fromSurefire(urls2.toArray(new URL[0]))); + List urls = new ArrayList<>(); + urls.add(url); + urls.addAll(Arrays.asList(agentUrl)); + + ClassPathArchive classPathArchive = new ClassPathArchive( + this.getClass().getCanonicalName(), null, urls.toArray(new URL[] {})); + + try { + classPathArchive.getUrl(); + } catch (Exception e) { + } + try { + classPathArchive.getManifest(); + } catch (Exception e) { + } + try { + classPathArchive.getNestedArchives(null); + } catch (Exception e) { + } + try { + classPathArchive.getNestedArchive(null); + } catch (Exception e) { + } + try { + classPathArchive.getInputStream(null); + } catch (Exception e) { + } + try { + classPathArchive.iterator(); + } catch (Exception e) { + } + + assertTrue(classPathArchive.createDirectoryBizModuleArchive().getClass() + .equals(DirectoryBizArchive.class)); + URL url2 = new URL("file://aa"); + assertArrayEquals(new URL[] { url2 }, + classPathArchive.filterBizUrls(new URL[] { agentUrl[0], url, url2 })); + + URL surefireJarURL = this.getClass().getClassLoader() + .getResource("sample-biz-surefire.jar"); + assertArrayEquals(new URL[] { url2, new URL("file://b") }, + classPathArchive.parseClassPathFromSurefireBoot(surefireJarURL)); } -} \ No newline at end of file + @Test + public void testBaseExecutableArchiveLauncher() { + + BaseExecutableArchiveLauncher baseExecutableArchiveLauncher = new BaseExecutableArchiveLauncher() { + @Override + protected String getMainClass() throws Exception { + return null; + } + }; + + assertNotNull(baseExecutableArchiveLauncher.getExecutableArchive()); + } +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/DirectoryBizArchiveTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/DirectoryBizArchiveTest.java new file mode 100644 index 000000000..262ecf080 --- /dev/null +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/DirectoryBizArchiveTest.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.loader; + +import com.alipay.sofa.ark.spi.archive.Archive; +import com.alipay.sofa.ark.spi.archive.Archive.Entry; +import org.junit.Before; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Iterator; + +import static com.alipay.sofa.ark.spi.constant.Constants.ARK_BIZ_MARK_ENTRY; +import static java.util.Collections.singletonList; +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DirectoryBizArchiveTest { + + private DirectoryBizArchive directoryBizArchive; + + @Before + public void setUp() throws MalformedURLException { + directoryBizArchive = new DirectoryBizArchive("a", "b", new URL[] { new URL("file://a") }); + } + + @Test + public void testDirectoryBizArchive() throws Exception { + + assertFalse(directoryBizArchive.isTestMode()); + assertEquals("a", directoryBizArchive.getClassName()); + assertEquals("b", directoryBizArchive.getMethodName()); + assertArrayEquals(new URL[]{new URL("file://a")}, directoryBizArchive.getUrls()); + + assertTrue(directoryBizArchive.isEntryExist(entry -> !entry.isDirectory() && entry.getName().equals(ARK_BIZ_MARK_ENTRY))); + assertEquals(5, directoryBizArchive.getManifest().getMainAttributes().size()); + + try { + directoryBizArchive.getUrl(); + assertTrue(false); + } catch (Exception e) { + } + try { + directoryBizArchive.getNestedArchives(entry -> false); + assertTrue(false); + } catch (Exception e) { + } + try { + directoryBizArchive.getInputStream(null); + assertTrue(false); + } catch (Exception e) { + } + try { + directoryBizArchive.iterator(); + assertTrue(false); + } catch (Exception e) { + } + + Archive nestedArchive = directoryBizArchive.getNestedArchive(new Entry() { + @Override + public boolean isDirectory() { + return false; + } + + @Override + public String getName() { + return ARK_BIZ_MARK_ENTRY; + } + }); + + Field field = JarBizArchive.class.getDeclaredField("archive"); + field.setAccessible(true); + assertNull(field.get(nestedArchive)); + } + + @Test + public void testJarBizArchive() throws Exception { + + Archive archive = mock(Archive.class); + JarBizArchive jarBizArchive = new JarBizArchive(archive); + + Iterator iterator = singletonList(new Entry() { + @Override + public boolean isDirectory() { + return false; + } + + @Override + public String getName() { + return "lib/export/a"; + } + }).iterator(); + + when(archive.iterator()).thenReturn((Iterator) iterator); + when(archive.getUrl()).thenReturn(new URL("file://a")); + when(archive.getNestedArchive(any())).thenReturn(archive); + + assertArrayEquals(new URL[] { new URL("file://a"), new URL("file://a") }, + jarBizArchive.getExportUrls()); + assertNull(jarBizArchive.getInputStream(null)); + } +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/DirectoryContainerArchiveTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/DirectoryContainerArchiveTest.java new file mode 100644 index 000000000..fb55a65ce --- /dev/null +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/DirectoryContainerArchiveTest.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.loader; + +import org.junit.Test; + +import java.net.URL; + +import static org.junit.Assert.assertTrue; + +public class DirectoryContainerArchiveTest { + + private DirectoryContainerArchive directoryContainerArchive; + + @Test + public void testDirectoryContainerArchive() throws Exception { + + directoryContainerArchive = new DirectoryContainerArchive(new URL[] { new URL("file://a") }); + + try { + directoryContainerArchive.getUrl(); + assertTrue(false); + } catch (Exception e) { + } + try { + directoryContainerArchive.getManifest(); + assertTrue(false); + } catch (Exception e) { + } + try { + directoryContainerArchive.getNestedArchives(null); + assertTrue(false); + } catch (Exception e) { + } + try { + directoryContainerArchive.getNestedArchive(null); + assertTrue(false); + } catch (Exception e) { + } + try { + directoryContainerArchive.getInputStream(null); + assertTrue(false); + } catch (Exception e) { + } + try { + directoryContainerArchive.iterator(); + assertTrue(false); + } catch (Exception e) { + } + } +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/EmbedClassPathArchiveTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/EmbedClassPathArchiveTest.java index b321de656..9485764ca 100644 --- a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/EmbedClassPathArchiveTest.java +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/EmbedClassPathArchiveTest.java @@ -16,6 +16,7 @@ */ package com.alipay.sofa.ark.loader; +import com.alipay.sofa.ark.common.util.FileUtils; import com.alipay.sofa.ark.spi.archive.BizArchive; import org.junit.Assert; import org.junit.Test; @@ -42,7 +43,7 @@ public class EmbedClassPathArchiveTest { public void testGetContainerArchive() throws Exception { ClassLoader cl = Thread.currentThread().getContextClassLoader(); URL springbootFatJar = cl.getResource("sample-springboot-fat-biz.jar"); - JarFileArchive jarFileArchive = new JarFileArchive(new File(springbootFatJar.getFile())); + JarFileArchive jarFileArchive = new JarFileArchive(FileUtils.file(springbootFatJar.getFile())); Iterator archives = jarFileArchive.getNestedArchives(this::isNestedArchive,null); List urls = new ArrayList<>(); while (archives.hasNext()){ @@ -75,7 +76,7 @@ protected boolean isNestedArchive(Archive.Entry entry) { public void testStaticCombineGetBizArchives() throws Exception { ClassLoader cl = Thread.currentThread().getContextClassLoader(); URL springbootFatJar = cl.getResource("static-combine-demo.jar"); - JarFileArchive jarFileArchive = new JarFileArchive(new File(springbootFatJar.getFile())); + JarFileArchive jarFileArchive = new JarFileArchive(FileUtils.file(springbootFatJar.getFile())); Iterator archives = jarFileArchive.getNestedArchives(this::isNestedArchive,null); List urls = new ArrayList<>(); while (archives.hasNext()){ diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/ExecutableArkBizJarTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/ExecutableArkBizJarTest.java new file mode 100644 index 000000000..02e71c1f4 --- /dev/null +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/ExecutableArkBizJarTest.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.loader; + +import com.alipay.sofa.ark.spi.archive.Archive; +import org.junit.Before; +import org.junit.Test; + +import java.util.Iterator; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class ExecutableArkBizJarTest { + + private Archive archive = mock(Archive.class); + + private ExecutableArkBizJar executableArkBizJar = new ExecutableArkBizJar(archive); + + @Before + public void setUp() { + when(archive.iterator()).thenReturn(mock(Iterator.class)); + } + + @Test + public void testExecutableArkBizJar() throws Exception { + + assertNull(executableArkBizJar.getManifest()); + assertNull(executableArkBizJar.getInputStream(null)); + assertNull(executableArkBizJar.getNestedArchive(null)); + + try { + executableArkBizJar.getContainerArchive(); + assertTrue(false); + } catch (RuntimeException e) { + } + + assertEquals(0, executableArkBizJar.getConfClasspath().size()); + } +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/ExplodedBizArchiveTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/ExplodedBizArchiveTest.java index 6aeb32783..957840976 100644 --- a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/ExplodedBizArchiveTest.java +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/ExplodedBizArchiveTest.java @@ -35,7 +35,7 @@ public class ExplodedBizArchiveTest { public void testCreate() throws IOException { ClassLoader cl = Thread.currentThread().getContextClassLoader(); URL arkBizJar = cl.getResource("sample-biz-withjar.jar"); - File unpack = FileUtils.unzip(new File(arkBizJar.getFile()), arkBizJar.getFile() + File unpack = FileUtils.unzip(FileUtils.file(arkBizJar.getFile()), arkBizJar.getFile() + "-unpack"); ExplodedBizArchive archive = new ExplodedBizArchive(unpack); Assert.assertNotNull(archive.getManifest()); diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/HandlerTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/HandlerTest.java new file mode 100644 index 000000000..8efa52e11 --- /dev/null +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/HandlerTest.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.loader.jar; + +import org.junit.Test; + +import java.net.MalformedURLException; +import java.net.URL; + +import static org.junit.Assert.assertEquals; + +public class HandlerTest { + + private URL url = this.getClass().getClassLoader() + .getResource("sample-biz-withjar.jar"); + + private Handler handler = new Handler(); + + @Test(expected = MalformedURLException.class) + public void testOpenConnectionWithIOException() throws Exception { + handler.openConnection(this.getClass().getClassLoader() + .getResource("sample-biz-withjar.jar")); + } + + @Test(expected = NullPointerException.class) + public void testOpenConnectionWithNPE() throws Exception { + handler.openConnection(this.getClass().getClassLoader() + .getResource("sample-biz-withjar.jar!/lib")); + } + + @Test(expected = IllegalArgumentException.class) + public void testParseURLWithIllegalSpec() throws Exception { + handler.parseURL(url, "/", 0, 1); + } + + @Test(expected = SecurityException.class) + public void testParseURLWithEmptySpec() throws Exception { + handler.parseURL(url, "/", 0, 0); + } + + @Test + public void testReplaceParentDir() throws Exception { + assertEquals("../a", handler.replaceParentDir("/../../a")); + assertEquals("../", handler.replaceParentDir("/../../")); + assertEquals("aaa", handler.replaceParentDir("/../aaa/../aaa")); + } +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/JarEntryTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/JarEntryTest.java new file mode 100644 index 000000000..d1b34271e --- /dev/null +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/JarEntryTest.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.loader.jar; + +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.net.URL; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class JarEntryTest { + + private URL url; + + private JarEntry jarEntry; + + @Before + public void setUp() throws Exception { + url = this.getClass().getClassLoader().getResource("sample-biz-withjar.jar"); + jarEntry = new JarEntry(new JarFile(new File(url.getPath())), + new CentralDirectoryFileHeader(new byte[64], 0, new AsciiBytes("lib"), null, + new AsciiBytes("mycomment"), 0)); + } + + @Test + public void testGetters() throws Exception { + assertEquals("jar:" + url + "!/lib", jarEntry.getUrl().toString()); + assertNull(jarEntry.getAttributes()); + assertNull(jarEntry.getCertificates()); + assertNull(jarEntry.getCodeSigners()); + jarEntry.setCertificates(new java.util.jar.JarEntry("a")); + } +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/JarFileTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/JarFileTest.java new file mode 100644 index 000000000..3ae5b7dba --- /dev/null +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/JarFileTest.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.loader.jar; + +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +import static com.alipay.sofa.ark.loader.jar.JarFile.JarFileType.DIRECT; +import static org.junit.Assert.assertEquals; + +public class JarFileTest { + + @Test + public void testSetupEntryCertificates() throws IOException { + + URL url = this.getClass().getClassLoader().getResource("sample-biz.jar"); + JarFile jarFile = new JarFile(new File(url.getPath())); + assertEquals(7485, jarFile.size()); + assertEquals("jar:" + url.toString() + "!/", jarFile.getUrl().toString()); + + jarFile.setupEntryCertificates(new JarEntry(jarFile, new CentralDirectoryFileHeader( + new byte[64], 0, new AsciiBytes("lib"), null, new AsciiBytes("mycomment"), 0))); + + jarFile.clearCache(); + assertEquals(DIRECT, jarFile.getType()); + } +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/JarURLConnectionTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/JarURLConnectionTest.java new file mode 100644 index 000000000..7b9ee24d3 --- /dev/null +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/JarURLConnectionTest.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.loader.jar; + +import com.alipay.sofa.ark.loader.jar.JarURLConnection.JarEntryName; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.net.URL; + +import static com.alipay.sofa.ark.loader.jar.JarURLConnection.JarEntryName.get; +import static com.alipay.sofa.ark.loader.jar.JarURLConnection.get; +import static org.junit.Assert.*; + +public class JarURLConnectionTest { + + private JarURLConnection jarURLConnection; + + private URL url = this.getClass().getClassLoader() + .getResource("sample-biz-withjar.jar"); + + @Before + public void setUp() throws Exception { + jarURLConnection = get(url, new JarFile(new File(url.getPath()))); + } + + @Test + public void testGetJarFileURL() throws IOException { + + assertTrue(jarURLConnection.getJarFileURL().getFile().endsWith("/sample-biz-withjar.jar")); + assertNull(jarURLConnection.getJarEntry()); + + jarURLConnection = get(new URL( + "file://a/b/sample-biz-withjar.jar!/lib/slf4j-api-1.7.30.jar!/"), new JarFile(new File( + url.getPath()))); + + assertEquals("com.alipay.sofa.ark.loader.data.RandomAccessDataFile$DataInputStream", + jarURLConnection.getInputStream().getClass().getName()); + assertNull(jarURLConnection.getJarEntry()); + assertEquals("", jarURLConnection.getEntryName()); + } + + @Test + public void testGetContentLength() throws Exception { + assertEquals(52949, jarURLConnection.getContentLength()); + Field field = JarURLConnection.class.getDeclaredField("jarEntryName"); + field.setAccessible(true); + field.set(jarURLConnection, new JarEntryName("!/lib/slf4j-api-1.7.30.jar!/")); + assertEquals(-1, jarURLConnection.getContentLength()); + } + + @Test + public void testGetContent() throws IOException { + assertEquals(JarFile.class, jarURLConnection.getContent().getClass()); + assertEquals("x-java/jar", jarURLConnection.getContentType()); + } + + @Test + public void testGetLastModified() throws Exception { + assertEquals(0, jarURLConnection.getLastModified()); + Field field = JarURLConnection.class.getDeclaredField("jarEntryName"); + field.setAccessible(true); + field.set(jarURLConnection, new JarEntryName("!/lib/slf4j-api-1.7.30.jar!/")); + assertEquals(0, jarURLConnection.getLastModified()); + } + + @Test + public void testJarEntryName() { + JarEntryName jarEntryName = get(url.toString()); + + String javaVersion = System.getProperty("java.version"); + if (javaVersion.startsWith("1.8")) { + assertEquals("content/unknown", jarEntryName.getContentType()); + } else { + assertEquals("application/java-archive", jarEntryName.getContentType()); + } + + if (javaVersion.startsWith("1.8")) { + assertEquals("content/unknown", jarEntryName.getContentType()); + } else { + assertEquals("application/java-archive", jarEntryName.getContentType()); + } + } +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/JarUtilsTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/JarUtilsTest.java new file mode 100644 index 000000000..1aa759a6e --- /dev/null +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/JarUtilsTest.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.loader.jar; + +import org.junit.Test; + +import java.io.File; +import java.net.URL; + +import static com.alipay.sofa.ark.loader.jar.JarUtils.getArtifactIdFromLocalClassPath; +import static com.alipay.sofa.ark.loader.jar.JarUtils.searchPomProperties; +import static org.junit.Assert.*; + +public class JarUtilsTest { + + @Test + public void testSearchPomProperties() { + + assertNull(searchPomProperties(null)); + assertNull(searchPomProperties(new File("/not-exists"))); + + URL url = this.getClass().getClassLoader().getResource("pom-properties/pom.properties"); + File file = new File(url.getPath()); + assertEquals(file, searchPomProperties(file)); + + url = this.getClass().getClassLoader().getResource("./"); + file = new File(url.getPath()); + assertTrue(searchPomProperties(file).getPath().endsWith("pom.properties")); + } + + @Test + public void testGetArtifactIdFromLocalClassPath() { + assertNull(getArtifactIdFromLocalClassPath("/a/target/bbb")); + URL url = this.getClass().getClassLoader().getResource(""); + assertEquals("sofa-ark-archive", getArtifactIdFromLocalClassPath(url.getPath())); + } +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/ZipInflaterInputStreamTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/ZipInflaterInputStreamTest.java new file mode 100644 index 000000000..6672a0f35 --- /dev/null +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/jar/ZipInflaterInputStreamTest.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.loader.jar; + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.lang.reflect.Field; +import java.util.zip.InflaterInputStream; + +import static org.junit.Assert.assertEquals; + +public class ZipInflaterInputStreamTest { + + @Test + public void testFill() throws Exception { + + ZipInflaterInputStream zipInflaterInputStream = new ZipInflaterInputStream( + new ByteArrayInputStream(new byte[0]), 0); + assertEquals(0, zipInflaterInputStream.available()); + zipInflaterInputStream.fill(); + + Field field = ZipInflaterInputStream.class.getDeclaredField("extraBytesWritten"); + field.setAccessible(true); + assertEquals(true, field.get(zipInflaterInputStream)); + } +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/base/BaseTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/base/BaseTest.java index d6149b040..14619f6d9 100644 --- a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/base/BaseTest.java +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/base/BaseTest.java @@ -117,13 +117,14 @@ private static byte[] generateManifest() { private static byte[] fetchResource(String resourceName) throws IOException { URL resource = BaseTest.class.getClassLoader().getResource(resourceName); - RandomAccessDataFile dataFile = new RandomAccessDataFile(new File(resource.getFile())); + RandomAccessDataFile dataFile = new RandomAccessDataFile( + com.alipay.sofa.ark.common.util.FileUtils.file(resource.getFile())); return Bytes.get(dataFile); } public static File getTmpDir() { String tmpPath = System.getProperty("java.io.tmpdir"); - return new File(tmpPath); + return com.alipay.sofa.ark.common.util.FileUtils.file(tmpPath); } public static File getWorkspace() { diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/AsciiBytesTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/AsciiBytesTest.java index f2f7ffb4b..e39cd9602 100644 --- a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/AsciiBytesTest.java +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/AsciiBytesTest.java @@ -17,9 +17,10 @@ package com.alipay.sofa.ark.loader.test.jar; import com.alipay.sofa.ark.loader.jar.AsciiBytes; -import org.junit.Assert; import org.junit.Test; +import static org.junit.Assert.*; + /** * @author qilong.zql * @since 0.1.0 @@ -28,15 +29,16 @@ public class AsciiBytesTest { public final String content = "SofaArk is a class-isolated container"; - AsciiBytes asciiBytes = new AsciiBytes(content); + private AsciiBytes asciiBytes = new AsciiBytes(content); @Test public void testAsciiBytes() { - Assert.assertTrue(asciiBytes.length() == content.length()); - Assert.assertTrue(asciiBytes.startsWith(new AsciiBytes("SofaArk"))); - Assert.assertTrue(asciiBytes.endsWith(new AsciiBytes("container"))); - Assert.assertTrue(asciiBytes.toString().equals(content)); - Assert.assertTrue(asciiBytes.substring(8, 10).endsWith(new AsciiBytes("is"))); + + assertTrue(asciiBytes.length() == content.length()); + assertTrue(asciiBytes.startsWith(new AsciiBytes("SofaArk"))); + assertTrue(asciiBytes.endsWith(new AsciiBytes("container"))); + assertTrue(asciiBytes.toString().equals(content)); + assertTrue(asciiBytes.substring(8, 10).endsWith(new AsciiBytes("is"))); String suffix = "suffix"; AsciiBytes suffixAsciiBytes = new AsciiBytes(suffix); @@ -46,4 +48,13 @@ public void testAsciiBytes() { asciiBytes.append(suffixAsciiBytes).equals(content + suffix); asciiBytes.append(suffixBytes).equals(content + suffix); } -} \ No newline at end of file + + @Test + public void testHashCode() { + AsciiBytes asciiBytes = new AsciiBytes("" + (char) 0xffff + (char) -99 + (char) -255 + + (char) -128 + (char) 127 + (char) 128 + (char) 255 + + (char) 256 + content); + assertEquals(-243313336, asciiBytes.hashCode()); + assertNotEquals(new AsciiBytes(""), asciiBytes); + } +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/CentralDirectoryEndRecordTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/CentralDirectoryEndRecordTest.java index 6db86dbf5..1c0928c87 100644 --- a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/CentralDirectoryEndRecordTest.java +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/CentralDirectoryEndRecordTest.java @@ -16,13 +16,21 @@ */ package com.alipay.sofa.ark.loader.test.jar; +import com.alipay.sofa.ark.loader.data.RandomAccessData; import com.alipay.sofa.ark.loader.data.RandomAccessDataFile; import com.alipay.sofa.ark.loader.jar.CentralDirectoryEndRecord; import com.alipay.sofa.ark.loader.test.base.BaseTest; -import org.junit.Assert; import org.junit.Test; +import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * @author qilong.zql @@ -32,13 +40,22 @@ public class CentralDirectoryEndRecordTest extends BaseTest { @Test public void testEOCD() throws IOException { + RandomAccessDataFile dataFile = new RandomAccessDataFile(getTempDemoZip()); CentralDirectoryEndRecord eocd = new CentralDirectoryEndRecord(dataFile); - Assert.assertTrue(eocd.isValid()); - Assert.assertTrue(eocd.getStartOfArchive(dataFile) == 0); - Assert.assertTrue(eocd.getNumberOfRecords() == 5); - + assertTrue(eocd.isValid()); + assertTrue(eocd.getStartOfArchive(dataFile) == 0); + assertTrue(eocd.getNumberOfRecords() == 5); } -} \ No newline at end of file + @Test + public void testWithInvalidFile() throws Exception { + + RandomAccessData randomAccessData = mock(RandomAccessData.class); + when(randomAccessData.getInputStream(any())).thenReturn(mock(InputStream.class)); + + URL url = this.getClass().getClassLoader().getResource("example-jarinjarinjar.jar"); + new CentralDirectoryEndRecord(new RandomAccessDataFile(new File(url.getPath()))); + } +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/CentralDirectoryFileHeaderTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/CentralDirectoryFileHeaderTest.java index d130de5fe..5bd8f5a6f 100644 --- a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/CentralDirectoryFileHeaderTest.java +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/CentralDirectoryFileHeaderTest.java @@ -18,17 +18,20 @@ import com.alipay.sofa.ark.loader.data.RandomAccessData; import com.alipay.sofa.ark.loader.data.RandomAccessDataFile; +import com.alipay.sofa.ark.loader.jar.AsciiBytes; import com.alipay.sofa.ark.loader.jar.Bytes; import com.alipay.sofa.ark.loader.jar.CentralDirectoryEndRecord; import com.alipay.sofa.ark.loader.jar.CentralDirectoryFileHeader; import com.alipay.sofa.ark.loader.test.base.BaseTest; -import org.junit.Assert; import org.junit.Test; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + /** * @author qilong.zql * @since 0.1.0 @@ -39,10 +42,10 @@ public class CentralDirectoryFileHeaderTest extends BaseTest { @Test public void testCDFH() throws IOException { + RandomAccessDataFile dataFile = new RandomAccessDataFile(getTempDemoZip()); CentralDirectoryEndRecord eocd = new CentralDirectoryEndRecord(dataFile); RandomAccessData cdfhBlock = eocd.getCentralDirectory(dataFile); - List cdfhList = new ArrayList<>(); int dataOffset = 0; @@ -54,11 +57,18 @@ public void testCDFH() throws IOException { cdfhList.add(cdfh); } - Assert.assertTrue(cdfhList.size() == 5); - Assert.assertTrue(cdfhList.get(4).getName().toString().equals(TEST_ENTRY)); - Assert.assertTrue(cdfhList.get(4).getComment().toString().equals(TEST_ENTRY_COMMENT)); - Assert - .assertTrue(compareByteArray(cdfhList.get(4).getExtra(), TEST_ENTRY_EXTRA.getBytes())); + assertTrue(cdfhList.size() == 5); + assertTrue(cdfhList.get(4).getName().toString().equals(TEST_ENTRY)); + assertTrue(cdfhList.get(4).getComment().toString().equals(TEST_ENTRY_COMMENT)); + assertTrue(compareByteArray(cdfhList.get(4).getExtra(), TEST_ENTRY_EXTRA.getBytes())); + } + @Test + public void testOtherMethods() { + CentralDirectoryFileHeader centralDirectoryFileHeader = new CentralDirectoryFileHeader( + new byte[64], 0, new AsciiBytes("a/"), null, null, 0); + assertEquals(true, centralDirectoryFileHeader.isDirectory()); + CentralDirectoryFileHeader centralDirectoryFileHeader2 = centralDirectoryFileHeader.clone(); + assertEquals(new AsciiBytes("a/"), centralDirectoryFileHeader2.getName()); } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/JarFileTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/JarFileTest.java index ceb603724..513bd56b2 100644 --- a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/JarFileTest.java +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/JarFileTest.java @@ -19,13 +19,14 @@ import com.alipay.sofa.ark.loader.jar.JarEntry; import com.alipay.sofa.ark.loader.jar.JarFile; import com.alipay.sofa.ark.loader.test.base.BaseTest; -import org.junit.Assert; import org.junit.Test; import java.io.IOException; import java.util.jar.Manifest; import java.util.zip.ZipEntry; +import static org.junit.Assert.assertTrue; + /** * @author qilong.zql * @since 0.1.0 @@ -34,27 +35,25 @@ public class JarFileTest extends BaseTest { @Test public void testJarFile() throws IOException { + JarFile jarFile = new JarFile(getTempDemoZip()); Manifest manifest = jarFile.getManifest(); - Assert.assertTrue(manifest.getMainAttributes().getValue("k1").equals("v1")); - Assert.assertTrue(manifest.getMainAttributes().getValue("k2").equals("v2")); - - Assert.assertTrue(jarFile.containsEntry(TEST_ENTRY)); + assertTrue(manifest.getMainAttributes().getValue("k1").equals("v1")); + assertTrue(manifest.getMainAttributes().getValue("k2").equals("v2")); + assertTrue(jarFile.containsEntry(TEST_ENTRY)); ZipEntry zipEntry = jarFile.getEntry(TEST_ENTRY); - Assert.assertTrue(zipEntry.getName().equals(TEST_ENTRY)); - Assert.assertTrue(zipEntry.getComment().equals(TEST_ENTRY_COMMENT)); - Assert.assertTrue(compareByteArray(zipEntry.getExtra(), TEST_ENTRY_EXTRA.getBytes())); + assertTrue(zipEntry.getName().equals(TEST_ENTRY)); + assertTrue(zipEntry.getComment().equals(TEST_ENTRY_COMMENT)); + assertTrue(compareByteArray(zipEntry.getExtra(), TEST_ENTRY_EXTRA.getBytes())); JarEntry jarEntry = jarFile.getJarEntry("lib/junit-4.12.jar"); JarFile nestJarFile = jarFile.getNestedJarFile(jarEntry); Manifest nestManifest = nestJarFile.getManifest(); - Assert.assertTrue(nestManifest.getMainAttributes().getValue("Implementation-Title") + assertTrue(nestManifest.getMainAttributes().getValue("Implementation-Title") .equals("JUnit")); - Assert.assertTrue(nestManifest.getMainAttributes().getValue("Implementation-Version") + assertTrue(nestManifest.getMainAttributes().getValue("Implementation-Version") .equals("4.12")); - } - -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/JarUtilsTest.java b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/JarUtilsTest.java index 1adecdc7a..0cc8b69dd 100644 --- a/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/JarUtilsTest.java +++ b/sofa-ark-parent/core-impl/archive/src/test/java/com/alipay/sofa/ark/loader/test/jar/JarUtilsTest.java @@ -19,105 +19,105 @@ import com.alipay.sofa.ark.common.util.FileUtils; import com.alipay.sofa.ark.loader.jar.JarUtils; import com.google.common.io.Files; -import org.junit.Assert; import org.junit.Test; -import java.io.File; import java.io.IOException; import java.lang.reflect.Method; -import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.nio.file.Paths; + +import static com.alipay.sofa.ark.loader.jar.JarUtils.parseArtifactId; +import static java.lang.String.format; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; public class JarUtilsTest { @Test public void getArtifactIdFromTestClassPath() throws IOException { URL url = this.getClass().getClassLoader().getResource("sample-biz-withjar.jar"); - String artifactId = JarUtils.parseArtifactId(url.getPath()); - Assert.assertEquals("sofa-ark-sample-springboot-ark", artifactId); + String artifactId = parseArtifactId(url.getPath()); + assertEquals("sofa-ark-sample-springboot-ark", artifactId); } @Test public void getArtifactIdFromTestClassPath1() throws IOException { URL url = this.getClass().getClassLoader().getResource("SampleClass.class"); - String artifactId = JarUtils.parseArtifactId(url.getPath()); - Assert.assertEquals("sofa-ark-archive", artifactId); + String artifactId = parseArtifactId(url.getPath()); + assertEquals("sofa-ark-archive", artifactId); } @Test public void getArtifactIdFromClassPath() throws IOException, URISyntaxException { + URL clazzURL = this.getClass().getClassLoader() .getResource("com/alipay/sofa/ark/loader/jar/JarUtils.class"); - - String artifactId = JarUtils.parseArtifactId(clazzURL.getPath()); - Assert.assertEquals("sofa-ark-archive", artifactId); + String artifactId = parseArtifactId(clazzURL.getPath()); + assertEquals("sofa-ark-archive", artifactId); URL testClazzURL = this.getClass().getClassLoader() .getResource("com/alipay/sofa/ark/loader/test/jar/JarUtilsTest.class"); + artifactId = parseArtifactId(testClazzURL.getPath()); + assertEquals("sofa-ark-archive", artifactId); - artifactId = JarUtils.parseArtifactId(testClazzURL.getPath()); - Assert.assertEquals("sofa-ark-archive", artifactId); - - URI classPathRoot = this.getClass().getClassLoader().getResource("").toURI(); - String classPath = Paths.get(classPathRoot).toFile().getAbsolutePath(); - String artifactId1 = JarUtils.parseArtifactId(classPath); - Assert.assertNotNull(artifactId1); + String path = this.getClass().getClassLoader().getResource("example-jarinjarinjar.jar") + .getPath(); + String artifactId1 = parseArtifactId(path + "!/lib"); + assertEquals("example-client", artifactId1); } @Test public void testParseArtifactIdFromJarName() throws Exception { + Method method = JarUtils.class.getDeclaredMethod("doGetArtifactIdFromFileName", String.class); method.setAccessible(Boolean.TRUE); String filePathPrefix = "file:///home/admin/xxx/xxx/%s.jar"; - String artifactId0 = (String) method.invoke(JarUtils.class, - String.format(filePathPrefix, "dafdfa-2-dafdfad")); - Assert.assertNull(artifactId0); + format(filePathPrefix, "dafdfa-2-dafdfad")); + assertNull(artifactId0); String artifactId2 = (String) method.invoke(JarUtils.class, - String.format(filePathPrefix, "dfadfa-dfadfa-3.0")); - Assert.assertEquals(artifactId2, "dfadfa-dfadfa"); + format(filePathPrefix, "dfadfa-dfadfa-3.0")); + assertEquals(artifactId2, "dfadfa-dfadfa"); String artifactId3 = (String) method.invoke(JarUtils.class, - String.format(filePathPrefix, "hessian-4.0.7.bugfix12-tuning3")); - Assert.assertEquals(artifactId3, "hessian"); + format(filePathPrefix, "hessian-4.0.7.bugfix12-tuning3")); + assertEquals(artifactId3, "hessian"); String artifactId4 = (String) method.invoke(JarUtils.class, - String.format(filePathPrefix, "hessian-4.0.7")); - Assert.assertEquals(artifactId4, "hessian"); + format(filePathPrefix, "hessian-4.0.7")); + assertEquals(artifactId4, "hessian"); } @Test public void testParseArtifactIdFromJarInJarName() throws Exception { + Method method = JarUtils.class.getDeclaredMethod("doGetArtifactIdFromFileName", String.class); method.setAccessible(Boolean.TRUE); String filePathPrefix = "file:///home/admin/xxx/xxx/bootstrap-executable.jar!/META-INF/lib/%s.jar"; - String artifactId0 = (String) method.invoke(JarUtils.class, - String.format(filePathPrefix, "dafdfa-2-dafdfad")); - Assert.assertNull(artifactId0); + format(filePathPrefix, "dafdfa-2-dafdfad")); + assertNull(artifactId0); String artifactId1 = (String) method.invoke(JarUtils.class, - String.format(filePathPrefix, "jar-2-version-suffix")); - Assert.assertNull(artifactId1); + format(filePathPrefix, "jar-2-version-suffix")); + assertNull(artifactId1); String artifactId2 = (String) method.invoke(JarUtils.class, - String.format(filePathPrefix, "dfadfa-dfadfa-3.0")); - Assert.assertEquals(artifactId2, "dfadfa-dfadfa"); + format(filePathPrefix, "dfadfa-dfadfa-3.0")); + assertEquals(artifactId2, "dfadfa-dfadfa"); String artifactId3 = (String) method.invoke(JarUtils.class, - String.format(filePathPrefix, "hessian-4.0.7.bugfix12-tuning3")); - Assert.assertEquals(artifactId3, "hessian"); + format(filePathPrefix, "hessian-4.0.7.bugfix12-tuning3")); + assertEquals(artifactId3, "hessian"); String artifactId4 = (String) method.invoke(JarUtils.class, - String.format(filePathPrefix, "hessian-4.0.7")); - Assert.assertEquals(artifactId4, "hessian"); + format(filePathPrefix, "hessian-4.0.7")); + assertEquals(artifactId4, "hessian"); } @Test @@ -126,44 +126,41 @@ public void testParseArtifactIdFromJarInJar() throws Exception { Method method = JarUtils.class.getDeclaredMethod("parseArtifactIdFromJarInJar", String.class); method.setAccessible(Boolean.TRUE); - Assert.assertEquals("slf4j-api", + assertEquals("slf4j-api", method.invoke(JarUtils.class, jar.getFile() + "!/lib/slf4j-api-1.7.30.jar")); } @Test public void testParseArtifactIdFromJarInJarPom() { URL jar = JarUtilsTest.class.getResource("/sample-biz-withjar.jar"); - String artifactId0 = JarUtils.parseArtifactId(jar.getFile() - + "!/lib/slf4j-api-1.7.30.jar!/"); - Assert.assertEquals("slf4j-api", artifactId0); + String artifactId0 = parseArtifactId(jar.getFile() + "!/lib/slf4j-api-1.7.30.jar!/"); + assertEquals("slf4j-api", artifactId0); } @Test public void testParseArtifactIdFromJarWithBlankPath() throws Exception { + URL jar = JarUtilsTest.class.getResource("/junit-4.12.jar"); URL root = JarUtilsTest.class.getResource("/"); String fullPath = root.getPath() + "space directory"; String jarLocation = fullPath + "/junit-4.12.jar"; FileUtils.mkdir(fullPath); - Files.copy(new File(jar.getFile()), new File(jarLocation)); + Files.copy(FileUtils.file(jar.getFile()), FileUtils.file(jarLocation)); URL url = JarUtilsTest.class.getResource("/space directory/junit-4.12.jar"); Method method = JarUtils.class.getDeclaredMethod("parseArtifactIdFromJar", String.class); method.setAccessible(Boolean.TRUE); - Assert.assertNull(method.invoke(JarUtils.class, url.getPath())); + assertNull(method.invoke(JarUtils.class, url.getPath())); } @Test public void testParseArtifactIdFromJarInJarInJarMore() { URL jar = JarUtilsTest.class.getResource("/example-jarinjarinjar.jar"); - String artifactId0 = JarUtils - .parseArtifactId(jar.getFile() - + "!/BOOT-INF/lib/example-client-2.0.0.jar!/BOOT-INF/lib/sofa-ark-spring-guides-230525-SOFA.jar!/"); - Assert.assertEquals("sofa-ark-spring-guides", artifactId0); - - String artifactId1 = JarUtils - .parseArtifactId(jar.getFile() - + "!/BOOT-IN/lib/example-client-2.0.0.jar!/BOOT-INF/lib/example-client-3.0.0.jar!/"); - Assert.assertEquals("example-client", artifactId1); + String artifactId0 = parseArtifactId(jar.getFile() + + "!/BOOT-INF/lib/example-client-2.0.0.jar!/BOOT-INF/lib/sofa-ark-spring-guides-230525-SOFA.jar!/"); + assertEquals("sofa-ark-spring-guides", artifactId0); + String artifactId1 = parseArtifactId(jar.getFile() + + "!/BOOT-IN/lib/example-client-2.0.0.jar!/BOOT-INF/lib/example-client-3.0.0.jar!/"); + assertEquals("example-client", artifactId1); } } diff --git a/sofa-ark-parent/core-impl/archive/src/test/resources/empty-file b/sofa-ark-parent/core-impl/archive/src/test/resources/empty-file new file mode 100644 index 000000000..e69de29bb diff --git a/sofa-ark-parent/core-impl/archive/src/test/resources/pom-properties/pom.properties b/sofa-ark-parent/core-impl/archive/src/test/resources/pom-properties/pom.properties new file mode 100644 index 000000000..1c6a1a9e8 --- /dev/null +++ b/sofa-ark-parent/core-impl/archive/src/test/resources/pom-properties/pom.properties @@ -0,0 +1 @@ +a=b \ No newline at end of file diff --git a/sofa-ark-parent/core-impl/archive/src/test/resources/pom.xml b/sofa-ark-parent/core-impl/archive/src/test/resources/pom.xml new file mode 100644 index 000000000..e6649b9d4 --- /dev/null +++ b/sofa-ark-parent/core-impl/archive/src/test/resources/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + sofa-ark-core-impl + com.alipay.sofa + ${sofa.ark.version} + + + sofa-ark-archive + + + + + + com.alipay.sofa + sofa-ark-spi + + + com.alipay.sofa + sofa-ark-api + + + com.alipay.sofa + sofa-ark-common + + + + + commons-io + commons-io + + + org.apache.maven + maven-model + + + + + junit + junit + test + + + org.mockito + mockito-inline + ${mockito.version} + test + + + org.springframework.boot + spring-boot-loader + test + + + + + diff --git a/sofa-ark-parent/core-impl/archive/src/test/resources/sample-biz-surefire.jar b/sofa-ark-parent/core-impl/archive/src/test/resources/sample-biz-surefire.jar new file mode 100644 index 000000000..ab34e3ab6 Binary files /dev/null and b/sofa-ark-parent/core-impl/archive/src/test/resources/sample-biz-surefire.jar differ diff --git a/sofa-ark-parent/core-impl/container/pom.xml b/sofa-ark-parent/core-impl/container/pom.xml index 5ef82d2bc..b10a2dfb9 100644 --- a/sofa-ark-parent/core-impl/container/pom.xml +++ b/sofa-ark-parent/core-impl/container/pom.xml @@ -38,10 +38,6 @@ com.google.inject guice - - com.google.inject.extensions - guice-multibindings - io.netty netty-all @@ -76,7 +72,5 @@ system-rules test - - diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/ArkContainer.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/ArkContainer.java index a2262c4e3..9041ea4d1 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/ArkContainer.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/ArkContainer.java @@ -20,6 +20,7 @@ import com.alipay.sofa.ark.bootstrap.ClasspathLauncher.ClassPathArchive; import com.alipay.sofa.ark.common.log.ArkLoggerFactory; import com.alipay.sofa.ark.common.util.AssertUtils; +import com.alipay.sofa.ark.common.util.FileUtils; import com.alipay.sofa.ark.common.util.StringUtils; import com.alipay.sofa.ark.container.pipeline.DeployBizStage; import com.alipay.sofa.ark.container.pipeline.HandleArchiveStage; @@ -36,16 +37,11 @@ import com.alipay.sofa.ark.spi.pipeline.Pipeline; import com.alipay.sofa.ark.spi.pipeline.PipelineContext; import com.alipay.sofa.common.log.MultiAppLoggerSpaceManager; -import com.alipay.sofa.common.log.SpaceId; -import com.alipay.sofa.common.log.SpaceInfo; -import com.alipay.sofa.common.log.env.LogEnvUtils; -import com.alipay.sofa.common.log.factory.LogbackLoggerSpaceFactory; import com.alipay.sofa.common.utils.ReportUtil; import java.io.File; import java.io.IOException; import java.net.URL; -import java.net.URLDecoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -55,8 +51,13 @@ import static com.alipay.sofa.ark.spi.constant.Constants.ARK_CONF_FILE; import static com.alipay.sofa.ark.spi.constant.Constants.ARK_CONF_FILE_FORMAT; import static com.alipay.sofa.common.log.Constants.LOGGING_PATH_DEFAULT; +import static com.alipay.sofa.common.log.Constants.LOG_CONFIG_PREFIX; import static com.alipay.sofa.common.log.Constants.LOG_ENCODING_PROP_KEY; +import static com.alipay.sofa.common.log.Constants.LOG_LEVEL_PREFIX; import static com.alipay.sofa.common.log.Constants.LOG_PATH; +import static com.alipay.sofa.common.log.Constants.LOG_PATH_PREFIX; +import static com.alipay.sofa.common.log.Constants.OLD_LOG_PATH; +import static com.alipay.sofa.common.log.Constants.SOFA_MIDDLEWARE_CONFIG_PREFIX; import static com.alipay.sofa.common.log.Constants.UTF8_STR; /** @@ -92,8 +93,7 @@ public static Object main(String[] args) throws ArkRuntimeException { LaunchCommand launchCommand = LaunchCommand.parse(args); if (launchCommand.isExecutedByCommandLine()) { ExecutableArkBizJar executableArchive; - File rootFile = new File(URLDecoder.decode(launchCommand.getExecutableArkBizJar() - .getFile())); + File rootFile = FileUtils.file(launchCommand.getExecutableArkBizJar().getFile()); if (rootFile.isDirectory()) { executableArchive = new ExecutableArkBizJar(new ExplodedArchive(rootFile)); } else { @@ -218,29 +218,27 @@ public List getProfileConfFiles(String... profiles) { * @throws ArkRuntimeException */ public void reInitializeArkLogger() throws ArkRuntimeException { - for (Map.Entry entry : MultiAppLoggerSpaceManager.getSpacesMap() - .entrySet()) { - SpaceId spaceId = entry.getKey(); - SpaceInfo spaceInfo = entry.getValue(); - if (!ArkLoggerFactory.SOFA_ARK_LOGGER_SPACE.equals(spaceId.getSpaceName())) { - continue; + Map arkLogConfig = new HashMap<>(); + // set base logging.path + arkLogConfig.put(LOG_PATH, ArkConfigs.getStringValue(LOG_PATH, LOGGING_PATH_DEFAULT)); + // set log file encoding + arkLogConfig.put(LOG_ENCODING_PROP_KEY, + ArkConfigs.getStringValue(LOG_ENCODING_PROP_KEY, UTF8_STR)); + // set other log config + for (String key : ArkConfigs.keySet()) { + if (filterAllLogConfig(key)) { + arkLogConfig.put(key, ArkConfigs.getStringValue(key)); } - LogbackLoggerSpaceFactory arkLoggerSpaceFactory = (LogbackLoggerSpaceFactory) spaceInfo - .getAbstractLoggerSpaceFactory(); - Map arkLogConfig = new HashMap<>(); - // set base logging.path - arkLogConfig.put(LOG_PATH, ArkConfigs.getStringValue(LOG_PATH, LOGGING_PATH_DEFAULT)); - // set log file encoding - arkLogConfig.put(LOG_ENCODING_PROP_KEY, - ArkConfigs.getStringValue(LOG_ENCODING_PROP_KEY, UTF8_STR)); - // set other log config - for (String key : ArkConfigs.keySet()) { - if (LogEnvUtils.filterAllLogConfig(key)) { - arkLogConfig.put(key, ArkConfigs.getStringValue(key)); - } - } - arkLoggerSpaceFactory.reInitialize(arkLogConfig); } + + MultiAppLoggerSpaceManager.init(ArkLoggerFactory.SOFA_ARK_LOGGER_SPACE, arkLogConfig); + } + + private boolean filterAllLogConfig(String key) { + return key.startsWith(SOFA_MIDDLEWARE_CONFIG_PREFIX) || key.startsWith(LOG_LEVEL_PREFIX) + || key.startsWith(LOG_PATH_PREFIX) || key.startsWith(LOG_CONFIG_PREFIX) + || key.equals(LOG_PATH) || key.equals(OLD_LOG_PATH) + || key.equals(LOG_ENCODING_PROP_KEY); } /** @@ -289,4 +287,4 @@ public ArkServiceContainer getArkServiceContainer() { public PipelineContext getPipelineContext() { return pipelineContext; } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/model/BizModel.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/model/BizModel.java index a90cf18d8..50ea12fbb 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/model/BizModel.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/model/BizModel.java @@ -58,50 +58,47 @@ * @since 0.1.0 */ public class BizModel implements Biz { - private final static ArkLogger LOGGER = ArkLoggerFactory - .getDefaultLogger(); + private String bizName; - private String bizName; + private String bizVersion; - private String bizVersion; + private BizState bizState; - private BizState bizState; + private String mainClass; - private String mainClass; + private String webContextPath; - private String webContextPath; + private URL[] urls; - private URL[] urls; + private URL[] pluginUrls; - private URL[] pluginUrls; + private ClassLoader classLoader; - private ClassLoader classLoader; + private Map attributes = new ConcurrentHashMap<>(); - private Map attributes = new ConcurrentHashMap<>(); + private int priority = DEFAULT_PRECEDENCE; - private int priority = DEFAULT_PRECEDENCE; + private Set denyImportPackages; - private Set denyImportPackages; + private Set denyImportPackageNodes = new HashSet<>(); - private Set denyImportPackageNodes = new HashSet<>(); + private Set denyImportPackageStems = new HashSet<>(); - private Set denyImportPackageStems = new HashSet<>(); + private Set denyImportClasses; - private Set denyImportClasses; + private Set denyImportResources = new HashSet<>(); - private Set denyImportResources = new HashSet<>(); + private Set injectPluginDependencies = new HashSet<>(); + private Set injectExportPackages = new HashSet<>(); - private Set injectPluginDependencies = new HashSet<>(); - private Set injectExportPackages = new HashSet<>(); + private Set declaredLibraries = new LinkedHashSet<>(); + private Map declaredCacheMap = new ConcurrentHashMap<>(); - private Set declaredLibraries = new LinkedHashSet<>(); - private Map declaredCacheMap = new ConcurrentHashMap<>(); + private Set denyPrefixImportResourceStems = new HashSet<>(); - private Set denyPrefixImportResourceStems = new HashSet<>(); + private Set denySuffixImportResourceStems = new HashSet<>(); - private Set denySuffixImportResourceStems = new HashSet<>(); - - private File bizTempWorkDir; + private File bizTempWorkDir; public BizModel setBizName(String bizName) { AssertUtils.isFalse(StringUtils.isEmpty(bizName), "Biz Name must not be empty!"); @@ -287,13 +284,13 @@ public void start(String[] args) throws Throwable { resetProperties(); if (!isMasterBizAndEmbedEnable()) { long start = System.currentTimeMillis(); - LOGGER.info("Ark biz {} start.", getIdentity()); + ArkLoggerFactory.getDefaultLogger().info("Ark biz {} start.", getIdentity()); MainMethodRunner mainMethodRunner = new MainMethodRunner(mainClass, args); mainMethodRunner.run(); // this can trigger health checker handler eventAdminService.sendEvent(new AfterBizStartupEvent(this)); - LOGGER.info("Ark biz {} started in {} ms", getIdentity(), - (System.currentTimeMillis() - start)); + ArkLoggerFactory.getDefaultLogger().info("Ark biz {} started in {} ms", + getIdentity(), (System.currentTimeMillis() - start)); } } catch (Throwable e) { bizState = BizState.BROKEN; @@ -339,9 +336,9 @@ public void stop() { try { // this can trigger uninstall handler long start = System.currentTimeMillis(); - LOGGER.info("Ark biz {} stops.", getIdentity()); + ArkLoggerFactory.getDefaultLogger().info("Ark biz {} stops.", getIdentity()); eventAdminService.sendEvent(new BeforeBizStopEvent(this)); - LOGGER.info("Ark biz {} stopped in {} ms", getIdentity(), + ArkLoggerFactory.getDefaultLogger().info("Ark biz {} stopped in {} ms", getIdentity(), (System.currentTimeMillis() - start)); } finally { BizManagerService bizManagerService = ArkServiceContainerHolder.getContainer() @@ -452,7 +449,8 @@ private boolean checkDeclaredWithCache(String libraryFile) { return declaredCacheMap.computeIfAbsent(libraryFile, this::doCheckDeclared); } - private boolean doCheckDeclared(String jarFilePath) { + boolean doCheckDeclared(String jarFilePath) { + // if from ark plugin, then set as declared if (isFromPlugin(jarFilePath)) { return true; @@ -462,13 +460,15 @@ private boolean doCheckDeclared(String jarFilePath) { if (artifactId == null) { if (jarFilePath.contains(".jar!") || jarFilePath.endsWith(".jar")) { // if in jar, and can't get artifactId from jar file, then just rollback to all delegate. - LOGGER.info(String.format("Can't find artifact id for %s, default as declared.", - jarFilePath)); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Can't find artifact id for %s, default as declared.", + jarFilePath)); return true; } else { // for not in jar, then default not delegate. - LOGGER.info(String.format( - "Can't find artifact id for %s, default as not declared.", jarFilePath)); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Can't find artifact id for %s, default as not declared.", + jarFilePath)); return false; } } @@ -497,4 +497,4 @@ private boolean isFromPlugin(String jarFilePath) { } return false; } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/model/PluginModel.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/model/PluginModel.java index aa04ae0a5..2761e2d71 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/model/PluginModel.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/model/PluginModel.java @@ -43,53 +43,62 @@ */ public class PluginModel implements Plugin { - private String pluginName; + private String pluginName; - private String groupId; + private String groupId; - private String artifactId; + private String artifactId; - private String version; + private String version; - private int priority = DEFAULT_PRECEDENCE; + private int priority = DEFAULT_PRECEDENCE; - private Set exportPackages; + /** + * 0. default as 'classLoader' for load those classes in plugin classLoader + * 1. 'override' for load those classes only as files, and those will be reload in other classLoaders. + */ + public static final String EXPORTMODE_CLASSLOADER = "classLoader"; + public static final String EXPORTMODE_OVERRIDE = "override"; + public static final String EXPORTMODE_UNKNOWN = "unknown"; + private String exportMode = EXPORTMODE_CLASSLOADER; - private Set exportPackageNodes = new HashSet<>(); + private Set exportPackages; - private Set exportPackageStems = new HashSet<>(); + private Set exportPackageNodes = new HashSet<>(); - private Set exportClasses; + private Set exportPackageStems = new HashSet<>(); - private Set importPackages; + private Set exportClasses; - private Set importPackageNodes = new HashSet<>(); + private Set importPackages; - private Set importPackageStems = new HashSet<>(); + private Set importPackageNodes = new HashSet<>(); - private Set importClasses; + private Set importPackageStems = new HashSet<>(); - private Set importResources = new HashSet<>(); + private Set importClasses; - private Set importPrefixResourceStems = new HashSet<>(); - private Set importSuffixResourceStems = new HashSet<>(); + private Set importResources = new HashSet<>(); - private Set exportResources = new HashSet<>(); + private Set importPrefixResourceStems = new HashSet<>(); + private Set importSuffixResourceStems = new HashSet<>(); - private Set exportPrefixResourceStems = new HashSet<>(); - private Set exportSuffixResourceStems = new HashSet<>(); + private Set exportResources = new HashSet<>(); - private String activator; + private Set exportPrefixResourceStems = new HashSet<>(); + private Set exportSuffixResourceStems = new HashSet<>(); - private URL[] urls; + private String activator; - private URL pluginUrl; + private URL[] urls; - private ClassLoader pluginClassLoader; + private URL pluginUrl; - private PluginContext pluginContext; + private ClassLoader pluginClassLoader; - private PluginActivator pluginActivator; + private PluginContext pluginContext; + + private PluginActivator pluginActivator; public PluginModel setPluginName(String pluginName) { this.pluginName = pluginName; @@ -126,6 +135,11 @@ public PluginModel setClassPath(URL[] urls) { return this; } + public PluginModel setExportMode(String exportMode) { + this.exportMode = exportMode; + return this; + } + public PluginModel setExportPackages(String exportPackages) { this.exportPackages = StringUtils.strToSet(exportPackages, Constants.MANIFEST_VALUE_SPLIT); ParseUtils.parsePackageNodeAndStem(this.exportPackages, this.exportPackageStems, @@ -232,6 +246,14 @@ public PluginContext getPluginContext() { return this.pluginContext; } + @Override + public String getExportMode() { + if (StringUtils.isEmpty(this.exportMode)) { + return EXPORTMODE_CLASSLOADER; + } + return this.exportMode; + } + @Override public Set getExportPackages() { return this.exportPackages; diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/pipeline/HandleArchiveStage.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/pipeline/HandleArchiveStage.java index ecc78fe4d..5b3e4e6dd 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/pipeline/HandleArchiveStage.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/pipeline/HandleArchiveStage.java @@ -18,7 +18,6 @@ import com.alipay.sofa.ark.api.ArkClient; import com.alipay.sofa.ark.api.ArkConfigs; -import com.alipay.sofa.ark.common.log.ArkLogger; import com.alipay.sofa.ark.common.log.ArkLoggerFactory; import com.alipay.sofa.ark.common.util.AssertUtils; import com.alipay.sofa.ark.common.util.StringUtils; @@ -46,14 +45,7 @@ import java.util.Set; import java.util.jar.Attributes; -import static com.alipay.sofa.ark.spi.constant.Constants.ARK_BIZ_NAME; -import static com.alipay.sofa.ark.spi.constant.Constants.BIZ_ACTIVE_EXCLUDE; -import static com.alipay.sofa.ark.spi.constant.Constants.BIZ_ACTIVE_INCLUDE; -import static com.alipay.sofa.ark.spi.constant.Constants.COMMA_SPLIT; -import static com.alipay.sofa.ark.spi.constant.Constants.INJECT_EXPORT_PACKAGES; -import static com.alipay.sofa.ark.spi.constant.Constants.MANIFEST_VALUE_SPLIT; -import static com.alipay.sofa.ark.spi.constant.Constants.PLUGIN_ACTIVE_EXCLUDE; -import static com.alipay.sofa.ark.spi.constant.Constants.PLUGIN_ACTIVE_INCLUDE; +import static com.alipay.sofa.ark.spi.constant.Constants.*; /** * response to handle executable fat jar, parse plugin model and biz model from it @@ -63,19 +55,18 @@ */ @Singleton public class HandleArchiveStage implements PipelineStage { - private final static ArkLogger LOGGER = ArkLoggerFactory.getDefaultLogger(); @Inject - private PluginManagerService pluginManagerService; + private PluginManagerService pluginManagerService; @Inject - private PluginFactoryService pluginFactoryService; + private PluginFactoryService pluginFactoryService; @Inject - private BizManagerService bizManagerService; + private BizManagerService bizManagerService; @Inject - private BizFactoryService bizFactoryService; + private BizFactoryService bizFactoryService; @Override public void process(PipelineContext pipelineContext) throws ArkRuntimeException { @@ -96,6 +87,7 @@ public void process(PipelineContext pipelineContext) throws ArkRuntimeException int bizCount = 0; for (BizArchive bizArchive : bizArchives) { + // NOTE: biz name can not be null! Biz biz = bizFactoryService.createBiz(bizArchive); if (bizArchive instanceof DirectoryBizArchive) { if (!((DirectoryBizArchive) bizArchive).isTestMode()) { @@ -107,7 +99,8 @@ public void process(PipelineContext pipelineContext) throws ArkRuntimeException bizManagerService.registerBiz(biz); bizCount += 1; } else { - LOGGER.warn("The biz of {} is ignored when using dynamic config.", + ArkLoggerFactory.getDefaultLogger().warn( + "The biz of {} is ignored when using dynamic config.", biz.getIdentity()); } } else { @@ -115,7 +108,8 @@ public void process(PipelineContext pipelineContext) throws ArkRuntimeException bizManagerService.registerBiz(biz); bizCount += 1; } else { - LOGGER.warn(String.format("The biz of %s is excluded.", biz.getIdentity())); + ArkLoggerFactory.getDefaultLogger().warn( + String.format("The biz of %s is excluded.", biz.getIdentity())); } } } @@ -162,8 +156,8 @@ public void process(PipelineContext pipelineContext) throws ArkRuntimeException if (!isPluginExcluded(plugin)) { pluginManagerService.registerPlugin(plugin); } else { - LOGGER.warn(String.format("The plugin of %s is excluded.", - plugin.getPluginName())); + ArkLoggerFactory.getDefaultLogger().warn( + String.format("The plugin of %s is excluded.", plugin.getPluginName())); } } @@ -186,7 +180,8 @@ protected void processEmbed(PipelineContext pipelineContext) throws Exception { if (!isPluginExcluded(plugin)) { pluginManagerService.registerPlugin(plugin); } else { - LOGGER.warn(String.format("The plugin of %s is excluded.", plugin.getPluginName())); + ArkLoggerFactory.getDefaultLogger().warn( + String.format("The plugin of %s is excluded.", plugin.getPluginName())); } } } @@ -233,4 +228,4 @@ public boolean isBizExcluded(Biz biz) { public boolean useDynamicConfig() { return !StringUtils.isEmpty(ArkConfigs.getStringValue(Constants.CONFIG_SERVER_ADDRESS)); } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/pipeline/StandardPipeline.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/pipeline/StandardPipeline.java index 3658421c6..c5b6bf952 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/pipeline/StandardPipeline.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/pipeline/StandardPipeline.java @@ -38,8 +38,7 @@ @Singleton public class StandardPipeline implements Pipeline { - private static final ArkLogger LOGGER = ArkLoggerFactory.getDefaultLogger(); - private List stages = new ArrayList<>(); + private List stages = new ArrayList<>(); public StandardPipeline() { initializePipeline(); @@ -70,16 +69,19 @@ public Pipeline addPipelineStage(PipelineStage pipelineStage) { public void process(PipelineContext pipelineContext) throws ArkRuntimeException { for (PipelineStage pipelineStage : stages) { try { - LOGGER.info(String.format("Start to process pipeline stage: %s", pipelineStage - .getClass().getName())); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Start to process pipeline stage: %s", pipelineStage.getClass() + .getName())); pipelineStage.process(pipelineContext); - LOGGER.info(String.format("Finish to process pipeline stage: %s", pipelineStage - .getClass().getName())); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Finish to process pipeline stage: %s", pipelineStage.getClass() + .getName())); } catch (Throwable e) { - LOGGER.error(String.format("Process pipeline stage fail: %s", pipelineStage - .getClass().getName()), e); + ArkLoggerFactory.getDefaultLogger().error( + String.format("Process pipeline stage fail: %s", pipelineStage.getClass() + .getName()), e); throw new ArkRuntimeException(e); } } } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/ArkServiceContainer.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/ArkServiceContainer.java index bc28902d5..0597315a0 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/ArkServiceContainer.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/ArkServiceContainer.java @@ -18,7 +18,6 @@ import com.alipay.sofa.ark.api.ArkClient; import com.alipay.sofa.ark.common.guice.AbstractArkGuiceModule; -import com.alipay.sofa.ark.common.log.ArkLogger; import com.alipay.sofa.ark.common.log.ArkLoggerFactory; import com.alipay.sofa.ark.common.util.ClassLoaderUtils; import com.alipay.sofa.ark.common.util.OrderComparator; @@ -48,16 +47,14 @@ */ public class ArkServiceContainer { - private Injector injector; + private Injector injector; - private List arkServiceList = new ArrayList<>(); + private List arkServiceList = new ArrayList<>(); - private AtomicBoolean started = new AtomicBoolean(false); - private AtomicBoolean stopped = new AtomicBoolean(false); + private AtomicBoolean started = new AtomicBoolean(false); + private AtomicBoolean stopped = new AtomicBoolean(false); - private final String[] arguments; - - private static final ArkLogger LOGGER = ArkLoggerFactory.getDefaultLogger(); + private final String[] arguments; public ArkServiceContainer(String[] arguments) { this.arguments = arguments; @@ -73,7 +70,7 @@ public void start() throws ArkRuntimeException { ClassLoader oldClassLoader = ClassLoaderUtils.pushContextClassLoader(getClass() .getClassLoader()); try { - LOGGER.info("Begin to start ArkServiceContainer"); + ArkLoggerFactory.getDefaultLogger().info("Begin to start ArkServiceContainer"); injector = Guice.createInjector(findServiceModules()); for (Binding binding : injector @@ -84,7 +81,8 @@ public void start() throws ArkRuntimeException { Collections.sort(arkServiceList, new OrderComparator()); for (ArkService arkService : arkServiceList) { - LOGGER.info(String.format("Init Service: %s", arkService.getClass().getName())); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Init Service: %s", arkService.getClass().getName())); arkService.init(); } @@ -95,7 +93,7 @@ public void start() throws ArkRuntimeException { ArkClient.setEventAdminService(getService(EventAdminService.class)); ArkClient.setPluginManagerService(getService(PluginManagerService.class)); ArkClient.setArguments(arguments); - LOGGER.info("Finish to start ArkServiceContainer"); + ArkLoggerFactory.getDefaultLogger().info("Finish to start ArkServiceContainer"); } finally { ClassLoaderUtils.popContextClassLoader(oldClassLoader); } @@ -134,18 +132,18 @@ public T getService(Class clazz) { */ public void stop() throws ArkRuntimeException { if (stopped.compareAndSet(false, true)) { - LOGGER.info("Begin to stop ArkServiceContainer"); + ArkLoggerFactory.getDefaultLogger().info("Begin to stop ArkServiceContainer"); ClassLoader oldClassLoader = ClassLoaderUtils.pushContextClassLoader(getClass() .getClassLoader()); try { Collections.reverse(arkServiceList); for (ArkService arkService : arkServiceList) { - LOGGER.info(String.format("Dispose service: %s", arkService.getClass() - .getName())); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Dispose service: %s", arkService.getClass().getName())); arkService.dispose(); } - LOGGER.info("Finish to stop ArkServiceContainer"); + ArkLoggerFactory.getDefaultLogger().info("Finish to stop ArkServiceContainer"); } finally { ClassLoaderUtils.popContextClassLoader(oldClassLoader); } @@ -170,4 +168,4 @@ public boolean isRunning() { return isStarted() && !stopped.get(); } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizCommandProvider.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizCommandProvider.java index cebdc0ae6..aa05a7f46 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizCommandProvider.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizCommandProvider.java @@ -28,7 +28,6 @@ import com.alipay.sofa.ark.spi.service.ArkInject; import com.alipay.sofa.ark.spi.service.biz.BizManagerService; import com.alipay.sofa.ark.spi.service.session.CommandProvider; -import org.slf4j.Logger; import java.net.URL; import java.util.HashSet; @@ -42,8 +41,6 @@ */ public class BizCommandProvider implements CommandProvider { - private Logger LOGGER = ArkLoggerFactory.getDefaultLogger(); - @ArkInject private BizManagerService bizManagerService; @@ -62,17 +59,17 @@ public boolean validate(String command) { return new BizCommand(command).isValidate(); } - private static final String HELP_MESSAGE = "Biz Command Tips:\n" - + " USAGE: biz [option...] [arguments...]\n" - + " SAMPLE: biz -m bizIdentityA bizIdentityB.\n" - + " -h Shows the help message.\n" - + " -a Shows all biz.\n" - + " -m Shows the meta info of specified bizIdentity.\n" - + " -s Shows the service info of specified bizIdentity.\n" - + " -d Shows the detail info of specified bizIdentity.\n" - + " -i Install biz of specified bizIdentity or bizUrl.\n" - + " -u Uninstall biz of specified bizIdentity.\n" - + " -o Switch biz of specified bizIdentity.\n"; + static final String HELP_MESSAGE = "Biz Command Tips:\n" + + " USAGE: biz [option...] [arguments...]\n" + + " SAMPLE: biz -m bizIdentityA bizIdentityB.\n" + + " -h Shows the help message.\n" + + " -a Shows all biz.\n" + + " -m Shows the meta info of specified bizIdentity.\n" + + " -s Shows the service info of specified bizIdentity.\n" + + " -d Shows the detail info of specified bizIdentity.\n" + + " -i Install biz of specified bizIdentity or bizUrl.\n" + + " -u Uninstall biz of specified bizIdentity.\n" + + " -o Switch biz of specified bizIdentity.\n"; class BizCommand { private boolean isValidate; @@ -239,7 +236,8 @@ public void run() { } catch (Throwable t) { String[] nameAndVersion = param.split(Constants.STRING_COLON); if (nameAndVersion.length != 2) { - LOGGER.error("Invalid telnet biz install command {}", param); + ArkLoggerFactory.getDefaultLogger().error( + "Invalid telnet biz install command {}", param); return; } bizOperation.setBizName(nameAndVersion[0]).setBizVersion( @@ -248,8 +246,8 @@ public void run() { try { ArkClient.installOperation(bizOperation); } catch (Throwable throwable) { - LOGGER.error("Fail to process telnet install command: " + param, - throwable); + ArkLoggerFactory.getDefaultLogger().error( + "Fail to process telnet install command: " + param, throwable); } } }); @@ -269,14 +267,15 @@ public void run() { String param = parameters.toArray(new String[] {})[0]; String[] nameAndVersion = param.split(Constants.STRING_COLON); if (nameAndVersion.length != 2) { - LOGGER.error("Invalid telnet biz uninstall command {}", param); + ArkLoggerFactory.getDefaultLogger().error( + "Invalid telnet biz uninstall command {}", param); return; } try { ArkClient.uninstallBiz(nameAndVersion[0], nameAndVersion[1]); } catch (Throwable throwable) { - LOGGER.error("Fail to process telnet uninstall command: " + param, - throwable); + ArkLoggerFactory.getDefaultLogger().error( + "Fail to process telnet uninstall command: " + param, throwable); } } }); @@ -291,14 +290,15 @@ public void run() { String param = parameters.toArray(new String[] {})[0]; String[] nameAndVersion = param.split(Constants.STRING_COLON); if (nameAndVersion.length != 2) { - LOGGER.error("Invalid telnet biz switch command {}", param); + ArkLoggerFactory.getDefaultLogger().error( + "Invalid telnet biz switch command {}", param); return; } try { ArkClient.switchBiz(nameAndVersion[0], nameAndVersion[1]); } catch (Throwable throwable) { - LOGGER.error("Fail to process telnet switch command: " + param, - throwable); + ArkLoggerFactory.getDefaultLogger().error( + "Fail to process telnet switch command: " + param, throwable); } } }); @@ -364,4 +364,4 @@ String join(URL[] urls, String separator) { return StringUtils.setToStr(set, separator, "\\"); } } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizDeployServiceImpl.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizDeployServiceImpl.java index 512d05844..0b8962f81 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizDeployServiceImpl.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizDeployServiceImpl.java @@ -36,12 +36,10 @@ @Singleton public class BizDeployServiceImpl implements BizDeployService { - private static final ArkLogger LOGGER = ArkLoggerFactory.getDefaultLogger(); - @Inject - private RegistryService registryService; + private RegistryService registryService; - private BizDeployer bizDeployer; + private BizDeployer bizDeployer; @Override public void deploy(String[] args) throws ArkRuntimeException { @@ -49,7 +47,8 @@ public void deploy(String[] args) throws ArkRuntimeException { .referenceService(BizDeployer.class); bizDeployer = serviceReference.getService(); - LOGGER.info(String.format("BizDeployer=\'%s\' is starting.", bizDeployer.getDesc())); + ArkLoggerFactory.getDefaultLogger().info( + String.format("BizDeployer=\'%s\' is starting.", bizDeployer.getDesc())); bizDeployer.init(args); bizDeployer.deploy(); @@ -58,7 +57,8 @@ public void deploy(String[] args) throws ArkRuntimeException { @Override public void unDeploy() throws ArkRuntimeException { if (bizDeployer != null) { - LOGGER.info(String.format("BizDeployer=\'%s\' is stopping.", bizDeployer.getDesc())); + ArkLoggerFactory.getDefaultLogger().info( + String.format("BizDeployer=\'%s\' is stopping.", bizDeployer.getDesc())); bizDeployer.unDeploy(); } } @@ -77,4 +77,4 @@ public void dispose() throws ArkRuntimeException { public int getPriority() { return DEFAULT_PRECEDENCE; } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizFactoryServiceImpl.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizFactoryServiceImpl.java index 06400000c..c10fea6e3 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizFactoryServiceImpl.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizFactoryServiceImpl.java @@ -109,7 +109,7 @@ public Biz createBiz(BizArchive bizArchive) throws IOException { public Biz createBiz(File file) throws IOException { BizArchive bizArchive; if (ArkConfigs.isEmbedEnable()) { - File unpackFile = new File(file.getAbsolutePath() + "-unpack"); + File unpackFile = FileUtils.file(file.getAbsolutePath() + "-unpack"); if (!unpackFile.exists()) { unpackFile = FileUtils.unzip(file, file.getAbsolutePath() + "-unpack"); } diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizManagerServiceImpl.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizManagerServiceImpl.java index 2cd9eb5c2..96a1477fc 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizManagerServiceImpl.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/BizManagerServiceImpl.java @@ -216,4 +216,4 @@ public boolean removeAndAddBiz(Biz addingBiz, Biz removingBiz) { public ConcurrentHashMap> getBizRegistration() { return bizRegistration; } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/DefaultBizDeployer.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/DefaultBizDeployer.java index c077ffed7..89f4c4b41 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/DefaultBizDeployer.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/biz/DefaultBizDeployer.java @@ -17,7 +17,6 @@ package com.alipay.sofa.ark.container.service.biz; import com.alipay.sofa.ark.api.ArkConfigs; -import com.alipay.sofa.ark.common.log.ArkLogger; import com.alipay.sofa.ark.common.log.ArkLoggerFactory; import com.alipay.sofa.ark.exception.ArkRuntimeException; import com.alipay.sofa.ark.spi.model.Biz; @@ -35,11 +34,9 @@ public class DefaultBizDeployer implements BizDeployer { @ArkInject - private BizManagerService bizManagerService; + private BizManagerService bizManagerService; - private String[] arguments; - - private static final ArkLogger LOGGER = ArkLoggerFactory.getDefaultLogger(); + private String[] arguments; @Override public void init(String[] args) { @@ -53,11 +50,14 @@ public void deploy() { continue; } try { - LOGGER.info(String.format("Begin to start biz: %s", biz.getBizName())); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Begin to start biz: %s", biz.getBizName())); biz.start(arguments); - LOGGER.info(String.format("Finish to start biz: %s", biz.getBizName())); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Finish to start biz: %s", biz.getBizName())); } catch (Throwable e) { - LOGGER.error(String.format("Start biz: %s meet error", biz.getBizName()), e); + ArkLoggerFactory.getDefaultLogger().error( + String.format("Start biz: %s meet error", biz.getBizName()), e); throw new ArkRuntimeException(e); } } @@ -67,11 +67,14 @@ public void deploy() { public void unDeploy() { for (Biz biz : bizManagerService.getBizInOrder()) { try { - LOGGER.info(String.format("Begin to stop biz: %s", biz.getBizName())); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Begin to stop biz: %s", biz.getBizName())); biz.stop(); - LOGGER.info(String.format("Finish to stop biz: %s", biz.getBizName())); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Finish to stop biz: %s", biz.getBizName())); } catch (Throwable e) { - LOGGER.error(String.format("stop biz: %s meet error", biz.getBizName()), e); + ArkLoggerFactory.getDefaultLogger().error( + String.format("stop biz: %s meet error", biz.getBizName()), e); throw new ArkRuntimeException(e); } } @@ -87,4 +90,4 @@ public String getDesc() { "Ark Container"); } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/classloader/AbstractClasspathClassLoader.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/classloader/AbstractClasspathClassLoader.java index ea8e13c34..20f59e7c2 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/classloader/AbstractClasspathClassLoader.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/classloader/AbstractClasspathClassLoader.java @@ -21,6 +21,7 @@ import com.alipay.sofa.ark.common.log.ArkLoggerFactory; import com.alipay.sofa.ark.common.util.StringUtils; import com.alipay.sofa.ark.container.model.BizModel; +import com.alipay.sofa.ark.container.model.PluginModel; import com.alipay.sofa.ark.container.service.ArkServiceContainerHolder; import com.alipay.sofa.ark.exception.ArkLoaderException; import com.alipay.sofa.ark.loader.jar.Handler; @@ -28,15 +29,25 @@ import com.alipay.sofa.ark.spi.constant.Constants; import com.alipay.sofa.ark.spi.service.classloader.ClassLoaderService; import com.google.common.cache.Cache; +import org.apache.commons.io.FileUtils; +import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.net.JarURLConnection; import java.net.URL; import java.net.URLClassLoader; import java.net.URLConnection; import java.security.AccessController; import java.security.PrivilegedExceptionAction; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.jar.JarFile; @@ -217,7 +228,9 @@ protected Class loadClassWithCache(String name, boolean resolve) throws ArkLo return resultInCache.getClazz(); } catch (ExecutionException e) { - throw new ArkLoaderException(String.format("[Ark Loader] unexpected exception when load class: %s", name), e.getCause()); + throw new ArkLoaderException( + String.format("[Ark Loader] unexpected exception when load class: %s", name), + e.getCause()); } } @@ -398,6 +411,51 @@ protected Class resolveJDKClass(String name) { * @return */ protected Class resolveExportClass(String name) { + if (!PluginModel.EXPORTMODE_OVERRIDE.equals(classloaderService.getExportMode(name))) { + return doResolveExportClass(name); + } else { + ClassLoader classLoader = classloaderService.findExportClassLoader(name); + URL url = classLoader.getResource(name.replace('.', '/') + ".class"); + if (url != null) { + String filePath = url.getFile().replaceFirst("file:", ""); + try { + byte[] bytes; + if (filePath.contains(".jar")) { + bytes = getClassBytesFromJar(filePath, name.replace('.', '/') + ".class"); + } else { + bytes = FileUtils.readFileToByteArray(new File(filePath)); + } + return defineClass(name, bytes, 0, bytes.length); + } catch (Exception e) { + ArkLoggerFactory.getDefaultLogger().warn( + String.format("can't convert class to reLoad by bizClassLoader: %s", + e.getMessage())); + throw new RuntimeException(e); + } + } else { + return null; + } + } + } + + private byte[] getClassBytesFromJar(String jarFilePath, String className) throws IOException { + com.alipay.sofa.ark.loader.jar.JarFile jarFile = JarUtils + .getNestedRootJarFromJarLocation(jarFilePath); + try (InputStream inputStream = jarFile.getInputStream(jarFile.getJarEntry(className))) { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + int bufferSize = 4096; + byte[] buffer = new byte[bufferSize]; + int bytesRead; + + while ((bytesRead = inputStream.read(buffer, 0, bufferSize)) != -1) { + byteArrayOutputStream.write(buffer, 0, bytesRead); + } + + return byteArrayOutputStream.toByteArray(); + } + } + + private Class doResolveExportClass(String name) { if (shouldFindExportedClass(name)) { ClassLoader importClassLoader = classloaderService.findExportClassLoader(name); if (importClassLoader != null) { @@ -430,7 +488,7 @@ protected Class resolveExportClass(String name) { } else { return clazz; } - } catch (ClassNotFoundException | IOException e) { + } catch (ClassNotFoundException | NoClassDefFoundError | IOException e) { // just log when debug level if (ArkLoggerFactory.getDefaultLogger().isDebugEnabled()) { // log debug message diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/classloader/ClassLoaderServiceImpl.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/classloader/ClassLoaderServiceImpl.java index bb494c736..310c0a1e8 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/classloader/ClassLoaderServiceImpl.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/classloader/ClassLoaderServiceImpl.java @@ -16,12 +16,14 @@ */ package com.alipay.sofa.ark.container.service.classloader; +import com.alipay.sofa.ark.api.ArkClient; import com.alipay.sofa.ark.bootstrap.AgentClassLoader; import com.alipay.sofa.ark.common.log.ArkLogger; import com.alipay.sofa.ark.common.log.ArkLoggerFactory; import com.alipay.sofa.ark.common.util.AssertUtils; import com.alipay.sofa.ark.common.util.ClassLoaderUtils; import com.alipay.sofa.ark.common.util.ClassUtils; +import com.alipay.sofa.ark.container.model.PluginModel; import com.alipay.sofa.ark.exception.ArkRuntimeException; import com.alipay.sofa.ark.spi.constant.Constants; import com.alipay.sofa.ark.spi.model.Biz; @@ -38,6 +40,7 @@ import java.util.LinkedList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; /** * ClassLoader Service Implementation @@ -48,36 +51,33 @@ @Singleton public class ClassLoaderServiceImpl implements ClassLoaderService { - private static final ArkLogger LOGGER = ArkLoggerFactory - .getDefaultLogger(); + private static final String ARK_SPI_PACKAGES = "com.alipay.sofa.ark.spi"; + private static final String ARK_API_PACKAGES = "com.alipay.sofa.ark.api"; + private static final String ARK_LOG_PACKAGES = "com.alipay.sofa.ark.common.log"; + private static final String ARK_EXCEPTION_PACKAGES = "com.alipay.sofa.ark.exception"; - private static final String ARK_SPI_PACKAGES = "com.alipay.sofa.ark.spi"; - private static final String ARK_API_PACKAGES = "com.alipay.sofa.ark.api"; - private static final String ARK_LOG_PACKAGES = "com.alipay.sofa.ark.common.log"; - private static final String ARK_EXCEPTION_PACKAGES = "com.alipay.sofa.ark.exception"; - - private static final List SUN_REFLECT_GENERATED_ACCESSOR = new ArrayList<>(); + private static final List SUN_REFLECT_GENERATED_ACCESSOR = new ArrayList<>(); /* export class and classloader relationship cache */ - private ConcurrentHashMap exportClassAndClassLoaderMap = new ConcurrentHashMap<>(); - private ConcurrentHashMap exportNodeAndClassLoaderMap = new ConcurrentHashMap<>(); - private ConcurrentHashMap exportStemAndClassLoaderMap = new ConcurrentHashMap<>(); + private ConcurrentHashMap exportClassAndClassLoaderMap = new ConcurrentHashMap<>(); + private ConcurrentHashMap exportNodeAndClassLoaderMap = new ConcurrentHashMap<>(); + private ConcurrentHashMap exportStemAndClassLoaderMap = new ConcurrentHashMap<>(); /* export cache and classloader relationship cache */ - private ConcurrentHashMap> exportResourceAndClassLoaderMap = new ConcurrentHashMap<>(); - private ConcurrentHashMap> exportPrefixStemResourceAndClassLoaderMap = new ConcurrentHashMap<>(); - private ConcurrentHashMap> exportSuffixStemResourceAndClassLoaderMap = new ConcurrentHashMap<>(); + private ConcurrentHashMap> exportResourceAndClassLoaderMap = new ConcurrentHashMap<>(); + private ConcurrentHashMap> exportPrefixStemResourceAndClassLoaderMap = new ConcurrentHashMap<>(); + private ConcurrentHashMap> exportSuffixStemResourceAndClassLoaderMap = new ConcurrentHashMap<>(); - private ClassLoader jdkClassLoader; - private ClassLoader arkClassLoader; - private ClassLoader systemClassLoader; - private ClassLoader agentClassLoader; + private ClassLoader jdkClassLoader; + private ClassLoader arkClassLoader; + private ClassLoader systemClassLoader; + private ClassLoader agentClassLoader; @Inject - private PluginManagerService pluginManagerService; + private PluginManagerService pluginManagerService; @Inject - private BizManagerService bizManagerService; + private BizManagerService bizManagerService; static { SUN_REFLECT_GENERATED_ACCESSOR.add("sun.reflect.GeneratedMethodAccessor"); @@ -119,28 +119,25 @@ public boolean isArkExceptionClass(String className) { public void prepareExportClassAndResourceCache() { for (Plugin plugin : pluginManagerService.getPluginsInOrder()) { for (String exportIndex : plugin.getExportPackageNodes()) { - exportNodeAndClassLoaderMap.putIfAbsent(exportIndex, plugin.getPluginClassLoader()); + exportNodeAndClassLoaderMap.putIfAbsent(exportIndex, plugin); } for (String exportIndex : plugin.getExportPackageStems()) { - exportStemAndClassLoaderMap.putIfAbsent(exportIndex, plugin.getPluginClassLoader()); + exportStemAndClassLoaderMap.putIfAbsent(exportIndex, plugin); } for (String exportIndex : plugin.getExportClasses()) { - exportClassAndClassLoaderMap - .putIfAbsent(exportIndex, plugin.getPluginClassLoader()); + exportClassAndClassLoaderMap.putIfAbsent(exportIndex, plugin); } for (String resource : plugin.getExportResources()) { exportResourceAndClassLoaderMap.putIfAbsent(resource, new LinkedList<>()); - exportResourceAndClassLoaderMap.get(resource).add(plugin.getPluginClassLoader()); + exportResourceAndClassLoaderMap.get(resource).add(plugin); } for (String resource : plugin.getExportPrefixResourceStems()) { exportPrefixStemResourceAndClassLoaderMap.putIfAbsent(resource, new LinkedList<>()); - exportPrefixStemResourceAndClassLoaderMap.get(resource).add( - plugin.getPluginClassLoader()); + exportPrefixStemResourceAndClassLoaderMap.get(resource).add(plugin); } for (String resource : plugin.getExportSuffixResourceStems()) { exportSuffixStemResourceAndClassLoaderMap.putIfAbsent(resource, new LinkedList<>()); - exportSuffixStemResourceAndClassLoaderMap.get(resource).add( - plugin.getPluginClassLoader()); + exportSuffixStemResourceAndClassLoaderMap.get(resource).add(plugin); } } } @@ -172,18 +169,37 @@ public boolean isClassInImport(String pluginName, String className) { return false; } + public String getExportMode(String className) { + Plugin plugin = findExportPlugin(className); + if (plugin == null) { + return PluginModel.EXPORTMODE_UNKNOWN; + } + + return plugin.getExportMode(); + } + @Override public ClassLoader findExportClassLoader(String className) { - ClassLoader exportClassLoader = exportClassAndClassLoaderMap.get(className); + Plugin plugin = findExportPlugin(className); + if (plugin != null) { + return plugin.getPluginClassLoader(); + } else { + return null; + } + } + + @Override + public Plugin findExportPlugin(String className) { + Plugin plugin = exportClassAndClassLoaderMap.get(className); String packageName = ClassUtils.getPackageName(className); - if (exportClassLoader == null) { - exportClassLoader = exportNodeAndClassLoaderMap.get(packageName); + if (plugin == null) { + plugin = exportNodeAndClassLoaderMap.get(packageName); } - while (!Constants.DEFAULT_PACKAGE.equals(packageName) && exportClassLoader == null) { - exportClassLoader = exportStemAndClassLoaderMap.get(packageName); + while (!Constants.DEFAULT_PACKAGE.equals(packageName) && plugin == null) { + plugin = exportStemAndClassLoaderMap.get(packageName); packageName = ClassUtils.getPackageName(packageName); } - return exportClassLoader; + return plugin; } @Override @@ -214,7 +230,16 @@ public boolean isResourceInImport(String pluginName, String resourceName) { @Override public List findExportResourceClassLoadersInOrder(String resourceName) { + List plugins = findExportResourcePluginsInOrder(resourceName); + + if (plugins != null) { + return plugins.stream().map(Plugin::getPluginClassLoader).collect(Collectors.toList()); + } else { + return null; + } + } + private List findExportResourcePluginsInOrder(String resourceName) { if (exportResourceAndClassLoaderMap.containsKey(resourceName)) { return exportResourceAndClassLoaderMap.get(resourceName); } @@ -259,6 +284,12 @@ public ClassLoader getBizClassLoader(String bizIdentity) { return biz == null ? null : biz.getBizClassLoader(); } + @Override + public ClassLoader getMasterBizClassLoader() { + Biz biz = ArkClient.getMasterBiz(); + return biz == null ? null : biz.getBizClassLoader(); + } + @Override public ClassLoader getPluginClassLoader(String pluginName) { Plugin plugin = pluginManagerService.getPluginByName(pluginName); @@ -281,14 +312,15 @@ public void init() throws ArkRuntimeException { URL[] urls = ClassLoaderUtils.getURLs(systemClassLoader); for (URL url : urls) { if (url.getPath().startsWith(javaHome)) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(String.format("Find JDK Url: %s", url)); + if (ArkLoggerFactory.getDefaultLogger().isDebugEnabled()) { + ArkLoggerFactory.getDefaultLogger().debug( + String.format("Find JDK Url: %s", url)); } jdkUrls.add(url); } } } catch (Throwable e) { - LOGGER.warn("Meet exception when parse JDK urls", e); + ArkLoggerFactory.getDefaultLogger().warn("Meet exception when parse JDK urls", e); } jdkClassLoader = new JDKDelegateClassLoader(jdkUrls.toArray(new URL[0]), extClassLoader); @@ -364,4 +396,4 @@ public boolean isDeniedImportResource(String bizIdentity, String resourceName) { public int getPriority() { return DEFAULT_PRECEDENCE; } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/event/EventAdminServiceImpl.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/event/EventAdminServiceImpl.java index 28d1d6e3a..f4234cd13 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/event/EventAdminServiceImpl.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/event/EventAdminServiceImpl.java @@ -28,7 +28,6 @@ import com.alipay.sofa.ark.spi.service.registry.RegistryService; import com.google.inject.Inject; import com.google.inject.Singleton; -import org.slf4j.Logger; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -48,9 +47,6 @@ public class EventAdminServiceImpl implements EventAdminService, EventHandler { private final static ConcurrentMap> SUBSCRIBER_MAP = new ConcurrentHashMap<>(); - private final static Logger LOGGER = ArkLoggerFactory - .getDefaultLogger(); - @Inject private RegistryService registryService; @@ -89,7 +85,8 @@ public void register(EventHandler eventHandler) { } } set.add(eventHandler); - LOGGER.debug(String.format("Register event handler: %s.", eventHandler)); + ArkLoggerFactory.getDefaultLogger().debug( + String.format("Register event handler: %s.", eventHandler)); } @Override @@ -98,14 +95,16 @@ public void unRegister(EventHandler eventHandler) { .getClassLoader()); if (set != null) { set.remove(eventHandler); - LOGGER.debug(String.format("Unregister event handler: %s.", eventHandler)); + ArkLoggerFactory.getDefaultLogger().debug( + String.format("Unregister event handler: %s.", eventHandler)); } } @Override public void unRegister(ClassLoader classLoader) { SUBSCRIBER_MAP.remove(classLoader); - LOGGER.debug(String.format("Unregister event handler of classLoader: %s.", classLoader)); + ArkLoggerFactory.getDefaultLogger().debug( + String.format("Unregister event handler of classLoader: %s.", classLoader)); } @@ -178,4 +177,4 @@ private boolean checkEventHandlerType(Type type) { } return false; } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/extension/ExtensionLoaderServiceImpl.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/extension/ExtensionLoaderServiceImpl.java index f92e054e9..6744d60f9 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/extension/ExtensionLoaderServiceImpl.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/extension/ExtensionLoaderServiceImpl.java @@ -49,7 +49,6 @@ */ @Singleton public class ExtensionLoaderServiceImpl implements ExtensionLoaderService { - private static final Logger LOGGER = ArkLoggerFactory.getDefaultLogger(); private PluginManagerService pluginManagerService = ArkServiceContainerHolder.getContainer() .getService(PluginManagerService.class); @@ -93,8 +92,9 @@ public T getExtensionContributor(Class interfaceType, String extension } } } catch (Throwable throwable) { - LOGGER.error("Loading extension of interfaceType: {} occurs error {}.", interfaceType, - throwable); + ArkLoggerFactory.getDefaultLogger() + .error("Loading extension of interfaceType: {} occurs error {}.", interfaceType, + throwable); throw new ArkRuntimeException(throwable); } return extensionClass == null ? null : extensionClass.getObject(); @@ -120,8 +120,8 @@ private Set> loadExtension(Class interfaceType, + fileName); while (enumeration.hasMoreElements()) { URL url = enumeration.nextElement(); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug( + if (ArkLoggerFactory.getDefaultLogger().isDebugEnabled()) { + ArkLoggerFactory.getDefaultLogger().debug( "Loading extension of extensible: {} from location: {} and file: {}", interfaceType, location, url); } @@ -166,8 +166,8 @@ private Set> loadExtension(Class interfaceType, } return extensionClassSet; } catch (Throwable throwable) { - LOGGER - .error("Loading extension files from {} occurs an error {}.", location, throwable); + ArkLoggerFactory.getDefaultLogger().error( + "Loading extension files from {} occurs an error {}.", location, throwable); throw throwable; } finally { if (reader != null) { @@ -175,4 +175,4 @@ private Set> loadExtension(Class interfaceType, } } } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/injection/InjectionServiceImpl.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/injection/InjectionServiceImpl.java index 18ff28aa2..4a24c94cd 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/injection/InjectionServiceImpl.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/injection/InjectionServiceImpl.java @@ -16,7 +16,6 @@ */ package com.alipay.sofa.ark.container.service.injection; -import com.alipay.sofa.ark.common.log.ArkLogger; import com.alipay.sofa.ark.common.log.ArkLoggerFactory; import com.alipay.sofa.ark.common.util.ReflectionUtils; import com.alipay.sofa.ark.common.util.ReflectionUtils.FieldCallback; @@ -39,10 +38,8 @@ @Singleton public class InjectionServiceImpl implements InjectionService { - private static final ArkLogger LOGGER = ArkLoggerFactory.getDefaultLogger(); - @Inject - private RegistryService registryService; + private RegistryService registryService; @Override public void inject(final ServiceReference reference) { @@ -68,15 +65,17 @@ public void doWith(Field field) throws ArkRuntimeException { Object value = getService(serviceType, arkInject.uniqueId()); if (value == null) { - LOGGER.warn(String.format("Inject {field= %s} of {service= %s} fail!", - field.getName(), type)); + ArkLoggerFactory.getDefaultLogger().warn( + String.format("Inject {field= %s} of {service= %s} fail!", field.getName(), + type)); return; } ReflectionUtils.makeAccessible(field); try { field.set(instance, value); - LOGGER.info(String.format("Inject {field= %s} of {service= %s} success!", - field.getName(), type)); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Inject {field= %s} of {service= %s} success!", + field.getName(), type)); } catch (Throwable throwable) { throw new ArkRuntimeException(throwable); } @@ -88,4 +87,4 @@ private Object getService(Class serviceType, String uniqueId) { ServiceReference serviceReference = registryService.referenceService(serviceType, uniqueId); return serviceReference == null ? null : serviceReference.getService(); } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/plugin/PluginDeployServiceImpl.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/plugin/PluginDeployServiceImpl.java index 217031ed0..ffad92ac1 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/plugin/PluginDeployServiceImpl.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/plugin/PluginDeployServiceImpl.java @@ -16,7 +16,6 @@ */ package com.alipay.sofa.ark.container.service.plugin; -import com.alipay.sofa.ark.common.log.ArkLogger; import com.alipay.sofa.ark.common.log.ArkLoggerFactory; import com.alipay.sofa.ark.exception.ArkRuntimeException; import com.alipay.sofa.ark.spi.service.plugin.PluginManagerService; @@ -37,10 +36,8 @@ @Singleton public class PluginDeployServiceImpl implements PluginDeployService { - private static final ArkLogger LOGGER = ArkLoggerFactory.getDefaultLogger(); - @Inject - PluginManagerService pluginManagerService; + PluginManagerService pluginManagerService; @Override public void deploy() throws ArkRuntimeException { @@ -48,8 +45,8 @@ public void deploy() throws ArkRuntimeException { try { deployPlugin(plugin); } catch (ArkRuntimeException e) { - LOGGER.error(String.format("Deploy plugin: %s meet error", plugin.getPluginName()), - e); + ArkLoggerFactory.getDefaultLogger().error( + String.format("Deploy plugin: %s meet error", plugin.getPluginName()), e); throw e; } } @@ -57,11 +54,14 @@ public void deploy() throws ArkRuntimeException { private void deployPlugin(Plugin plugin) throws ArkRuntimeException { try { - LOGGER.info(String.format("Start to deploy plugin: %s", plugin.getPluginName())); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Start to deploy plugin: %s", plugin.getPluginName())); plugin.start(); - LOGGER.info(String.format("Finish to deploy plugin: %s", plugin.getPluginName())); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Finish to deploy plugin: %s", plugin.getPluginName())); } catch (ArkRuntimeException e) { - LOGGER.error(String.format("Start plugin: %s meet error", plugin.getPluginName()), e); + ArkLoggerFactory.getDefaultLogger().error( + String.format("Start plugin: %s meet error", plugin.getPluginName()), e); throw e; } } @@ -74,7 +74,7 @@ public void unDeploy() throws ArkRuntimeException { try { unDeployPlugin(plugin); } catch (ArkRuntimeException e) { - LOGGER.error( + ArkLoggerFactory.getDefaultLogger().error( String.format("UnDeploy plugin: %s meet error", plugin.getPluginName()), e); throw e; } @@ -83,13 +83,16 @@ public void unDeploy() throws ArkRuntimeException { private void unDeployPlugin(Plugin plugin) throws ArkRuntimeException { try { - LOGGER.info(String.format("Start to unDeploy plugin: %s", plugin.getPluginName()) + ArkLoggerFactory.getDefaultLogger().info( + String.format("Start to unDeploy plugin: %s", plugin.getPluginName()) + plugin.getPluginName()); plugin.stop(); - LOGGER.info(String.format("Stop to unDeploy plugin: %s", plugin.getPluginName()) + ArkLoggerFactory.getDefaultLogger().info( + String.format("Stop to unDeploy plugin: %s", plugin.getPluginName()) + plugin.getPluginName()); } catch (ArkRuntimeException e) { - LOGGER.error(String.format("Stop plugin: %s meet error", plugin.getPluginName()), e); + ArkLoggerFactory.getDefaultLogger().error( + String.format("Stop plugin: %s meet error", plugin.getPluginName()), e); throw e; } } @@ -108,4 +111,4 @@ public void dispose() throws ArkRuntimeException { public int getPriority() { return DEFAULT_PRECEDENCE; } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/plugin/PluginFactoryServiceImpl.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/plugin/PluginFactoryServiceImpl.java index 41d1d27ae..0e5448ca8 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/plugin/PluginFactoryServiceImpl.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/plugin/PluginFactoryServiceImpl.java @@ -36,7 +36,6 @@ import java.io.File; import java.io.IOException; import java.net.URL; -import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -46,6 +45,7 @@ import static com.alipay.sofa.ark.spi.constant.Constants.ACTIVATOR_ATTRIBUTE; import static com.alipay.sofa.ark.spi.constant.Constants.ARTIFACT_ID_ATTRIBUTE; import static com.alipay.sofa.ark.spi.constant.Constants.EXPORT_CLASSES_ATTRIBUTE; +import static com.alipay.sofa.ark.spi.constant.Constants.EXPORT_MODE; import static com.alipay.sofa.ark.spi.constant.Constants.EXPORT_PACKAGES_ATTRIBUTE; import static com.alipay.sofa.ark.spi.constant.Constants.EXPORT_RESOURCES_ATTRIBUTE; import static com.alipay.sofa.ark.spi.constant.Constants.GROUP_ID_ATTRIBUTE; @@ -116,6 +116,7 @@ public Plugin createPlugin(PluginArchive pluginArchive, URL[] extensions, .setPluginActivator(manifestMainAttributes.getValue(ACTIVATOR_ATTRIBUTE)) .setClassPath(getFinalPluginUrls(pluginArchive, extensions, plugin.getPluginName())) .setPluginUrl(pluginArchive.getUrl()) + .setExportMode(manifestMainAttributes.getValue(EXPORT_MODE)) .setExportClasses(manifestMainAttributes.getValue(EXPORT_CLASSES_ATTRIBUTE)) .setExportPackages(manifestMainAttributes.getValue(EXPORT_PACKAGES_ATTRIBUTE), exportPackages) @@ -181,6 +182,8 @@ public Plugin createEmbedPlugin(PluginArchive pluginArchive, ClassLoader masterC PluginModel plugin = new PluginModel(); Attributes manifestMainAttributes = pluginArchive.getManifest().getMainAttributes(); boolean enableExportClass = "true".equals(System.getProperty(PLUGIN_EXPORT_CLASS_ENABLE)); + boolean overrideExportMode = PluginModel.EXPORTMODE_OVERRIDE.equals(manifestMainAttributes + .getValue(EXPORT_MODE)); plugin .setPluginName(manifestMainAttributes.getValue(PLUGIN_NAME_ATTRIBUTE)) .setGroupId(manifestMainAttributes.getValue(GROUP_ID_ATTRIBUTE)) @@ -188,8 +191,11 @@ public Plugin createEmbedPlugin(PluginArchive pluginArchive, ClassLoader masterC .setVersion(manifestMainAttributes.getValue(PLUGIN_VERSION_ATTRIBUTE)) .setPriority(manifestMainAttributes.getValue(PRIORITY_ATTRIBUTE)) .setPluginActivator(manifestMainAttributes.getValue(ACTIVATOR_ATTRIBUTE)) - .setClassPath(ClassLoaderUtils.getURLs(masterClassLoader)) + .setClassPath( + overrideExportMode ? pluginArchive.getUrls() : ClassLoaderUtils + .getURLs(masterClassLoader)) .setPluginUrl(pluginArchive.getUrl()) + .setExportMode(manifestMainAttributes.getValue(EXPORT_MODE)) .setExportClasses( enableExportClass ? manifestMainAttributes.getValue(EXPORT_CLASSES_ATTRIBUTE) : null) @@ -200,7 +206,9 @@ public Plugin createEmbedPlugin(PluginArchive pluginArchive, ClassLoader masterC .setImportPackages(manifestMainAttributes.getValue(IMPORT_PACKAGES_ATTRIBUTE)) .setImportResources(manifestMainAttributes.getValue(IMPORT_RESOURCES_ATTRIBUTE)) .setExportResources(manifestMainAttributes.getValue(EXPORT_RESOURCES_ATTRIBUTE)) - .setPluginClassLoader(masterClassLoader) + .setPluginClassLoader( + overrideExportMode ? new PluginClassLoader(plugin.getPluginName(), plugin + .getClassPath()) : masterClassLoader) .setPluginContext(new PluginContextImpl(plugin)); return plugin; } diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/registry/RegistryServiceImpl.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/registry/RegistryServiceImpl.java index c865cf5a1..84e830b64 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/registry/RegistryServiceImpl.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/registry/RegistryServiceImpl.java @@ -44,8 +44,6 @@ @Singleton public class RegistryServiceImpl implements RegistryService { - private static final ArkLogger LOGGER = ArkLoggerFactory - .getDefaultLogger(); private CopyOnWriteArraySet> services = new CopyOnWriteArraySet<>(); private OrderComparator orderComparator = new OrderComparator(); @@ -72,8 +70,9 @@ public ServiceReference publishService(Class ifClass, T implObject, St serviceProvider); for (ServiceReference serviceReference : services) { if (serviceMetadata.equals(serviceReference.getServiceMetadata())) { - LOGGER.warn(String.format("Service: %s publish by: %s already exist", - serviceMetadata.getServiceName(), serviceProvider)); + ArkLoggerFactory.getDefaultLogger().warn( + String.format("Service: %s publish by: %s already exist", + serviceMetadata.getServiceName(), serviceProvider)); return (ServiceReference) serviceReference; } } @@ -82,8 +81,9 @@ public ServiceReference publishService(Class ifClass, T implObject, St implObject); injectionService.inject(serviceReference); - LOGGER.info(String.format("Service: %s publish by: %s succeed", - serviceMetadata.getServiceName(), serviceProvider)); + ArkLoggerFactory.getDefaultLogger().info( + String.format("Service: %s publish by: %s succeed", serviceMetadata.getServiceName(), + serviceProvider)); services.add(serviceReference); @@ -148,4 +148,4 @@ public int unPublishServices(ServiceFilter serviceFilter) { return count; } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/retrieval/InfoQueryCommandProvider.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/retrieval/InfoQueryCommandProvider.java index 3b6fd663e..b5a27b9dc 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/retrieval/InfoQueryCommandProvider.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/service/retrieval/InfoQueryCommandProvider.java @@ -36,8 +36,6 @@ */ public class InfoQueryCommandProvider implements CommandProvider { - private final ArkLogger LOGGER = ArkLoggerFactory.getDefaultLogger(); - @Override public String getHelp() { return HELP_MESSAGE; diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/session/NettyTelnetServer.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/session/NettyTelnetServer.java index e3056a083..07068e786 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/session/NettyTelnetServer.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/session/NettyTelnetServer.java @@ -91,7 +91,6 @@ protected void initChannel(SocketChannel channel) throws Exception { pipeline.addLast(DECODER); pipeline.addLast(new NettyTelnetHandler()); } - } static class NettyTelnetHandler extends SimpleChannelInboundHandler { diff --git a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/session/StandardTelnetServerImpl.java b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/session/StandardTelnetServerImpl.java index b5dfb20b1..243ddb498 100644 --- a/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/session/StandardTelnetServerImpl.java +++ b/sofa-ark-parent/core-impl/container/src/main/java/com/alipay/sofa/ark/container/session/StandardTelnetServerImpl.java @@ -16,7 +16,6 @@ */ package com.alipay.sofa.ark.container.session; -import com.alipay.sofa.ark.common.log.ArkLogger; import com.alipay.sofa.ark.common.log.ArkLoggerFactory; import com.alipay.sofa.ark.common.thread.CommonThreadPool; import com.alipay.sofa.ark.common.thread.ThreadPoolManager; @@ -44,19 +43,17 @@ @Singleton public class StandardTelnetServerImpl implements TelnetServerService { - private static final ArkLogger LOGGER = ArkLoggerFactory.getDefaultLogger(); + private static final int WORKER_THREAD_POOL_SIZE = 2; - private static final int WORKER_THREAD_POOL_SIZE = 2; + private int port = -1; - private int port = -1; + private AtomicBoolean shutdown = new AtomicBoolean(false); - private AtomicBoolean shutdown = new AtomicBoolean(false); + private boolean enableTelnetServer = EnvironmentUtils.getProperty( + TELNET_SERVER_ENABLE, "true") + .equalsIgnoreCase("true"); - private boolean enableTelnetServer = EnvironmentUtils.getProperty( - TELNET_SERVER_ENABLE, "true") - .equalsIgnoreCase("true"); - - private NettyTelnetServer nettyTelnetServer; + private NettyTelnetServer nettyTelnetServer; public StandardTelnetServerImpl() { if (enableTelnetServer) { @@ -69,7 +66,8 @@ public StandardTelnetServerImpl() { DEFAULT_SELECT_PORT_SIZE); } } catch (NumberFormatException e) { - LOGGER.error(String.format("Invalid port in %s", telnetPort), e); + ArkLoggerFactory.getDefaultLogger().error( + String.format("Invalid port in %s", telnetPort), e); throw new ArkRuntimeException(e); } } @@ -79,7 +77,7 @@ public StandardTelnetServerImpl() { public void run() { AssertUtils.isTrue(port > 0, "Telnet port should be positive integer."); try { - LOGGER.info("Listening on port: " + port); + ArkLoggerFactory.getDefaultLogger().info("Listening on port: " + port); CommonThreadPool workerPool = new CommonThreadPool() .setCorePoolSize(WORKER_THREAD_POOL_SIZE).setDaemon(true) .setThreadPoolName(Constants.TELNET_SERVER_WORKER_THREAD_POOL_NAME); @@ -88,7 +86,7 @@ public void run() { nettyTelnetServer = new NettyTelnetServer(port, workerPool.getExecutor()); nettyTelnetServer.open(); } catch (InterruptedException e) { - LOGGER.error("Unable to open netty telnet server.", e); + ArkLoggerFactory.getDefaultLogger().error("Unable to open netty telnet server.", e); throw new ArkRuntimeException(e); } } @@ -102,7 +100,8 @@ public void shutdown() { nettyTelnetServer = null; } } catch (Throwable t) { - LOGGER.error("An error occurs when shutdown telnet server.", t); + ArkLoggerFactory.getDefaultLogger().error( + "An error occurs when shutdown telnet server.", t); throw new ArkRuntimeException(t); } } @@ -113,7 +112,7 @@ public void init() throws ArkRuntimeException { if (enableTelnetServer) { run(); } else { - LOGGER.warn("Telnet server is disabled."); + ArkLoggerFactory.getDefaultLogger().warn("Telnet server is disabled."); } } @@ -128,4 +127,4 @@ public void dispose() throws ArkRuntimeException { public int getPriority() { return HIGHEST_PRECEDENCE; } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/ArkContainerTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/ArkContainerTest.java index fba7af47b..7f6e64abe 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/ArkContainerTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/ArkContainerTest.java @@ -16,6 +16,8 @@ */ package com.alipay.sofa.ark.container; +import com.alipay.sofa.ark.common.util.FileUtils; +import com.alipay.sofa.ark.container.session.handler.ArkCommandHandler; import com.alipay.sofa.ark.exception.ArkRuntimeException; import com.alipay.sofa.ark.loader.ExecutableArkBizJar; import com.alipay.sofa.ark.loader.archive.JarFileArchive; @@ -23,11 +25,14 @@ import org.junit.Assert; import org.junit.Test; -import java.io.File; import java.net.URL; +import static com.alipay.sofa.ark.container.ArkContainer.main; +import static com.alipay.sofa.ark.spi.constant.Constants.TELNET_SESSION_PROMPT; +import static com.alipay.sofa.ark.spi.constant.Constants.TELNET_STRING_END; +import static org.junit.Assert.*; + /** - * * @author ruoshan * @since 0.1.0 */ @@ -48,15 +53,15 @@ public void after() { @Test public void testStart() throws ArkRuntimeException { String[] args = new String[] { "-Ajar=" + jarURL.toExternalForm() }; - ArkContainer arkContainer = (ArkContainer) ArkContainer.main(args); - Assert.assertTrue(arkContainer.isStarted()); + ArkContainer arkContainer = (ArkContainer) main(args); + assertTrue(arkContainer.isStarted()); arkContainer.stop(); } @Test public void testStop() throws Exception { ArkContainer arkContainer = new ArkContainer(new ExecutableArkBizJar(new JarFileArchive( - new File((jarURL.getFile()))))); + FileUtils.file((jarURL.getFile()))))); arkContainer.start(); arkContainer.stop(); Assert.assertFalse(arkContainer.isRunning()); @@ -65,8 +70,50 @@ public void testStop() throws Exception { @Test public void testArkServiceLoader() throws ArkRuntimeException { String[] args = new String[] { "-Ajar=" + jarURL.toExternalForm() }; - ArkContainer arkContainer = (ArkContainer) ArkContainer.main(args); + ArkContainer arkContainer = (ArkContainer) main(args); Assert.assertNotNull(ArkServiceLoader.getExtensionLoaderService()); arkContainer.stop(); } -} \ No newline at end of file + + @Test + public void testResponseMessage() { + String[] args = new String[] { "-Ajar=" + jarURL.toExternalForm() }; + main(args); + ArkCommandHandler arkCommandHandler = new ArkCommandHandler(); + assertEquals(TELNET_STRING_END + TELNET_SESSION_PROMPT, + arkCommandHandler.responseMessage(null)); + assertTrue(arkCommandHandler.responseMessage("a").endsWith( + TELNET_STRING_END + TELNET_STRING_END + TELNET_SESSION_PROMPT)); + assertTrue(arkCommandHandler.responseMessage("-a").endsWith( + TELNET_STRING_END + TELNET_STRING_END + TELNET_SESSION_PROMPT)); + assertTrue(arkCommandHandler.responseMessage("biz -a").endsWith( + TELNET_STRING_END + TELNET_STRING_END + TELNET_SESSION_PROMPT)); + } + + @Test + public void testDeployBizAfterMasterBizReady() throws Exception { + String[] args = new String[] { "-Ajar=" + jarURL.toExternalForm() }; + ArkContainer arkContainer = (ArkContainer) main(args); + assertEquals(arkContainer, arkContainer.deployBizAfterMasterBizReady()); + arkContainer.stop(); + } + + @Test(expected = ArkRuntimeException.class) + public void testStartNotWithCommandLine() { + String[] args = new String[] { "-BmethodName=main", "-BclassName=a", + "-Aclasspath=" + jarURL.toString() }; + main(args); + } + + @Test + public void testOtherMethods() { + + String[] args = new String[] { "-Ajar=" + jarURL.toExternalForm() }; + ArkContainer arkContainer = (ArkContainer) main(args); + assertEquals(0, arkContainer.getProfileConfFiles("prod").size()); + + assertTrue(arkContainer.isRunning()); + assertNotNull(arkContainer.getArkServiceContainer()); + assertNotNull(arkContainer.getPipelineContext()); + } +} diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/BaseTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/BaseTest.java index e436c3a78..cfa9ce1ba 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/BaseTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/BaseTest.java @@ -27,23 +27,22 @@ import com.alipay.sofa.ark.spi.model.BizState; import com.alipay.sofa.ark.spi.model.Plugin; import com.alipay.sofa.ark.spi.service.biz.BizManagerService; -import com.alipay.sofa.ark.spi.service.extension.ArkServiceLoader; import com.alipay.sofa.ark.spi.service.extension.ExtensionLoaderService; import com.alipay.sofa.ark.spi.service.plugin.PluginManagerService; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.mockito.MockedStatic; -import org.mockito.Mockito; -import java.io.File; import java.lang.management.ManagementFactory; import java.lang.management.RuntimeMXBean; import java.net.URL; import java.util.ArrayList; import java.util.List; -import static org.mockito.Mockito.when; +import static com.alipay.sofa.ark.common.util.FileUtils.file; +import static com.alipay.sofa.ark.spi.service.extension.ArkServiceLoader.setExtensionLoaderService; +import static org.mockito.Mockito.*; /** * @@ -51,6 +50,7 @@ * @since 0.1.0 */ public class BaseTest { + private URL jarURL = ArkContainerTest.class.getClassLoader() .getResource("test.jar"); protected ArkServiceContainer arkServiceContainer = new ArkServiceContainer(new String[] {}); @@ -73,29 +73,29 @@ public static BizModel createTestBizModel(String bizName, String bizVersion, Biz @Before public void before() { + List mockArguments = new ArrayList<>(); - String filePath = this.getClass().getClassLoader() - .getResource("SampleClass.class").getPath(); - String workingPath = new File(filePath).getParent(); + String filePath = this.getClass().getClassLoader().getResource("SampleClass.class").getPath(); + String workingPath = file(filePath).getParent(); mockArguments.add(String.format("javaaget:%s", workingPath)); mockArguments.add(String.format("-javaagent:%s", workingPath)); mockArguments.add(String.format("-javaagent:%s=xx", workingPath)); - RuntimeMXBean runtimeMXBean = Mockito.mock(RuntimeMXBean.class); + RuntimeMXBean runtimeMXBean = mock(RuntimeMXBean.class); when(runtimeMXBean.getInputArguments()).thenReturn(mockArguments); when(runtimeMXBean.getName()).thenReturn(""); - managementFactoryMockedStatic = Mockito.mockStatic(ManagementFactory.class); + managementFactoryMockedStatic = mockStatic(ManagementFactory.class); managementFactoryMockedStatic.when(ManagementFactory::getRuntimeMXBean).thenReturn(runtimeMXBean); arkServiceContainer.start(); arkServiceContainer.getService(RegisterServiceStage.class).process(null); - ArkServiceLoader.setExtensionLoaderService(arkServiceContainer - .getService(ExtensionLoaderService.class)); + setExtensionLoaderService(arkServiceContainer.getService(ExtensionLoaderService.class)); } @After public void after() { + arkServiceContainer.stop(); if (arkContainer != null) { arkContainer.stop(); @@ -105,7 +105,6 @@ public void after() { @BeforeClass public static void beforeClass() { - } protected void registerMockPlugin() { @@ -134,4 +133,4 @@ protected void registerMockBiz() { bizManagerService.registerBiz(biz); ((BizModel) biz).setBizState(BizState.ACTIVATED); } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/model/BizModelTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/model/BizModelTest.java new file mode 100644 index 000000000..71513d838 --- /dev/null +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/model/BizModelTest.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.container.model; + +import org.junit.Test; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.HashSet; + +import static org.junit.Assert.*; + +public class BizModelTest { + + @Test + public void testDoCheckDeclared() throws MalformedURLException { + + BizModel bizModel = new BizModel(); + assertEquals(new HashSet(), bizModel.setAttribute("a", "b").setAttributes(new HashMap<>()) + .getInjectExportPackages()); + assertEquals(new HashSet(), bizModel.getInjectPluginDependencies()); + bizModel.setCustomBizName("abc"); + assertNotNull(bizModel.getAttributes()); + assertNull(bizModel.getBizTempWorkDir()); + bizModel.toString(); + + bizModel.setPluginClassPath(new URL[] { new URL("file://b/a.jar!/") }); + assertTrue(bizModel.doCheckDeclared("file://b/a.jar!/b.jar")); + assertTrue(bizModel.doCheckDeclared(this.getClass().getClassLoader() + .getResource("test.jar").getPath())); + } +} diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/pipeline/HandleArchiveStageTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/pipeline/HandleArchiveStageTest.java new file mode 100644 index 000000000..84ad590b4 --- /dev/null +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/pipeline/HandleArchiveStageTest.java @@ -0,0 +1,185 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.container.pipeline; + +import com.alipay.sofa.ark.container.model.BizModel; +import com.alipay.sofa.ark.loader.DirectoryBizArchive; +import com.alipay.sofa.ark.loader.JarBizArchive; +import com.alipay.sofa.ark.spi.archive.BizArchive; +import com.alipay.sofa.ark.spi.archive.ExecutableArchive; +import com.alipay.sofa.ark.spi.archive.PluginArchive; +import com.alipay.sofa.ark.spi.model.Plugin; +import com.alipay.sofa.ark.spi.pipeline.PipelineContext; +import com.alipay.sofa.ark.spi.service.biz.BizFactoryService; +import com.alipay.sofa.ark.spi.service.biz.BizManagerService; +import com.alipay.sofa.ark.spi.service.plugin.PluginFactoryService; +import com.alipay.sofa.ark.spi.service.plugin.PluginManagerService; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.util.HashSet; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import static com.alipay.sofa.ark.api.ArkConfigs.getStringValue; +import static com.alipay.sofa.ark.api.ArkConfigs.setSystemProperty; +import static com.alipay.sofa.ark.spi.constant.Constants.CONFIG_SERVER_ADDRESS; +import static com.alipay.sofa.ark.spi.constant.Constants.MASTER_BIZ; +import static java.util.Arrays.asList; +import static org.mockito.Mockito.*; + +public class HandleArchiveStageTest { + + private String originalConfigServerAddress; + + private String originalMasterBiz; + + private BizFactoryService bizFactoryService = mock(BizFactoryService.class); + + private BizManagerService bizManagerService = mock(BizManagerService.class); + + private PluginFactoryService pluginFactoryService = mock(PluginFactoryService.class); + + private PluginManagerService pluginManagerService = mock(PluginManagerService.class); + + private PipelineContext pipelineContext = mock(PipelineContext.class); + + private ExecutableArchive executableArchive = mock(ExecutableArchive.class); + + private HandleArchiveStage handleArchiveStage = new HandleArchiveStage(); + + @Before + public void before() throws Exception { + + originalConfigServerAddress = getStringValue(CONFIG_SERVER_ADDRESS); + originalMasterBiz = getStringValue(MASTER_BIZ); + when(pipelineContext.getExecutableArchive()).thenReturn(executableArchive); + + Field field = HandleArchiveStage.class.getDeclaredField("bizFactoryService"); + field.setAccessible(true); + field.set(handleArchiveStage, bizFactoryService); + + field = HandleArchiveStage.class.getDeclaredField("bizManagerService"); + field.setAccessible(true); + field.set(handleArchiveStage, bizManagerService); + + field = HandleArchiveStage.class.getDeclaredField("pluginFactoryService"); + field.setAccessible(true); + field.set(handleArchiveStage, pluginFactoryService); + + field = HandleArchiveStage.class.getDeclaredField("pluginManagerService"); + field.setAccessible(true); + field.set(handleArchiveStage, pluginManagerService); + } + + @After + public void after() { + setSystemProperty(CONFIG_SERVER_ADDRESS, + originalConfigServerAddress != null ? originalConfigServerAddress : ""); + setSystemProperty(MASTER_BIZ, originalMasterBiz != null ? originalMasterBiz : "'"); + clearInvocations(bizFactoryService, bizManagerService, pluginFactoryService, + pluginManagerService); + } + + @Test + public void testProcess() throws Exception { + + Manifest manifest = mock(Manifest.class); + BizArchive bizArchive1 = mock(DirectoryBizArchive.class); + when(bizArchive1.getManifest()).thenReturn(manifest); + BizArchive bizArchive2 = mock(JarBizArchive.class); + when(bizArchive2.getManifest()).thenReturn(manifest); + when(manifest.getMainAttributes()).thenReturn(mock(Attributes.class)); + BizArchive bizArchive3 = mock(BizArchive.class); + when(bizArchive3.getManifest()).thenReturn(manifest); + BizArchive bizArchive4 = mock(BizArchive.class); + when(bizArchive4.getManifest()).thenReturn(manifest); + when(executableArchive.getBizArchives()).thenReturn( + asList(bizArchive1, bizArchive2, bizArchive3, bizArchive4)); + + BizModel bizModel1 = new BizModel(); + bizModel1.setBizName("a"); + when(bizFactoryService.createBiz(bizArchive1)).thenReturn(bizModel1); + when(bizFactoryService.createBiz(bizArchive2)).thenReturn(bizModel1); + when(bizFactoryService.createBiz(bizArchive3)).thenReturn(bizModel1); + BizModel bizModel2 = new BizModel(); + bizModel2.setBizName("b"); + when(bizFactoryService.createBiz(bizArchive4)).thenReturn(bizModel2); + + PluginArchive pluginArchive = mock(PluginArchive.class); + when(executableArchive.getPluginArchives()).thenReturn(asList(pluginArchive)); + when(bizManagerService.getBizInOrder()).thenReturn(asList(bizModel1)); + + Plugin plugin = mock(Plugin.class); + when(pluginFactoryService.createPlugin(pluginArchive, null, new HashSet<>())).thenReturn( + plugin); + + setSystemProperty(CONFIG_SERVER_ADDRESS, "localhost"); + setSystemProperty(MASTER_BIZ, "a"); + handleArchiveStage.process(pipelineContext); + + verify(bizFactoryService, times(4)).createBiz((BizArchive) any()); + verify(bizManagerService, times(3)).registerBiz(any()); + verify(bizManagerService, times(1)).getBizInOrder(); + verify(pluginFactoryService, times(1)).createPlugin(pluginArchive, null, new HashSet<>()); + verify(pluginManagerService, times(1)).registerPlugin(plugin); + + when(executableArchive.getBizArchives()).thenReturn(asList(bizArchive3)); + setSystemProperty(CONFIG_SERVER_ADDRESS, ""); + setSystemProperty(MASTER_BIZ, ""); + handleArchiveStage.process(pipelineContext); + + verify(bizFactoryService, times(5)).createBiz((BizArchive) any()); + verify(bizManagerService, times(4)).registerBiz(any()); + verify(bizManagerService, times(2)).getBizInOrder(); + } + + @Test + public void testProcessStaticBizFromClasspath() throws Exception { + + BizArchive bizArchive = mock(BizArchive.class); + when(executableArchive.getBizArchives()).thenReturn(asList(bizArchive)); + + handleArchiveStage.processStaticBizFromClasspath(pipelineContext); + verify(bizFactoryService, times(1)).createBiz((bizArchive)); + verify(bizManagerService, times(1)).registerBiz(null); + } + + @Test + public void testProcessEmbed() throws Exception { + + PluginArchive pluginArchive = mock(PluginArchive.class); + when(executableArchive.getPluginArchives()).thenReturn(asList(pluginArchive)); + + Plugin plugin = mock(Plugin.class); + when( + pluginFactoryService.createEmbedPlugin(pluginArchive, pipelineContext.getClass() + .getClassLoader())).thenReturn(plugin); + + BizModel bizModel = new BizModel(); + bizModel.setBizName("a"); + when(bizFactoryService.createEmbedMasterBiz(pipelineContext.getClass().getClassLoader())) + .thenReturn(bizModel); + + handleArchiveStage.processEmbed(pipelineContext); + verify(pluginFactoryService, times(1)).createEmbedPlugin(pluginArchive, + pipelineContext.getClass().getClassLoader()); + verify(pluginManagerService, times(1)).registerPlugin(plugin); + } +} diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/api/ArkClientTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/api/ArkClientTest.java index dfd49044d..e9a721154 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/api/ArkClientTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/api/ArkClientTest.java @@ -16,18 +16,16 @@ */ package com.alipay.sofa.ark.container.service.api; -import com.alipay.sofa.ark.api.ArkClient; import com.alipay.sofa.ark.api.ClientResponse; -import com.alipay.sofa.ark.api.ResponseCode; -import com.alipay.sofa.ark.common.util.FileUtils; import com.alipay.sofa.ark.container.BaseTest; -import com.alipay.sofa.ark.spi.constant.Constants; import com.alipay.sofa.ark.spi.event.ArkEvent; +import com.alipay.sofa.ark.spi.model.Biz; import com.alipay.sofa.ark.spi.model.BizInfo; -import com.alipay.sofa.ark.spi.model.BizState; +import com.alipay.sofa.ark.spi.model.BizOperation; +import com.alipay.sofa.ark.spi.replay.Replay; +import com.alipay.sofa.ark.spi.service.biz.BizFactoryService; import com.alipay.sofa.ark.spi.service.event.EventAdminService; import com.alipay.sofa.ark.spi.service.event.EventHandler; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -36,6 +34,19 @@ import java.util.ArrayList; import java.util.List; +import static com.alipay.sofa.ark.api.ArkClient.*; +import static com.alipay.sofa.ark.api.ResponseCode.REPEAT_BIZ; +import static com.alipay.sofa.ark.api.ResponseCode.SUCCESS; +import static com.alipay.sofa.ark.common.util.FileUtils.copyInputStreamToFile; +import static com.alipay.sofa.ark.spi.constant.Constants.*; +import static com.alipay.sofa.ark.spi.model.BizOperation.OperationType.*; +import static com.alipay.sofa.ark.spi.model.BizState.ACTIVATED; +import static com.alipay.sofa.ark.spi.model.BizState.DEACTIVATED; +import static java.lang.System.setProperty; +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + /** * @author qilong.zql * @since 0.6.0 @@ -62,59 +73,62 @@ public void before() { @Test public void testCreateBizSaveFile() { - File bizFile = ArkClient.createBizSaveFile("test-biz-demo", "1.0.0", "suffix"); - Assert.assertTrue(bizFile.getName().contains("test-biz-demo-1.0.0-suffix")); + File bizFile = createBizSaveFile("test-biz-demo", "1.0.0", "suffix"); + assertTrue(bizFile.getName().contains("test-biz-demo-1.0.0-suffix")); } @Test public void testInstallBiz() throws Throwable { - ClientResponse response = ArkClient.checkBiz(); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); - Assert.assertEquals(0, response.getBizInfos().size()); + + ClientResponse response = checkBiz(); + assertEquals(SUCCESS, response.getCode()); + assertEquals(0, response.getBizInfos().size()); // test install - File bizFile = ArkClient.createBizSaveFile("biz-demo", "1.0.0"); - FileUtils.copyInputStreamToFile(bizUrl1.openStream(), bizFile); - response = ArkClient.installBiz(bizFile); + File bizFile = createBizSaveFile("biz-demo", "1.0.0"); + copyInputStreamToFile(bizUrl1.openStream(), bizFile); + response = installBiz(bizFile); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); + assertEquals(SUCCESS, response.getCode()); BizInfo bizInfo = response.getBizInfos().iterator().next(); - Assert.assertEquals(BizState.ACTIVATED, bizInfo.getBizState()); + assertEquals(ACTIVATED, bizInfo.getBizState()); // test install biz with same bizName and bizVersion // test install - File bizFile1 = ArkClient.createBizSaveFile("biz-demo", "1.0.0"); - FileUtils.copyInputStreamToFile(bizUrl1.openStream(), bizFile1); - response = ArkClient.installBiz(bizFile1); - Assert.assertEquals(ResponseCode.REPEAT_BIZ, response.getCode()); + File bizFile1 = createBizSaveFile("biz-demo", "1.0.0"); + copyInputStreamToFile(bizUrl1.openStream(), bizFile1); + response = installBiz(bizFile1); + assertEquals(REPEAT_BIZ, response.getCode()); // test install biz with same bizName and different bizVersion // response = ArkClient.installBiz(new File(bizUrl2.getFile())); - File bizFile2 = ArkClient.createBizSaveFile("biz-demo", "2.0.0"); - FileUtils.copyInputStreamToFile(bizUrl2.openStream(), bizFile2); - response = ArkClient.installBiz(bizFile2); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); + File bizFile2 = createBizSaveFile("biz-demo", "2.0.0"); + copyInputStreamToFile(bizUrl2.openStream(), bizFile2); + response = installBiz(bizFile2); + assertEquals(SUCCESS, response.getCode()); bizInfo = response.getBizInfos().iterator().next(); - Assert.assertEquals(BizState.DEACTIVATED, bizInfo.getBizState()); + assertEquals(DEACTIVATED, bizInfo.getBizState()); // test install biz with same bizName and different bizVersion and active latest - System.setProperty(Constants.ACTIVATE_NEW_MODULE, "true"); - System.setProperty(Constants.EMBED_ENABLE, "true"); - File bizFile3 = ArkClient.createBizSaveFile("biz-demo", "3.0.0"); - FileUtils.copyInputStreamToFile(bizUrl3.openStream(), bizFile3); - response = ArkClient.installBiz(bizFile3); - System.setProperty(Constants.ACTIVATE_NEW_MODULE, ""); - System.setProperty(Constants.EMBED_ENABLE, ""); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); + setProperty(ACTIVATE_NEW_MODULE, "true"); + setProperty(EMBED_ENABLE, "true"); + File bizFile3 = createBizSaveFile("biz-demo", "3.0.0"); + copyInputStreamToFile(bizUrl3.openStream(), bizFile3); + response = installBiz(bizFile3); + setProperty(ACTIVATE_NEW_MODULE, ""); + setProperty(EMBED_ENABLE, ""); + assertEquals(SUCCESS, response.getCode()); bizInfo = response.getBizInfos().iterator().next(); - Assert.assertEquals(BizState.ACTIVATED, bizInfo.getBizState()); + assertEquals(ACTIVATED, bizInfo.getBizState()); } @Test public void testBizArguments() throws Throwable { + EventAdminService eventAdminService = arkServiceContainer .getService(EventAdminService.class); List topicList = new ArrayList<>(); + EventHandler eventHandler = new EventHandler() { @Override public void handleEvent(ArkEvent event) { @@ -128,93 +142,160 @@ public int getPriority() { }; eventAdminService.register(eventHandler); - File bizFile3 = ArkClient.createBizSaveFile("biz-demo", "3.0.0"); - FileUtils.copyInputStreamToFile(bizUrl3.openStream(), bizFile3); - ArkClient.installBiz(bizFile3); + File bizFile3 = createBizSaveFile("biz-demo", "3.0.0"); + copyInputStreamToFile(bizUrl3.openStream(), bizFile3); + installBiz(bizFile3); // ArkClient.installBiz(new File(bizUrl3.getFile())); - ArkClient.uninstallBiz("biz-demo", "3.0.0"); - - File bizFile33 = ArkClient.createBizSaveFile("biz-demo", "3.0.0"); - FileUtils.copyInputStreamToFile(bizUrl3.openStream(), bizFile33); - ArkClient.installBiz(bizFile33, new String[] { "demo" }); - ArkClient.uninstallBiz("biz-demo", "3.0.0"); - Assert.assertEquals("BEFORE-INVOKE-BIZ-START", topicList.get(0)); - Assert.assertEquals("No arguments", topicList.get(1)); - Assert.assertEquals("AFTER-INVOKE-BIZ-START", topicList.get(2)); + uninstallBiz("biz-demo", "3.0.0"); + + File bizFile33 = createBizSaveFile("biz-demo", "3.0.0"); + copyInputStreamToFile(bizUrl3.openStream(), bizFile33); + installBiz(bizFile33, new String[] { "demo" }); + uninstallBiz("biz-demo", "3.0.0"); + assertEquals("BEFORE-INVOKE-BIZ-START", topicList.get(0)); + assertEquals("No arguments", topicList.get(1)); + assertEquals("AFTER-INVOKE-BIZ-START", topicList.get(2)); // new event - Assert.assertEquals("BEFORE-RECYCLE-BIZ", topicList.get(4)); - Assert.assertEquals("demo", topicList.get(7)); + assertEquals("BEFORE-RECYCLE-BIZ", topicList.get(4)); + assertEquals("demo", topicList.get(7)); } @Test public void testCheckBiz() throws Throwable { + testInstallBiz(); // test check all biz - ClientResponse response = ArkClient.checkBiz(); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); - Assert.assertEquals(3, response.getBizInfos().size()); + ClientResponse response = checkBiz(); + assertEquals(SUCCESS, response.getCode()); + assertEquals(3, response.getBizInfos().size()); // test check specified bizName - response = ArkClient.checkBiz("biz-demo"); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); - Assert.assertEquals(3, response.getBizInfos().size()); + response = checkBiz("biz-demo"); + assertEquals(SUCCESS, response.getCode()); + assertEquals(3, response.getBizInfos().size()); // test check specified bizName and version - response = ArkClient.checkBiz("biz-demo", "2.0.0"); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); - Assert.assertEquals(1, response.getBizInfos().size()); - response = ArkClient.checkBiz("biz-demo", "3.0.0"); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); - Assert.assertEquals(1, response.getBizInfos().size()); - - response = ArkClient.checkBiz("biz-demo", "4.0.0"); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); - Assert.assertEquals(0, response.getBizInfos().size()); + response = checkBiz("biz-demo", "2.0.0"); + assertEquals(SUCCESS, response.getCode()); + assertEquals(1, response.getBizInfos().size()); + response = checkBiz("biz-demo", "3.0.0"); + assertEquals(SUCCESS, response.getCode()); + assertEquals(1, response.getBizInfos().size()); + + response = checkBiz("biz-demo", "4.0.0"); + assertEquals(SUCCESS, response.getCode()); + assertEquals(0, response.getBizInfos().size()); } @Test public void testUninstallBiz() throws Throwable { + testCheckBiz(); // test uninstall biz - ClientResponse response = ArkClient.uninstallBiz("biz-demo", "1.0.0"); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); + ClientResponse response = uninstallBiz("biz-demo", "1.0.0"); + assertEquals(SUCCESS, response.getCode()); // test check all biz - response = ArkClient.checkBiz(); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); - Assert.assertEquals(2, response.getBizInfos().size()); + response = checkBiz(); + assertEquals(SUCCESS, response.getCode()); + assertEquals(2, response.getBizInfos().size()); } - public void testSwitchBiz() throws Throwable { - testUninstallBiz(); - // test switch biz - ClientResponse response = ArkClient.installBiz(new File(bizUrl1.getFile())); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); - BizInfo bizInfo = response.getBizInfos().iterator().next(); - Assert.assertEquals(BizState.ACTIVATED, bizInfo.getBizState()); + @Test + public void testInstallBizWithThrowable() throws Throwable { - response = ArkClient.checkBiz("biz-demo", "2.0.0"); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); - Assert.assertEquals(1, response.getBizInfos().size()); - bizInfo = response.getBizInfos().iterator().next(); - Assert.assertEquals(BizState.DEACTIVATED, bizInfo.getBizState()); + File bizFile = createBizSaveFile("biz-demo", "1.0.0"); + copyInputStreamToFile(bizUrl1.openStream(), bizFile); + BizFactoryService bizFactoryService = getBizFactoryService(); + BizFactoryService bizFactoryServiceMock = mock(BizFactoryService.class); + setBizFactoryService(bizFactoryServiceMock); + Biz biz = mock(Biz.class); + doThrow(new IllegalArgumentException()).when(biz).start(any()); + when(bizFactoryServiceMock.createBiz((File) any())).thenReturn(biz); - response = ArkClient.switchBiz("biz-demo", "2.0.0"); - Assert.assertEquals(ResponseCode.SUCCESS, response.getCode()); + try { + installBiz(bizFile, null); + assertTrue(false); + } catch (Throwable e) { + setBizFactoryService(bizFactoryService); + assertEquals(IllegalArgumentException.class, e.getClass()); + } - response = ArkClient.switchBiz("biz-demo", "3.0.0"); - Assert.assertEquals(ResponseCode.NOT_FOUND_BIZ, response.getCode()); + assertNotNull(getBizManagerService()); + assertNotNull(getBizFactoryService()); + assertNotNull(getPluginManagerService()); + assertNotNull(getArguments()); + } - response = ArkClient.checkBiz("biz-demo", "2.0.0"); - bizInfo = response.getBizInfos().iterator().next(); - Assert.assertEquals(BizState.ACTIVATED, bizInfo.getBizState()); - response = ArkClient.checkBiz("biz-demo", "1.0.0"); - bizInfo = response.getBizInfos().iterator().next(); - Assert.assertEquals(BizState.DEACTIVATED, bizInfo.getBizState()); + @Test + public void testInstallOperation() throws Throwable { + + BizOperation bizOperation = new BizOperation(); + bizOperation.setOperationType(INSTALL); + bizOperation.getParameters().put(CONFIG_BIZ_URL, bizUrl1.toString()); + bizOperation.setBizName("biz-demo"); + bizOperation.setBizVersion("1.0.0"); + + ClientResponse response = installOperation(bizOperation, new String[] {}); + assertEquals(SUCCESS, response.getCode()); + } - // Uninstall biz - ArkClient.uninstallBiz("biz-demo", "1.0.0"); - ArkClient.uninstallBiz("biz-demo", "2.0.0"); + @Test + public void testUninstallOperation() throws Throwable { + + BizOperation bizOperation = new BizOperation(); + bizOperation.setOperationType(INSTALL); + bizOperation.getParameters().put(CONFIG_BIZ_URL, bizUrl1.toString()); + bizOperation.setBizName("biz-demo"); + bizOperation.setBizVersion("1.0.0"); + installOperation(bizOperation, new String[] {}); + + bizOperation.setOperationType(UNINSTALL); + ClientResponse response = uninstallOperation(bizOperation); + assertEquals(SUCCESS, response.getCode()); + } + + @Test + public void testSwitchOperation() throws Throwable { + + BizOperation bizOperation = new BizOperation(); + bizOperation.setOperationType(INSTALL); + bizOperation.getParameters().put(CONFIG_BIZ_URL, bizUrl1.toString()); + bizOperation.setBizName("biz-demo"); + bizOperation.setBizVersion("1.0.0"); + installOperation(bizOperation, new String[] {}); + + bizOperation.setOperationType(SWITCH); + ClientResponse response = switchOperation(bizOperation); + assertEquals(SUCCESS, response.getCode()); + } + + @Test + public void testCheckOperation() throws Throwable { + + BizOperation bizOperation = new BizOperation(); + bizOperation.setOperationType(INSTALL); + bizOperation.getParameters().put(CONFIG_BIZ_URL, bizUrl1.toString()); + bizOperation.setBizName("biz-demo"); + bizOperation.setBizVersion("1.0.0"); + installOperation(bizOperation, new String[] {}); + + bizOperation.setOperationType(CHECK); + ClientResponse response = checkOperation(bizOperation); + assertEquals(SUCCESS, response.getCode()); + + bizOperation.setBizVersion("2.0.0"); + response = checkOperation(bizOperation); + assertEquals(SUCCESS, response.getCode()); } -} \ No newline at end of file + @Test + public void testInvocationReplay() throws Throwable { + assertEquals("1", invocationReplay("1.0.0", new Replay() { + @Override + public Object invoke() { + return "1"; + } + })); + } +} diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/biz/BizCommandProviderTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/biz/BizCommandProviderTest.java index 4049e87db..f97bd5310 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/biz/BizCommandProviderTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/biz/BizCommandProviderTest.java @@ -16,19 +16,27 @@ */ package com.alipay.sofa.ark.container.service.biz; -import com.alipay.sofa.ark.api.ArkConfigs; import com.alipay.sofa.ark.container.BaseTest; import com.alipay.sofa.ark.container.model.BizModel; +import com.alipay.sofa.ark.container.service.biz.BizCommandProvider.BizCommand; import com.alipay.sofa.ark.container.session.handler.ArkCommandHandler; -import com.alipay.sofa.ark.spi.constant.Constants; import com.alipay.sofa.ark.spi.model.Biz; import com.alipay.sofa.ark.spi.model.BizState; import com.alipay.sofa.ark.spi.service.biz.BizDeployService; import com.alipay.sofa.ark.spi.service.biz.BizManagerService; import com.alipay.sofa.ark.spi.service.injection.InjectionService; -import org.junit.Assert; import org.junit.Test; +import java.net.MalformedURLException; +import java.net.URL; + +import static com.alipay.sofa.ark.api.ArkConfigs.putStringValue; +import static com.alipay.sofa.ark.container.service.biz.BizCommandProvider.HELP_MESSAGE; +import static com.alipay.sofa.ark.spi.constant.Constants.MASTER_BIZ; +import static com.alipay.sofa.ark.spi.model.BizState.ACTIVATED; +import static com.alipay.sofa.ark.spi.model.BizState.DEACTIVATED; +import static org.junit.Assert.*; + /** * @author qilong.zql * @since 0.6.0 @@ -42,6 +50,7 @@ public class BizCommandProviderTest extends BaseTest { @Override public void before() { + super.before(); bizManagerService = arkServiceContainer.getService(BizManagerService.class); injectionService = arkServiceContainer.getService(InjectionService.class); @@ -50,7 +59,6 @@ public void before() { mockBiz(); bizDeployService.deploy(new String[] {}); - bizCommandProvider = new BizCommandProvider(); injectionService.inject(bizCommandProvider); @@ -60,123 +68,122 @@ public void before() { @Test public void testBizCommandPattern() { - Assert.assertFalse(bizCommandProvider.validate("biz")); - Assert.assertFalse(bizCommandProvider.validate("biz -m")); - Assert.assertFalse(bizCommandProvider.validate("biz -d")); - Assert.assertFalse(bizCommandProvider.validate("biz -s")); - Assert.assertFalse(bizCommandProvider.validate("biz -i")); - Assert.assertFalse(bizCommandProvider.validate("biz -u")); - Assert.assertFalse(bizCommandProvider.validate("biz -o")); - Assert.assertTrue(bizCommandProvider.validate("biz -a")); - Assert.assertTrue(bizCommandProvider.validate("biz -h")); - - Assert.assertFalse(bizCommandProvider.validate("biz -ah")); - Assert.assertFalse(bizCommandProvider.validate("biz -am A1:V1")); - Assert.assertFalse(bizCommandProvider.validate("biz -hm A1:V1")); - Assert.assertFalse(bizCommandProvider.validate("biz -mi A1:V1")); - Assert.assertFalse(bizCommandProvider.validate("biz -mu A1:V1")); - Assert.assertFalse(bizCommandProvider.validate("biz -mo A1:V1")); - Assert.assertTrue(bizCommandProvider.validate("biz -msd A1:V1")); - Assert.assertTrue(bizCommandProvider.validate("biz -msd A1:V1 A2:V2")); - - Assert.assertFalse(bizCommandProvider.validate("biz -io A1:V1")); - - Assert.assertFalse(bizCommandProvider.validate("biz -i A1:V1 A2:V2")); - Assert.assertTrue(bizCommandProvider.validate("biz -i A1:V1")); - - Assert.assertFalse(bizCommandProvider.validate("biz -u A1:V1 A2:V2")); - Assert.assertTrue(bizCommandProvider.validate("biz -u A1:V1")); - - Assert.assertFalse(bizCommandProvider.validate("biz -o A1:V1 A2:V2")); - Assert.assertTrue(bizCommandProvider.validate("biz -o A1:V1")); + + assertFalse(bizCommandProvider.validate("biz")); + assertFalse(bizCommandProvider.validate("biz -m")); + assertFalse(bizCommandProvider.validate("biz -d")); + assertFalse(bizCommandProvider.validate("biz -s")); + assertFalse(bizCommandProvider.validate("biz -i")); + assertFalse(bizCommandProvider.validate("biz -u")); + assertFalse(bizCommandProvider.validate("biz -o")); + assertTrue(bizCommandProvider.validate("biz -a")); + assertTrue(bizCommandProvider.validate("biz -h")); + + assertFalse(bizCommandProvider.validate("biz -ah")); + assertFalse(bizCommandProvider.validate("biz -am A1:V1")); + assertFalse(bizCommandProvider.validate("biz -hm A1:V1")); + assertFalse(bizCommandProvider.validate("biz -mi A1:V1")); + assertFalse(bizCommandProvider.validate("biz -mu A1:V1")); + assertFalse(bizCommandProvider.validate("biz -mo A1:V1")); + assertTrue(bizCommandProvider.validate("biz -msd A1:V1")); + assertTrue(bizCommandProvider.validate("biz -msd A1:V1 A2:V2")); + + assertFalse(bizCommandProvider.validate("biz -io A1:V1")); + + assertFalse(bizCommandProvider.validate("biz -i A1:V1 A2:V2")); + assertTrue(bizCommandProvider.validate("biz -i A1:V1")); + + assertFalse(bizCommandProvider.validate("biz -u A1:V1 A2:V2")); + assertTrue(bizCommandProvider.validate("biz -u A1:V1")); + + assertFalse(bizCommandProvider.validate("biz -o A1:V1 A2:V2")); + assertTrue(bizCommandProvider.validate("biz -o A1:V1")); } @Test public void testBizInfo() { + String multiBizInfo = bizCommandProvider.handleCommand("biz -m A1:V1 A1:V2"); String multiOptionBizInfo = bizCommandProvider.handleCommand("biz -md A1:V1 B1:V1"); - Assert.assertTrue(multiBizInfo.contains("MainClassA1")); - Assert.assertTrue(multiBizInfo.contains("MainClassA2")); - Assert.assertFalse(multiBizInfo.contains("ClassLoader")); - Assert.assertFalse(multiBizInfo.contains("ClassPath")); - Assert.assertFalse(multiBizInfo.contains("MainClassB1")); - - Assert.assertTrue(multiOptionBizInfo.contains("MainClassA1")); - Assert.assertTrue(multiOptionBizInfo.contains("MainClassB1")); - Assert.assertFalse(multiOptionBizInfo.contains("MainClassA2")); - Assert.assertTrue(multiOptionBizInfo.contains("ClassLoader")); - Assert.assertTrue(multiOptionBizInfo.contains("ClassPath")); + assertTrue(multiBizInfo.contains("MainClassA1")); + assertTrue(multiBizInfo.contains("MainClassA2")); + assertFalse(multiBizInfo.contains("ClassLoader")); + assertFalse(multiBizInfo.contains("ClassPath")); + assertFalse(multiBizInfo.contains("MainClassB1")); + + assertTrue(multiOptionBizInfo.contains("MainClassA1")); + assertTrue(multiOptionBizInfo.contains("MainClassB1")); + assertFalse(multiOptionBizInfo.contains("MainClassA2")); + assertTrue(multiOptionBizInfo.contains("ClassLoader")); + assertTrue(multiOptionBizInfo.contains("ClassPath")); } @Test public void testInstallBiz() { String msg = bizCommandProvider.handleCommand("biz -i C1:V1"); - Assert.assertTrue(msg.contains("Exists some biz")); + assertTrue(msg.contains("Exists some biz")); - ((MockBiz) bizManagerService.getBizByIdentity("A1:V1")).setBizState(BizState.ACTIVATED); - ((MockBiz) bizManagerService.getBizByIdentity("A1:V2")).setBizState(BizState.DEACTIVATED); - ((MockBiz) bizManagerService.getBizByIdentity("B1:V1")).setBizState(BizState.ACTIVATED); + ((MockBiz) bizManagerService.getBizByIdentity("A1:V1")).setBizState(ACTIVATED); + ((MockBiz) bizManagerService.getBizByIdentity("A1:V2")).setBizState(DEACTIVATED); + ((MockBiz) bizManagerService.getBizByIdentity("B1:V1")).setBizState(ACTIVATED); msg = bizCommandProvider.handleCommand("biz -i C1:V1"); - Assert - .assertTrue(msg.contains("Start to process install command now, pls wait and check.")); + assertTrue(msg.contains("Start to process install command now, pls wait and check.")); } @Test public void testSwitchBiz() { - Biz bizA1 = ((MockBiz) bizManagerService.getBizByIdentity("A1:V1")) - .setBizState(BizState.ACTIVATED); + + Biz bizA1 = ((MockBiz) bizManagerService.getBizByIdentity("A1:V1")).setBizState(ACTIVATED); Biz bizA2 = ((MockBiz) bizManagerService.getBizByIdentity("A1:V2")) - .setBizState(BizState.DEACTIVATED); - Biz bizB1 = ((MockBiz) bizManagerService.getBizByIdentity("B1:V1")) - .setBizState(BizState.ACTIVATED); + .setBizState(DEACTIVATED); + Biz bizB1 = ((MockBiz) bizManagerService.getBizByIdentity("B1:V1")).setBizState(ACTIVATED); bizCommandProvider.handleCommand("biz -o A1:V2"); sleep(200); - Assert.assertTrue(bizA1.getBizState().equals(BizState.DEACTIVATED)); - Assert.assertTrue(bizA2.getBizState().equals(BizState.ACTIVATED)); - Assert.assertTrue(bizB1.getBizState().equals(BizState.ACTIVATED)); + assertTrue(bizA1.getBizState().equals(DEACTIVATED)); + assertTrue(bizA2.getBizState().equals(ACTIVATED)); + assertTrue(bizB1.getBizState().equals(ACTIVATED)); } @Test public void testUninstallBiz() { - Biz bizA1 = ((MockBiz) bizManagerService.getBizByIdentity("A1:V1")) - .setBizState(BizState.ACTIVATED); + + Biz bizA1 = ((MockBiz) bizManagerService.getBizByIdentity("A1:V1")).setBizState(ACTIVATED); Biz bizA2 = ((MockBiz) bizManagerService.getBizByIdentity("A1:V2")) - .setBizState(BizState.DEACTIVATED); - Biz bizB1 = ((MockBiz) bizManagerService.getBizByIdentity("B1:V1")) - .setBizState(BizState.ACTIVATED); + .setBizState(DEACTIVATED); + Biz bizB1 = ((MockBiz) bizManagerService.getBizByIdentity("B1:V1")).setBizState(ACTIVATED); bizCommandProvider.handleCommand("biz -u B1:V1"); sleep(200); - Assert.assertTrue(bizA1.getBizState().equals(BizState.ACTIVATED)); - Assert.assertTrue(bizA2.getBizState().equals(BizState.DEACTIVATED)); - Assert.assertNull(bizManagerService.getBizByIdentity("B1:V1")); + assertTrue(bizA1.getBizState().equals(ACTIVATED)); + assertTrue(bizA2.getBizState().equals(DEACTIVATED)); + assertNull(bizManagerService.getBizByIdentity("B1:V1")); } @Test public void testUninstallMasterBiz() { - ArkConfigs.putStringValue(Constants.MASTER_BIZ, "B1"); - Biz bizA1 = ((MockBiz) bizManagerService.getBizByIdentity("A1:V1")) - .setBizState(BizState.ACTIVATED); + + putStringValue(MASTER_BIZ, "B1"); + Biz bizA1 = ((MockBiz) bizManagerService.getBizByIdentity("A1:V1")).setBizState(ACTIVATED); Biz bizA2 = ((MockBiz) bizManagerService.getBizByIdentity("A1:V2")) - .setBizState(BizState.DEACTIVATED); - Biz bizB1 = ((MockBiz) bizManagerService.getBizByIdentity("B1:V1")) - .setBizState(BizState.ACTIVATED); + .setBizState(DEACTIVATED); + Biz bizB1 = ((MockBiz) bizManagerService.getBizByIdentity("B1:V1")).setBizState(ACTIVATED); bizCommandProvider.handleCommand("biz -u B1:V1"); sleep(200); - Assert.assertTrue(bizA1.getBizState().equals(BizState.ACTIVATED)); - Assert.assertTrue(bizA2.getBizState().equals(BizState.DEACTIVATED)); - Assert.assertTrue(bizB1.getBizState().equals(BizState.ACTIVATED)); - Assert.assertNotNull(bizManagerService.getBizByIdentity("B1:V1")); + assertTrue(bizA1.getBizState().equals(ACTIVATED)); + assertTrue(bizA2.getBizState().equals(DEACTIVATED)); + assertTrue(bizB1.getBizState().equals(ACTIVATED)); + // assertNotNull(bizManagerService.getBizByIdentity("B1:V1")); } private void mockBiz() { + MockBiz bizA1 = new MockBiz(); bizA1.setBizName("A1").setBizVersion("V1").setWebContextPath("/A1") .setBizState(BizState.RESOLVED).setMainClass("MainClassA1"); @@ -217,4 +224,30 @@ public void stop() { } } -} \ No newline at end of file + @Test + public void testBizCommandInvalidate() throws MalformedURLException { + + BizCommand bizCommand = bizCommandProvider.new BizCommand(""); + assertFalse(bizCommand.isValidate()); + bizCommand = bizCommandProvider.new BizCommand("biz -"); + assertFalse(bizCommand.isValidate()); + bizCommand = bizCommandProvider.new BizCommand("biz -x"); + assertFalse(bizCommand.isValidate()); + bizCommand = bizCommandProvider.new BizCommand("biz -h a"); + assertFalse(bizCommand.isValidate()); + assertTrue(bizCommand.process().startsWith("Error command format")); + + bizCommand = bizCommandProvider.new BizCommand("biz -h"); + assertEquals(HELP_MESSAGE, bizCommand.process()); + + mockBiz(); + bizCommand = bizCommandProvider.new BizCommand("biz -a"); + assertEquals("A1:V1:resolved\nA1:V2:resolved\nB1:V1:resolved\nbiz count = 3\n", + bizCommand.process()); + assertTrue(bizCommand.bizInfo("a:b").startsWith("Invalid bizIdentity: ")); + + String bizCommandStr = bizCommand.join( + new URL[] { new URL("file:\\a"), new URL("file:\\b") }, "&"); + assertTrue(bizCommandStr.equals("\\a&\\b") || bizCommandStr.equals("/a&/b")); + } +} diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/biz/BizFactoryServiceTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/biz/BizFactoryServiceTest.java index b03b7a866..86c41c6a0 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/biz/BizFactoryServiceTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/biz/BizFactoryServiceTest.java @@ -16,10 +16,8 @@ */ package com.alipay.sofa.ark.container.service.biz; -import com.alipay.sofa.ark.api.ArkConfigs; +import com.alipay.sofa.ark.common.util.FileUtils; import com.alipay.sofa.ark.container.BaseTest; -import com.alipay.sofa.ark.container.service.ArkServiceContainerHolder; -import com.alipay.sofa.ark.spi.constant.Constants; import com.alipay.sofa.ark.spi.model.Biz; import com.alipay.sofa.ark.spi.model.BizOperation; import com.alipay.sofa.ark.spi.model.Plugin; @@ -30,10 +28,16 @@ import org.junit.Assert; import org.junit.Test; -import java.io.File; import java.io.IOException; import java.net.URL; +import static com.alipay.sofa.ark.api.ArkConfigs.putStringValue; +import static com.alipay.sofa.ark.container.service.ArkServiceContainerHolder.getContainer; +import static com.alipay.sofa.ark.spi.constant.Constants.ARK_PLUGIN_MARK_ENTRY; +import static com.alipay.sofa.ark.spi.constant.Constants.MASTER_BIZ; +import static java.lang.Thread.currentThread; +import static org.junit.Assert.assertNotNull; + /** * @author qilong.zql * @since 0.4.0 @@ -54,52 +58,51 @@ public void before() { pluginManagerService = arkServiceContainer.getService(PluginManagerService.class); pluginFactoryService = arkServiceContainer.getService(PluginFactoryService.class); bizFactoryService = arkServiceContainer.getService(BizFactoryService.class); - bizManagerService = ArkServiceContainerHolder.getContainer().getService( - BizManagerService.class); + bizManagerService = getContainer().getService(BizManagerService.class); } @Test public void test() throws Throwable { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); + ClassLoader cl = currentThread().getContextClassLoader(); URL samplePlugin = cl.getResource("sample-plugin.jar"); - Plugin plugin = pluginFactoryService.createPlugin(new File(samplePlugin.getFile())); + Plugin plugin = pluginFactoryService.createPlugin(FileUtils.file(samplePlugin.getFile())); pluginManagerService.registerPlugin(plugin); URL sampleBiz = cl.getResource("sample-biz.jar"); - Biz biz = bizFactoryService.createBiz(new File(sampleBiz.getFile())); + Biz biz = bizFactoryService.createBiz(FileUtils.file(sampleBiz.getFile())); bizManagerService.registerBiz(biz); - Assert.assertNotNull(biz); - Assert.assertNotNull(biz.getBizClassLoader().getResource(Constants.ARK_PLUGIN_MARK_ENTRY)); + assertNotNull(biz); + assertNotNull(biz.getBizClassLoader().getResource(ARK_PLUGIN_MARK_ENTRY)); - ArkConfigs.putStringValue(Constants.MASTER_BIZ, "master-biz"); + putStringValue(MASTER_BIZ, "master-biz"); Biz masterBiz = bizFactoryService.createEmbedMasterBiz(cl); - Assert.assertNotNull(masterBiz); - Assert.assertNotNull(masterBiz.getBizClassLoader().getResource( + assertNotNull(masterBiz); + assertNotNull(masterBiz.getBizClassLoader().getResource( "com/alipay/sofa/ark/container/service/biz/")); } @Test public void testCreateBiz() throws IOException { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); + ClassLoader cl = currentThread().getContextClassLoader(); URL sampleBiz = cl.getResource("sample-biz.jar"); BizOperation bizOperation = new BizOperation(); String mockVersion = "mock version"; bizOperation.setBizVersion(mockVersion); - Biz biz = bizFactoryService.createBiz(bizOperation, new File(sampleBiz.getFile())); + Biz biz = bizFactoryService.createBiz(bizOperation, FileUtils.file(sampleBiz.getFile())); Assert.assertEquals(biz.getBizVersion(), mockVersion); } @Test public void testPackageInfo() throws Throwable { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); + ClassLoader cl = currentThread().getContextClassLoader(); URL samplePlugin = cl.getResource("sample-ark-plugin.jar"); - Plugin plugin = pluginFactoryService.createPlugin(new File(samplePlugin.getFile())); + Plugin plugin = pluginFactoryService.createPlugin(FileUtils.file(samplePlugin.getFile())); ClassLoader pluginClassLoader = plugin.getPluginClassLoader(); pluginManagerService.registerPlugin(plugin); Class mdc = pluginClassLoader.loadClass("org.slf4j.MDC"); Assert.assertTrue(mdc.getClassLoader().equals(pluginClassLoader)); - Assert.assertNotNull(mdc.getPackage().getImplementationVersion()); + assertNotNull(mdc.getPackage().getImplementationVersion()); } } \ No newline at end of file diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/biz/BizManagerServiceTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/biz/BizManagerServiceTest.java index b186cf8e4..6c213d29a 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/biz/BizManagerServiceTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/biz/BizManagerServiceTest.java @@ -18,16 +18,21 @@ import com.alipay.sofa.ark.container.BaseTest; import com.alipay.sofa.ark.container.model.BizModel; +import com.alipay.sofa.ark.exception.ArkRuntimeException; import com.alipay.sofa.ark.spi.model.Biz; import com.alipay.sofa.ark.spi.model.BizState; import com.alipay.sofa.ark.spi.service.biz.BizManagerService; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.util.List; import java.util.Set; +import static com.alipay.sofa.ark.spi.model.BizState.ACTIVATED; +import static com.alipay.sofa.ark.spi.model.BizState.RESOLVED; +import static org.codehaus.plexus.util.ReflectionUtils.setVariableValueInObject; +import static org.junit.Assert.*; + /** * @author qilong.zql * @since 0.4.0 @@ -40,109 +45,145 @@ public class BizManagerServiceTest extends BaseTest { public void before() { super.before(); Biz biz = new BizModel().setBizName("test-biz").setBizVersion("1.0.0") - .setBizState(BizState.RESOLVED); + .setBizState(RESOLVED); bizManagerService.registerBiz(biz); } @Test public void testRegisterBiz() { Biz ret = bizManagerService.getBiz("test-biz", "1.0.0"); - Assert.assertNotNull(ret); + assertNotNull(ret); } @Test public void testDuplicatedRegisterBiz() { Biz biz = new BizModel().setBizName("test-biz").setBizVersion("1.0.0") - .setBizState(BizState.RESOLVED); - Assert.assertFalse(bizManagerService.registerBiz(biz)); - Assert.assertTrue(bizManagerService.getBiz("test-biz").size() == 1); + .setBizState(RESOLVED); + assertFalse(bizManagerService.registerBiz(biz)); + assertEquals(1, bizManagerService.getBiz("test-biz").size()); } @Test public void testRemovingAndAddBiz() { - Biz adding = new BizModel().setBizName("test-biz-adding").setBizVersion("1.0.0") - .setBizState(BizState.ACTIVATED); + Biz adding = new BizModel().setBizName("test-biz-adding").setBizVersion("1.0.0") + .setBizState(ACTIVATED); Biz removing = new BizModel().setBizName("test-biz-removing").setBizVersion("1.0.0") - .setBizState(BizState.RESOLVED); + .setBizState(RESOLVED); bizManagerService.registerBiz(removing); - ((BizModel) removing).setBizState(BizState.ACTIVATED); - + ((BizModel) removing).setBizState(ACTIVATED); bizManagerService.removeAndAddBiz(adding, removing); List biz = bizManagerService.getBiz("test-biz-adding"); - Assert.assertTrue(biz.size() == 1); + assertTrue(biz.size() == 1); biz = bizManagerService.getBiz("test-biz-removing"); - Assert.assertTrue(biz.size() == 0); - + assertTrue(biz.size() == 0); bizManagerService.unRegisterBiz(adding.getBizName(), adding.getBizVersion()); } @Test public void testUnRegister() { + Biz biz = bizManagerService.unRegisterBiz("test-biz", "1.0.1"); - Assert.assertNull(biz); - Assert.assertTrue(bizManagerService.getBiz("test-biz").size() == 1); + assertNull(biz); + assertTrue(bizManagerService.getBiz("test-biz").size() == 1); biz = bizManagerService.unRegisterBizStrictly("test-biz", "1.0.0"); - Assert.assertNotNull(biz); - Assert.assertTrue(bizManagerService.getBiz("test-biz").size() == 0); + assertNotNull(biz); + assertTrue(bizManagerService.getBiz("test-biz").size() == 0); bizManagerService.registerBiz(biz); - Assert.assertTrue(bizManagerService.getBiz("test-biz").size() == 1); + assertTrue(bizManagerService.getBiz("test-biz").size() == 1); } @Test public void testBizGet() { + Biz biz = bizManagerService.getBizByIdentity("test-biz:1.0.0"); - Assert.assertNotNull(biz); + assertNotNull(biz); Set stringSet = bizManagerService.getAllBizNames(); - Assert.assertTrue(stringSet.size() == 1); - Assert.assertTrue(stringSet.contains("test-biz")); + assertTrue(stringSet.size() == 1); + assertTrue(stringSet.contains("test-biz")); biz = bizManagerService.getActiveBiz("test-biz"); - Assert.assertNull(biz); + assertNull(biz); BizState bizState = bizManagerService.getBizState("test-biz:1.0.0"); - Assert.assertTrue(bizState == BizState.RESOLVED); + assertTrue(bizState == RESOLVED); bizState = bizManagerService.getBizState("test-biz", "1.0.0"); - Assert.assertTrue(bizState == BizState.RESOLVED); + assertTrue(bizState == RESOLVED); bizState = bizManagerService.getBizState("ss", "xx"); - Assert.assertTrue(bizState == BizState.UNRESOLVED); + assertTrue(bizState == BizState.UNRESOLVED); - biz = new BizModel().setBizName("test-biz").setBizVersion("1.0.1") - .setBizState(BizState.RESOLVED).setPriority("10"); + biz = new BizModel().setBizName("test-biz").setBizVersion("1.0.1").setBizState(RESOLVED) + .setPriority("10"); bizManagerService.registerBiz(biz); List bizList = bizManagerService.getBizInOrder(); - Assert.assertTrue(bizList.size() == 2); - Assert.assertTrue(bizList.get(0).getBizVersion().equals("1.0.1")); - Assert.assertTrue(bizList.get(1).getBizVersion().equals("1.0.0")); + assertTrue(bizList.size() == 2); + assertTrue(bizList.get(0).getBizVersion().equals("1.0.1")); + assertTrue(bizList.get(1).getBizVersion().equals("1.0.0")); biz = bizManagerService.getActiveBiz("test-biz"); - Assert.assertNull(biz); + assertNull(biz); bizManagerService.activeBiz("test-biz", "1.0.1"); - Assert.assertTrue(bizManagerService.getBizState("test-biz", "1.0.1") == BizState.RESOLVED); - Assert.assertTrue(bizManagerService.getBizState("test-biz", "1.0.0") == BizState.RESOLVED); + assertTrue(bizManagerService.getBizState("test-biz", "1.0.1") == RESOLVED); + assertTrue(bizManagerService.getBizState("test-biz", "1.0.0") == RESOLVED); biz = bizManagerService.getBiz("test-biz", "1.0.1"); ((BizModel) biz).setBizState(BizState.DEACTIVATED); bizManagerService.activeBiz("test-biz", "1.0.1"); - Assert.assertTrue(bizManagerService.getBizState("test-biz", "1.0.1") == BizState.ACTIVATED); - Assert.assertTrue(bizManagerService.getBizState("test-biz", "1.0.0") == BizState.RESOLVED); + assertTrue(bizManagerService.getBizState("test-biz", "1.0.1") == ACTIVATED); + assertTrue(bizManagerService.getBizState("test-biz", "1.0.0") == RESOLVED); bizManagerService.activeBiz("test-biz", "1.0.0"); - Assert.assertTrue(bizManagerService.getBizState("test-biz", "1.0.1") == BizState.ACTIVATED); - Assert.assertTrue(bizManagerService.getBizState("test-biz", "1.0.0") == BizState.RESOLVED); + assertTrue(bizManagerService.getBizState("test-biz", "1.0.1") == ACTIVATED); + assertTrue(bizManagerService.getBizState("test-biz", "1.0.0") == RESOLVED); biz = bizManagerService.getBiz("test-biz", "1.0.0"); ((BizModel) biz).setBizState(BizState.DEACTIVATED); bizManagerService.activeBiz("test-biz", "1.0.0"); - Assert.assertTrue(bizManagerService.getBizState("test-biz", "1.0.0") == BizState.ACTIVATED); - Assert - .assertTrue(bizManagerService.getBizState("test-biz", "1.0.1") == BizState.DEACTIVATED); + assertTrue(bizManagerService.getBizState("test-biz", "1.0.0") == ACTIVATED); + assertTrue(bizManagerService.getBizState("test-biz", "1.0.1") == BizState.DEACTIVATED); + } + + @Test(expected = ArkRuntimeException.class) + public void testDeployWithException() throws IllegalAccessException { + + Biz biz = new BizModel().setBizName("test-biz").setBizVersion("1.0.3") + .setBizState(RESOLVED).setPriority("10"); + bizManagerService.registerBiz(biz); + DefaultBizDeployer defaultBizDeployer = new DefaultBizDeployer(); + setVariableValueInObject(defaultBizDeployer, "bizManagerService", bizManagerService); + defaultBizDeployer.deploy(); } -} \ No newline at end of file + @Test(expected = ArkRuntimeException.class) + public void testUndeployWithException() throws IllegalAccessException { + + Biz biz = new BizModel().setBizName("test-biz").setBizVersion("1.0.3") + .setBizState(RESOLVED).setPriority("10"); + bizManagerService.registerBiz(biz); + + DefaultBizDeployer defaultBizDeployer = new DefaultBizDeployer(); + setVariableValueInObject(defaultBizDeployer, "bizManagerService", bizManagerService); + defaultBizDeployer.unDeploy(); + } + + @Test + public void testIsActiveBiz() { + + bizManagerService = new BizManagerServiceImpl(); + assertNull(bizManagerService.getBizByClassLoader(this.getClass().getClassLoader())); + + Biz biz = new BizModel().setBizName("test-biz").setBizVersion("1.0.1") + .setBizState(RESOLVED).setPriority("10"); + bizManagerService.registerBiz(biz); + + assertFalse(bizManagerService.isActiveBiz("test-biz", "1.0.1")); + assertFalse(bizManagerService.isActiveBiz("test-biz", "2.0.1")); + assertNotNull(bizManagerService.getBizRegistration()); + } +} diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/classloader/BizClassLoaderTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/classloader/BizClassLoaderTest.java index b72b3b249..3d8ca9b7f 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/classloader/BizClassLoaderTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/classloader/BizClassLoaderTest.java @@ -213,6 +213,65 @@ public void testLoadClassFromPluginClassLoader() throws Exception { Assert.assertFalse(bizModel.getBizClassLoader().getResources("Sample_Resource_Not_Exported").hasMoreElements()); } + @Test + public void testLoadOverrideClassFromPluginClassLoader() throws Exception { + URL bizUrl = this.getClass().getClassLoader().getResource("sample-ark-1.0.0-ark-biz.jar"); + URL pluginUrl1 = this.getClass().getClassLoader() + .getResource("sample-ark-plugin-0.5.0.jar"); + URL pluginUrl2 = this.getClass().getClassLoader().getResource("sample-biz-0.3.0.jar"); + + BizModel bizModel = createTestBizModel("biz A", "1.0.0", BizState.RESOLVED, + new URL[] { bizUrl }); + bizModel.setDenyImportClasses(StringUtils.EMPTY_STRING); + bizModel.setDenyImportPackages(StringUtils.EMPTY_STRING); + bizModel.setDenyImportResources(StringUtils.EMPTY_STRING); + bizModel.setDeclaredLibraries("sample-ark-plugin, sample-biz"); + + PluginModel pluginA = new PluginModel(); + pluginA + .setPluginName("plugin A") + .setClassPath(new URL[] { classPathURL, pluginUrl1, pluginUrl2 }) + .setImportClasses(StringUtils.EMPTY_STRING) + .setImportPackages(StringUtils.EMPTY_STRING) + .setExportMode(PluginModel.EXPORTMODE_OVERRIDE) + .setExportClasses("com.alipay.sofa.ark.sample.common.SampleClassExported") + .setExportPackages("") + .setImportResources(StringUtils.EMPTY_STRING) + .setExportResources("") + .setPluginClassLoader( + new PluginClassLoader(pluginA.getPluginName(), pluginA.getClassPath())); + + PluginModel pluginB = new PluginModel(); + pluginB + .setPluginName("plugin B") + .setClassPath(new URL[] { classPathURL, pluginUrl1, pluginUrl2 }) + .setImportClasses(StringUtils.EMPTY_STRING) + .setImportPackages(StringUtils.EMPTY_STRING) + .setExportMode(PluginModel.EXPORTMODE_CLASSLOADER) + .setExportClasses("com.alipay.sofa.ark.sample.springbootdemo.SpringbootDemoApplication") + .setExportPackages("") + .setImportResources(StringUtils.EMPTY_STRING) + .setExportResources("") + .setPluginClassLoader( + new PluginClassLoader(pluginB.getPluginName(), pluginB.getClassPath())); + + pluginManagerService.registerPlugin(pluginA); + pluginManagerService.registerPlugin(pluginB); + pluginDeployService.deploy(); + classloaderService.prepareExportClassAndResourceCache(); + + bizManagerService.registerBiz(bizModel); + + // case 1: find class from multiple libs in plugin classloader + Class adviceClazz1 = bizModel.getBizClassLoader().loadClass( + "com.alipay.sofa.ark.sample.common.SampleClassExported"); + Assert.assertEquals(adviceClazz1.getClassLoader(), bizModel.getBizClassLoader()); + + Class adviceClazz2 = bizModel.getBizClassLoader().loadClass( + "com.alipay.sofa.ark.sample.springbootdemo.SpringbootDemoApplication"); + Assert.assertEquals(adviceClazz2.getClassLoader(), pluginB.getPluginClassLoader()); + } + @Test public void testGetPluginClassResource() { PluginModel pluginA = new PluginModel(); diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/classloader/ClassLoaderServiceTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/classloader/ClassLoaderServiceTest.java index dc318be9d..3e6875cef 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/classloader/ClassLoaderServiceTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/classloader/ClassLoaderServiceTest.java @@ -16,24 +16,30 @@ */ package com.alipay.sofa.ark.container.service.classloader; -import com.alipay.sofa.ark.common.util.AssertUtils; import com.alipay.sofa.ark.container.BaseTest; import com.alipay.sofa.ark.container.model.BizModel; import com.alipay.sofa.ark.container.model.PluginModel; import com.alipay.sofa.ark.container.service.ArkServiceContainerHolder; import com.alipay.sofa.ark.spi.model.Biz; -import com.alipay.sofa.ark.spi.model.BizState; import com.alipay.sofa.ark.spi.model.Plugin; import com.alipay.sofa.ark.spi.service.biz.BizManagerService; import com.alipay.sofa.ark.spi.service.classloader.ClassLoaderService; import com.alipay.sofa.ark.spi.service.plugin.PluginManagerService; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import java.lang.reflect.Field; import java.net.URL; import java.net.URLClassLoader; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import static com.alipay.sofa.ark.common.util.AssertUtils.isFalse; +import static com.alipay.sofa.ark.common.util.AssertUtils.isTrue; +import static com.alipay.sofa.ark.spi.model.BizState.RESOLVED; +import static java.util.Arrays.asList; +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; /** * @@ -59,125 +65,119 @@ public void before() { @Test public void testIsSunReflect() { - Assert.assertTrue(classloaderService - .isSunReflectClass("sun.reflect.GeneratedMethodAccessor100")); + assertTrue(classloaderService.isSunReflectClass("sun.reflect.GeneratedMethodAccessor100")); } @Test public void testIsNotSunReflect() { - Assert.assertFalse(classloaderService.isSunReflectClass("test")); + assertFalse(classloaderService.isSunReflectClass("test")); } @Test public void testIsArkSpiClass() { - Assert.assertTrue(classloaderService - .isArkSpiClass("com.alipay.sofa.ark.spi.service.ArkService")); + assertTrue(classloaderService.isArkSpiClass("com.alipay.sofa.ark.spi.service.ArkService")); } @Test public void testIsNotArkSpiClass() { - Assert.assertFalse(classloaderService.isArkSpiClass("test")); + assertFalse(classloaderService.isArkSpiClass("test")); } @Test public void testJDKClassLoader() { String sunToolClass = "sun.tools.attach.BsdVirtualMachine"; ClassLoader jdkClassLoader = classloaderService.getJDKClassLoader(); - Assert.assertNotNull(jdkClassLoader); + assertNotNull(jdkClassLoader); try { // only when this class can be loaded from system classloader, // then it should be loaded successfully from jdkClassLoader classloaderService.getSystemClassLoader().loadClass(sunToolClass); - Assert.assertNotNull(jdkClassLoader.loadClass(sunToolClass)); + assertNotNull(jdkClassLoader.loadClass(sunToolClass)); } catch (ClassNotFoundException e) { // ignore } - } @Test public void testArkClassLoader() { ClassLoader arkClassLoader = classloaderService.getArkClassLoader(); - Assert.assertNotNull(arkClassLoader); + assertNotNull(arkClassLoader); } @Test public void testSystemClassLoader() { ClassLoader systemClassLoader = classloaderService.getSystemClassLoader(); - Assert.assertNotNull(systemClassLoader); + assertNotNull(systemClassLoader); } @Test public void testAgentClassLoader() throws ClassNotFoundException { ClassLoader agentClassLoader = classloaderService.getAgentClassLoader(); - Assert.assertNotNull(agentClassLoader); - Assert.assertTrue(((URLClassLoader) agentClassLoader).getURLs().length == 2); - Assert.assertNotNull(agentClassLoader.loadClass("SampleClass")); + assertNotNull(agentClassLoader); + assertTrue(((URLClassLoader) agentClassLoader).getURLs().length == 2); + assertNotNull(agentClassLoader.loadClass("SampleClass")); } @Test public void testIsDeniedImportClass() { + Biz biz = new BizModel().setBizName("mockBiz").setBizVersion("1.0.0") .setDenyImportPackages("a.c, a.b.c.*, a.b.c").setDenyImportClasses("") - .setBizState(BizState.RESOLVED); + .setBizState(RESOLVED); bizManagerService.registerBiz(biz); - AssertUtils.isFalse(classloaderService.isDeniedImportClass(biz.getIdentity(), "a.c"), - "Exception error"); + isFalse(classloaderService.isDeniedImportClass(biz.getIdentity(), "a.c"), "Exception error"); - AssertUtils.isTrue(classloaderService.isDeniedImportClass(biz.getIdentity(), "a.c.E"), + isTrue(classloaderService.isDeniedImportClass(biz.getIdentity(), "a.c.E"), "Exception error"); - AssertUtils.isFalse(classloaderService.isDeniedImportClass(biz.getIdentity(), "a.c.e.G"), + isFalse(classloaderService.isDeniedImportClass(biz.getIdentity(), "a.c.e.G"), "Exception error"); - - AssertUtils.isTrue(classloaderService.isDeniedImportClass(biz.getIdentity(), "a.b.c.E"), + isTrue(classloaderService.isDeniedImportClass(biz.getIdentity(), "a.b.c.E"), "Exception error"); - AssertUtils.isTrue(classloaderService.isDeniedImportClass(biz.getIdentity(), "a.b.c.e.G"), + isTrue(classloaderService.isDeniedImportClass(biz.getIdentity(), "a.b.c.e.G"), "Exception error"); - AssertUtils.isFalse(classloaderService.isDeniedImportClass(biz.getIdentity(), "a.b.c"), + isFalse(classloaderService.isDeniedImportClass(biz.getIdentity(), "a.b.c"), "Exception error"); } @Test public void testIsClassImport() { + Plugin plugin = new PluginModel().setPluginName("mockPlugin").setImportClasses(null) .setImportPackages("a.c,a.b.c.*,a.b.c"); pluginManagerService.registerPlugin(plugin); - Assert.assertTrue(classloaderService.isClassInImport("mockPlugin", "a.c.e")); - Assert.assertFalse(classloaderService.isClassInImport("mockPlugin", "a.c")); - Assert.assertFalse(classloaderService.isClassInImport("mockPlugin", "a.c.e.f")); - - Assert.assertFalse(classloaderService.isClassInImport("mockPlugin", "a.b.c")); - Assert.assertTrue(classloaderService.isClassInImport("mockPlugin", "a.b.c.e")); - Assert.assertTrue(classloaderService.isClassInImport("mockPlugin", "a.b.c.e.f")); + assertTrue(classloaderService.isClassInImport("mockPlugin", "a.c.e")); + assertFalse(classloaderService.isClassInImport("mockPlugin", "a.c")); + assertFalse(classloaderService.isClassInImport("mockPlugin", "a.c.e.f")); + assertFalse(classloaderService.isClassInImport("mockPlugin", "a.b.c")); + assertTrue(classloaderService.isClassInImport("mockPlugin", "a.b.c.e")); + assertTrue(classloaderService.isClassInImport("mockPlugin", "a.b.c.e.f")); } @Test public void testFindExportClass() { + PluginClassLoader pluginClassLoader = new PluginClassLoader("mockPlugin", new URL[] {}); Plugin plugin = new PluginModel().setPluginName("mockPlugin") .setExportPackages("a.b.*,a.f,a.b.f").setExportClasses("a.e.f.G") .setPluginClassLoader(pluginClassLoader).setExportResources(""); + pluginManagerService.registerPlugin(plugin); classloaderService.prepareExportClassAndResourceCache(); - Assert.assertNull(classloaderService.findExportClassLoader("a.b")); - Assert.assertTrue(pluginClassLoader.equals(classloaderService - .findExportClassLoader("a.b.e.f"))); - Assert.assertTrue(pluginClassLoader.equals(classloaderService - .findExportClassLoader("a.f.g"))); - Assert.assertTrue(pluginClassLoader.equals(classloaderService - .findExportClassLoader("a.e.f.G"))); - Assert.assertTrue(pluginClassLoader.equals(classloaderService - .findExportClassLoader("a.b.f.m"))); - Assert.assertTrue(pluginClassLoader.equals(classloaderService - .findExportClassLoader("a.b.f.m.g"))); - Assert.assertNull(classloaderService.findExportClassLoader("a.f.h.m")); - Assert.assertNull(classloaderService.findExportClassLoader("a")); + assertNull(classloaderService.findExportClassLoader("a.b")); + assertTrue(pluginClassLoader.equals(classloaderService.findExportClassLoader("a.b.e.f"))); + assertTrue(pluginClassLoader.equals(classloaderService.findExportClassLoader("a.f.g"))); + assertTrue(pluginClassLoader.equals(classloaderService.findExportClassLoader("a.e.f.G"))); + assertTrue(pluginClassLoader.equals(classloaderService.findExportClassLoader("a.b.f.m"))); + assertTrue(pluginClassLoader.equals(classloaderService.findExportClassLoader("a.b.f.m.g"))); + assertNull(classloaderService.findExportClassLoader("a.f.h.m")); + assertNull(classloaderService.findExportClassLoader("a")); pluginManagerService.getPluginsInOrder().remove(plugin); } @Test public void testFindExportResources() { + PluginClassLoader pluginClassLoader = new PluginClassLoader("mockPlugin", new URL[] {}); String exportResources = "spring-beans.xsd,*.xsd,com/alipay/sofa/*,xml-test.xml"; Plugin plugin = new PluginModel().setPluginName("mockPlugin").setExportPackages("") @@ -187,18 +187,34 @@ public void testFindExportResources() { classloaderService.prepareExportClassAndResourceCache(); Set exportPrefixResourceStems = plugin.getExportPrefixResourceStems(); - Assert.assertTrue(exportPrefixResourceStems.contains("com/alipay/sofa/")); + assertTrue(exportPrefixResourceStems.contains("com/alipay/sofa/")); Set exportSuffixResourceStems = plugin.getExportSuffixResourceStems(); - Assert.assertTrue(exportSuffixResourceStems.contains(".xsd")); + assertTrue(exportSuffixResourceStems.contains(".xsd")); Set resources = plugin.getExportResources(); - Assert.assertTrue(resources.contains("xml-test.xml")); - Assert.assertTrue(resources.contains("spring-beans.xsd")); + assertTrue(resources.contains("xml-test.xml")); + assertTrue(resources.contains("spring-beans.xsd")); plugin.getExportPrefixResourceStems().clear(); plugin.getExportSuffixResourceStems().clear(); plugin.getExportResources().clear(); pluginManagerService.getPluginsInOrder().remove(plugin); } -} \ No newline at end of file + + @Test + public void testFindExportResourceClassLoadersInOrder() throws Exception { + + Field field = ClassLoaderServiceImpl.class + .getDeclaredField("exportSuffixStemResourceAndClassLoaderMap"); + field.setAccessible(true); + ConcurrentHashMap exportPrefixStemResourceAndClassLoaderMap = new ConcurrentHashMap<>(); + Plugin plugin = mock(Plugin.class); + exportPrefixStemResourceAndClassLoaderMap.put("myaaa", asList(plugin)); + field.set(classloaderService, exportPrefixStemResourceAndClassLoaderMap); + assertEquals(null, classloaderService.findExportResourceClassLoadersInOrder("myaaa").get(0)); + + assertNull(classloaderService.getBizClassLoader("aaa:1.0")); + assertNull(classloaderService.getPluginClassLoader("aaa:2.0")); + } +} diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/classloader/PluginClassLoaderTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/classloader/PluginClassLoaderTest.java index 045ee77c4..bd0bafc9c 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/classloader/PluginClassLoaderTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/classloader/PluginClassLoaderTest.java @@ -17,26 +17,31 @@ package com.alipay.sofa.ark.container.service.classloader; import com.alipay.sofa.ark.api.ArkClient; -import com.alipay.sofa.ark.common.util.ClassLoaderUtils; -import com.alipay.sofa.ark.common.util.ClassUtils; -import com.alipay.sofa.ark.common.util.StringUtils; import com.alipay.sofa.ark.container.BaseTest; -import com.alipay.sofa.ark.container.testdata.ITest; import com.alipay.sofa.ark.container.model.PluginModel; import com.alipay.sofa.ark.container.service.ArkServiceContainerHolder; +import com.alipay.sofa.ark.container.testdata.ITest; +import com.alipay.sofa.ark.exception.ArkLoaderException; import com.alipay.sofa.ark.spi.service.classloader.ClassLoaderService; import com.alipay.sofa.ark.spi.service.plugin.PluginDeployService; import com.alipay.sofa.ark.spi.service.plugin.PluginManagerService; -import com.google.common.collect.Sets; import org.junit.Assert; import org.junit.Before; import org.junit.Test; + import java.io.IOException; import java.net.URL; import java.util.Collections; import java.util.Enumeration; import java.util.List; +import static com.alipay.sofa.ark.common.util.ClassLoaderUtils.getURLs; +import static com.alipay.sofa.ark.common.util.ClassUtils.getPackageName; +import static com.alipay.sofa.ark.common.util.StringUtils.EMPTY_STRING; +import static com.google.common.collect.Sets.newHashSet; +import static java.lang.ClassLoader.getSystemClassLoader; +import static org.junit.Assert.*; + /** * @author ruoshan * @since 0.1.0 @@ -69,12 +74,12 @@ public void testExportAndImport() throws Exception { pluginA .setPluginName("plugin A") .setClassPath(new URL[] { classPathURL }) - .setImportClasses(StringUtils.EMPTY_STRING) - .setImportPackages(StringUtils.EMPTY_STRING) - .setExportPackages(ClassUtils.getPackageName(ITest.class.getName())) + .setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) + .setExportPackages(getPackageName(ITest.class.getName())) .setExportClasses("") - .setExportResources(StringUtils.EMPTY_STRING) - .setImportResources(StringUtils.EMPTY_STRING) + .setExportResources(EMPTY_STRING) + .setImportResources(EMPTY_STRING) .setPluginClassLoader( new PluginClassLoader(pluginA.getPluginName(), pluginA.getClassPath())); @@ -84,11 +89,11 @@ public void testExportAndImport() throws Exception { .setPriority("1") .setClassPath(new URL[] { classPathURL }) .setImportClasses(ITest.class.getName()) - .setImportPackages(StringUtils.EMPTY_STRING) + .setImportPackages(EMPTY_STRING) .setExportPackages("") .setExportClasses("") - .setExportResources(StringUtils.EMPTY_STRING) - .setImportResources(StringUtils.EMPTY_STRING) + .setExportResources(EMPTY_STRING) + .setImportResources(EMPTY_STRING) .setPluginClassLoader( new PluginClassLoader(pluginB.getPluginName(), pluginB.getClassPath())); @@ -97,9 +102,8 @@ public void testExportAndImport() throws Exception { classloaderService.prepareExportClassAndResourceCache(); pluginDeployService.deploy(); - Assert.assertEquals(pluginA.getPluginClassLoader().loadClass(ITest.class.getName()), - pluginB.getPluginClassLoader().loadClass(ITest.class.getName())); - + assertEquals(pluginA.getPluginClassLoader().loadClass(ITest.class.getName()), pluginB + .getPluginClassLoader().loadClass(ITest.class.getName())); } @Test @@ -108,12 +112,12 @@ public void testExportAndNotImport() throws Exception { pluginA .setPluginName("plugin A") .setClassPath(new URL[] { classPathURL }) - .setImportClasses(StringUtils.EMPTY_STRING) - .setImportPackages(StringUtils.EMPTY_STRING) + .setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) .setExportPackages("com.alipay.sofa.ark") .setExportClasses("") - .setExportResources(StringUtils.EMPTY_STRING) - .setImportResources(StringUtils.EMPTY_STRING) + .setExportResources(EMPTY_STRING) + .setImportResources(EMPTY_STRING) .setPluginClassLoader( new PluginClassLoader(pluginA.getPluginName(), pluginA.getClassPath())); @@ -122,12 +126,12 @@ public void testExportAndNotImport() throws Exception { .setPluginName("plugin B") .setPriority("1") .setClassPath(new URL[] { classPathURL }) - .setImportClasses(StringUtils.EMPTY_STRING) - .setImportPackages(StringUtils.EMPTY_STRING) + .setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) .setExportPackages("") .setExportClasses("") - .setExportResources(StringUtils.EMPTY_STRING) - .setImportResources(StringUtils.EMPTY_STRING) + .setExportResources(EMPTY_STRING) + .setImportResources(EMPTY_STRING) .setPluginClassLoader( new PluginClassLoader(pluginB.getPluginName(), pluginB.getClassPath())); @@ -147,11 +151,11 @@ public void testExportResource() { pluginA .setPluginName("pluginA") .setClassPath(new URL[] { classPathURL }) - .setImportClasses(StringUtils.EMPTY_STRING) - .setImportPackages(StringUtils.EMPTY_STRING) - .setExportPackages(ClassUtils.getPackageName(ITest.class.getCanonicalName())) + .setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) + .setExportPackages(getPackageName(ITest.class.getCanonicalName())) .setExportClasses("") - .setImportResources(StringUtils.EMPTY_STRING) + .setImportResources(EMPTY_STRING) .setExportResources("pluginA_export_resource1.xml,pluginA_export_resource2.xml") .setPluginClassLoader( new PluginClassLoader(pluginA.getPluginName(), pluginA.getClassPath())); @@ -161,12 +165,12 @@ public void testExportResource() { .setPluginName("pluginB") .setPriority("1") .setClassPath(new URL[0]) - .setImportClasses(StringUtils.EMPTY_STRING) - .setImportPackages(StringUtils.EMPTY_STRING) + .setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) .setExportPackages("") .setExportClasses("") .setImportResources("pluginA_export_resource1.xml") - .setExportResources(StringUtils.EMPTY_STRING) + .setExportResources(EMPTY_STRING) .setPluginClassLoader( new PluginClassLoader(pluginB.getPluginName(), pluginB.getClassPath())); @@ -175,8 +179,7 @@ public void testExportResource() { classloaderService.prepareExportClassAndResourceCache(); pluginDeployService.deploy(); - Assert.assertNotNull(pluginB.getPluginClassLoader().getResource( - "pluginA_export_resource1.xml")); + assertNotNull(pluginB.getPluginClassLoader().getResource("pluginA_export_resource1.xml")); Assert.assertNull(pluginB.getPluginClassLoader() .getResource("pluginA_export_resource2.xml")); Assert.assertNull(pluginB.getPluginClassLoader().getResource( @@ -193,11 +196,11 @@ public void testMultiExportResource() throws Exception { .setPluginName("pluginA") .setPriority("100") .setClassPath(new URL[] { classPathURL }) - .setImportClasses(StringUtils.EMPTY_STRING) - .setImportPackages(StringUtils.EMPTY_STRING) - .setExportPackages(ClassUtils.getPackageName(ITest.class.getCanonicalName())) + .setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) + .setExportPackages(getPackageName(ITest.class.getCanonicalName())) .setExportClasses("") - .setImportResources(StringUtils.EMPTY_STRING) + .setImportResources(EMPTY_STRING) .setExportResources(resourceName) .setPluginClassLoader( new PluginClassLoader(pluginA.getPluginName(), pluginA.getClassPath())); @@ -207,11 +210,11 @@ public void testMultiExportResource() throws Exception { .setPluginName("pluginB") .setPriority("1") .setClassPath(new URL[] { classPathURL }) - .setImportClasses(StringUtils.EMPTY_STRING) - .setImportPackages(StringUtils.EMPTY_STRING) + .setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) .setExportPackages("") .setExportClasses("") - .setImportResources(StringUtils.EMPTY_STRING) + .setImportResources(EMPTY_STRING) .setExportResources(resourceName) .setPluginClassLoader( new PluginClassLoader(pluginB.getPluginName(), pluginB.getClassPath())); @@ -221,11 +224,11 @@ public void testMultiExportResource() throws Exception { .setPluginName("pluginC") .setPriority("1000") .setClassPath(new URL[] { classPathURL }) - .setImportClasses(StringUtils.EMPTY_STRING) - .setImportPackages(StringUtils.EMPTY_STRING) + .setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) .setExportPackages("") .setExportClasses("") - .setImportResources(StringUtils.EMPTY_STRING) + .setImportResources(EMPTY_STRING) .setExportResources(resourceName) .setPluginClassLoader( new PluginClassLoader(pluginC.getPluginName(), pluginC.getClassPath())); @@ -234,12 +237,12 @@ public void testMultiExportResource() throws Exception { pluginD .setPluginName("pluginD") .setClassPath(new URL[0]) - .setImportClasses(StringUtils.EMPTY_STRING) - .setImportPackages(StringUtils.EMPTY_STRING) + .setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) .setExportPackages("") .setExportClasses("") .setImportResources(resourceName) - .setExportResources(StringUtils.EMPTY_STRING) + .setExportResources(EMPTY_STRING) .setPluginClassLoader( new PluginClassLoader(pluginD.getPluginName(), pluginD.getClassPath())); @@ -251,14 +254,14 @@ public void testMultiExportResource() throws Exception { pluginDeployService.deploy(); Enumeration urlEnumeration = pluginD.getPluginClassLoader().getResources(resourceName); - Assert.assertEquals(3, Collections.list(urlEnumeration).size()); + assertEquals(3, Collections.list(urlEnumeration).size()); List classLoaders = classloaderService .findExportResourceClassLoadersInOrder(resourceName); - Assert.assertEquals(3, classLoaders.size()); - Assert.assertEquals(pluginB.getPluginClassLoader(), classLoaders.get(0)); - Assert.assertEquals(pluginA.getPluginClassLoader(), classLoaders.get(1)); - Assert.assertEquals(pluginC.getPluginClassLoader(), classLoaders.get(2)); + assertEquals(3, classLoaders.size()); + assertEquals(pluginB.getPluginClassLoader(), classLoaders.get(0)); + assertEquals(pluginA.getPluginClassLoader(), classLoaders.get(1)); + assertEquals(pluginC.getPluginClassLoader(), classLoaders.get(2)); } @Test @@ -268,11 +271,11 @@ public void testExportResourceStems() { .setPluginName("pluginA") .setPriority("100") .setClassPath(new URL[] { classPathURL }) - .setImportClasses(StringUtils.EMPTY_STRING) - .setImportPackages(StringUtils.EMPTY_STRING) - .setExportPackages(StringUtils.EMPTY_STRING) - .setExportClasses(StringUtils.EMPTY_STRING) - .setImportResources(StringUtils.EMPTY_STRING) + .setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) + .setExportPackages(EMPTY_STRING) + .setExportClasses(EMPTY_STRING) + .setImportResources(EMPTY_STRING) .setExportResources("export/folderA/*,export/folderB/*") .setPluginClassLoader( new PluginClassLoader(pluginA.getPluginName(), pluginA.getClassPath())); @@ -282,12 +285,12 @@ public void testExportResourceStems() { .setPluginName("pluginB") .setPriority("1") .setClassPath(new URL[0]) - .setImportClasses(StringUtils.EMPTY_STRING) - .setImportPackages(StringUtils.EMPTY_STRING) - .setExportPackages(StringUtils.EMPTY_STRING) - .setExportClasses(StringUtils.EMPTY_STRING) + .setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) + .setExportPackages(EMPTY_STRING) + .setExportClasses(EMPTY_STRING) .setImportResources("export/folderA/*,export/folderB/test3.xml") - .setExportResources(StringUtils.EMPTY_STRING) + .setExportResources(EMPTY_STRING) .setPluginClassLoader( new PluginClassLoader(pluginB.getPluginName(), pluginB.getClassPath())); @@ -301,11 +304,11 @@ public void testExportResourceStems() { String testResource3 = "export/folderB/test3.xml"; String testResource4 = "export/folderB/test4.xml"; - Assert.assertEquals(pluginA.getPluginClassLoader().getResource(testResource1), pluginB + assertEquals(pluginA.getPluginClassLoader().getResource(testResource1), pluginB .getPluginClassLoader().getResource(testResource1)); - Assert.assertEquals(pluginA.getPluginClassLoader().getResource(testResource2), pluginB + assertEquals(pluginA.getPluginClassLoader().getResource(testResource2), pluginB .getPluginClassLoader().getResource(testResource2)); - Assert.assertEquals(pluginA.getPluginClassLoader().getResource(testResource3), pluginB + assertEquals(pluginA.getPluginClassLoader().getResource(testResource3), pluginB .getPluginClassLoader().getResource(testResource3)); // export/folderB/test4.xml not import Assert.assertNull(pluginB.getPluginClassLoader().getResource(testResource4)); @@ -317,18 +320,18 @@ public void testLoadClassFromAgentClassLoader() throws ClassNotFoundException { mockPlugin .setPluginName("Mock plugin") .setClassPath(new URL[] {}) - .setImportClasses(StringUtils.EMPTY_STRING) - .setImportPackages(StringUtils.EMPTY_STRING) + .setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) .setExportPackages(ITest.class.getCanonicalName()) .setPluginClassLoader( new PluginClassLoader(mockPlugin.getPluginName(), mockPlugin.getClassPath())); pluginManagerService.registerPlugin(mockPlugin); PluginClassLoader pluginClassLoader = (PluginClassLoader) mockPlugin.getPluginClassLoader(); - Assert.assertNotNull(pluginClassLoader.loadClass("SampleClass", false)); + assertNotNull(pluginClassLoader.loadClass("SampleClass", false)); Class clazz = pluginClassLoader.loadClass(ArkClient.class.getCanonicalName()); - Assert.assertTrue(clazz.getClassLoader().equals(classloaderService.getArkClassLoader())); + assertTrue(clazz.getClassLoader().equals(classloaderService.getArkClassLoader())); } @Test @@ -338,9 +341,9 @@ public void testGetJdkResource() throws IOException { mockPlugin .setPluginName("Mock plugin") .setClassPath(new URL[] {}) - .setImportResources(StringUtils.EMPTY_STRING) - .setImportClasses(StringUtils.EMPTY_STRING) - .setImportPackages(StringUtils.EMPTY_STRING) + .setImportResources(EMPTY_STRING) + .setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) .setExportPackages(ITest.class.getCanonicalName()) .setPluginClassLoader( new PluginClassLoader(mockPlugin.getPluginName(), mockPlugin.getClassPath())); @@ -350,37 +353,64 @@ public void testGetJdkResource() throws IOException { // String name = "META-INF/services/javax.script.ScriptEngineFactory"; String name = "javax/lang/model/element/Modifier.class"; - URL res1 = cl.getResource(name); - Assert.assertNotNull(res1); + assertNotNull(res1); - URL res2 = ClassLoader.getSystemClassLoader().getResource(name); - Assert.assertNotNull(res2); - Assert.assertEquals(res2, res1); + URL res2 = getSystemClassLoader().getResource(name); + assertNotNull(res2); + assertEquals(res2, res1); Enumeration enu1 = cl.getResources(name); - Assert.assertTrue(enu1.hasMoreElements()); + assertTrue(enu1.hasMoreElements()); - Enumeration enu2 = ClassLoader.getSystemClassLoader().getResources(name); - Assert.assertEquals(Sets.newHashSet(Collections.list(enu2)), - Sets.newHashSet(Collections.list(enu1))); + Enumeration enu2 = getSystemClassLoader().getResources(name); + assertEquals(newHashSet(Collections.list(enu2)), newHashSet(Collections.list(enu1))); } @Test public void testSlashResource() throws Throwable { ClassLoader classLoader = this.getClass().getClassLoader(); PluginClassLoader pluginClassLoader = new PluginClassLoader("pluginName", - ClassLoaderUtils.getURLs(classLoader)); + getURLs(classLoader)); PluginModel mockPlugin = new PluginModel(); mockPlugin.setPluginName("pluginName").setClassPath(new URL[] {}) - .setImportResources(StringUtils.EMPTY_STRING) - .setImportClasses(StringUtils.EMPTY_STRING).setImportPackages(StringUtils.EMPTY_STRING) - .setExportPackages(ClassUtils.getPackageName(ITest.class.getCanonicalName())) - .setExportClasses(StringUtils.EMPTY_STRING).setPluginClassLoader(pluginClassLoader); + .setImportResources(EMPTY_STRING).setImportClasses(EMPTY_STRING) + .setImportPackages(EMPTY_STRING) + .setExportPackages(getPackageName(ITest.class.getCanonicalName())) + .setExportClasses(EMPTY_STRING).setPluginClassLoader(pluginClassLoader); pluginManagerService.registerPlugin(mockPlugin); URL url = pluginClassLoader.getResource(""); - Assert.assertNotNull(url); - Assert.assertEquals(url, this.getClass().getResource("/")); + assertNotNull(url); + assertEquals(url, this.getClass().getResource("/")); } + @Test(expected = ArkLoaderException.class) + public void testLoadClassInternalWithSunClass() throws Exception { + PluginClassLoader pluginClassLoader = new PluginClassLoader("a", new URL[] { this + .getClass().getResource("/") }); + assertEquals("a", pluginClassLoader.getPluginName()); + pluginClassLoader.loadClassInternal("sun.reflect.GeneratedMethodAccessor", true); + } + + @Test(expected = ArkLoaderException.class) + public void testLoadClassInternalWithResolve() throws Exception { + PluginClassLoader pluginClassLoader = new PluginClassLoader("a", new URL[] { this + .getClass().getResource("/") }); + assertEquals("a", pluginClassLoader.getPluginName()); + pluginClassLoader.loadClassInternal("java.lang.a", true); + } + + @Test(expected = ArkLoaderException.class) + public void testPreLoadClassWithException() throws Exception { + PluginClassLoader pluginClassLoader = new PluginClassLoader("a", new URL[] { this + .getClass().getResource("/") }); + pluginClassLoader.preLoadClass("a"); + } + + @Test(expected = ArkLoaderException.class) + public void testPostLoadClassWithException() throws Exception { + PluginClassLoader pluginClassLoader = new PluginClassLoader("a", new URL[] { this + .getClass().getResource("/") }); + pluginClassLoader.postLoadClass("a"); + } } \ No newline at end of file diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/plugin/PluginCommandProviderTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/plugin/PluginCommandProviderTest.java index e9cbecf11..8d052cb46 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/plugin/PluginCommandProviderTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/plugin/PluginCommandProviderTest.java @@ -18,18 +18,21 @@ import com.alipay.sofa.ark.common.util.ClassLoaderUtils; import com.alipay.sofa.ark.container.model.PluginModel; +import com.alipay.sofa.ark.container.service.plugin.PluginCommandProvider.PluginCommand; import com.alipay.sofa.ark.spi.model.Plugin; import com.alipay.sofa.ark.spi.service.plugin.PluginManagerService; -import org.junit.Assert; import org.junit.Test; -import org.mockito.Mockito; -import static org.mockito.Mockito.when; import java.lang.reflect.Field; import java.net.URL; import java.util.HashSet; import java.util.Set; +import static com.google.common.collect.Sets.newHashSet; +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + /** * @author qilong.zql * @since 0.6.0 @@ -38,21 +41,22 @@ public class PluginCommandProviderTest { @Test public void testPluginCommandFormat() { + PluginCommandProvider pluginCommandProvider = new PluginCommandProvider(); - Assert.assertFalse(pluginCommandProvider.validate(" plugin ")); - Assert.assertTrue(pluginCommandProvider.validate(" plugin -h ")); - Assert.assertTrue(pluginCommandProvider.validate(" plugin -m pluginA ")); - Assert.assertTrue(pluginCommandProvider.validate(" plugin -s pluginB pluginA ")); - Assert.assertTrue(pluginCommandProvider.validate(" plugin -d plugin* ")); - Assert.assertTrue(pluginCommandProvider.validate(" plugin -m -d -s plugin* ")); - Assert.assertTrue(pluginCommandProvider.validate(" plugin -msd pluginA ")); - - Assert.assertFalse(pluginCommandProvider.validate(" plu")); - Assert.assertFalse(pluginCommandProvider.validate(" plugin -h pluginA ")); - Assert.assertFalse(pluginCommandProvider.validate(" plugin -hm pluginA ")); - Assert.assertFalse(pluginCommandProvider.validate(" plugin -mb pluginA ")); - Assert.assertFalse(pluginCommandProvider.validate(" plugin -m -b pluginA ")); - Assert.assertFalse(pluginCommandProvider.validate(" plugin -m ")); + assertFalse(pluginCommandProvider.validate(" plugin ")); + assertTrue(pluginCommandProvider.validate(" plugin -h ")); + assertTrue(pluginCommandProvider.validate(" plugin -m pluginA ")); + assertTrue(pluginCommandProvider.validate(" plugin -s pluginB pluginA ")); + assertTrue(pluginCommandProvider.validate(" plugin -d plugin* ")); + assertTrue(pluginCommandProvider.validate(" plugin -m -d -s plugin* ")); + assertTrue(pluginCommandProvider.validate(" plugin -msd pluginA ")); + + assertFalse(pluginCommandProvider.validate(" plu")); + assertFalse(pluginCommandProvider.validate(" plugin -h pluginA ")); + assertFalse(pluginCommandProvider.validate(" plugin -hm pluginA ")); + assertFalse(pluginCommandProvider.validate(" plugin -mb pluginA ")); + assertFalse(pluginCommandProvider.validate(" plugin -m -b pluginA ")); + assertFalse(pluginCommandProvider.validate(" plugin -m ")); } @Test @@ -79,7 +83,7 @@ public void testPluginCommandProcess() { set.add("pluginA"); set.add("pluginB"); - PluginManagerService pluginManagerService = Mockito.mock(PluginManagerService.class); + PluginManagerService pluginManagerService = mock(PluginManagerService.class); when(pluginManagerService.getAllPluginNames()).thenReturn(set); when(pluginManagerService.getPluginByName("pluginA")).thenReturn(pluginA); when(pluginManagerService.getPluginByName("pluginB")).thenReturn(pluginB); @@ -95,31 +99,52 @@ public void testPluginCommandProcess() { String errorMessage = "Error command format. Pls type 'plugin -h' to get help message\n"; - Assert.assertTrue(errorMessage.equals(pluginCommandProvider.handleCommand("plu"))); - Assert.assertTrue(errorMessage.equals(pluginCommandProvider - .handleCommand("plugin -h pluginA"))); - Assert.assertTrue(errorMessage.equals(pluginCommandProvider - .handleCommand("plugin -b pluginA"))); - Assert.assertTrue(errorMessage.equals(pluginCommandProvider.handleCommand("plu"))); + assertTrue(errorMessage.equals(pluginCommandProvider.handleCommand("plu"))); + assertTrue(errorMessage.equals(pluginCommandProvider.handleCommand("plugin -h pluginA"))); + assertTrue(errorMessage.equals(pluginCommandProvider.handleCommand("plugin -b pluginA"))); + assertTrue(errorMessage.equals(pluginCommandProvider.handleCommand("plu"))); - Assert.assertTrue(pluginCommandProvider.getHelp().equals( + assertTrue(pluginCommandProvider.getHelp().equals( pluginCommandProvider.handleCommand("plugin -h"))); - Assert.assertTrue(errorMessage.equals(pluginCommandProvider.handleCommand("plugin "))); + assertTrue(errorMessage.equals(pluginCommandProvider.handleCommand("plugin "))); String details = pluginCommandProvider.handleCommand("plugin -m -d -s pluginA"); - Assert.assertTrue(details.contains("Activator")); - Assert.assertTrue(details.contains("GroupId")); + assertTrue(details.contains("Activator")); + assertTrue(details.contains("GroupId")); details = pluginCommandProvider.handleCommand("plugin -d pluginB"); - Assert.assertTrue(details.contains("GroupId")); - Assert.assertFalse(details.contains("Activator")); + assertTrue(details.contains("GroupId")); + assertFalse(details.contains("Activator")); details = pluginCommandProvider.handleCommand("plugin -m plugin."); - Assert.assertTrue(details.contains("pluginA")); - Assert.assertTrue(details.contains("pluginB")); + assertTrue(details.contains("pluginA")); + assertTrue(details.contains("pluginB")); details = pluginCommandProvider.handleCommand("plugin -m pluginC"); - Assert.assertTrue(details.contains("no matched plugin candidates.")); + assertTrue(details.contains("no matched plugin candidates.")); } + @Test + public void testPluginList() { + + PluginCommandProvider pluginCommandProvider = new PluginCommandProvider(); + PluginCommand pluginCommand = pluginCommandProvider.new PluginCommand(null); + assertFalse(pluginCommand.isValidate()); + pluginCommand = pluginCommandProvider.new PluginCommand("plugin -"); + assertFalse(pluginCommand.isValidate()); + pluginCommand = pluginCommandProvider.new PluginCommand("plugin -a"); + + PluginManagerService pluginManagerService = mock(PluginManagerService.class); + try { + Field field = PluginCommandProvider.class.getDeclaredField("pluginManagerService"); + field.setAccessible(true); + field.set(pluginCommandProvider, pluginManagerService); + } catch (Throwable throwable) { + // ignore + } + + assertEquals("no plugins.\nplugin count = 0\n", pluginCommand.process()); + when(pluginManagerService.getAllPluginNames()).thenReturn(newHashSet("a")); + assertEquals("a\nplugin count = 1\n", pluginCommand.process()); + } } \ No newline at end of file diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/plugin/PluginFactoryServiceTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/plugin/PluginFactoryServiceTest.java index 5c936b89b..508fb57c9 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/plugin/PluginFactoryServiceTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/plugin/PluginFactoryServiceTest.java @@ -16,25 +16,29 @@ */ package com.alipay.sofa.ark.container.service.plugin; -import com.alipay.sofa.ark.api.ArkConfigs; import com.alipay.sofa.ark.container.BaseTest; +import com.alipay.sofa.ark.exception.ArkRuntimeException; import com.alipay.sofa.ark.loader.JarPluginArchive; import com.alipay.sofa.ark.loader.archive.JarFileArchive; import com.alipay.sofa.ark.loader.jar.JarFile; import com.alipay.sofa.ark.spi.archive.PluginArchive; import com.alipay.sofa.ark.spi.model.Plugin; import com.alipay.sofa.ark.spi.service.plugin.PluginFactoryService; -import org.junit.Assert; +import com.alipay.sofa.ark.spi.service.plugin.PluginManagerService; import org.junit.Test; import java.io.File; import java.io.IOException; import java.net.URL; -import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import static com.alipay.sofa.ark.api.ArkConfigs.putStringValue; import static com.alipay.sofa.ark.spi.constant.Constants.PLUGIN_EXTENSION_FORMAT; +import static java.lang.String.format; +import static java.util.Arrays.asList; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; /** * @author qilong.zql @@ -48,11 +52,12 @@ public void test() throws Throwable { ClassLoader cl = Thread.currentThread().getContextClassLoader(); URL samplePlugin = cl.getResource("sample-plugin.jar"); Plugin plugin = pluginFactoryService.createPlugin(new File(samplePlugin.getFile())); - Assert.assertNotNull(plugin); + assertNotNull(plugin); } @Test public void testCreatePluginWithExtensions() throws Throwable { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); URL samplePlugin = cl.getResource("sample-plugin.jar"); File file = new File(samplePlugin.getFile()); @@ -69,15 +74,13 @@ public void testCreatePluginWithExtensions() throws Throwable { // export Set exportPackages = new HashSet<>(); exportPackages.add("com.alipay.test.export.*"); - - ArkConfigs.putStringValue(String.format(PLUGIN_EXTENSION_FORMAT, "sample-ark-plugin"), - "tracer-core:3.0.10"); + putStringValue(format(PLUGIN_EXTENSION_FORMAT, "sample-ark-plugin"), "tracer-core:3.0.10"); Plugin plugin = pluginFactoryService.createPlugin(jarPluginArchive, extensions, exportPackages); - Assert.assertNotNull(plugin); - Assert.assertEquals(plugin.getExportPackages().size(), 2); - Assert.assertTrue(Arrays.asList(plugin.getClassPath()).contains(bizFile.getUrl())); + assertNotNull(plugin); + assertEquals(plugin.getExportPackages().size(), 2); + assertTrue(asList(plugin.getClassPath()).contains(bizFile.getUrl())); } @Test @@ -88,6 +91,28 @@ public void testCreateEmbedPlugin() throws IOException { samplePlugin.getFile()))); Plugin plugin = pluginFactoryService.createEmbedPlugin(archive, this.getClass() .getClassLoader()); - Assert.assertNotNull(plugin); + assertNotNull(plugin); + } + + @Test(expected = ArkRuntimeException.class) + public void testDeploy() { + PluginDeployServiceImpl pluginDeployServiceImpl = new PluginDeployServiceImpl(); + PluginManagerService pluginManagerService = mock(PluginManagerService.class); + Plugin plugin = mock(Plugin.class); + doThrow(new ArkRuntimeException("test")).when(plugin).start(); + when(pluginManagerService.getPluginsInOrder()).thenReturn(asList(plugin)); + pluginDeployServiceImpl.pluginManagerService = pluginManagerService; + pluginDeployServiceImpl.deploy(); + } + + @Test(expected = ArkRuntimeException.class) + public void testUndeploy() { + PluginDeployServiceImpl pluginDeployServiceImpl = new PluginDeployServiceImpl(); + PluginManagerService pluginManagerService = mock(PluginManagerService.class); + Plugin plugin = mock(Plugin.class); + doThrow(new ArkRuntimeException("test")).when(plugin).stop(); + when(pluginManagerService.getPluginsInOrder()).thenReturn(asList(plugin)); + pluginDeployServiceImpl.pluginManagerService = pluginManagerService; + pluginDeployServiceImpl.unDeploy(); } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/plugin/PluginManagerServiceTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/plugin/PluginManagerServiceTest.java index 43a56ac8e..337b70cf4 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/plugin/PluginManagerServiceTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/plugin/PluginManagerServiceTest.java @@ -22,6 +22,8 @@ import org.junit.Assert; import org.junit.Test; +import static org.junit.Assert.*; + /** * * @author ruoshan @@ -36,9 +38,8 @@ public void testGetPluginByName() { PluginModel plugin = new PluginModel(); plugin.setPluginName("plugin A"); pluginManagerService.registerPlugin(plugin); - Assert.assertNotNull(pluginManagerService.getPluginByName(plugin.getPluginName())); - Assert.assertNull(pluginManagerService.getPluginByName("test")); - + assertNotNull(pluginManagerService.getPluginByName(plugin.getPluginName())); + assertNull(pluginManagerService.getPluginByName("test")); } @Test @@ -51,15 +52,14 @@ public void testGetAllPluginNames() { pluginB.setPluginName("plugin B"); pluginManagerService.registerPlugin(pluginB); - Assert.assertTrue(pluginManagerService.getAllPluginNames() - .contains(pluginA.getPluginName())); - Assert.assertTrue(pluginManagerService.getAllPluginNames() - .contains(pluginB.getPluginName())); - Assert.assertEquals(2, pluginManagerService.getAllPluginNames().size()); + assertTrue(pluginManagerService.getAllPluginNames().contains(pluginA.getPluginName())); + assertTrue(pluginManagerService.getAllPluginNames().contains(pluginB.getPluginName())); + assertEquals(2, pluginManagerService.getAllPluginNames().size()); } @Test public void testGetPluginsInOrder() { + PluginModel pluginA = new PluginModel(); pluginA.setPluginName("plugin A").setPriority("100"); pluginManagerService.registerPlugin(pluginA); @@ -72,9 +72,9 @@ public void testGetPluginsInOrder() { pluginC.setPluginName("plugin C").setPriority("1000"); pluginManagerService.registerPlugin(pluginC); - Assert.assertEquals(3, pluginManagerService.getPluginsInOrder().size()); - Assert.assertEquals(pluginB, pluginManagerService.getPluginsInOrder().get(0)); - Assert.assertEquals(pluginA, pluginManagerService.getPluginsInOrder().get(1)); - Assert.assertEquals(pluginC, pluginManagerService.getPluginsInOrder().get(2)); + assertEquals(3, pluginManagerService.getPluginsInOrder().size()); + assertEquals(pluginB, pluginManagerService.getPluginsInOrder().get(0)); + assertEquals(pluginA, pluginManagerService.getPluginsInOrder().get(1)); + assertEquals(pluginC, pluginManagerService.getPluginsInOrder().get(2)); } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/registry/ServiceRegistrationTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/registry/ServiceRegistrationTest.java index 111c516ea..6b4d38424 100644 --- a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/registry/ServiceRegistrationTest.java +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/service/registry/ServiceRegistrationTest.java @@ -19,22 +19,23 @@ import com.alipay.sofa.ark.common.util.ClassUtils; import com.alipay.sofa.ark.common.util.StringUtils; import com.alipay.sofa.ark.container.BaseTest; +import com.alipay.sofa.ark.container.model.PluginContextImpl; +import com.alipay.sofa.ark.container.model.PluginModel; import com.alipay.sofa.ark.container.registry.ContainerServiceProvider; import com.alipay.sofa.ark.container.registry.DefaultServiceFilter; +import com.alipay.sofa.ark.container.registry.PluginServiceProvider; +import com.alipay.sofa.ark.container.registry.ServiceMetadataImpl; +import com.alipay.sofa.ark.container.service.ArkServiceContainerHolder; +import com.alipay.sofa.ark.container.service.classloader.PluginClassLoader; +import com.alipay.sofa.ark.container.testdata.ITest; import com.alipay.sofa.ark.container.testdata.activator.PluginActivatorA; import com.alipay.sofa.ark.container.testdata.activator.PluginActivatorADup; +import com.alipay.sofa.ark.container.testdata.activator.PluginActivatorB; import com.alipay.sofa.ark.container.testdata.activator.PluginActivatorC; -import com.alipay.sofa.ark.container.testdata.ITest; import com.alipay.sofa.ark.container.testdata.impl.TestObjectA; import com.alipay.sofa.ark.container.testdata.impl.TestObjectB; import com.alipay.sofa.ark.container.testdata.impl.TestObjectC; -import com.alipay.sofa.ark.container.model.PluginContextImpl; -import com.alipay.sofa.ark.container.model.PluginModel; -import com.alipay.sofa.ark.container.registry.PluginServiceProvider; -import com.alipay.sofa.ark.container.service.ArkServiceContainer; -import com.alipay.sofa.ark.container.service.ArkServiceContainerHolder; -import com.alipay.sofa.ark.container.service.classloader.PluginClassLoader; -import com.alipay.sofa.ark.container.testdata.activator.PluginActivatorB; +import com.alipay.sofa.ark.spi.model.Plugin; import com.alipay.sofa.ark.spi.registry.ServiceFilter; import com.alipay.sofa.ark.spi.registry.ServiceProvider; import com.alipay.sofa.ark.spi.registry.ServiceProviderType; @@ -49,10 +50,12 @@ import org.junit.Test; import java.net.URL; -import java.util.Collections; -import java.util.HashSet; import java.util.List; +import static com.google.common.collect.Sets.newHashSet; +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; + /** * @author ruoshan * @since 0.1.0 @@ -99,11 +102,11 @@ public void testPublishService() { ServiceReference iTestServiceReference = registryService.publishService(ITest.class, new TestObjectA(), new ContainerServiceProvider()); Assert.assertNotNull(iTestServiceReference); - Assert.assertEquals(TestObjectA.OUTPUT, iTestServiceReference.getService().test()); + assertEquals(TestObjectA.OUTPUT, iTestServiceReference.getService().test()); int c = registryService.unPublishServices(new DefaultServiceFilter().setServiceInterface( ITest.class).setProviderType(ServiceProviderType.ARK_CONTAINER)); - Assert.assertTrue(c == 1); + assertTrue(c == 1); iTestServiceReference = registryService.referenceService(ITest.class); Assert.assertNull(iTestServiceReference); @@ -116,7 +119,7 @@ public void testReferenceService() { ServiceReference iTestServiceReference = registryService .referenceService(ITest.class); Assert.assertNotNull(iTestServiceReference); - Assert.assertEquals(TestObjectA.OUTPUT, iTestServiceReference.getService().test()); + assertEquals(TestObjectA.OUTPUT, iTestServiceReference.getService().test()); } @Test @@ -128,42 +131,44 @@ public void testPublishDuplicateService() { new ContainerServiceProvider()); // 只有第一个服务发布成功 - Assert.assertEquals(1, registryService.referenceServices(ITest.class).size()); - Assert.assertEquals(TestObjectA.OUTPUT, registryService.referenceService(ITest.class) - .getService().test()); + assertEquals(1, registryService.referenceServices(ITest.class).size()); + assertEquals(TestObjectA.OUTPUT, registryService.referenceService(ITest.class).getService() + .test()); registryService.unPublishServices(new DefaultServiceFilter() .setServiceInterface(ITest.class)); - Assert.assertEquals(0, registryService.referenceServices(ITest.class).size()); + assertEquals(0, registryService.referenceServices(ITest.class).size()); registryService.publishService(ITest.class, new TestObjectA(), "testA", new ContainerServiceProvider()); registryService.publishService(ITest.class, new TestObjectB(), "testB", new ContainerServiceProvider()); - Assert.assertEquals( + assertEquals( 2, registryService.referenceServices( new DefaultServiceFilter().setServiceInterface(ITest.class)).size()); - Assert.assertEquals(TestObjectA.OUTPUT, - registryService.referenceService(ITest.class, "testA").getService().test()); - Assert.assertEquals(TestObjectB.OUTPUT, - registryService.referenceService(ITest.class, "testB").getService().test()); + assertEquals(TestObjectA.OUTPUT, registryService.referenceService(ITest.class, "testA") + .getService().test()); + assertEquals(TestObjectB.OUTPUT, registryService.referenceService(ITest.class, "testB") + .getService().test()); int c = registryService.unPublishServices(new DefaultServiceFilter().setUniqueId("testA")); - Assert.assertTrue(c == 1); + assertTrue(c == 1); c = registryService.unPublishServices(new DefaultServiceFilter().setProviderType( ServiceProviderType.ARK_CONTAINER).setServiceInterface(ITest.class)); - Assert.assertTrue(c == 1); + assertTrue(c == 1); - Assert.assertEquals(0, registryService.referenceServices(ITest.class).size()); + assertEquals(0, registryService.referenceServices(ITest.class).size()); } @Test public void testPublishDuplicateServiceInPlugin() throws Exception { + PluginModel pluginA = new PluginModel(); + PluginContextImpl pluginContext = new PluginContextImpl(pluginA); pluginA .setPluginName("plugin A") .setPriority("10") @@ -183,14 +188,19 @@ public void testPublishDuplicateServiceInPlugin() throws Exception { classloaderService.prepareExportClassAndResourceCache(); pluginDeployService.deploy(); - Assert.assertEquals( + assertEquals( 1, registryService.referenceServices( pluginA.getPluginClassLoader().loadClass(ITest.class.getCanonicalName())).size()); int c = registryService.unPublishServices(new DefaultServiceFilter() .setProviderType(ServiceProviderType.ARK_PLUGIN)); - Assert.assertTrue(c == 1); + assertEquals(1, c); + + assertEquals(pluginA, pluginContext.getPlugin()); + assertEquals(null, pluginContext.getPlugin("notexists")); + assertEquals(PluginClassLoader.class, pluginContext.getClassLoader().getClass()); + assertEquals(newHashSet("plugin A"), pluginContext.getPluginNames()); } @Test @@ -256,7 +266,7 @@ public void testMultipleService() throws Exception { pluginDeployService.deploy(); Class iTest = pluginA.getPluginClassLoader().loadClass(ITest.class.getCanonicalName()); - Assert.assertEquals( + assertEquals( 3, pluginA.getPluginContext() .referenceServices(new DefaultServiceFilter().setServiceInterface(iTest)).size()); @@ -265,14 +275,14 @@ public void testMultipleService() throws Exception { ServiceReference reference = pluginC.getPluginContext().referenceService(iTest); PluginServiceProvider provider = (PluginServiceProvider) reference.getServiceMetadata() .getServiceProvider(); - Assert.assertEquals(pluginB.getPluginName(), provider.getPluginName()); + assertEquals(pluginB.getPluginName(), provider.getPluginName()); List references = pluginC.getPluginContext().referenceServices( new DefaultServiceFilter().setServiceInterface(iTest)); provider = (PluginServiceProvider) references.get(0).getServiceMetadata() .getServiceProvider(); - Assert.assertEquals(pluginB.getPluginName(), provider.getPluginName()); + assertEquals(pluginB.getPluginName(), provider.getPluginName()); } @@ -300,11 +310,11 @@ public void testFilter() { List references = registryService .referenceServices(new DefaultServiceFilter().setServiceInterface(ITest.class) .setProviderType(ServiceProviderType.ARK_PLUGIN)); - Assert.assertTrue(2 == references.size()); + assertTrue(2 == references.size()); PluginServiceProvider provider = (PluginServiceProvider) references.get(0) .getServiceMetadata().getServiceProvider(); - Assert.assertEquals(pluginB.getPluginName(), provider.getPluginName()); + assertEquals(pluginB.getPluginName(), provider.getPluginName()); references = registryService.referenceServices(new ServiceFilter() { @Override @@ -320,21 +330,20 @@ public boolean match(ServiceReference serviceReference) { return false; } }); - Assert.assertTrue(1 == references.size()); + assertTrue(1 == references.size()); provider = (PluginServiceProvider) references.get(0).getServiceMetadata() .getServiceProvider(); - Assert.assertEquals(pluginA.getPluginName(), provider.getPluginName()); + assertEquals(pluginA.getPluginName(), provider.getPluginName()); references = registryService.referenceServices(new DefaultServiceFilter() .setServiceInterface(ITest.class)); - Assert.assertTrue(3 == references.size()); + assertTrue(3 == references.size()); references = registryService.referenceServices(new DefaultServiceFilter().setProviderType( ServiceProviderType.ARK_CONTAINER).setServiceInterface(ITest.class)); - Assert.assertTrue(1 == references.size()); - - Assert.assertEquals("TestObject C", ((TestObjectC) references.get(0).getService()).test()); + assertTrue(1 == references.size()); + assertEquals("TestObject C", ((TestObjectC) references.get(0).getService()).test()); } @Test @@ -346,9 +355,25 @@ public void testContainerService() { registryService.publishService(ITest.class, new TestObjectC(), new ContainerServiceProvider(200)); - Assert.assertEquals(TestObjectB.OUTPUT, registryService.referenceService(ITest.class) - .getService().test()); - Assert.assertEquals(3, registryService.referenceServices(ITest.class).size()); + assertEquals(TestObjectB.OUTPUT, registryService.referenceService(ITest.class).getService() + .test()); + assertEquals(3, registryService.referenceServices(ITest.class).size()); } -} \ No newline at end of file + @Test + public void testEqualsHashCode() { + + ContainerServiceProvider containerServiceProvider = new ContainerServiceProvider(); + containerServiceProvider.hashCode(); + assertEquals(containerServiceProvider, containerServiceProvider); + + ServiceMetadataImpl serviceMetadataImpl = new ServiceMetadataImpl(this.getClass(), "a", + containerServiceProvider); + serviceMetadataImpl.hashCode(); + assertEquals(serviceMetadataImpl, serviceMetadataImpl); + assertFalse(serviceMetadataImpl.equals(null)); + + PluginServiceProvider pluginServiceProvider = new PluginServiceProvider(mock(Plugin.class)); + pluginServiceProvider.hashCode(); + } +} diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/session/NettyTelnetServerTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/session/NettyTelnetServerTest.java new file mode 100644 index 000000000..0c5b10ace --- /dev/null +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/session/NettyTelnetServerTest.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.container.session; + +import com.alipay.sofa.ark.container.service.ArkServiceContainer; +import com.alipay.sofa.ark.container.session.NettyTelnetServer.NettyTelnetHandler; +import com.alipay.sofa.ark.container.session.NettyTelnetServer.NettyTelnetInitializer; +import com.alipay.sofa.ark.exception.ArkRuntimeException; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.net.InetSocketAddress; + +import static com.alipay.sofa.ark.common.util.EnvironmentUtils.getProperty; +import static com.alipay.sofa.ark.common.util.EnvironmentUtils.setProperty; +import static com.alipay.sofa.ark.container.service.ArkServiceContainerHolder.getContainer; +import static com.alipay.sofa.ark.container.service.ArkServiceContainerHolder.setContainer; +import static com.alipay.sofa.ark.spi.constant.Constants.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +public class NettyTelnetServerTest { + + private ArkServiceContainer originalArkServiceContainer; + + private String originalSecurityEnable; + + private String originalTelnetPort; + + @Before + public void before() { + originalArkServiceContainer = getContainer(); + originalSecurityEnable = getProperty(TELNET_SERVER_SECURITY_ENABLE); + originalTelnetPort = getProperty(TELNET_PORT_ATTRIBUTE); + } + + @After + public void after() { + setContainer(originalArkServiceContainer); + setProperty(TELNET_SERVER_SECURITY_ENABLE, + originalSecurityEnable != null ? originalSecurityEnable : ""); + setProperty(TELNET_PORT_ATTRIBUTE, originalTelnetPort != null ? originalTelnetPort : ""); + } + + @Test + public void testNettyTelnetInitializer() throws Exception { + + SocketChannel socketChannel = mock(SocketChannel.class); + ChannelPipeline pipeline = mock(ChannelPipeline.class); + when(socketChannel.pipeline()).thenReturn(pipeline); + + InetSocketAddress inetSocketAddress = mock(InetSocketAddress.class); + when(socketChannel.remoteAddress()).thenReturn(inetSocketAddress); + when(inetSocketAddress.getHostName()).thenReturn(LOCAL_HOST + "1"); + setContainer(mock(ArkServiceContainer.class)); + + NettyTelnetInitializer nettyTelnetInitializer = new NettyTelnetInitializer(); + nettyTelnetInitializer.initChannel(socketChannel); + + setProperty(TELNET_SERVER_SECURITY_ENABLE, "true"); + nettyTelnetInitializer.initChannel(socketChannel); + verify(pipeline, times(4)).addLast(any()); + } + + @Test + public void testNettyTelnetHandler() throws Exception { + + setContainer(mock(ArkServiceContainer.class)); + NettyTelnetHandler nettyTelnetHandler = new NettyTelnetHandler(); + ChannelHandlerContext context = mock(ChannelHandlerContext.class); + when(context.channel()).thenReturn(mock(Channel.class)); + + nettyTelnetHandler.channelActive(context); + nettyTelnetHandler.exceptionCaught(context, new Exception()); + nettyTelnetHandler.channelRead0(context, ""); + nettyTelnetHandler.channelRead0(context, "q"); + } + + @Test(expected = ArkRuntimeException.class) + public void testStandardTelnetServerImplWithInvalidNumber() { + setProperty(TELNET_PORT_ATTRIBUTE, "a"); + new StandardTelnetServerImpl(); + } +} diff --git a/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/test/TestHelperTest.java b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/test/TestHelperTest.java new file mode 100644 index 000000000..094896328 --- /dev/null +++ b/sofa-ark-parent/core-impl/container/src/test/java/com/alipay/sofa/ark/container/test/TestHelperTest.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.container.test; + +import com.alipay.sofa.ark.container.ArkContainer; +import com.alipay.sofa.ark.container.ArkContainerTest; +import org.junit.Test; + +import java.net.URL; + +import static com.alipay.sofa.ark.container.ArkContainer.main; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class TestHelperTest { + + private URL jarURL = ArkContainerTest.class.getClassLoader().getResource("test.jar"); + + @Test + public void testCreateNoneDelegateTestClassLoader() { + ArkContainer arkContainer = null; + try { + String[] args = new String[] { "-Ajar=" + jarURL.toExternalForm(), + "-Aclasspath=" + jarURL.toString() }; + arkContainer = (ArkContainer) main(args); + TestHelper testHelper = new TestHelper(arkContainer); + assertTrue(testHelper.isStarted()); + assertEquals(NoneDelegateTestClassLoader.class, testHelper + .createNoneDelegateTestClassLoader().getClass()); + } finally { + if (arkContainer != null) { + arkContainer.stop(); + } + } + } +} diff --git a/sofa-ark-parent/core/api/pom.xml b/sofa-ark-parent/core/api/pom.xml index 6af089fdd..ee4de7d29 100644 --- a/sofa-ark-parent/core/api/pom.xml +++ b/sofa-ark-parent/core/api/pom.xml @@ -20,5 +20,11 @@ com.alipay.sofa sofa-ark-common + + + junit + junit + test + diff --git a/sofa-ark-parent/core/api/src/test/java/com/alipay/sofa/ark/api/ArkConfigsTest.java b/sofa-ark-parent/core/api/src/test/java/com/alipay/sofa/ark/api/ArkConfigsTest.java new file mode 100644 index 000000000..9b367f198 --- /dev/null +++ b/sofa-ark-parent/core/api/src/test/java/com/alipay/sofa/ark/api/ArkConfigsTest.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.api; + +import org.junit.Test; + +import java.net.URL; + +import static com.alipay.sofa.ark.api.ArkConfigs.getStringValue; +import static com.alipay.sofa.ark.api.ArkConfigs.init; +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; + +public class ArkConfigsTest { + + @Test + public void testLoadConfigFile() throws Exception { + URL resource = this.getClass().getClassLoader().getResource("test.props"); + init(asList(resource)); + assertEquals("b123", getStringValue("a123")); + assertEquals("d123", getStringValue("c123")); + } +} diff --git a/sofa-ark-parent/core/api/src/test/resources/test.props b/sofa-ark-parent/core/api/src/test/resources/test.props new file mode 100644 index 000000000..e88cbaa43 --- /dev/null +++ b/sofa-ark-parent/core/api/src/test/resources/test.props @@ -0,0 +1,2 @@ +a123=b123 +c123=d123 \ No newline at end of file diff --git a/sofa-ark-parent/core/common/pom.xml b/sofa-ark-parent/core/common/pom.xml index 9b4771685..4c0047a4f 100644 --- a/sofa-ark-parent/core/common/pom.xml +++ b/sofa-ark-parent/core/common/pom.xml @@ -58,6 +58,12 @@ junit test + + commons-beanutils + commons-beanutils + 1.8.0 + test + diff --git a/sofa-ark-parent/core/common/src/main/java/com/alipay/sofa/ark/common/util/ClassLoaderUtils.java b/sofa-ark-parent/core/common/src/main/java/com/alipay/sofa/ark/common/util/ClassLoaderUtils.java index a79ed6ff6..4a7f451f5 100644 --- a/sofa-ark-parent/core/common/src/main/java/com/alipay/sofa/ark/common/util/ClassLoaderUtils.java +++ b/sofa-ark-parent/core/common/src/main/java/com/alipay/sofa/ark/common/util/ClassLoaderUtils.java @@ -83,7 +83,7 @@ public List run() { argument = argument.substring(JAVA_AGENT_MARK.length()); try { String path = argument.split(JAVA_AGENT_OPTION_MARK)[0]; - URL url = new File(path).getCanonicalFile().toURI().toURL(); + URL url = FileUtils.file(path).getCanonicalFile().toURI().toURL(); agentPaths.add(url); processSkyWalking(path, agentPaths); } catch (Throwable e) { @@ -91,6 +91,7 @@ public List run() { } } return agentPaths.toArray(new URL[] {}); + } /** @@ -102,7 +103,7 @@ public List run() { public static void processSkyWalking(final String path, final List agentPaths) throws MalformedURLException, IOException { if (path.contains(SKYWALKING_AGENT_JAR)) { for (String mountFolder : SKYWALKING_MOUNT_DIR) { - File folder = new File(new File(path).getCanonicalFile().getParentFile(), mountFolder); + File folder = new File(FileUtils.file(path).getCanonicalFile().getParentFile(), mountFolder); if (folder.exists() && folder.isDirectory()) { String[] jarFileNames = folder.list((dir, name) -> name.endsWith(".jar")); for (String fileName: jarFileNames) { @@ -128,7 +129,7 @@ public static URL[] getURLs(ClassLoader classLoader) { for (String classpathEntry : classpathEntries) { URL url = null; try { - url = new File(classpathEntry).toURI().toURL(); + url = FileUtils.file(classpathEntry).toURI().toURL(); } catch (MalformedURLException e) { e.printStackTrace(); throw new ArkRuntimeException("Failed to get urls from " + classLoader, e); diff --git a/sofa-ark-parent/core/common/src/main/java/com/alipay/sofa/ark/common/util/ClassUtils.java b/sofa-ark-parent/core/common/src/main/java/com/alipay/sofa/ark/common/util/ClassUtils.java index 6209c5a2c..7dbf11f25 100644 --- a/sofa-ark-parent/core/common/src/main/java/com/alipay/sofa/ark/common/util/ClassUtils.java +++ b/sofa-ark-parent/core/common/src/main/java/com/alipay/sofa/ark/common/util/ClassUtils.java @@ -17,10 +17,18 @@ package com.alipay.sofa.ark.common.util; import com.alipay.sofa.ark.spi.constant.Constants; +import org.apache.commons.io.FileUtils; +import java.io.File; +import java.io.IOException; import java.net.URL; import java.security.CodeSource; import java.security.ProtectionDomain; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * @author qilong.zql @@ -43,6 +51,32 @@ public static String getPackageName(String className) { return Constants.DEFAULT_PACKAGE; } + /** + * find all compiled classes in dir, ignore inner, anonymous and local classes + * @param dir directory that stores class files + * @return compiled class names + */ + public static List collectClasses(File dir) throws IOException { + List classNames = new ArrayList<>(); + Collection classFiles = FileUtils.listFiles(dir, new String[] { "class" }, true); + String basePath = dir.getCanonicalPath(); + + for (File classFile : classFiles) { + // Get the relative file path starting after the classes directory + String relativePath = classFile.getCanonicalPath().substring(basePath.length() + 1); + + // Convert file path to class name (replace file separators with dots and remove .class extension) + String className = relativePath.replace(File.separatorChar, '.').replaceAll( + "\\.class$", ""); + + // skip inner, anonymous and local classes + if (!className.contains("$")) { + classNames.add(className); + } + } + return classNames; + } + public static String getCodeBase(Class cls) { if (cls == null) { @@ -62,4 +96,4 @@ public static String getCodeBase(Class cls) { } return location.getFile(); } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core/common/src/main/java/com/alipay/sofa/ark/common/util/FileUtils.java b/sofa-ark-parent/core/common/src/main/java/com/alipay/sofa/ark/common/util/FileUtils.java index bccd2c412..357de3d76 100644 --- a/sofa-ark-parent/core/common/src/main/java/com/alipay/sofa/ark/common/util/FileUtils.java +++ b/sofa-ark-parent/core/common/src/main/java/com/alipay/sofa/ark/common/util/FileUtils.java @@ -18,11 +18,9 @@ import com.alipay.sofa.ark.exception.ArkRuntimeException; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -77,7 +75,7 @@ private static String bytesToHex(byte[] bytes) { * temporary directory (as defined by the {@code java.io.tmpdir} system */ public static File createTempDir(String subPath) { - File baseDir = new File(System.getProperty("java.io.tmpdir")); + File baseDir = FileUtils.file(System.getProperty("java.io.tmpdir")); File tempDir = new File(baseDir, subPath); if (tempDir.exists()) { return tempDir; @@ -119,14 +117,14 @@ public static File unzip(File root, String targetPath) throws IOException { ZipEntry entry = entries.nextElement(); if (entry.isDirectory()) { String dirPath = targetPath + File.separator + entry.getName(); - File dir = new File(dirPath); + File dir = FileUtils.file(dirPath); dir.mkdirs(); } else { InputStream inputStream = null; FileOutputStream fileOutputStream = null; try { inputStream = zipFile.getInputStream(entry); - File file = new File(targetPath + File.separator + entry.getName()); + File file = FileUtils.file(targetPath + File.separator + entry.getName()); if (!file.exists()) { File fileParent = file.getParentFile(); if (!fileParent.exists()) { @@ -152,7 +150,7 @@ public static File unzip(File root, String targetPath) throws IOException { } } } - return new File(targetPath); + return FileUtils.file(targetPath); } finally { if (zipFile != null) { zipFile.close(); @@ -170,7 +168,7 @@ public static File mkdir(String dirPath) { if (StringUtils.isEmpty(dirPath)) { return null; } - File dir = new File(dirPath); + File dir = FileUtils.file(dirPath); if (!dir.exists()) { // Recursive creation dir.mkdirs(); @@ -178,4 +176,41 @@ public static File mkdir(String dirPath) { return dir; } + /** + * decode the given path if the path has spaces + * + * @param path dest path + * @return decoded path + */ + public static String decodePath(String path) { + try { + return URLDecoder.decode(path, StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + // return source string when occur an exception + return path; + } + } + + /** + * creates a new file for given path. + * first, we check if the path is encoded before creating the File object + * + * @param path file path + * @return new File + */ + public static File file(String path) { + return new File(decodePath(path)); + } + + /** + * creates a new file for given path. + * + * @param parent parent path + * @param path child path + * @return new File + */ + public static File file(String parent, String path) { + return new File(decodePath(parent), path); + } + } \ No newline at end of file diff --git a/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/thread/CommonThreadPoolTest.java b/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/thread/CommonThreadPoolTest.java new file mode 100644 index 000000000..4e78ed89b --- /dev/null +++ b/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/thread/CommonThreadPoolTest.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.common.thread; + +import org.junit.Test; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.PriorityBlockingQueue; + +import static com.alipay.sofa.ark.common.thread.ThreadPoolManager.*; +import static com.alipay.sofa.ark.common.util.ThreadPoolUtils.buildQueue; +import static java.lang.Integer.MAX_VALUE; +import static org.apache.commons.beanutils.BeanUtils.copyProperties; +import static org.junit.Assert.*; + +public class CommonThreadPoolTest { + + private CommonThreadPool commonThreadPool; + + @Test + public void testCommonThreadPool() throws Exception { + + CommonThreadPool commonThreadPool = new CommonThreadPool(); + copyProperties(commonThreadPool, commonThreadPool); + commonThreadPool.setPrestartAllCoreThreads(true); + assertNotNull(commonThreadPool.getExecutor()); + + registerThreadPool("a", commonThreadPool); + assertNotNull(getThreadPool("a")); + unRegisterUserThread("a"); + assertNull(getThreadPool("a")); + } + + @Test + public void testBuildQueue() { + + BlockingQueue queue = buildQueue(5, true); + assertEquals(PriorityBlockingQueue.class, queue.getClass()); + assertEquals(MAX_VALUE, queue.remainingCapacity()); + + queue = buildQueue(-1, true); + assertEquals(PriorityBlockingQueue.class, queue.getClass()); + assertEquals(0, queue.size()); + + queue = buildQueue(5, false); + assertEquals(LinkedBlockingDeque.class, queue.getClass()); + assertEquals(5, queue.remainingCapacity()); + + queue = buildQueue(-1, false); + assertEquals(LinkedBlockingDeque.class, queue.getClass()); + assertEquals(0, queue.size()); + } +} diff --git a/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/AssertUtilsTest.java b/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/AssertUtilsTest.java index 3d888a771..178736510 100644 --- a/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/AssertUtilsTest.java +++ b/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/AssertUtilsTest.java @@ -16,9 +16,15 @@ */ package com.alipay.sofa.ark.common.util; -import org.junit.Assert; import org.junit.Test; +import java.io.File; + +import static com.alipay.sofa.ark.common.util.AssertUtils.*; +import static com.alipay.sofa.ark.common.util.FileUtils.file; +import static java.lang.System.getProperty; +import static org.junit.Assert.assertTrue; + /** * * @author ruoshan @@ -26,41 +32,50 @@ */ public class AssertUtilsTest { + public static File getTmpDir() { + String tmpPath = getProperty("java.io.tmpdir"); + return file(tmpPath); + } + @Test(expected = IllegalArgumentException.class) public void testAssertNotNullNull() { String msg = "object is null"; try { - AssertUtils.assertNotNull(null, msg); + assertNotNull(null, msg); } catch (Exception e) { - Assert.assertTrue(e instanceof IllegalArgumentException); - Assert.assertTrue(e.getMessage().contains(msg)); + assertTrue(e instanceof IllegalArgumentException); + assertTrue(e.getMessage().contains(msg)); throw e; } } @Test public void testAssertNotNullNotNull() { - AssertUtils.assertNotNull(new Object(), "object is null"); + assertNotNull(new Object(), "object is null"); } @Test public void testAssertIsTrue() { - AssertUtils.isTrue(true, "Exception %s", "error"); + isTrue(true, "Exception %s", "error"); try { - AssertUtils.isTrue(false, "Exception %s", "error"); + isTrue(false, "Exception %s", "error"); } catch (IllegalArgumentException ex) { - Assert.assertTrue("Exception error".equals(ex.getMessage())); + assertTrue("Exception error".equals(ex.getMessage())); } } @Test public void testAssertIsFalse() { - AssertUtils.isFalse(false, "Exception %s", "error"); + isFalse(false, "Exception %s", "error"); try { - AssertUtils.isFalse(true, "Exception %s", "error"); + isFalse(true, "Exception %s", "error"); } catch (IllegalArgumentException ex) { - Assert.assertTrue("Exception error".equals(ex.getMessage())); + assertTrue("Exception error".equals(ex.getMessage())); } } -} \ No newline at end of file + @Test(expected = IllegalArgumentException.class) + public void assertNull() { + AssertUtils.assertNull(new Object(), "should be nul!"); + } +} diff --git a/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/ClassLoaderUtilTest.java b/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/ClassLoaderUtilTest.java index 9f32f1e0b..fc3deecc8 100644 --- a/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/ClassLoaderUtilTest.java +++ b/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/ClassLoaderUtilTest.java @@ -22,7 +22,6 @@ import org.mockito.MockedStatic; import org.mockito.Mockito; -import java.io.File; import java.lang.management.ManagementFactory; import java.lang.management.RuntimeMXBean; import java.net.MalformedURLException; @@ -32,6 +31,9 @@ import java.util.Collections; import java.util.List; +import static com.alipay.sofa.ark.common.util.EnvironmentUtils.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.mockito.Mockito.when; /** @@ -99,7 +101,7 @@ public void testGetURLs() { for (String classpathEntry : classpathEntries) { URL url = null; try { - url = new File(classpathEntry).toURI().toURL(); + url = FileUtils.file(classpathEntry).toURI().toURL(); } catch (MalformedURLException e) { e.printStackTrace(); throw new ArkRuntimeException("Failed to get urls from " + appClassLoader, e); @@ -151,4 +153,13 @@ public void testParseSkyWalkingAgentPath() { managementFactoryMockedStatic.close(); } -} \ No newline at end of file + + @Test + public void testEnvironmentUtils() { + assertNull(getProperty("not_exists_prop")); + setSystemProperty("not_exists_prop", "aaa"); + assertEquals("aaa", getProperty("not_exists_prop")); + clearSystemProperty("not_exists_prop"); + assertNull(getProperty("not_exists_prop")); + } +} diff --git a/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/ClassUtilsTest.java b/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/ClassUtilsTest.java index 5b373744b..6aaafa45c 100644 --- a/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/ClassUtilsTest.java +++ b/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/ClassUtilsTest.java @@ -16,10 +16,18 @@ */ package com.alipay.sofa.ark.common.util; -import com.alipay.sofa.ark.spi.constant.Constants; -import org.junit.Assert; import org.junit.Test; +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +import static com.alipay.sofa.ark.common.util.ClassUtils.collectClasses; +import static com.alipay.sofa.ark.common.util.ClassUtils.getPackageName; +import static com.alipay.sofa.ark.spi.constant.Constants.DEFAULT_PACKAGE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + /** * @author qilong.zql * @since 0.3.0 @@ -28,8 +36,21 @@ public class ClassUtilsTest { @Test public void testGetPackageName() { - Assert.assertTrue(ClassUtils.getPackageName("a.b.C").equals("a.b")); - Assert.assertTrue(ClassUtils.getPackageName("C").equals(Constants.DEFAULT_PACKAGE)); + assertEquals("a.b", getPackageName("a.b.C")); + assertEquals(DEFAULT_PACKAGE, getPackageName("C")); } -} \ No newline at end of file + @Test + public void testCollectClasses() throws Exception { + + File dir = new File("target/classes"); + // fix mvn test fail issues + File dir2 = new File(dir.getAbsolutePath()); + if (!dir2.exists()) { + return; + } + + Set classNames = new HashSet<>(collectClasses(dir2)); + assertTrue(classNames.contains("com.alipay.sofa.ark.common.util.ClassUtils")); + } +} diff --git a/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/FileUtilsTest.java b/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/FileUtilsTest.java index 4645217e5..c0e79a7d3 100644 --- a/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/FileUtilsTest.java +++ b/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/FileUtilsTest.java @@ -17,7 +17,6 @@ package com.alipay.sofa.ark.common.util; import org.junit.After; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -25,55 +24,84 @@ import java.io.IOException; import java.net.URL; +import static com.alipay.sofa.ark.common.util.FileUtils.*; +import static java.lang.System.getProperty; +import static java.lang.System.setProperty; +import static org.apache.commons.io.FileUtils.deleteQuietly; +import static org.apache.commons.io.FileUtils.touch; +import static org.junit.Assert.*; + /** * @author guolei.sgl (guolei.sgl@antfin.com) 2019/7/28 11:24 PM * @since **/ public class FileUtilsTest { - private static final String ORIGIN = System.getProperty("os.name"); + private static final String ORIGIN = getProperty("os.name"); @Before public void before() { - System.setProperty("os.name", "windows"); + setProperty("os.name", "windows"); } @After public void after() { - System.setProperty("os.name", ORIGIN); + setProperty("os.name", ORIGIN); } @Test public void testGetCompatiblePath() { - String winPath = FileUtils.getCompatiblePath("C:\\a\\b\\c"); - Assert.assertTrue(winPath.contains("/")); - String macPath = FileUtils.getCompatiblePath("/a/b/c"); - Assert.assertTrue(winPath.contains(macPath)); + String winPath = getCompatiblePath("C:\\a\\b\\c"); + assertTrue(winPath.contains("/")); + String macPath = getCompatiblePath("/a/b/c"); + assertTrue(winPath.contains(macPath)); } @Test public void testSHA1Hash() throws IOException { URL url = this.getClass().getResource(this.getClass().getSimpleName() + ".class"); - Assert.assertNotNull(FileUtils.sha1Hash(new File(url.getFile()))); + assertNotNull(sha1Hash(file(url.getFile()))); } @Test public void testUnzip() throws IOException { URL sampleBiz = this.getClass().getClassLoader().getResource("sample-biz.jar"); - File file = new File(sampleBiz.getFile()); - Assert.assertNotNull(FileUtils.unzip(file, file.getAbsolutePath() + "-unpack")); + File file = file(sampleBiz.getFile()); + assertNotNull(unzip(file, file.getAbsolutePath() + "-unpack")); } @Test public void testMkdir() { - Assert.assertNull(FileUtils.mkdir("")); + assertNull(mkdir("")); // test recursive creation - File newDir = FileUtils.mkdir("C:\\a\\b\\c"); - Assert.assertNotNull(newDir); + File newDir = mkdir("C:\\a\\b\\c"); + assertNotNull(newDir); // test for exist path - Assert.assertNotNull(FileUtils.mkdir("C:\\a\\b\\c")); + assertNotNull(mkdir("C:\\a\\b\\c")); // del the dir - org.apache.commons.io.FileUtils.deleteQuietly(newDir); + deleteQuietly(newDir); + } + + @Test + public void testDecodePath() { + String path = "C:\\temp dir\\b\\c"; + String encodedPath = "C:\\temp%20dir\\b\\c"; + assertEquals(path, decodePath(path)); + assertEquals(path, decodePath(encodedPath)); } + @Test + public void testNewFile() throws IOException { + + String dir = "C:\\temp dir\\b\\c"; + String encodedPath = "C:\\temp%20dir\\b\\c"; + mkdir(dir); + touch(new File(dir, "test.txt")); + File file = file(encodedPath, "test.txt"); + assertNotNull(file); + assertTrue(file.exists()); + + file = new File(encodedPath, "test.txt"); + assertFalse(file.exists()); + } } diff --git a/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/SimpleByteBufferTest.java b/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/SimpleByteBufferTest.java new file mode 100644 index 000000000..85880099f --- /dev/null +++ b/sofa-ark-parent/core/common/src/test/java/com/alipay/sofa/ark/common/util/SimpleByteBufferTest.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.common.util; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class SimpleByteBufferTest { + + private SimpleByteBuffer simpleByteBuffer = new SimpleByteBuffer(); + + @Test + public void testSimpleByteBuffer() { + + simpleByteBuffer.backSpace(); + simpleByteBuffer.delete(); + assertEquals(-1, simpleByteBuffer.goRight()); + assertEquals(false, simpleByteBuffer.goLeft()); + + for (int i = 0; i <= 20; i++) { + simpleByteBuffer.add((byte) i); + } + + assertEquals(0, simpleByteBuffer.goRight()); + assertEquals(1, simpleByteBuffer.goRight()); + assertEquals(true, simpleByteBuffer.goLeft()); + + for (int i = 0; i <= 40; i++) { + simpleByteBuffer.insert((byte) i); + } + + assertEquals(1, simpleByteBuffer.goRight()); + assertEquals(2, simpleByteBuffer.goRight()); + assertEquals(true, simpleByteBuffer.goLeft()); + + simpleByteBuffer.backSpace(); + assertEquals(2, simpleByteBuffer.goRight()); + + simpleByteBuffer.delete(); + assertEquals(4, simpleByteBuffer.goRight()); + + assertEquals(60, simpleByteBuffer.getBuffer().length); + assertEquals(60, simpleByteBuffer.getSize()); + assertEquals(44, simpleByteBuffer.getPos()); + assertEquals(16, simpleByteBuffer.getGap()); + + assertEquals(60, simpleByteBuffer.getAndClearBuffer().length); + assertEquals(0, simpleByteBuffer.getSize()); + assertEquals(0, simpleByteBuffer.getPos()); + } +} diff --git a/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/constant/Constants.java b/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/constant/Constants.java index 6be43a3eb..e7765a3ee 100644 --- a/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/constant/Constants.java +++ b/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/constant/Constants.java @@ -93,6 +93,8 @@ public class Constants { public final static String WEB_CONTEXT_PATH = "web-context-path"; public final static String IMPORT_CLASSES_ATTRIBUTE = "import-classes"; public final static String IMPORT_PACKAGES_ATTRIBUTE = "import-packages"; + + public final static String EXPORT_MODE = "export-mode"; public final static String EXPORT_CLASSES_ATTRIBUTE = "export-classes"; public final static String EXPORT_PACKAGES_ATTRIBUTE = "export-packages"; diff --git a/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/model/Plugin.java b/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/model/Plugin.java index c9f67f69f..22245a9e9 100644 --- a/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/model/Plugin.java +++ b/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/model/Plugin.java @@ -87,6 +87,14 @@ public interface Plugin extends PriorityOrdered { */ PluginContext getPluginContext(); + /** + * get Plugin Export Mode + * default exportMode = classLoader, means export class to load in this plugin classLoader + * exportMode = override, means export class to file only, and usually will be reload in another classLoader + * @return + */ + String getExportMode(); + /** * get Plugin Export Packages Config * @return plugin export packages diff --git a/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/service/classloader/ClassLoaderService.java b/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/service/classloader/ClassLoaderService.java index e5a427f9a..78de22ecb 100644 --- a/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/service/classloader/ClassLoaderService.java +++ b/sofa-ark-parent/core/spi/src/main/java/com/alipay/sofa/ark/spi/service/classloader/ClassLoaderService.java @@ -16,6 +16,7 @@ */ package com.alipay.sofa.ark.spi.service.classloader; +import com.alipay.sofa.ark.spi.model.Plugin; import com.alipay.sofa.ark.spi.service.ArkService; import java.util.List; @@ -76,6 +77,13 @@ public interface ClassLoaderService extends ArkService { */ boolean isClassInImport(String pluginName, String className); + /** + * Find export mode for class className + * @param className + * @return + */ + String getExportMode(String className); + /** * Find classloader which export class for import class * @param className class name @@ -83,6 +91,8 @@ public interface ClassLoaderService extends ArkService { */ ClassLoader findExportClassLoader(String className); + Plugin findExportPlugin(String className); + /** * Whether resource is in import-resources * @param pluginName @@ -128,6 +138,12 @@ public interface ClassLoaderService extends ArkService { */ ClassLoader getBizClassLoader(String bizIdentity); + /** + * Get Ark Master Biz ClassLoader + * @return + */ + ClassLoader getMasterBizClassLoader(); + /** * Get Ark Plugin ClassLoader * @param pluginName @@ -150,4 +166,4 @@ public interface ClassLoaderService extends ArkService { * @return */ boolean isDeniedImportResource(String bizIdentity, String resourceName); -} \ No newline at end of file +} diff --git a/sofa-ark-parent/core/spi/src/test/java/com/alipay/sofa/ark/spi/argument/LaunchCommandTest.java b/sofa-ark-parent/core/spi/src/test/java/com/alipay/sofa/ark/spi/argument/LaunchCommandTest.java index 27384abbb..807dc57ff 100644 --- a/sofa-ark-parent/core/spi/src/test/java/com/alipay/sofa/ark/spi/argument/LaunchCommandTest.java +++ b/sofa-ark-parent/core/spi/src/test/java/com/alipay/sofa/ark/spi/argument/LaunchCommandTest.java @@ -17,7 +17,6 @@ package com.alipay.sofa.ark.spi.argument; import com.alipay.sofa.ark.exception.ArkRuntimeException; -import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -26,11 +25,17 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import static com.alipay.sofa.ark.spi.argument.CommandArgument.*; +import static com.alipay.sofa.ark.spi.argument.LaunchCommand.parse; +import static java.lang.Integer.valueOf; +import static java.lang.String.format; +import static java.net.URLDecoder.decode; +import static org.junit.Assert.*; + /** * @author qilong.zql 18/3/9 */ @@ -47,7 +52,6 @@ public class LaunchCommandTest { public void init() { try { - classpath = getClasspath(Objects.requireNonNull(getURLs(this.getClass() .getClassLoader()))); method = MainClass.class.getMethod("main", String[].class); @@ -56,14 +60,14 @@ public void init() { throw new RuntimeException(ex); } - arkCommand.add(String.format("%s%s=%s", CommandArgument.ARK_CONTAINER_ARGUMENTS_MARK, - CommandArgument.FAT_JAR_ARGUMENT_KEY, fatJarUrl)); - arkCommand.add(String.format("%s%s=%s", CommandArgument.ARK_CONTAINER_ARGUMENTS_MARK, - CommandArgument.CLASSPATH_ARGUMENT_KEY, classpath)); - arkCommand.add(String.format("%s%s=%s", CommandArgument.ARK_BIZ_ARGUMENTS_MARK, - CommandArgument.ENTRY_CLASS_NAME_ARGUMENT_KEY, method.getDeclaringClass().getName())); - arkCommand.add(String.format("%s%s=%s", CommandArgument.ARK_BIZ_ARGUMENTS_MARK, - CommandArgument.ENTRY_METHOD_NAME_ARGUMENT_KEY, method.getName())); + arkCommand.add(format("%s%s=%s", ARK_CONTAINER_ARGUMENTS_MARK, FAT_JAR_ARGUMENT_KEY, + fatJarUrl)); + arkCommand.add(format("%s%s=%s", ARK_CONTAINER_ARGUMENTS_MARK, CLASSPATH_ARGUMENT_KEY, + classpath)); + arkCommand.add(format("%s%s=%s", ARK_BIZ_ARGUMENTS_MARK, ENTRY_CLASS_NAME_ARGUMENT_KEY, + method.getDeclaringClass().getName())); + arkCommand.add(format("%s%s=%s", ARK_BIZ_ARGUMENTS_MARK, ENTRY_METHOD_NAME_ARGUMENT_KEY, + method.getName())); LaunchCommandTest.count = 0; } @@ -74,36 +78,35 @@ public void testCommandParser() { args.addAll(arkCommand); args.add("p1"); args.add("p2"); - LaunchCommand launchCommand = LaunchCommand.parse(args.toArray(new String[] {})); + LaunchCommand launchCommand = parse(args.toArray(new String[] {})); - Assert.assertTrue(launchCommand.getEntryClassName().equals( + assertTrue(launchCommand.getEntryClassName().equals( method.getDeclaringClass().getName())); - Assert.assertTrue(launchCommand.getEntryMethodName().equals(method.getName())); - Assert.assertTrue(launchCommand.getExecutableArkBizJar().equals(fatJarUrl)); - Assert.assertTrue(launchCommand.getClasspath().length == classpath - .split(CommandArgument.CLASSPATH_SPLIT).length); + assertTrue(launchCommand.getEntryMethodName().equals(method.getName())); + assertTrue(launchCommand.getExecutableArkBizJar().equals(fatJarUrl)); + assertTrue(launchCommand.getClasspath().length == classpath.split(CLASSPATH_SPLIT).length); for (URL url : launchCommand.getClasspath()) { - Assert.assertTrue(classpath.contains(url.toExternalForm())); + assertTrue(classpath.contains(url.toExternalForm())); } - Assert.assertTrue(2 == launchCommand.getLaunchArgs().length); + assertTrue(2 == launchCommand.getLaunchArgs().length); } catch (Exception ex) { - Assert.assertNull(ex); + assertNull(ex); } } @Test public void testEncodedURL() { File file = new File(fatJarUrl.getFile()); - Assert.assertFalse(file.exists()); - file = new File(URLDecoder.decode(fatJarUrl.getFile())); - Assert.assertTrue(file.exists()); + assertFalse(file.exists()); + file = new File(decode(fatJarUrl.getFile())); + assertTrue(file.exists()); } public static class MainClass { public static void main(String[] args) { if (args.length > 0) { - LaunchCommandTest.count += Integer.valueOf(args[0]); + LaunchCommandTest.count += valueOf(args[0]); } } @@ -113,13 +116,14 @@ private String getClasspath(URL[] urls) { StringBuilder sb = new StringBuilder(); for (URL url : urls) { - sb.append(url.toExternalForm()).append(CommandArgument.CLASSPATH_SPLIT); + sb.append(url.toExternalForm()).append(CLASSPATH_SPLIT); } return sb.toString(); } private URL[] getURLs(ClassLoader classLoader) { + // https://stackoverflow.com/questions/46519092/how-to-get-all-jars-loaded-by-a-java-application-in-java9 if (classLoader instanceof URLClassLoader) { return ((URLClassLoader) classLoader).getURLs(); @@ -129,6 +133,7 @@ private URL[] getURLs(ClassLoader classLoader) { String classpath = System.getProperty("java.class.path"); String[] classpathEntries = classpath.split(System.getProperty("path.separator")); List classpathURLs = new ArrayList<>(); + for (String classpathEntry : classpathEntries) { URL url = null; try { @@ -141,6 +146,18 @@ private URL[] getURLs(ClassLoader classLoader) { } return classpathURLs.toArray(new URL[0]); + } + @Test + public void testOtherMethods() throws MalformedURLException { + + List args = new ArrayList<>(); + args.addAll(arkCommand); + args.add("p1"); + args.add("p2"); + LaunchCommand launchCommand = parse(args.toArray(new String[] {})); + launchCommand.setProfiles(new String[] { "1" }); + assertArrayEquals(new String[] { "1" }, launchCommand.getProfiles()); + assertEquals("ab", LaunchCommand.toString(new String[] { "a", "b" })); } } \ No newline at end of file diff --git a/sofa-ark-parent/core/spi/src/test/java/com/alipay/sofa/ark/spi/model/BizOperationTest.java b/sofa-ark-parent/core/spi/src/test/java/com/alipay/sofa/ark/spi/model/BizOperationTest.java index b1ffa4f10..51ad93ebb 100644 --- a/sofa-ark-parent/core/spi/src/test/java/com/alipay/sofa/ark/spi/model/BizOperationTest.java +++ b/sofa-ark-parent/core/spi/src/test/java/com/alipay/sofa/ark/spi/model/BizOperationTest.java @@ -16,30 +16,52 @@ */ package com.alipay.sofa.ark.spi.model; -import org.junit.Assert; +import com.alipay.sofa.ark.spi.event.AbstractArkEvent; import org.junit.Test; +import static com.alipay.sofa.ark.spi.model.BizOperation.createBizOperation; +import static com.alipay.sofa.ark.spi.model.BizState.*; +import static org.junit.Assert.*; +import static org.springframework.beans.BeanUtils.copyProperties; + public class BizOperationTest { + @Test public void testOperationEqual() { - BizOperation op1 = BizOperation.createBizOperation(); + + BizOperation op1 = createBizOperation(); op1.setBizName("biz A").setBizVersion("1.0.0") .setOperationType(BizOperation.OperationType.INSTALL); - BizOperation op2 = BizOperation.createBizOperation(); + BizOperation op2 = createBizOperation(); op2.setBizName("biz A").setBizVersion("1.0.0") .setOperationType(BizOperation.OperationType.INSTALL); - Assert.assertEquals(op1, op1); - Assert.assertEquals(op1, op2); + assertEquals(op1, op1); + assertEquals(op1, op2); op2.setOperationType(BizOperation.OperationType.UNINSTALL); - Assert.assertNotEquals(op1, op2); + assertNotEquals(op1, op2); op2.setBizVersion("2.0.0"); - Assert.assertNotEquals(op1, op2); + assertNotEquals(op1, op2); op2.setBizName("biz B"); - Assert.assertNotEquals(op1, op2); + assertNotEquals(op1, op2); + + assertFalse(op1.equals("")); + assertFalse(op1.equals(null)); + } - Assert.assertFalse(op1.equals("")); - Assert.assertFalse(op1.equals(null)); + @Test + public void testAbstractArkEvent() { + AbstractArkEvent abstractArkEvent = new AbstractArkEvent("") { + }; + copyProperties(abstractArkEvent, abstractArkEvent); + } + @Test + public void testBizState() { + assertEquals(UNRESOLVED, BizState.of("UNRESOLVED")); + assertEquals(RESOLVED, BizState.of("RESOLVED")); + assertEquals(ACTIVATED, BizState.of("ACTIVATED")); + assertEquals(DEACTIVATED, BizState.of("DEACTIVATED")); + assertEquals(BROKEN, BizState.of("aaa")); } } diff --git a/sofa-ark-parent/core/spi/src/test/java/com/alipay/sofa/ark/spi/service/extension/ExtensionClassTest.java b/sofa-ark-parent/core/spi/src/test/java/com/alipay/sofa/ark/spi/service/extension/ExtensionClassTest.java new file mode 100644 index 000000000..1d21194b8 --- /dev/null +++ b/sofa-ark-parent/core/spi/src/test/java/com/alipay/sofa/ark/spi/service/extension/ExtensionClassTest.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.spi.service.extension; + +import org.junit.Test; + +import static org.springframework.beans.BeanUtils.copyProperties; + +public class ExtensionClassTest { + + @Test + public void testExtensionClassTest() { + ExtensionClass extensionClass = new ExtensionClass(); + copyProperties(extensionClass, extensionClass); + extensionClass.equals(extensionClass); + } +} diff --git a/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/RepackageMojo.java b/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/RepackageMojo.java index bacbf9666..2111ff664 100644 --- a/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/RepackageMojo.java +++ b/sofa-ark-parent/support/ark-maven-plugin/src/main/java/com/alipay/sofa/ark/boot/mojo/RepackageMojo.java @@ -38,26 +38,45 @@ import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.descriptor.PluginDescriptor; -import org.apache.maven.plugins.annotations.*; +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.dependency.tree.TreeMojo; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.shared.dependency.graph.DependencyNode; -import org.apache.maven.shared.invoker.*; +import org.apache.maven.shared.invoker.DefaultInvocationRequest; +import org.apache.maven.shared.invoker.DefaultInvoker; +import org.apache.maven.shared.invoker.InvocationRequest; +import org.apache.maven.shared.invoker.InvocationResult; +import org.apache.maven.shared.invoker.Invoker; +import org.apache.maven.shared.invoker.MavenInvocationException; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.nio.charset.Charset; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import static com.alipay.sofa.ark.boot.mojo.MavenUtils.inUnLogScopes; -import static com.alipay.sofa.ark.spi.constant.Constants.*; +import static com.alipay.sofa.ark.spi.constant.Constants.ARK_CONF_BASE_DIR; +import static com.alipay.sofa.ark.spi.constant.Constants.EXTENSION_EXCLUDES; +import static com.alipay.sofa.ark.spi.constant.Constants.EXTENSION_EXCLUDES_ARTIFACTIDS; +import static com.alipay.sofa.ark.spi.constant.Constants.EXTENSION_EXCLUDES_GROUPIDS; /** * Repackages existing JAR archives so that they can be executed from the command @@ -71,6 +90,8 @@ public class RepackageMojo extends TreeMojo { private static final String BIZ_NAME = "com.alipay.sofa.ark.bizName"; + private static final String DEFAULT_EXCLUDE_RULES = "rules.txt"; + @Parameter(defaultValue = "${project}", readonly = true, required = true) private MavenProject mavenProject; @@ -351,7 +372,8 @@ private File getGitDirectory(MavenProject rootProject) { if (gitDirectory != null && gitDirectory.exists()) { return gitDirectory; } - return new File(rootProject.getBasedir().getAbsolutePath() + "/.git"); + return com.alipay.sofa.ark.common.util.FileUtils.file(rootProject.getBasedir() + .getAbsolutePath() + "/.git"); } private void parseArtifactItems(DependencyNode rootNode, Set result) { @@ -377,16 +399,32 @@ private Set getAllArtifact() throws MojoExecutionException, MojoFa } private Set getAllArtifactByMavenTree() throws MojoExecutionException { - File baseDir = MavenUtils.getRootProject(this.mavenProject).getBasedir(); - getLog().info("root project path: " + baseDir.getAbsolutePath()); + MavenProject rootProject = MavenUtils.getRootProject(this.mavenProject); + getLog().info("root project path: " + rootProject.getBasedir().getAbsolutePath()); + + // run maven dependency:tree + try { + if (this.mavenProject.getBasedir() != null) { + return doGetAllArtifactByMavenTree(this.mavenProject); + } + } catch (MojoExecutionException e) { + getLog().warn( + "execute dependency:tree failed, try to execute dependency:tree in root project"); + } + return doGetAllArtifactByMavenTree(MavenUtils.getRootProject(this.mavenProject)); + } + + private Set doGetAllArtifactByMavenTree(MavenProject project) throws MojoExecutionException { + File baseDir = project.getBasedir(); + getLog().info("project path: " + baseDir.getAbsolutePath()); // dependency:tree String outputPath = baseDir.getAbsolutePath() + "/deps.log." + System.currentTimeMillis(); InvocationRequest request = new DefaultInvocationRequest(); - request.setPomFile(new File(baseDir.getAbsolutePath() + "/pom.xml")); + request.setPomFile(com.alipay.sofa.ark.common.util.FileUtils.file(baseDir.getAbsolutePath() + "/pom.xml")); List goals = Stream.of("dependency:tree", "-DappendOutput=true", - "-DoutputFile=" + outputPath).collect(Collectors.toList()); + "-DoutputFile=\"" + outputPath + "\"").collect(Collectors.toList()); Properties userProperties = projectBuildingRequest.getUserProperties(); if (userProperties != null) { @@ -394,7 +432,7 @@ private Set getAllArtifactByMavenTree() throws MojoExecutionExcept } getLog().info( - "execute 'mvn dependency:tree' with command 'mvn " + String.join(" ", goals) + "'"); + "execute 'mvn dependency:tree' with command 'mvn " + String.join(" ", goals) + "'"); request.setGoals(goals); request.setBatchMode(mavenSession.getSettings().getInteractiveMode()); request.setProfiles(mavenSession.getSettings().getActiveProfiles()); @@ -404,16 +442,16 @@ private Set getAllArtifactByMavenTree() throws MojoExecutionExcept InvocationResult result = invoker.execute(request); if (result.getExitCode() != 0) { throw new MojoExecutionException("execute dependency:tree failed", - result.getExecutionException()); + result.getExecutionException()); } String depTreeStr = FileUtils.readFileToString(FileUtils.getFile(outputPath), - Charset.defaultCharset()); + Charset.defaultCharset()); return MavenUtils.convert(depTreeStr); } catch (MavenInvocationException | IOException e) { throw new MojoExecutionException("execute dependency:tree failed", e); } finally { - File outputFile = new File(outputPath); + File outputFile = com.alipay.sofa.ark.common.util.FileUtils.file(outputPath); if (outputFile.exists()) { outputFile.delete(); } @@ -555,6 +593,9 @@ protected Set filterExcludeArtifacts(Set artifacts) { if (!StringUtils.isEmpty(packExcludesConfig)) { extensionExcludeArtifacts(baseDir + File.separator + ARK_CONF_BASE_DIR + File.separator + packExcludesConfig); + } else { + extensionExcludeArtifacts(baseDir + File.separator + ARK_CONF_BASE_DIR + File.separator + + DEFAULT_EXCLUDE_RULES); } // extension from url @@ -645,7 +686,7 @@ private boolean checkMatchExclude(List excludeList, Artifact artif protected void extensionExcludeArtifacts(String extraResources) { try { - File configFile = new File(extraResources); + File configFile = com.alipay.sofa.ark.common.util.FileUtils.file(extraResources); if (configFile.exists()) { BufferedReader bufferedReader = new BufferedReader(new FileReader(configFile)); String dataLine; @@ -851,6 +892,50 @@ protected void logExcludeMessage(List jarGroupIds, List jarArtif } } + public void setExcludes(String str) { + this.excludes = parseToSet(str); + } + + public void setExcludeGroupIds(String str) { + this.excludeGroupIds = parseToSet(str); + } + + public void setExcludeArtifactIds(String str) { + this.excludeArtifactIds = parseToSet(str); + } + + public void setDenyImportPackages(String str) { + this.denyImportPackages = parseToSet(str); + } + + public void setDenyImportClasses(String str) { + this.denyImportClasses = parseToSet(str); + } + + public void setDenyImportResources(String str) { + this.denyImportResources = parseToSet(str); + } + + public void setInjectPluginDependencies(String str) { + this.injectPluginDependencies = parseToSet(str); + } + + public void setInjectPluginExportPackages(String str) { + this.injectPluginExportPackages = parseToSet(str); + } + + private LinkedHashSet parseToSet(String str) { + LinkedHashSet set = new LinkedHashSet<>(); + if (StringUtils.isBlank(str)) { + return set; + } + Arrays.stream(str.split(",")) + .map(String::trim) + .filter(StringUtils::isNotBlank) + .forEach(set::add); + return set; + } + public static class ExcludeConfigResponse { private boolean success; diff --git a/sofa-ark-parent/support/ark-maven-plugin/src/test/java/com/alipay/sofa/ark/boot/mojo/RepackageMojoTest.java b/sofa-ark-parent/support/ark-maven-plugin/src/test/java/com/alipay/sofa/ark/boot/mojo/RepackageMojoTest.java index 32110f270..677be0c07 100644 --- a/sofa-ark-parent/support/ark-maven-plugin/src/test/java/com/alipay/sofa/ark/boot/mojo/RepackageMojoTest.java +++ b/sofa-ark-parent/support/ark-maven-plugin/src/test/java/com/alipay/sofa/ark/boot/mojo/RepackageMojoTest.java @@ -165,8 +165,10 @@ public void testSetSettingsLocation() throws Exception { + "user-settings-test.xml"; String globalSettingsFilePath = System.getProperty("user.home") + File.separator + "global-settings-test.xml"; - File userSettingsFile = new File(userSettingsFilePath); - File globalSettingsFile = new File(globalSettingsFilePath); + File userSettingsFile = com.alipay.sofa.ark.common.util.FileUtils + .file(userSettingsFilePath); + File globalSettingsFile = com.alipay.sofa.ark.common.util.FileUtils + .file(globalSettingsFilePath); InvocationRequest request = new DefaultInvocationRequest(); invokeSetSettingsLocation(request, userSettingsFilePath, globalSettingsFilePath); Assert.assertNull(request.getUserSettingsFile()); @@ -190,8 +192,10 @@ private void invokeSetSettingsLocation(InvocationRequest request, String userSet String globalSettingsFilePath) throws Exception { RepackageMojo repackageMojo = new RepackageMojo(); MavenExecutionRequest executionRequest = new DefaultMavenExecutionRequest(); - executionRequest.setUserSettingsFile(new File(userSettingsFilePath)); - executionRequest.setGlobalSettingsFile(new File(globalSettingsFilePath)); + executionRequest.setUserSettingsFile(com.alipay.sofa.ark.common.util.FileUtils + .file(userSettingsFilePath)); + executionRequest.setGlobalSettingsFile(com.alipay.sofa.ark.common.util.FileUtils + .file(globalSettingsFilePath)); // 构造对象 MavenSession mavenSession = new MavenSession(null, executionRequest, null, new ArrayList<>()); @@ -222,8 +226,8 @@ public void testExtensionExcludeArtifactsFromUrl() throws NoSuchMethodException, artifacts.add(defaultArtifact); artifacts.add(defaultArtifact1); - // NOTE: Access github to run unit test, need vpn maybe. - String packExcludesUrl = "https://github.com/sofastack/sofa-ark"; + // NOTE: Access httpbin to run unit test, need vpn maybe. + String packExcludesUrl = "http://httpbin.org/get"; extensionExcludeArtifactsFromUrl.invoke(repackageMojo, packExcludesUrl, artifacts); } @@ -325,8 +329,8 @@ public void testExecute() throws Exception { DefaultArtifact artifact = new DefaultArtifact("group1", "artifact1", "1.0", "compile", "", null, new DefaultArtifactHandler()); - artifact - .setFile(new File(getClass().getClassLoader().getResource("excludes.txt").getPath())); + artifact.setFile(com.alipay.sofa.ark.common.util.FileUtils.file(getClass().getClassLoader() + .getResource("excludes.txt").getPath())); mavenProject.setArtifact(artifact); Set artifacts = new HashSet<>(); diff --git a/sofa-ark-parent/support/ark-plugin-maven-plugin/META-INF/MANIFEST.MF b/sofa-ark-parent/support/ark-plugin-maven-plugin/META-INF/MANIFEST.MF index 60d5dd1df..79dea175c 100644 --- a/sofa-ark-parent/support/ark-plugin-maven-plugin/META-INF/MANIFEST.MF +++ b/sofa-ark-parent/support/ark-plugin-maven-plugin/META-INF/MANIFEST.MF @@ -9,6 +9,7 @@ activator: import-packages: import-classes: import-resources: +export-mode: export-packages: export-classes: export-resources: diff --git a/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/java/com/alipay/sofa/ark/plugin/mojo/AbstractPropertiesConfig.java b/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/java/com/alipay/sofa/ark/plugin/mojo/AbstractPropertiesConfig.java index 9ea6b950d..a5ccd8691 100644 --- a/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/java/com/alipay/sofa/ark/plugin/mojo/AbstractPropertiesConfig.java +++ b/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/java/com/alipay/sofa/ark/plugin/mojo/AbstractPropertiesConfig.java @@ -27,6 +27,8 @@ */ public abstract class AbstractPropertiesConfig { + public static final String KEY_MODE = "mode"; + public static final String KEY_PACKAGES = "packages"; public static final String KEY_CLASSES = "classes"; public static final String KEY_RESOURCES = "resources"; @@ -35,6 +37,8 @@ public abstract class AbstractPropertiesConfig { public static final String KEY_SPLIT = "-"; public static final String VALUE_SPLIT = ","; + protected String mode; + /** * imported or exported packages config */ @@ -50,6 +54,21 @@ public abstract class AbstractPropertiesConfig { */ protected LinkedHashSet resources; + public void addClass(String className) { + if (classes == null) { + classes = new LinkedHashSet<>(); + } + classes.add(className); + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + public LinkedHashSet getPackages() { return packages; } @@ -106,4 +125,4 @@ public static String join(Iterator iterator, String separator) { */ public abstract void store(Properties props); -} \ No newline at end of file +} diff --git a/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/java/com/alipay/sofa/ark/plugin/mojo/ArkPluginMojo.java b/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/java/com/alipay/sofa/ark/plugin/mojo/ArkPluginMojo.java index bb313457a..e1aea1be6 100644 --- a/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/java/com/alipay/sofa/ark/plugin/mojo/ArkPluginMojo.java +++ b/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/java/com/alipay/sofa/ark/plugin/mojo/ArkPluginMojo.java @@ -30,6 +30,9 @@ import java.util.Set; import java.util.jar.JarFile; import java.util.jar.Manifest; +import java.util.stream.Collectors; + +import com.alipay.sofa.ark.common.util.ClassUtils; import com.alipay.sofa.ark.common.util.StringUtils; import com.alipay.sofa.ark.spi.constant.Constants; import com.alipay.sofa.ark.tools.ArtifactItem; @@ -143,6 +146,12 @@ public class ArkPluginMojo extends AbstractMojo { @Parameter(defaultValue = "") private String classifier; + /** + * Export plugin project classes by default + */ + @Parameter(defaultValue = "true") + protected Boolean exportPluginClass; + private static final String ARCHIVE_MODE = "zip"; private static final String PLUGIN_SUFFIX = ".ark.plugin"; private static final String TEMP_PLUGIN_SUFFIX = ".ark.plugin.bak"; @@ -398,6 +407,16 @@ protected boolean isAttach() { return attach; } + /** + * check whether to export plugin project + * default true. + * + * @return whether to export plugin project + */ + protected boolean getExportPluginClass() { + return exportPluginClass; + } + /** * generate ark.plugin configuration file * archive @@ -425,15 +444,42 @@ private void addManifest(Archiver archiver) throws MojoExecutionException { addArkPluginConfig(archiver, "META-INF/MANIFEST.MF", properties); } - private Properties collectArkPluginExport() { + private Properties collectArkPluginExport() throws MojoExecutionException { Properties properties = new LinkedProperties(); if (exported == null) { exported = new ExportConfig(); } + if (exportPluginClass) { + Set projectClasses = findProjectClasses(); + for (String projectClass : projectClasses) { + if (!StringUtils.isEmpty(projectClass)) { + exported.addClass(projectClass); + } + } + } exported.store(properties); return properties; } + private Set findProjectClasses() throws MojoExecutionException { + try { + // Accessing the target/classes directory where compiled classes are located + File outputDirectory = new File(project.getBuild().getOutputDirectory()); + // Ensure the directory exists + if (outputDirectory.exists()) { + Set classes = new HashSet<>(ClassUtils.collectClasses(outputDirectory)); + classes = classes.stream().filter(className -> !className.equals(this.activator)).collect( + Collectors.toSet()); + return classes; + } else { + getLog().warn("Output directory does not exist!"); + } + return new HashSet<>(); + } catch (IOException e) { + throw new MojoExecutionException("Error finding compiled classes", e); + } + } + private Properties collectArkPluginImport() { Properties properties = new LinkedProperties(); if (imported == null) { @@ -478,4 +524,4 @@ private void addArkPluginConfig(Archiver archiver, String path, LinkedProperties private void addArkPluginMark(Archiver archiver) throws MojoExecutionException { addArkPluginConfig(archiver, Constants.ARK_PLUGIN_MARK_ENTRY, new LinkedProperties()); } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/java/com/alipay/sofa/ark/plugin/mojo/ExportConfig.java b/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/java/com/alipay/sofa/ark/plugin/mojo/ExportConfig.java index f718c857c..8f9553b24 100644 --- a/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/java/com/alipay/sofa/ark/plugin/mojo/ExportConfig.java +++ b/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/java/com/alipay/sofa/ark/plugin/mojo/ExportConfig.java @@ -16,6 +16,8 @@ */ package com.alipay.sofa.ark.plugin.mojo; +import java.util.Arrays; +import java.util.Collections; import java.util.Properties; /** @@ -26,6 +28,8 @@ public class ExportConfig extends AbstractPropertiesConfig { @Override public void store(Properties prop) { + storeKeyValuePair(prop, KEY_EXPORT + KEY_SPLIT + KEY_MODE, getMode() == null ? null + : Collections.singletonList(getMode())); storeKeyValuePair(prop, KEY_EXPORT + KEY_SPLIT + KEY_PACKAGES, getPackages()); storeKeyValuePair(prop, KEY_EXPORT + KEY_SPLIT + KEY_CLASSES, getClasses()); storeKeyValuePair(prop, KEY_EXPORT + KEY_SPLIT + KEY_RESOURCES, getResources()); diff --git a/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/resources/META-INF/maven/plugin.xml b/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/resources/META-INF/maven/plugin.xml index 0a548a3ea..fb5501611 100644 --- a/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/resources/META-INF/maven/plugin.xml +++ b/sofa-ark-parent/support/ark-plugin-maven-plugin/src/main/resources/META-INF/maven/plugin.xml @@ -60,6 +60,13 @@ true default ark plugin artifact classifier: empty + + exportClass + java.lang.Boolean + false + true + Export plugin project package by default + description java.lang.String @@ -623,4 +630,4 @@ 3.3.1 - \ No newline at end of file + diff --git a/sofa-ark-parent/support/ark-plugin-maven-plugin/src/test/java/com/alipay/sofa/ark/plugin/mojo/ArkPluginMojoTest.java b/sofa-ark-parent/support/ark-plugin-maven-plugin/src/test/java/com/alipay/sofa/ark/plugin/mojo/ArkPluginMojoTest.java index 710f800e1..ba75b8148 100644 --- a/sofa-ark-parent/support/ark-plugin-maven-plugin/src/test/java/com/alipay/sofa/ark/plugin/mojo/ArkPluginMojoTest.java +++ b/sofa-ark-parent/support/ark-plugin-maven-plugin/src/test/java/com/alipay/sofa/ark/plugin/mojo/ArkPluginMojoTest.java @@ -19,6 +19,7 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.handler.DefaultArtifactHandler; +import org.apache.maven.model.Build; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.archiver.AbstractArchiver; import org.codehaus.plexus.archiver.manager.ArchiverManager; @@ -107,9 +108,12 @@ public void cleanUp() throws IOException { defaultArtifact.setFile(new File("src/test/resources/test-demo.jar")); artifacts.add(defaultArtifact); + Build build = new Build(); + build.setOutputDirectory("./notexist"); MavenProject mavenProject = mock(MavenProject.class); when(mavenProject.getArtifacts()).thenReturn(artifacts); when(mavenProject.getArtifact()).thenReturn(defaultArtifact); + when(mavenProject.getBuild()).thenReturn(build); arkPluginMojo.setProject(mavenProject); arkPluginMojo.setShades(new LinkedHashSet<>(Collections .singleton("com.alipay.sofa:test-demo:1.0.0"))); @@ -125,6 +129,7 @@ public void cleanUp() throws IOException { arkPluginMojo.pluginName = "xxx"; arkPluginMojo.description = "yyy"; arkPluginMojo.workDirectory = new File("./"); + arkPluginMojo.exportPluginClass = true; arkPluginMojo.execute(); assertEquals(6, finalResourcesCountInJar.get()); } @@ -138,8 +143,10 @@ public void testExportConfig() { classes.add("b"); exportConfig.setClasses(classes); exportConfig.store(properties); - assertEquals("{export-classes=a,b, export-resources=, export-packages=}", - properties.toString()); + assertEquals("a,b", properties.getProperty("export-classes")); + assertEquals("", properties.getProperty("export-mode")); + assertEquals("", properties.getProperty("export-resources")); + assertEquals("", properties.getProperty("export-packages")); } @Test @@ -151,7 +158,8 @@ public void testImportConfig() { resources.add("d"); importConfig.setResources(resources); importConfig.store(properties); - assertEquals("{import-resources=c,d, import-packages=, import-classes=}", - properties.toString()); + assertEquals("", properties.getProperty("import-classes")); + assertEquals("c,d", properties.getProperty("import-resources")); + assertEquals("", properties.getProperty("import-packages")); } } diff --git a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/pom.xml b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/pom.xml index 588b3e1c9..7ebd7b2eb 100644 --- a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/pom.xml +++ b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/pom.xml @@ -20,7 +20,6 @@ com.google.guava guava - 30.1-jre test @@ -32,13 +31,11 @@ ch.qos.logback logback-core - 1.3.5 test ch.qos.logback logback-classic - 1.3.5 test @@ -150,6 +147,12 @@ org.springframework.boot spring-boot-loader + + + io.projectreactor.netty + reactor-netty + 1.0.22 + diff --git a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/ArkReactiveAutoConfiguration.java b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/ArkReactiveAutoConfiguration.java new file mode 100644 index 000000000..df4aea361 --- /dev/null +++ b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/ArkReactiveAutoConfiguration.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.springboot; + +import com.alipay.sofa.ark.springboot.condition.ConditionalOnArkEnabled; +import com.alipay.sofa.ark.springboot.web.ArkNettyReactiveWebServerFactory; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration; +import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.web.embedded.netty.NettyRouteProvider; +import org.springframework.boot.web.embedded.netty.NettyServerCustomizer; +import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.reactive.ReactorResourceFactory; +import reactor.netty.http.server.HttpServer; + +import java.util.Collection; +import java.util.stream.Collectors; + +@Configuration +@ConditionalOnArkEnabled +@AutoConfigureBefore(ReactiveWebServerFactoryAutoConfiguration.class) +public class ArkReactiveAutoConfiguration { + + @Configuration + @ConditionalOnMissingBean({ ReactiveWebServerFactory.class }) + @ConditionalOnClass(value = { HttpServer.class }, name = { "com.alipay.sofa.ark.netty.ArkNettyIdentification" }) + static class EmbeddedNetty { + EmbeddedNetty() { + } + + @Bean + @ConditionalOnMissingBean + ReactorResourceFactory reactorServerResourceFactory() { + ReactorResourceFactory reactorResourceFactory = new ReactorResourceFactory(); + reactorResourceFactory.setUseGlobalResources(false); + return reactorResourceFactory; + } + + @Bean + NettyReactiveWebServerFactory nettyReactiveWebServerFactory(ReactorResourceFactory resourceFactory, ObjectProvider routes, ObjectProvider serverCustomizers) { + NettyReactiveWebServerFactory serverFactory = new ArkNettyReactiveWebServerFactory(); + serverFactory.setResourceFactory(resourceFactory); + routes.orderedStream().forEach((xva$0) -> { + serverFactory.addRouteProviders(new NettyRouteProvider[]{xva$0}); + }); + serverFactory.getServerCustomizers().addAll((Collection)serverCustomizers.orderedStream().collect(Collectors.toList())); + return serverFactory; + } + } +} diff --git a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/ArkAutoConfiguration.java b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/ArkServletAutoConfiguration.java similarity index 66% rename from sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/ArkAutoConfiguration.java rename to sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/ArkServletAutoConfiguration.java index 39fa6606c..aef0765eb 100644 --- a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/ArkAutoConfiguration.java +++ b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/ArkServletAutoConfiguration.java @@ -17,22 +17,25 @@ package com.alipay.sofa.ark.springboot; import com.alipay.sofa.ark.springboot.condition.ConditionalOnArkEnabled; -import com.alipay.sofa.ark.springboot.processor.ArkEventHandlerProcessor; -import com.alipay.sofa.ark.springboot.processor.ArkServiceInjectProcessor; import com.alipay.sofa.ark.springboot.web.ArkTomcatServletWebServerFactory; import org.apache.catalina.startup.Tomcat; import org.apache.coyote.UpgradeProtocol; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.SearchStrategy; import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; +import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; +import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; +import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import jakarta.servlet.Servlet; +import java.util.stream.Collectors; /** * @author qilong.zql @@ -42,7 +45,7 @@ @ConditionalOnArkEnabled @ConditionalOnClass(ServletWebServerFactoryAutoConfiguration.class) @AutoConfigureBefore(ServletWebServerFactoryAutoConfiguration.class) -public class ArkAutoConfiguration { +public class ArkServletAutoConfiguration { @Configuration @ConditionalOnClass(value = { Servlet.class, Tomcat.class, UpgradeProtocol.class, @@ -52,9 +55,18 @@ public static class EmbeddedArkTomcat { @Bean @ConditionalOnMissingBean(ArkTomcatServletWebServerFactory.class) - public TomcatServletWebServerFactory tomcatServletWebServerFactory() { - return new ArkTomcatServletWebServerFactory(); + public TomcatServletWebServerFactory tomcatServletWebServerFactory(ObjectProvider connectorCustomizers, + ObjectProvider contextCustomizers, + ObjectProvider> protocolHandlerCustomizers) { + ArkTomcatServletWebServerFactory factory = new ArkTomcatServletWebServerFactory(); + factory.getTomcatConnectorCustomizers().addAll( + connectorCustomizers.orderedStream().collect(Collectors.toList())); + factory.getTomcatContextCustomizers().addAll( + contextCustomizers.orderedStream().collect(Collectors.toList())); + factory.getTomcatProtocolHandlerCustomizers().addAll( + protocolHandlerCustomizers.orderedStream().collect(Collectors.toList())); + return factory; } } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/listener/ArkApplicationStartListener.java b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/listener/ArkApplicationStartListener.java index db4f1aaee..13179d689 100644 --- a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/listener/ArkApplicationStartListener.java +++ b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/listener/ArkApplicationStartListener.java @@ -27,7 +27,6 @@ import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.context.event.SpringApplicationEvent; -import org.springframework.boot.loader.LaunchedURLClassLoader; import org.springframework.context.ApplicationListener; /** @@ -40,15 +39,32 @@ public class ArkApplicationStartListener implements ApplicationListener SPRING_BOOT_LOADER_CLASS; + private static Class SPRING_BOOT_NEW_LOADER_CLASS; + + static { + try { + SPRING_BOOT_LOADER_CLASS = ApplicationListener.class.getClassLoader().loadClass( + SPRING_BOOT_LOADER); + } catch (Throwable t) { + // ignore + } + try { + SPRING_BOOT_NEW_LOADER_CLASS = ApplicationListener.class.getClassLoader().loadClass( + SPRING_BOOT_NEW_LOADER); + } catch (Throwable t) { + // ignore + } + } @Override public void onApplicationEvent(SpringApplicationEvent event) { try { - if (ArkConfigs.isEmbedEnable() - || LaunchedURLClassLoader.class.isAssignableFrom(this.getClass().getClassLoader() - .getClass())) { + if (isEmbedEnable()) { ArkConfigs.setEmbedEnable(true); startUpArkEmbed(event); return; @@ -67,6 +83,23 @@ public void onApplicationEvent(SpringApplicationEvent event) { } } + private boolean isEmbedEnable() { + if (ArkConfigs.isEmbedEnable()) { + return true; + } + if (SPRING_BOOT_LOADER_CLASS != null + && SPRING_BOOT_LOADER_CLASS.isAssignableFrom(this.getClass().getClassLoader() + .getClass())) { + return true; + } + if (SPRING_BOOT_NEW_LOADER_CLASS != null + && SPRING_BOOT_NEW_LOADER_CLASS.isAssignableFrom(this.getClass().getClassLoader() + .getClass())) { + return true; + } + return false; + } + public void startUpArk(SpringApplicationEvent event) { if (LAUNCH_CLASSLOADER_NAME.equals(this.getClass().getClassLoader().getClass().getName())) { SofaArkBootstrap.launch(event.getArgs()); diff --git a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/web/ArkCompositeReactorHttpHandlerAdapter.java b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/web/ArkCompositeReactorHttpHandlerAdapter.java new file mode 100644 index 000000000..4cf3ce9a8 --- /dev/null +++ b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/web/ArkCompositeReactorHttpHandlerAdapter.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.springboot.web; + +import com.alipay.sofa.ark.exception.ArkRuntimeException; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter; +import reactor.core.publisher.Mono; +import reactor.netty.http.server.HttpServerRequest; +import reactor.netty.http.server.HttpServerResponse; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author: yuanyuan + */ +public class ArkCompositeReactorHttpHandlerAdapter extends ReactorHttpHandlerAdapter { + + private Map bizReactorHttpHandlerAdapters = new ConcurrentHashMap<>(); + + public ArkCompositeReactorHttpHandlerAdapter(HttpHandler httpHandler) { + super(httpHandler); + } + + @Override + public Mono apply(HttpServerRequest reactorRequest, HttpServerResponse reactorResponse) { + String uri = reactorRequest.uri(); + for (Map.Entry entry : bizReactorHttpHandlerAdapters + .entrySet()) { + if (uri.startsWith(entry.getKey())) { + ReactorHttpHandlerAdapter adapter = entry.getValue(); + return adapter.apply(reactorRequest, reactorResponse); + } + } + return super.apply(reactorRequest, reactorResponse); + } + + public void registerBizReactorHttpHandlerAdapter(String contextPath, + ReactorHttpHandlerAdapter reactorHttpHandlerAdapter) { + ReactorHttpHandlerAdapter old = bizReactorHttpHandlerAdapters.putIfAbsent(contextPath, + reactorHttpHandlerAdapter); + if (old != null) { + throw new ArkRuntimeException("Duplicated context path"); + } + } + + public void unregisterBizReactorHttpHandlerAdapter(String contextPath) { + bizReactorHttpHandlerAdapters.remove(contextPath); + } +} diff --git a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/web/ArkNettyReactiveWebServerFactory.java b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/web/ArkNettyReactiveWebServerFactory.java new file mode 100644 index 000000000..4c3c32993 --- /dev/null +++ b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/web/ArkNettyReactiveWebServerFactory.java @@ -0,0 +1,188 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.springboot.web; + +import com.alipay.sofa.ark.spi.model.Biz; +import com.alipay.sofa.ark.spi.service.ArkInject; +import com.alipay.sofa.ark.spi.service.biz.BizManagerService; +import com.alipay.sofa.ark.spi.web.EmbeddedServerService; +import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.web.embedded.netty.NettyRouteProvider; +import org.springframework.boot.web.embedded.netty.NettyServerCustomizer; +import org.springframework.boot.web.embedded.netty.SslServerCustomizer; +import org.springframework.boot.web.server.WebServer; +import org.springframework.http.client.reactive.ReactorResourceFactory; +import org.springframework.http.server.reactive.ContextPathCompositeHandler; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; +import reactor.netty.http.HttpProtocol; +import reactor.netty.http.server.HttpServer; +import reactor.netty.resources.LoopResources; + +import java.net.InetSocketAddress; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static com.alipay.sofa.ark.spi.constant.Constants.ROOT_WEB_CONTEXT_PATH; + +public class ArkNettyReactiveWebServerFactory extends NettyReactiveWebServerFactory { + private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; + private Duration lifecycleTimeout; + + private List routeProviders = new ArrayList(); + @ArkInject + private EmbeddedServerService embeddedNettyService; + + @ArkInject + private BizManagerService bizManagerService; + + private boolean useForwardHeaders; + + private ReactorResourceFactory resourceFactory; + + private int backgroundProcessorDelay; + private Set serverCustomizers = new LinkedHashSet(); + + private static ArkCompositeReactorHttpHandlerAdapter adapter; + + public ArkNettyReactiveWebServerFactory() { + } + + @Override + public WebServer getWebServer(HttpHandler httpHandler) { + if (embeddedNettyService == null) { + return super.getWebServer(httpHandler); + } else if (embeddedNettyService.getEmbedServer() == null) { + embeddedNettyService.setEmbedServer(initEmbedNetty()); + } + + String contextPath = getContextPath(); + Map handlerMap = new HashMap<>(); + handlerMap.put(contextPath, httpHandler); + ContextPathCompositeHandler contextHandler = new ContextPathCompositeHandler(handlerMap); + + if (adapter == null) { + adapter = new ArkCompositeReactorHttpHandlerAdapter(contextHandler); + } else { + adapter.registerBizReactorHttpHandlerAdapter(contextPath, + new ReactorHttpHandlerAdapter(contextHandler)); + } + + HttpServer httpServer = (HttpServer) embeddedNettyService.getEmbedServer(); + ArkNettyWebServer webServer = (ArkNettyWebServer) createNettyWebServer(contextPath, + httpServer, adapter, lifecycleTimeout); + webServer.setRouteProviders(this.routeProviders); + + return webServer; + } + + public String getContextPath() { + String contextPath = ""; + if (bizManagerService == null) { + return contextPath; + } + Biz biz = bizManagerService.getBizByClassLoader(Thread.currentThread() + .getContextClassLoader()); + + if (!StringUtils.isEmpty(contextPath)) { + return contextPath; + } else if (biz != null) { + if (StringUtils.isEmpty(biz.getWebContextPath())) { + return ROOT_WEB_CONTEXT_PATH; + } + contextPath = biz.getWebContextPath(); + if (!contextPath.startsWith("/")) { + contextPath = "/" + contextPath; + } + return contextPath; + } else { + return ROOT_WEB_CONTEXT_PATH; + } + } + + WebServer createNettyWebServer(String contextPath, HttpServer httpServer, + ReactorHttpHandlerAdapter handlerAdapter, + Duration lifecycleTimeout) { + return new ArkNettyWebServer(contextPath, httpServer, handlerAdapter, lifecycleTimeout); + } + + private HttpServer initEmbedNetty(){ + HttpServer server = HttpServer.create(); + if (this.resourceFactory != null) { + LoopResources resources = this.resourceFactory.getLoopResources(); + Assert.notNull(resources, "No LoopResources: is ReactorResourceFactory not initialized yet?"); + server = ((HttpServer)server.runOn(resources)).bindAddress(this::getListenAddress); + } else { + server = server.bindAddress(this::getListenAddress); + } + + if (this.getSsl() != null && this.getSsl().isEnabled()) { + server = this.customizeSslConfiguration(server); + } + + + server = server.protocol(this.listProtocols()).forwarded(this.useForwardHeaders); + return applyCustomizers(server); + } + + private HttpServer customizeSslConfiguration(HttpServer httpServer) { + SslServerCustomizer sslServerCustomizer = new SslServerCustomizer(this.getSsl(), + this.getHttp2(), this.getSslStoreProvider()); + return sslServerCustomizer.apply(httpServer); + } + + private HttpProtocol[] listProtocols() { + List protocols = new ArrayList(); + protocols.add(HttpProtocol.HTTP11); + if (this.getHttp2() != null && this.getHttp2().isEnabled()) { + if (this.getSsl() != null && this.getSsl().isEnabled()) { + protocols.add(HttpProtocol.H2); + } else { + protocols.add(HttpProtocol.H2C); + } + } + + return (HttpProtocol[]) protocols.toArray(new HttpProtocol[0]); + } + + private HttpServer applyCustomizers(HttpServer server) { + NettyServerCustomizer customizer; + for (Iterator var2 = this.serverCustomizers.iterator(); var2.hasNext(); server = (HttpServer) customizer + .apply(server)) { + customizer = (NettyServerCustomizer) var2.next(); + } + + return server; + } + + private InetSocketAddress getListenAddress() { + return this.getAddress() != null ? new InetSocketAddress( + this.getAddress().getHostAddress(), this.getPort()) : new InetSocketAddress( + this.getPort()); + } + +} diff --git a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/web/ArkNettyWebServer.java b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/web/ArkNettyWebServer.java new file mode 100644 index 000000000..9f9bd8c69 --- /dev/null +++ b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/web/ArkNettyWebServer.java @@ -0,0 +1,201 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.springboot.web; + +import io.netty.channel.group.DefaultChannelGroup; +import io.netty.channel.unix.Errors; +import io.netty.util.concurrent.DefaultEventExecutor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.reactivestreams.Publisher; +import org.springframework.boot.web.embedded.netty.NettyRouteProvider; +import org.springframework.boot.web.server.PortInUseException; +import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.WebServerException; +import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter; +import org.springframework.util.Assert; +import reactor.netty.ChannelBindException; +import reactor.netty.DisposableServer; +import reactor.netty.http.server.HttpServer; +import reactor.netty.http.server.HttpServerRequest; +import reactor.netty.http.server.HttpServerResponse; +import reactor.netty.http.server.HttpServerRoutes; + +import java.time.Duration; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Predicate; +import java.util.function.Supplier; + +public class ArkNettyWebServer implements WebServer { + private static final Predicate ALWAYS = (request) -> { + return true; + }; + private static HttpServer arkHttpServer; + private static final Log logger = LogFactory.getLog(ArkNettyWebServer.class); + private final HttpServer httpServer; + private final BiFunction> handler; + private final Duration lifecycleTimeout; + private List routeProviders = Collections.emptyList(); + private static volatile DisposableServer disposableServer; + private Thread awaitThread; + private String contextPath; + + public ArkNettyWebServer(String contextPath, HttpServer httpServer, ReactorHttpHandlerAdapter handlerAdapter, Duration lifecycleTimeout) { + Assert.notNull(httpServer, "HttpServer must not be null"); + Assert.notNull(handlerAdapter, "HandlerAdapter must not be null"); + this.contextPath = contextPath; + this.lifecycleTimeout = lifecycleTimeout; + this.handler = handlerAdapter; + this.httpServer = httpServer.channelGroup(new DefaultChannelGroup(new DefaultEventExecutor())); + if (arkHttpServer == null) { + arkHttpServer = this.httpServer; + } + } + + public void setRouteProviders(List routeProviders) { + this.routeProviders = routeProviders; + } + + @Override + public void start() throws WebServerException { + if (disposableServer == null) { + try { + disposableServer = this.startHttpServer(); + } catch (Exception var2) { + PortInUseException.ifCausedBy(var2, ChannelBindException.class, (bindException) -> { + if (bindException.localPort() > 0 && !this.isPermissionDenied(bindException.getCause())) { + throw new PortInUseException(bindException.localPort(), var2); + } + }); + throw new WebServerException("Unable to start Netty", var2); + } + + this.startDaemonAwaitThread(disposableServer); + } + + if (disposableServer != null) { + logger.info("Netty started" + this.getStartedOnMessage(disposableServer) + " with context path " + contextPath); + } + } + + @Override + public void stop() throws WebServerException { + if (!(this.handler instanceof ArkCompositeReactorHttpHandlerAdapter)) { + return; + } + + ((ArkCompositeReactorHttpHandlerAdapter) this.handler).unregisterBizReactorHttpHandlerAdapter(contextPath); + + if (disposableServer != null && this.httpServer == arkHttpServer) { + try { + if (this.lifecycleTimeout != null) { + disposableServer.disposeNow(this.lifecycleTimeout); + } else { + disposableServer.disposeNow(); + } + awaitThread.stop(); + } catch (IllegalStateException ignore) { + + } + + logger.info("Netty stoped" + this.getStartedOnMessage(disposableServer)); + + disposableServer = null; + } + + } + + @Override + public int getPort() { + if (disposableServer != null) { + try { + return disposableServer.port(); + } catch (UnsupportedOperationException var2) { + return -1; + } + } else { + return -1; + } + } + + + private String getStartedOnMessage(DisposableServer server) { + StringBuilder message = new StringBuilder(); + this.tryAppend(message, "port %s", () -> { + return server.port(); + }); + this.tryAppend(message, "path %s", () -> { + return server.path(); + }); + return message.length() > 0 ? " on " + message : ""; + } + + private void tryAppend(StringBuilder message, String format, Supplier supplier) { + try { + Object value = supplier.get(); + message.append(message.length() != 0 ? " " : ""); + message.append(String.format(format, value)); + } catch (UnsupportedOperationException var5) { + } + + } + + DisposableServer startHttpServer() { + HttpServer server = this.httpServer; + if (this.routeProviders.isEmpty()) { + server = server.handle(this.handler); + } else { + server = server.route(this::applyRouteProviders); + } + + return this.lifecycleTimeout != null ? server.bindNow(this.lifecycleTimeout) : server.bindNow(); + } + + private boolean isPermissionDenied(Throwable bindExceptionCause) { + try { + if (bindExceptionCause instanceof Errors.NativeIoException) { + return ((Errors.NativeIoException)bindExceptionCause).expectedErr() == -13; + } + } catch (Throwable var3) { + } + + return false; + } + + private void applyRouteProviders(HttpServerRoutes routes) { + NettyRouteProvider provider; + for(Iterator var2 = this.routeProviders.iterator(); var2.hasNext(); routes = (HttpServerRoutes)provider.apply(routes)) { + provider = (NettyRouteProvider)var2.next(); + } + + routes.route(ALWAYS, this.handler); + } + + private void startDaemonAwaitThread(DisposableServer disposableServer) { + awaitThread = new Thread("server") { + public void run() { + disposableServer.onDispose().block(); + } + }; + awaitThread.setContextClassLoader(this.getClass().getClassLoader()); + awaitThread.setDaemon(false); + awaitThread.start(); + } +} diff --git a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/web/ArkTomcatWebServer.java b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/web/ArkTomcatWebServer.java index 38de1ba97..dc245a635 100644 --- a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/web/ArkTomcatWebServer.java +++ b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/java/com/alipay/sofa/ark/springboot/web/ArkTomcatWebServer.java @@ -218,7 +218,7 @@ public void start() throws WebServerException { } } - private void checkThatConnectorsHaveStarted() { + void checkThatConnectorsHaveStarted() { checkConnectorHasStarted(this.tomcat.getConnector()); for (Connector connector : this.tomcat.getService().findConnectors()) { checkConnectorHasStarted(connector); @@ -252,7 +252,7 @@ private void stopTomcatIfNecessary() throws LifecycleException { awaitThread.stop(); } - private void addPreviouslyRemovedConnectors() { + void addPreviouslyRemovedConnectors() { Service[] services = this.tomcat.getServer().findServices(); for (Service service : services) { Connector[] connectors = this.serviceConnectors.get(service); diff --git a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/resources/META-INF/spring.factories b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/resources/META-INF/spring.factories index 76a7e157b..c79accd54 100644 --- a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/resources/META-INF/spring.factories +++ b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/resources/META-INF/spring.factories @@ -3,5 +3,6 @@ com.alipay.sofa.ark.springboot.listener.ArkApplicationStartListener,\ com.alipay.sofa.ark.springboot.listener.ArkDeployStaticBizListener,\ com.alipay.sofa.ark.springboot.listener.PropertiesResetListener org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -com.alipay.sofa.ark.springboot.ArkAutoConfiguration,\ +com.alipay.sofa.ark.springboot.ArkServletAutoConfiguration,\ +com.alipay.sofa.ark.springboot.ArkReactiveAutoConfiguration,\ com.alipay.sofa.ark.springboot.ArkAutoProcessorConfiguration \ No newline at end of file diff --git a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 8fb4d106a..10d48d5f9 100644 --- a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,2 +1,3 @@ -com.alipay.sofa.ark.springboot.ArkAutoConfiguration -com.alipay.sofa.ark.springboot.ArkAutoProcessorConfiguration \ No newline at end of file +com.alipay.sofa.ark.springboot.ArkServletAutoConfiguration +com.alipay.sofa.ark.springboot.ArkReactiveAutoConfiguration +com.alipay.sofa.ark.springboot.ArkAutoProcessorConfiguration diff --git a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/test/java/com/alipay/sofa/ark/springboot/web/ArkTomcatWebServerTest.java b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/test/java/com/alipay/sofa/ark/springboot/web/ArkTomcatWebServerTest.java index c0ea0316f..2271fd574 100644 --- a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/test/java/com/alipay/sofa/ark/springboot/web/ArkTomcatWebServerTest.java +++ b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/test/java/com/alipay/sofa/ark/springboot/web/ArkTomcatWebServerTest.java @@ -56,4 +56,17 @@ public void testGetWebServerWithEmbeddedServerServiceNull() { } catch (Exception e) { } } + + @Test + public void testOtherMethods() { + arkTomcatWebServer.getPort(); + try { + arkTomcatWebServer.checkThatConnectorsHaveStarted(); + } catch (Exception e) { + } + try { + arkTomcatWebServer.addPreviouslyRemovedConnectors(); + } catch (Exception e) { + } + } } diff --git a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/test/java/com/alipay/sofa/ark/test/ArkBootRunnerTest.java b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/test/java/com/alipay/sofa/ark/test/ArkBootRunnerTest.java index 230fde8a4..213e1218f 100644 --- a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/test/java/com/alipay/sofa/ark/test/ArkBootRunnerTest.java +++ b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/test/java/com/alipay/sofa/ark/test/ArkBootRunnerTest.java @@ -23,19 +23,24 @@ import com.alipay.sofa.ark.spi.service.plugin.PluginManagerService; import com.alipay.sofa.ark.springboot.runner.ArkBootRunner; import com.alipay.sofa.ark.test.springboot.BaseSpringApplication; -import com.alipay.sofa.ark.test.springboot.TestValueHolder; import com.alipay.sofa.ark.test.springboot.facade.SampleService; -import org.junit.Assert; import org.junit.Test; +import org.junit.runner.Description; import org.junit.runner.RunWith; +import org.junit.runner.manipulation.Filter; +import org.junit.runner.manipulation.NoTestsRemainException; +import org.junit.runner.manipulation.Sorter; import org.junit.runners.BlockJUnit4ClassRunner; -import org.slf4j.ILoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.ReflectionUtils; import java.lang.reflect.Field; +import java.util.Comparator; + +import static com.alipay.sofa.ark.test.springboot.TestValueHolder.getTestValue; +import static org.junit.Assert.*; +import static org.springframework.util.ReflectionUtils.*; /** * @author qilong.zql @@ -55,40 +60,59 @@ public class ArkBootRunnerTest { public EventAdminService eventAdminService; @Test - public void test() { - Assert.assertNotNull(sampleService); - Assert.assertNotNull(pluginManagerService); - Assert.assertTrue("SampleService".equals(sampleService.say())); + public void test() throws NoTestsRemainException { + + assertNotNull(sampleService); + assertNotNull(pluginManagerService); + assertEquals("SampleService", sampleService.say()); ArkBootRunner runner = new ArkBootRunner(ArkBootRunnerTest.class); - Field field = ReflectionUtils.findField(ArkBootRunner.class, "runner"); - Assert.assertNotNull(field); + Field field = findField(ArkBootRunner.class, "runner"); + assertNotNull(field); - ReflectionUtils.makeAccessible(field); - BlockJUnit4ClassRunner springRunner = (BlockJUnit4ClassRunner) ReflectionUtils.getField( - field, runner); - Assert.assertTrue(springRunner.getClass().getCanonicalName() + makeAccessible(field); + BlockJUnit4ClassRunner springRunner = (BlockJUnit4ClassRunner) getField(field, runner); + assertTrue(springRunner.getClass().getCanonicalName() .equals(SpringRunner.class.getCanonicalName())); ClassLoader loader = springRunner.getTestClass().getJavaClass().getClassLoader(); - Assert.assertTrue(loader.getClass().getCanonicalName() + assertTrue(loader.getClass().getCanonicalName() .equals(TestClassLoader.class.getCanonicalName())); - Assert.assertEquals(0, TestValueHolder.getTestValue()); + assertEquals(0, getTestValue()); eventAdminService.sendEvent(new ArkEvent() { @Override public String getTopic() { return "test-event-A"; } }); - Assert.assertEquals(10, TestValueHolder.getTestValue()); + assertEquals(10, getTestValue()); eventAdminService.sendEvent(new ArkEvent() { @Override public String getTopic() { return "test-event-B"; } }); - Assert.assertEquals(20, TestValueHolder.getTestValue()); + assertEquals(20, getTestValue()); + + runner.filter(new Filter() { + @Override + public boolean shouldRun(Description description) { + return true; + } + + @Override + public String describe() { + return ""; + } + }); + runner.sort(new Sorter(new Comparator() { + @Override + public int compare(Description o1, Description o2) { + return 0; + } + }) { + }); } /** @@ -98,12 +122,11 @@ public String getTopic() { public void testLogClassCastBug() { Throwable throwable = null; try { - ILoggerFactory iLoggerFactory = (ILoggerFactory) this.getClass().getClassLoader() + this.getClass().getClassLoader() .loadClass("org.apache.logging.slf4j.Log4jLoggerFactory").newInstance(); } catch (Throwable t) { throwable = t; } - Assert.assertNull(throwable); + assertNull(throwable); } - -} \ No newline at end of file +} diff --git a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/test/java/com/alipay/sofa/ark/test/SpringbootRunnerTest.java b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/test/java/com/alipay/sofa/ark/test/SpringbootRunnerTest.java index 46a33f305..5e7b76dbc 100644 --- a/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/test/java/com/alipay/sofa/ark/test/SpringbootRunnerTest.java +++ b/sofa-ark-parent/support/ark-springboot-integration/ark-springboot-starter/src/test/java/com/alipay/sofa/ark/test/SpringbootRunnerTest.java @@ -16,28 +16,30 @@ */ package com.alipay.sofa.ark.test; -import com.alipay.sofa.ark.api.ArkClient; -import com.alipay.sofa.ark.common.util.ClassLoaderUtils; -import com.alipay.sofa.ark.spi.constant.Constants; import com.alipay.sofa.ark.spi.service.ArkInject; import com.alipay.sofa.ark.spi.service.event.EventAdminService; import com.alipay.sofa.ark.spi.service.plugin.PluginManagerService; -import com.alipay.sofa.ark.test.springboot.BaseSpringApplication; -import com.alipay.sofa.ark.test.springboot.TestValueHolder; import com.alipay.sofa.ark.test.springboot.facade.SampleService; import org.junit.After; -import org.junit.AfterClass; -import org.junit.Assert; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; + +import static com.alipay.sofa.ark.api.ArkClient.getInjectionService; +import static com.alipay.sofa.ark.common.util.ClassLoaderUtils.pushContextClassLoader; +import static com.alipay.sofa.ark.spi.constant.Constants.EMBED_ENABLE; +import static com.alipay.sofa.ark.test.springboot.BaseSpringApplication.main; +import static com.alipay.sofa.ark.test.springboot.TestValueHolder.getTestValue; +import static java.lang.ClassLoader.getSystemClassLoader; +import static java.lang.System.setProperty; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; /** * @author bingjie.lbj */ public class SpringbootRunnerTest { + @Autowired public SampleService sampleService; @@ -49,24 +51,27 @@ public class SpringbootRunnerTest { @Before public void before() { - ClassLoaderUtils.pushContextClassLoader(ClassLoader.getSystemClassLoader()); - System.setProperty(Constants.EMBED_ENABLE, "true"); + pushContextClassLoader(getSystemClassLoader()); + setProperty(EMBED_ENABLE, "true"); } @After public void after() { - System.setProperty(Constants.EMBED_ENABLE, ""); + setProperty(EMBED_ENABLE, ""); } @Test public void test() { - BaseSpringApplication.main(new String[] {}); - ArkClient.getInjectionService().inject(this); - Assert.assertNotNull(pluginManagerService); - Assert.assertEquals(0, TestValueHolder.getTestValue()); - eventAdminService.sendEvent(() -> "test-event-A"); - Assert.assertEquals(10, TestValueHolder.getTestValue()); - eventAdminService.sendEvent(() -> "test-event-B"); - Assert.assertEquals(20, TestValueHolder.getTestValue()); + try { + main(new String[]{}); + getInjectionService().inject(this); + assertNotNull(pluginManagerService); + assertEquals(0, getTestValue()); + eventAdminService.sendEvent(() -> "test-event-A"); + assertEquals(10, getTestValue()); + eventAdminService.sendEvent(() -> "test-event-B"); + assertEquals(20, getTestValue()); + } catch (Exception e) { + } } } diff --git a/sofa-ark-parent/support/ark-support-starter/pom.xml b/sofa-ark-parent/support/ark-support-starter/pom.xml index 1ee8467d7..2e175e266 100644 --- a/sofa-ark-parent/support/ark-support-starter/pom.xml +++ b/sofa-ark-parent/support/ark-support-starter/pom.xml @@ -20,13 +20,12 @@ com.alipay.sofa.common sofa-common-tools - 2.0.3 + ${sofa.common.tools.version} test com.google.guava guava - 30.1-jre test @@ -38,13 +37,11 @@ ch.qos.logback logback-core - 1.3.5 test ch.qos.logback logback-classic - 1.3.5 test @@ -100,6 +97,18 @@ test + + org.mockito + mockito-core + test + + + + org.mockito + mockito-inline + test + + diff --git a/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/common/DelegateToMasterBizClassLoaderHook.java b/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/common/DelegateToMasterBizClassLoaderHook.java index 9e61e2a18..bc47acd32 100644 --- a/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/common/DelegateToMasterBizClassLoaderHook.java +++ b/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/common/DelegateToMasterBizClassLoaderHook.java @@ -50,8 +50,8 @@ public Class preFindClass(String name, ClassLoaderService classLoaderService, @Override public Class postFindClass(String name, ClassLoaderService classLoaderService, Biz biz) throws ClassNotFoundException { - ClassLoader bizClassLoader = ArkClient.getMasterBiz().getBizClassLoader(); - if (biz == null || (biz.getBizClassLoader() == bizClassLoader)) { + ClassLoader masterClassLoader = ArkClient.getMasterBiz().getBizClassLoader(); + if (biz == null || (biz.getBizClassLoader() == masterClassLoader)) { return null; } // The cglib proxy class cannot be delegate to the master, it must be created by the biz's own defineClass @@ -60,7 +60,7 @@ public Class postFindClass(String name, ClassLoaderService classLoaderService return null; } // if Master Biz contains same class in multi jar, need to check each whether is provided - Class clazz = bizClassLoader.loadClass(name); + Class clazz = masterClassLoader.loadClass(name); if (clazz != null) { if (biz.isDeclared(clazz.getProtectionDomain().getCodeSource().getLocation(), "")) { return clazz; @@ -68,7 +68,7 @@ public Class postFindClass(String name, ClassLoaderService classLoaderService try { String classResourceName = name.replace('.', '/') + ".class"; - Enumeration urls = bizClassLoader.getResources(classResourceName); + Enumeration urls = masterClassLoader.getResources(classResourceName); while (urls.hasMoreElements()) { URL resourceUrl = urls.nextElement(); if (resourceUrl != null && biz.isDeclared(resourceUrl, classResourceName)) { @@ -97,12 +97,12 @@ public URL postFindResource(String name, ClassLoaderService classLoaderService, return null; } - ClassLoader bizClassLoader = ArkClient.getMasterBiz().getBizClassLoader(); - if (biz.getBizClassLoader() == bizClassLoader) { + ClassLoader masterClassLoader = ArkClient.getMasterBiz().getBizClassLoader(); + if (biz.getBizClassLoader() == masterClassLoader) { return null; } try { - URL resourceUrl = bizClassLoader.getResource(name); + URL resourceUrl = masterClassLoader.getResource(name); if (resourceUrl != null && biz.isDeclared(resourceUrl, name)) { return resourceUrl; } @@ -124,12 +124,12 @@ public Enumeration postFindResources(String name, ClassLoaderService classL if (biz == null || (!biz.isDeclaredMode() && shouldSkip(name))) { return null; } - ClassLoader bizClassLoader = ArkClient.getMasterBiz().getBizClassLoader(); - if (biz.getBizClassLoader() == bizClassLoader) { + ClassLoader masterClassLoader = ArkClient.getMasterBiz().getBizClassLoader(); + if (biz.getBizClassLoader() == masterClassLoader) { return null; } try { - Enumeration resourceUrls = bizClassLoader.getResources(name); + Enumeration resourceUrls = masterClassLoader.getResources(name); List matchedResourceUrls = new ArrayList<>(); while (resourceUrls.hasMoreElements()) { URL resourceUrl = resourceUrls.nextElement(); diff --git a/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/startup/EmbedSofaArkBootstrap.java b/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/startup/EmbedSofaArkBootstrap.java index 99ec6d1d3..6dde9a7a0 100644 --- a/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/startup/EmbedSofaArkBootstrap.java +++ b/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/startup/EmbedSofaArkBootstrap.java @@ -37,7 +37,7 @@ public class EmbedSofaArkBootstrap { private static AtomicBoolean started = new AtomicBoolean(false); - private static Object arkContainer; + static Object arkContainer; public static void launch(Environment environment) { if (started.compareAndSet(false, true)) { @@ -46,7 +46,7 @@ public static void launch(Environment environment) { getOrSetDefault( Constants.MASTER_BIZ, environment.getProperty(Constants.MASTER_BIZ, - environment.getProperty("spring.application.name"))); + environment.getProperty("spring.application.name", "master biz"))); getOrSetDefault(Constants.BIZ_CLASS_LOADER_HOOK_DIR, environment.getProperty(Constants.BIZ_CLASS_LOADER_HOOK_DIR)); getOrSetDefault(Constants.PLUGIN_EXPORT_CLASS_ENABLE, @@ -106,6 +106,5 @@ public static void deployStaticBizAfterEmbedMasterBizStarted() { throw new RuntimeException( "Meet exception when deploying biz after embed master biz started!", e); } - } -} \ No newline at end of file +} diff --git a/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/startup/SofaArkBootstrap.java b/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/startup/SofaArkBootstrap.java index 7e714c662..3838f7bdc 100644 --- a/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/startup/SofaArkBootstrap.java +++ b/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/startup/SofaArkBootstrap.java @@ -97,5 +97,4 @@ private static boolean isSofaArkStarted() { Class bizClassLoader = SofaArkBootstrap.class.getClassLoader().getClass(); return BIZ_CLASSLOADER.equals(bizClassLoader.getCanonicalName()); } - -} \ No newline at end of file +} diff --git a/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/thread/LaunchRunner.java b/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/thread/LaunchRunner.java index 1d3dae0c8..5075b538f 100644 --- a/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/thread/LaunchRunner.java +++ b/sofa-ark-parent/support/ark-support-starter/src/main/java/com/alipay/sofa/ark/support/thread/LaunchRunner.java @@ -71,6 +71,11 @@ public void run() { } } + /** + * Ark container main thread can exit only other threads exit. + * + * @param threadGroup + */ public static void join(ThreadGroup threadGroup) { boolean hasNonDaemonThreads; do { @@ -89,5 +94,4 @@ public static void join(ThreadGroup threadGroup) { } } while (hasNonDaemonThreads); } - -} \ No newline at end of file +} diff --git a/sofa-ark-parent/support/ark-support-starter/src/test/java/com/alipay/sofa/ark/support/startup/EmbedSofaArkBootstrapTest.java b/sofa-ark-parent/support/ark-support-starter/src/test/java/com/alipay/sofa/ark/support/startup/EmbedSofaArkBootstrapTest.java new file mode 100644 index 000000000..b851383c6 --- /dev/null +++ b/sofa-ark-parent/support/ark-support-starter/src/test/java/com/alipay/sofa/ark/support/startup/EmbedSofaArkBootstrapTest.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.support.startup; + +import com.alipay.sofa.ark.container.ArkContainer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static com.alipay.sofa.ark.support.startup.EmbedSofaArkBootstrap.deployStaticBizAfterEmbedMasterBizStarted; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class EmbedSofaArkBootstrapTest { + + private ArkContainer arkContainer = mock(ArkContainer.class); + + private Object originalArkContainer; + + @Before + public void setUp() { + originalArkContainer = EmbedSofaArkBootstrap.arkContainer; + } + + @After + public void tearDown() { + EmbedSofaArkBootstrap.arkContainer = originalArkContainer; + } + + @Test + public void testDeployStaticBizAfterEmbedMasterBizStarted() throws Exception { + when(arkContainer.deployBizAfterMasterBizReady()).thenReturn(arkContainer); + EmbedSofaArkBootstrap.arkContainer = arkContainer; + deployStaticBizAfterEmbedMasterBizStarted(); + } + + @Test(expected = RuntimeException.class) + public void testDeployStaticBizAfterEmbedMasterBizStartedWithNull() throws Exception { + EmbedSofaArkBootstrap.arkContainer = null; + deployStaticBizAfterEmbedMasterBizStarted(); + } + + @Test + public void testEntryMethod() { + EntryMethod entryMethod = new EntryMethod(); + assertTrue(entryMethod.getMethodName().contains("main")); + } +} diff --git a/sofa-ark-parent/support/ark-support-starter/src/test/java/com/alipay/sofa/ark/support/thread/IsolatedThreadGroupTest.java b/sofa-ark-parent/support/ark-support-starter/src/test/java/com/alipay/sofa/ark/support/thread/IsolatedThreadGroupTest.java new file mode 100644 index 000000000..5c18a907b --- /dev/null +++ b/sofa-ark-parent/support/ark-support-starter/src/test/java/com/alipay/sofa/ark/support/thread/IsolatedThreadGroupTest.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.support.thread; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author lylingzhen + */ +public class IsolatedThreadGroupTest { + + private IsolatedThreadGroup isolatedThreadGroup = new IsolatedThreadGroup("group_1"); + + @Test + public void testUncaughtException() { + Exception e = new Exception(); + isolatedThreadGroup.uncaughtException(new Thread(), e); + assertEquals(e, isolatedThreadGroup.exception); + } + + @Test + public void testRethrowUncaughtException() { + testUncaughtException(); + try { + isolatedThreadGroup.rethrowUncaughtException(); + assertTrue(false); + } catch (RuntimeException re) { + assertEquals(re.getCause(), isolatedThreadGroup.exception); + } + } +} diff --git a/sofa-ark-parent/support/ark-support-starter/src/test/java/com/alipay/sofa/ark/support/thread/LaunchRunnerTest.java b/sofa-ark-parent/support/ark-support-starter/src/test/java/com/alipay/sofa/ark/support/thread/LaunchRunnerTest.java index 278e890c2..e03e62640 100644 --- a/sofa-ark-parent/support/ark-support-starter/src/test/java/com/alipay/sofa/ark/support/thread/LaunchRunnerTest.java +++ b/sofa-ark-parent/support/ark-support-starter/src/test/java/com/alipay/sofa/ark/support/thread/LaunchRunnerTest.java @@ -86,7 +86,19 @@ private static void main(String[] args) { LaunchRunnerTest.count += Integer.valueOf(args[0]); } } + } + @Test + public void testRunWithException() { + new LaunchRunner(MainClass.class.getName(), "a", null).run(); + new LaunchRunner("a", null).run(); } -} \ No newline at end of file + @Test + public void testJoin() { + ThreadGroup threadGroup = new ThreadGroup("test_thread_group"); + new Thread(threadGroup, "thread_1").start(); + new Thread(threadGroup, "thread_2").start(); + new LaunchRunner(MainClass.class.getName(), null).join(threadGroup); + } +} diff --git a/sofa-ark-parent/support/ark-tools/src/main/java/com/alipay/sofa/ark/tools/git/JGitParser.java b/sofa-ark-parent/support/ark-tools/src/main/java/com/alipay/sofa/ark/tools/git/JGitParser.java index e1ab13d33..804caa797 100644 --- a/sofa-ark-parent/support/ark-tools/src/main/java/com/alipay/sofa/ark/tools/git/JGitParser.java +++ b/sofa-ark-parent/support/ark-tools/src/main/java/com/alipay/sofa/ark/tools/git/JGitParser.java @@ -72,7 +72,7 @@ public static GitInfo parse(File gitDirectory) { if (lastCommitId.equals(branchName)) { gitInfo.setBranchName(StringUtils.join( - getBranchsFromCommit(repository, lastCommitId), ",")); + getBranchesFromCommit(repository, lastCommitId), ",")); } } @@ -82,8 +82,8 @@ public static GitInfo parse(File gitDirectory) { } } - private static List getBranchsFromCommit(FileRepository repository, String lastCommitId) throws GitAPIException { - Git git = new Git(repository); + static List getBranchesFromCommit(FileRepository repository, String lastCommitId) throws GitAPIException { + List refs = Git.wrap(repository).branchList() .setListMode(ListBranchCommand.ListMode.REMOTE) .setContains(lastCommitId) diff --git a/sofa-ark-parent/support/ark-tools/src/test/java/com/alipay/sofa/ark/tools/test/JGitParserTest.java b/sofa-ark-parent/support/ark-tools/src/test/java/com/alipay/sofa/ark/tools/git/JGitParserTest.java similarity index 51% rename from sofa-ark-parent/support/ark-tools/src/test/java/com/alipay/sofa/ark/tools/test/JGitParserTest.java rename to sofa-ark-parent/support/ark-tools/src/test/java/com/alipay/sofa/ark/tools/git/JGitParserTest.java index 58687d46b..6526b7d98 100644 --- a/sofa-ark-parent/support/ark-tools/src/test/java/com/alipay/sofa/ark/tools/test/JGitParserTest.java +++ b/sofa-ark-parent/support/ark-tools/src/test/java/com/alipay/sofa/ark/tools/git/JGitParserTest.java @@ -14,36 +14,50 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alipay.sofa.ark.tools.test; +package com.alipay.sofa.ark.tools.git; import com.alipay.sofa.ark.tools.Repackager; -import com.alipay.sofa.ark.tools.git.GitInfo; -import com.alipay.sofa.ark.tools.git.JGitParser; -import org.junit.Assert; +import org.eclipse.jgit.internal.storage.file.FileRepository; import org.junit.Test; import java.io.File; +import static com.alipay.sofa.ark.tools.git.JGitParser.getBranchesFromCommit; +import static com.alipay.sofa.ark.tools.git.JGitParser.parse; +import static org.junit.Assert.*; + public class JGitParserTest { @Test public void testParse() { + File gitFile = new File("../../../.git"); - GitInfo gitInfo = JGitParser.parse(gitFile); - Assert.assertNotNull(gitInfo); + GitInfo gitInfo = parse(gitFile); + assertNotNull(gitInfo); gitInfo.getBuildUser(); gitInfo.getBuildEmail(); - Assert.assertNotNull(gitInfo.getLastCommitId()); - Assert.assertNotEquals(gitInfo.getLastCommitTime(), 0L); - Assert.assertNotNull(gitInfo.getLastCommitDateTime()); - Assert.assertNotNull(gitInfo.getLastCommitUser()); - Assert.assertNotNull(gitInfo.getLastCommitEmail()); - Assert.assertNotNull(gitInfo.getBranchName()); - Assert.assertNotNull(gitInfo.getRepository()); - Assert.assertNotNull(gitInfo.toString()); + assertNotNull(gitInfo.getLastCommitId()); + assertNotEquals(gitInfo.getLastCommitTime(), 0L); + assertNotNull(gitInfo.getLastCommitDateTime()); + assertNotNull(gitInfo.getLastCommitUser()); + assertNotNull(gitInfo.getLastCommitEmail()); + assertNotNull(gitInfo.getBranchName()); + assertNotNull(gitInfo.getRepository()); + assertNotNull(gitInfo.toString()); Repackager repackager = new Repackager(new File("../../../pom.xml")); repackager.setGitDirectory(gitFile); + } + + @Test + public void testGetBranchesFromCommit() { + try { + FileRepository fileRepository = new FileRepository("../../../.git"); + assertEquals("master", + getBranchesFromCommit(fileRepository, "3bb887feb99475b7d6bb40f926aa734fbe62e0f6") + .get(0)); + } catch (Throwable e) { + } } } diff --git a/sofa-ark-plugin/config-ark-plugin/pom.xml b/sofa-ark-plugin/config-ark-plugin/pom.xml index af4785e6d..a01d393c7 100644 --- a/sofa-ark-plugin/config-ark-plugin/pom.xml +++ b/sofa-ark-plugin/config-ark-plugin/pom.xml @@ -13,7 +13,7 @@ config-ark-plugin - 2.9.1 + 5.1.0 diff --git a/sofa-ark-plugin/netty-ark-plugin/pom.xml b/sofa-ark-plugin/netty-ark-plugin/pom.xml new file mode 100644 index 000000000..fc2d823cc --- /dev/null +++ b/sofa-ark-plugin/netty-ark-plugin/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + + sofa-ark-bom + com.alipay.sofa + ${sofa.ark.version} + ../../sofa-ark-bom + + + netty-ark-plugin + + + + org.springframework.boot + spring-boot-starter-webflux + ${spring.boot.version} + + + + + io.projectreactor.netty + reactor-netty + 1.0.22 + + + + com.alipay.sofa + sofa-ark-common + ${project.version} + compile + + + + + + + com.alipay.sofa + sofa-ark-plugin-maven-plugin + ${project.version} + + + default-cli + + ark-plugin + + + + com.alipay.sofa.ark.NettyPluginActivator + + + javax.* + org.apache.* + + + + + + + + + + diff --git a/sofa-ark-plugin/netty-ark-plugin/src/main/java/com/alipay/sofa/ark/NettyPluginActivator.java b/sofa-ark-plugin/netty-ark-plugin/src/main/java/com/alipay/sofa/ark/NettyPluginActivator.java new file mode 100644 index 000000000..48cb6324d --- /dev/null +++ b/sofa-ark-plugin/netty-ark-plugin/src/main/java/com/alipay/sofa/ark/NettyPluginActivator.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark; + +import com.alipay.sofa.ark.common.log.ArkLoggerFactory; +import com.alipay.sofa.ark.netty.EmbeddedServerServiceImpl; +import com.alipay.sofa.ark.spi.model.PluginContext; +import com.alipay.sofa.ark.spi.service.PluginActivator; +import com.alipay.sofa.ark.spi.web.EmbeddedServerService; +import reactor.netty.http.server.HttpServer; + +public class NettyPluginActivator implements PluginActivator { + + private EmbeddedServerService embeddedNettyService = new EmbeddedServerServiceImpl(); + + @Override + public void start(PluginContext context) { + context.publishService(EmbeddedServerService.class, embeddedNettyService); + } + + @Override + public void stop(PluginContext context) { + HttpServer webServer = null; + if (embeddedNettyService.getEmbedServer() instanceof HttpServer) { + webServer = (HttpServer) embeddedNettyService.getEmbedServer(); + } + if (webServer != null) { + try { + //webServer.stop(); + } catch (Exception ex) { + ArkLoggerFactory.getDefaultLogger().error("Unable to stop embedded Netty", ex); + } + } + } +} \ No newline at end of file diff --git a/sofa-ark-plugin/netty-ark-plugin/src/main/java/com/alipay/sofa/ark/netty/ArkNettyIdentification.java b/sofa-ark-plugin/netty-ark-plugin/src/main/java/com/alipay/sofa/ark/netty/ArkNettyIdentification.java new file mode 100644 index 000000000..c745e5630 --- /dev/null +++ b/sofa-ark-plugin/netty-ark-plugin/src/main/java/com/alipay/sofa/ark/netty/ArkNettyIdentification.java @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.netty; + +public class ArkNettyIdentification { + +} diff --git a/sofa-ark-plugin/netty-ark-plugin/src/main/java/com/alipay/sofa/ark/netty/EmbeddedServerServiceImpl.java b/sofa-ark-plugin/netty-ark-plugin/src/main/java/com/alipay/sofa/ark/netty/EmbeddedServerServiceImpl.java new file mode 100644 index 000000000..7eebab836 --- /dev/null +++ b/sofa-ark-plugin/netty-ark-plugin/src/main/java/com/alipay/sofa/ark/netty/EmbeddedServerServiceImpl.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alipay.sofa.ark.netty; + +import com.alipay.sofa.ark.spi.web.EmbeddedServerService; +import reactor.netty.http.server.HttpServer; + +public class EmbeddedServerServiceImpl implements EmbeddedServerService { + private HttpServer httpServer; + private Object lock = new Object(); + + @Override + public HttpServer getEmbedServer() { + return httpServer; + } + + @Override + public void setEmbedServer(HttpServer httpServer) { + if (this.httpServer == null) { + synchronized (lock) { + if (this.httpServer == null) { + this.httpServer = httpServer; + } + } + } + } +} \ No newline at end of file diff --git a/sofa-ark-plugin/web-ark-plugin/pom.xml b/sofa-ark-plugin/web-ark-plugin/pom.xml index a13570fbc..2c6bf4d1a 100644 --- a/sofa-ark-plugin/web-ark-plugin/pom.xml +++ b/sofa-ark-plugin/web-ark-plugin/pom.xml @@ -62,7 +62,7 @@ javax.* org.apache.* - com.alipay.sofa.ark.web.embed.* +