diff --git a/assemblies/nexus-base-feature/pom.xml b/assemblies/nexus-base-feature/pom.xml
index 000334a9a4b6a17f32627ae2b30542da5597d34f..7c56fb62207edfa2605815a6a0107f64ccd2274b 100644
--- a/assemblies/nexus-base-feature/pom.xml
+++ b/assemblies/nexus-base-feature/pom.xml
@@ -19,7 +19,7 @@
org.sonatype.nexus.assembliesnexus-assemblies
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-base-feature
diff --git a/assemblies/nexus-base-template/pom.xml b/assemblies/nexus-base-template/pom.xml
index 3c7b39395f06801f54462f12cbf260cb880df0d6..a5f96a624b0a06bd9c07e0e09b3eab062ae3e284 100644
--- a/assemblies/nexus-base-template/pom.xml
+++ b/assemblies/nexus-base-template/pom.xml
@@ -21,7 +21,7 @@
org.sonatype.nexus.assembliesnexus-assemblies
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-base-template
diff --git a/assemblies/nexus-boot-feature/pom.xml b/assemblies/nexus-boot-feature/pom.xml
index 9a604cdafdb9ada5b93578769c9959f0d72ffd8c..1578a10015b8912c97d2856bc2d05f55572df010 100644
--- a/assemblies/nexus-boot-feature/pom.xml
+++ b/assemblies/nexus-boot-feature/pom.xml
@@ -19,7 +19,7 @@
org.sonatype.nexus.assembliesnexus-assemblies
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-boot-feature
diff --git a/assemblies/nexus-core-feature/pom.xml b/assemblies/nexus-core-feature/pom.xml
index 50c0a784ea48b48e8b193f752af9370dcf1ea6cc..7e07b099e4b54ab04185328a6fc59ae78975f4ed 100644
--- a/assemblies/nexus-core-feature/pom.xml
+++ b/assemblies/nexus-core-feature/pom.xml
@@ -19,7 +19,7 @@
org.sonatype.nexus.assembliesnexus-assemblies
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-core-feature
diff --git a/assemblies/nexus-startup-feature/pom.xml b/assemblies/nexus-startup-feature/pom.xml
index 0f6c070f7707ec6cd91833b78fe1edc4c859915d..fc41711ab3ce3e3807d1aa11b727100a07a6d495 100644
--- a/assemblies/nexus-startup-feature/pom.xml
+++ b/assemblies/nexus-startup-feature/pom.xml
@@ -19,7 +19,7 @@
org.sonatype.nexus.assembliesnexus-assemblies
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-startup-feature
diff --git a/assemblies/pom.xml b/assemblies/pom.xml
index f5ac4172d71124e38304f0fd6190a91c4acc3c50..77ecee1b67714db14dda05ca8b8685bbe6c36d56 100644
--- a/assemblies/pom.xml
+++ b/assemblies/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-parent
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.assemblies
@@ -45,7 +45,7 @@
org.sonatype.nexusnexus-componentspom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -53,7 +53,7 @@
org.sonatype.nexus.pluginsnexus-pluginspom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
diff --git a/buildsupport/all/pom.xml b/buildsupport/all/pom.xml
index 2fe4f9ba06a9aa6883afd15f406b592e8ee798f3..9624c0e79d53eddf0149959a8e6d47c3cbb24d5a 100644
--- a/buildsupport/all/pom.xml
+++ b/buildsupport/all/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-all
@@ -35,7 +35,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-commonspom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -43,7 +43,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-dbpom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -51,7 +51,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-goodiespom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -59,7 +59,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-groovypom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -67,7 +67,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-guicepom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -75,7 +75,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-httpclientpom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -83,7 +83,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-internalpom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -91,7 +91,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-jettypom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -99,7 +99,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-jrubypom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -107,7 +107,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-loggingpom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -115,7 +115,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-mavenpom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -123,7 +123,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-metricspom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -131,7 +131,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-osgipom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -139,7 +139,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-otherpom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -147,7 +147,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-restpom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -155,7 +155,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-securitypom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -163,7 +163,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-testingpom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -171,7 +171,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-uipom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
diff --git a/buildsupport/commons/pom.xml b/buildsupport/commons/pom.xml
index 320d396475eed403e3080ed05f1f7183244f8d0e..9b550483c43443847e8ebf992e9d6f6f710d9463 100644
--- a/buildsupport/commons/pom.xml
+++ b/buildsupport/commons/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-commons
diff --git a/buildsupport/db/pom.xml b/buildsupport/db/pom.xml
index e03f193580c5a36e317273c5b6c90a246a3e9d83..2da5306f8a6bf2e517e9e6195dc19778c1392657 100644
--- a/buildsupport/db/pom.xml
+++ b/buildsupport/db/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-db
diff --git a/buildsupport/extjs-maven-plugin/pom.xml b/buildsupport/extjs-maven-plugin/pom.xml
index 9a2977296b1251d801307b8bfe3c47ab1c814c12..8c88df260b70845db9e2cb0fc707c84b025c9ffa 100644
--- a/buildsupport/extjs-maven-plugin/pom.xml
+++ b/buildsupport/extjs-maven-plugin/pom.xml
@@ -21,7 +21,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02extjs-maven-plugin
@@ -37,7 +37,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-allpom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
diff --git a/buildsupport/goodies/pom.xml b/buildsupport/goodies/pom.xml
index 82a006c71995bd41c9944582af9670f6e7aa3047..a88985ab316c2b3e96613c51a6265d7dc4e9187f 100644
--- a/buildsupport/goodies/pom.xml
+++ b/buildsupport/goodies/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-goodies
diff --git a/buildsupport/groovy/pom.xml b/buildsupport/groovy/pom.xml
index 6451b5b4bed8ff926344d4e44c65989fcf34904d..de5e555b30a9a03d490392774aba5eaa58a62c28 100644
--- a/buildsupport/groovy/pom.xml
+++ b/buildsupport/groovy/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-groovy
diff --git a/buildsupport/guice/pom.xml b/buildsupport/guice/pom.xml
index b93505a653b2900f0ab0dd3d669334c8cef44fe1..0f2cc3802dd3e2095c83f653330ba27219cc017e 100644
--- a/buildsupport/guice/pom.xml
+++ b/buildsupport/guice/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-guice
diff --git a/buildsupport/httpclient/pom.xml b/buildsupport/httpclient/pom.xml
index 2de33633d6aca6cd3c085e3a2f43e146536a97e7..f70f051bf5a00939e62b6d100bf2ed4503f0f8fb 100644
--- a/buildsupport/httpclient/pom.xml
+++ b/buildsupport/httpclient/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-httpclient
diff --git a/buildsupport/internal/pom.xml b/buildsupport/internal/pom.xml
index b1267753a5130114ea07b1a5ec6411b573ef4a95..3a7be49bd90435757c0cf483df23fcb5fbd4d7bf 100644
--- a/buildsupport/internal/pom.xml
+++ b/buildsupport/internal/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-internal
diff --git a/buildsupport/jetty/pom.xml b/buildsupport/jetty/pom.xml
index c12698cebde581804916b2d3f9dcec6805c94385..053cc0a170788446debf0577dd1172a63ef0f4ae 100644
--- a/buildsupport/jetty/pom.xml
+++ b/buildsupport/jetty/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-jetty
diff --git a/buildsupport/jruby/pom.xml b/buildsupport/jruby/pom.xml
index 9ac4275b5fc6b968d07ef6227b0b1d61d5c7fec7..68ed0995225e125c835fa8b9d27d810247b3ac4f 100644
--- a/buildsupport/jruby/pom.xml
+++ b/buildsupport/jruby/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-jruby
diff --git a/buildsupport/logging/pom.xml b/buildsupport/logging/pom.xml
index e86eba2325b8322651c1c71dde01ba6b5fdb9f81..2cbd8d15cdd9cd0541885520aac7259ed0005785 100644
--- a/buildsupport/logging/pom.xml
+++ b/buildsupport/logging/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-logging
diff --git a/buildsupport/maven/pom.xml b/buildsupport/maven/pom.xml
index 4033d9fbc77b1773cf32b145df4f5eb00ef49deb..87e651d475518dc7c072393ecb6ec0369c675216 100644
--- a/buildsupport/maven/pom.xml
+++ b/buildsupport/maven/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-maven
diff --git a/buildsupport/metrics/pom.xml b/buildsupport/metrics/pom.xml
index 1d6db02785273c924f64edd555fa336e5d5c598c..3c4c193350b6f4278460a7d0ad416d0a0b226c0f 100644
--- a/buildsupport/metrics/pom.xml
+++ b/buildsupport/metrics/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-metrics
diff --git a/buildsupport/osgi/pom.xml b/buildsupport/osgi/pom.xml
index a8f09d7c2794795a75c7ec905943327e7800eb56..6d1de71c0734f19f6927df134ca1bb874241fda6 100644
--- a/buildsupport/osgi/pom.xml
+++ b/buildsupport/osgi/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-osgi
diff --git a/buildsupport/other/pom.xml b/buildsupport/other/pom.xml
index b206b287aca67ee4f8b60a31c10b9d928b2782bf..ecd6ae71d8873ec2ed7d4bd416d80c5cc0de81ed 100644
--- a/buildsupport/other/pom.xml
+++ b/buildsupport/other/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-other
diff --git a/buildsupport/pom.xml b/buildsupport/pom.xml
index 9ad5da578e04e905fc4c08a61bc9bd72a382455b..51727ffdb698ef6fe7484f7b3e1ef48d1765ceb2 100644
--- a/buildsupport/pom.xml
+++ b/buildsupport/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-parent
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.buildsupport
diff --git a/buildsupport/rest/pom.xml b/buildsupport/rest/pom.xml
index c64930ac13ba6532eb0869992bc9b038d1cc55bb..320f2d00af966c62520d2c71276d643cfa5ba5f3 100644
--- a/buildsupport/rest/pom.xml
+++ b/buildsupport/rest/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-rest
diff --git a/buildsupport/scripts/pom.xml b/buildsupport/scripts/pom.xml
index 8053db090bf7aeb770c57e39181d8cee3e874047..9de48bb83590bdb47aff0b4e5b141b152d83caf9 100644
--- a/buildsupport/scripts/pom.xml
+++ b/buildsupport/scripts/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-scripts
@@ -36,7 +36,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-allpom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
diff --git a/buildsupport/security/pom.xml b/buildsupport/security/pom.xml
index df356a9b9d63124fef4b1d0262740007bd81b82e..288e9370665a4491ed99da360dfc6fbc7eaddbd5 100644
--- a/buildsupport/security/pom.xml
+++ b/buildsupport/security/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-security
diff --git a/buildsupport/testing/pom.xml b/buildsupport/testing/pom.xml
index 46dc952ce6e32ad439cb72942d51c8bea6534f66..995a4991487050357db9e3fc74917fd51b9c54ee 100644
--- a/buildsupport/testing/pom.xml
+++ b/buildsupport/testing/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-testing
diff --git a/buildsupport/ui/pom.xml b/buildsupport/ui/pom.xml
index a7780bb7653bd6c9098024dbb396d6e6eb519e9f..e1e768d2b3f8149f2bf18560c110888940865cfb 100644
--- a/buildsupport/ui/pom.xml
+++ b/buildsupport/ui/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-buildsupport-ui
diff --git a/components/nexus-analytics-api/pom.xml b/components/nexus-analytics-api/pom.xml
index 7c452ad0115054172d5df059544a277750f92c55..1b2b96a9ffc4a3ecee8ac0230f07df63d0c86bc0 100644
--- a/components/nexus-analytics-api/pom.xml
+++ b/components/nexus-analytics-api/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-analytics-api
diff --git a/components/nexus-audit/pom.xml b/components/nexus-audit/pom.xml
index 89ab52a5383ca9eac90555258c510559b62bbf1a..e10530e6b13b698a779d2ce7ab6e501bf69992fe 100644
--- a/components/nexus-audit/pom.xml
+++ b/components/nexus-audit/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-audit
diff --git a/components/nexus-base/pom.xml b/components/nexus-base/pom.xml
index 604ea66f6a9b6a73898f86889f099865a7c81821..79b96670fdafcf15d3d51c3aa0f86d63fbc032e3 100644
--- a/components/nexus-base/pom.xml
+++ b/components/nexus-base/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-base
diff --git a/components/nexus-blobstore-api/pom.xml b/components/nexus-blobstore-api/pom.xml
index 1ff4694bc2c8787b80275eb37cf2f840f415899a..ac08635bfb67760cb91e6fd16322731f9f8395fa 100644
--- a/components/nexus-blobstore-api/pom.xml
+++ b/components/nexus-blobstore-api/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-blobstore-api
diff --git a/components/nexus-blobstore-file/pom.xml b/components/nexus-blobstore-file/pom.xml
index 8354485274a2c68d5ed967f12b6a5df6b138cb3f..ab9e4bc0f074a55b36dd832703df3e4080494f2b 100644
--- a/components/nexus-blobstore-file/pom.xml
+++ b/components/nexus-blobstore-file/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-blobstore-file
diff --git a/components/nexus-blobstore/pom.xml b/components/nexus-blobstore/pom.xml
index 1e387b136c675a5a806cefbf8091d3785a33863a..89d974b34d6e1d129df75fa75f13d53aa9e0dee4 100644
--- a/components/nexus-blobstore/pom.xml
+++ b/components/nexus-blobstore/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-blobstore
diff --git a/components/nexus-bootstrap/pom.xml b/components/nexus-bootstrap/pom.xml
index 1c7a644885ff9bdcb8e218fb17cb9a2b2e74b026..af37fd77ee16d247b83f63d5afc6043f7494af03 100644
--- a/components/nexus-bootstrap/pom.xml
+++ b/components/nexus-bootstrap/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-bootstrap
diff --git a/components/nexus-cache/pom.xml b/components/nexus-cache/pom.xml
index 3b5f06c93ae997b4561b4d0f74c745162c829239..6d12a2a2a8885c711b552b2e36ec07d738a47df6 100644
--- a/components/nexus-cache/pom.xml
+++ b/components/nexus-cache/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-cache
diff --git a/components/nexus-capability/pom.xml b/components/nexus-capability/pom.xml
index 1314f9d48c5e0952b3350269e39ecf08269d327b..d8b47019496b5fd386fbd05ea1d7bc72062a5090 100644
--- a/components/nexus-capability/pom.xml
+++ b/components/nexus-capability/pom.xml
@@ -21,7 +21,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-capability
diff --git a/components/nexus-commands/pom.xml b/components/nexus-commands/pom.xml
index ca231510a71e319790e8101e10b4dce96648f01f..37970b10662c0679fdc25ab467f429ea37a66589 100644
--- a/components/nexus-commands/pom.xml
+++ b/components/nexus-commands/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-commands
diff --git a/components/nexus-common/pom.xml b/components/nexus-common/pom.xml
index 1adba73a85518078747ab3771ce52d0793d38e12..25c60b982c329bb12723f939ffafcd8a3707980e 100644
--- a/components/nexus-common/pom.xml
+++ b/components/nexus-common/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-common
diff --git a/components/nexus-core/pom.xml b/components/nexus-core/pom.xml
index a5c2ea2701bee23088c9d03b9a4221f7d0351619..c63b27b1412d949fc669d8f8c0c3c92d1fcfbb8f 100644
--- a/components/nexus-core/pom.xml
+++ b/components/nexus-core/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-core
diff --git a/components/nexus-core/src/main/java/org/sonatype/nexus/internal/backup/DatabaseBackupTaskDescriptor.java b/components/nexus-core/src/main/java/org/sonatype/nexus/internal/backup/DatabaseBackupTaskDescriptor.java
index 4ba1fa4a7e019b28205bbfb3cc67ef74a0b53b20..b1254a1b26ae4a36ae1488b432f62e485e9bf13a 100644
--- a/components/nexus-core/src/main/java/org/sonatype/nexus/internal/backup/DatabaseBackupTaskDescriptor.java
+++ b/components/nexus-core/src/main/java/org/sonatype/nexus/internal/backup/DatabaseBackupTaskDescriptor.java
@@ -35,7 +35,7 @@ import static org.sonatype.nexus.formfields.FormField.MANDATORY;
public class DatabaseBackupTaskDescriptor
extends TaskDescriptorSupport
{
- public static final String MSG = "Admin - Export databases for backup";
+ public static final String MSG = "Export configuration & metadata for backup";
public static final String TYPE_ID = "db.backup";
diff --git a/components/nexus-core/src/main/java/org/sonatype/nexus/internal/script/ScriptTaskDescriptor.java b/components/nexus-core/src/main/java/org/sonatype/nexus/internal/script/ScriptTaskDescriptor.java
index aab13259907de50974efbf008f859fabf32bdaad..410458a9f759a8a338691cc821d9a2750435a8ee 100644
--- a/components/nexus-core/src/main/java/org/sonatype/nexus/internal/script/ScriptTaskDescriptor.java
+++ b/components/nexus-core/src/main/java/org/sonatype/nexus/internal/script/ScriptTaskDescriptor.java
@@ -43,7 +43,7 @@ public class ScriptTaskDescriptor
private interface Messages
extends MessageBundle
{
- @DefaultMessage("Admin - Execute script")
+ @DefaultMessage("Execute script")
String name();
@DefaultMessage("Language")
diff --git a/components/nexus-core/src/main/java/org/sonatype/nexus/internal/security/apikey/ApiKeyStoreImpl.java b/components/nexus-core/src/main/java/org/sonatype/nexus/internal/security/apikey/ApiKeyStoreImpl.java
index 6db3ea0bf361c3fc7b0c692f018c33afa8d1e9cf..a63c1769b232ca50340f947e3e8f6f5947a24baf 100644
--- a/components/nexus-core/src/main/java/org/sonatype/nexus/internal/security/apikey/ApiKeyStoreImpl.java
+++ b/components/nexus-core/src/main/java/org/sonatype/nexus/internal/security/apikey/ApiKeyStoreImpl.java
@@ -46,7 +46,6 @@ import static org.sonatype.nexus.common.app.ManagedLifecycle.Phase.SCHEMAS;
import static org.sonatype.nexus.common.stateguard.StateGuardLifecycleSupport.State.STARTED;
import static org.sonatype.nexus.orient.transaction.OrientTransactional.inTx;
import static org.sonatype.nexus.orient.transaction.OrientTransactional.inTxRetry;
-import static org.sonatype.nexus.scheduling.CancelableHelper.checkCancellation;
/**
* OrientDB impl of {@link ApiKeyStore}.
@@ -177,11 +176,9 @@ public class ApiKeyStoreImpl
@Override
@Guarded(by = STARTED)
public void purgeApiKeys() {
- checkCancellation();
inTxRetry(databaseInstance).run(db -> {
List delete = new ArrayList<>();
for (ApiKey entity : entityAdapter.browse(db)) {
- checkCancellation();
try {
principalsHelper.getUserStatus(entity.getPrincipals());
}
@@ -191,7 +188,6 @@ public class ApiKeyStoreImpl
}
}
for (ApiKey entity : delete) {
- checkCancellation();
entityAdapter.deleteEntity(db, entity);
}
});
diff --git a/components/nexus-core/src/main/java/org/sonatype/nexus/internal/security/apikey/PurgeApiKeysTask.java b/components/nexus-core/src/main/java/org/sonatype/nexus/internal/security/apikey/PurgeApiKeysTask.java
index 65f59f5dc87ffa922eec97149972e074648f6071..9d66608149f6cfc881a6c27c2de73b055038b7ff 100644
--- a/components/nexus-core/src/main/java/org/sonatype/nexus/internal/security/apikey/PurgeApiKeysTask.java
+++ b/components/nexus-core/src/main/java/org/sonatype/nexus/internal/security/apikey/PurgeApiKeysTask.java
@@ -15,7 +15,6 @@ package org.sonatype.nexus.internal.security.apikey;
import javax.inject.Inject;
import javax.inject.Named;
-import org.sonatype.nexus.scheduling.Cancelable;
import org.sonatype.nexus.scheduling.TaskSupport;
import org.sonatype.nexus.security.authc.apikey.ApiKeyStore;
@@ -30,7 +29,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
@Named
public class PurgeApiKeysTask
extends TaskSupport
- implements Cancelable
{
private final ApiKeyStore store;
@@ -47,6 +45,6 @@ public class PurgeApiKeysTask
@Override
public String getMessage() {
- return "Deleting orphaned API keys";
+ return "Purging orphaned API keys";
}
}
diff --git a/components/nexus-core/src/main/java/org/sonatype/nexus/internal/security/apikey/PurgeApiKeysTaskDescriptor.java b/components/nexus-core/src/main/java/org/sonatype/nexus/internal/security/apikey/PurgeApiKeysTaskDescriptor.java
index 10ad3496850bd6798bca7cd124b57df0f8a0939b..e1b2d2b518508b04a2526886127ab604c9147207 100644
--- a/components/nexus-core/src/main/java/org/sonatype/nexus/internal/security/apikey/PurgeApiKeysTaskDescriptor.java
+++ b/components/nexus-core/src/main/java/org/sonatype/nexus/internal/security/apikey/PurgeApiKeysTaskDescriptor.java
@@ -32,7 +32,7 @@ public class PurgeApiKeysTaskDescriptor
public PurgeApiKeysTaskDescriptor() {
super(TYPE_ID,
PurgeApiKeysTask.class,
- "Admin - Delete orphaned API keys",
+ "Purge orphaned API keys",
VISIBLE,
EXPOSED
);
diff --git a/components/nexus-core/src/test/java/org/sonatype/nexus/internal/security/apikey/ApiKeyStoreImplTest.groovy b/components/nexus-core/src/test/java/org/sonatype/nexus/internal/security/apikey/ApiKeyStoreImplTest.groovy
index 8050b47f113be23c3408b5951212025304789845..9fa780861db5bef09be378b58c085d920881e456 100644
--- a/components/nexus-core/src/test/java/org/sonatype/nexus/internal/security/apikey/ApiKeyStoreImplTest.groovy
+++ b/components/nexus-core/src/test/java/org/sonatype/nexus/internal/security/apikey/ApiKeyStoreImplTest.groovy
@@ -12,32 +12,25 @@
*/
package org.sonatype.nexus.internal.security.apikey
-import java.util.concurrent.atomic.AtomicBoolean
-
import org.sonatype.goodies.testsupport.TestSupport
import org.sonatype.nexus.crypto.internal.CryptoHelperImpl
import org.sonatype.nexus.crypto.internal.RandomBytesGeneratorImpl
import org.sonatype.nexus.orient.testsupport.DatabaseInstanceRule
-import org.sonatype.nexus.scheduling.CancelableHelper
-import org.sonatype.nexus.scheduling.TaskInterruptedException
import org.sonatype.nexus.security.UserPrincipalsHelper
-import org.sonatype.nexus.security.user.UserNotFoundException
-import org.sonatype.nexus.security.user.UserStatus
import com.google.common.collect.Maps
import org.apache.shiro.subject.PrincipalCollection
import org.apache.shiro.subject.SimplePrincipalCollection
+import org.hamcrest.MatcherAssert
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
-import org.mockito.Mock
-import static org.hamcrest.MatcherAssert.assertThat
+import static MatcherAssert.assertThat
import static org.hamcrest.Matchers.equalTo
import static org.hamcrest.Matchers.nullValue
-import static org.junit.Assert.fail
-import static org.mockito.Mockito.when
+import static org.mockito.Mockito.mock
/**
* Tests {@link ApiKeyStoreImpl}
@@ -45,35 +38,17 @@ import static org.mockito.Mockito.when
class ApiKeyStoreImplTest
extends TestSupport
{
- private static final String PRINCIPAL_A_NAME = 'name-a'
-
- private static final String PRINCIPAL_A_DOMAIN = 'foo'
-
- private static final String PRINCIPAL_B_NAME = 'name-b'
-
- private static final String PRINCIPAL_B_DOMAIN = 'bar'
-
- private static final UserStatus USER_STATUS = UserStatus.disabled
-
- private static final boolean CANCELLED = true
-
@Rule
public DatabaseInstanceRule database = DatabaseInstanceRule.inMemory('test')
- @Mock
- private UserPrincipalsHelper principalsHelper
-
- private AtomicBoolean cancelled = new AtomicBoolean(!CANCELLED)
-
private ApiKeyStoreImpl underTest
@Before
void setup() {
- CancelableHelper.set(cancelled)
underTest = new ApiKeyStoreImpl(
database.instanceProvider,
new ApiKeyEntityAdapter(ClassLoader.getSystemClassLoader()),
- principalsHelper,
+ mock(UserPrincipalsHelper.class),
Maps.newHashMap(),
new DefaultApiKeyFactory(new RandomBytesGeneratorImpl(new CryptoHelperImpl()))
)
@@ -86,7 +61,6 @@ class ApiKeyStoreImplTest
underTest.stop()
underTest = null
}
- CancelableHelper.remove()
}
@Test
@@ -172,47 +146,6 @@ class ApiKeyStoreImplTest
assertThat(key2, equalTo(key));
}
- @Test
- void 'Can purge orphaned API keys'() {
- PrincipalCollection principalA = makePrincipals(PRINCIPAL_A_NAME)
- PrincipalCollection principalB = makePrincipals(PRINCIPAL_B_NAME)
- char[] apiKeyForPrincipalA = underTest.createApiKey(PRINCIPAL_A_DOMAIN, principalA)
- underTest.createApiKey(PRINCIPAL_B_NAME, principalB)
- when(principalsHelper.getUserStatus(principalA)).thenReturn(USER_STATUS)
- when(principalsHelper.getUserStatus(principalB)).
- thenThrow(new UserNotFoundException(principalB.getPrimaryPrincipal()))
-
- underTest.purgeApiKeys()
-
- //Verify that api keys that belong to non-existent users are purged
- assertThat(underTest.getApiKey(PRINCIPAL_A_DOMAIN, principalA), equalTo(apiKeyForPrincipalA))
- assertThat(underTest.getApiKey(PRINCIPAL_B_DOMAIN, principalB), nullValue())
- }
-
- @Test
- void 'Purge orphaned API keys is cancelable'() {
- PrincipalCollection principalA = makePrincipals(PRINCIPAL_A_NAME)
- PrincipalCollection principalB = makePrincipals(PRINCIPAL_B_NAME)
- char[] apiKeyForPrincipalA = underTest.createApiKey(PRINCIPAL_A_DOMAIN, principalA)
- char[] apiKeyForPrincipalB = underTest.createApiKey(PRINCIPAL_B_DOMAIN, principalB)
- when(principalsHelper.getUserStatus(principalA)).
- thenThrow(new UserNotFoundException(principalA.getPrimaryPrincipal()))
- when(principalsHelper.getUserStatus(principalB)).
- thenThrow(new UserNotFoundException(principalB.getPrimaryPrincipal()))
- cancelled.set(CANCELLED)
-
- try {
- underTest.purgeApiKeys()
- fail("Expected exception to be thrown")
- }
- catch (TaskInterruptedException expected) {
- }
-
- //Verify that no api keys were purged even though they belong to non-existent users
- assertThat(underTest.getApiKey(PRINCIPAL_A_DOMAIN, principalA), equalTo(apiKeyForPrincipalA))
- assertThat(underTest.getApiKey(PRINCIPAL_B_DOMAIN, principalB), equalTo(apiKeyForPrincipalB))
- }
-
private PrincipalCollection makePrincipals(String name) {
return new SimplePrincipalCollection(name, "foo")
}
diff --git a/components/nexus-crypto/pom.xml b/components/nexus-crypto/pom.xml
index 858149ce2a3aa7c173e23531b6111720f8040c52..e20839d8167fefa4faea8cb8a877a1ce8ab89d7d 100644
--- a/components/nexus-crypto/pom.xml
+++ b/components/nexus-crypto/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-crypto
diff --git a/components/nexus-elasticsearch/pom.xml b/components/nexus-elasticsearch/pom.xml
index d34031a4a0f2cba04c7a67eb66fe1f3f9b374435..1f2a0714813404806d57181a857d4e9e3d27d02b 100644
--- a/components/nexus-elasticsearch/pom.xml
+++ b/components/nexus-elasticsearch/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-elasticsearch
diff --git a/components/nexus-email/pom.xml b/components/nexus-email/pom.xml
index df4441965ac40e795cf3ea6b8dc45f017a8b04dc..bd858e1f010b1a65f335bc8d5551bc62de19f290 100644
--- a/components/nexus-email/pom.xml
+++ b/components/nexus-email/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-email
diff --git a/components/nexus-extdirect/pom.xml b/components/nexus-extdirect/pom.xml
index 8d6f6ab7e340bb8961d5073f8e5d43cdea0427e9..d4dc6312dd4404653adaa4b550160106593e3e4b 100644
--- a/components/nexus-extdirect/pom.xml
+++ b/components/nexus-extdirect/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-extdirect
diff --git a/components/nexus-extender/pom.xml b/components/nexus-extender/pom.xml
index 9231e7e84db34f4b5bdd18c699a7ad01cd605b8f..5f4abbe7c27c9a1f7dd1985a483d7ca4cb4533a3 100644
--- a/components/nexus-extender/pom.xml
+++ b/components/nexus-extender/pom.xml
@@ -19,7 +19,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-extender
diff --git a/components/nexus-formfields/pom.xml b/components/nexus-formfields/pom.xml
index b6043f7ddf471ed8f3f9bfdb851d706127105a4c..14ec43f52749e78628abd38b69c0a778b07ba37a 100644
--- a/components/nexus-formfields/pom.xml
+++ b/components/nexus-formfields/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-formfields
diff --git a/components/nexus-guice-servlet/pom.xml b/components/nexus-guice-servlet/pom.xml
index 8ba77896d0ae80769009bca395051aadeeb3d97b..a8e64195a05da65d0276e31a583d841371149f48 100644
--- a/components/nexus-guice-servlet/pom.xml
+++ b/components/nexus-guice-servlet/pom.xml
@@ -19,7 +19,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-guice-servlet
diff --git a/components/nexus-httpclient/pom.xml b/components/nexus-httpclient/pom.xml
index 13c6a5406404a5d049ba6e621af3daf02dbee750..9fe9ee5b8b1401d434cde06be83fc838e43d3c7b 100644
--- a/components/nexus-httpclient/pom.xml
+++ b/components/nexus-httpclient/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-httpclient
diff --git a/components/nexus-jmx/pom.xml b/components/nexus-jmx/pom.xml
index 03fd6a5d41f2ea0da8908efb20c36c1a1caca05c..f12ce0deb7ba8975f595276e5e410fb93836c744 100644
--- a/components/nexus-jmx/pom.xml
+++ b/components/nexus-jmx/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-jmx
diff --git a/components/nexus-main/pom.xml b/components/nexus-main/pom.xml
index d75d24839859f2117a5770c378ccb2d9ce55c3c4..b059f468d9c2f05c4211eee7e8b46576fb7612c7 100644
--- a/components/nexus-main/pom.xml
+++ b/components/nexus-main/pom.xml
@@ -21,7 +21,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-main
diff --git a/components/nexus-mime/pom.xml b/components/nexus-mime/pom.xml
index a8cd3c4984b563dc331ca2d0ee1316c3e6562b9d..27652b362e7e9591a366a78184a613c9d66d95c9 100644
--- a/components/nexus-mime/pom.xml
+++ b/components/nexus-mime/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-mime
diff --git a/components/nexus-orient-console/pom.xml b/components/nexus-orient-console/pom.xml
index b6efc4808fdfda3e5ef0baed72715f5c90cc4ece..2411237ab467148f421d87e57cce84c8accef50e 100644
--- a/components/nexus-orient-console/pom.xml
+++ b/components/nexus-orient-console/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-orient-console
diff --git a/components/nexus-orient/pom.xml b/components/nexus-orient/pom.xml
index 8044e35c1ae7170f2965e1255271b4eada196fda..48683880a46e9ca42aabbe85853d0f2ce99d6a1b 100644
--- a/components/nexus-orient/pom.xml
+++ b/components/nexus-orient/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-orient
diff --git a/components/nexus-oss-edition/pom.xml b/components/nexus-oss-edition/pom.xml
index d6bdfa79bae1f326eaa0546e4a1dd0f12db430f7..4c134f96f3875fca6ce8443b2154a95b3bfea81f 100644
--- a/components/nexus-oss-edition/pom.xml
+++ b/components/nexus-oss-edition/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-oss-edition
diff --git a/components/nexus-pax-exam/pom.xml b/components/nexus-pax-exam/pom.xml
index 501b8d2691b5f78ea71a84b91fd017584ecd8e87..f10c49c15966c5805ae5d51088e5997b32103fa8 100644
--- a/components/nexus-pax-exam/pom.xml
+++ b/components/nexus-pax-exam/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-pax-exam
diff --git a/components/nexus-pax-logging/pom.xml b/components/nexus-pax-logging/pom.xml
index c53de9f23730282c356e2069f8c0d223af29c3fa..eb75be0f5a60b029a495144d907d3609480ca818 100644
--- a/components/nexus-pax-logging/pom.xml
+++ b/components/nexus-pax-logging/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-pax-logging
diff --git a/components/nexus-plugin-api/pom.xml b/components/nexus-plugin-api/pom.xml
index 92a8c9a8f5ff96974e9fec084e4ae4507a1bf00b..b26b79d5ad212c996fdf3ecf74ca32316bc1d86f 100644
--- a/components/nexus-plugin-api/pom.xml
+++ b/components/nexus-plugin-api/pom.xml
@@ -19,7 +19,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-plugin-api
diff --git a/components/nexus-quartz/pom.xml b/components/nexus-quartz/pom.xml
index 08fb27133d7ca012234139999d3aafbcd297562e..ea28810cee239a9cfbfa114ed60036f412b4c432 100644
--- a/components/nexus-quartz/pom.xml
+++ b/components/nexus-quartz/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-quartz
diff --git a/components/nexus-rapture/pom.xml b/components/nexus-rapture/pom.xml
index 4cd08228e0401ae51c13ea6a3750e562af7bc40b..b4a99531e09fec92f0b265b2d9e5fd92a075db09 100644
--- a/components/nexus-rapture/pom.xml
+++ b/components/nexus-rapture/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-rapture
diff --git a/components/nexus-repository/pom.xml b/components/nexus-repository/pom.xml
index ae2ef24017433a73324cfdfb71ee5a13b29b79de..a4a6d23384aaf6b430ce2703eb390085be56abfa 100644
--- a/components/nexus-repository/pom.xml
+++ b/components/nexus-repository/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-repository
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/browse/internal/RebuildBrowseNodesTaskDescriptor.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/browse/internal/RebuildBrowseNodesTaskDescriptor.java
index e7f2af7b5784cd923a0632d33a6210abd372e9e8..f4f89da2f5706ab7df7b8ccb47f75fd53dcf874d 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/browse/internal/RebuildBrowseNodesTaskDescriptor.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/browse/internal/RebuildBrowseNodesTaskDescriptor.java
@@ -38,7 +38,7 @@ public class RebuildBrowseNodesTaskDescriptor
@Inject
public RebuildBrowseNodesTaskDescriptor(final NodeAccess nodeAccess, BrowseNodeConfiguration configuration) {
- super(TYPE_ID, RebuildBrowseNodesTask.class, "Repair - Rebuild repository browse",
+ super(TYPE_ID, RebuildBrowseNodesTask.class, "Rebuild repository browse tree",
configuration.isEnabled() ? VISIBLE : NOT_VISIBLE, configuration.isEnabled() ? EXPOSED : NOT_EXPOSED,
new RepositoryCombobox(REPOSITORY_NAME_FIELD_ID, "Repository", "Select the repository to rebuild browse tree",
true).excludingAnyOfTypes(GroupType.NAME).includeAnEntryForAllRepositories(),
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/purge/PurgeUnusedTaskDescriptor.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/purge/PurgeUnusedTaskDescriptor.java
index 96ddc9bd26d70eaa31163a54af7781ad4f890ee4..4f22e7dbf027b9eaa3e2447bf9b56bf39a3b1e0f 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/purge/PurgeUnusedTaskDescriptor.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/purge/PurgeUnusedTaskDescriptor.java
@@ -33,7 +33,7 @@ import static org.sonatype.nexus.repository.purge.PurgeUnusedTask.REPOSITORY_NAM
public class PurgeUnusedTaskDescriptor
extends TaskDescriptorSupport
{
- public static final String TASK_NAME = "Repository - Delete unused components";
+ public static final String TASK_NAME = "Purge unused components and assets";
public static final String TYPE_ID = "repository.purge-unused";
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/api/ComponentResponseUtils.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/api/ComponentResponseUtils.java
deleted file mode 100644
index 2ca23372c48c6b79a37da21120468df8e44df5f6..0000000000000000000000000000000000000000
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/api/ComponentResponseUtils.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Sonatype Nexus (TM) Open Source Version
- * Copyright (c) 2008-present Sonatype, Inc.
- * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
- *
- * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
- * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
- *
- * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
- * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
- * Eclipse Foundation. All other trademarks are the property of their respective owners.
- */
-package org.sonatype.nexus.repository.rest.api;
-
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-
-import org.sonatype.nexus.repository.storage.Component;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
-
-/**
- * Utils for working with {@link Component} responses in the REST API.
- *
- * @since 3.next
- */
-public class ComponentResponseUtils
-{
- private static final String NAME = "name";
-
- private static final String GROUP = "group";
-
- private static final String VERSION = "version";
-
- private ComponentResponseUtils() {
- // empty
- }
-
- /**
- * Create a simple map to use in a {@link org.sonatype.nexus.rest.SimpleApiResponse} from the given {@link Component}.
- *
- * @param component the {@link Component} to produce the map from
- * @return Map of component attributes. Will always contain the name, and optionally the group and version if they exist.
- */
- public static Map mapFor(Component component) {
- Builder builder = ImmutableMap.builder().put(NAME, component.name());
- maybePut(builder, component, Component::group, GROUP);
- maybePut(builder, component, Component::version, VERSION);
- return builder.build();
- }
-
- public static void maybePut(final Builder builder,
- final T t,
- final Function f,
- final String key)
- {
- Optional.of(t).map(f).ifPresent(v -> builder.put(key, v));
- }
-}
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/ComponentUploadParameterContributor.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/ComponentUploadParameterContributor.java
index 15c4debce11639cf95864d564c950bf2ce55f906..4ce193fba5752084a5fe9ae7468c877070c52c12 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/ComponentUploadParameterContributor.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/ComponentUploadParameterContributor.java
@@ -26,7 +26,6 @@ import org.sonatype.nexus.repository.upload.UploadManager;
import org.sonatype.nexus.swagger.ParameterContributor;
import com.google.common.collect.ImmutableList;
-import io.swagger.models.HttpMethod;
import io.swagger.models.parameters.FormParameter;
import static io.swagger.models.HttpMethod.POST;
@@ -39,13 +38,11 @@ import static io.swagger.models.HttpMethod.POST;
public class ComponentUploadParameterContributor
extends ParameterContributor
{
- private static final List HTTP_METHODS = ImmutableList.of(POST);
-
private static final List PATHS = ImmutableList.of(ComponentsResource.RESOURCE_URI);
@Inject
public ComponentUploadParameterContributor(final UploadManager uploadManager) {
- super(HTTP_METHODS, PATHS, transformUploadDefinitions(uploadManager.getAvailableDefinitions()));
+ super(POST, PATHS, transformUploadDefinitions(uploadManager.getAvailableDefinitions()));
}
private static Collection transformUploadDefinitions(final Collection uploadDefinitions) {
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/SearchParameterContributor.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/SearchParameterContributor.java
index 30a673700eb24c9ce8e65f674d61bf60e1cbcb91..019947e11dc3366159b739ef801cafe3d0219443 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/SearchParameterContributor.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/SearchParameterContributor.java
@@ -26,7 +26,6 @@ import org.sonatype.nexus.repository.rest.internal.resources.SearchResource;
import org.sonatype.nexus.swagger.ParameterContributor;
import com.google.common.collect.ImmutableList;
-import io.swagger.models.HttpMethod;
import io.swagger.models.parameters.QueryParameter;
import static io.swagger.models.HttpMethod.GET;
@@ -40,8 +39,6 @@ import static java.util.stream.Collectors.toList;
public class SearchParameterContributor
extends ParameterContributor
{
- private static final List HTTP_METHODS = ImmutableList.of(GET);
-
private static final List PATHS = ImmutableList.of(
SearchResource.RESOURCE_URI,
SearchResource.RESOURCE_URI + SearchResource.SEARCH_ASSET_URI,
@@ -50,7 +47,7 @@ public class SearchParameterContributor
@Inject
public SearchParameterContributor(final SearchMappingsService searchMappings) {
- super(HTTP_METHODS, PATHS, transformMappings(searchMappings.getAllMappings()));
+ super(GET, PATHS, transformMappings(searchMappings.getAllMappings()));
}
private static Collection transformMappings(final Iterable searchMappings) { // NOSONAR
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoriesResource.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoriesResource.java
deleted file mode 100644
index ba62728a147da482ec282b0f2c5d764f4a6d8074..0000000000000000000000000000000000000000
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoriesResource.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Sonatype Nexus (TM) Open Source Version
- * Copyright (c) 2008-present Sonatype, Inc.
- * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
- *
- * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
- * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
- *
- * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
- * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
- * Eclipse Foundation. All other trademarks are the property of their respective owners.
- */
-package org.sonatype.nexus.repository.rest.internal.resources;
-
-import java.util.List;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-
-import org.sonatype.nexus.repository.rest.api.RepositoryXO;
-import org.sonatype.nexus.repository.rest.internal.resources.doc.RepositoriesResourceDoc;
-import org.sonatype.nexus.rest.Resource;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.stream.Collectors.toList;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static org.sonatype.nexus.repository.rest.internal.resources.RepositoriesResource.RESOURCE_URI;
-import static org.sonatype.nexus.rest.APIConstants.BETA_API_PREFIX;
-
-/**
- * @since 3.next
- */
-@Named
-@Singleton
-@Path(RESOURCE_URI)
-@Produces(APPLICATION_JSON)
-@Consumes(APPLICATION_JSON)
-public class RepositoriesResource
- implements Resource, RepositoriesResourceDoc
-{
- public static final String RESOURCE_URI = BETA_API_PREFIX + "/repositories";
-
- private final RepositoryManagerRESTAdapter repositoryManagerRESTAdapter;
-
- @Inject
- public RepositoriesResource(final RepositoryManagerRESTAdapter repositoryManagerRESTAdapter) {
- this.repositoryManagerRESTAdapter = checkNotNull(repositoryManagerRESTAdapter);
- }
-
- @GET
- public List getRepositories() {
- return repositoryManagerRESTAdapter.getRepositories()
- .stream()
- .map(RepositoryXO::fromRepository)
- .collect(toList());
- }
-}
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoryManagerRESTAdapter.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoryManagerRESTAdapter.java
index 55079005a077d29a3c37c0c7eb9bead05e65e74a..85f13278e4d6e575db7aeea708ff26f2280fa017 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoryManagerRESTAdapter.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoryManagerRESTAdapter.java
@@ -12,8 +12,6 @@
*/
package org.sonatype.nexus.repository.rest.internal.resources;
-import java.util.List;
-
import org.sonatype.nexus.repository.Repository;
/**
@@ -31,9 +29,4 @@ public interface RepositoryManagerRESTAdapter
* supplied id exists.
*/
Repository getRepository(String repositoryId);
-
- /**
- * Retrieve all repositories that the user access to.
- */
- List getRepositories();
}
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoryManagerRESTAdapterImpl.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoryManagerRESTAdapterImpl.java
index 063a3603cc64565d1e985c44a0f08c1577065dce..164ae02f402e54718cf90ce3cade7561a34eed2b 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoryManagerRESTAdapterImpl.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoryManagerRESTAdapterImpl.java
@@ -12,9 +12,6 @@
*/
package org.sonatype.nexus.repository.rest.internal.resources;
-import java.util.List;
-import java.util.stream.Collectors;
-
import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.NotFoundException;
@@ -27,8 +24,6 @@ import org.sonatype.nexus.repository.security.RepositoryViewPermission;
import org.sonatype.nexus.security.SecurityHelper;
import org.sonatype.nexus.selector.SelectorManager;
-import com.google.common.collect.Streams;
-
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.Collections.singletonList;
import static java.util.Optional.ofNullable;
@@ -84,13 +79,6 @@ public class RepositoryManagerRESTAdapterImpl
}
}
- @Override
- public List getRepositories() {
- return Streams.stream(repositoryManager.browse())
- .filter(this::userCanBrowseRepository)
- .collect(Collectors.toList());
- }
-
private boolean userCanViewRepository(final Repository repository) {
return userHasReadPermission(repository) || userHasAnyContentSelectorAccess(repository);
}
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/search/RebuildIndexTask.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/search/RebuildIndexTask.java
index bad273347952628139b486a9ba40ecfc85c55c7e..7d5aa8db738ef82295517e399f14edf31fd3627c 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/search/RebuildIndexTask.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/search/RebuildIndexTask.java
@@ -39,7 +39,7 @@ public class RebuildIndexTask
@Override
public String getMessage() {
- return "Rebuilding search index of " + getRepositoryField();
+ return "Rebuilding index of " + getRepositoryField();
}
}
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/search/RebuildIndexTaskDescriptor.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/search/RebuildIndexTaskDescriptor.java
index 5ea114a04360219b047a1201f819db76e15ab167..f2bf54c2bbab209de7d5c90e7b96406dcb59f712 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/search/RebuildIndexTaskDescriptor.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/search/RebuildIndexTaskDescriptor.java
@@ -38,7 +38,7 @@ public class RebuildIndexTaskDescriptor
public RebuildIndexTaskDescriptor(final NodeAccess nodeAccess) {
super(TYPE_ID,
RebuildIndexTask.class,
- "Repair - Rebuild repository search",
+ "Rebuild repository index",
VISIBLE,
EXPOSED,
new RepositoryCombobox(
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/ComponentMaintenance.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/ComponentMaintenance.java
index 1b39a6cc4b3d7b64a066ee9145f007476809bf93..59e0799d24b0495a0cd65ace7cbf9612cd15e76f 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/ComponentMaintenance.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/ComponentMaintenance.java
@@ -29,28 +29,8 @@ public interface ComponentMaintenance
*/
void deleteComponent(EntityId componentId);
- /**
- * Deletes a component and maybe the associated blobs.
- *
- * @param componentId entity id of the component to delete
- * @param deleteBlobs should blob deletion be requested
- *
- * @since 3.next
- */
- void deleteComponent(EntityId componentId, boolean deleteBlobs);
-
/**
* Deletes an asset from storage.
*/
void deleteAsset(EntityId assetId);
-
- /**
- * Deletes an asset and maybe the associated blob.
- *
- * @param assetId entity id of the asset to delete
- * @param deleteBlob should blob deletion be requested
- *
- * @since 3.next
- */
- void deleteAsset(EntityId assetId, boolean deleteBlob);
}
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/DefaultComponentMaintenanceImpl.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/DefaultComponentMaintenanceImpl.java
index d1fa38cf23989cc0f1e1d23220f383ab06e5fc53..bca4881c70c6fd6299adba447b524a5ae1880000 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/DefaultComponentMaintenanceImpl.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/DefaultComponentMaintenanceImpl.java
@@ -39,18 +39,10 @@ public class DefaultComponentMaintenanceImpl
*/
@Override
public void deleteComponent(final EntityId componentId) {
- deleteComponent(componentId, true);
- }
-
- /**
- * Deletes the component directly, with no additional bookkeeping.
- */
- @Override
- public void deleteComponent(final EntityId componentId, final boolean deleteBlobs) {
checkNotNull(componentId);
UnitOfWork.begin(getRepository().facet(StorageFacet.class).txSupplier());
try {
- deleteComponentTx(componentId, deleteBlobs);
+ deleteComponentTx(componentId);
}
finally {
UnitOfWork.end();
@@ -58,14 +50,14 @@ public class DefaultComponentMaintenanceImpl
}
@TransactionalDeleteBlob
- protected void deleteComponentTx(final EntityId componentId, final boolean deleteBlobs) {
+ protected void deleteComponentTx(final EntityId componentId) {
StorageTx tx = UnitOfWork.currentTx();
Component component = tx.findComponentInBucket(componentId, tx.findBucket(getRepository()));
if (component == null) {
return;
}
log.info("Deleting component: {}", component);
- tx.deleteComponent(component, deleteBlobs);
+ tx.deleteComponent(component);
}
/**
@@ -74,16 +66,10 @@ public class DefaultComponentMaintenanceImpl
@Override
@Guarded(by = STARTED)
public void deleteAsset(final EntityId assetId) {
- deleteAsset(assetId, true);
- }
-
- @Override
- @Guarded(by = STARTED)
- public void deleteAsset(final EntityId assetId, final boolean deleteBlob) {
checkNotNull(assetId);
UnitOfWork.begin(getRepository().facet(StorageFacet.class).txSupplier());
try {
- deleteAssetTx(assetId, deleteBlob);
+ deleteAssetTx(assetId);
}
finally {
UnitOfWork.end();
@@ -91,13 +77,13 @@ public class DefaultComponentMaintenanceImpl
}
@TransactionalDeleteBlob
- protected void deleteAssetTx(final EntityId assetId, final boolean deleteBlob) {
+ protected void deleteAssetTx(final EntityId assetId) {
StorageTx tx = UnitOfWork.currentTx();
Asset asset = tx.findAsset(assetId, tx.findBucket(getRepository()));
if (asset == null) {
return;
}
log.info("Deleting asset: {}", asset);
- tx.deleteAsset(asset, deleteBlob);
+ tx.deleteAsset(asset);
}
}
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/RebuildAssetUploadMetadataTaskDescriptor.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/RebuildAssetUploadMetadataTaskDescriptor.java
index 1c9dcab79dcb0220db864416837ad8fc1cc3f627..0e1be50be6d8913e4968925b8451cca9f3687642 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/RebuildAssetUploadMetadataTaskDescriptor.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/RebuildAssetUploadMetadataTaskDescriptor.java
@@ -37,7 +37,7 @@ public class RebuildAssetUploadMetadataTaskDescriptor
super(
TYPE_ID,
RebuildAssetUploadMetadataTask.class,
- "Repair - Reconcile date metadata from blob store",
+ "Rebuild asset upload metadata",
configuration.isEnabled() ? VISIBLE : NOT_VISIBLE,
configuration.isEnabled() ? EXPOSED : NOT_EXPOSED,
nodeAccess.isClustered() ? newLimitNodeFormField() : null);
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/SingleAssetComponentMaintenance.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/SingleAssetComponentMaintenance.java
index 97ad7b7f2547ddd2a7df05245476dad6935f5036..4702f6620fdce8e2d10332cb1303bbee33692116 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/SingleAssetComponentMaintenance.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/SingleAssetComponentMaintenance.java
@@ -32,7 +32,7 @@ public class SingleAssetComponentMaintenance
* Deletes both the asset and its component.
*/
@TransactionalDeleteBlob
- protected void deleteAssetTx(final EntityId assetId, final boolean deleteBlob) {
+ protected void deleteAssetTx(final EntityId assetId) {
StorageTx tx = UnitOfWork.currentTx();
final Asset asset = tx.findAsset(assetId, tx.findBucket(getRepository()));
if (asset == null) {
@@ -41,11 +41,11 @@ public class SingleAssetComponentMaintenance
final EntityId componentId = asset.componentId();
if (componentId == null) {
// Assets without components should be deleted on their own
- super.deleteAssetTx(assetId, deleteBlob);
+ super.deleteAssetTx(assetId);
}
else {
// Otherwise, delete the component, which in turn cascades down to the asset
- deleteComponentTx(componentId, deleteBlob);
+ deleteComponentTx(componentId);
}
}
}
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/StorageTx.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/StorageTx.java
index 92f288d3b5dc5b1244b965e24fcc4ea26077ec9d..83eee92d515fa97507cbe47380c16fc81f7a5660 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/StorageTx.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/StorageTx.java
@@ -332,31 +332,11 @@ public interface StorageTx
*/
void deleteComponent(Component component);
- /**
- * Deletes an existing component, all constituent assets, and maybe requests deletion of the asset blobs.
- *
- * @param component to be deleted
- * @param deleteBlobs should asset blob deletion be requested
- *
- * @since 3.next
- */
- void deleteComponent(Component component, boolean deleteBlobs);
-
/**
* Deletes an existing asset and requests the blob to be deleted.
*/
void deleteAsset(Asset asset);
- /**
- * Deletes an existing asset and maybe requests the blob be deleted.
- *
- * @param asset to be deleted
- * @param deleteBlob should blob deletion be requested
- *
- * @since 3.next
- */
- void deleteAsset(Asset asset, boolean deleteBlob);
-
/**
* Creates a new Blob and updates the given asset with a reference to it, hash metadata, size, and content type.
* The old blob, if any, will be deleted.
diff --git a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/StorageTxImpl.java b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/StorageTxImpl.java
index f8119d58327ff2c232ee1a6a6c71ff3f0eb448c5..0891515fc16b02b8ee6dd96d4c2d2b1d2db39e56 100644
--- a/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/StorageTxImpl.java
+++ b/components/nexus-repository/src/main/java/org/sonatype/nexus/repository/storage/StorageTxImpl.java
@@ -530,48 +530,31 @@ public class StorageTxImpl
@Override
@Guarded(by = ACTIVE)
- public void deleteComponent(final Component component) {
+ public void deleteComponent(Component component) {
deleteComponent(component, true);
}
- @Override
- @Guarded(by = ACTIVE)
- public void deleteComponent(final Component component, final boolean deleteBlobs) {
- deleteComponent(component, true, deleteBlobs);
- }
-
- private void deleteComponent(final Component component, final boolean checkWritePolicy, final boolean deleteBlobs) {
+ private void deleteComponent(final Component component, final boolean checkWritePolicy) {
checkNotNull(component);
for (Asset asset : browseAssets(component)) {
- deleteAsset(asset, checkWritePolicy ? writePolicySelector.select(asset, writePolicy) : null, deleteBlobs);
+ deleteAsset(asset, checkWritePolicy ? writePolicySelector.select(asset, writePolicy) : null);
}
componentEntityAdapter.deleteEntity(db, component);
}
@Override
@Guarded(by = ACTIVE)
- public void deleteAsset(final Asset asset) {
- deleteAsset(asset, true);
- }
-
- @Override
- @Guarded(by = ACTIVE)
- public void deleteAsset(final Asset asset, final boolean deleteBlob) {
- deleteAsset(asset, writePolicySelector.select(asset, writePolicy), deleteBlob);
+ public void deleteAsset(Asset asset) {
+ deleteAsset(asset, writePolicySelector.select(asset, writePolicy));
}
- private void deleteAsset(final Asset asset,
- @Nullable final WritePolicy effectiveWritePolicy,
- final boolean deleteBlob)
- {
+ private void deleteAsset(final Asset asset, @Nullable final WritePolicy effectiveWritePolicy) {
checkNotNull(asset);
- if (deleteBlob) {
- BlobRef blobRef = asset.blobRef();
- if (blobRef != null) {
- deleteBlob(blobRef, effectiveWritePolicy, format("Deleting asset %s", EntityHelper.id(asset)));
- }
+ BlobRef blobRef = asset.blobRef();
+ if (blobRef != null) {
+ deleteBlob(blobRef, effectiveWritePolicy, format("Deleting asset %s", EntityHelper.id(asset)));
}
assetEntityAdapter.deleteEntity(db, asset);
}
diff --git a/components/nexus-repository/src/test/java/org/sonatype/nexus/repository/rest/api/ComponentResponseUtilsTest.groovy b/components/nexus-repository/src/test/java/org/sonatype/nexus/repository/rest/api/ComponentResponseUtilsTest.groovy
deleted file mode 100644
index a5bdc31f8552d267854951902afb23cb8c337f32..0000000000000000000000000000000000000000
--- a/components/nexus-repository/src/test/java/org/sonatype/nexus/repository/rest/api/ComponentResponseUtilsTest.groovy
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Sonatype Nexus (TM) Open Source Version
- * Copyright (c) 2008-present Sonatype, Inc.
- * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
- *
- * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
- * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
- *
- * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
- * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
- * Eclipse Foundation. All other trademarks are the property of their respective owners.
- */
-package org.sonatype.nexus.repository.rest.api
-
-import org.sonatype.nexus.repository.storage.DefaultComponent
-
-import spock.lang.Specification
-
-class ComponentResponseUtilsTest
- extends Specification
-{
- def "a component with only a name has only that name in the return map"() {
- given: 'component only has name'
- def component = new DefaultComponent()
- component.name("name")
-
- when: 'method called'
- def result = ComponentResponseUtils.mapFor(component)
-
- then: 'map will only contain name'
- result.size() == 1
- result.containsKey("name")
- }
-
- def "a component with all attributes has all three entries in map"() {
- given: 'component is fully populated'
- def component = new DefaultComponent()
- component.name("name")
- component.group("group")
- component.version("1.0.0")
-
- when: 'method called'
- def result = ComponentResponseUtils.mapFor(component)
-
- then: 'map will contain all three entries'
- result.size() == 3
- result.containsKey("name")
- result.containsKey("group")
- result.containsKey("version")
- }
-}
diff --git a/components/nexus-repository/src/test/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoriesResourceTest.groovy b/components/nexus-repository/src/test/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoriesResourceTest.groovy
deleted file mode 100644
index 335a3c437f585f5b9748928a7e6291eb031df17f..0000000000000000000000000000000000000000
--- a/components/nexus-repository/src/test/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoriesResourceTest.groovy
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Sonatype Nexus (TM) Open Source Version
- * Copyright (c) 2008-present Sonatype, Inc.
- * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
- *
- * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
- * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
- *
- * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
- * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
- * Eclipse Foundation. All other trademarks are the property of their respective owners.
- */
-package org.sonatype.nexus.repository.rest.internal.resources
-
-import org.sonatype.goodies.testsupport.TestSupport
-import org.sonatype.nexus.repository.Format
-import org.sonatype.nexus.repository.Repository
-import org.sonatype.nexus.repository.Type
-import org.sonatype.nexus.repository.rest.api.RepositoryXO
-import org.sonatype.nexus.repository.types.HostedType
-import org.sonatype.nexus.repository.types.ProxyType
-
-import org.junit.Before
-import org.junit.Test
-import org.mockito.Mock
-
-import static org.hamcrest.Matchers.is
-import static org.junit.Assert.assertThat
-import static org.mockito.Mockito.mock
-import static org.mockito.Mockito.when
-
-class RepositoriesResourceTest
- extends TestSupport
-{
- private static final String REPOSITORY_1_NAME = 'repoOneName'
-
- private static final Format REPOSITORY_1_FORMAT = new Format('repoOneFormat') {}
-
- private static final Type REPOSITORY_1_TYPE = new ProxyType()
-
- private static final String REPOSITORY_1_URL = 'repoOneUrl'
-
- private static final RepositoryXO REPOSITORY_XO_1 =
- new RepositoryXO(name: REPOSITORY_1_NAME, format: REPOSITORY_1_FORMAT.getValue(),
- type: REPOSITORY_1_TYPE.getValue(), url: REPOSITORY_1_URL)
-
- private static final String REPOSITORY_2_NAME = 'repoTwoName'
-
- private static final Format REPOSITORY_2_FORMAT = new Format('repoTwoFormat') {}
-
- private static final Type REPOSITORY_2_TYPE = new HostedType()
-
- private static final String REPOSITORY_2_URL = 'repoTwoUrl'
-
- private static final RepositoryXO REPOSITORY_XO_2 =
- new RepositoryXO(name: REPOSITORY_2_NAME, format: REPOSITORY_2_FORMAT.getValue(),
- type: REPOSITORY_2_TYPE.getValue(), url: REPOSITORY_2_URL)
-
- @Mock
- private RepositoryManagerRESTAdapter repositoryManagerRESTAdapter
-
- private RepositoriesResource underTest
-
- @Before
- void setup() {
- Repository repository1 =
- createMockRepository(REPOSITORY_1_NAME, REPOSITORY_1_FORMAT, REPOSITORY_1_TYPE, REPOSITORY_1_URL)
- Repository repository2 =
- createMockRepository(REPOSITORY_2_NAME, REPOSITORY_2_FORMAT, REPOSITORY_2_TYPE, REPOSITORY_2_URL)
-
- when(repositoryManagerRESTAdapter.getRepositories()).thenReturn([repository1, repository2])
-
- underTest = new RepositoriesResource(repositoryManagerRESTAdapter)
- }
-
- @Test
- void testGetRepositories() {
- assertThat(underTest.getRepositories(), is([REPOSITORY_XO_1, REPOSITORY_XO_2]))
- }
-
- private static Repository createMockRepository(final String name, final Format format, final Type type,
- final String url)
- {
- Repository repository = mock(Repository.class)
- when(repository.getName()).thenReturn(name)
- when(repository.getFormat()).thenReturn(format)
- when(repository.getType()).thenReturn(type)
- when(repository.getUrl()).thenReturn(url)
- return repository
- }
-}
diff --git a/components/nexus-repository/src/test/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoryManagerRESTAdapterImplTest.java b/components/nexus-repository/src/test/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoryManagerRESTAdapterImplTest.java
index 21cf2ceac223d1ca81fc2cdfd2ce248bbaf1bbff..b0aac50dc5736b83cd3fe43e4792a8358c22336b 100644
--- a/components/nexus-repository/src/test/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoryManagerRESTAdapterImplTest.java
+++ b/components/nexus-repository/src/test/java/org/sonatype/nexus/repository/rest/internal/resources/RepositoryManagerRESTAdapterImplTest.java
@@ -12,8 +12,6 @@
*/
package org.sonatype.nexus.repository.rest.internal.resources;
-import java.util.Arrays;
-
import javax.ws.rs.NotFoundException;
import javax.ws.rs.WebApplicationException;
@@ -44,38 +42,12 @@ import static org.sonatype.nexus.security.BreadActions.READ;
public class RepositoryManagerRESTAdapterImplTest
extends TestSupport
{
- private static final String REPOSITORY_NAME = "repoName";
-
- private static final String REPOSITORY_NAME_2 = "repoNameTwo";
-
- private static final String REPOSITORY_NAME_3 = "repoNameThree";
-
- private static final String REPOSITORY_FORMAT = "repoFormat";
-
- private static final String REPOSITORY_FORMAT_2 = "repoFormatTwo";
-
- private static final String REPOSITORY_FORMAT_3 = "repoFormatThree";
-
- private static final boolean PERMIT_BROWSE = true;
-
- private static final boolean PERMIT_READ = true;
-
- private static final boolean IGNORED_PERMIT_READ = false;
-
- private static final boolean PERMIT_VIA_CONTENT_SELECTOR = true;
-
@Mock
RepositoryManager repositoryManager;
@Mock
Repository repository;
- @Mock
- Repository repository2;
-
- @Mock
- Repository repository3;
-
@Mock
SecurityHelper securityHelper;
@@ -88,64 +60,53 @@ public class RepositoryManagerRESTAdapterImplTest
@Mock
Format repositoryFormat;
- @Mock
- Format repositoryFormat2;
-
- @Mock
- Format repositoryFormat3;
-
@Mock
SelectorConfiguration selectorConfiguration;
@Mock
SelectorManager selectorManager;
+ final String REPOSITORY_NAME = "test";
+
RepositoryManagerRESTAdapterImpl underTest;
@Before
public void setUp() throws Exception {
when(repositoryManager.get(REPOSITORY_NAME)).thenReturn(repository);
- when(repositoryManager.browse()).thenReturn(Arrays.asList(repository, repository2, repository3));
when(repository.getFormat()).thenReturn(repositoryFormat);
- when(repository2.getFormat()).thenReturn(repositoryFormat2);
- when(repository3.getFormat()).thenReturn(repositoryFormat3);
when(selectorManager.browse()).thenReturn(singletonList(selectorConfiguration));
when(selectorConfiguration.getName()).thenReturn("selector");
when(repository.getName()).thenReturn(REPOSITORY_NAME);
- when(repository2.getName()).thenReturn(REPOSITORY_NAME_2);
- when(repository3.getName()).thenReturn(REPOSITORY_NAME_3);
- when(repositoryFormat.getValue()).thenReturn(REPOSITORY_FORMAT);
- when(repositoryFormat2.getValue()).thenReturn(REPOSITORY_FORMAT_2);
- when(repositoryFormat3.getValue()).thenReturn(REPOSITORY_FORMAT_3);
+ when(repositoryFormat.getValue()).thenReturn("m2");
underTest = new RepositoryManagerRESTAdapterImpl(repositoryManager, securityHelper, selectorManager);
}
@Test
public void getRepository_allPermissions() throws Exception {
- configurePermissions(repository, PERMIT_BROWSE, PERMIT_READ, PERMIT_VIA_CONTENT_SELECTOR);
+ configurePermissions(true, true, true);
assertThat(underTest.getRepository(REPOSITORY_NAME), is(repository));
}
@Test
public void getRepository_browseOnly() throws Exception {
- configurePermissions(repository, PERMIT_BROWSE, !PERMIT_READ, !PERMIT_VIA_CONTENT_SELECTOR);
+ configurePermissions(true, false, false);
assertThat(underTest.getRepository(REPOSITORY_NAME), is(repository));
}
@Test
public void getRepository_contentSelectorOnly() throws Exception {
- configurePermissions(repository, !PERMIT_BROWSE, !PERMIT_READ, PERMIT_VIA_CONTENT_SELECTOR);
+ configurePermissions(false, false, true);
assertThat(underTest.getRepository(REPOSITORY_NAME), is(repository));
}
@Test
public void getRepository_readOnlyReturnsForbidden() throws Exception {
- configurePermissions(repository, !PERMIT_BROWSE, PERMIT_READ, !PERMIT_VIA_CONTENT_SELECTOR);
+ configurePermissions(false, true, false);
try {
underTest.getRepository(REPOSITORY_NAME);
@@ -158,12 +119,11 @@ public class RepositoryManagerRESTAdapterImplTest
@Test(expected = NotFoundException.class)
public void getRepository_notFoundWithNoPermissions() {
- configurePermissions(repository, !PERMIT_BROWSE, !PERMIT_READ, !PERMIT_VIA_CONTENT_SELECTOR);
+ configurePermissions(false, false, false);
underTest.getRepository(REPOSITORY_NAME);
}
- private void configurePermissions(final Repository repository,
- final boolean permitBrowse,
+ private void configurePermissions(final boolean permitBrowse,
final boolean permitRead,
final boolean permitViaContentSelector)
{
@@ -198,13 +158,4 @@ public class RepositoryManagerRESTAdapterImplTest
assertThat(e.getResponse().getStatus(), is(422));
}
}
-
- @Test
- public void getRepositories() {
- configurePermissions(repository, !PERMIT_BROWSE, IGNORED_PERMIT_READ, PERMIT_VIA_CONTENT_SELECTOR);
- configurePermissions(repository2, PERMIT_BROWSE, IGNORED_PERMIT_READ, !PERMIT_VIA_CONTENT_SELECTOR);
- configurePermissions(repository3, !PERMIT_BROWSE, IGNORED_PERMIT_READ, !PERMIT_VIA_CONTENT_SELECTOR);
-
- assertThat(underTest.getRepositories(), is(Arrays.asList(repository, repository2)));
- }
}
diff --git a/components/nexus-rest-client/pom.xml b/components/nexus-rest-client/pom.xml
index 2b5d889c8edd679ff0021d24c877913630b31f29..bd17b42c95713bf6d98a9b366237c68b8a5a954b 100644
--- a/components/nexus-rest-client/pom.xml
+++ b/components/nexus-rest-client/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-rest-client
diff --git a/components/nexus-rest-jackson2/pom.xml b/components/nexus-rest-jackson2/pom.xml
index 964217f8f98a487a22b47196a834ba4f38f937fb..d2d8130558c3256c571169347ab9281699699488 100644
--- a/components/nexus-rest-jackson2/pom.xml
+++ b/components/nexus-rest-jackson2/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-rest-jackson2
diff --git a/components/nexus-rest/pom.xml b/components/nexus-rest/pom.xml
index d27b8c0c826975b597c9ddc6cd47f6d32bc0d592..3e79f303160a98c4ec289a13e3bf6c9f377c2b84 100644
--- a/components/nexus-rest/pom.xml
+++ b/components/nexus-rest/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-rest
diff --git a/components/nexus-scheduling/pom.xml b/components/nexus-scheduling/pom.xml
index 453da94f4597d0bc457ceb39d6a6c52aa89964d9..4ea0ac8399a2e293481bfdfd304b821d725312ed 100644
--- a/components/nexus-scheduling/pom.xml
+++ b/components/nexus-scheduling/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-scheduling
diff --git a/components/nexus-script/pom.xml b/components/nexus-script/pom.xml
index ac52a847a27d9123b7363ed364c1ee7b01a9b6e0..5b0f66ba3f8325d5dfb827fb302c48547a2ab940 100644
--- a/components/nexus-script/pom.xml
+++ b/components/nexus-script/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-script
diff --git a/components/nexus-security/pom.xml b/components/nexus-security/pom.xml
index a40c7a107ce6056118b35b8043360e96342a0c27..db9a6be6c851718f752b78f9b0545f59b44b48d0 100644
--- a/components/nexus-security/pom.xml
+++ b/components/nexus-security/pom.xml
@@ -21,7 +21,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-security
diff --git a/components/nexus-selector/pom.xml b/components/nexus-selector/pom.xml
index 05f138ae1b6884d7492b32105338a90fb4ed8784..edab56b3d18d218c5ebe43bb6ac425ea1409e38e 100644
--- a/components/nexus-selector/pom.xml
+++ b/components/nexus-selector/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-selector
diff --git a/components/nexus-servlet/pom.xml b/components/nexus-servlet/pom.xml
index 233754cad7fbf43ee79824f156e5a1d95c4066e0..2504353803c288a07475d0ed5bf3778fbce53578 100644
--- a/components/nexus-servlet/pom.xml
+++ b/components/nexus-servlet/pom.xml
@@ -19,7 +19,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-servlet
diff --git a/components/nexus-siesta/pom.xml b/components/nexus-siesta/pom.xml
index 4a4295b8648596f0fab7a1594f15414160ac691a..25a43b6f88fdf1d15bd920a6e6f68e0fb4de37c1 100644
--- a/components/nexus-siesta/pom.xml
+++ b/components/nexus-siesta/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-siesta
diff --git a/components/nexus-ssl/pom.xml b/components/nexus-ssl/pom.xml
index 678a71e8b2ad9979a8c7c60e052c3d3960eb321b..381a0033aadf377d32f86cf5f23f2ba8be50a86b 100644
--- a/components/nexus-ssl/pom.xml
+++ b/components/nexus-ssl/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-ssl
diff --git a/components/nexus-supportzip-api/pom.xml b/components/nexus-supportzip-api/pom.xml
index 2104d8a86656432a72d0f5d0fa67240e3198c33c..7db87e4c8b202871f3cc7a3d07d8958835fca7ea 100644
--- a/components/nexus-supportzip-api/pom.xml
+++ b/components/nexus-supportzip-api/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-supportzip-api
diff --git a/components/nexus-swagger/pom.xml b/components/nexus-swagger/pom.xml
index 89b2d09014cb494c9819ab9f21de78c3c2df8da6..012847a17c9fb229d8d112e402f02609f77fc97d 100644
--- a/components/nexus-swagger/pom.xml
+++ b/components/nexus-swagger/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-swagger
diff --git a/components/nexus-swagger/src/main/java/org/sonatype/nexus/swagger/ParameterContributor.java b/components/nexus-swagger/src/main/java/org/sonatype/nexus/swagger/ParameterContributor.java
index dcc18cb0fffaf5aa3edd44ba7cf2e3408cd9cb0c..655d07fba1c41f29f5fa856083751aa30624ba03 100644
--- a/components/nexus-swagger/src/main/java/org/sonatype/nexus/swagger/ParameterContributor.java
+++ b/components/nexus-swagger/src/main/java/org/sonatype/nexus/swagger/ParameterContributor.java
@@ -39,7 +39,7 @@ public abstract class ParameterContributor httpMethods;
+ private final HttpMethod httpMethod;
private final Collection paths;
@@ -49,11 +49,11 @@ public abstract class ParameterContributor httpMethods,
+ public ParameterContributor(final HttpMethod httpMethod,
final Collection paths,
final Collection params)
{
- this.httpMethods = checkNotNull(httpMethods);
+ this.httpMethod = checkNotNull(httpMethod);
this.paths = checkNotNull(paths);
this.params = checkNotNull(params);
this.contributed = paths.stream().collect(toMap(p -> p, p -> false));
@@ -65,12 +65,10 @@ public abstract class ParameterContributor {
- paths.forEach(p -> {
- if (!contributed.get(p) && contributeGetParameters(swagger, httpMethod, p, params)) {
- contributed.put(p, true);
- }
- });
+ paths.forEach(p -> {
+ if (!contributed.get(p) && contributeGetParameters(swagger, httpMethod, p, params)) {
+ contributed.put(p, true);
+ }
});
allContributed = contributed.entrySet().stream().allMatch(Entry::getValue);
diff --git a/components/nexus-task-logging/pom.xml b/components/nexus-task-logging/pom.xml
index 4a65f32455f38622fb9dc0826ecfbd4b496e402b..aa3c9319bd203ceebd6755e0ac04045eabd2c3aa 100644
--- a/components/nexus-task-logging/pom.xml
+++ b/components/nexus-task-logging/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-task-logging
diff --git a/components/nexus-test-common/pom.xml b/components/nexus-test-common/pom.xml
index 756c824d1c9d74f50f5ca95dd8720f8bf2ea0561..106cc1d76251c549a948c85ff80d3026d27c2366 100644
--- a/components/nexus-test-common/pom.xml
+++ b/components/nexus-test-common/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-test-common
diff --git a/components/nexus-thread/pom.xml b/components/nexus-thread/pom.xml
index ec4307bd2d73fa6afe48d7ce6f486304f1bd60f4..67b24d5a4678a8b097c714d7024c5098ce85d2ac 100644
--- a/components/nexus-thread/pom.xml
+++ b/components/nexus-thread/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-thread
diff --git a/components/nexus-transaction/pom.xml b/components/nexus-transaction/pom.xml
index 1e4efae82b4c4732b2b389a1b31a81590d332f3c..787e184ff92a691cb904fd7ce95c1c58f1520af0 100644
--- a/components/nexus-transaction/pom.xml
+++ b/components/nexus-transaction/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-transaction
diff --git a/components/nexus-upgrade/pom.xml b/components/nexus-upgrade/pom.xml
index 987decbc9a72fd50bb6e18215f8faa56d9cafab5..df806ba31d6eed65d688717bd414439416ca756f 100644
--- a/components/nexus-upgrade/pom.xml
+++ b/components/nexus-upgrade/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-upgrade
diff --git a/components/nexus-validation/pom.xml b/components/nexus-validation/pom.xml
index b1b60c0b06c77b56d700d00f3ab0fc8bf228d223..445ed8cbcd263c71017666f832a537d6aa729560 100644
--- a/components/nexus-validation/pom.xml
+++ b/components/nexus-validation/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-validation
diff --git a/components/nexus-webhooks/pom.xml b/components/nexus-webhooks/pom.xml
index 7e5a1598a1dc3dc9c2395a4cf9e2c07aa97010f8..6e8e656179be34ad366268252d8db253010f4f46 100644
--- a/components/nexus-webhooks/pom.xml
+++ b/components/nexus-webhooks/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-webhooks
diff --git a/components/nexus-webresources-api/pom.xml b/components/nexus-webresources-api/pom.xml
index 5ef6de5f62a5139d7648ea5f313dadcd88f7d4f2..469e7a615301aa27e22ae3ba7dc1831903c9fd79 100644
--- a/components/nexus-webresources-api/pom.xml
+++ b/components/nexus-webresources-api/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-components
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-webresources-api
diff --git a/components/pom.xml b/components/pom.xml
index 1d417bc3c89b6fa3f28fef4d5638d8f40fccfd89..f56513fbfd6e1255b9a82b1743e620e077126392 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-parent
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-components
@@ -91,7 +91,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-allpom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -99,7 +99,7 @@
org.sonatype.nexus.bundlesnexus-thirdparty-bundlespom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
diff --git a/mvnw b/mvnw
old mode 100755
new mode 100644
diff --git a/plugins/nexus-audit-plugin/pom.xml b/plugins/nexus-audit-plugin/pom.xml
index 09b72318a4a6e7e107ac175e1d6c5f7d3c3a5da7..23abb73bfcc0eb251c2d3c672c6430b8e099b5d1 100644
--- a/plugins/nexus-audit-plugin/pom.xml
+++ b/plugins/nexus-audit-plugin/pom.xml
@@ -21,7 +21,7 @@
org.sonatype.nexus.pluginsnexus-plugins
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-audit-plugin
diff --git a/plugins/nexus-blobstore-s3/pom.xml b/plugins/nexus-blobstore-s3/pom.xml
index 7616bcd28f00fc148bf3a32ed43a7ffae4f766a6..c39db25cc30f2b07deb55138582de866272e3d0e 100644
--- a/plugins/nexus-blobstore-s3/pom.xml
+++ b/plugins/nexus-blobstore-s3/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.pluginsnexus-plugins
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-blobstore-s3
diff --git a/plugins/nexus-blobstore-tasks/pom.xml b/plugins/nexus-blobstore-tasks/pom.xml
index 7f3f82191946fd9f34871263960de15ddbf3a49f..67351ee918e56d2ac09abc5c4f215c1f56b93944 100644
--- a/plugins/nexus-blobstore-tasks/pom.xml
+++ b/plugins/nexus-blobstore-tasks/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.pluginsnexus-plugins
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-blobstore-tasks
diff --git a/plugins/nexus-blobstore-tasks/src/main/java/org/sonatype/nexus/blobstore/compact/internal/CompactBlobStoreTaskDescriptor.java b/plugins/nexus-blobstore-tasks/src/main/java/org/sonatype/nexus/blobstore/compact/internal/CompactBlobStoreTaskDescriptor.java
index 2950b0a31baa6d121baa861367ba5f308e1555b0..190e8e7cc3de4ff54e5a77b20711165c95ce43f6 100644
--- a/plugins/nexus-blobstore-tasks/src/main/java/org/sonatype/nexus/blobstore/compact/internal/CompactBlobStoreTaskDescriptor.java
+++ b/plugins/nexus-blobstore-tasks/src/main/java/org/sonatype/nexus/blobstore/compact/internal/CompactBlobStoreTaskDescriptor.java
@@ -40,7 +40,7 @@ public class CompactBlobStoreTaskDescriptor
public CompactBlobStoreTaskDescriptor() {
super(TYPE_ID,
CompactBlobStoreTask.class,
- "Admin - Compact blob store",
+ "Compact blob store",
VISIBLE,
EXPOSED,
new ComboboxFormField(
diff --git a/plugins/nexus-blobstore-tasks/src/main/java/org/sonatype/nexus/blobstore/restore/RestoreMetadataTaskDescriptor.java b/plugins/nexus-blobstore-tasks/src/main/java/org/sonatype/nexus/blobstore/restore/RestoreMetadataTaskDescriptor.java
index 3b9440752a5a145b13cee2e13d07d69c4c6ad7ce..8431b783be4610c4361f23573fd40e7c8a9c4552 100644
--- a/plugins/nexus-blobstore-tasks/src/main/java/org/sonatype/nexus/blobstore/restore/RestoreMetadataTaskDescriptor.java
+++ b/plugins/nexus-blobstore-tasks/src/main/java/org/sonatype/nexus/blobstore/restore/RestoreMetadataTaskDescriptor.java
@@ -45,7 +45,7 @@ public class RestoreMetadataTaskDescriptor
static final String DRY_RUN = "dryRun";
private interface Messages extends MessageBundle {
- @DefaultMessage("Repair - Reconcile component database from blob store")
+ @DefaultMessage("Restore Asset/Component metadata from Blob Store")
String name();
@DefaultMessage("Blob store")
diff --git a/plugins/nexus-coreui-plugin/pom.xml b/plugins/nexus-coreui-plugin/pom.xml
index e9b843255f633f305c213b922dc8cf41b781cb40..8683636d09471dc396a2943d9607b8bbf313794e 100644
--- a/plugins/nexus-coreui-plugin/pom.xml
+++ b/plugins/nexus-coreui-plugin/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.pluginsnexus-plugins
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-coreui-plugin
diff --git a/plugins/nexus-repository-httpbridge/pom.xml b/plugins/nexus-repository-httpbridge/pom.xml
index 4eee779008bb2f4f8141acc420cda749cb16453e..55e360fc0f41666507506c36a3a8fb9cb50e7674 100644
--- a/plugins/nexus-repository-httpbridge/pom.xml
+++ b/plugins/nexus-repository-httpbridge/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.pluginsnexus-plugins
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-repository-httpbridge
diff --git a/plugins/nexus-repository-maven/pom.xml b/plugins/nexus-repository-maven/pom.xml
index 5d198d8cbcccf53fd09d4bfaf388b8eda5101edd..8a2d72497e33d62559f750cbedc61a8cb672e88e 100644
--- a/plugins/nexus-repository-maven/pom.xml
+++ b/plugins/nexus-repository-maven/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.pluginsnexus-plugins
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-repository-maven
diff --git a/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/internal/hosted/MavenHostedComponentMaintenanceFacet.java b/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/internal/hosted/MavenHostedComponentMaintenanceFacet.java
index b2838e0cccd83ad70521422e76b0c4f0b538d477..1ccb5af69c23e8531e3885daf7b91a21c50aeaae 100644
--- a/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/internal/hosted/MavenHostedComponentMaintenanceFacet.java
+++ b/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/internal/hosted/MavenHostedComponentMaintenanceFacet.java
@@ -38,7 +38,7 @@ public class MavenHostedComponentMaintenanceFacet
extends DefaultComponentMaintenanceImpl
{
@Override
- public void deleteComponent(final EntityId componentId, final boolean deleteBlobs) {
+ public void deleteComponent(final EntityId componentId) {
String[] coordinates = Transactional.operation
.withDb(getRepository().facet(StorageFacet.class).txSupplier())
.call(() -> {
@@ -53,7 +53,7 @@ public class MavenHostedComponentMaintenanceFacet
}
return null;
});
- super.deleteComponent(componentId, deleteBlobs);
+ super.deleteComponent(componentId);
if (coordinates != null) {
getRepository().facet(MavenHostedFacet.class)
.deleteMetadata(coordinates[0], coordinates[1], coordinates[2]);
diff --git a/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/PublishMavenIndexTaskDescriptor.java b/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/PublishMavenIndexTaskDescriptor.java
index 6534d46efc90d6d41dfd774661a44ccab7bbb4fd..47ca83814ef64b17e0ce35d3fbea4fd8aab4603d 100644
--- a/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/PublishMavenIndexTaskDescriptor.java
+++ b/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/PublishMavenIndexTaskDescriptor.java
@@ -36,13 +36,13 @@ public class PublishMavenIndexTaskDescriptor
public PublishMavenIndexTaskDescriptor() {
super(TYPE_ID,
PublishMavenIndexTask.class,
- "Maven - Publish Maven Indexer files",
+ "Publish Maven indexes",
VISIBLE,
EXPOSED,
new RepositoryCombobox(
REPOSITORY_NAME_FIELD_ID,
"Repository",
- "Select the Maven repository to publish indexer files for",
+ "Select the Maven repository to publish indexes for",
true
).includingAnyOfFormats(Maven2Format.NAME).includeAnEntryForAllRepositories()
);
diff --git a/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/PurgeMavenUnusedSnapshotsTaskDescriptor.java b/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/PurgeMavenUnusedSnapshotsTaskDescriptor.java
index 81c7af10dfac058dc54f7c961d0afbff86794db8..149efbe35e6421bc605d43e19b9a798cc3fb47a9 100644
--- a/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/PurgeMavenUnusedSnapshotsTaskDescriptor.java
+++ b/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/PurgeMavenUnusedSnapshotsTaskDescriptor.java
@@ -34,7 +34,7 @@ import static org.sonatype.nexus.repository.maven.tasks.PurgeMavenUnusedSnapshot
public class PurgeMavenUnusedSnapshotsTaskDescriptor
extends TaskDescriptorSupport
{
- public static final String TASK_NAME = "Maven - Delete unused SNAPSHOT";
+ public static final String TASK_NAME = "Purge unused Maven snapshot versions";
public static final String TYPE_ID = "repository.maven.purge-unused-snapshots";
@@ -51,13 +51,13 @@ public class PurgeMavenUnusedSnapshotsTaskDescriptor
new RepositoryCombobox(
REPOSITORY_NAME_FIELD_ID,
"Repository",
- "Select the repository to delete unused snapshot versions from",
+ "Select the repository to purge unused snapshot versions from",
FormField.MANDATORY
).includingAnyOfFacets(PurgeUnusedSnapshotsFacet.class).includeAnEntryForAllRepositories(),
new NumberTextFormField(
LAST_USED_FIELD_ID,
"Last used in days",
- "Delete all snapshots that were last used before given number of days",
+ "Purge all snapshots that were last used before given number of days",
FormField.MANDATORY
).withInitialValue(LAST_USED_INIT_VALUE).withMinimumValue(LAST_USED_MIN_VALUE)
);
diff --git a/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/RebuildMaven2MetadataTaskDescriptor.java b/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/RebuildMaven2MetadataTaskDescriptor.java
index 91b49c3a8d40ef0d9880284d47b300ce01b30980..be9acfc34b1797a0bc527c362e9de64a6595393d 100644
--- a/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/RebuildMaven2MetadataTaskDescriptor.java
+++ b/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/RebuildMaven2MetadataTaskDescriptor.java
@@ -49,7 +49,7 @@ public class RebuildMaven2MetadataTaskDescriptor
public RebuildMaven2MetadataTaskDescriptor() {
super(TYPE_ID,
RebuildMaven2MetadataTask.class,
- "Repair - Rebuild Maven repository metadata (maven-metadata.xml)",
+ "Rebuild Maven repository metadata",
VISIBLE,
EXPOSED,
new RepositoryCombobox(
diff --git a/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/RemoveSnapshotsTaskDescriptor.java b/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/RemoveSnapshotsTaskDescriptor.java
index 76f0647c82df775472211e25b99a6a6196384708..5e5589a24e6dc2a6141c0297eb4e1c17d5bba6c2 100644
--- a/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/RemoveSnapshotsTaskDescriptor.java
+++ b/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/RemoveSnapshotsTaskDescriptor.java
@@ -47,7 +47,7 @@ public class RemoveSnapshotsTaskDescriptor
{
super(TYPE_ID,
RemoveSnapshotsTask.class,
- "Maven - Delete SNAPSHOT",
+ "Remove snapshots from Maven repository",
VISIBLE,
EXPOSED,
new RepositoryCombobox(REPOSITORY_NAME_FIELD_ID,
@@ -62,14 +62,14 @@ public class RemoveSnapshotsTaskDescriptor
true).withInitialValue(1).withMinimumValue(-1),
new NumberTextFormField(SNAPSHOT_RETENTION_DAYS,
"Snapshot retention (days)",
- "Delete all snapshots older than this, provided we still keep the minimum number specified.",
+ "Purge all snapshots older than this, provided we still keep the minimum number specified.",
true).withInitialValue(30).withMinimumValue(0),
new CheckboxFormField(REMOVE_IF_RELEASED,
"Remove if released",
- "Delete all snapshots that have a corresponding release", false),
+ "Purge all snapshots that have a corresponding release", false),
new NumberTextFormField(GRACE_PERIOD,
"Grace period after release (days)",
- "The grace period during which snapshots with an associated release will not be deleted.",
+ "The grace period during which snapshots with an associated release will not be purged.",
false).withMinimumValue(0));
}
}
diff --git a/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/UnpublishMavenIndexTaskDescriptor.java b/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/UnpublishMavenIndexTaskDescriptor.java
index 9b6a9e6d3c082e88b55d3d9725a013197a253cd9..719b037595c3c333a42fea7327c7b2d20a1fd86d 100644
--- a/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/UnpublishMavenIndexTaskDescriptor.java
+++ b/plugins/nexus-repository-maven/src/main/java/org/sonatype/nexus/repository/maven/tasks/UnpublishMavenIndexTaskDescriptor.java
@@ -36,7 +36,7 @@ public class UnpublishMavenIndexTaskDescriptor
public UnpublishMavenIndexTaskDescriptor() {
super(TYPE_ID,
UnpublishMavenIndexTask.class,
- "Maven - Unpublish Maven Indexer files",
+ "Remove Maven indexes",
VISIBLE,
EXPOSED,
new RepositoryCombobox(
diff --git a/plugins/nexus-repository-raw/pom.xml b/plugins/nexus-repository-raw/pom.xml
index a34c532171e255b1e9cff1ffbc0868a0829bd5b1..14721670bed37ae0ac94c31ffda47c9ba2e73b32 100644
--- a/plugins/nexus-repository-raw/pom.xml
+++ b/plugins/nexus-repository-raw/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.pluginsnexus-plugins
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-repository-raw
diff --git a/plugins/nexus-restore-maven/pom.xml b/plugins/nexus-restore-maven/pom.xml
index cb815f076b0d56e45e68e100758217fe5edf4d10..412a4cd8de475a3233289e51a8938bb329856b6f 100644
--- a/plugins/nexus-restore-maven/pom.xml
+++ b/plugins/nexus-restore-maven/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.pluginsnexus-plugins
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-restore-maven
diff --git a/plugins/nexus-script-plugin/pom.xml b/plugins/nexus-script-plugin/pom.xml
index 7f257588c604fceb07b8fcf6eb4282e3427c62a3..0e60186080b4b0af4b1e1ffa6605fb77c046f9d9 100644
--- a/plugins/nexus-script-plugin/pom.xml
+++ b/plugins/nexus-script-plugin/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.pluginsnexus-plugins
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-script-plugin
diff --git a/plugins/nexus-ssl-plugin/pom.xml b/plugins/nexus-ssl-plugin/pom.xml
index d81be741c87b08cf991bac0f3f93e62446181e50..f878f9803702b3df68a452f5eef6cfe8acd83a07 100644
--- a/plugins/nexus-ssl-plugin/pom.xml
+++ b/plugins/nexus-ssl-plugin/pom.xml
@@ -21,7 +21,7 @@
org.sonatype.nexus.pluginsnexus-plugins
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-ssl-plugin
diff --git a/plugins/nexus-task-log-cleanup/pom.xml b/plugins/nexus-task-log-cleanup/pom.xml
index 5e87799522539ee09628433795106a094cfac6c1..1365085e7dff53badf9fc7d75cfd8e38e16bef3d 100644
--- a/plugins/nexus-task-log-cleanup/pom.xml
+++ b/plugins/nexus-task-log-cleanup/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexus.pluginsnexus-plugins
- 3.8.0-SNAPSHOT
+ 3.8.0-02nexus-task-log-cleanup
diff --git a/plugins/pom.xml b/plugins/pom.xml
index e7abf92962f8fd485294585d34a0a346059b3c23..35ff4b3cd0bc1cacee40860a26f1bf3aadb38cd7 100644
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -20,7 +20,7 @@
org.sonatype.nexusnexus-parent
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.plugins
@@ -51,7 +51,7 @@
org.sonatype.nexus.buildsupportnexus-buildsupport-allpom
- 3.8.0-SNAPSHOT
+ 3.8.0-02import
@@ -62,13 +62,13 @@
org.sonatype.nexus.pluginsnexus-audit-plugin
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.pluginsnexus-audit-plugin
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -78,13 +78,13 @@
org.sonatype.nexus.pluginsnexus-blobstore-tasks
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.pluginsnexus-blobstore-tasks
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -94,13 +94,13 @@
org.sonatype.nexus.pluginsnexus-coreui-plugin
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.pluginsnexus-coreui-plugin
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -109,7 +109,7 @@
org.sonatype.nexus.pluginsnexus-coreui-pluginsources
- 3.8.0-SNAPSHOT
+ 3.8.0-02
@@ -117,13 +117,13 @@
org.sonatype.nexus.pluginsnexus-repository-httpbridge
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.pluginsnexus-repository-httpbridge
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -133,13 +133,13 @@
org.sonatype.nexus.pluginsnexus-repository-maven
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.pluginsnexus-repository-maven
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -147,13 +147,13 @@
org.sonatype.nexus.pluginsnexus-restore-maven
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.pluginsnexus-restore-maven
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -163,13 +163,13 @@
org.sonatype.nexus.pluginsnexus-repository-raw
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.pluginsnexus-repository-raw
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -179,13 +179,13 @@
org.sonatype.nexus.pluginsnexus-ssl-plugin
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.pluginsnexus-ssl-plugin
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -195,13 +195,13 @@
org.sonatype.nexus.pluginsnexus-script-plugin
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.pluginsnexus-script-plugin
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -211,13 +211,13 @@
org.sonatype.nexus.pluginsnexus-task-log-cleanup
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.pluginsnexus-task-log-cleanup
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -227,13 +227,13 @@
org.sonatype.nexus.pluginsnexus-blobstore-s3
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexus.pluginsnexus-blobstore-s3
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
diff --git a/pom.xml b/pom.xml
index 8f8c29e47cf65796caecf65d2cb54c4876d04eda..6181d56d2e99d5c5c7b004871d5ee773fe399aec 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,7 +29,7 @@
${project.groupId}:${project.artifactId}pom
- 3.8.0-SNAPSHOT
+ 3.8.0-022008http://nexus.sonatype.org/
@@ -88,7 +88,7 @@
Define nexus versions. The 'nexus.version' property always refers to the version of the current project.
These values must always be constants; 'nexus.version' will get update automatically by set-version.
-->
- 3.8.0-SNAPSHOT
+ 3.8.0-022.14.6-02
@@ -142,169 +142,169 @@
org.sonatype.nexusnexus-analytics-api
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-audit
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-base
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-blobstore
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-blobstore-api
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-blobstore-file
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-bootstrap
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-capability
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-commands
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-common
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-core
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-crypto
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-orient
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-orient-console
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-cache
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-elasticsearch
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-email
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-extdirect
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-extender
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-httpclient
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-jmx
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-scheduling
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-formfields
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-guice-servlet
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-main
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-mime
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-oss-edition
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-oss-edition
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -312,44 +312,44 @@
org.sonatype.nexusnexus-pax-logging
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-plugin-api
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-quartz
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-rapture
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-rapture
- 3.8.0-SNAPSHOT
+ 3.8.0-02sourcesorg.sonatype.nexusnexus-repository
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-repository
- 3.8.0-SNAPSHOT
+ 3.8.0-02teststest
@@ -357,109 +357,109 @@
org.sonatype.nexusnexus-rest
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-rest-client
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-rest-jackson2
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-script
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-security
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-selector
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-servlet
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-siesta
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-ssl
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-supportzip-api
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-swagger
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-task-logging
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-thread
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-transaction
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-upgrade
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-validation
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-webhooks
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-webresources-api
- 3.8.0-SNAPSHOT
+ 3.8.0-02
@@ -467,13 +467,13 @@
org.sonatype.nexusnexus-pax-exam
- 3.8.0-SNAPSHOT
+ 3.8.0-02org.sonatype.nexusnexus-test-common
- 3.8.0-SNAPSHOT
+ 3.8.0-02
@@ -481,7 +481,7 @@
org.sonatype.nexus.assembliesnexus-startup-feature
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -489,7 +489,7 @@
org.sonatype.nexus.assembliesnexus-boot-feature
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -497,7 +497,7 @@
org.sonatype.nexus.assembliesnexus-base-feature
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -505,7 +505,7 @@
org.sonatype.nexus.assembliesnexus-core-feature
- 3.8.0-SNAPSHOT
+ 3.8.0-02featuresxml
@@ -513,7 +513,7 @@
org.sonatype.nexus.assembliesnexus-base-template
- 3.8.0-SNAPSHOT
+ 3.8.0-02zip
@@ -793,7 +793,7 @@
org.sonatype.nexus.buildsupportextjs-maven-plugin
- 3.8.0-SNAPSHOT
+ 3.8.0-02
diff --git a/revision.txt b/revision.txt
index a64e5cd392c910395bb0862620be526be472d364..6c19d2f35a74e1e3af106e95768a67d75e5e954e 100644
--- a/revision.txt
+++ b/revision.txt
@@ -1 +1 @@
-b=master,r=efff85647125f90a57bacf46f29e76cf1b3a31d2,t=2018-02-02-1826-12385
\ No newline at end of file
+b=release-3.8.0,r=4900ae4d4f3bd55c34d43678225019bbb8d2e303,t=2018-02-01-1948-2081
\ No newline at end of file
diff --git a/thirdparty-bundles/LICENSE.txt b/thirdparty-bundles/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d6b3020fc7e5fcc7971e2df653af622de77ca06d
--- /dev/null
+++ b/thirdparty-bundles/LICENSE.txt
@@ -0,0 +1,87 @@
+Eclipse Public License -v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
diff --git a/thirdparty-bundles/README.md b/thirdparty-bundles/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..a49d8cb6b7ee7271a8784d63e5fdb8646329ee88
--- /dev/null
+++ b/thirdparty-bundles/README.md
@@ -0,0 +1,47 @@
+
+# Sonatype Nexus Repository Open Source Codebase
+
+[![Join the chat at https://gitter.im/sonatype/nexus-developers](https://badges.gitter.im/sonatype/nexus-developers.svg)](https://gitter.im/sonatype/nexus-developers?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+## Requirements
+
+* Apache Maven 3.3.3+
+* Java 8+
+* Network access to https://repository.sonatype.org/content/groups/sonatype-public-grid
+
+## Building
+
+To build the project and generate the template assembly use the included Maven wrapper:
+
+ ./mvnw clean install
+
+## Running
+
+To run Nexus Repository, after building, unzip the assembly and start the server:
+
+ unzip -d target assemblies/nexus-base-template/target/nexus-base-template-*.zip
+ ./target/nexus-base-template-*/bin/nexus console
+
+The `nexus-base-template` assembly is used as the basis for the official Sonatype Nexus distributions.
+
+## Getting help
+
+Looking to contribute to our code but need some help? There's a few ways to get information or our attention:
+
+* File an issue in [our public JIRA](https://issues.sonatype.org/browse/NEXUS)
+* Check out the [Nexus3](http://stackoverflow.com/questions/tagged/nexus3) tag on Stack Overflow
+* Check out the [Nexus Repository User List](https://groups.google.com/a/glists.sonatype.com/forum/?hl=en#!forum/nexus-users)
+* Connect with [@sonatypeDev](https://twitter.com/sonatypeDev) on Twitter
diff --git a/thirdparty-bundles/assemblies/nexus-base-feature/pom.xml b/thirdparty-bundles/assemblies/nexus-base-feature/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7c56fb62207edfa2605815a6a0107f64ccd2274b
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-feature/pom.xml
@@ -0,0 +1,111 @@
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.assemblies
+ nexus-assemblies
+ 3.8.0-02
+
+
+ nexus-base-feature
+ ${project.groupId}:${project.artifactId}
+ feature
+
+
+
+ org.apache.karaf.shell
+ org.apache.karaf.shell.core
+ provided
+
+
+
+ org.apache.karaf.shell
+ org.apache.karaf.shell.commands
+ provided
+
+
+
+ org.sonatype.nexus
+ nexus-extender
+
+
+
+ org.sonatype.nexus
+ nexus-plugin-api
+
+
+
+ org.sonatype.nexus
+ nexus-base
+
+
+
+ org.sonatype.nexus
+ nexus-extdirect
+
+
+
+ org.sonatype.nexus
+ nexus-siesta
+
+
+
+ org.sonatype.nexus
+ nexus-swagger
+
+
+
+ org.sonatype.nexus
+ nexus-rapture
+
+
+
+
+
+
+ org.codehaus.gmavenplus
+ gmavenplus-plugin
+
+
+ mvn-coordinates
+ initialize
+
+ execute
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.karaf.tooling
+ karaf-maven-plugin
+
+
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-feature/src/main/feature/feature.xml b/thirdparty-bundles/assemblies/nexus-base-feature/src/main/feature/feature.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0d8220e5599b8ea6332b6007fabbeacd3fcd029a
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-feature/src/main/feature/feature.xml
@@ -0,0 +1,46 @@
+
+
+
+
+ wrap:${mvn:javax.el}$overwrite=merge&Fragment-Host=org.hibernate.validator
+ wrap:${mvn:validation-api}$overwrite=merge&Fragment-Host=org.hibernate.validator
+ wrap:${mvn:paranamer}$overwrite=merge&Fragment-Host=org.hibernate.validator
+ wrap:${mvn:httpcore}$Bundle-SymbolicName=httpcore
+ wrap:${mvn:httpclient}$Bundle-SymbolicName=httpclient&Fragment-Host=httpcore
+ wrap:${mvn:jaxb-core}$Bundle-SymbolicName=jaxb-core
+ wrap:${mvn:jaxb-impl}$Bundle-SymbolicName=jaxb-impl&Fragment-Host=jaxb-core
+ wrap:${mvn:resteasy-jaxrs}$Bundle-SymbolicName=resteasy-jaxrs&Fragment-Host=org.sonatype.nexus.siesta
+ wrap:${mvn:resteasy-atom-provider}$Bundle-SymbolicName=resteasy-atom-provider&Fragment-Host=org.sonatype.nexus.siesta
+ wrap:${mvn:resteasy-jackson2-provider}$Bundle-SymbolicName=resteasy-jackson2-provider&Fragment-Host=org.sonatype.nexus.siesta
+ wrap:${mvn:resteasy-jaxb-provider}$Bundle-SymbolicName=resteasy-jaxb-provider&Fragment-Host=org.sonatype.nexus.siesta
+ wrap:${mvn:resteasy-multipart-provider}$Bundle-SymbolicName=resteasy-multipart-provider&Fragment-Host=org.sonatype.nexus.siesta
+ wrap:${mvn:resteasy-validator-provider-11}$Bundle-SymbolicName=resteasy-validator-provider&Fragment-Host=org.sonatype.nexus.siesta
+ wrap:${mvn:resteasy-client}$Bundle-SymbolicName=resteasy-client&Fragment-Host=org.sonatype.nexus.siesta
+
+
+ wrap:${mvn:swagger-core}$overwrite=merge&Import-Package=com.google.common.*,*
+ wrap:${mvn:swagger-jaxrs}$overwrite=merge&Import-Package=com.google.common.*,*
+
+
+ ${mvn:nexus-extender}
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/pom.xml b/thirdparty-bundles/assemblies/nexus-base-template/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a5f96a624b0a06bd9c07e0e09b3eab062ae3e284
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/pom.xml
@@ -0,0 +1,394 @@
+
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.assemblies
+ nexus-assemblies
+ 3.8.0-02
+
+
+ nexus-base-template
+ ${project.groupId}:${project.artifactId}
+ karaf-assembly
+
+
+
+
+ org.sonatype.nexus
+ nexus-main
+ provided
+
+
+
+
+ org.apache.felix
+ org.apache.felix.framework
+ provided
+
+
+
+
+ org.apache.karaf.features
+ framework
+ kar
+
+
+
+ org.apache.karaf.features
+ standard
+ features
+ xml
+
+
+
+ org.sonatype.nexus.assemblies
+ nexus-startup-feature
+ features
+ xml
+
+
+
+
+ org.sonatype.nexus.assemblies
+ nexus-boot-feature
+ features
+ xml
+ runtime
+
+
+
+ org.sonatype.nexus.assemblies
+ nexus-base-feature
+ features
+ xml
+ runtime
+
+
+
+ org.sonatype.nexus
+ nexus-oss-edition
+ features
+ xml
+ runtime
+
+
+
+ org.sonatype.nexus.assemblies
+ nexus-core-feature
+ features
+ xml
+ runtime
+
+
+
+
+ org.webjars
+ swagger-ui
+ provided
+
+
+
+
+ com.orientechnologies
+ orientdb-community
+ zip
+ runtime
+
+
+ *
+ *
+
+
+
+
+
+
+ org.sonatype.nexus
+ nexus-orient-console
+ provided
+
+
+
+
+
+
+ org.codehaus.gmavenplus
+ gmavenplus-plugin
+
+
+ pax-url-settings
+ initialize
+
+ execute
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+
+
+ configure-assembly
+ prepare-package
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${org.ops4j.pax.logging:pax-logging-api:jar}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${line.separator}
+
+ # SONATYPE: disable .cfg store on feature install
+ configCfgStore=false
+
+ # SONATYPE: disable automatic updates and retries
+ serviceRequirements=disable
+ updateSnapshots=false
+ scheduleMaxRun=1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.karaf.tooling
+ karaf-maven-plugin
+
+
+ false
+ false
+
+ false
+
+ 1.8
+
+ true
+
+ wrap
+ bundle
+ config
+ diagnostic
+ feature
+ jaas
+ log
+ package
+ shell
+ service
+ system
+ nexus-startup-feature
+
+
+ nexus-boot-feature
+
+
+ management
+ ssh
+ nexus-core-feature
+ nexus-oss-edition
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ bundle
+ package
+
+ single
+
+
+ false
+
+ ${project.basedir}/src/main/assembly/bundle.xml
+
+
+
+
+
+
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/assembly/bundle.xml b/thirdparty-bundles/assemblies/nexus-base-template/src/main/assembly/bundle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1e1c4b9c9dfb609e9b002650049c1f189ad04e6e
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/assembly/bundle.xml
@@ -0,0 +1,73 @@
+
+
+
+
+ bundle
+
+
+ zip
+
+
+ false
+
+
+
+ ${project.build.directory}/assembly
+ ${project.build.finalName}
+ 0644
+ 0755
+
+ bin/*
+ data/**
+
+
+
+
+ ${project.build.directory}/assembly
+ ${project.build.finalName}
+ 0644
+ 0755
+ dos
+
+ bin/*.bat
+
+
+
+
+ ${project.build.directory}/assembly
+ ${project.build.finalName}
+ 0755
+ 0755
+ unix
+
+ bin/*
+
+
+ bin/*.bat
+
+
+
+
+ ${project.build.directory}/sonatype-work
+ sonatype-work
+ 0644
+ 0755
+
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/LICENSE.txt b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d6b3020fc7e5fcc7971e2df653af622de77ca06d
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/LICENSE.txt
@@ -0,0 +1,87 @@
+Eclipse Public License -v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/NOTICE.txt b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/NOTICE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d88aaa17c4c41dd8fbe45e4a54c362eec98e2506
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/NOTICE.txt
@@ -0,0 +1,10 @@
+Sonatype Nexus (TM) Open Source Version.
+Copyright (c) 2008-present Sonatype, Inc. All rights reserved.
+All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions
+
+This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+
+Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+Eclipse Foundation. All other trademarks are the property of their respective owners.
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/bin/nexus b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/bin/nexus
new file mode 100644
index 0000000000000000000000000000000000000000..c7790b460112b9890d3640018b77e8792a57662a
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/bin/nexus
@@ -0,0 +1,436 @@
+#!/bin/sh
+DIRNAME=`dirname "$0"`
+PROGNAME=`basename "$0"`
+
+#
+# Sourcing environment settings for karaf similar to tomcats setenv
+#
+KARAF_SCRIPT="karaf"
+export KARAF_SCRIPT
+if [ -f "$DIRNAME/setenv" ]; then
+ . "$DIRNAME/setenv"
+fi
+
+#
+# Set up some easily accessible MIN/MAX params for JVM mem usage
+#
+if [ "x$JAVA_MIN_MEM" = "x" ]; then
+ JAVA_MIN_MEM=1200M
+ export JAVA_MIN_MEM
+fi
+if [ "x$JAVA_MAX_MEM" = "x" ]; then
+ JAVA_MAX_MEM=1200M
+ export JAVA_MAX_MEM
+fi
+if [ "x$DIRECT_MAX_MEM" = "x" ]; then
+ DIRECT_MAX_MEM=2G
+ export DIRECT_MAX_MEM
+fi
+
+#
+# Check the mode that initiated the script
+#
+if [ "x$1" != "x" ]; then
+ MODE=$1
+fi
+
+warn() {
+ echo "${PROGNAME}: $*"
+}
+
+die() {
+ warn "$*"
+ exit 1
+}
+
+detectOS() {
+ # OS specific support (must be 'true' or 'false').
+ cygwin=false;
+ darwin=false;
+ aix=false;
+ os400=false;
+ case "`uname`" in
+ CYGWIN*)
+ cygwin=true
+ ;;
+ Darwin*)
+ darwin=true
+ ;;
+ AIX*)
+ aix=true
+ ;;
+ OS400*)
+ os400=true
+ ;;
+ esac
+ # For AIX, set an environment variable
+ if $aix; then
+ export LDR_CNTRL=MAXDATA=0xB0000000@DSA
+ echo $LDR_CNTRL
+ fi
+}
+
+unlimitFD() {
+ # Use the maximum available, or set MAX_FD != -1 to use that
+ if [ "x$MAX_FD" = "x" ]; then
+ MAX_FD="maximum"
+ fi
+
+ # Increase the maximum file descriptors if we can
+ if [ "$os400" = "false" ] && [ "$cygwin" = "false" ]; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ]; then
+ # use the system max
+ MAX_FD="$MAX_FD_LIMIT"
+ else
+ warn "Could not query system maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+ fi
+ if [ "$MAX_FD" != 'unlimited' ]; then
+ ulimit -n $MAX_FD > /dev/null
+ if [ $? -ne 0 ]; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ fi
+ fi
+}
+
+locateHome() {
+ if [ "x$KARAF_HOME" = "x" ]; then
+ # In POSIX shells, CDPATH may cause cd to write to stdout
+ (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+ # KARAF_HOME is not provided, fall back to default
+ KARAF_HOME=`cd "$DIRNAME/.."; pwd`
+ fi
+
+ if [ ! -d "$KARAF_HOME" ]; then
+ die "KARAF_HOME is not valid: $KARAF_HOME"
+ fi
+}
+
+locateBase() {
+ if [ "x$KARAF_BASE" != "x" ]; then
+ if [ ! -d "$KARAF_BASE" ]; then
+ die "KARAF_BASE is not valid: $KARAF_BASE"
+ fi
+ else
+ KARAF_BASE=$KARAF_HOME
+ fi
+}
+
+locateData() {
+ if [ "x$KARAF_DATA" != "x" ]; then
+ if [ ! -d "$KARAF_DATA" ]; then
+ die "KARAF_DATA is not valid: $KARAF_DATA"
+ fi
+ else
+ KARAF_DATA=$KARAF_BASE/../sonatype-work/nexus3
+ fi
+}
+
+locateEtc() {
+ if [ "x$KARAF_ETC" != "x" ]; then
+ if [ ! -d "$KARAF_ETC" ]; then
+ die "KARAF_ETC is not valid: $KARAF_ETC"
+ fi
+ else
+ KARAF_ETC=$KARAF_BASE/etc/karaf
+ fi
+}
+
+setupNativePath() {
+ # Support for loading native libraries
+ LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:$KARAF_BASE/lib:$KARAF_HOME/lib"
+
+ # For Cygwin, set PATH from LD_LIBRARY_PATH
+ if $cygwin; then
+ LD_LIBRARY_PATH=`cygpath --path --windows "$LD_LIBRARY_PATH"`
+ PATH="$PATH;$LD_LIBRARY_PATH"
+ export PATH
+ fi
+ export LD_LIBRARY_PATH
+}
+
+pathCanonical() {
+ local dst="${1}"
+ while [ -h "${dst}" ] ; do
+ ls=`ls -ld "${dst}"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ dst="$link"
+ else
+ dst="`dirname "${dst}"`/$link"
+ fi
+ done
+ local bas=`basename "${dst}"`
+ local dir=`dirname "${dst}"`
+ if [ "$bas" != "$dir" ]; then
+ dst="`pathCanonical "$dir"`/$bas"
+ fi
+ echo "${dst}" | sed -e 's#//#/#g' -e 's#/./#/#g' -e 's#/[^/]*/../#/#g'
+}
+
+locateJava() {
+ # Setup the Java Virtual Machine
+ if $cygwin ; then
+ [ -n "$JAVA" ] && JAVA=`cygpath --unix "$JAVA"`
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+ fi
+
+ if [ "x$JAVA_HOME" = "x" ] && [ "$darwin" = "true" ]; then
+ JAVA_HOME="$(/usr/libexec/java_home -v 1.8)"
+ fi
+ if [ "x$JAVA" = "x" ] && [ -r /etc/gentoo-release ] ; then
+ JAVA_HOME=`java-config --jre-home`
+ fi
+ if [ "x$JAVA" = "x" ]; then
+ if [ "x$JAVA_HOME" != "x" ]; then
+ if [ ! -d "$JAVA_HOME" ]; then
+ die "JAVA_HOME is not valid: $JAVA_HOME"
+ fi
+ JAVA="$JAVA_HOME/bin/java"
+ else
+ warn "JAVA_HOME not set; results may vary"
+ JAVA=`type java`
+ JAVA=`expr "$JAVA" : '.* \(/.*\)$'`
+ if [ "x$JAVA" = "x" ]; then
+ die "java command not found"
+ fi
+ fi
+ fi
+ if [ "x$JAVA_HOME" = "x" ]; then
+ JAVA_HOME="$(dirname $(dirname $(pathCanonical "$JAVA")))"
+ fi
+}
+
+detectJVM() {
+ #echo "`$JAVA -version`"
+ # This service should call `java -version`,
+ # read stdout, and look for hints
+ if $JAVA -version 2>&1 | grep "^IBM" ; then
+ JVM_VENDOR="IBM"
+ # on OS/400, java -version does not contain IBM explicitly
+ elif $os400; then
+ JVM_VENDOR="IBM"
+ else
+ JVM_VENDOR="SUN"
+ fi
+ # echo "JVM vendor is $JVM_VENDOR"
+}
+
+checkJvmVersion() {
+ # echo "`$JAVA -version`"
+ VERSION=`$JAVA -version 2>&1 | egrep '"([0-9].[0-9]\..*[0-9]).*"' | awk '{print substr($3,2,length($3)-2)}' | awk '{print substr($1, 3, 3)}' | sed -e 's;\.;;g'`
+ # echo $VERSION
+ if [ "$VERSION" -lt "60" ]; then
+ echo "JVM must be greater than 1.6"
+ exit 1;
+ fi
+}
+
+setupDebugOptions() {
+ if [ "x$JAVA_OPTS" = "x" ]; then
+ JAVA_OPTS="$DEFAULT_JAVA_OPTS"
+ fi
+ export JAVA_OPTS
+
+ if [ "x$EXTRA_JAVA_OPTS" != "x" ]; then
+ JAVA_OPTS="$JAVA_OPTS $EXTRA_JAVA_OPTS"
+ fi
+
+ # Set Debug options if enabled
+ if [ "x$KARAF_DEBUG" != "x" ]; then
+ # Ignore DEBUG in case of stop, client, or status mode
+ if [ "x$MODE" = "xstop" ]; then
+ return
+ fi
+ if [ "x$MODE" = "xclient" ]; then
+ return
+ fi
+ if [ "x$MODE" = "xstatus" ]; then
+ return
+ fi
+ # Use the defaults if JAVA_DEBUG_OPTS was not set
+ if [ "x$JAVA_DEBUG_OPTS" = "x" ]; then
+ JAVA_DEBUG_OPTS="$DEFAULT_JAVA_DEBUG_OPTS"
+ fi
+
+ JAVA_OPTS="$JAVA_DEBUG_OPTS $JAVA_OPTS"
+ warn "Enabling Java debug options: $JAVA_DEBUG_OPTS"
+ fi
+}
+
+setupDefaults() {
+ # SONATYPE: preferred IPv4 by default
+ if [ "x$KARAF_OPTS" = "x" ]; then
+ KARAF_OPTS="-Djava.net.preferIPv4Stack=true"
+ fi
+
+ DEFAULT_JAVA_OPTS="-Xms$JAVA_MIN_MEM -Xmx$JAVA_MAX_MEM -XX:MaxDirectMemorySize=$DIRECT_MAX_MEM -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass -XX:+LogVMOutput -XX:LogFile=../sonatype-work/nexus3/log/jvm.log -XX:-OmitStackTraceInFastThrow "
+
+ if [ "$darwin" = "true" ] && [ "$JVM_VENDOR" = "SUN" ] && [ `ulimit -n` -gt 10240 ]; then
+ # NEXUS-14184 - Open up OSX file descriptor limit
+ DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS -XX:-MaxFDLimit "
+ fi
+
+ #Set the JVM_VENDOR specific JVM flags
+ if [ "$JVM_VENDOR" = "SUN" ]; then
+ # SONATYPE: removed -XX:PermSize and -XX:MaxPermSize
+ # SONATYPE: removed -Dcom.sun.management.jmxremote
+ DEFAULT_JAVA_OPTS="-server $DEFAULT_JAVA_OPTS"
+ elif [ "$JVM_VENDOR" = "IBM" ]; then
+ if $os400; then
+ DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS"
+ elif $aix; then
+ DEFAULT_JAVA_OPTS="-Xverify:none -Xdump:heap -Xlp $DEFAULT_JAVA_OPTS"
+ else
+ DEFAULT_JAVA_OPTS="-Xverify:none $DEFAULT_JAVA_OPTS"
+ fi
+ fi
+
+ # Add the jars in the lib dir
+ for file in "$KARAF_HOME"/lib/boot/*.jar
+ do
+ if [ -z "$CLASSPATH" ]; then
+ CLASSPATH="$file"
+ else
+ CLASSPATH="$CLASSPATH:$file"
+ fi
+ done
+
+ DEFAULT_JAVA_DEBUG_PORT="5005"
+ if [ "x$JAVA_DEBUG_PORT" = "x" ]; then
+ JAVA_DEBUG_PORT="$DEFAULT_JAVA_DEBUG_PORT"
+ fi
+ DEFAULT_JAVA_DEBUG_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$JAVA_DEBUG_PORT"
+
+ ##
+ ## TODO: Move to conf/profiler/yourkit.{sh|cmd}
+ ##
+ # Uncomment to enable YourKit profiling
+ #DEFAULT_JAVA_DEBUG_OPTS="-Xrunyjpagent"
+}
+
+init() {
+ # Determine if there is special OS handling we must perform
+ detectOS
+
+ # Unlimit the number of file descriptors if possible
+ unlimitFD
+
+ # Locate the Karaf home directory
+ locateHome
+
+ # Locate the Karaf base directory
+ locateBase
+
+ # Locate the Karaf data directory
+ locateData
+
+ # Locate the Karaf etc directory
+ locateEtc
+
+ # Setup the native library path
+ setupNativePath
+
+ # Locate the Java VM to execute
+ locateJava
+
+ # Determine the JVM vendor
+ detectJVM
+
+ # Determine the JVM version >= 1.6
+ checkJvmVersion
+
+ # Setup default options
+ setupDefaults
+
+ # Install debug options
+ setupDebugOptions
+
+}
+
+run() {
+ OPTS="-Dkaraf.startLocalConsole=true -Dkaraf.startRemoteShell=true"
+ MAIN=org.sonatype.nexus.karaf.NexusMain
+ while [ "$1" != "" ]; do
+ case $1 in
+ 'clean')
+ rm -Rf "$KARAF_DATA"
+ shift
+ ;;
+ 'debug')
+ if [ "x$JAVA_DEBUG_OPTS" = "x" ]; then
+ JAVA_DEBUG_OPTS="$DEFAULT_JAVA_DEBUG_OPTS"
+ fi
+ JAVA_OPTS="$JAVA_DEBUG_OPTS $JAVA_OPTS"
+ shift
+ ;;
+ 'status')
+ MAIN=org.apache.karaf.main.Status
+ shift
+ ;;
+ 'stop')
+ MAIN=org.apache.karaf.main.Stop
+ shift
+ ;;
+ 'run' | 'console')
+ shift
+ ;;
+ 'start')
+ NOHUP="true"
+ OPTS="-Dkaraf.startLocalConsole=false -Dkaraf.startRemoteShell=true"
+ shift
+ ;;
+ 'server')
+ OPTS="-Dkaraf.startLocalConsole=false -Dkaraf.startRemoteShell=true"
+ shift
+ ;;
+ 'client')
+ OPTS="-Dkaraf.startLocalConsole=true -Dkaraf.startRemoteShell=false"
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+ done
+
+ # SONATYPE: commented
+ #JAVA_ENDORSED_DIRS="${JAVA_HOME}/jre/lib/endorsed:${JAVA_HOME}/lib/endorsed:${KARAF_HOME}/lib/endorsed"
+ #JAVA_EXT_DIRS="${JAVA_HOME}/jre/lib/ext:${JAVA_HOME}/lib/ext:${KARAF_HOME}/lib/ext"
+ if $cygwin; then
+ KARAF_HOME=`cygpath --path --windows "$KARAF_HOME"`
+ KARAF_BASE=`cygpath --path --windows "$KARAF_BASE"`
+ KARAF_DATA=`cygpath --path --windows "$KARAF_DATA"`
+ KARAF_ETC=`cygpath --path --windows "$KARAF_ETC"`
+ if [ ! -z "$CLASSPATH" ]; then
+ CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+ fi
+ JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
+ # SONATYPE: commented
+ #JAVA_ENDORSED_DIRS=`cygpath --path --windows "$JAVA_ENDORSED_DIRS"`
+ #JAVA_EXT_DIRS=`cygpath --path --windows "$JAVA_EXT_DIRS"`
+ fi
+ cd "$KARAF_BASE"
+
+ # SONATYPE: prepare log and tmp directories
+ mkdir -p "$KARAF_DATA/log" "$KARAF_DATA/tmp"
+
+ # SONATYPE: removed -Djavax.management.builder.initial
+ # SONATYPE: removed -Djava.endorsed.dirs="${JAVA_ENDORSED_DIRS}"
+ # SONATYPE: removed -Djava.ext.dirs="${JAVA_EXT_DIRS}"
+ if [ "$NOHUP" = "true" ]; then
+ exec nohup "$JAVA" $JAVA_OPTS -Dkaraf.instances="${KARAF_DATA}/instances" -Dkaraf.home="$KARAF_HOME" -Dkaraf.base="$KARAF_BASE" -Dkaraf.data="$KARAF_DATA" -Dkaraf.etc="$KARAF_ETC" -Djava.io.tmpdir="$KARAF_DATA/tmp" -Djava.util.logging.config.file="$KARAF_ETC/java.util.logging.properties" $KARAF_OPTS $OPTS -classpath "$CLASSPATH" $MAIN "$@" > /dev/null 2>&1 &
+ else
+ exec "$JAVA" $JAVA_OPTS -Dkaraf.instances="${KARAF_DATA}/instances" -Dkaraf.home="$KARAF_HOME" -Dkaraf.base="$KARAF_BASE" -Dkaraf.data="$KARAF_DATA" -Dkaraf.etc="$KARAF_ETC" -Djava.io.tmpdir="$KARAF_DATA/tmp" -Djava.util.logging.config.file="$KARAF_ETC/java.util.logging.properties" $KARAF_OPTS $OPTS -classpath "$CLASSPATH" $MAIN "$@"
+ fi
+}
+
+main() {
+ init
+ run "$@"
+}
+
+main "$@"
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/bin/nexus.bat b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/bin/nexus.bat
new file mode 100644
index 0000000000000000000000000000000000000000..877955e3a4400553d8ce580e05f4815e36c181c5
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/bin/nexus.bat
@@ -0,0 +1,331 @@
+@echo off
+if not "%ECHO%" == "" echo %ECHO%
+
+setlocal
+set DIRNAME=%~dp0%
+set PROGNAME=%~nx0%
+set ARGS=%*
+
+rem Sourcing environment settings for karaf similar to tomcats setenv
+SET KARAF_SCRIPT="karaf.bat"
+if exist "%DIRNAME%setenv.bat" (
+ call "%DIRNAME%setenv.bat"
+)
+
+rem Check console window title. Set to Karaf by default
+if not "%KARAF_TITLE%" == "" (
+ title %KARAF_TITLE%
+) else (
+ title Karaf
+)
+
+rem Check/Set up some easily accessible MIN/MAX params for JVM mem usage
+if "%JAVA_MIN_MEM%" == "" (
+ set JAVA_MIN_MEM=1200M
+)
+if "%JAVA_MAX_MEM%" == "" (
+ set JAVA_MAX_MEM=1200M
+)
+if "%DIRECT_MAX_MEM%" == "" (
+ set DIRECT_MAX_MEM=2G
+)
+
+goto BEGIN
+
+:warn
+ echo %PROGNAME%: %*
+goto :EOF
+
+:BEGIN
+
+rem # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+if not "%KARAF_HOME%" == "" (
+ call :warn Ignoring predefined value for KARAF_HOME
+)
+set KARAF_HOME=%DIRNAME%..
+if not exist "%KARAF_HOME%" (
+ call :warn KARAF_HOME is not valid: "%KARAF_HOME%"
+ goto END
+)
+
+if not "%KARAF_BASE%" == "" (
+ if not exist "%KARAF_BASE%" (
+ call :warn KARAF_BASE is not valid: "%KARAF_BASE%"
+ goto END
+ )
+)
+if "%KARAF_BASE%" == "" (
+ set "KARAF_BASE=%KARAF_HOME%"
+)
+
+if not "%KARAF_DATA%" == "" (
+ if not exist "%KARAF_DATA%" (
+ call :warn KARAF_DATA is not valid: "%KARAF_DATA%"
+ goto END
+ )
+)
+if "%KARAF_DATA%" == "" (
+ set "KARAF_DATA=%KARAF_BASE%\..\sonatype-work\nexus3"
+)
+
+if not "%KARAF_ETC%" == "" (
+ if not exist "%KARAF_ETC%" (
+ call :warn KARAF_ETC is not valid: "%KARAF_ETC%"
+ goto END
+ )
+)
+if "%KARAF_ETC%" == "" (
+ set "KARAF_ETC=%KARAF_BASE%\etc\karaf"
+)
+
+set LOCAL_CLASSPATH=%CLASSPATH%
+set JAVA_MODE=-server
+
+set CLASSPATH=%LOCAL_CLASSPATH%;%KARAF_BASE%\conf
+set DEFAULT_JAVA_DEBUG_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
+
+if "%LOCAL_CLASSPATH%" == "" goto :KARAF_CLASSPATH_EMPTY
+ set CLASSPATH=%LOCAL_CLASSPATH%;%KARAF_BASE%\conf
+ goto :KARAF_CLASSPATH_END
+:KARAF_CLASSPATH_EMPTY
+ set CLASSPATH=%KARAF_BASE%\conf
+:KARAF_CLASSPATH_END
+
+rem Setup Karaf Home
+if exist "%KARAF_HOME%\conf\karaf-rc.cmd" call %KARAF_HOME%\conf\karaf-rc.cmd
+if exist "%HOME%\karaf-rc.cmd" call %HOME%\karaf-rc.cmd
+
+rem Support for loading native libraries
+set PATH=%PATH%;%KARAF_BASE%\lib;%KARAF_HOME%\lib
+
+rem Setup the Java Virtual Machine
+if not "%JAVA%" == "" goto :Check_JAVA_END
+ if not "%JAVA_HOME%" == "" goto :TryJDKEnd
+ call :warn JAVA_HOME not set; results may vary
+:TryJRE
+ start /w regedit /e __reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment"
+ if not exist __reg1.txt goto :TryJDK
+ type __reg1.txt | find "CurrentVersion" > __reg2.txt
+ if errorlevel 1 goto :TryJDK
+ for /f "tokens=2 delims==" %%x in (__reg2.txt) do set JavaTemp=%%~x
+ if errorlevel 1 goto :TryJDK
+ set JavaTemp=%JavaTemp%##
+ set JavaTemp=%JavaTemp: ##=##%
+ set JavaTemp=%JavaTemp: ##=##%
+ set JavaTemp=%JavaTemp: ##=##%
+ set JavaTemp=%JavaTemp: ##=##%
+ set JavaTemp=%JavaTemp: ##=##%
+ set JavaTemp=%JavaTemp:##=%
+ del __reg1.txt
+ del __reg2.txt
+ start /w regedit /e __reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\%JavaTemp%"
+ if not exist __reg1.txt goto :TryJDK
+ type __reg1.txt | find "JavaHome" > __reg2.txt
+ if errorlevel 1 goto :TryJDK
+ for /f "tokens=2 delims==" %%x in (__reg2.txt) do set JAVA_HOME=%%~x
+ if errorlevel 1 goto :TryJDK
+ del __reg1.txt
+ del __reg2.txt
+ goto TryJDKEnd
+:TryJDK
+ start /w regedit /e __reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit"
+ if not exist __reg1.txt (
+ goto TryRegJRE
+ )
+ type __reg1.txt | find "CurrentVersion" > __reg2.txt
+ if errorlevel 1 (
+ goto TryRegJRE
+ )
+ for /f "tokens=2 delims==" %%x in (__reg2.txt) do set JavaTemp=%%~x
+ if errorlevel 1 (
+ goto TryRegJRE
+ )
+ set JavaTemp=%JavaTemp%##
+ set JavaTemp=%JavaTemp: ##=##%
+ set JavaTemp=%JavaTemp: ##=##%
+ set JavaTemp=%JavaTemp: ##=##%
+ set JavaTemp=%JavaTemp: ##=##%
+ set JavaTemp=%JavaTemp: ##=##%
+ set JavaTemp=%JavaTemp:##=%
+ del __reg1.txt
+ del __reg2.txt
+ start /w regedit /e __reg1.txt "HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit\%JavaTemp%"
+ if not exist __reg1.txt (
+ goto TryRegJRE
+ )
+ type __reg1.txt | find "JavaHome" > __reg2.txt
+ if errorlevel 1 (
+ goto TryRegJRE
+ )
+ for /f "tokens=2 delims==" %%x in (__reg2.txt) do set JAVA_HOME=%%~x
+ if errorlevel 1 (
+ goto TryRegJRE
+ )
+ del __reg1.txt
+ del __reg2.txt
+:TryRegJRE
+ rem try getting the JAVA_HOME from registry
+ FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKLM\Software\JavaSoft\Java Runtime Environment" /v CurrentVersion`) DO (
+ set JAVA_VERSION=%%A
+ )
+ FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKLM\Software\JavaSoft\Java Runtime Environment\%JAVA_VERSION%" /v JavaHome`) DO (
+ set JAVA_HOME=%%A %%B
+ )
+ if not exist "%JAVA_HOME%" (
+ goto TryRegJDK
+ )
+ goto TryJDKEnd
+:TryRegJDK
+ rem try getting the JAVA_HOME from registry
+ FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKLM\Software\JavaSoft\Java Development Kit" /v CurrentVersion`) DO (
+ set JAVA_VERSION=%%A
+ )
+ FOR /F "usebackq tokens=3*" %%A IN (`REG QUERY "HKLM\Software\JavaSoft\Java Development Kit\%JAVA_VERSION%" /v JavaHome`) DO (
+ set JAVA_HOME=%%A %%B
+ )
+ if not exist "%JAVA_HOME%" (
+ call :warn Unable to retrieve JAVA_HOME from Registry
+ )
+ goto TryJDKEnd
+:TryJDKEnd
+ if not exist "%JAVA_HOME%" (
+ call :warn JAVA_HOME is not valid: "%JAVA_HOME%"
+ goto END
+ )
+ set JAVA=%JAVA_HOME%\bin\java
+:Check_JAVA_END
+
+if not exist "%JAVA_HOME%\bin\server\jvm.dll" (
+ if not exist "%JAVA_HOME%\jre\bin\server\jvm.dll" (
+ echo WARNING: Running Karaf on a Java HotSpot Client VM because server-mode is not available.
+ echo Install Java Developer Kit to fix this.
+ echo For more details see http://java.sun.com/products/hotspot/whitepaper.html#client
+ set JAVA_MODE=-client
+ )
+)
+
+rem SONATYPE: preferred IPv4 by default
+if "%KARAF_OPTS%" == "" set KARAF_OPTS=-Djava.net.preferIPv4Stack=true
+
+rem SONATYPE: removed -Dcom.sun.management.jmxremote and unused derby properties
+set DEFAULT_JAVA_OPTS=%JAVA_MODE% -Xms%JAVA_MIN_MEM% -Xmx%JAVA_MAX_MEM% -XX:MaxDirectMemorySize=%DIRECT_MAX_MEM% -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass -XX:+LogVMOutput -XX:LogFile=..\sonatype-work\nexus3\log\jvm.log -XX:-OmitStackTraceInFastThrow
+
+rem SONATYPE: removed -XX:PermSize and -XX:MaxPermSize
+
+if "%JAVA_OPTS%" == "" set JAVA_OPTS=%DEFAULT_JAVA_OPTS%
+
+if "%EXTRA_JAVA_OPTS%" == "" goto :KARAF_EXTRA_JAVA_OPTS_END
+ set JAVA_OPTS=%JAVA_OPTS% %EXTRA_JAVA_OPTS%
+:KARAF_EXTRA_JAVA_OPTS_END
+
+if "%KARAF_DEBUG%" == "" goto :KARAF_DEBUG_END
+ if "%1" == "stop" goto :KARAF_DEBUG_END
+ if "%1" == "client" goto :KARAF_DEBUG_END
+ if "%1" == "status" goto :KARAF_DEBUG_END
+ rem Use the defaults if JAVA_DEBUG_OPTS was not set
+ if "%JAVA_DEBUG_OPTS%" == "" set JAVA_DEBUG_OPTS=%DEFAULT_JAVA_DEBUG_OPTS%
+
+ set JAVA_OPTS=%JAVA_DEBUG_OPTS% %JAVA_OPTS%
+ call :warn Enabling Java debug options: %JAVA_DEBUG_OPTS%
+:KARAF_DEBUG_END
+
+if "%KARAF_PROFILER%" == "" goto :KARAF_PROFILER_END
+ set KARAF_PROFILER_SCRIPT=%KARAF_HOME%\conf\profiler\%KARAF_PROFILER%.cmd
+
+ if exist "%KARAF_PROFILER_SCRIPT%" goto :KARAF_PROFILER_END
+ call :warn Missing configuration for profiler '%KARAF_PROFILER%': %KARAF_PROFILER_SCRIPT%
+ goto END
+:KARAF_PROFILER_END
+
+rem Setup the classpath
+pushd "%KARAF_HOME%\lib\boot"
+for %%G in (*.jar) do call:APPEND_TO_CLASSPATH %%G
+popd
+goto CLASSPATH_END
+
+: APPEND_TO_CLASSPATH
+set filename=%~1
+set suffix=%filename:~-4%
+if %suffix% equ .jar set CLASSPATH=%CLASSPATH%;%KARAF_HOME%\lib\boot\%filename%
+goto :EOF
+
+:CLASSPATH_END
+
+rem Execute the JVM or the load the profiler
+if "%KARAF_PROFILER%" == "" goto :RUN
+ rem Execute the profiler if it has been configured
+ call :warn Loading profiler script: %KARAF_PROFILER_SCRIPT%
+ call %KARAF_PROFILER_SCRIPT%
+
+:RUN
+ SET OPTS=-Dkaraf.startLocalConsole=true -Dkaraf.startRemoteShell=true
+ SET MAIN=org.sonatype.nexus.karaf.NexusMain
+ SET SHIFT=false
+
+:RUN_LOOP
+ if "%1" == "stop" goto :EXECUTE_STOP
+ if "%1" == "status" goto :EXECUTE_STATUS
+ if "%1" == "run" goto :EXECUTE_CONSOLE
+ if "%1" == "console" goto :EXECUTE_CONSOLE
+ if "%1" == "start" goto :EXECUTE_SERVER
+ if "%1" == "server" goto :EXECUTE_SERVER
+ if "%1" == "client" goto :EXECUTE_CLIENT
+ if "%1" == "clean" goto :EXECUTE_CLEAN
+ if "%1" == "debug" goto :EXECUTE_DEBUG
+ goto :EXECUTE
+
+:EXECUTE_STOP
+ SET MAIN=org.apache.karaf.main.Stop
+ shift
+ goto :RUN_LOOP
+
+:EXECUTE_STATUS
+ SET MAIN=org.apache.karaf.main.Status
+ shift
+ goto :RUN_LOOP
+
+:EXECUTE_CONSOLE
+ shift
+ goto :RUN_LOOP
+
+:EXECUTE_SERVER
+ SET OPTS=-Dkaraf.startLocalConsole=false -Dkaraf.startRemoteShell=true
+ shift
+ goto :RUN_LOOP
+
+:EXECUTE_CLIENT
+ SET OPTS=-Dkaraf.startLocalConsole=true -Dkaraf.startRemoteShell=false
+ shift
+ goto :RUN_LOOP
+
+:EXECUTE_CLEAN
+ rmdir /S /Q "%KARAF_DATA%"
+ shift
+ goto :RUN_LOOP
+
+:EXECUTE_DEBUG
+ if "%JAVA_DEBUG_OPTS%" == "" set JAVA_DEBUG_OPTS=%DEFAULT_JAVA_DEBUG_OPTS%
+ set JAVA_OPTS=%JAVA_DEBUG_OPTS% %JAVA_OPTS%
+ shift
+ goto :RUN_LOOP
+
+:EXECUTE
+ SET ARGS=%1 %2 %3 %4 %5 %6 %7 %8
+ rem Execute the Java Virtual Machine
+ cd "%KARAF_BASE%"
+ rem SONATYPE: removed -Djavax.management.builder.initial
+ rem SONATYPE: removed -Djava.endorsed.dirs="%JAVA_HOME%\jre\lib\endorsed;%JAVA_HOME%\lib\endorsed;%KARAF_HOME%\lib\endorsed"
+ rem SONATYPE: removed -Djava.ext.dirs="%JAVA_HOME%\jre\lib\ext;%JAVA_HOME%\lib\ext;%KARAF_HOME%\lib\ext"
+ "%JAVA%" %JAVA_OPTS% %OPTS% -classpath "%CLASSPATH%" -Dkaraf.instances="%KARAF_DATA%\instances" -Dkaraf.home="%KARAF_HOME%" -Dkaraf.base="%KARAF_BASE%" -Dkaraf.etc="%KARAF_ETC%" -Djava.io.tmpdir="%KARAF_DATA%\tmp" -Dkaraf.data="%KARAF_DATA%" -Djava.util.logging.config.file="%KARAF_ETC%\java.util.logging.properties" %KARAF_OPTS% %MAIN% %ARGS%
+
+rem # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+:END
+
+endlocal
+
+if not "%PAUSE%" == "" pause
+
+:END_NO_PAUSE
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/bin/setenv b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/bin/setenv
new file mode 100644
index 0000000000000000000000000000000000000000..912804f5fd448bf9f35d8b28765e6f0a0f9c4f5c
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/bin/setenv
@@ -0,0 +1,31 @@
+#!/bin/sh
+# handle specific scripts; the SCRIPT_NAME is exactly the name of the Karaf
+# script; for example karaf, start, stop, admin, client, ...
+#
+# if [ "$KARAF_SCRIPT" = "SCRIPT_NAME" ]; then
+# Actions go here...
+# fi
+
+#
+# general settings which should be applied for all scripts go here; please keep
+# in mind that it is possible that scripts might be executed more than once, e.g.
+# in example of the start script where the start script is executed first and the
+# karaf script afterwards.
+#
+
+#
+# The following section shows the possible configuration options for the default
+# karaf scripts
+#
+# JAVA_HOME # Location of Java installation
+# JAVA_MIN_MEM # Minimum Java heap memory for the JVM
+# JAVA_MAX_MEM # Maximum Java heap memory for the JVM
+# DIRECT_MAX_MEM # Maximum direct buffer memory for the JVM
+# EXTRA_JAVA_OPTS # Additional JVM options
+# KARAF_HOME # Karaf home folder
+# KARAF_DATA # Karaf data folder
+# KARAF_BASE # Karaf base folder
+# KARAF_ETC # Karaf etc folder
+# KARAF_OPTS # Additional available Karaf options
+# KARAF_DEBUG # Enable debug mode
+# KARAF_REDIRECT # Enable/set the std/err redirection when using bin/start
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/bin/setenv.bat b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/bin/setenv.bat
new file mode 100644
index 0000000000000000000000000000000000000000..8da0cab48f83f3f1675cca0202c3717e4e3daff0
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/bin/setenv.bat
@@ -0,0 +1,44 @@
+@echo off
+rem
+rem handle specific scripts; the SCRIPT_NAME is exactly the name of the Karaf
+rem script; for example karaf.bat, start.bat, stop.bat, admin.bat, client.bat, ...
+rem
+rem if "%KARAF_SCRIPT%" == "SCRIPT_NAME" (
+rem Actions go here...
+rem )
+
+rem
+rem general settings which should be applied for all scripts go here; please keep
+rem in mind that it is possible that scripts might be executed more than once, e.g.
+rem in example of the start script where the start script is executed first and the
+rem karaf script afterwards.
+rem
+
+rem
+rem The following section shows the possible configuration options for the default
+rem karaf scripts
+rem
+rem Window name of the windows console
+rem SET KARAF_TITLE
+rem Location of Java installation
+rem SET JAVA_HOME
+rem Minimum Java heap memory for the JVM
+rem SET JAVA_MIN_MEM
+rem Maximum Java heap memory for the JVM
+rem SET JAVA_MAX_MEM
+rem Maximum direct buffer memory for the JVM
+rem SET DIRECT_MAX_MEM
+rem Additional JVM options
+rem SET EXTRA_JAVA_OPTS
+rem Karaf home folder
+rem SET KARAF_HOME
+rem Karaf data folder
+rem SET KARAF_DATA
+rem Karaf base folder
+rem SET KARAF_BASE
+rem Karaf etc folder
+rem SET KARAF_ETC
+rem Additional available Karaf options
+rem SET KARAF_OPTS
+rem Enable debug mode
+rem SET KARAF_DEBUG
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/deploy/.placeholder b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/deploy/.placeholder
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/fabric/ehcache.xml b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/fabric/ehcache.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8e9206d4dc0d65ecf7979e17eba06cc23b7e314a
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/fabric/ehcache.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+ 10000
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/fabric/elasticsearch.yml b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/fabric/elasticsearch.yml
new file mode 100644
index 0000000000000000000000000000000000000000..de6fd25e1b3b1e69520ab6d9726e9fc228ee29aa
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/fabric/elasticsearch.yml
@@ -0,0 +1,114 @@
+cluster.name: nexus
+
+path:
+ home: ${karaf.base}
+ conf: ${fabric.etc}
+ data: ${karaf.data}/elasticsearch
+ logs: ${karaf.data}/log
+ work: ${java.io.tmpdir}/elasticsearch
+
+node.data: true
+node.master: true
+
+# Disable groovy script integration
+script.groovy.sandbox.enabled: false
+
+# Disable networking
+node.local: true
+http.enabled: false
+discovery.zen.ping.multicast.enabled: false
+
+# ======================== Elasticsearch Configuration =========================
+#
+# NOTE: Elasticsearch comes with reasonable defaults for most settings.
+# Before you set out to tweak and tune the configuration, make sure you
+# understand what are you trying to accomplish and the consequences.
+#
+# The primary way of configuring a node is via this file. This template lists
+# the most important settings you may want to configure for a production cluster.
+#
+# Please see the documentation for further information on configuration options:
+#
+#
+# ---------------------------------- Cluster -----------------------------------
+#
+# Use a descriptive name for your cluster:
+#
+# cluster.name: my-application
+#
+# ------------------------------------ Node ------------------------------------
+#
+# Use a descriptive name for the node:
+#
+# node.name: node-1
+#
+# Add custom attributes to the node:
+#
+# node.rack: r1
+#
+# ----------------------------------- Paths ------------------------------------
+#
+# Path to directory where to store the data (separate multiple locations by comma):
+#
+# path.data: /path/to/data
+#
+# Path to log files:
+#
+# path.logs: /path/to/logs
+#
+# ----------------------------------- Memory -----------------------------------
+#
+# Lock the memory on startup:
+#
+# bootstrap.memory_lock: true
+#
+# Make sure that the `ES_HEAP_SIZE` environment variable is set to about half the memory
+# available on the system and that the owner of the process is allowed to use this limit.
+#
+# Elasticsearch performs poorly when the system is swapping the memory.
+#
+# ---------------------------------- Network -----------------------------------
+#
+# Set the bind address to a specific IP (IPv4 or IPv6):
+#
+# network.host: 192.168.0.1
+#
+# Set a custom port for HTTP:
+#
+# http.port: 9200
+#
+# For more information, see the documentation at:
+#
+#
+# --------------------------------- Discovery ----------------------------------
+#
+# Pass an initial list of hosts to perform discovery when new node is started:
+# The default list of hosts is ["127.0.0.1", "[::1]"]
+#
+# discovery.zen.ping.unicast.hosts: ["host1", "host2"]
+#
+# Prevent the "split brain" by configuring the majority of nodes (total number of nodes / 2 + 1):
+#
+# discovery.zen.minimum_master_nodes: 3
+#
+# For more information, see the documentation at:
+#
+#
+# ---------------------------------- Gateway -----------------------------------
+#
+# Block initial recovery after a full cluster restart until N nodes are started:
+#
+# gateway.recover_after_nodes: 3
+#
+# For more information, see the documentation at:
+#
+#
+# ---------------------------------- Various -----------------------------------
+#
+# Disable starting multiple nodes on a single system:
+#
+# node.max_local_storage_nodes: 1
+#
+# Require explicit names when deleting indices:
+#
+# action.destructive_requires_name: true
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/fabric/orientdb-security.json b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/fabric/orientdb-security.json
new file mode 100644
index 0000000000000000000000000000000000000000..010732bf7f962445769e70da5df8413d608f3b81
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/fabric/orientdb-security.json
@@ -0,0 +1,3 @@
+{
+ "enabled": false
+}
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty-http-redirect-to-https.xml b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty-http-redirect-to-https.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0c1ab9e3fdd0f8edee00578a282b44edc786e8e0
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty-http-redirect-to-https.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+ /*
+
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty-http.xml b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty-http.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ae159057c6438223f5962fd388a1bbc08195f8e3
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty-http.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty-https.xml b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty-https.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fa01fe9c26be4793f0e629269680083199d10714
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty-https.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+ https
+
+
+
+
+
+
+
+
+
+
+
+ /keystore.jks
+ password
+ password
+ /keystore.jks
+ password
+
+
+
+
+
+ SSL_RSA_WITH_DES_CBC_SHA
+ SSL_DHE_RSA_WITH_DES_CBC_SHA
+ SSL_DHE_DSS_WITH_DES_CBC_SHA
+ SSL_RSA_EXPORT_WITH_RC4_40_MD5
+ SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
+ SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
+ SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http/1.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty-requestlog.xml b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty-requestlog.xml
new file mode 100644
index 0000000000000000000000000000000000000000..46201535029cec545bea76b6fba88798a5c4be5a
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty-requestlog.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+ /logback-access.xml
+ true
+
+
+
+
+
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty.xml b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e51b7f3aa5cf4622b70ffa420ce2b73ed20c68e8
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/jetty.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+ /nexus-web.xml
+ /public
+
+ true
+
+
+ org.eclipse.jetty.webapp.WebXmlConfiguration
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+ 512
+
+
+
+
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/nexus-web.xml b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/nexus-web.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6d5a48980471d3685e9a9a999c5dc90fb7bb76e3
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/jetty/nexus-web.xml
@@ -0,0 +1,32 @@
+
+
+
+ Sonatype Nexus
+
+
+ org.sonatype.nexus.bootstrap.osgi.BootstrapListener
+
+
+
+ nexusFilter
+ org.sonatype.nexus.bootstrap.osgi.DelegatingFilter
+
+
+
+ nexusFilter
+ /*
+ REQUEST
+ ERROR
+
+
+
+ index.html
+
+
+
+ /error.html
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/config.properties b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/config.properties
new file mode 100644
index 0000000000000000000000000000000000000000..3a36a934d9f15936975a559da7d3ca09a7e427f5
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/config.properties
@@ -0,0 +1,215 @@
+#
+# This file lists Karaf default settings for this particular version of Karaf.
+# For easier maintenance when upgrading Karaf and to better document which
+# default values have changed, it is recommended to place any changes to
+# these values in a custom.properties file in the same folder as this file.
+# Each value specified in custom.properties will override the default value
+# here.
+#
+
+#
+# Properties file inclusions (as a space separated list of relative paths)
+# Included files will override the values specified in this file
+# NB: ${includes} properties files are mandatory, it means that Karaf will not start
+# if the include file is not found
+#
+${includes} = jre.properties custom.properties
+
+#
+# Properties file inclusions (as a space separated list of relative paths)
+# Included files will override the values specified in this file
+# NB: ${optionals} properties files are optionals, it means that Karaf will just
+# display a warning message but the bootstrap will be performed
+#
+# ${optionals} = my.properties
+
+#
+# Framework selection properties
+#
+karaf.framework=felix
+
+#
+# Location of the OSGi frameworks
+#
+karaf.framework.equinox=mvn\:org.eclipse.birt.runtime/org.eclipse.osgi/3.10.2.v20150203-1939
+karaf.framework.felix=mvn\:org.apache.felix/org.apache.felix.framework/5.6.2
+
+#
+# Framework config properties.
+#
+org.osgi.framework.system.packages= \
+ org.osgi.dto;version="1.0",\
+ org.osgi.resource;version="1.0",\
+ org.osgi.resource.dto;version="1.0";uses:="org.osgi.dto",\
+ org.osgi.framework;version="1.8",\
+ org.osgi.framework.dto;version="1.8";uses:="org.osgi.dto",\
+ org.osgi.framework.hooks.bundle;version="1.1";uses:="org.osgi.framework",\
+ org.osgi.framework.hooks.resolver;version="1.0";uses:="org.osgi.framework.wiring",\
+ org.osgi.framework.hooks.service;version="1.1";uses:="org.osgi.framework",\
+ org.osgi.framework.hooks.weaving;version="1.1";uses:="org.osgi.framework.wiring",\
+ org.osgi.framework.launch;version="1.2";uses:="org.osgi.framework",\
+ org.osgi.framework.namespace;version="1.1";uses:="org.osgi.resource",\
+ org.osgi.framework.startlevel;version="1.0";uses:="org.osgi.framework",\
+ org.osgi.framework.startlevel.dto;version="1.0";uses:="org.osgi.dto",\
+ org.osgi.framework.wiring;version="1.2";uses:="org.osgi.framework,org.osgi.resource",\
+ org.osgi.framework.wiring.dto;version="1.2";uses:="org.osgi.dto,org.osgi.resource.dto",\
+ org.osgi.service.condpermadmin;version="1.1.1";uses:="org.osgi.framework,org.osgi.service.permissionadmin",\
+ org.osgi.service.packageadmin;version="1.2";uses:="org.osgi.framework",org.osgi.service.permissionadmin;version="1.2",\
+ org.osgi.service.resolver;version="1.0";uses:="org.osgi.resource",\
+ org.osgi.service.startlevel;version="1.1";uses:="org.osgi.framework",\
+ org.osgi.service.url;version="1.0",\
+ org.osgi.util.tracker;version="1.5.1";uses:="org.osgi.framework",\
+ org.apache.karaf.version;version="4.0.9",\
+ org.apache.karaf.diagnostic.core.common;uses:=org.apache.karaf.diagnostic.core;version="4.0.9",\
+ org.apache.karaf.diagnostic.core;uses:=org.osgi.framework;version="4.0.9",\
+ org.apache.karaf.jaas.boot.principal;uses:=javax.security.auth;version="4.0.9",\
+ org.apache.karaf.jaas.boot;uses:="javax.security.auth,javax.security.auth.callback,javax.security.auth.login,javax.security.auth.spi,org.osgi.framework";version="4.0.9",\
+ ${jre-${java.specification.version}}
+
+#
+# Extra packages appended after standard packages
+#
+org.osgi.framework.system.packages.extra= \
+ sun.security.ssl, \
+ com.sun.net.httpserver, \
+ javax.annotation;version=1.2, \
+ javax.annotation.meta;version=1.2, \
+ javax.annotation.security;version=1.2, \
+ org.bouncycastle.asn1;version=1.56, \
+ org.bouncycastle.asn1.x500;version=1.56, \
+ org.bouncycastle.asn1.x509;version=1.56, \
+ org.bouncycastle.cert;version=1.56, \
+ org.bouncycastle.cert.jcajce;version=1.56, \
+ org.bouncycastle.crypto.prng;version=1.56, \
+ org.bouncycastle.jce.provider;version=1.56, \
+ org.bouncycastle.openssl;version=1.56, \
+ org.bouncycastle.openssl.jcajce;version=1.56, \
+ org.bouncycastle.openpgp;version=1.56, \
+ org.bouncycastle.openpgp.operator;version=1.56, \
+ org.bouncycastle.operator;version=1.56, \
+ org.bouncycastle.operator.jcajce;version=1.56, \
+ org.bouncycastle.util.encoders;version=1.56, \
+ org.bouncycastle.x509;version=1.56, \
+ org.xerial.snappy, \
+ org.apache.karaf.branding, \
+ sun.misc, \
+ sun.nio.ch
+
+org.osgi.framework.system.capabilities= \
+ ${eecap-${java.specification.version}}, \
+ osgi.service;effective:=active;objectClass=org.osgi.service.packageadmin.PackageAdmin, \
+ osgi.service;effective:=active;objectClass=org.osgi.service.resolver.Resolver, \
+ osgi.service;effective:=active;objectClass=org.osgi.service.startlevel.StartLevel, \
+ osgi.service;effective:=active;objectClass=org.osgi.service.url.URLHandlers
+
+eecap-1.8= osgi.ee; osgi.ee="OSGi/Minimum"; version:List="1.0,1.1,1.2", \
+ osgi.ee; osgi.ee="JavaSE"; version:List="1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8"
+eecap-1.7= osgi.ee; osgi.ee="OSGi/Minimum"; version:List="1.0,1.1,1.2", \
+ osgi.ee; osgi.ee="JavaSE"; version:List="1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7"
+eecap-1.6= osgi.ee; osgi.ee="OSGi/Minimum"; version:List="1.0,1.1,1.2", \
+ osgi.ee; osgi.ee="JavaSE"; version:List="1.0,1.1,1.2,1.3,1.4,1.5,1.6"
+eecap-1.5= osgi.ee; osgi.ee="OSGi/Minimum"; version:List="1.0,1.1,1.2", \
+ osgi.ee; osgi.ee="JavaSE"; version:List="1.0,1.1,1.2,1.3,1.4,1.5"
+eecap-1.4= osgi.ee; osgi.ee="OSGi/Minimum"; version:List="1.0,1.1,1.2", \
+ osgi.ee; osgi.ee="JavaSE"; version:List="1.0,1.1,1.2,1.3,1.4"
+eecap-1.3= osgi.ee; osgi.ee="OSGi/Minimum"; version:List="1.0,1.1", \
+ osgi.ee; osgi.ee="JavaSE"; version:List="1.0,1.1,1.2,1.3"
+eecap-1.2= osgi.ee; osgi.ee="OSGi/Minimum"; version:List="1.0,1.1", \
+ osgi.ee; osgi.ee="JavaSE"; version:List="1.0,1.1,1.2"
+
+#
+# javax.transaction is needed to avoid class loader constraint violation when using javax.sql
+#
+org.osgi.framework.bootdelegation=\
+ com.sun.*, \
+ javax.transaction, \
+ javax.transaction.*, \
+ javax.xml.crypto, \
+ javax.xml.crypto.*, \
+ sun.*
+
+# jVisualVM support
+# in order to use Karaf with jvisualvm, the org.osgi.framework.bootdelegation property has to contain the org.netbeans.lib.profiler.server package
+# and, so, it should look like:
+#
+# org.osgi.framework.bootdelegation=org.apache.karaf.jaas.boot,org.apache.karaf.jaas.boot.principal,sun.*,com.sun.*,javax.transaction,javax.transaction.*,javax.xml.crypto,javax.xml.crypto.*,org.netbeans.lib.profiler.server
+#
+# YourKit support
+# in order to use Karaf with YourKit, the org.osgi.framework.bootdelegation property has to contain the com.yourkit.* packages
+#Â and, so, it should look like:
+#
+# org.osgi.framework.bootdelegation=org.apache.karaf.jaas.boot,org.apache.karaf.jaas.boot.principal,sun.*,com.sun.*,javax.transaction,javax.transaction.*,javax.xml.crypto,javax.xml.crypto.*,com.yourkit.*
+#
+
+#
+# OSGi Execution Environment
+#
+org.osgi.framework.executionenvironment=J2SE-1.8,JavaSE-1.8,J2SE-1.7,JavaSE-1.7,J2SE-1.6,JavaSE-1.6,J2SE-1.5,JavaSE-1.5,J2SE-1.4,JavaSE-1.4,J2SE-1.3,JavaSE-1.3,J2SE-1.2,,JavaSE-1.2,CDC-1.1/Foundation-1.1,CDC-1.0/Foundation-1.0,J2ME,OSGi/Minimum-1.1,OSGi/Minimum-1.0
+
+#
+# Set the parent classloader for the bundle to the classloader that loads the Framework (i.e. everything in lib/*.jar)
+#
+org.osgi.framework.bundle.parent=framework
+
+#
+# Definition of the default bundle start level
+#
+org.osgi.framework.startlevel.beginning=100
+karaf.startlevel.bundle=80
+
+#
+# The location of the Karaf shutdown port file
+#
+karaf.shutdown.port.file=${karaf.data}/port
+
+#
+# Configuration FileMonitor properties
+#
+felix.fileinstall.enableConfigSave = true
+felix.fileinstall.dir = ${karaf.etc}
+felix.fileinstall.filter = .*\\.cfg
+felix.fileinstall.poll = 1000
+felix.fileinstall.noInitialDelay = true
+felix.fileinstall.log.level = 3
+felix.fileinstall.log.default = jul
+
+# Use cached urls for bundle CodeSource to avoid
+# problems with JCE cached informations, see KARAF-3974
+felix.bundlecodesource.usecachedurls = true
+
+#
+# Delay for writing the framework state to disk in equinox
+# must be >= 1000 and <= 1800000
+#
+eclipse.stateSaveDelayInterval = 1000
+
+#
+# OBR Repository list
+# This property will be modified by the obr:addUrl and obr:removeUrl commands.
+#
+obr.repository.url =
+
+#
+# Start blueprint bundles synchronously when possible
+#
+org.apache.aries.blueprint.synchronous=true
+
+#
+# Do not weave all any classes by default
+#
+org.apache.aries.proxy.weaving.enabled=
+
+#
+# mvn url handler requires config instance configuration
+#
+#org.ops4j.pax.url.mvn.requireConfigAdminConfig=true
+
+#
+# Don't delay the console startup. Set to true if you want the console to start after all other bundles
+#
+karaf.delay.console=false
+
+#
+# shutdown command, change if needed
+#
+karaf.shutdown.command=faRcsbjiOtDfNuIR49fQJVav6D191MXIUTSWeh0rOnRNlRF8R1eVDgMASDTMkJgR
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/custom.properties b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/custom.properties
new file mode 100644
index 0000000000000000000000000000000000000000..c9049af2f11161dacfc1ad722d410e4427acae3f
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/custom.properties
@@ -0,0 +1,22 @@
+#
+# All the values specified here will override the default values given
+# in config.properties.
+#
+
+karaf.systemBundlesStartLevel=50
+
+#
+# You can place any customized configuration here.
+#
+
+# A very small amount of logging before pax-logging is enabled ends up here
+karaf.bootstrap.log=${karaf.data}/log/karaf.log
+
+# early load of mvn: protocol config
+${includes}=org.ops4j.pax.url.mvn.cfg
+
+karaf.lock.class=org.sonatype.nexus.karaf.NexusFileLock
+
+# Temporary workaround for https://issues.apache.org/jira/browse/FELIX-5184
+felix.native.osname.alias.windowsserver2012=windows server 2012,win32
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/java.util.logging.properties b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/java.util.logging.properties
new file mode 100644
index 0000000000000000000000000000000000000000..c8d5d5f4b9ab0a98c9e31c853a18dcc1a9eaba62
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/java.util.logging.properties
@@ -0,0 +1,4 @@
+# Empty java.util.logging.properties to prevent the log to stderr, so that
+# all logs will be delegated to pax logging JUL handler only
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/jmx.acl.cfg b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/jmx.acl.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..f74b37a8077af4cda7d12623cea924c6abdc2205
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/jmx.acl.cfg
@@ -0,0 +1,54 @@
+#
+# Generic JMX ACL
+#
+# This file defines the roles required for MBean operations for MBeans that
+# do not have this defined explicitly.
+#
+# The definition of ACLs for JMX operations works as follows:
+#
+# The required roles for JMX operations are defined in configuration files
+# read via OSGi ConfigAdmin.
+#
+# JMX RBAC-related configuration is prefixed with jmx.acl and based on the
+# JMX ObjectName that it applies to. For example specific configuration for
+# an MBean with the following objectName: foo.bar:type=Test can be placed in
+# a configuration file called jmx.acl.foo.bar.Test.cfg. More generic
+# configuration can be placed in the domain (e.g. jmx.acl.foo.bar.cfg) or
+# at the top level (jmx.acl.cfg). A simple configuration file looks like
+# this:
+# test : admin
+# getVal : manager, viewer
+#
+# The system looks for required roles using the following process:
+# The most specific configuration file/pid is tried first. E.g. in the
+# above example the jmx.acl.foo.bar.Test.cfg is looked at first. In this
+# configuration, the system looks for a:
+# 1. Specific match for the current invocation, e.g. test(int)["17"] : role1
+# 2. Reg exp match for the current invocation, e.g. test(int)[/[0-9]/] : role2
+# In both cases the passed argument is converted to a String for the
+# comparison.
+# If any of the above match all the roles with matching definitions
+# are collected and allowed. If no matches are found the following is tried:
+# 3. Signature match for the invocation, e.g. test(int) : role3. If
+# matched the associated roles are used.
+# 4. Method name match for the invocation, e.g. test : role4. If matched
+# the associated roles are used.
+# 5. A method name wildcard match, e.g. te* : role5. For all the
+# wildcard matches found in the current configuration file, the roles
+# associated with the longest match are used. So if you have te* and * and
+# the method invoked is 'test', then the roles defined with te* are used,
+# not the ones defined with *.
+# If no matching definition is found in the current configuration file, a
+# more general configuration file is looked for. So jmx.acl.foo.bar.cfg is
+# tried next, this matches the domain of the MBean. If there is no match
+# found in the domain the most generic configuration file is consulted
+# (jmx.acl.cfg).
+# If a matching definition is found, this is used and the process will not
+# look for any other matching definitions. So the most specific definition
+# always takes precedence.
+#
+list* = viewer
+get* = viewer
+is* = viewer
+set* = admin
+* = admin
\ No newline at end of file
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.felix.fileinstall-deploy.cfg b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.felix.fileinstall-deploy.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..3a13eb8c8bbe772a8f9cce448b3f88b2f572b31a
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.felix.fileinstall-deploy.cfg
@@ -0,0 +1,10 @@
+#
+# Hot deployment of bundles
+#
+
+felix.fileinstall.dir=${karaf.base}/deploy
+felix.fileinstall.tmpdir=${karaf.data}/generated-bundles
+felix.fileinstall.poll=1000
+felix.fileinstall.active.level=80
+felix.fileinstall.start.level=200
+felix.fileinstall.log.level=3
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.jaas.cfg b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.jaas.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..5551593637aed0f3b14b91cb9dc594973bc64eaf
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.jaas.cfg
@@ -0,0 +1,42 @@
+#
+# Boolean enabling / disabling encrypted passwords
+#
+encryption.enabled = false
+
+#
+# Encryption Service name
+# the default one is 'basic'
+# a more powerful one named 'jasypt' is available
+# when installing the encryption feature
+#
+encryption.name =
+
+#
+# Encryption prefix
+#
+encryption.prefix = {CRYPT}
+
+#
+# Encryption suffix
+#
+encryption.suffix = {CRYPT}
+
+#
+# Set the encryption algorithm to use in Karaf JAAS login module
+# Supported encryption algorithms follow:
+# MD2
+# MD5
+# SHA-1
+# SHA-256
+# SHA-384
+# SHA-512
+#
+encryption.algorithm = MD5
+
+#
+# Encoding of the encrypted password.
+# Can be:
+# hexadecimal
+# base64
+#
+encryption.encoding = hexadecimal
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.kar.cfg b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.kar.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..cd34c462c7fafb2e2cfe8bbd84bfd6cce6fd6a6e
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.kar.cfg
@@ -0,0 +1,5 @@
+#
+# Enable or disable the refresh of the bundles when installing
+# the features contained in a KAR file
+#
+noAutoRefreshBundles=false
\ No newline at end of file
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.log.cfg b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.log.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..75cbb8d007649282cd04b5a0cdbdbb82e2d2fe53
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.log.cfg
@@ -0,0 +1,14 @@
+#
+# This configuration file is used to configure the default values for the log:display
+# and log:exception-display commands.
+#
+
+# The number of log statements to be displayed using log:display
+size=500
+
+# this matches the pattern in logback.xml with a few caveats
+# the date %d parameter is split up to avoid quoting in output
+# the %n parameter is omitted to avoid duplicate new lines
+# the %thread parameter becomes %t
+# the %mdc parameter becomes %X and doesn't have a default value
+pattern=%d{yyyy-MM-dd} %d{HH:mm:ss,SSSZ} %-5p [%t] %X{userId} %c - %m
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.management.cfg b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.management.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..b17e007de97ac52c7c484a558f67763d6bc7ebb1
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.management.cfg
@@ -0,0 +1,48 @@
+#
+# The properties in this file define the configuration of Apache Karaf's JMX Management
+#
+
+#
+# Port number for RMI registry connection
+#
+rmiRegistryPort = 8099
+
+#
+# Host for RMI registry
+#
+rmiRegistryHost = 0.0.0.0
+
+#
+# Port number for RMI server connection
+#
+rmiServerPort = 8044
+
+#
+# Host for RMI server
+#
+rmiServerHost = 0.0.0.0
+
+#
+# Name of the JAAS realm used for authentication
+#
+jmxRealm = shiro
+
+#
+# The service URL for the JMXConnectorServer
+#
+serviceUrl = service:jmx:rmi://${rmiServerHost}:${rmiServerPort}/jndi/rmi://${rmiRegistryHost}:${rmiRegistryPort}/karaf-${karaf.name}
+
+#
+# Whether any threads started for the JMXConnectorServer should be started as daemon threads
+#
+daemon = true
+
+#
+# Whether the JMXConnectorServer should be started in a separate thread
+#
+threaded = true
+
+#
+# The ObjectName used to register the JMXConnectorServer
+#
+objectName = connector:name=rmi
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.service.acl.command.cfg b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.service.acl.command.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..766e4053da4ed76ded1113be4d3db14c259b45d4
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.service.acl.command.cfg
@@ -0,0 +1,5 @@
+#
+# Restrict all shell commands to admin role by default
+#
+service.guard = (&(osgi.command.scope=*)(osgi.command.function=*))
+execute = admin
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.shell.cfg b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.shell.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..0c982b7d2ac267e5df13d9db2758f3fd35533313
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.apache.karaf.shell.cfg
@@ -0,0 +1,61 @@
+#
+# These properties are used to configure Karaf's ssh shell.
+#
+
+#
+# Via sshPort and sshHost you define the address you can login into Karaf.
+#
+sshPort = 8022
+sshHost = 0.0.0.0
+
+#
+# The sshIdleTimeout defines the inactivity timeout to logout the SSH session.
+# The sshIdleTimeout is in milliseconds, and the default is set to 30 minutes.
+#
+sshIdleTimeout = 1800000
+
+#
+# sshRealm defines which JAAS domain to use for password authentication.
+#
+sshRealm = shiro
+
+#
+# The location of the hostKey file defines where the private/public key of the server
+# is located. If no file is at the defined location it will be ignored.
+#
+hostKey = ${karaf.data}/host.key
+
+#
+# The format used for hostKey.
+#Â Possible values are simple (Karaf internal), or PEM (OpenSSH format)
+#
+hostKeyFormat = simple
+
+#
+# Self defined key size in 1024, 2048, 3072, or 4096
+# If not set, this defaults to 4096.
+#
+# keySize = 4096
+
+#
+# Specify host key algorithm, defaults to RSA
+#
+# algorithm = RSA
+
+#
+# Specify an additional welcome banner to be displayed when a user logs into the server.
+#
+# welcomeBanner =
+
+#
+# Defines the completion mode on the Karaf shell console. The possible values are:
+# - GLOBAL: it's the same behavior as in previous Karaf releases. The completion displays all commands and all aliases
+# ignoring if you are in a subshell or not.
+# - FIRST: the completion displays all commands and all aliases only when you are not in a subshell. When you are
+# in a subshell, the completion displays only the commands local to the subshell.
+# - SUBSHELL: the completion displays only the subshells on the root level. When you are in a subshell, the completion
+# displays only the commands local to the subshell.
+# This property define the default value when you use the Karaf shell console.
+# You can change the completion mode directly in the shell console, using shell:completion command.
+#
+completionMode = GLOBAL
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.ops4j.pax.url.mvn.cfg b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.ops4j.pax.url.mvn.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..13f5deecbfaa8d8c17ea8c81964d3f944122e806
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/org.ops4j.pax.url.mvn.cfg
@@ -0,0 +1,78 @@
+##########################################################################
+# customized to only lookup bundles from the assembled system repository #
+##########################################################################
+
+#
+# If set to true, the following property will not allow any certificate to be used
+# when accessing Maven repositories through SSL
+#
+#org.ops4j.pax.url.mvn.certificateCheck=
+
+#
+# Path to the local Maven settings file.
+# The repositories defined in this file will be automatically added to the list
+# of default repositories if the 'org.ops4j.pax.url.mvn.repositories' property
+# below is not set.
+# The following locations are checked for the existence of the settings.xml file
+# * 1. looks for the specified url
+# * 2. if not found looks for ${user.home}/.m2/settings.xml
+# * 3. if not found looks for ${maven.home}/conf/settings.xml
+# * 4. if not found looks for ${M2_HOME}/conf/settings.xml
+#
+# Default to empty settings file, comment this out to pick up your local Maven settings
+org.ops4j.pax.url.mvn.settings=${karaf.base}/${karaf.default.repository}/settings.xml
+
+#
+# Path to the local Maven repository which is used to avoid downloading
+# artifacts when they already exist locally.
+# The value of this property will be extracted from the settings.xml file
+# above, or defaulted to:
+# System.getProperty( "user.home" ) + "/.m2/repository"
+#
+# Default to Karaf's system repository, comment this out to use your local repository
+org.ops4j.pax.url.mvn.localRepository=file:${karaf.base}/${karaf.default.repository}
+
+#
+# Default this to false. It's just weird to use undocumented repos
+#
+org.ops4j.pax.url.mvn.useFallbackRepositories=false
+
+#
+# Uncomment if you don't wanna use the proxy settings
+# from the Maven conf/settings.xml file
+#
+org.ops4j.pax.url.mvn.proxySupport=false
+
+#
+# Comma separated list of repositories scanned when resolving an artifact.
+# Those repositories will be checked before iterating through the
+# below list of repositories and even before the local repository
+# A repository url can be appended with zero or more of the following flags:
+# @snapshots : the repository contains snapshots
+# @noreleases : the repository does not contain any released artifacts
+#
+# The following property value will add the system folder as a repo.
+#
+org.ops4j.pax.url.mvn.defaultRepositories=\
+ file:${karaf.base}/${karaf.default.repository}@id=system.repository@snapshots
+
+# Use the default local repo (e.g.~/.m2/repository) as a "remote" repo
+#org.ops4j.pax.url.mvn.defaultLocalRepoAsRemote=
+
+#
+# Comma separated list of repositories scanned when resolving an artifact.
+# A repository url can be appended with zero or more of the following flags:
+# @snapshots : the repository contains snapshots
+# @noreleases : the repository does not contain any released artifacts
+# @id=repoid : the id for the repository, just like in the settings.xml this is optional but recommended
+#
+# The default list doesn't contain any snapshot repositories as it can impact artifact resolution.
+# During development you may want to add the following repositories containing snapshots:
+# https://repository.apache.org/content/groups/snapshots-group@id=apache@snapshots@noreleases
+# https://oss.sonatype.org/content/repositories/snapshots@id=sonatype@snapshots@norelease
+# https://oss.sonatype.org/content/repositories/ops4j-snapshots@id=ops4j@snapshots@noreleases
+#
+# If you want to install additional bundles from central add this entry to the list:
+# https://repo1.maven.org/maven2@id=central
+#
+org.ops4j.pax.url.mvn.repositories=
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/shell.init.script b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/shell.init.script
new file mode 100644
index 0000000000000000000000000000000000000000..ea402718c40db717cab9135793c1d0261a29e770
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/shell.init.script
@@ -0,0 +1,15 @@
+//
+// This script is run each time a shell is created.
+// You can define here closures or variables that will be available
+// in each session.
+//
+ld = { log:display $args } ;
+lde = { log:exception-display $args } ;
+la = { bundle:list -t 0 $args } ;
+ls = { service:list $args } ;
+cl = { config:list "(service.pid=$args)" } ;
+halt = { system:shutdown -h -f $args } ;
+help = { *:help $args | more } ;
+man = { help $args } ;
+log:list = { log:get ALL } ;
+service:get = { $.context getService ($.context getServiceReference $args) };
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/system.properties b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/system.properties
new file mode 100644
index 0000000000000000000000000000000000000000..58a4a75cc478977532815456b6e2e5d21200a137
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/karaf/system.properties
@@ -0,0 +1,122 @@
+#
+# The properties defined in this file will be made available through system
+# properties at the very beginning of the Karaf's boot process.
+#
+
+
+# Log level when the pax-logging service is not available
+# This level will only be used while the pax-logging service bundle
+# is not fully available.
+# To change log levels, please refer to the org.ops4j.pax.logging.cfg file
+# instead.
+org.ops4j.pax.logging.DefaultServiceLog.level = ERROR
+
+#
+# Name of this Karaf instance.
+#
+karaf.name = root
+
+#
+# Default repository where bundles will be loaded from before using
+# other Maven repositories. For the full Maven configuration, see
+# the org.ops4j.pax.url.mvn.cfg file.
+#
+karaf.default.repository = system
+
+#
+# Location of a shell script that will be run when starting a shell
+# session. This script can be used to create aliases and define
+# additional commands.
+#
+karaf.shell.init.script = ${karaf.etc}/shell.init.script
+
+#
+# Sets the maximum size of the shell command history. If not set,
+# defaults to 500 entries. Setting to 0 will disable history.
+#
+# karaf.shell.history.maxSize = 0
+
+#
+# Deletes the entire karaf.data directory at every start
+#
+karaf.clean.all = false
+
+#
+# Deletes the karaf.data/cache directory at every start
+#
+karaf.clean.cache = true
+
+#
+# User name for the Karaf local console
+#
+karaf.local.user = karaf
+
+#
+# Roles to use when logging into a local Karaf console.
+#
+# The syntax is the following:
+# [classname:]principal
+# where classname is the class name of the principal object
+# (defaults to org.apache.karaf.jaas.modules.RolePrincipal)
+# and principal is the name of the principal of that class
+# (defaults to instance).
+#
+karaf.local.roles = admin,manager,viewer,systembundles
+
+#
+# Set this empty property to avoid errors when validating xml documents.
+#
+xml.catalog.files =
+
+#
+# Suppress the bell in the console when hitting backspace too many times
+# for example
+#
+jline.nobell = true
+
+#
+# ServiceMix specs options
+#
+org.apache.servicemix.specs.debug = false
+org.apache.servicemix.specs.timeout = 0
+
+#
+# Settings for the OSGi 4.3 Weaving
+# By default, we will not weave any classes. Change this setting to include classes
+# that you application needs to have woven.
+#
+org.apache.aries.proxy.weaving.enabled = none
+# Classes not to weave - Aries default + Xerces which is known to have issues.
+org.apache.aries.proxy.weaving.disabled = org.objectweb.asm.*,org.slf4j.*,org.apache.log4j.*,javax.*,org.apache.xerces.*
+
+#
+# By default, only Karaf shell commands are secured, but additional services can be
+# secured by expanding this filter
+#
+karaf.secured.services = (&(osgi.command.scope=*)(osgi.command.function=*))
+
+karaf.history=${user.home}/.nexus/karaf.history
+
+java.awt.headless=true
+networkaddress.cache.ttl=3600
+
+com.sun.jndi.ldap.connect.pool.protocol=plain ssl
+
+org.ops4j.pax.logging.StaticLogbackContext=true
+org.ops4j.pax.logging.StaticLogbackFile=${logback.etc}/logback.xml
+org.jboss.logging.provider=slf4j
+
+# orientdb direct-memory chunk size in bytes
+memory.chunk.size=268435456
+
+# orientdb memory checker interval, in milliseconds (60 minutes)
+profiler.memoryCheckInterval=3600000
+
+# orientdb: temporary workaround for NEXUS-14409
+distributed.checkIntegrityLastTxs=0
+
+# orientdb: NEXUS-14843
+index.cursor.prefetchSize=10000
+
+# orientdb: NEXUS-10402
+distributed.shutdownTimeout=20000
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/logback/logback-access.xml b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/logback/logback-access.xml
new file mode 100644
index 0000000000000000000000000000000000000000..05971e96b348e614ed0e4f8426c6cfced96a70b5
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/logback/logback-access.xml
@@ -0,0 +1,16 @@
+
+
+
+ ${karaf.data}/log/request.log
+ true
+
+ %clientHost %l %user [%date] "%requestURL" %statusCode %bytesSent %elapsedTime "%header{User-Agent}"
+
+
+ ${karaf.data}/log/request-%d{yyyy-MM-dd}.log.gz
+ 90
+
+
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/logback/logback.xml b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/logback/logback.xml
new file mode 100644
index 0000000000000000000000000000000000000000..576ddc4e3028dfea5f6a240e3b0f6d5ad979c7f5
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/logback/logback.xml
@@ -0,0 +1,67 @@
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+ %d{"yyyy-MM-dd HH:mm:ss,SSSZ"} %-5p [%thread] %mdc{userId:-*SYSTEM} %c - %m%n
+
+
+
+
+ ${karaf.data}/log/nexus.log
+ true
+
+ %d{"yyyy-MM-dd HH:mm:ss,SSSZ"} %-5p [%thread] %node %mdc{userId:-*SYSTEM} %c - %m%n
+
+
+ ${karaf.data}/log/nexus-%d{yyyy-MM-dd}.log.gz
+ 90
+
+
+
+
+
+
+
+ taskIdAndDate
+ unknown
+
+
+
+ ${karaf.data}/log/tasks/${taskIdAndDate}.log
+
+ %d{"yyyy-MM-dd HH:mm:ss,SSSZ"} %-5p [%thread] %node %mdc{userId:-*SYSTEM} %c - %m%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/nexus-default.properties b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/nexus-default.properties
new file mode 100644
index 0000000000000000000000000000000000000000..76543378170398884e66ccb19ee61838ad973fd3
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/nexus-default.properties
@@ -0,0 +1,14 @@
+## DO NOT EDIT - CUSTOMIZATIONS BELONG IN $data-dir/etc/nexus.properties
+##
+# Jetty section
+application-port=8081
+application-host=0.0.0.0
+nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-requestlog.xml
+nexus-context-path=/
+
+# Nexus section
+nexus-edition=nexus-oss-edition
+nexus-features=\
+ nexus-core-feature
+
+nexus.upgrade.warnOnMissingDependencies=true
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/ssl/.placeholder b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/etc/ssl/.placeholder
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/COPYRIGHT.html b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/COPYRIGHT.html
new file mode 100644
index 0000000000000000000000000000000000000000..661315bbc3abd1d0a296731e294e28db3c0d1da8
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/COPYRIGHT.html
@@ -0,0 +1,33 @@
+
+
+
+
+ Copyright
+
+
+
+
+ Sonatype and Sonatype Nexus are trademarks of Sonatype, Inc.
+
+ Apache Maven is a trademark of the Apache Foundation.
+
+ M2Eclipse is a trademark of the Eclipse Foundation.
+
+ All other trademarks are the property of their respective owners.
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/LICENSE.html b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/LICENSE.html
new file mode 100644
index 0000000000000000000000000000000000000000..3998fcebeebe4d34f47c8777b4db160be1d1dec1
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/LICENSE.html
@@ -0,0 +1,261 @@
+
+
+
+
+
+
+Eclipse Public License - Version 1.0
+
+
+
+
+
+
+
Eclipse Public License - v 1.0
+
+
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR
+DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS
+AGREEMENT.
+
+
1. DEFINITIONS
+
+
"Contribution" means:
+
+
a) in the case of the initial Contributor, the initial
+code and documentation distributed under this Agreement, and
+
b) in the case of each subsequent Contributor:
+
i) changes to the Program, and
+
ii) additions to the Program;
+
where such changes and/or additions to the Program
+originate from and are distributed by that particular Contributor. A
+Contribution 'originates' from a Contributor if it was added to the
+Program by such Contributor itself or anyone acting on such
+Contributor's behalf. Contributions do not include additions to the
+Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii)
+are not derivative works of the Program.
+
+
"Contributor" means any person or entity that distributes
+the Program.
+
+
"Licensed Patents" mean patent claims licensable by a
+Contributor which are necessarily infringed by the use or sale of its
+Contribution alone or when combined with the Program.
+
+
"Program" means the Contributions distributed in accordance
+with this Agreement.
+
+
"Recipient" means anyone who receives the Program under
+this Agreement, including all Contributors.
+
+
2. GRANT OF RIGHTS
+
+
a) Subject to the terms of this Agreement, each
+Contributor hereby grants Recipient a non-exclusive, worldwide,
+royalty-free copyright license to reproduce, prepare derivative works
+of, publicly display, publicly perform, distribute and sublicense the
+Contribution of such Contributor, if any, and such derivative works, in
+source code and object code form.
+
+
b) Subject to the terms of this Agreement, each
+Contributor hereby grants Recipient a non-exclusive, worldwide,
+royalty-free patent license under Licensed Patents to make, use, sell,
+offer to sell, import and otherwise transfer the Contribution of such
+Contributor, if any, in source code and object code form. This patent
+license shall apply to the combination of the Contribution and the
+Program if, at the time the Contribution is added by the Contributor,
+such addition of the Contribution causes such combination to be covered
+by the Licensed Patents. The patent license shall not apply to any other
+combinations which include the Contribution. No hardware per se is
+licensed hereunder.
+
+
c) Recipient understands that although each Contributor
+grants the licenses to its Contributions set forth herein, no assurances
+are provided by any Contributor that the Program does not infringe the
+patent or other intellectual property rights of any other entity. Each
+Contributor disclaims any liability to Recipient for claims brought by
+any other entity based on infringement of intellectual property rights
+or otherwise. As a condition to exercising the rights and licenses
+granted hereunder, each Recipient hereby assumes sole responsibility to
+secure any other intellectual property rights needed, if any. For
+example, if a third party patent license is required to allow Recipient
+to distribute the Program, it is Recipient's responsibility to acquire
+that license before distributing the Program.
+
+
d) Each Contributor represents that to its knowledge it
+has sufficient copyright rights in its Contribution, if any, to grant
+the copyright license set forth in this Agreement.
+
+
3. REQUIREMENTS
+
+
A Contributor may choose to distribute the Program in object code
+form under its own license agreement, provided that:
+
+
a) it complies with the terms and conditions of this
+Agreement; and
+
+
b) its license agreement:
+
+
i) effectively disclaims on behalf of all Contributors
+all warranties and conditions, express and implied, including warranties
+or conditions of title and non-infringement, and implied warranties or
+conditions of merchantability and fitness for a particular purpose;
+
+
ii) effectively excludes on behalf of all Contributors
+all liability for damages, including direct, indirect, special,
+incidental and consequential damages, such as lost profits;
+
+
iii) states that any provisions which differ from this
+Agreement are offered by that Contributor alone and not by any other
+party; and
+
+
iv) states that source code for the Program is available
+from such Contributor, and informs licensees how to obtain it in a
+reasonable manner on or through a medium customarily used for software
+exchange.
+
+
When the Program is made available in source code form:
+
+
a) it must be made available under this Agreement; and
+
+
b) a copy of this Agreement must be included with each
+copy of the Program.
+
+
Contributors may not remove or alter any copyright notices contained
+within the Program.
+
+
Each Contributor must identify itself as the originator of its
+Contribution, if any, in a manner that reasonably allows subsequent
+Recipients to identify the originator of the Contribution.
+
+
4. COMMERCIAL DISTRIBUTION
+
+
Commercial distributors of software may accept certain
+responsibilities with respect to end users, business partners and the
+like. While this license is intended to facilitate the commercial use of
+the Program, the Contributor who includes the Program in a commercial
+product offering should do so in a manner which does not create
+potential liability for other Contributors. Therefore, if a Contributor
+includes the Program in a commercial product offering, such Contributor
+("Commercial Contributor") hereby agrees to defend and
+indemnify every other Contributor ("Indemnified Contributor")
+against any losses, damages and costs (collectively "Losses")
+arising from claims, lawsuits and other legal actions brought by a third
+party against the Indemnified Contributor to the extent caused by the
+acts or omissions of such Commercial Contributor in connection with its
+distribution of the Program in a commercial product offering. The
+obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In
+order to qualify, an Indemnified Contributor must: a) promptly notify
+the Commercial Contributor in writing of such claim, and b) allow the
+Commercial Contributor to control, and cooperate with the Commercial
+Contributor in, the defense and any related settlement negotiations. The
+Indemnified Contributor may participate in any such claim at its own
+expense.
+
+
For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those
+performance claims and warranties, and if a court requires any other
+Contributor to pay any damages as a result, the Commercial Contributor
+must pay those damages.
+
+
5. NO WARRANTY
+
+
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
+PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION,
+ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
+OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
+responsible for determining the appropriateness of using and
+distributing the Program and assumes all risks associated with its
+exercise of rights under this Agreement , including but not limited to
+the risks and costs of program errors, compliance with applicable laws,
+damage to or loss of data, programs or equipment, and unavailability or
+interruption of operations.
+
+
6. DISCLAIMER OF LIABILITY
+
+
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
+NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
+DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
7. GENERAL
+
+
If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further action
+by the parties hereto, such provision shall be reformed to the minimum
+extent necessary to make such provision valid and enforceable.
+
+
If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other
+software or hardware) infringes such Recipient's patent(s), then such
+Recipient's rights granted under Section 2(b) shall terminate as of the
+date such litigation is filed.
+
+
All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of time
+after becoming aware of such noncompliance. If all Recipient's rights
+under this Agreement terminate, Recipient agrees to cease use and
+distribution of the Program as soon as reasonably practicable. However,
+Recipient's obligations under this Agreement and any licenses granted by
+Recipient relating to the Program shall continue and survive.
+
+
Everyone is permitted to copy and distribute copies of this
+Agreement, but in order to avoid inconsistency the Agreement is
+copyrighted and may only be modified in the following manner. The
+Agreement Steward reserves the right to publish new versions (including
+revisions) of this Agreement from time to time. No one other than the
+Agreement Steward has the right to modify this Agreement. The Eclipse
+Foundation is the initial Agreement Steward. The Eclipse Foundation may
+assign the responsibility to serve as the Agreement Steward to a
+suitable separate entity. Each new version of the Agreement will be
+given a distinguishing version number. The Program (including
+Contributions) may always be distributed subject to the version of the
+Agreement under which it was received. In addition, after a new version
+of the Agreement is published, Contributor may elect to distribute the
+Program (including its Contributions) under the new version. Except as
+expressly stated in Sections 2(a) and 2(b) above, Recipient receives no
+rights or licenses to the intellectual property of any Contributor under
+this Agreement, whether expressly, by implication, estoppel or
+otherwise. All rights in the Program not expressly granted under this
+Agreement are reserved.
+
+
This Agreement is governed by the laws of the State of New York and
+the intellectual property laws of the United States of America. No party
+to this Agreement will bring a legal action under this Agreement more
+than one year after the cause of action arose. Each party waives its
+rights to a jury trial in any resulting litigation.
+
+
+
+
\ No newline at end of file
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/apple-touch-icon.png b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/apple-touch-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..e3086bfff759a844746687152f904ff50357c8d5
Binary files /dev/null and b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/apple-touch-icon.png differ
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/browserconfig.xml b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/browserconfig.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7b1730de6ac8121dc130f5e6c40266fe4b21d8c3
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/browserconfig.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+ #00a300
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/favicon-16x16.png b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/favicon-16x16.png
new file mode 100644
index 0000000000000000000000000000000000000000..93f5dabecbaf2fdec67598db87bfecdf49287536
Binary files /dev/null and b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/favicon-16x16.png differ
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/favicon-32x32.png b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/favicon-32x32.png
new file mode 100644
index 0000000000000000000000000000000000000000..ea8d5729646361bb78ec55e606d8ab9d747427c4
Binary files /dev/null and b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/favicon-32x32.png differ
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/favicon.ico b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..076b8a3d1913481e4442b38c5a4a549f10fc6129
Binary files /dev/null and b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/favicon.ico differ
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-144x144.png b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-144x144.png
new file mode 100644
index 0000000000000000000000000000000000000000..6ca07ef3a6c61e33d4ae649e9d66277d2cb706a9
Binary files /dev/null and b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-144x144.png differ
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-150x150.png b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-150x150.png
new file mode 100644
index 0000000000000000000000000000000000000000..bd2be50b81a8803b9f645428fa97aa2955db077e
Binary files /dev/null and b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-150x150.png differ
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-310x150.png b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-310x150.png
new file mode 100644
index 0000000000000000000000000000000000000000..ea359bd9c0ecafc6550e5572e52b30457bbaea36
Binary files /dev/null and b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-310x150.png differ
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-310x310.png b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-310x310.png
new file mode 100644
index 0000000000000000000000000000000000000000..f114ac2e5354b73d6285da4d7caad9c7036e6099
Binary files /dev/null and b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-310x310.png differ
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-70x70.png b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-70x70.png
new file mode 100644
index 0000000000000000000000000000000000000000..9d6fbbbfda308c33dc15c47d1656b0c5e026a48d
Binary files /dev/null and b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/mstile-70x70.png differ
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/robots.txt b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/robots.txt
new file mode 100644
index 0000000000000000000000000000000000000000..36ad3aa1347abc85187695a4728d091df319232f
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/robots.txt
@@ -0,0 +1,4 @@
+User-agent: *
+Disallow: /repository/
+Disallow: /service/
+Allow: /
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/safari-pinned-tab.svg b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/safari-pinned-tab.svg
new file mode 100644
index 0000000000000000000000000000000000000000..8921cc629b227dcd0715d742d92c284edfce7209
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/public/safari-pinned-tab.svg
@@ -0,0 +1,36 @@
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/system/settings.xml b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/system/settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f0a1b0b121a3f3e4d66de0593da6894b50b24a5f
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/overlay/system/settings.xml
@@ -0,0 +1 @@
+
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/sonatype-work/nexus3/clean_cache b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/sonatype-work/nexus3/clean_cache
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/sonatype-work/nexus3/log/.placeholder b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/sonatype-work/nexus3/log/.placeholder
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/sonatype-work/nexus3/tmp/.placeholder b/thirdparty-bundles/assemblies/nexus-base-template/src/main/resources/sonatype-work/nexus3/tmp/.placeholder
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/thirdparty-bundles/assemblies/nexus-boot-feature/pom.xml b/thirdparty-bundles/assemblies/nexus-boot-feature/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1578a10015b8912c97d2856bc2d05f55572df010
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-boot-feature/pom.xml
@@ -0,0 +1,45 @@
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.assemblies
+ nexus-assemblies
+ 3.8.0-02
+
+
+ nexus-boot-feature
+ ${project.groupId}:${project.artifactId}
+ feature
+
+
+
+ org.sonatype.nexus
+ nexus-bootstrap
+
+
+
+
+
+
+ org.apache.karaf.tooling
+ karaf-maven-plugin
+
+
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-core-feature/pom.xml b/thirdparty-bundles/assemblies/nexus-core-feature/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7e07b099e4b54ab04185328a6fc59ae78975f4ed
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-core-feature/pom.xml
@@ -0,0 +1,153 @@
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.assemblies
+ nexus-assemblies
+ 3.8.0-02
+
+
+ nexus-core-feature
+ ${project.groupId}:${project.artifactId}
+ feature
+
+
+
+
+
+
+ org.sonatype.nexus
+ nexus-bootstrap
+ provided
+
+
+
+ org.sonatype.nexus
+ nexus-commands
+ provided
+
+
+
+ org.sonatype.nexus
+ nexus-orient
+ provided
+
+
+
+ org.sonatype.nexus
+ nexus-security
+ provided
+
+
+
+
+
+ org.sonatype.nexus
+ nexus-core
+
+
+
+ org.sonatype.nexus
+ nexus-quartz
+
+
+
+ org.sonatype.nexus.plugins
+ nexus-audit-plugin
+ features
+ xml
+
+
+
+ org.sonatype.nexus.plugins
+ nexus-blobstore-tasks
+ features
+ xml
+
+
+
+ org.sonatype.nexus.plugins
+ nexus-ssl-plugin
+ features
+ xml
+
+
+
+ org.sonatype.nexus.plugins
+ nexus-coreui-plugin
+ features
+ xml
+
+
+
+ org.sonatype.nexus.plugins
+ nexus-repository-httpbridge
+ features
+ xml
+
+
+
+ org.sonatype.nexus.plugins
+ nexus-repository-maven
+ features
+ xml
+
+
+
+ org.sonatype.nexus.plugins
+ nexus-repository-raw
+ features
+ xml
+
+
+
+ org.sonatype.nexus.plugins
+ nexus-restore-maven
+ features
+ xml
+
+
+
+ org.sonatype.nexus.plugins
+ nexus-script-plugin
+ features
+ xml
+
+
+
+ org.sonatype.nexus.plugins
+ nexus-task-log-cleanup
+ features
+ xml
+
+
+
+
+
+
+
+ org.apache.karaf.tooling
+ karaf-maven-plugin
+
+ true
+
+
+
+
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-core-feature/src/main/feature/feature.xml b/thirdparty-bundles/assemblies/nexus-core-feature/src/main/feature/feature.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a5c1f8c685f63f90439ec4a74f80ac9b03e5b129
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-core-feature/src/main/feature/feature.xml
@@ -0,0 +1,27 @@
+
+
+
+
+ nexus-audit-plugin
+ nexus-blobstore-tasks
+ nexus-ssl-plugin
+ nexus-coreui-plugin
+ nexus-repository-httpbridge
+ nexus-repository-maven
+ nexus-repository-raw
+ nexus-restore-maven
+
+
diff --git a/thirdparty-bundles/assemblies/nexus-startup-feature/pom.xml b/thirdparty-bundles/assemblies/nexus-startup-feature/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fc41711ab3ce3e3807d1aa11b727100a07a6d495
--- /dev/null
+++ b/thirdparty-bundles/assemblies/nexus-startup-feature/pom.xml
@@ -0,0 +1,157 @@
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.assemblies
+ nexus-assemblies
+ 3.8.0-02
+
+
+ nexus-startup-feature
+ ${project.groupId}:${project.artifactId}
+ feature
+
+
+
+
+ org.sonatype.nexus
+ nexus-pax-logging
+
+
+
+ com.codahale.metrics
+ metrics-logback
+
+
+
+ javax.servlet
+ javax.servlet-api
+
+
+
+ org.eclipse.jetty
+ jetty-webapp
+
+
+
+ org.eclipse.jetty
+ jetty-continuation
+
+
+
+ org.eclipse.jetty
+ jetty-servlet
+
+
+
+ org.eclipse.jetty
+ jetty-security
+
+
+
+ org.eclipse.jetty
+ jetty-server
+
+
+
+ org.eclipse.jetty
+ jetty-deploy
+
+
+
+ org.eclipse.jetty
+ jetty-util
+
+
+
+ org.eclipse.jetty
+ jetty-util-ajax
+
+
+
+ org.eclipse.jetty
+ jetty-servlets
+
+
+
+ org.eclipse.jetty
+ jetty-proxy
+
+
+
+ org.eclipse.jetty
+ jetty-http
+
+
+
+ org.eclipse.jetty
+ jetty-io
+
+
+
+ org.eclipse.jetty
+ jetty-xml
+
+
+
+ org.eclipse.jetty
+ jetty-jmx
+
+
+
+ org.eclipse.jetty
+ jetty-rewrite
+
+
+
+ com.codahale.metrics
+ metrics-jetty9
+
+
+
+
+ org.apache.servicemix.bundles
+ org.apache.servicemix.bundles.javax-inject
+
+
+
+
+ net.java.dev.jna
+ jna
+
+
+
+
+
+
+ org.apache.karaf.tooling
+ karaf-maven-plugin
+
+ 8
+
+
+
+
+
+
diff --git a/thirdparty-bundles/assemblies/pom.xml b/thirdparty-bundles/assemblies/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..77ecee1b67714db14dda05ca8b8685bbe6c36d56
--- /dev/null
+++ b/thirdparty-bundles/assemblies/pom.xml
@@ -0,0 +1,63 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus
+ nexus-parent
+ 3.8.0-02
+
+
+ org.sonatype.nexus.assemblies
+ nexus-assemblies
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ nexus-startup-feature
+ nexus-boot-feature
+ nexus-base-feature
+ nexus-core-feature
+ nexus-base-template
+
+
+
+
+
+
+
+
+ org.sonatype.nexus
+ nexus-components
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.plugins
+ nexus-plugins
+ pom
+ 3.8.0-02
+ import
+
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/README.md b/thirdparty-bundles/buildsupport/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..7e332743eccf960f43ba2e0f7aff0e054076e909
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/README.md
@@ -0,0 +1,19 @@
+
+# Build Support
+
+Modules which provide `dependencyManagement` configuration in small(ish) groups.
+
+The `all` module aggregates to allow a single import to pick up all the configuration.
diff --git a/thirdparty-bundles/buildsupport/all/pom.xml b/thirdparty-bundles/buildsupport/all/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9624c0e79d53eddf0149959a8e6d47c3cbb24d5a
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/all/pom.xml
@@ -0,0 +1,180 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-all
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-commons
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-db
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-goodies
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-groovy
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-guice
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-httpclient
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-internal
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-jetty
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-jruby
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-logging
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-maven
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-metrics
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-osgi
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-other
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-rest
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-security
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-testing
+ pom
+ 3.8.0-02
+ import
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-ui
+ pom
+ 3.8.0-02
+ import
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/commons/pom.xml b/thirdparty-bundles/buildsupport/commons/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9b550483c43443847e8ebf992e9d6f6f710d9463
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/commons/pom.xml
@@ -0,0 +1,133 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-commons
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+
+
+
+ commons-io
+ commons-io
+ 2.4
+
+
+
+ commons-codec
+ commons-codec
+ 1.10
+
+
+
+ commons-lang
+ commons-lang
+ 2.6
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.4
+
+
+
+ commons-fileupload
+ commons-fileupload
+ 1.3.2
+
+
+
+ commons-beanutils
+ commons-beanutils
+ 1.9.2
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+
+ commons-cli
+ commons-cli
+ 1.4
+
+
+
+ commons-collections
+ commons-collections
+ 3.2.2
+
+
+
+ org.apache.commons
+ commons-collections4
+ 4.1
+
+
+
+ commons-configuration
+ commons-configuration
+ 1.10
+
+
+
+ org.apache.commons
+ commons-compress
+ 1.11
+
+
+
+
+ org.tukaani
+ xz
+ 1.5
+
+
+
+ org.apache.commons
+ commons-email
+ 1.5
+
+
+
+ org.apache.commons
+ commons-jexl3
+ 3.0
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/db/pom.xml b/thirdparty-bundles/buildsupport/db/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2da5306f8a6bf2e517e9e6195dc19778c1392657
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/db/pom.xml
@@ -0,0 +1,164 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-db
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 2.2.31
+ 3.7.8
+ 2.0.1
+
+
+
+
+
+
+ com.orientechnologies
+ orientdb-core
+ ${orientdb.version}
+
+
+ org.xerial.snappy
+ snappy-java
+
+
+
+
+
+ com.orientechnologies
+ orientdb-enterprise
+ ${orientdb.version}
+
+
+
+ com.orientechnologies
+ orientdb-tools
+ ${orientdb.version}
+
+
+ com.orientechnologies
+ orientdb-core
+
+
+ com.orientechnologies
+ orientdb-client
+
+
+ com.orientechnologies
+ orientdb-object
+
+
+
+
+
+ com.orientechnologies
+ orientdb-object
+ ${orientdb.version}
+
+
+
+ com.orientechnologies
+ orientdb-server
+ ${orientdb.version}
+
+
+
+ com.orientechnologies
+ orientdb-distributed
+ ${orientdb.version}
+
+
+ com.hazelcast
+ hazelcast-all
+
+
+ com.orientechnologies
+ orientdb-graphdb
+
+
+
+
+
+ com.orientechnologies
+ orientdb-client
+ ${orientdb.version}
+
+
+
+ com.orientechnologies
+ orientdb-jdbc
+ ${orientdb.version}
+
+
+
+ com.orientechnologies
+ orientdb-community
+ ${orientdb.version}
+ zip
+
+
+
+ mysql
+ mysql-connector-java
+ 5.1.36
+
+
+
+ com.hazelcast
+ hazelcast
+ ${hazelcast.version}
+
+
+
+ com.hazelcast
+ hazelcast
+ ${hazelcast.version}
+ tests
+
+
+
+ com.hazelcast
+ hazelcast-aws
+ ${hazelcast-aws.version}
+
+
+
+ net.java.dev.jna
+ jna
+ 4.5.0
+
+
+
+ net.java.dev.jna
+ jna-platform
+ 4.5.0
+
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/pom.xml b/thirdparty-bundles/buildsupport/extjs-maven-plugin/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8c88df260b70845db9e2cb0fc707c84b025c9ffa
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/pom.xml
@@ -0,0 +1,112 @@
+
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ extjs-maven-plugin
+ ${project.groupId}:${project.artifactId}
+ maven-plugin
+
+
+
+
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-all
+ pom
+ 3.8.0-02
+ import
+
+
+
+
+
+
+
+ org.apache.maven
+ maven-plugin-api
+
+
+
+ org.apache.maven.plugin-tools
+ maven-plugin-annotations
+
+
+
+ com.google.guava
+ guava
+
+
+
+ com.google.code.findbugs
+ jsr305
+ true
+
+
+
+
+ org.codehaus.plexus
+ plexus-utils
+
+
+
+ org.mozilla
+ rhino
+
+
+
+ org.sonatype.goodies
+ goodies-testsupport
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-plugin-plugin
+
+
+
+ descriptor
+ helpmojo
+
+
+
+ true
+
+
+
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/AggregateJsMojo.java b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/AggregateJsMojo.java
new file mode 100644
index 0000000000000000000000000000000000000000..3d805bbbae5285cdd9618800e90cf2bd81e4f0f5
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/AggregateJsMojo.java
@@ -0,0 +1,129 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.extjs;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.Writer;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.codehaus.plexus.util.DirectoryScanner;
+
+import static org.apache.maven.plugins.annotations.LifecyclePhase.PROCESS_RESOURCES;
+
+/**
+ * Aggregate javascript sources in order as required by ExtJS.
+ *
+ * @since 3.0
+ */
+@Mojo(name="aggregate-js", defaultPhase = PROCESS_RESOURCES)
+public class AggregateJsMojo
+ extends AbstractMojo
+{
+ private static final String[] DEFAULT_INCLUDES = { "**/*.js" };
+
+ @Parameter(required = true)
+ private File sourceDirectory;
+
+ @Parameter
+ private String[] includes;
+
+ @Parameter
+ private String[] excludes;
+
+ @Parameter(required = true)
+ private File outputFile;
+
+ @Parameter
+ private String namespace;
+
+ /**
+ * Enables extra warnings which may hint at problems.
+ */
+ @Parameter(property = "extjs.warnings", defaultValue = "false")
+ private boolean warnings;
+
+ /**
+ * Enable omission (auto-commenting) of lines surrounded by {@code //} and {@code //}.
+ */
+ @Parameter(property = "extjs.omit", defaultValue = "false")
+ private boolean omit;
+
+ /**
+ * Omission flags. When named flag is enabled, sections matching those omission tokens will be commented out.
+ */
+ @Parameter
+ private Map omitFlags;
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ try {
+ doExecute();
+ }
+ catch (Exception e) {
+ throw new MojoExecutionException(e.toString(), e);
+ }
+ }
+
+ private void doExecute() throws Exception {
+ // build scanner to find files to aggregate
+ DirectoryScanner files = new DirectoryScanner();
+ files.setBasedir(sourceDirectory);
+ if (includes == null || includes.length == 0) {
+ files.setIncludes(DEFAULT_INCLUDES);
+ }
+ else {
+ files.setIncludes(includes);
+ }
+ files.setExcludes(excludes);
+ files.addDefaultExcludes();
+
+ // build the list of ordered classes to include
+ ClassDefScanner scanner = new ClassDefScanner(getLog());
+ scanner.setWarnings(warnings);
+ if (namespace == null) {
+ getLog().warn("Namespace is not configured; will be unable to detect and resolve MVC references");
+ }
+ else {
+ scanner.setNamespace(namespace);
+ }
+ List classes = scanner.scan(files);
+
+ // aggregate all class sources
+ getLog().info("Writing: " + outputFile);
+ Writer output = new BufferedWriter(new FileWriter(outputFile));
+ try {
+ FileAppender appender;
+ if (omit) {
+ appender = new OmissionFileAppender(getLog(), output, omitFlags);
+ }
+ else {
+ appender = new FileAppender(getLog(), output);
+ }
+
+ for (ClassDef def : classes) {
+ appender.append(def.getSource());
+ }
+ }
+ finally {
+ output.close();
+ }
+ }
+}
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/ClassDef.java b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/ClassDef.java
new file mode 100644
index 0000000000000000000000000000000000000000..b7e14228ca1bc11cffa663d72bd36c94f3c183b5
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/ClassDef.java
@@ -0,0 +1,192 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.extjs;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * ExtJS class definition record.
+ *
+ * @since 3.0
+ */
+public class ClassDef
+{
+ private final String name;
+
+ private final File source;
+
+ private final Set dependencies = new HashSet<>();
+
+ private final List alternateClassName = new ArrayList<>();
+
+ private final List alias = new ArrayList<>();
+
+ private double priority = 0;
+
+ private String extend;
+
+ private String override;
+
+ private List requires;
+
+ private List mixins;
+
+ private List uses;
+
+ private List mvcControllers;
+
+ private List mvcModels;
+
+ private List mvcStores;
+
+ private List mvcViews;
+
+ public ClassDef(final String name, final File source) {
+ this.name = checkNotNull(name);
+ this.source = checkNotNull(source);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public File getSource() {
+ return source;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "{" +
+ "name='" + name + '\'' +
+ ", source=" + source +
+ '}';
+ }
+
+ public Set getDependencies() {
+ return dependencies;
+ }
+
+ public List getAlternateClassName() {
+ return alternateClassName;
+ }
+
+ public List getAlias() {
+ return alias;
+ }
+
+ public double getPriority() {
+ return priority;
+ }
+
+ public void setPriority(final double priority) {
+ this.priority = priority;
+ }
+
+ @Nullable
+ public String getExtend() {
+ return extend;
+ }
+
+ public void setExtend(final String extend) {
+ this.extend = checkNotNull(extend);
+ dependencies.add(extend);
+ }
+
+ @Nullable
+ public String getOverride() {
+ return override;
+ }
+
+ public void setOverride(final String override) {
+ this.override = checkNotNull(override);
+ dependencies.add(override);
+ }
+
+ @Nullable
+ public List getRequires() {
+ return requires;
+ }
+
+ public void setRequires(final List requires) {
+ this.requires = checkNotNull(requires);
+ dependencies.addAll(requires);
+ }
+
+ @Nullable
+ public List getMixins() {
+ return mixins;
+ }
+
+ public void setMixins(final List mixins) {
+ this.mixins = checkNotNull(mixins);
+ dependencies.addAll(mixins);
+ }
+
+ @Nullable
+ public List getUses() {
+ return uses;
+ }
+
+ public void setUses(final List uses) {
+ this.uses = checkNotNull(uses);
+ dependencies.addAll(uses);
+ }
+
+ //
+ // Custom handling for MVC support
+ //
+
+ @Nullable
+ public List getMvcControllers() {
+ return mvcControllers;
+ }
+
+ public void setMvcControllers(final List mvcControllers) {
+ this.mvcControllers = checkNotNull(mvcControllers);
+ }
+
+ @Nullable
+ public List getMvcModels() {
+ return mvcModels;
+ }
+
+ public void setMvcModels(final List mvcModels) {
+ this.mvcModels = checkNotNull(mvcModels);
+ }
+
+ @Nullable
+ public List getMvcStores() {
+ return mvcStores;
+ }
+
+ public void setMvcStores(final List mvcStores) {
+ this.mvcStores = checkNotNull(mvcStores);
+ }
+
+ @Nullable
+ public List getMvcViews() {
+ return mvcViews;
+ }
+
+ public void setMvcViews(final List mvcViews) {
+ this.mvcViews = checkNotNull(mvcViews);
+ }
+}
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/ClassDefScanner.java b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/ClassDefScanner.java
new file mode 100644
index 0000000000000000000000000000000000000000..a9fd7e1a4ed8862ee5bcf69f085be32c625d129e
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/ClassDefScanner.java
@@ -0,0 +1,617 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.extjs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import org.apache.maven.plugin.logging.Log;
+import org.codehaus.plexus.util.Scanner;
+import org.codehaus.plexus.util.dag.DAG;
+import org.codehaus.plexus.util.dag.TopologicalSorter;
+import org.codehaus.plexus.util.dag.Vertex;
+import org.mozilla.javascript.CompilerEnvirons;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.ErrorReporter;
+import org.mozilla.javascript.Parser;
+import org.mozilla.javascript.ast.ArrayLiteral;
+import org.mozilla.javascript.ast.AstNode;
+import org.mozilla.javascript.ast.AstRoot;
+import org.mozilla.javascript.ast.FunctionCall;
+import org.mozilla.javascript.ast.Name;
+import org.mozilla.javascript.ast.NewExpression;
+import org.mozilla.javascript.ast.NodeVisitor;
+import org.mozilla.javascript.ast.NumberLiteral;
+import org.mozilla.javascript.ast.ObjectLiteral;
+import org.mozilla.javascript.ast.ObjectProperty;
+import org.mozilla.javascript.ast.PropertyGet;
+import org.mozilla.javascript.ast.StringLiteral;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.mozilla.javascript.Token.CALL;
+import static org.mozilla.javascript.Token.NEW;
+
+/**
+ * ExtJS 4+ class definition scanner.
+ *
+ * @since 3.0
+ */
+public class ClassDefScanner
+{
+ private final Map classes = new HashMap<>();
+
+ private final Log log;
+
+ private boolean warnings = false;
+
+ private String namespace;
+
+ public ClassDefScanner(final Log log) {
+ this.log = checkNotNull(log);
+ }
+
+ public boolean isWarnings() {
+ return warnings;
+ }
+
+ public void setWarnings(final boolean warnings) {
+ this.warnings = warnings;
+ }
+
+ @Nullable
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(@Nullable final String namespace) {
+ this.namespace = namespace;
+ }
+
+ /**
+ * Scan a set of files and return a list of class definitions in dependency order.
+ * ie. Foo extends Bar, Bar will be before Foo.
+ */
+ public List scan(final Scanner files) throws Exception {
+ checkNotNull(files);
+
+ final boolean debug = log.isDebugEnabled();
+
+ // reset and scan for files
+ classes.clear();
+
+ log.debug("Finding files to scan...");
+ files.scan();
+
+ // scan each file
+ String[] included = files.getIncludedFiles();
+ log.debug("Scanning " + included.length + " files...");
+ for (String path : included) {
+ File file = new File(files.getBasedir(), path);
+ scan(file);
+ }
+
+ // TODO: Sort out how/if we want to resolve aliases, ATM this data is collected by not used
+
+ // Resolve all references and build map with all class defs (including aliases/alts)
+ Map classNames = new HashMap<>();
+ List allClasses = new ArrayList<>();
+ for (ClassDef def : classes.values()) {
+ log.debug("Processing: " + def);
+
+ classNames.put(def.getName(), def);
+ for (String alt : def.getAlternateClassName()) {
+ classNames.put(alt, def);
+ }
+
+ resolve(def);
+
+ allClasses.add(def);
+ }
+
+ // Sort all classes by priority, so that higher-priority value is closer to the start and processed sooner
+ // ie. priority=10 is closer to the start than priority=1
+ Collections.sort(allClasses, new Comparator()
+ {
+ @Override
+ public int compare(final ClassDef a, final ClassDef b) {
+ return Double.compare(b.getPriority(), a.getPriority());
+ }
+ });
+
+ if (debug) {
+ log.debug("All classes:");
+ for (ClassDef def : allClasses) {
+ log.debug(" " + def.getName());
+ }
+ }
+
+ // build the graph
+ DAG graph = new DAG();
+ for (ClassDef def : allClasses) {
+ graph.addVertex(def.getName());
+ for (String name : def.getDependencies()) {
+ // resolve dependencies which have class defs to primary class name
+ ClassDef dep = classNames.get(name);
+ if (dep != null) {
+ name = dep.getName();
+ }
+ graph.addEdge(def.getName(), name);
+ }
+ }
+
+ // display some debug information about the graph
+ if (debug) {
+ log.debug("Vertices:");
+ for (Vertex v : graph.getVerticies()) {
+ log.debug(" " + v.getLabel());
+ if (!v.getParents().isEmpty()) {
+ log.debug(" parents:");
+ for (Vertex parent : v.getParents()) {
+ log.debug(" " + parent.getLabel());
+ }
+ }
+ if (!v.getChildren().isEmpty()) {
+ log.debug(" children:");
+ for (Vertex child : v.getChildren()) {
+ log.debug(" " + child.getLabel());
+ }
+ }
+ }
+ }
+
+ // result sorted list of class definitions
+ Set results = new LinkedHashSet<>();
+ log.debug("Ordered classes:");
+ // the graph contains many references, only include those which are class defs
+ for (String className : TopologicalSorter.sort(graph)) {
+ ClassDef def = classNames.get(className);
+ // skip duplicates (due to alt/aliases)
+ if (def != null && !results.contains(def)) {
+ log.debug(" " + def.getName());
+ results.add(def);
+ }
+ }
+
+ log.debug("Found " + results.size() + " classes");
+ return new ArrayList<>(results);
+ }
+
+ /**
+ * Resolve all references.
+ */
+ private void resolve(final ClassDef def) {
+ // resolve mvc references if namespace is set
+ if (namespace != null) {
+ if (def.getMvcControllers() != null) {
+ for (String name : def.getMvcControllers()) {
+ appendMvcDependency(def, "controller", name);
+ }
+ }
+ if (def.getMvcModels() != null) {
+ for (String name : def.getMvcModels()) {
+ appendMvcDependency(def, "model", name);
+ }
+ }
+ if (def.getMvcStores() != null) {
+ for (String name : def.getMvcStores()) {
+ appendMvcDependency(def, "store", name);
+ }
+ }
+ if (def.getMvcViews() != null) {
+ for (String name : def.getMvcViews()) {
+ appendMvcDependency(def, "view", name);
+ }
+ }
+ }
+ }
+
+ private void appendMvcDependency(final ClassDef def, final String type, final String name) {
+ if (classes.containsKey(name)) {
+ // already qualified name
+ def.getDependencies().add(name);
+ }
+ else {
+ if (name.contains("@")) {
+ // namespace is embedded: @
+ String[] parts = name.split("@", 2);
+ def.getDependencies().add(String.format("%s.%s", parts[1], parts[0]));
+ }
+ else {
+ def.getDependencies().add(String.format("%s.%s.%s", namespace, type, name));
+ }
+ }
+ }
+
+ /**
+ * Scan the given file for class definitions and accumulate dependencies.
+ */
+ private void scan(final File source) throws IOException {
+ log.debug("Scanning: " + source);
+
+ ErrorReporter errorReporter = new LogErrorReporter(log);
+
+ CompilerEnvirons env = new CompilerEnvirons();
+ env.setErrorReporter(errorReporter);
+
+ Parser parser = new Parser(env, errorReporter);
+ Reader reader = new BufferedReader(new FileReader(source));
+ try {
+ AstRoot root = parser.parse(reader, source.getAbsolutePath(), 0);
+ DependencyAccumulator visitor = new DependencyAccumulator(source);
+ root.visit(visitor);
+
+ // complain if no def was found in this source
+ if (visitor.current == null) {
+ log.warn("No class definition was found while processing: " + source);
+ }
+ }
+ finally {
+ reader.close();
+ }
+ }
+
+ private class DependencyAccumulator
+ implements NodeVisitor
+ {
+ private final File source;
+
+ private ClassDef current;
+
+ private DependencyAccumulator(final File source) {
+ this.source = source;
+ }
+
+ /**
+ * Helper to report error for given node position in ast tree.
+ */
+ private RuntimeException reportError(final AstNode node, final String message, Object... params) {
+ throw Context.reportRuntimeError(String.format(message, params),
+ source.getAbsolutePath(),
+ node.getLineno(), // seems to always be the line before?
+ node.debugPrint(),
+ 0 // line-offset is unknown?
+ );
+ }
+
+ /**
+ * Helper to check state and report error for given node position in ast tree.
+ */
+ private void checkState(boolean expression, final AstNode node, final String message, Object... params) {
+ if (!expression) {
+ throw reportError(node, message, params);
+ }
+ }
+
+ @Override
+ public boolean visit(final AstNode node) {
+ int type = node.getType();
+
+ switch (type) {
+ case CALL: {
+ FunctionCall call = (FunctionCall) node;
+ String name = nameOf(call.getTarget());
+
+ // if we can not determine the function name, skip
+ if (name == null) {
+ break;
+ }
+
+ if (name.equals("Ext.define")) {
+ // complain if we found more than one class
+ if (current != null) {
+ log.warn("Found duplicate class definition in source: " + source);
+ }
+ processClassDef(call);
+ return true; // process children
+ }
+ else if (name.equals("Ext.create")) {
+ // complain if we have references to classes with Ext.create() and missing requires
+ if (!call.getArguments().isEmpty() && call.getArguments().get(0) instanceof StringLiteral) {
+ String className = nameOf(call.getArguments().get(0));
+ maybeWarnMissingRequires(className, "Ext.create");
+ }
+ return false; // ignore children
+ }
+ break;
+ }
+
+ case NEW: {
+ // complain if we have references to classes with 'new' and missing requires
+ NewExpression expr = (NewExpression) node;
+ String className = nameOf(expr.getTarget());
+ maybeWarnMissingRequires(className, "new");
+ break;
+ }
+ }
+
+ return true; // process children
+ }
+
+ /**
+ * Find the textual name of the given node.
+ */
+ @Nullable
+ private String nameOf(final AstNode node) {
+ if (node instanceof Name) {
+ return ((Name) node).getIdentifier();
+ }
+ else if (node instanceof PropertyGet) {
+ PropertyGet prop = (PropertyGet) node;
+ return String.format("%s.%s", nameOf(prop.getTarget()), nameOf(prop.getProperty()));
+ }
+ else if (node instanceof StringLiteral) {
+ return ((StringLiteral) node).getValue();
+ }
+ return null;
+ }
+
+ /**
+ * Return string literal value.
+ */
+ private String stringLiteral(final AstNode node) {
+ checkState(node instanceof StringLiteral, node, "Expected string literal only");
+ //noinspection ConstantConditions
+ StringLiteral string = (StringLiteral) node;
+ return string.getValue();
+ }
+
+ /**
+ * Return number literal value.
+ */
+ private double numberLiteral(final AstNode node) {
+ checkState(node instanceof NumberLiteral, node, "Expected number literal only");
+ //noinspection ConstantConditions
+ NumberLiteral number = (NumberLiteral) node;
+ return number.getNumber();
+ }
+
+ /**
+ * Returns string array literal values.
+ */
+ private List arrayStringLiteral(final AstNode node) {
+ checkState(node instanceof ArrayLiteral, node, "Expected array literal only");
+ List result = new ArrayList<>();
+ //noinspection ConstantConditions
+ ArrayLiteral array = (ArrayLiteral) node;
+ for (AstNode element : array.getElements()) {
+ result.add(stringLiteral(element));
+ }
+ return result;
+ }
+
+ /**
+ * Returns string literal or array of string literals.
+ *
+ * @see #stringLiteral(AstNode)
+ * @see #arrayStringLiteral(AstNode)
+ */
+ private List stringLiterals(final AstNode node) {
+ // string literal or array of string literals
+ if (node instanceof StringLiteral) {
+ return Collections.singletonList(stringLiteral(node));
+ }
+ else if (node instanceof ArrayLiteral) {
+ return arrayStringLiteral(node);
+ }
+ else {
+ throw reportError(node, "Expected string literal or array of string literal only");
+ }
+ }
+
+ /**
+ * Maybe warn if a needed class has not been required.
+ */
+ private void maybeWarnMissingRequires(final String className, final String usage) {
+ if (warnings) {
+ if (!current.getDependencies().contains(className)) {
+ log.warn(String.format("Class '%s' missing requires for '%s' usage of: %s",
+ current.getName(), usage, className));
+ }
+ }
+ }
+
+ /**
+ * Process an {@code Ext.define} class definition.
+ */
+ private void processClassDef(final FunctionCall node) {
+ List args = node.getArguments();
+ checkState(args.size() >= 2, node,
+ "Invalid number of arguments for Ext.define"); // simple def or def with callback
+
+ // class-name
+ checkState(args.get(0) instanceof StringLiteral, node, "Ext.define arg[0] must be string");
+ String className = nameOf(args.get(0));
+
+ // try and avoid file-name/class-name mismatches early
+ sanityCheckClassName(className);
+
+ current = new ClassDef(className, source);
+ classes.put(className, current);
+
+ // class def object
+ checkState(args.get(1) instanceof ObjectLiteral, node, "Ext.define arg[1] must be object");
+ ObjectLiteral obj = (ObjectLiteral) args.get(1);
+ for (ObjectProperty prop : obj.getElements()) {
+ String name = nameOf(prop.getLeft());
+ switch (name) {
+
+ // ExtJS core class def
+
+ case "extend":
+ // string literal only
+ current.setExtend(stringLiteral(prop.getRight()));
+ break;
+
+ case "override":
+ // string literal only
+ current.setOverride(stringLiteral(prop.getRight()));
+ break;
+
+ case "@aggregate_priority":
+ // number only
+ current.setPriority(numberLiteral(prop.getRight()));
+ break;
+
+ case "requires":
+ // array of string literals only
+ current.setRequires(arrayStringLiteral(prop.getRight()));
+ break;
+
+ case "require":
+ // complain if we found 'require' this almost certainly should be 'requires'
+ log.warn(
+ String.format("Found 'require' and probably should be 'requires' in: %s#%s", source, prop.getLineno()));
+ break;
+
+ case "uses":
+ // array of string literals only
+ current.setUses(arrayStringLiteral(prop.getRight()));
+ break;
+
+ case "alternateClassName": {
+ // string literal or array of string literals
+ current.getAlternateClassName().addAll(stringLiterals(prop.getRight()));
+ break;
+ }
+
+ case "alias": {
+ // string literal or array of string literals
+ current.getAlias().addAll(stringLiterals(prop.getRight()));
+ break;
+ }
+
+ case "xtype": {
+ // string literal only
+ current.getAlias().add("widget." + stringLiteral(prop.getRight()));
+ break;
+ }
+
+ case "mixins": {
+ // array of strings, or object
+ List mixins = new ArrayList<>();
+ if (prop.getRight() instanceof ArrayLiteral) {
+ mixins.addAll(arrayStringLiteral(prop.getRight()));
+ }
+ else if (prop.getRight() instanceof ObjectLiteral) {
+ ObjectLiteral child = (ObjectLiteral) prop.getRight();
+ for (ObjectProperty element : child.getElements()) {
+ mixins.add(stringLiteral(element.getRight()));
+ }
+ }
+ else {
+ throw reportError(prop.getRight(), "Expected array or object literal only");
+ }
+ current.setMixins(mixins);
+ break;
+ }
+ }
+
+ // Additional stuff we have to detect for ExtJS MVC support
+
+ if (isExtends("Ext.app.Application")) {
+ // class looks like an application, process more fields
+ switch (name) {
+ case "controllers":
+ // array of string literals only
+ current.setMvcControllers(arrayStringLiteral(prop.getRight()));
+ break;
+
+ case "models":
+ // array of string literals only
+ current.setMvcModels(arrayStringLiteral(prop.getRight()));
+ break;
+
+ case "stores":
+ // array of string literals only
+ current.setMvcStores(arrayStringLiteral(prop.getRight()));
+ break;
+
+ case "views":
+ // array of string literals only
+ current.setMvcViews(arrayStringLiteral(prop.getRight()));
+ break;
+ }
+ }
+ else if (isMvcClass("controller")) {
+ // class looks like a controller, process more fields
+ switch (name) {
+ case "models":
+ // array of string literals only
+ current.setMvcModels(arrayStringLiteral(prop.getRight()));
+ break;
+
+ case "stores":
+ // array of string literals only
+ current.setMvcStores(arrayStringLiteral(prop.getRight()));
+ break;
+
+ case "views":
+ // array of string literals only
+ current.setMvcViews(arrayStringLiteral(prop.getRight()));
+ break;
+ }
+ }
+ else if (isMvcClass("store")) {
+ // class looks like a store, process more fields
+ switch (name) {
+ case "model":
+ // string literal only
+ current.getDependencies().add(stringLiteral(prop.getRight()));
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Complain if classes are defined with wrong names, or in wrong files.
+ */
+ private void sanityCheckClassName(final String className) {
+ String found = source.toURI().getPath();
+ String expected = className.replace('.', '/') + ".js";
+ if (!found.endsWith(expected)) {
+ log.warn(String.format("Expected class '%s' to be defined in filename '%s', but was defined in: %s",
+ className, expected, found));
+ }
+ }
+
+ /**
+ * Highly hackish means to determine given class-name is a MVC type.
+ * Requires namespace to be configured.
+ */
+ private boolean isMvcClass(final String type) {
+ return namespace != null && current.getName().startsWith(String.format("%s.%s.", namespace, type));
+ }
+
+ /**
+ * Check if current class extends (directly) given class-name.
+ */
+ private boolean isExtends(final String className) {
+ String superClass = current.getExtend();
+ return superClass != null && superClass.equals(className);
+ }
+ }
+}
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/FileAppender.java b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/FileAppender.java
new file mode 100644
index 0000000000000000000000000000000000000000..49dc6f77acffbcce282c6fdf789609c1815fcf32
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/FileAppender.java
@@ -0,0 +1,70 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.extjs;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.maven.plugin.logging.Log;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * File appender.
+ *
+ * @since 3.0
+ */
+public class FileAppender
+{
+ protected final Log log;
+
+ protected final Writer output;
+
+ public FileAppender(final Log log, final Writer output) {
+ this.log = checkNotNull(log);
+ this.output = checkNotNull(output);
+ }
+
+ protected File source;
+
+ protected long linenum;
+
+ public void append(final File source) throws IOException {
+ this.source = checkNotNull(source);
+ this.linenum = 0;
+
+ log.debug("Appending: " + source);
+
+ BufferedReader input = new BufferedReader(new FileReader(source));
+ try {
+ String line;
+ while ((line = input.readLine()) != null) {
+ linenum++;
+ append(line);
+ }
+ }
+ finally {
+ input.close();
+ }
+
+ output.write('\n');
+ }
+
+ protected void append(final String line) throws IOException {
+ output.write(line);
+ output.write('\n');
+ }
+}
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/LogErrorReporter.java b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/LogErrorReporter.java
new file mode 100644
index 0000000000000000000000000000000000000000..d94fdc620166710d81c3eb43bd40a5564eb1e030
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/LogErrorReporter.java
@@ -0,0 +1,53 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.extjs;
+
+import org.apache.maven.plugin.logging.Log;
+import org.mozilla.javascript.ErrorReporter;
+import org.mozilla.javascript.EvaluatorException;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Mojo {@link Log} adapting {@link ErrorReporter}.
+ *
+ * @since 3.0
+ */
+public class LogErrorReporter
+ implements ErrorReporter
+{
+ private final Log log;
+
+ public LogErrorReporter(final Log log) {
+ this.log = checkNotNull(log);
+ }
+
+ private String format(final String message, final String sourceName, final int line, final String lineSource, final int lineOffset) {
+ return String.format("%s (%s#%d:%d): %s", message, sourceName, line, lineOffset, lineSource);
+ }
+
+ @Override
+ public void warning(final String message, final String sourceName, final int line, final String lineSource, final int lineOffset) {
+ log.warn(format(message, sourceName, line, lineSource, lineOffset));
+ }
+
+ @Override
+ public void error(final String message, final String sourceName, final int line, final String lineSource, final int lineOffset){
+ log.error(format(message, sourceName, line, lineSource, lineOffset));
+ }
+
+ @Override
+ public EvaluatorException runtimeError(final String message, final String sourceName, final int line, final String lineSource, final int lineOffset) {
+ return new EvaluatorException(message, sourceName, line, lineSource, lineOffset);
+ }
+}
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/OmissionFileAppender.java b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/OmissionFileAppender.java
new file mode 100644
index 0000000000000000000000000000000000000000..60ae2eb58810f2c602f04179480ec244452f3af2
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/main/java/org/sonatype/nexus/extjs/OmissionFileAppender.java
@@ -0,0 +1,113 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.extjs;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.annotation.Nullable;
+
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * Omission token aware file appender.
+ *
+ * @since 3.0
+ */
+public class OmissionFileAppender
+ extends FileAppender
+{
+ public static final String IF_START_PREFIX = "// flags = new HashMap<>();
+
+ public OmissionFileAppender(final Log log,
+ final Writer output,
+ @Nullable final Map rawFlags)
+ {
+ super(log, output);
+ if (rawFlags != null) {
+ parseFlags(rawFlags);
+ }
+ }
+
+ public Map getFlags() {
+ return flags;
+ }
+
+ private void parseFlags(final Map rawFlags) {
+ for (Entry entry : rawFlags.entrySet()) {
+ boolean flag = Boolean.parseBoolean(entry.getValue());
+ flags.put(entry.getKey(), flag);
+ }
+ log.debug("Omit flags: " + flags);
+ }
+
+ private boolean omit;
+
+ @Override
+ public void append(final File source) throws IOException {
+ this.omit = false;
+
+ super.append(source);
+
+ // complain if still in omit mode at the end of the file
+ if (omit) {
+ log.warn("Missing omit end token: " + source);
+ }
+ }
+
+ @Override
+ protected void append(final String line) throws IOException {
+ // check for omission start and stop tokens
+ String trimmedLine = line.trim();
+ if (isOmitStart(trimmedLine)) {
+ // complain if already in omit mode and we found a start token (nesting is not allowed)
+ if (omit) {
+ log.warn("Unexpected omit start token: " + source + "#" + linenum);
+ }
+ omit = true;
+ }
+ else if (isOmitStop(trimmedLine)) {
+ omit = false;
+ }
+ else if (omit) {
+ output.write("//");
+ }
+
+ super.append(line);
+ }
+
+ private boolean isOmitStart(final String line) {
+ // assumes line is trimmed
+ if (line.startsWith(IF_START_PREFIX) && line.endsWith(IF_START_SUFFIX)) {
+ String flagName = line.substring(IF_START_PREFIX.length(), line.length() - IF_START_SUFFIX.length());
+ Boolean flag = flags.get(flagName);
+ return flag != null && flag;
+ }
+ return false;
+ }
+
+ private boolean isOmitStop(final String line) {
+ // assumes line is trimmed
+ return line.equals(IF_END);
+ }
+}
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/java/org/sonatype/nexus/extjs/ClassDefScannerTest.java b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/java/org/sonatype/nexus/extjs/ClassDefScannerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..25574171e53313a2c67c23d8e9484bbd62ff4c7b
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/java/org/sonatype/nexus/extjs/ClassDefScannerTest.java
@@ -0,0 +1,145 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.extjs;
+
+import java.io.File;
+import java.util.List;
+
+import org.sonatype.goodies.testsupport.TestSupport;
+
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugin.logging.SystemStreamLog;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Tests for {@link ClassDefScanner}.
+ */
+public class ClassDefScannerTest
+ extends TestSupport
+{
+ private ClassDefScanner scanner;
+
+ @Before
+ public void setUp() throws Exception {
+ Log log = new SystemStreamLog()
+ {
+ @Override
+ public boolean isDebugEnabled() {
+ return true;
+ }
+ };
+ this.scanner = new ClassDefScanner(log);
+ }
+
+ private List scan(final File basedir) throws Exception {
+ DirectoryScanner files = new DirectoryScanner();
+ files.setBasedir(basedir);
+ files.setIncludes(new String[]{"**/*.js"});
+
+ List classes = scanner.scan(files);
+ log("Classes:");
+ for (ClassDef def : classes) {
+ log(" {} [priority: {}]", def.getName(), def.getPriority());
+ for (String dep : def.getDependencies()) {
+ log(" + {}", dep);
+ }
+ }
+ return classes;
+ }
+
+ @Test
+ public void basicOrder() throws Exception {
+ File basedir = util.resolveFile("src/test/resources/basic");
+ List classes = scan(basedir);
+
+ assertThat(classes, hasSize(3));
+
+ ClassDef baz = classes.get(0);
+ assertThat(baz.getName(), is("Baz"));
+
+ ClassDef bar = classes.get(1);
+ assertThat(bar.getName(), is("Bar"));
+ assertThat(bar.getDependencies(), contains("Baz"));
+
+ ClassDef foo = classes.get(2);
+ assertThat(foo.getName(), is("Foo"));
+ assertThat(foo.getDependencies(), contains("Bar"));
+ }
+
+ @Test
+ public void priorityOrder() throws Exception {
+ File basedir = util.resolveFile("src/test/resources/priority");
+ List classes = scan(basedir);
+
+ assertThat(classes, hasSize(5));
+
+ ClassDef poo = classes.get(0);
+ assertThat(poo.getName(), is("Poo"));
+
+ ClassDef ick = classes.get(1);
+ assertThat(ick.getName(), is("Ick"));
+ assertThat(ick.getDependencies(), contains("Poo"));
+
+ ClassDef baz = classes.get(2);
+ assertThat(baz.getName(), is("Baz"));
+
+ ClassDef bar = classes.get(3);
+ assertThat(bar.getName(), is("Bar"));
+ assertThat(bar.getDependencies(), contains("Baz"));
+
+ ClassDef foo = classes.get(4);
+ assertThat(foo.getName(), is("Foo"));
+ assertThat(foo.getDependencies(), contains("Bar"));
+ }
+
+ @Test
+ public void altClassNameOrder() throws Exception {
+ File basedir = util.resolveFile("src/test/resources/altclassname");
+ List classes = scan(basedir);
+
+ assertThat(classes, hasSize(3));
+
+ ClassDef baz = classes.get(0);
+ assertThat(baz.getName(), is("Baz"));
+
+ ClassDef bar = classes.get(1);
+ assertThat(bar.getName(), is("Bar"));
+ assertThat(bar.getAlternateClassName(), containsInAnyOrder("Test.Bar", "Other.Bar"));
+ assertThat(bar.getDependencies(), contains("Baz"));
+
+ ClassDef foo = classes.get(2);
+ assertThat(foo.getName(), is("Foo"));
+ assertThat(foo.getAlternateClassName(), containsInAnyOrder("Test.Foo"));
+ assertThat(foo.getDependencies(), contains("Test.Bar"));
+ }
+
+ @Test
+ public void mvcOrder() throws Exception {
+ File basedir = util.resolveFile("src/test/resources/mvc");
+ scanner.setNamespace("Test");
+ List classes = scan(basedir);
+
+ assertThat(classes, hasSize(5));
+
+ assertThat(classes.get(4).getName(), is("Test.Application"));
+ assertThat(classes.get(4).getDependencies(), containsInAnyOrder("Ext.app.Application", "Test.controller.Fun"));
+ }
+}
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/altclassname/Bar.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/altclassname/Bar.js
new file mode 100644
index 0000000000000000000000000000000000000000..c8ce309d5fd7533be011e99c9848251ee6d2f151
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/altclassname/Bar.js
@@ -0,0 +1,9 @@
+Ext.define('Bar', {
+ alternateClassName: [
+ 'Test.Bar',
+ 'Other.Bar'
+ ],
+ requires: [
+ 'Baz'
+ ]
+});
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/altclassname/Baz.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/altclassname/Baz.js
new file mode 100644
index 0000000000000000000000000000000000000000..b1f7b6ae1e222646991132f9cf6a8ec63c9962f7
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/altclassname/Baz.js
@@ -0,0 +1 @@
+Ext.define('Baz', {});
\ No newline at end of file
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/altclassname/Foo.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/altclassname/Foo.js
new file mode 100644
index 0000000000000000000000000000000000000000..efaa030112cc017bc47076754562a17471d7af0e
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/altclassname/Foo.js
@@ -0,0 +1,6 @@
+Ext.define('Foo', {
+ alternateClassName: 'Test.Foo',
+ requires: [
+ 'Test.Bar'
+ ]
+});
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/basic/Bar.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/basic/Bar.js
new file mode 100644
index 0000000000000000000000000000000000000000..985ef1fee81b116b59e25acf78c3702d863bf011
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/basic/Bar.js
@@ -0,0 +1,5 @@
+Ext.define('Bar', {
+ requires: [
+ 'Baz'
+ ]
+});
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/basic/Baz.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/basic/Baz.js
new file mode 100644
index 0000000000000000000000000000000000000000..b1f7b6ae1e222646991132f9cf6a8ec63c9962f7
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/basic/Baz.js
@@ -0,0 +1 @@
+Ext.define('Baz', {});
\ No newline at end of file
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/basic/Foo.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/basic/Foo.js
new file mode 100644
index 0000000000000000000000000000000000000000..562d52fcf420709bd48583ee5d5eced143ffd10a
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/basic/Foo.js
@@ -0,0 +1,5 @@
+Ext.define('Foo', {
+ requires: [
+ 'Bar'
+ ]
+});
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/Application.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/Application.js
new file mode 100644
index 0000000000000000000000000000000000000000..1e3aaf41d07a06425c653acb92706382ede9518d
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/Application.js
@@ -0,0 +1,7 @@
+Ext.define('Test.Application', {
+ extend: 'Ext.app.Application',
+
+ controllers: [
+ 'Fun'
+ ]
+});
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/controller/Fun.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/controller/Fun.js
new file mode 100644
index 0000000000000000000000000000000000000000..715fe24ffadfa95967a54293d7f853dc5d447dad
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/controller/Fun.js
@@ -0,0 +1,10 @@
+Ext.define('Test.controller.Fun', {
+ extend: 'Ext.app.Controller',
+
+ stores: [
+ 'Fun'
+ ],
+ views: [
+ 'Fun'
+ ]
+});
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/model/Fun.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/model/Fun.js
new file mode 100644
index 0000000000000000000000000000000000000000..27286dae349a4f266608619ed2e16abd6d3b60ab
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/model/Fun.js
@@ -0,0 +1,3 @@
+Ext.define('Test.model.Fun', {
+ extend: 'Ext.data.Model'
+});
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/store/Fun.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/store/Fun.js
new file mode 100644
index 0000000000000000000000000000000000000000..ce394d17b905ba24194a7eff8530fa7af9a91948
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/store/Fun.js
@@ -0,0 +1,4 @@
+Ext.define('Test.store.Fun', {
+ extend: 'Ext.data.Store',
+ model: 'Test.model.Fun'
+});
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/view/Fun.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/view/Fun.js
new file mode 100644
index 0000000000000000000000000000000000000000..be94030587a25472b1483d8f503e4d8bda9dfbce
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/mvc/view/Fun.js
@@ -0,0 +1,3 @@
+Ext.define('Test.view.Fun', {
+ extend: 'Ext.panel.Panel'
+});
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Bar.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Bar.js
new file mode 100644
index 0000000000000000000000000000000000000000..985ef1fee81b116b59e25acf78c3702d863bf011
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Bar.js
@@ -0,0 +1,5 @@
+Ext.define('Bar', {
+ requires: [
+ 'Baz'
+ ]
+});
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Baz.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Baz.js
new file mode 100644
index 0000000000000000000000000000000000000000..b1f7b6ae1e222646991132f9cf6a8ec63c9962f7
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Baz.js
@@ -0,0 +1 @@
+Ext.define('Baz', {});
\ No newline at end of file
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Foo.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Foo.js
new file mode 100644
index 0000000000000000000000000000000000000000..562d52fcf420709bd48583ee5d5eced143ffd10a
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Foo.js
@@ -0,0 +1,5 @@
+Ext.define('Foo', {
+ requires: [
+ 'Bar'
+ ]
+});
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Ick.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Ick.js
new file mode 100644
index 0000000000000000000000000000000000000000..6d27a8c6e49f8520b21e87a0a57c8bbb9c8e3567
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Ick.js
@@ -0,0 +1,6 @@
+Ext.define('Ick', {
+ '@aggregate_priority': 10,
+ requires: [
+ 'Poo'
+ ]
+});
diff --git a/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Poo.js b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Poo.js
new file mode 100644
index 0000000000000000000000000000000000000000..b8b027779f0d46e1833a68f99d19336e7b562d76
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/extjs-maven-plugin/src/test/resources/priority/Poo.js
@@ -0,0 +1,3 @@
+Ext.define('Poo', {
+ '@aggregate_priority': 9
+});
diff --git a/thirdparty-bundles/buildsupport/goodies/pom.xml b/thirdparty-bundles/buildsupport/goodies/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a88985ab316c2b3e96613c51a6265d7dc4e9187f
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/goodies/pom.xml
@@ -0,0 +1,76 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-goodies
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 2.2.4
+
+
+
+
+
+
+ org.sonatype.goodies
+ goodies-common
+ ${goodies.version}
+
+
+
+ org.sonatype.goodies
+ goodies-httpfixture
+ ${goodies.version}
+
+
+
+ org.sonatype.goodies
+ goodies-i18n
+ ${goodies.version}
+
+
+
+ org.sonatype.goodies
+ goodies-lifecycle
+ ${goodies.version}
+
+
+
+ org.sonatype.goodies
+ goodies-prefs
+ ${goodies.version}
+
+
+
+ org.sonatype.goodies
+ goodies-testsupport
+ ${goodies.version}
+
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/groovy/pom.xml b/thirdparty-bundles/buildsupport/groovy/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..de5e555b30a9a03d490392774aba5eaa58a62c28
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/groovy/pom.xml
@@ -0,0 +1,96 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-groovy
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 2.4.11
+ 1.9.7
+ 1.0-groovy-2.4
+
+
+
+
+
+
+
+
+ org.codehaus.groovy
+ groovy-all
+ ${groovy.version}
+
+
+
+ org.codehaus.groovy
+ groovy
+ ${groovy.version}
+
+
+
+ org.apache.ant
+ ant
+ ${ant.version}
+
+
+
+ org.apache.ant
+ ant-launcher
+ ${ant.version}
+
+
+
+ org.spockframework
+ spock-core
+ ${spock.version}
+
+
+
+ org.spockframework
+ spock-guice
+ ${spock.version}
+
+
+
+ cglib
+ cglib-nodep
+ 3.2.0
+
+
+
+ org.objenesis
+ objenesis
+ 2.2
+
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/guice/pom.xml b/thirdparty-bundles/buildsupport/guice/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0f2cc3802dd3e2095c83f653330ba27219cc017e
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/guice/pom.xml
@@ -0,0 +1,109 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-guice
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 0.3.2
+ 4.1.0
+
+
+
+
+
+ javax.annotation
+ javax.annotation-api
+ 1.2
+
+
+
+ org.apache.servicemix.bundles
+ org.apache.servicemix.bundles.javax-inject
+ 1_2
+
+
+
+ org.apache.servicemix.bundles
+ org.apache.servicemix.bundles.aopalliance
+ 1.0_6
+
+
+
+ javax.enterprise
+ cdi-api
+ 1.2
+
+
+ javax.inject
+ javax.inject
+
+
+
+
+
+ com.google.inject
+ guice
+ ${guice.version}
+
+
+ javax.inject
+ javax.inject
+
+
+ aopalliance
+ aopalliance
+
+
+
+
+
+ com.google.inject.extensions
+ guice-servlet
+ ${guice.version}
+
+
+
+ com.google.inject.extensions
+ guice-multibindings
+ ${guice.version}
+
+
+
+ com.google.inject.extensions
+ guice-assistedinject
+ ${guice.version}
+
+
+
+ org.eclipse.sisu
+ org.eclipse.sisu.inject
+ ${eclipse-sisu.version}
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/httpclient/pom.xml b/thirdparty-bundles/buildsupport/httpclient/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f70f051bf5a00939e62b6d100bf2ed4503f0f8fb
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/httpclient/pom.xml
@@ -0,0 +1,60 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-httpclient
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.2
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+
+ org.apache.httpcomponents
+ httpmime
+ 4.5.2
+
+
+
+ org.apache.httpcomponents
+ httpcore
+ 4.4.6
+
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/internal/pom.xml b/thirdparty-bundles/buildsupport/internal/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3a7be49bd90435757c0cf483df23fcb5fbd4d7bf
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/internal/pom.xml
@@ -0,0 +1,192 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-internal
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 1.4.3
+ 1.7.1-01
+ 1.35.0-02
+ 2.8.0-01
+
+
+
+
+
+
+
+
+ com.sonatype.licensing
+ license-bundle
+ ${sonatype-licensing.version}
+
+
+ aopalliance
+ aopalliance
+
+
+ org.sonatype.sisu
+ sisu-guice
+
+
+ xmlpull
+ xmlpull
+
+
+ xpp3
+ xpp3_min
+
+
+
+
+
+ com.sonatype.licensing
+ license-creator
+ ${sonatype-licensing.version}
+
+
+
+ com.sonatype.licensing
+ license-extension
+ ${sonatype-licensing.version}
+
+
+
+
+
+ com.sonatype.clm
+ com.sonatype.clm.dto.model
+ ${clm.dto.model.version}
+
+
+
+ com.sonatype.insight.scan
+ insight-scanner-archive
+ ${insight-scanner.version}
+
+
+
+ com.sonatype.insight.scan
+ insight-scanner-core
+ ${insight-scanner.version}
+
+
+
+ com.sonatype.insight.scan
+ insight-scanner-model-io
+ ${insight-scanner.version}
+
+
+
+ com.sonatype.insight.scan
+ insight-scanner-model
+ ${insight-scanner.version}
+
+
+
+ com.sonatype.insight.scan
+ insight-test-reverse-proxy
+ ${insight-scanner.version}
+
+
+
+ com.sonatype.insight.brain
+ hds-mock-server
+ ${insight-brain.version}
+
+
+
+ com.sonatype.insight.brain
+ insight-rm-common
+ ${insight-brain.version}
+
+
+
+ com.sonatype.insight.brain
+ insight-brain-data
+ ${insight-brain.version}
+ tests
+
+
+ *
+ *
+
+
+
+
+
+ com.sonatype.insight.brain
+ insight-brain-service
+ ${insight-brain.version}
+
+
+
+ junit
+ junit
+
+
+ com.sonatype.licensing
+ license-bundle
+
+
+
+
+
+ com.sonatype.insight.brain
+ insight-brain-service
+ ${insight-brain.version}
+ tests
+
+
+ *
+ *
+
+
+
+
+
+
+
+ com.sonatype.analytics
+ analytics-client
+ 1.1.0
+
+
+
+ com.sonatype.analytics
+ analytics-assembly
+ bundle
+ zip
+ 1.1.0
+
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/jetty/pom.xml b/thirdparty-bundles/buildsupport/jetty/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..053cc0a170788446debf0577dd1172a63ef0f4ae
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/jetty/pom.xml
@@ -0,0 +1,147 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-jetty
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 9.4.8.v20171121
+
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+
+
+
+ org.eclipse.jetty
+ jetty-webapp
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-continuation
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-servlet
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-servlet
+ tests
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-security
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-server
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-deploy
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-client
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-util
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-util-ajax
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-servlets
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-proxy
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-http
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-io
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-xml
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-jmx
+ ${eclipse-jetty.version}
+
+
+
+ org.eclipse.jetty
+ jetty-rewrite
+ ${eclipse-jetty.version}
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/jruby/pom.xml b/thirdparty-bundles/buildsupport/jruby/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..68ed0995225e125c835fa8b9d27d810247b3ac4f
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/jruby/pom.xml
@@ -0,0 +1,48 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-jruby
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+
+
+
+ org.jruby
+ jruby-complete
+ 9.0.5.0
+
+
+
+ org.yaml
+ snakeyaml
+ 1.18
+
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/logging/pom.xml b/thirdparty-bundles/buildsupport/logging/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2cbd8d15cdd9cd0541885520aac7259ed0005785
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/logging/pom.xml
@@ -0,0 +1,128 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-logging
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 1.7.25
+ 1.2.2
+ 1.10.0
+
+
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+
+
+
+ org.slf4j
+ slf4j-simple
+ ${slf4j.version}
+
+
+
+ org.slf4j
+ jcl-over-slf4j
+ ${slf4j.version}
+
+
+
+ org.slf4j
+ log4j-over-slf4j
+ ${slf4j.version}
+
+
+
+ org.slf4j
+ jul-to-slf4j
+ ${slf4j.version}
+
+
+
+ ch.qos.logback
+ logback-core
+ ${logback.version}
+
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+
+
+
+ ch.qos.logback
+ logback-access
+ ${logback.version}
+
+
+
+ org.ops4j.pax.logging
+ pax-logging-api
+ ${pax-logging.version}
+
+
+
+ org.ops4j.pax.logging
+ pax-logging-logback
+ ${pax-logging.version}
+
+
+ ch.qos.logback
+ logback-core
+
+
+ ch.qos.logback
+ logback-classic
+
+
+ ch.qos.logback.contrib
+ logback-jackson
+
+
+ ch.qos.logback.contrib
+ logback-json-core
+
+
+ ch.qos.logback.contrib
+ logback-json-classic
+
+
+
+
+
+ uk.org.lidalia
+ sysout-over-slf4j
+ 1.0.2
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/maven/pom.xml b/thirdparty-bundles/buildsupport/maven/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..87e651d475518dc7c072393ecb6ec0369c675216
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/maven/pom.xml
@@ -0,0 +1,157 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-maven
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 3.3.3
+ 1.0.2.v20150114
+
+
+
+
+
+ org.apache.maven
+ maven-aether-provider
+ ${apache-maven.version}
+
+
+
+ org.apache.maven
+ maven-model
+ ${apache-maven.version}
+
+
+
+ org.apache.maven
+ maven-repository-metadata
+ ${apache-maven.version}
+
+
+
+ org.apache.maven
+ maven-artifact
+ ${apache-maven.version}
+
+
+
+ org.apache.maven
+ maven-settings
+ ${apache-maven.version}
+
+
+
+ org.apache.maven
+ maven-settings-builder
+ ${apache-maven.version}
+
+
+
+ org.apache.maven
+ maven-core
+ ${apache-maven.version}
+
+
+
+ org.apache.maven
+ maven-plugin-api
+ ${apache-maven.version}
+
+
+
+ org.apache.maven
+ maven-compat
+ ${apache-maven.version}
+
+
+
+ org.apache.maven.plugin-tools
+ maven-plugin-annotations
+ 3.4
+
+
+
+ org.apache.maven.shared
+ maven-shared-utils
+ 0.8
+
+
+
+ org.apache.maven.shared
+ maven-verifier
+ 1.6
+
+
+ junit
+ junit-dep
+
+
+ junit
+ junit
+
+
+
+
+
+ org.eclipse.aether
+ aether-api
+ ${aether.version}
+
+
+
+ org.eclipse.aether
+ aether-util
+ ${aether.version}
+
+
+
+ org.eclipse.aether
+ aether-spi
+ ${aether.version}
+
+
+
+ org.eclipse.aether
+ aether-impl
+ ${aether.version}
+
+
+
+ org.apache.maven.indexer
+ indexer-reader
+ 5.1.2-816025a
+
+
+
+ org.apache.maven.archetype
+ archetype-catalog
+ 2.4
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/metrics/pom.xml b/thirdparty-bundles/buildsupport/metrics/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3c4c193350b6f4278460a7d0ad416d0a0b226c0f
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/metrics/pom.xml
@@ -0,0 +1,92 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-metrics
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 3.0.2
+
+
+
+
+
+ com.codahale.metrics
+ metrics-core
+ ${metrics.version}
+
+
+
+ com.codahale.metrics
+ metrics-annotation
+ ${metrics.version}
+
+
+
+ com.palominolabs.metrics
+ metrics-guice
+ ${metrics.version}
+
+
+
+ com.codahale.metrics
+ metrics-servlets
+ ${metrics.version}
+
+
+
+ com.codahale.metrics
+ metrics-jetty9
+ ${metrics.version}
+
+
+ org.eclipse.jetty
+ jetty-server
+
+
+
+
+
+ com.codahale.metrics
+ metrics-httpclient
+ ${metrics.version}
+
+
+
+ com.codahale.metrics
+ metrics-logback
+ ${metrics.version}
+
+
+
+ com.codahale.metrics
+ metrics-servlet
+ ${metrics.version}
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/osgi/pom.xml b/thirdparty-bundles/buildsupport/osgi/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6d1de71c0734f19f6927df134ca1bb874241fda6
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/osgi/pom.xml
@@ -0,0 +1,119 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-osgi
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 4.0.9
+
+
+
+
+
+ org.osgi
+ org.osgi.core
+ 6.0.0
+
+
+
+ org.osgi
+ org.osgi.compendium
+ 5.0.0
+
+
+
+ org.apache.felix
+ org.apache.felix.framework
+ 5.6.2
+
+
+
+ org.apache.karaf
+ org.apache.karaf.main
+ ${karaf.version}
+
+
+
+ org.apache.karaf.bundle
+ org.apache.karaf.bundle.core
+ ${karaf.version}
+
+
+
+ org.apache.karaf.features
+ framework
+ ${karaf.version}
+ kar
+
+
+
+ org.apache.karaf.features
+ standard
+ ${karaf.version}
+ features
+ xml
+
+
+
+ org.eclipse.equinox
+ org.eclipse.equinox.region
+ 1.1.0.v20120522-1841
+
+
+
+ org.apache.karaf.features
+ org.apache.karaf.features.core
+ ${karaf.version}
+
+
+
+ org.apache.karaf.jaas
+ org.apache.karaf.jaas.boot
+ ${karaf.version}
+
+
+
+ org.apache.karaf.jaas
+ org.apache.karaf.jaas.config
+ ${karaf.version}
+
+
+
+ org.apache.karaf.shell
+ org.apache.karaf.shell.core
+ ${karaf.version}
+
+
+
+ org.apache.karaf.shell
+ org.apache.karaf.shell.commands
+ ${karaf.version}
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/other/pom.xml b/thirdparty-bundles/buildsupport/other/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ecd6ae71d8873ec2ed7d4bd416d80c5cc0de81ed
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/other/pom.xml
@@ -0,0 +1,316 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-other
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 1.11.201
+
+
+
+
+
+ com.google.guava
+ guava
+ 21.0
+
+
+
+ com.google.code.findbugs
+ jsr305
+ 3.0.0
+
+
+
+ javax.mail
+ mail
+ 1.4.7
+
+
+
+ org.apache.velocity
+ velocity
+ 1.7
+
+
+
+ joda-time
+ joda-time
+ 2.9.5
+
+
+
+ org.hdrhistogram
+ HdrHistogram
+ 2.1.6
+
+
+
+ org.apache.tika
+ tika-core
+ 1.14
+
+
+
+ org.codehaus.mojo
+ animal-sniffer-annotations
+ 1.14
+
+
+
+ eu.bitwalker
+ UserAgentUtils
+ 1.19
+
+
+
+ javax.validation
+ validation-api
+ 1.1.0.Final
+
+
+
+ javax.el
+ javax.el-api
+ 2.2.5
+
+
+
+ org.glassfish.web
+ javax.el
+ 2.2.6
+
+
+
+ org.hibernate
+ hibernate-validator
+ 5.1.2.Final
+
+
+
+ org.quartz-scheduler
+ quartz
+ 2.2.2
+
+
+
+ org.sonatype.sisu
+ sisu-odata4j
+ 0.0.7
+
+
+
+ org.elasticsearch
+ elasticsearch
+ 2.4.3
+
+
+
+ com.vividsolutions
+ jts
+ 1.13
+
+
+
+ javax.interceptor
+ javax.interceptor-api
+ 1.2
+
+
+
+ javax.transaction
+ javax.transaction-api
+ 1.2
+
+
+
+ com.thoughtworks.paranamer
+ paranamer
+ 2.8
+
+
+
+ org.codehaus.plexus
+ plexus-interpolation
+ 1.24
+
+
+
+ org.codehaus.plexus
+ plexus-utils
+ 3.0.24
+
+
+
+
+
+
+
+
+
+
+ org.apache.geronimo.specs
+ geronimo-jcache_1.0_spec
+ 1.0-alpha-1
+
+
+
+ org.ehcache
+ ehcache
+ 3.2.1
+
+
+
+ com.squareup
+ tape
+ 1.2.3
+
+
+
+ org.freemarker
+ freemarker
+ 2.3.23
+
+
+
+ org.mozilla
+ rhino
+ 1.7.7
+
+
+
+ com.atlassian.crowd.client
+ atlassian-crowd-rest-client
+ 1.1
+
+
+
+ commons-httpclient
+ commons-httpclient
+
+
+
+ commons-lang
+ commons-lang
+
+
+ commons-codec
+ commons-codec
+
+
+
+
+
+ se.sawano.java
+ alphanumeric-comparator
+ 1.4.1
+
+
+
+ org.redline-rpm
+ redline
+ 1.2.5
+
+
+
+ com.google.jimfs
+ jimfs
+ 1.1
+
+
+
+ com.amazonaws
+ aws-java-sdk-core
+ ${aws-java-sdk.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+
+ com.amazonaws
+ aws-java-sdk-s3
+ ${aws-java-sdk.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+
+ com.amazonaws
+ aws-java-sdk-sts
+ ${aws-java-sdk.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+
+ com.amazonaws
+ aws-java-sdk-kms
+ ${aws-java-sdk.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+
+ software.amazon.ion
+ ion-java
+ 1.0.2
+
+
+
+ com.amazonaws
+ jmespath-java
+ ${aws-java-sdk.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/pom.xml b/thirdparty-bundles/buildsupport/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..51727ffdb698ef6fe7484f7b3e1ef48d1765ceb2
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/pom.xml
@@ -0,0 +1,66 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus
+ nexus-parent
+ 3.8.0-02
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ commons
+ db
+ goodies
+ groovy
+ guice
+ httpclient
+ internal
+ jetty
+ jruby
+ logging
+ maven
+ metrics
+ osgi
+ other
+ rest
+ security
+ testing
+ ui
+
+
+ all
+
+ extjs-maven-plugin
+
+
+
+
+ include-scripts
+
+ scripts
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/rest/pom.xml b/thirdparty-bundles/buildsupport/rest/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..320f2d00af966c62520d2c71276d643cfa5ba5f3
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/rest/pom.xml
@@ -0,0 +1,248 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-rest
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 2.9.2
+ 3.1.3.Final
+ 1.5.12
+
+
+
+
+
+
+ javax.ws.rs
+ javax.ws.rs-api
+ 2.0
+
+
+
+ org.jsoup
+ jsoup
+ 1.9.1
+
+
+
+
+ com.thoughtworks.xstream
+ xstream
+ 1.4.10
+
+
+ xmlpull
+ xmlpull
+
+
+ xpp3
+ xpp3_min
+
+
+
+
+
+ org.apache.servicemix.bundles
+ org.apache.servicemix.bundles.xpp3
+ 1.1.4c_7
+
+
+
+ com.sun.xml.fastinfoset
+ FastInfoset
+ 1.2.13
+
+
+
+ com.ning
+ compress-lzf
+ 1.0.2
+
+
+
+ io.netty
+ netty
+ 3.10.6.Final
+
+
+
+ io.swagger
+ swagger-annotations
+ ${swagger.version}
+
+
+
+ io.swagger
+ swagger-jaxrs
+ ${swagger.version}
+
+
+
+ org.webjars
+ swagger-ui
+ 2.2.10
+
+
+
+
+
+ org.jboss.resteasy
+ resteasy-jaxrs
+ ${resteasy.version}
+
+
+
+ org.jboss.resteasy
+ resteasy-jaxb-provider
+ ${resteasy.version}
+
+
+
+ org.jboss.resteasy
+ resteasy-multipart-provider
+ ${resteasy.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+
+ org.jboss.resteasy
+ resteasy-atom-provider
+ ${resteasy.version}
+
+
+
+ org.jboss.resteasy
+ resteasy-client
+ ${resteasy.version}
+
+
+
+ org.jboss.resteasy
+ resteasy-jackson2-provider
+ ${resteasy.version}
+
+
+
+ org.jboss.resteasy
+ resteasy-validator-provider-11
+ ${resteasy.version}
+
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ ${jackson2.version}
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ ${jackson2.version}
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson2.version}
+
+
+
+ com.fasterxml.jackson.jaxrs
+ jackson-jaxrs-json-provider
+ ${jackson2.version}
+
+
+
+ com.fasterxml.jackson.jaxrs
+ jackson-jaxrs-base
+ ${jackson2.version}
+
+
+
+ com.fasterxml.jackson.jaxrs
+ jackson-jaxrs-smile-provider
+ ${jackson2.version}
+
+
+
+ com.fasterxml.jackson.module
+ jackson-module-jaxb-annotations
+ ${jackson2.version}
+
+
+
+ com.fasterxml.jackson.module
+ jackson-module-parameter-names
+ ${jackson2.version}
+
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-cbor
+ ${jackson2.version}
+
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-smile
+ ${jackson2.version}
+
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-yaml
+ ${jackson2.version}
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-joda
+ ${jackson2.version}
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-guava
+ ${jackson2.version}
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/scripts/fixcrlf.groovy b/thirdparty-bundles/buildsupport/scripts/fixcrlf.groovy
new file mode 100644
index 0000000000000000000000000000000000000000..0716253ee3fd1b383bd1486d7d0adbe8ed52d7bf
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/scripts/fixcrlf.groovy
@@ -0,0 +1,37 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+def ant = new AntBuilder()
+
+def basedir = System.getProperty('basedir', '.') as File
+def fixlast = System.getProperty('fixlast', 'false')
+
+println "Normalizing line-endings to LF in: ${basedir.canonicalFile}"
+println " fixlast: $fixlast"
+
+ant.fixcrlf(
+ srcDir: basedir,
+ eol: 'lf',
+ eof: 'remove',
+ fixlast: fixlast
+) {
+ include(name: '**/*.java')
+ include(name: '**/*.groovy')
+ include(name: '**/*.js')
+ include(name: '**/*.css')
+ include(name: '**/*.vm')
+ include(name: '**/*.tpl')
+ include(name: '**/*.properties')
+ include(name: '**/*.xml')
+ include(name: '**/*.yml')
+ include(name: '**/*.txt')
+}
diff --git a/thirdparty-bundles/buildsupport/scripts/gobble.groovy b/thirdparty-bundles/buildsupport/scripts/gobble.groovy
new file mode 100644
index 0000000000000000000000000000000000000000..fc4c3ef3a3ef2c5f1b3a654934716d2102f99d70
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/scripts/gobble.groovy
@@ -0,0 +1,56 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+//
+// Helper to consume the output of `mvn versions:display-dependency-updates versions:display-plugin-updates`
+// and spit out unique version upgrades available.
+//
+// Usage:
+//
+// mvn versions:display-dependency-updates versions:display-plugin-updates | groovy buildsupport/scripts/gobble.groovy
+//
+
+def lines = System.in.readLines()
+
+def iter = lines.iterator()
+while (iter.hasNext()) {
+ def line = iter.next()
+ if (line.startsWith('[INFO] --- versions-maven-plugin')) {
+ break
+ }
+}
+
+def chomp(line) {
+ return line[6..-1].trim()
+}
+
+def updates = new HashSet()
+while (iter.hasNext()) {
+ def line = chomp(iter.next())
+
+ if (line.endsWith(' ...')) {
+ line = line + ' ' + chomp(iter.next())
+ }
+
+ if (line.contains('->')) {
+ def parts = line.split('\\s')
+ def update="${parts[0]}: ${parts[2]} -> ${parts[4]}"
+ updates << update
+ }
+}
+
+updates = new ArrayList(updates)
+updates.sort()
+
+for (update in updates) {
+ println update
+}
\ No newline at end of file
diff --git a/thirdparty-bundles/buildsupport/scripts/i18nVerifier.groovy b/thirdparty-bundles/buildsupport/scripts/i18nVerifier.groovy
new file mode 100644
index 0000000000000000000000000000000000000000..69e9d718ee74a694e374790605b8673618ff9323
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/scripts/i18nVerifier.groovy
@@ -0,0 +1,193 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+
+import groovy.io.FileType
+import groovy.json.JsonOutput
+import groovy.util.logging.Slf4j
+import jdk.nashorn.internal.ir.CallNode
+import jdk.nashorn.internal.ir.FunctionNode
+import jdk.nashorn.internal.ir.LexicalContext
+import jdk.nashorn.internal.ir.Node
+import jdk.nashorn.internal.ir.ObjectNode
+import jdk.nashorn.internal.ir.PropertyNode
+import jdk.nashorn.internal.ir.visitor.NodeVisitor
+import jdk.nashorn.internal.parser.Parser
+import jdk.nashorn.internal.runtime.Context
+import jdk.nashorn.internal.runtime.ErrorManager
+import jdk.nashorn.internal.runtime.Source
+import jdk.nashorn.internal.runtime.options.Options
+
+@Slf4j
+@Grab('ch.qos.logback:logback-classic:1.1.2')
+/**
+ * Parse Javascript files named 'PluginStrings.js' for i18n definitions and compare those to all calls against the
+ * NX.I18n service to find calls which would result in error.
+ */
+class NashornExtI18nParser
+{
+ private final List folders
+
+ private final Options options
+
+ NashornExtI18nParser(final List folders) {
+ this.folders = folders
+ folders.each { assert it.exists() && it.isDirectory(), "File doesn't exist or isn't a folder: $it" }
+ this.options = new Options('nashorn')
+ options.set('anon.functions', true)
+ options.set('parse.only', true)
+ options.set('scripting', true)
+ }
+
+ Map parse() {
+ def candidates = []
+ def pluginStringsFiles = []
+
+ folders.each { target ->
+ target.eachFileRecurse(FileType.FILES) { File file ->
+ if (file.name.endsWith('.js')) {
+ if (file.name == 'PluginStrings.js') {
+ pluginStringsFiles << file
+ }
+ else {
+ if(!shouldIgnore(file)) {
+ candidates << file
+ }
+ }
+ }
+ }
+ }
+
+ def keys = [] as TreeSet
+ pluginStringsFiles.each {
+ log.debug "Processing PluginStrings.js: $it"
+ def pluginStrings = parsePluginStrings(it)
+ keys.addAll(pluginStrings)
+ log.debug "Added ${pluginStrings.size()} keys"
+ }
+
+ LexicalContext lexicalContext = new LexicalContext()
+ NodeVisitor i18nVisitor = new I18NVisitor(lexicalContext)
+ NodeVisitor labelHelpVisitor = new LabelHelpVisitor(lexicalContext)
+
+ candidates.each { File file ->
+ log.debug "Processing candidate: $file"
+ parseJS(file).accept(lexicalContext, i18nVisitor)
+ parseJS(file).accept(lexicalContext, labelHelpVisitor)
+ }
+
+ Set usedKeys = i18nVisitor.keys
+ def unusedKeys = keys - usedKeys
+ def undefinedKeys = usedKeys - keys
+ return [
+ 'Available key size': keys.size(),
+ 'Used key size' : usedKeys.size(),
+ 'Unused keys' : unusedKeys,
+ 'Undefined keys' : undefinedKeys,
+ 'Number of fields with help text' : labelHelpVisitor.fieldsWithHelp.size(),
+ 'Number of fields without help text' : labelHelpVisitor.fieldsWithoutHelp.size(),
+ 'Fields without help' : labelHelpVisitor.fieldsWithoutHelp
+ ]
+ }
+
+ private List parsePluginStrings(File pluginStrings) {
+ FunctionNode functionNode = parseJS(pluginStrings)
+
+ def extDefine = functionNode.body.statements[0]
+ def defineArgs = extDefine.expression.args[1]
+ def keysField = defineArgs.elements.find { it.keyName == 'keys' }
+ return keysField.value.elements.collect { it.keyName }
+ }
+
+ private FunctionNode parseJS(File jsFile) {
+ ErrorManager errors = new ErrorManager()
+ Context context = new Context(options, errors, Thread.currentThread().getContextClassLoader())
+ return new Parser(context.getEnv(), Source.sourceFor('temp', jsFile.text), errors).parse()
+ }
+
+ private boolean shouldIgnore(File file) {
+ def isDev = file.absolutePath.split('/').contains('dev')
+ if(isDev) {
+ log.trace("Ignoring $file")
+ }
+ return isDev
+ }
+}
+
+@Slf4j
+class I18NVisitor
+ extends NodeVisitor
+{
+
+ final Set keys = [] as TreeSet
+
+ I18NVisitor(final LexicalContext lc) {
+ super(lc)
+ }
+
+ @Override
+ protected boolean enterDefault(final Node node) {
+ if (node.getClass() == CallNode && node.toString().contains('NX.I18n') &&
+ (node.function.property == 'get' || node.function.property == 'format')) {
+ log.trace('Found key: {}',node.args[0].value)
+ keys << node.args[0].value
+ }
+ return true
+ }
+}
+
+@Slf4j
+class LabelHelpVisitor
+ extends NodeVisitor
+{
+ static final Closure KEY_FINDER = { String keyName, Node n ->
+ n.getClass() == PropertyNode && n.keyName == keyName
+ }
+ static final Closure FIELD_LABEL = KEY_FINDER.curry('fieldLabel')
+ static final Closure HELP_TEXT = KEY_FINDER.curry('helpText')
+
+ final Set fieldsWithHelp = [] as TreeSet
+ final Set fieldsWithoutHelp = [] as TreeSet
+
+ LabelHelpVisitor(final LexicalContext lc) {
+ super(lc)
+ }
+
+ @Override
+ protected boolean enterDefault(final Node node) {
+ if (node.getClass() == ObjectNode && node.elements.find(FIELD_LABEL)) {
+ PropertyNode fieldLabel = node.elements.find(FIELD_LABEL)
+ PropertyNode helpText = node.elements.find(HELP_TEXT)
+ log.trace(" Found fieldLabel: ${fieldLabel.keyName} with value: ${fieldLabel.value} and helpText: ${helpText?.value}")
+ if(helpText) {
+ fieldsWithHelp << fieldLabel.value.toString()
+ }
+ else {
+ fieldsWithoutHelp << fieldLabel.value.toString()
+ }
+ }
+ return true
+ }
+}
+
+/**
+ * Default if run from parent of nexus-oss/nexus-pro folders, can be overridden by space separated command line
+ * parameters
+ */
+def targetFolders = args ?: [
+ 'plugins/nexus-coreui-plugin/src/main/resources/static/rapture/NX/coreui',
+ 'private/plugins/nexus-proui-plugin/src/main/resources/static/rapture/NX/proui',
+ 'components/nexus-rapture/src/main/resources/static/rapture/NX'
+]
+println JsonOutput.
+ prettyPrint(JsonOutput.
+ toJson(new NashornExtI18nParser(targetFolders.collect { String folder -> new File(folder) }).parse()))
diff --git a/thirdparty-bundles/buildsupport/scripts/nexusresourcedirs.groovy b/thirdparty-bundles/buildsupport/scripts/nexusresourcedirs.groovy
new file mode 100644
index 0000000000000000000000000000000000000000..d55da06fe0c983781b61771b24760772eb20a298
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/scripts/nexusresourcedirs.groovy
@@ -0,0 +1,42 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+//
+// Helper to generate NEXUS_RESOURCE_DIRS environment variable.
+//
+// Usage from project directory:
+//
+// export NEXUS_RESOURCE_DIRS=`groovy ./buildsupport/scripts/nexusresourcedirs.groovy`
+//
+// Aggregate projects using 'roots' property, from parent of project directories:
+//
+// export NEXUS_RESOURCE_DIRS=`groovy -Droots=nexus-oss,nexus-pro,nexus-bundles nexus-oss/buildsupport/scripts/nexusresourcedirs.groovy`
+//
+
+def roots = System.getProperty('roots', '.')
+def dirs = []
+
+roots.split(',').each { root ->
+ def dir = new File(root)
+ if (dir.exists()) {
+ dir.eachDirRecurse {
+ if (it.path.endsWith('src/main/resources/static')) {
+ dirs << it.parentFile.canonicalPath
+ }
+ else if (it.path.endsWith('src/test/ft-resources')) {
+ dirs << it.canonicalPath
+ }
+ }
+ }
+}
+
+println dirs.join(',')
diff --git a/thirdparty-bundles/buildsupport/scripts/pom.xml b/thirdparty-bundles/buildsupport/scripts/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9de48bb83590bdb47aff0b4e5b141b152d83caf9
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/scripts/pom.xml
@@ -0,0 +1,62 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-scripts
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+
+
+
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport-all
+ pom
+ 3.8.0-02
+ import
+
+
+
+
+
+
+
+
+ idea
+
+
+ org.codehaus.groovy
+ groovy-all
+ provided
+
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/security/pom.xml b/thirdparty-bundles/buildsupport/security/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..288e9370665a4491ed99da360dfc6fbc7eaddbd5
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/security/pom.xml
@@ -0,0 +1,104 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-security
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 1.56
+ 1.3.2
+
+
+
+
+
+
+
+
+ org.bouncycastle
+ bcprov-jdk15on
+ ${bouncycastle.version}
+
+
+
+ org.bouncycastle
+ bcpg-jdk15on
+ ${bouncycastle.version}
+
+
+
+ org.bouncycastle
+ bcpkix-jdk15on
+ ${bouncycastle.version}
+
+
+
+
+
+ org.apache.geronimo.framework
+ geronimo-crypto
+ 2.2.1
+
+
+
+
+
+ org.apache.shiro
+ shiro-core
+ ${apache-shiro.version}
+
+
+ commons-logging
+ commons-logging
+
+
+ commons-beanutils
+ commons-beanutils
+
+
+
+
+
+ org.apache.shiro
+ shiro-guice
+ ${apache-shiro.version}
+
+
+
+ org.apache.shiro
+ shiro-web
+ ${apache-shiro.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/testing/pom.xml b/thirdparty-bundles/buildsupport/testing/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..995a4991487050357db9e3fc74917fd51b9c54ee
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/testing/pom.xml
@@ -0,0 +1,196 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-testing
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+ 4.9.2
+ 2.38.0
+
+
+
+
+
+
+ org.databene
+ contiperf
+ 2.3.4
+
+
+
+ com.github.dblock
+ oshi-core
+ 1.4
+
+
+
+ com.icegreen
+ greenmail
+ 1.4.1
+
+
+ javax.activation
+ activation
+
+
+
+
+
+ junit
+ junit
+ 4.12
+
+
+
+ com.jayway.awaitility
+ awaitility
+ 1.7.0
+
+
+
+ net.javacrumbs.json-unit
+ json-unit
+ 1.15.0
+
+
+
+ org.ops4j.pax.exam
+ pax-exam
+ ${pax-exam.version}
+
+
+
+ org.ops4j.pax.exam
+ pax-exam-junit4
+ ${pax-exam.version}
+
+
+
+ org.ops4j.pax.exam
+ pax-exam-spi
+ ${pax-exam.version}
+
+
+
+ org.ops4j.pax.exam
+ pax-exam-extender-service
+ ${pax-exam.version}
+
+
+
+ org.ops4j.pax.exam
+ pax-exam-container-karaf
+ ${pax-exam.version}
+
+
+
+ org.ops4j.pax.exam
+ pax-exam-features
+ ${pax-exam.version}
+ xml
+
+
+
+ org.ops4j.pax.url
+ pax-url-aether
+ 2.4.7
+
+
+
+ org.littleshoot
+ littleproxy
+ 1.1.0
+
+
+
+
+ org.apache.directory.server
+ apacheds-test-framework
+ 2.0.0-M19
+
+
+ org.slf4j
+ slf4j-log4j12
+
+
+ bouncycastle
+ bcprov-jdk15
+
+
+ org.apache.directory.server
+ apacheds-jdbm-partition
+
+
+ org.apache.directory.jdbm
+ apacheds-jdbm1
+
+
+
+
+
+ com.bryntum.siesta
+ siesta-standard
+ 3.1.0
+ zip
+
+
+
+ com.spotify
+ docker-client
+ 6.1.0
+ shaded
+
+
+
+ com.github.stefanbirkner
+ system-rules
+ 1.16.1
+
+
+
+ com.unboundid
+ unboundid-ldapsdk
+ 3.2.1
+
+
+
+ org.xmlunit
+ xmlunit-core
+ 2.3.0
+
+
+
+ io.gatling.highcharts
+ gatling-charts-highcharts
+ 2.2.5
+
+
+
+
+
diff --git a/thirdparty-bundles/buildsupport/ui/pom.xml b/thirdparty-bundles/buildsupport/ui/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e1e768d2b3f8149f2bf18560c110888940865cfb
--- /dev/null
+++ b/thirdparty-bundles/buildsupport/ui/pom.xml
@@ -0,0 +1,54 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus.buildsupport
+ nexus-buildsupport
+ 3.8.0-02
+
+
+ nexus-buildsupport-ui
+ ${project.groupId}:${project.artifactId}
+ pom
+
+
+
+
+ com.sencha
+ ext
+ commercial
+ zip
+ 4.2.3
+
+
+
+ org.sonatype.directjngine
+ directjngine
+ 2.2.1
+
+
+
+ com.google.code.gson
+ gson
+ 2.3.1
+
+
+
+
+
diff --git a/thirdparty-bundles/components/nexus-analytics-api/pom.xml b/thirdparty-bundles/components/nexus-analytics-api/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1b2b96a9ffc4a3ecee8ac0230f07df63d0c86bc0
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-analytics-api/pom.xml
@@ -0,0 +1,48 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus
+ nexus-components
+ 3.8.0-02
+
+
+ nexus-analytics-api
+ ${project.groupId}:${project.artifactId}
+ bundle
+
+
+
+ org.sonatype.nexus
+ nexus-common
+
+
+
+ org.apache.shiro
+ shiro-core
+
+
+
+ org.sonatype.goodies
+ goodies-testsupport
+ test
+
+
+
+
diff --git a/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/EventData.java b/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/EventData.java
new file mode 100644
index 0000000000000000000000000000000000000000..070e8071a89ac6bd057509329d7b89d9f95a99b3
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/EventData.java
@@ -0,0 +1,152 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.analytics;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.sonatype.nexus.common.entity.AbstractEntity;
+
+/**
+ * Analytics event data.
+ *
+ * @since 3.0
+ */
+public class EventData
+ extends AbstractEntity
+ implements Cloneable, Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Event type.
+ */
+ private String type;
+
+ /**
+ * Event timestamp in milliseconds.
+ */
+ private Long timestamp;
+
+ /**
+ * Event sequence (rolling) to distinguish events which have the same timestamp.
+ */
+ private Long sequence;
+
+ /**
+ * Event duration in nanoseconds.
+ */
+ private Long duration;
+
+ /**
+ * Event user-id.
+ */
+ private String userId;
+
+ /**
+ * Event session-id.
+ */
+ private String sessionId;
+
+ /**
+ * Event attributes.
+ */
+ private Map attributes = new HashMap<>();
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(final String type) {
+ this.type = type;
+ }
+
+ public Long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(final Long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public Long getSequence() {
+ return sequence;
+ }
+
+ public void setSequence(final Long sequence) {
+ this.sequence = sequence;
+ }
+
+ public Long getDuration() {
+ return duration;
+ }
+
+ public void setDuration(final Long duration) {
+ this.duration = duration;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(final String userId) {
+ this.userId = userId;
+ }
+
+ public String getSessionId() {
+ return sessionId;
+ }
+
+ public void setSessionId(final String sessionId) {
+ this.sessionId = sessionId;
+ }
+
+ public Map getAttributes() {
+ return attributes;
+ }
+
+ /**
+ * @since 3.5
+ */
+ public void setAttributes(final Map attributes) {
+ this.attributes = attributes;
+ }
+
+ /**
+ * Returns a deeply cloned copy.
+ */
+ public EventData copy() {
+ try {
+ EventData copy = (EventData) clone();
+ copy.attributes = new HashMap<>(this.attributes);
+ return copy;
+ }
+ catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "{" +
+ "type='" + type + '\'' +
+ ", timestamp=" + timestamp +
+ ", sequence=" + sequence +
+ ", duration=" + duration +
+ ", userId='" + userId + '\'' +
+ ", sessionId='" + sessionId + '\'' +
+ ", attributes=" + attributes +
+ '}';
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/EventDataFactory.java b/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/EventDataFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..43d5ba7349fc97348cbf238bedf3443a2176cdac
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/EventDataFactory.java
@@ -0,0 +1,72 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.analytics;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.sonatype.nexus.common.node.NodeAccess;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.Subject;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Helper to build {@link EventData} instances.
+ *
+ * @since 3.6.0
+ */
+@Named
+@Singleton
+public class EventDataFactory
+{
+ private final RollingCounter counter = new RollingCounter(999_999_999_999_999L);
+
+ private final NodeAccess nodeAccess;
+
+ @Inject
+ public EventDataFactory(final NodeAccess nodeAccess) {
+ this.nodeAccess = checkNotNull(nodeAccess);
+ }
+
+ public EventData create(final String type) {
+ EventData data = new EventData();
+ data.setType(type);
+ data.setTimestamp(System.currentTimeMillis());
+ data.setSequence(counter.next());
+
+ // capture the user and session ids if we can
+ Subject subject = SecurityUtils.getSubject();
+ if (subject != null) {
+ Object principal = subject.getPrincipal();
+ if (principal != null) {
+ data.setUserId(principal.toString());
+ }
+
+ Session session = subject.getSession(false);
+ if (session != null) {
+ data.setSessionId(session.getId().toString());
+ }
+ }
+
+ // capture node id
+ if (nodeAccess.getId() != null) {
+ data.getAttributes().put("nodeId", nodeAccess.getId());
+ }
+
+ return data;
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/EventRecorder.java b/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/EventRecorder.java
new file mode 100644
index 0000000000000000000000000000000000000000..10362c9cb642f8fad5aa29e56d24287c3e65c013
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/EventRecorder.java
@@ -0,0 +1,25 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.analytics;
+
+/**
+ * Analytics event data recorder.
+ *
+ * @since 3.0
+ */
+public interface EventRecorder
+{
+ boolean isEnabled();
+
+ void record(EventData data);
+}
diff --git a/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/RollingCounter.java b/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/RollingCounter.java
new file mode 100644
index 0000000000000000000000000000000000000000..754407c33ce205020d94affe5a34d695bd93bf96
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/RollingCounter.java
@@ -0,0 +1,44 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.analytics;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Rolling (zero-based) long counter.
+ *
+ * @since 3.0
+ */
+class RollingCounter
+{
+ private final AtomicLong value = new AtomicLong(-1);
+
+ private final long max;
+
+ RollingCounter(final long max) {
+ checkArgument(max > 0);
+ this.max = max + 1; // inclusive
+ }
+
+ public long next() {
+ long current, next;
+ do {
+ current = value.get();
+ next = (current + 1) % max;
+ }
+ while (!value.compareAndSet(current, next));
+ return next;
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/package-info.java b/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..5cad4397d5075923e9f19880f220ec414b2b09db
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-analytics-api/src/main/java/org/sonatype/nexus/analytics/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+
+/**
+ * Analytics event collection.
+ *
+ * @since 3.0
+ */
+package org.sonatype.nexus.analytics;
\ No newline at end of file
diff --git a/thirdparty-bundles/components/nexus-analytics-api/src/test/java/org/sonatype/nexus/analytics/EventDataFactoryTest.java b/thirdparty-bundles/components/nexus-analytics-api/src/test/java/org/sonatype/nexus/analytics/EventDataFactoryTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7c77b7d85689bd25c3239301b97868fdaccfdd8b
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-analytics-api/src/test/java/org/sonatype/nexus/analytics/EventDataFactoryTest.java
@@ -0,0 +1,109 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.analytics;
+
+import org.sonatype.goodies.testsupport.TestSupport;
+import org.sonatype.nexus.common.node.NodeAccess;
+
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.subject.support.SubjectThreadState;
+import org.apache.shiro.util.ThreadState;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests for {@link EventDataFactory}.
+ */
+public class EventDataFactoryTest
+ extends TestSupport
+{
+ private ThreadState threadState;
+
+ @Mock
+ private Subject subject;
+
+ @Mock
+ private NodeAccess nodeAccess;
+
+ @Before
+ public void setUp() throws Exception {
+ threadState = new SubjectThreadState(subject);
+ threadState.bind();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (threadState != null) {
+ threadState.clear();
+ threadState = null;
+ }
+ }
+
+ @Test
+ public void basics() throws Exception {
+ when(subject.getPrincipal()).thenReturn("foo");
+ Session session = mock(Session.class);
+ when(subject.getSession(false)).thenReturn(session);
+ when(session.getId()).thenReturn("1234");
+
+ EventData event = new EventDataFactory(nodeAccess).create("TEST");
+ assertThat(event, notNullValue());
+ assertThat(event.getType(), is("TEST"));
+ assertThat(event.getTimestamp(), notNullValue());
+ assertThat(event.getSequence(), notNullValue());
+ assertThat(event.getUserId(), is("foo"));
+ assertThat(event.getSessionId(), is("1234"));
+ }
+
+ @Test
+ public void subjectWithNullPrincipal() throws Exception {
+ when(subject.getPrincipal()).thenReturn(null);
+
+ EventData event = new EventDataFactory(nodeAccess).create("TEST");
+ assertThat(event, notNullValue());
+ assertThat(event.getUserId(), nullValue());
+ }
+
+ @Test
+ public void subjectWithNullSession() throws Exception {
+ when(subject.getSession(false)).thenReturn(null);
+
+ EventData event = new EventDataFactory(nodeAccess).create("TEST");
+ assertThat(event, notNullValue());
+ assertThat(event.getSessionId(), nullValue());
+ }
+
+ @Test
+ public void nodeIdWhenClustered() throws Exception {
+ when(nodeAccess.getId()).thenReturn("e91d48ec-8460-11e7-bb31-be2e44b06b34");
+
+ EventData event = new EventDataFactory(nodeAccess).create("TEST");
+
+ assertThat(event, notNullValue());
+ assertThat(event.getAttributes().entrySet(), hasSize(1));
+ assertThat(event.getAttributes(), hasEntry("nodeId", "e91d48ec-8460-11e7-bb31-be2e44b06b34"));
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-analytics-api/src/test/java/org/sonatype/nexus/analytics/RollingCounterTest.java b/thirdparty-bundles/components/nexus-analytics-api/src/test/java/org/sonatype/nexus/analytics/RollingCounterTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..147aa92c9e5e5befaea5de8767c31811ed176387
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-analytics-api/src/test/java/org/sonatype/nexus/analytics/RollingCounterTest.java
@@ -0,0 +1,59 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.analytics;
+
+import org.sonatype.goodies.testsupport.TestSupport;
+
+import org.junit.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+/**
+ * Tests for {@link RollingCounter}.
+ */
+public class RollingCounterTest
+ extends TestSupport
+{
+ @Test
+ public void basics() {
+ RollingCounter underTest = new RollingCounter(5);
+ assertThat(underTest.next(), is(0L));
+ assertThat(underTest.next(), is(1L));
+ assertThat(underTest.next(), is(2L));
+ assertThat(underTest.next(), is(3L));
+ assertThat(underTest.next(), is(4L));
+ assertThat(underTest.next(), is(5L));
+
+ // rolls
+ assertThat(underTest.next(), is(0L));
+ assertThat(underTest.next(), is(1L));
+ assertThat(underTest.next(), is(2L));
+ assertThat(underTest.next(), is(3L));
+ assertThat(underTest.next(), is(4L));
+ assertThat(underTest.next(), is(5L));
+
+ // rolls
+ assertThat(underTest.next(), is(0L));
+ assertThat(underTest.next(), is(1L));
+ assertThat(underTest.next(), is(2L));
+ assertThat(underTest.next(), is(3L));
+ assertThat(underTest.next(), is(4L));
+ assertThat(underTest.next(), is(5L));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void maxTooSmall() {
+ new RollingCounter(0);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-audit/pom.xml b/thirdparty-bundles/components/nexus-audit/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e10530e6b13b698a779d2ce7ab6e501bf69992fe
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-audit/pom.xml
@@ -0,0 +1,43 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus
+ nexus-components
+ 3.8.0-02
+
+
+ nexus-audit
+ ${project.groupId}:${project.artifactId}
+ bundle
+
+
+
+ org.sonatype.nexus
+ nexus-common
+
+
+
+ org.sonatype.goodies
+ goodies-testsupport
+ test
+
+
+
+
diff --git a/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/AuditData.java b/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/AuditData.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb78a06f459ee304ea58f061e9502b2c0185221a
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/AuditData.java
@@ -0,0 +1,177 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+
+package org.sonatype.nexus.audit;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.sonatype.nexus.common.entity.AbstractEntity;
+import org.sonatype.nexus.common.entity.EntityMetadata;
+import org.sonatype.nexus.common.node.NodeAccess;
+
+/**
+ * Audit data.
+ *
+ * @since 3.1
+ */
+public class AuditData
+ extends AbstractEntity
+ implements Cloneable, Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The domain of the audit data.
+ *
+ * ex: 'security.user'
+ *
+ * Domain should use dot-notation to encode hierarchy structure.
+ */
+ private String domain;
+
+ /**
+ * The type of audit data relevant for domain.
+ *
+ * ex: 'create'
+ */
+ private String type;
+
+ /**
+ * Context of the audit data for domain and type.
+ *
+ * ex: 'jdillon'
+ */
+ private String context;
+
+ /**
+ * When the change occurred.
+ */
+ private Date timestamp;
+
+ /**
+ * The node-id where the change occurred.
+ *
+ * @see NodeAccess#getId()
+ */
+ private String nodeId;
+
+ /**
+ * Who initiated the change.
+ *
+ * ex: 'admin/192.168.0.57'
+ */
+ private String initiator;
+
+ /**
+ * Extensible attributes for the change.
+ */
+ private Map attributes = new LinkedHashMap<>();
+
+ public String getDomain() {
+ return domain;
+ }
+
+ public void setDomain(final String domain) {
+ this.domain = domain;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(final String type) {
+ this.type = type;
+ }
+
+ public String getContext() {
+ return context;
+ }
+
+ public void setContext(final String context) {
+ this.context = context;
+ }
+
+ public Date getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(final Date timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ public String getNodeId() {
+ return nodeId;
+ }
+
+ public void setNodeId(final String nodeId) {
+ this.nodeId = nodeId;
+ }
+
+ public String getInitiator() {
+ return initiator;
+ }
+
+ public void setInitiator(final String initiator) {
+ this.initiator = initiator;
+ }
+
+ public Map getAttributes() {
+ return attributes;
+ }
+
+ /**
+ * @since 3.5
+ */
+ public void setAttributes(final Map attributes) {
+ this.attributes = attributes;
+ }
+
+ /**
+ * Returns a deeply cloned copy.
+ */
+ public AuditData copy() {
+ try {
+ AuditData copy = (AuditData) clone();
+ copy.attributes = new LinkedHashMap<>(this.attributes);
+ return copy;
+ }
+ catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Returns deeply cloned copy detached from {@link EntityMetadata}.
+ */
+ public AuditData detach() {
+ AuditData copy = copy();
+ copy.setEntityMetadata(null);
+ return copy;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "{" +
+ "domain='" + domain + '\'' +
+ ", type='" + type + '\'' +
+ ", context='" + context + '\'' +
+ ", timestamp=" + timestamp +
+ ", nodeId='" + nodeId + '\'' +
+ ", initiator='" + initiator + '\'' +
+ ", attributes=" + attributes +
+ '}';
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/AuditDataRecordedEvent.java b/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/AuditDataRecordedEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..2cf73d9b105f6dedd1c409465d694cefff038dda
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/AuditDataRecordedEvent.java
@@ -0,0 +1,41 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+
+package org.sonatype.nexus.audit;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Event fired after {@link AuditData} had been recorded.
+ *
+ * @since 3.1
+ */
+public class AuditDataRecordedEvent
+{
+ private final AuditData data;
+
+ public AuditDataRecordedEvent(final AuditData data) {
+ this.data = checkNotNull(data);
+ }
+
+ public AuditData getData() {
+ return data;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "{" +
+ "data=" + data +
+ '}';
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/AuditRecorder.java b/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/AuditRecorder.java
new file mode 100644
index 0000000000000000000000000000000000000000..45a9d5b6e8274d266e616e4052c6877922564524
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/AuditRecorder.java
@@ -0,0 +1,29 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+
+package org.sonatype.nexus.audit;
+
+/**
+ * Audit data recorder.
+ *
+ * @since 3.1
+ */
+public interface AuditRecorder
+{
+ boolean isEnabled();
+
+ /**
+ * Record audit data and fires {@link AuditDataRecordedEvent}.
+ */
+ void record(AuditData data);
+}
diff --git a/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/AuditorSupport.java b/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/AuditorSupport.java
new file mode 100644
index 0000000000000000000000000000000000000000..18595777db6d1c4dbdb07a0785adec0c4e23010b
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/AuditorSupport.java
@@ -0,0 +1,142 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+
+package org.sonatype.nexus.audit;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+import org.sonatype.goodies.common.ComponentSupport;
+import org.sonatype.nexus.common.event.EventHelper;
+import org.sonatype.nexus.common.text.Strings2;
+
+import com.google.common.base.Joiner;
+
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * Support for auditor implementations.
+ *
+ * @since 3.1
+ */
+public abstract class AuditorSupport
+ extends ComponentSupport
+{
+ /**
+ * Context value to use for global/system audit data when there is nothing more specific to use.
+ */
+ protected static final String SYSTEM_CONTEXT = "system";
+
+ /**
+ * Common type for created events.
+ */
+ protected static final String CREATED_TYPE = "created";
+
+ /**
+ * Common type for updated events.
+ */
+ protected static final String UPDATED_TYPE = "updated";
+
+ /**
+ * Common type for deleted events.
+ */
+ protected static final String DELETED_TYPE = "deleted";
+
+ /**
+ * Common type for changed events.
+ */
+ protected static final String CHANGED_TYPE = "changed";
+
+ /**
+ * Helper to join a list into a string for attributes.
+ */
+ private static final Joiner LIST_JOINER = Joiner.on(", ").skipNulls();
+
+ private Provider auditRecorder;
+
+ /**
+ * Mapping of class to simple type names for auditing.
+ */
+ private Map typeLookup = new HashMap<>();
+
+ @Inject
+ public void setAuditRecorder(final Provider auditRecorder) {
+ this.auditRecorder = auditRecorder;
+ }
+
+ /**
+ * Register a simple type name for given class.
+ */
+ protected void registerType(final Class type, final String name) {
+ typeLookup.put(type, name);
+ }
+
+ /**
+ * Lookup simple type name for given class.
+ *
+ * If there is no mapping then the class.simpleName will be used.
+ */
+ protected String type(final Class type) {
+ String name = typeLookup.get(type);
+ if (name == null) {
+ return Strings2.lower(type.getSimpleName());
+ }
+ return name;
+ }
+
+ private AuditRecorder recorder() {
+ checkState(auditRecorder != null, "Missing audit-recorder");
+ return auditRecorder.get();
+ }
+
+ /**
+ * @deprecated use {@link #isRecording()} instead
+ */
+ @Deprecated
+ protected boolean isEnabled() {
+ return isRecording();
+ }
+
+ /**
+ * @since 3.2
+ */
+ protected boolean isRecording() {
+ return recorder().isEnabled() && !EventHelper.isReplicating();
+ }
+
+ protected void record(final AuditData data) {
+ recorder().record(data);
+ }
+
+ /**
+ * Helper to convert an object into a string.
+ */
+ @Nullable
+ protected static String string(final Object value) {
+ if (value == null) {
+ return null;
+ }
+ return String.valueOf(value);
+ }
+
+ /**
+ * Helper to conviert an iterable into a string.
+ */
+ protected static String string(final Iterable value) {
+ return LIST_JOINER.join(value);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/InitiatorProvider.java b/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/InitiatorProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ce5c459a52e86c2e940d4b98bcbf170c9a65a32
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/InitiatorProvider.java
@@ -0,0 +1,26 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.audit;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Provides the current context {@link AuditData#initiator} value.
+ *
+ * @since 3.1
+ */
+public interface InitiatorProvider
+{
+ @Nonnull
+ String get();
+}
diff --git a/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/package-info.java b/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..6052a8609a8a29521cb6ab7ff70e253d8538dd65
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-audit/src/main/java/org/sonatype/nexus/audit/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+
+/**
+ * Audit framework.
+ *
+ * @since 3.1
+ */
+package org.sonatype.nexus.audit;
diff --git a/thirdparty-bundles/components/nexus-base/pom.xml b/thirdparty-bundles/components/nexus-base/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..79b96670fdafcf15d3d51c3aa0f86d63fbc032e3
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/pom.xml
@@ -0,0 +1,190 @@
+
+
+
+ 4.0.0
+
+
+ org.sonatype.nexus
+ nexus-components
+ 3.8.0-02
+
+
+ nexus-base
+ ${project.groupId}:${project.artifactId}
+ bundle
+
+
+
+ org.apache.karaf.jaas
+ org.apache.karaf.jaas.boot
+ provided
+
+
+
+ org.apache.karaf.jaas
+ org.apache.karaf.jaas.config
+ provided
+
+
+
+ org.slf4j
+ jcl-over-slf4j
+
+
+
+ javax.ws.rs
+ javax.ws.rs-api
+
+
+
+ ch.qos.logback
+ logback-core
+
+
+
+ ch.qos.logback
+ logback-classic
+
+
+
+ com.codahale.metrics
+ metrics-core
+
+
+
+ com.palominolabs.metrics
+ metrics-guice
+
+
+
+ com.codahale.metrics
+ metrics-httpclient
+
+
+
+ com.codahale.metrics
+ metrics-servlets
+
+
+
+ com.codahale.metrics
+ metrics-servlet
+
+
+
+ com.orientechnologies
+ orientdb-tools
+
+
+
+ org.apache.velocity
+ velocity
+
+
+
+ org.sonatype.nexus
+ nexus-commands
+
+
+
+ org.sonatype.nexus
+ nexus-mime
+
+
+
+ org.sonatype.nexus
+ nexus-orient
+
+
+
+ org.sonatype.nexus
+ nexus-scheduling
+
+
+
+ org.sonatype.nexus
+ nexus-security
+
+
+
+ org.sonatype.nexus
+ nexus-servlet
+
+
+
+ org.sonatype.nexus
+ nexus-ssl
+
+
+
+ org.sonatype.nexus
+ nexus-thread
+
+
+
+ org.sonatype.nexus
+ nexus-upgrade
+
+
+
+ org.sonatype.nexus
+ nexus-supportzip-api
+
+
+
+ org.sonatype.nexus
+ nexus-webresources-api
+
+
+
+ org.sonatype.goodies
+ goodies-testsupport
+ test
+
+
+
+ org.spockframework
+ spock-core
+ test
+
+
+
+ cglib
+ cglib-nodep
+ test
+
+
+
+ org.objenesis
+ objenesis
+ test
+
+
+
+ com.jayway.awaitility
+ awaitility
+ test
+
+
+
+ org.eclipse.jetty
+ jetty-servlet
+ test
+
+
+
+
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/app/ApplicationDirectoriesImpl.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/app/ApplicationDirectoriesImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..797bc06dcd2125c7876e71d5c8f73bb9825cea97
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/app/ApplicationDirectoriesImpl.java
@@ -0,0 +1,139 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.app;
+
+import java.io.File;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.sonatype.goodies.common.ComponentSupport;
+import org.sonatype.nexus.common.app.ApplicationDirectories;
+import org.sonatype.nexus.common.io.DirectoryHelper;
+
+import com.google.common.base.Throwables;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Default {@link ApplicationDirectories} implementation.
+ *
+ * @since 2.8
+ */
+@Named
+@Singleton
+public class ApplicationDirectoriesImpl
+ extends ComponentSupport
+ implements ApplicationDirectories
+{
+ private final File installDir;
+
+ private final File configDir;
+
+ private final File workDir;
+
+ private final File tempDir;
+
+ @Inject
+ public ApplicationDirectoriesImpl(@Named("${karaf.base}") final File installDir,
+ @Named("${karaf.data}") final File workDir)
+ {
+ this.installDir = resolve(installDir, false);
+ log.debug("Install dir: {}", this.installDir);
+
+ this.configDir = resolve(new File(installDir, "etc"), false);
+ log.debug("Config dir: {}", this.configDir);
+
+ this.workDir = resolve(workDir, true);
+ log.debug("Work dir: {}", this.workDir);
+
+ // Resolve the tmp dir from system properties.
+ String tmplocation = System.getProperty("java.io.tmpdir", "tmp");
+ this.tempDir = resolve(new File(tmplocation), true);
+ log.debug("Temp dir: {}", this.tempDir);
+ }
+
+ @Override
+ public File getInstallDirectory() {
+ return installDir;
+ }
+
+ @Override
+ public File getConfigDirectory(final String subsystem) {
+ checkNotNull(subsystem);
+ return new File(configDir, subsystem);
+ }
+
+ @Override
+ public File getTemporaryDirectory() {
+ return tempDir;
+ }
+
+ @Override
+ public File getWorkDirectory() {
+ return workDir;
+ }
+
+ @Override
+ public File getWorkDirectory(final String path, final boolean create) {
+ checkNotNull(path);
+ File dir = new File(path);
+ if (!dir.isAbsolute()) {
+ dir = new File(getWorkDirectory(), path);
+ }
+ return resolve(dir, create);
+ }
+
+ @Override
+ public File getWorkDirectory(final String path) {
+ return getWorkDirectory(path, true);
+ }
+
+ private void mkdir(final File dir) {
+ if (dir.isDirectory()) {
+ // skip already exists
+ return;
+ }
+
+ try {
+ DirectoryHelper.mkdir(dir.toPath());
+ log.debug("Created directory: {}", dir);
+ }
+ catch (Exception e) {
+ log.error("Failed to create directory: {}", dir);
+ Throwables.throwIfUnchecked(e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ private File resolve(File dir, final boolean create) {
+ checkNotNull(dir);
+
+ log.trace("Resolving directory: {}; create: {}", dir, create);
+ try {
+ dir = dir.getCanonicalFile();
+ }
+ catch (Exception e) {
+ log.error("Failed to canonicalize directory: {}", dir);
+ Throwables.throwIfUnchecked(e);
+ throw new RuntimeException(e);
+ }
+
+ if (create) {
+ mkdir(dir);
+ }
+
+ return dir;
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/app/BaseUrlManagerImpl.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/app/BaseUrlManagerImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..80429d633ea11a2010b1db664e4b1b85a931dcec
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/app/BaseUrlManagerImpl.java
@@ -0,0 +1,128 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.app;
+
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+import javax.servlet.http.HttpServletRequest;
+
+import org.sonatype.goodies.common.ComponentSupport;
+import org.sonatype.nexus.common.app.BaseUrlHolder;
+import org.sonatype.nexus.common.app.BaseUrlManager;
+
+import com.google.common.base.Strings;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Default {@link BaseUrlManager}.
+ *
+ * @since 3.0
+ */
+@Named
+@Singleton
+public class BaseUrlManagerImpl
+ extends ComponentSupport
+ implements BaseUrlManager
+{
+ private final Provider requestProvider;
+
+ private volatile String url;
+
+ private volatile boolean force;
+
+ @Inject
+ public BaseUrlManagerImpl(final Provider requestProvider,
+ @Named("${org.sonatype.nexus.internal.app.BaseUrlManagerImpl.force:-false}") final boolean force) {
+ this.requestProvider = checkNotNull(requestProvider);
+ this.force = force;
+ log.debug("Force: {}", force);
+ }
+
+ @Override
+ public void setUrl(final String url) {
+ this.url = url;
+ }
+
+ @Override
+ public String getUrl() {
+ return url;
+ }
+
+ @Override
+ public boolean isForce() {
+ return force;
+ }
+
+ @Override
+ public void setForce(final boolean force) {
+ this.force = force;
+ }
+
+ /**
+ * Return the current HTTP servlet-request if there is one in the current scope.
+ */
+ @Nullable
+ private HttpServletRequest httpRequest() {
+ try {
+ return requestProvider.get();
+ }
+ catch (Exception e) {
+ log.trace("Unable to resolve HTTP servlet-request", e);
+ return null;
+ }
+ }
+
+ /**
+ * Detect base-url from forced settings, request or non-forced settings.
+ */
+ @Nullable
+ @Override
+ public String detectUrl() {
+ // force base-url always wins if set
+ if (force && !Strings.isNullOrEmpty(url)) {
+ return url;
+ }
+
+ // attempt to detect from HTTP request
+ HttpServletRequest request = httpRequest();
+ if (request != null) {
+ StringBuffer url = request.getRequestURL();
+ String uri = request.getRequestURI();
+ String ctx = request.getContextPath();
+ return url.substring(0, url.length() - uri.length() + ctx.length());
+ }
+
+ // no request in context, non-forced base-url
+ if (!Strings.isNullOrEmpty(url)) {
+ return url;
+ }
+
+ // unable to determine base-url
+ return null;
+ }
+
+ /**
+ * Detect and set (if non-null) the base-url.
+ */
+ @Override
+ public void detectAndHoldUrl() {
+ String url = detectUrl();
+ if (url != null) {
+ BaseUrlHolder.set(url);
+ }
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/app/GlobalComponentLookupHelperImpl.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/app/GlobalComponentLookupHelperImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..c441460190a3ab18a436bf37af9f57045556db83
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/app/GlobalComponentLookupHelperImpl.java
@@ -0,0 +1,121 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.app;
+
+import java.util.Iterator;
+
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.sonatype.goodies.common.ComponentSupport;
+import org.sonatype.nexus.common.app.GlobalComponentLookupHelper;
+
+import com.google.inject.Key;
+import org.eclipse.sisu.BeanEntry;
+import org.eclipse.sisu.inject.BeanLocator;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.inject.name.Names.named;
+
+/**
+ * Default {@link GlobalComponentLookupHelper}.
+ *
+ * @since 3.0
+ */
+@Named
+@Singleton
+public class GlobalComponentLookupHelperImpl
+ extends ComponentSupport
+ implements GlobalComponentLookupHelper
+{
+ private final ClassLoader classLoader;
+
+ private final BeanLocator beanLocator;
+
+ @Inject
+ public GlobalComponentLookupHelperImpl(@Named("nexus-uber") final ClassLoader classLoader,
+ final BeanLocator beanLocator)
+ {
+ this.classLoader = checkNotNull(classLoader);
+ this.beanLocator = checkNotNull(beanLocator);
+ }
+
+ @Override
+ @Nullable
+ public Object lookup(final String className) {
+ checkNotNull(className);
+ try {
+ log.trace("Looking up component by class-name: {}", className);
+ Class> type = classLoader.loadClass(className);
+ return lookup(type);
+ }
+ catch (Exception e) {
+ log.trace("Unable to lookup component by class-name: {}; ignoring", className, e);
+ }
+ return null;
+ }
+
+ @Override
+ @Nullable
+ @SuppressWarnings("unchecked")
+ public T lookup(final Class clazz) {
+ checkNotNull(clazz);
+ return (T) lookup(Key.get(clazz));
+ }
+
+ @Override
+ @Nullable
+ @SuppressWarnings("unchecked")
+ public T lookup(final Class clazz, final String name) {
+ checkNotNull(clazz);
+ checkNotNull(name);
+ return (T) lookup(Key.get(clazz, named(name)));
+ }
+
+ @Override
+ @Nullable
+ public Object lookup(final Key key) {
+ checkNotNull(key);
+ try {
+ log.trace("Looking up component by key: {}", key);
+ @SuppressWarnings("unchecked")
+ Iterator iter = beanLocator.locate(key).iterator();
+ if (iter.hasNext()) {
+ return iter.next().getValue();
+ }
+ else {
+ log.trace("Component not found for key: {}", key);
+ }
+ }
+ catch (Exception e) {
+ log.trace("Unable to lookup component by key: {}; ignoring", key, e);
+ }
+ return null;
+ }
+
+ @Override
+ @Nullable
+ public Class> type(final String className) {
+ checkNotNull(className);
+ try {
+ log.trace("Looking up type: {}", className);
+ return classLoader.loadClass(className);
+ }
+ catch (Exception e) {
+ log.trace("Unable to lookup type: {}; ignoring", className, e);
+ }
+ return null;
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/app/NexusUberClassloader.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/app/NexusUberClassloader.java
new file mode 100644
index 0000000000000000000000000000000000000000..a4d1d88c64ae25339767a8829e7d1359ccf9cbc6
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/app/NexusUberClassloader.java
@@ -0,0 +1,104 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.app;
+
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import com.google.common.base.Throwables;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.collect.Lists;
+import org.eclipse.sisu.space.ClassSpace;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+// FIXME: Rename to GlobalClassLoader, and "global" for named key
+
+/**
+ * ClassLoader which exposes all {@link ClassSpace}s in the application.
+ *
+ * @since 2.6
+ */
+@Named("nexus-uber")
+@Singleton
+public class NexusUberClassloader
+ extends ClassLoader
+{
+ private final List spaces;
+
+ private final Cache> classLookups = CacheBuilder.newBuilder().weakValues().build();
+
+ @Inject
+ public NexusUberClassloader(final List spaces) {
+ this.spaces = checkNotNull(spaces);
+ }
+
+ @Override
+ public Class> loadClass(String name) throws ClassNotFoundException {
+ return loadClass(name, false);
+ }
+
+ @Override
+ protected Class> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+ try {
+ // cache successful results to save having to find them again
+ return classLookups.get(name, () -> searchSpacesForClass(name));
+ }
+ catch (ExecutionException e) { // NOSONAR: only interested in the cause
+ Throwables.propagateIfPossible(e.getCause(), ClassNotFoundException.class);
+ throw new ClassNotFoundException(name, e.getCause());
+ }
+ }
+
+ @Override
+ public URL getResource(final String name) {
+ for (ClassSpace space : spaces) {
+ URL result = space.getResource(name);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Enumeration getResources(final String name) {
+ List result = Lists.newArrayList();
+ for (ClassSpace space : spaces) {
+ for (Enumeration resources = space.getResources(name); resources.hasMoreElements(); ) {
+ result.add(resources.nextElement());
+ }
+ }
+ return Collections.enumeration(result);
+ }
+
+ private Class> searchSpacesForClass(final String name) throws ClassNotFoundException {
+ for (ClassSpace space : spaces) {
+ try {
+ return space.loadClass(name);
+ }
+ catch (TypeNotPresentException e) {
+ // ignore it
+ }
+ }
+ throw new ClassNotFoundException(name);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/event/DebugEventInspector.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/event/DebugEventInspector.java
new file mode 100644
index 0000000000000000000000000000000000000000..738541012df3512286f67d95f0e5f6529908c7f3
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/event/DebugEventInspector.java
@@ -0,0 +1,87 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.event;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.sonatype.goodies.common.ComponentSupport;
+import org.sonatype.nexus.common.event.EventManager;
+import org.sonatype.nexus.common.property.SystemPropertiesHelper;
+import org.sonatype.nexus.jmx.reflect.ManagedAttribute;
+import org.sonatype.nexus.jmx.reflect.ManagedObject;
+
+import com.google.common.eventbus.AllowConcurrentEvents;
+import com.google.common.eventbus.Subscribe;
+import org.eclipse.sisu.EagerSingleton;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * A simple "debug" helper component, that dumps out events to log.
+ *
+ * Usable for debugging or problem solving, not for production use!
+ *
+ * It will register itself to listen for events only when enabled,
+ * otherwise it will not spend any CPU cycles being dormant.
+ *
+ * It can be enabled via System property or JMX.
+ *
+ * @author cstamas
+ * @since 2.1
+ */
+@Named
+@EagerSingleton
+@ManagedObject
+public class DebugEventInspector
+ extends ComponentSupport
+{
+ private static final boolean ENABLED_DEFAULT = SystemPropertiesHelper.getBoolean(
+ DebugEventInspector.class.getName() + ".enabled", false);
+
+ private volatile boolean enabled;
+
+ private final EventManager eventManager;
+
+ @Inject
+ public DebugEventInspector(final EventManager eventManager) {
+ this.eventManager = checkNotNull(eventManager);
+ setEnabled(ENABLED_DEFAULT);
+ }
+
+ @ManagedAttribute
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ @ManagedAttribute
+ public void setEnabled(boolean enabled) {
+ try {
+ if (enabled && !this.enabled) {
+ eventManager.register(this);
+ }
+ else if (!enabled && this.enabled) {
+ eventManager.unregister(this);
+ }
+ }
+ finally {
+ this.enabled = enabled;
+ }
+ }
+
+ @Subscribe
+ @AllowConcurrentEvents
+ public void accept(final Object event) {
+ log.info("{}", event);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/event/EventExecutor.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/event/EventExecutor.java
new file mode 100644
index 0000000000000000000000000000000000000000..41211570e4d7beb5b94685d97231db6c67cc516e
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/event/EventExecutor.java
@@ -0,0 +1,146 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.event;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.sonatype.goodies.lifecycle.LifecycleSupport;
+import org.sonatype.nexus.common.app.ManagedLifecycle;
+import org.sonatype.nexus.common.event.EventAware.Asynchronous;
+import org.sonatype.nexus.thread.NexusExecutorService;
+import org.sonatype.nexus.thread.NexusThreadFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import static org.sonatype.nexus.common.app.ManagedLifecycle.Phase.TASKS;
+import static org.sonatype.nexus.common.event.EventHelper.asReplicating;
+import static org.sonatype.nexus.common.event.EventHelper.isReplicating;
+import static org.sonatype.nexus.internal.event.EventManagerImpl.HOST_THREAD_POOL_SIZE;
+
+/**
+ * Custom {@link Executor} used to dispatch events to {@link Asynchronous} subscribers.
+ *
+ * As Nexus starts, subscribers are called directly by the originating thread. Once the
+ * TASKS phase is reached subscribers will be called asynchronously using a thread pool.
+ *
+ * Conversely as Nexus stops, the thread pool is shutdown after leaving the TASKS phase
+ * and subscribers will again be called directly by the originating thread. This avoids
+ * asynchronous subscribers from having services disappear beneath them.
+ *
+ * @since 3.2
+ */
+@Named
+@ManagedLifecycle(phase = TASKS)
+@Singleton
+class EventExecutor
+ extends LifecycleSupport
+ implements Executor
+{
+ private volatile Executor delegate;
+
+ public EventExecutor() {
+ // single-threaded until we reach TASKS phase
+ this.delegate = MoreExecutors.directExecutor();
+ }
+
+ /**
+ * Move from direct to asynchronous subscriber processing.
+ */
+ @Override
+ protected void doStart() throws Exception {
+ // direct hand-off used! Host pool will use caller thread to execute async subscribers when pool full!
+ ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
+ 0,
+ HOST_THREAD_POOL_SIZE,
+ 60L,
+ TimeUnit.SECONDS,
+ new SynchronousQueue<>(),
+ new NexusThreadFactory("event", "event-manager"),
+ new CallerRunsPolicy()
+ );
+
+ // begin distributing events in truly asynchronous fashion
+ delegate = NexusExecutorService.forCurrentSubject(threadPool);
+ }
+
+ /**
+ * Move from asynchronous to direct subscriber processing.
+ */
+ @Override
+ protected void doStop() throws Exception {
+ Executor currentExecutor = delegate;
+
+ if (currentExecutor instanceof NexusExecutorService) {
+ // go back to single-threaded for rest of shutdown
+ delegate = MoreExecutors.directExecutor();
+
+ // wait for all background event subscribers to finish to have consistent state
+ ((NexusExecutorService) currentExecutor).shutdown();
+ try {
+ ((NexusExecutorService) currentExecutor).awaitTermination(5L, TimeUnit.SECONDS);
+ }
+ catch (InterruptedException e) {
+ log.debug("Interrupted while waiting for termination", e);
+ }
+ }
+ }
+
+ /**
+ * Used by UTs and ITs only, to "wait for calm period", when all the async event subscribers finished.
+ */
+ @VisibleForTesting
+ boolean isCalmPeriod() {
+ Executor currentExecutor = delegate;
+
+ if (currentExecutor instanceof NexusExecutorService) {
+ ThreadPoolExecutor threadPool = (ThreadPoolExecutor)
+ ((NexusExecutorService) currentExecutor).getTargetExecutorService();
+
+ // "calm period" is when we have no queued nor active threads
+ return threadPool.getQueue().isEmpty() && threadPool.getActiveCount() == 0;
+ }
+
+ return true; // single-threaded mode
+ }
+
+ @Override
+ public void execute(final Runnable command) {
+ delegate.execute(inheritIsReplicating(command));
+ }
+
+ /**
+ * Binds current "isReplicating" context to the {@link Runnable} regardless which thread executes it.
+ */
+ private static Runnable inheritIsReplicating(final Runnable command) {
+ if (!isReplicating()) {
+ return command; // no need to inherit flag
+ }
+ return () -> {
+ // check state from context of thread doing the running
+ if (!isReplicating()) {
+ asReplicating(command); // set flag for duration of command
+ }
+ else {
+ command.run(); // flag already set, maintain it
+ }
+ };
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/event/EventManagerImpl.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/event/EventManagerImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..4fdf94c86e675b802dfc417aebf66a2f86922ed4
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/event/EventManagerImpl.java
@@ -0,0 +1,136 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.event;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.sonatype.goodies.lifecycle.LifecycleSupport;
+import org.sonatype.nexus.common.app.ManagedLifecycle;
+import org.sonatype.nexus.common.event.EventAware;
+import org.sonatype.nexus.common.event.EventAware.Asynchronous;
+import org.sonatype.nexus.common.event.EventManager;
+import org.sonatype.nexus.common.property.SystemPropertiesHelper;
+import org.sonatype.nexus.jmx.reflect.ManagedAttribute;
+import org.sonatype.nexus.jmx.reflect.ManagedObject;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.eventbus.EventBus;
+import com.google.inject.Key;
+import org.eclipse.sisu.BeanEntry;
+import org.eclipse.sisu.Mediator;
+import org.eclipse.sisu.inject.BeanLocator;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.sonatype.nexus.common.app.ManagedLifecycle.Phase.EVENTS;
+import static org.sonatype.nexus.common.event.EventBusFactory.reentrantAsyncEventBus;
+import static org.sonatype.nexus.common.event.EventBusFactory.reentrantEventBus;
+
+/**
+ * Default {@link EventManager}.
+ */
+@Named
+@ManagedLifecycle(phase = EVENTS)
+@ManagedObject(typeClass=EventManager.class)
+@Singleton
+public class EventManagerImpl
+ extends LifecycleSupport
+ implements EventManager
+{
+ static final int HOST_THREAD_POOL_SIZE = SystemPropertiesHelper.getInteger(
+ EventManagerImpl.class.getName() + ".poolSize", 500);
+
+ private final BeanLocator beanLocator;
+
+ private final EventExecutor eventExecutor;
+
+ private final EventBus eventBus;
+
+ private final EventBus asyncBus;
+
+ @Inject
+ public EventManagerImpl(final BeanLocator beanLocator, final EventExecutor eventExecutor)
+ {
+ this.beanLocator = checkNotNull(beanLocator);
+ this.eventExecutor = checkNotNull(eventExecutor);
+
+ this.eventBus = reentrantEventBus("nexus");
+ this.asyncBus = reentrantAsyncEventBus("nexus.async", eventExecutor);
+ }
+
+ /**
+ * Mediator to register and unregister {@link EventAware} components.
+ */
+ private static class EventAwareMediator
+ implements Mediator
+ {
+ @Override
+ public void add(final BeanEntry entry, final EventManagerImpl watcher) {
+ watcher.register(entry.getValue());
+ }
+
+ @Override
+ public void remove(final BeanEntry entry, final EventManagerImpl watcher) {
+ watcher.unregister(entry.getValue());
+ }
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ // watch for EventSubscriber components and register/unregister them
+ beanLocator.watch(Key.get(EventAware.class, Named.class), new EventAwareMediator(), this);
+ }
+
+ @Override
+ public void register(final Object object) {
+ boolean async = object instanceof Asynchronous;
+
+ if (async) {
+ asyncBus.register(object);
+ }
+ else {
+ eventBus.register(object);
+ }
+
+ log.trace("Registered {}{}", async ? "ASYNC " : "", object);
+ }
+
+ @Override
+ public void unregister(final Object object) {
+ boolean async = object instanceof Asynchronous;
+
+ if (async) {
+ asyncBus.unregister(object);
+ }
+ else {
+ eventBus.unregister(object);
+ }
+
+ log.trace("Unregistered {}{}", async ? "ASYNC " : "", object);
+ }
+
+ @Override
+ public void post(final Object event) {
+ // notify synchronous subscribers before going asynchronous
+ eventBus.post(event);
+ asyncBus.post(event);
+ }
+
+ @Override
+ @VisibleForTesting
+ @ManagedAttribute
+ public boolean isCalmPeriod() {
+ return eventExecutor.isCalmPeriod();
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogConfigurationCustomizerImpl.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogConfigurationCustomizerImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..cbd529cd651559b3cd0490deff7f83fdb7b4f30c
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogConfigurationCustomizerImpl.java
@@ -0,0 +1,53 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.log;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.sonatype.nexus.common.log.LogConfigurationCustomizer;
+import org.sonatype.nexus.common.log.LoggerLevel;
+
+/**
+ * Configures core Nexus loggers.
+ *
+ * @since 2.7
+ */
+@Named
+@Singleton
+public class LogConfigurationCustomizerImpl
+ implements LogConfigurationCustomizer
+{
+ @Override
+ public void customize(final Configuration configuration) {
+ // non Nexus loggers
+ configuration.setLoggerLevel("org.apache.commons", LoggerLevel.WARN);
+
+ configuration.setLoggerLevel("org.eclipse.jetty", LoggerLevel.INFO);
+ configuration.setLoggerLevel("eu.medsea.mimeutil.MimeUtil2", LoggerLevel.INFO);
+
+ // NEXUS-5456: limit noisy guice timing logger
+ configuration.setLoggerLevel("com.google.inject.internal.util.Stopwatch", LoggerLevel.INFO);
+
+ // NEXUS-5835: limit noisy jmx connections to Nexus when root.level is DEBUG
+ configuration.setLoggerLevel("javax.management", LoggerLevel.INFO);
+ configuration.setLoggerLevel("sun.rmi", LoggerLevel.INFO);
+
+ // Useful loggers (level will be calculated as effective level)
+ configuration.setLoggerLevel("org.sonatype.nexus", LoggerLevel.DEFAULT);
+
+ configuration.setLoggerLevel("org.sonatype.nexus.jmx", LoggerLevel.DEFAULT);
+ configuration.setLoggerLevel("org.sonatype.nexus.internal.log", LoggerLevel.DEFAULT);
+ configuration.setLoggerLevel("org.sonatype.nexus.plugins", LoggerLevel.DEFAULT);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogMarkerImpl.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogMarkerImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..87ebfafee149e99dae9ed5ce7506f611660c9345
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogMarkerImpl.java
@@ -0,0 +1,64 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.log;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.sonatype.goodies.common.ComponentSupport;
+import org.sonatype.nexus.common.event.EventManager;
+import org.sonatype.nexus.common.log.LogManager;
+import org.sonatype.nexus.common.log.LogMarkInsertedEvent;
+import org.sonatype.nexus.common.log.LogMarker;
+import org.sonatype.nexus.common.log.LoggerLevel;
+
+import com.google.common.base.Strings;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Default implementation of {@link LogMarker}.
+ *
+ * @since 3.1
+ */
+@Named
+@Singleton
+public class LogMarkerImpl
+ extends ComponentSupport
+ implements LogMarker
+{
+ private final LogManager logManager;
+
+ private final EventManager eventManager;
+
+ @Inject
+ public LogMarkerImpl(final LogManager logManager, final EventManager eventManager) {
+ this.logManager = checkNotNull(logManager);
+ this.eventManager = checkNotNull(eventManager);
+ }
+
+ @Override
+ public void markLog(final String message) {
+ // ensure that level for marking logger is enabled
+ LoggerLevel loggerLevel = logManager.getLoggerEffectiveLevel(log.getName());
+ if (LoggerLevel.INFO.compareTo(loggerLevel) < 0) {
+ logManager.setLoggerLevel(log.getName(), LoggerLevel.INFO);
+ }
+
+ String asterixes = Strings.repeat("*", message.length() + 4);
+ log.info("\n{}\n* {} *\n{}", asterixes, message, asterixes);
+
+ eventManager.post(new LogMarkInsertedEvent(message));
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogbackLevels.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogbackLevels.java
new file mode 100644
index 0000000000000000000000000000000000000000..7277410d30b157d6e0deadbdd3ebdff2f2952ff3
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogbackLevels.java
@@ -0,0 +1,62 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.log;
+
+import org.sonatype.nexus.common.log.LoggerLevel;
+
+import ch.qos.logback.classic.Level;
+
+/**
+ * Logback levels helper.
+ *
+ * @since 3.0
+ */
+class LogbackLevels
+{
+ private LogbackLevels() {
+ // empty
+ }
+
+ /**
+ * Convert a Logback {@link Level} into a {@link LoggerLevel}.
+ */
+ public static LoggerLevel convert(final Level level) {
+ switch (level.toInt()) {
+ case Level.ERROR_INT:
+ return LoggerLevel.ERROR;
+
+ case Level.WARN_INT:
+ return LoggerLevel.WARN;
+
+ case Level.INFO_INT:
+ return LoggerLevel.INFO;
+
+ case Level.DEBUG_INT:
+ return LoggerLevel.DEBUG;
+
+ case Level.OFF_INT:
+ return LoggerLevel.OFF;
+
+ case Level.TRACE_INT:
+ default:
+ return LoggerLevel.TRACE;
+ }
+ }
+
+ /**
+ * Convert a {@link LoggerLevel} into a Logback {@link Level}.
+ */
+ public static Level convert(final LoggerLevel level) {
+ return Level.valueOf(level.name());
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogbackLogManager.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogbackLogManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..abcef42ab7ba44bd602340f6f2893501266fd046
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogbackLogManager.java
@@ -0,0 +1,434 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.log;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.sonatype.nexus.common.app.ManagedLifecycle;
+import org.sonatype.nexus.common.event.EventManager;
+import org.sonatype.nexus.common.log.LogConfigurationCustomizer;
+import org.sonatype.nexus.common.log.LogManager;
+import org.sonatype.nexus.common.log.LoggerLevel;
+import org.sonatype.nexus.common.log.LoggerLevelChangedEvent;
+import org.sonatype.nexus.common.log.LoggersResetEvent;
+import org.sonatype.nexus.common.stateguard.Guarded;
+import org.sonatype.nexus.common.stateguard.StateGuardLifecycleSupport;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.FileAppender;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.io.ByteStreams;
+import com.google.inject.Key;
+import org.eclipse.sisu.BeanEntry;
+import org.eclipse.sisu.Mediator;
+import org.eclipse.sisu.inject.BeanLocator;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.impl.StaticLoggerBinder;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.sonatype.nexus.common.app.ManagedLifecycle.Phase.KERNEL;
+import static org.sonatype.nexus.common.stateguard.StateGuardLifecycleSupport.State.STARTED;
+
+/**
+ * Logback {@link LogManager}.
+ */
+@Named
+@ManagedLifecycle(phase = KERNEL)
+@Singleton
+public class LogbackLogManager
+ extends StateGuardLifecycleSupport
+ implements LogManager
+{
+ private final EventManager eventManager;
+
+ private final BeanLocator beanLocator;
+
+ private final Map customizations;
+
+ private final LoggerOverrides overrides;
+
+ @Inject
+ public LogbackLogManager(final EventManager eventManager,
+ final BeanLocator beanLocator,
+ final LoggerOverrides overrides)
+ {
+ this.eventManager = checkNotNull(eventManager);
+ this.beanLocator = checkNotNull(beanLocator);
+ this.overrides = checkNotNull(overrides);
+ this.customizations = new HashMap<>();
+ }
+
+ /**
+ * Mediator to register customizers.
+ */
+ private static class CustomizerMediator
+ implements Mediator
+ {
+ @Override
+ public void add(final BeanEntry entry, final LogbackLogManager watcher) {
+ watcher.registerCustomization(entry.getValue());
+ }
+
+ @Override
+ public void remove(final BeanEntry entry, final LogbackLogManager watcher) {
+ // ignore
+ }
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ configure();
+
+ // watch for LogConfigurationCustomizer components
+ beanLocator.watch(Key.get(LogConfigurationCustomizer.class, Named.class), new CustomizerMediator(), this);
+ }
+
+ private void configure() {
+ log.info("Configuring");
+
+ // sanity clear customizations
+ customizations.clear();
+
+ // load and apply overrides
+ overrides.load();
+ for (Entry entry : overrides) {
+ setLogbackLoggerLevel(entry.getKey(), LogbackLevels.convert(entry.getValue()));
+ }
+ }
+
+ @Override
+ protected void doStop() throws Exception {
+ // inform logback to shutdown
+ loggerContext().stop();
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public Set getLogFiles() {
+ HashSet files = new HashSet<>();
+
+ for (Appender> appender : appenders()) {
+ if (appender instanceof FileAppender) {
+ String path = ((FileAppender>) appender).getFile();
+ files.add(new File(path));
+ }
+ }
+
+ return files;
+ }
+
+ @Override
+ @Nullable
+ @Guarded(by = STARTED)
+ public File getLogFile(final String fileName) {
+ Set files = getLogFiles();
+ for (File file : files) {
+ if (file.getName().equals(fileName)) {
+ return file;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ @Nullable
+ @Guarded(by = STARTED)
+ public InputStream getLogFileStream(final String fileName, final long from, final long count) throws IOException {
+ log.debug("Retrieving log file: {}", fileName);
+
+ // checking for platform or normalized path-separator (on unix these are the same)
+ if (fileName.contains(File.pathSeparator) || fileName.contains("/")) {
+ log.warn("Cannot retrieve log files with path separators in their name");
+ return null;
+ }
+
+ File file = getLogFile(fileName);
+ if (file == null || !file.exists()) {
+ log.warn("Log file does not exist: {}", fileName);
+ return null;
+ }
+
+ long fromByte = from;
+ long bytesCount = count;
+ if (count < 0) {
+ bytesCount = Math.abs(count);
+ fromByte = Math.max(0, file.length() - bytesCount);
+ }
+
+ InputStream input = new BufferedInputStream(new FileInputStream(file));
+ if (fromByte == 0 && bytesCount >= file.length()) {
+ return input;
+ }
+ else {
+ input.skip(fromByte);
+ return ByteStreams.limit(input, bytesCount);
+ }
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public Map getLoggers() {
+ Map loggers = new HashMap<>();
+
+ // add all loggers which are defined in context which have a level (ie. not inheriting from parent)
+ LoggerContext ctx = loggerContext();
+ for (ch.qos.logback.classic.Logger logger : ctx.getLoggerList()) {
+ String name = logger.getName();
+ Level level = logger.getLevel();
+ // only include loggers which explicit levels configured
+ if (level != null) {
+ loggers.put(name, LogbackLevels.convert(level));
+ }
+ }
+
+ // add all customized loggers
+ for (Entry entry : customizations.entrySet()) {
+ String name = entry.getKey();
+ LoggerLevel level = entry.getValue();
+
+ // skip if there is already a logger with a set level in context
+ if (!loggers.containsKey(name)) {
+ // resolve effective level of logger
+ if (LoggerLevel.DEFAULT == level) {
+ level = getLoggerEffectiveLevel(entry.getKey());
+ }
+ loggers.put(name, level);
+ }
+ }
+
+ return loggers;
+ }
+
+ /**
+ * @since 3.2
+ */
+ @Override
+ @Guarded(by = STARTED)
+ public Map getOverriddenLoggers() {
+ Map loggers = new HashMap<>();
+ overrides.forEach(override -> loggers.put(override.getKey(), override.getValue()));
+ return loggers;
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public void resetLoggers() {
+ log.debug("Resetting loggers");
+
+ // reset all overridden logger levels to null (inherit from parent)
+ for (Map.Entry entry : overrides) {
+ if (!Logger.ROOT_LOGGER_NAME.equals(entry.getKey())) {
+ setLogbackLoggerLevel(entry.getKey(), null);
+ }
+ }
+
+ // clear overrides cache and update persistence
+ overrides.reset();
+
+ // reset root level to default
+ setLoggerLevel(Logger.ROOT_LOGGER_NAME, LoggerLevel.DEFAULT);
+
+ // re-apply customizations
+ applyCustomizations();
+
+ eventManager.post(new LoggersResetEvent());
+
+ log.debug("Loggers reset to default levels");
+ }
+
+ //
+ // Logger levels
+ //
+
+ @Override
+ @Guarded(by = STARTED)
+ public void setLoggerLevel(final String name, @Nullable final LoggerLevel level) {
+ if (level == null) {
+ unsetLoggerLevel(name);
+ return;
+ }
+
+ log.debug("Set logger level: {}={}", name, level);
+ LoggerLevel calculated = null;
+
+ if (Logger.ROOT_LOGGER_NAME.equals(name)) {
+ calculated = (level == LoggerLevel.DEFAULT ? LoggerLevel.INFO : level);
+ overrides.set(name, calculated);
+ }
+ else {
+ // else we customize the logger overrides configuration
+ if (level == LoggerLevel.DEFAULT) {
+ boolean customizedByUser = overrides.contains(name) && !customizations.containsKey(name);
+ unsetLoggerLevel(name);
+ if (customizedByUser) {
+ overrides.set(name, calculated = getLoggerEffectiveLevel(name));
+ }
+ else {
+ LoggerLevel customizedLevel = customizations.get(name);
+ if (customizedLevel != null && customizedLevel != LoggerLevel.DEFAULT) {
+ calculated = customizedLevel;
+ }
+ }
+ }
+ else {
+ overrides.set(name, calculated = level);
+ }
+ }
+
+ // update override persistence
+ overrides.save();
+
+ if (calculated != null) {
+ setLogbackLoggerLevel(name, LogbackLevels.convert(calculated));
+ }
+
+ eventManager.post(new LoggerLevelChangedEvent(name, level));
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public void unsetLoggerLevel(final String name) {
+ log.debug("Unset logger level: {}", name);
+
+ if (overrides.remove(name) != null) {
+ overrides.save();
+ }
+
+ if (Logger.ROOT_LOGGER_NAME.equals(name)) {
+ setLogbackLoggerLevel(name, Level.INFO);
+ }
+ else {
+ setLogbackLoggerLevel(name, null);
+ }
+
+ eventManager.post(new LoggerLevelChangedEvent(name, null));
+ }
+
+ @Override
+ @Nullable
+ @Guarded(by = STARTED)
+ public LoggerLevel getLoggerLevel(final String name) {
+ Level level = loggerContext().getLogger(name).getLevel();
+ if (level != null) {
+ return LogbackLevels.convert(level);
+ }
+ return null;
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public LoggerLevel getLoggerEffectiveLevel(final String name) {
+ Level level = loggerContext().getLogger(name).getEffectiveLevel();
+ return LogbackLevels.convert(level);
+ }
+
+ /**
+ * Helper to set a named logback logger level.
+ */
+ private void setLogbackLoggerLevel(final String name, @Nullable final Level level) {
+ log.trace("Set logback logger level: {}={}", name, level);
+ loggerContext().getLogger(name).setLevel(level);
+ }
+
+ //
+ // Customizations
+ //
+
+ /**
+ * Register and apply customizations.
+ */
+ @VisibleForTesting
+ void registerCustomization(final LogConfigurationCustomizer customizer) {
+ log.debug("Registering customizations: {}", customizer);
+
+ customizer.customize((name, level) -> {
+ checkNotNull(name);
+ checkNotNull(level);
+ customizations.put(name, level);
+
+ // only apply customization if there is not an override, and the level is not DEFAULT
+ if (!overrides.contains(name) && level != LoggerLevel.DEFAULT) {
+ setLogbackLoggerLevel(name, LogbackLevels.convert(level));
+ }
+ });
+ }
+
+ /**
+ * Apply all registered customizations.
+ */
+ private void applyCustomizations() {
+ log.debug("Applying customizations");
+
+ for (Entry entry : customizations.entrySet()) {
+ if (entry.getValue() != LoggerLevel.DEFAULT) {
+ setLogbackLoggerLevel(entry.getKey(), LogbackLevels.convert(entry.getValue()));
+ }
+ }
+ }
+
+ //
+ // Helpers
+ //
+
+ /**
+ * Returns the current logger-context.
+ */
+ @VisibleForTesting
+ static LoggerContext loggerContext() {
+ ILoggerFactory factory = LoggerFactory.getILoggerFactory();
+ if (factory instanceof LoggerContext) {
+ return (LoggerContext) factory;
+ }
+ // Pax-Logging registers a custom implementation of ILoggerFactory which hides logback; as a workaround
+ // we set org.ops4j.pax.logging.StaticLogbackContext=true in system.properties and access it statically
+ return (LoggerContext) StaticLoggerBinder.getSingleton().getLoggerFactory();
+ }
+
+ /**
+ * Returns all configured appenders.
+ */
+ private static Collection> appenders() {
+ List> result = new ArrayList<>();
+ for (Logger l : loggerContext().getLoggerList()) {
+ ch.qos.logback.classic.Logger log = (ch.qos.logback.classic.Logger) l;
+ Iterator> iter = log.iteratorForAppenders();
+ while (iter.hasNext()) {
+ result.add(iter.next());
+ }
+ }
+ return result;
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogbackLoggerOverrides.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogbackLoggerOverrides.java
new file mode 100644
index 0000000000000000000000000000000000000000..692b75693a6a54287da8ec627e0a7ce4a525d2a1
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LogbackLoggerOverrides.java
@@ -0,0 +1,216 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.log;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.sonatype.goodies.common.ComponentSupport;
+import org.sonatype.goodies.common.FileReplacer;
+import org.sonatype.nexus.common.app.ApplicationDirectories;
+import org.sonatype.nexus.common.log.LoggerLevel;
+
+import ch.qos.logback.classic.Logger;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Logback {@link LoggerOverrides} implementation.
+ *
+ * Special handling for {@code ROOT} logger, which is persisted as {@code root.level} property.
+ *
+ * @since 2.7
+ */
+@Named
+@Singleton
+public class LogbackLoggerOverrides
+ extends ComponentSupport
+ implements LoggerOverrides
+{
+ private final File file;
+
+ private final Map loggerLevels = new HashMap<>();
+
+ @Inject
+ public LogbackLoggerOverrides(final ApplicationDirectories applicationDirectories) {
+ checkNotNull(applicationDirectories);
+ this.file = new File(applicationDirectories.getWorkDirectory("etc/logback"), "logback-overrides.xml");
+ log.info("File: {}", file);
+ }
+
+ @VisibleForTesting
+ LogbackLoggerOverrides(final File file) {
+ this.file = checkNotNull(file);
+ }
+
+ @Override
+ public synchronized void load() {
+ log.debug("Load");
+
+ loggerLevels.clear();
+ if (file.exists()) {
+ try {
+ loggerLevels.putAll(read(file));
+ }
+ catch (Exception e) {
+ Throwables.throwIfUnchecked(e);
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public synchronized void save() {
+ log.debug("Save");
+
+ try {
+ write(file, loggerLevels);
+ }
+ catch (Exception e) {
+ Throwables.throwIfUnchecked(e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public synchronized void reset() {
+ log.debug("Reset");
+
+ loggerLevels.clear();
+ try {
+ write(file, loggerLevels);
+ }
+ catch (Exception e) {
+ Throwables.throwIfUnchecked(e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public synchronized void set(final String name, final LoggerLevel level) {
+ log.debug("Set: {}={}", name, level);
+
+ loggerLevels.put(name, level);
+ }
+
+ @Override
+ @Nullable
+ public synchronized LoggerLevel get(final String name) {
+ return loggerLevels.get(name);
+ }
+
+ @Override
+ @Nullable
+ public synchronized LoggerLevel remove(final String name) {
+ log.debug("Remove: {}", name);
+
+ return loggerLevels.remove(name);
+ }
+
+ @Override
+ public synchronized boolean contains(final String name) {
+ return loggerLevels.containsKey(name);
+ }
+
+ @Override
+ public synchronized Iterator> iterator() {
+ return ImmutableMap.copyOf(loggerLevels).entrySet().iterator();
+ }
+
+ //
+ // Logback xml-format I/O
+ //
+
+ /**
+ * Read logger levels from logback.xml formatted include file.
+ */
+ private Map read(final File inputFile) throws Exception {
+ final Map result = Maps.newHashMap();
+
+ SAXParserFactory parserFactory = SAXParserFactory.newInstance();
+ parserFactory.setValidating(false);
+ parserFactory.setNamespaceAware(true);
+ parserFactory.newSAXParser().parse(inputFile, new DefaultHandler()
+ {
+ @Override
+ public void startElement(final String uri,
+ final String localName,
+ final String qName,
+ final Attributes attributes) throws SAXException
+ {
+ // NOTE: ATM we are ignoring 'property' elements, this is needed for root, but is only needed
+ // NOTE: to persist as a property for use in top-level logback.xml file
+
+ if ("logger".equals(localName)) {
+ String name = attributes.getValue("name");
+ String level = attributes.getValue("level");
+ result.put(name, LoggerLevel.valueOf(level));
+ }
+ }
+ });
+ return result;
+ }
+
+ /**
+ * Write logger levels and root property to logback.xml formatted include file.
+ */
+ private void write(final File outputFile, final Map overrides) throws Exception {
+ final FileReplacer fileReplacer = new FileReplacer(outputFile);
+ fileReplacer.setDeleteBackupFile(true);
+ fileReplacer.replace(output -> {
+ try (final BufferedWriter out = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8))) {
+ out.write("");
+ out.newLine();
+ out.newLine();
+ out.write("");
+ out.newLine();
+ out.newLine();
+ out.write("");
+ out.newLine();
+ for (Entry entry : overrides.entrySet()) {
+ if (Logger.ROOT_LOGGER_NAME.equals(entry.getKey())) {
+ out.write(String.format(" %n", entry.getValue()));
+ }
+ else {
+ out.write(String.format(" %n", entry.getKey(), entry.getValue()));
+ }
+ }
+ out.write("");
+ out.newLine();
+ }
+ });
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggerAction.groovy b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggerAction.groovy
new file mode 100644
index 0000000000000000000000000000000000000000..4c6b04afe9afddecbc86fc02f22aaae43aeac10e
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggerAction.groovy
@@ -0,0 +1,82 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.log
+
+import javax.inject.Inject
+import javax.inject.Named
+
+import org.sonatype.nexus.common.log.LogManager
+import org.sonatype.nexus.common.log.LoggerLevel
+
+import org.apache.karaf.shell.api.action.Action
+import org.apache.karaf.shell.api.action.Argument
+import org.apache.karaf.shell.api.action.Command
+import org.apache.karaf.shell.api.action.Completion
+import org.apache.karaf.shell.api.action.Option
+
+/**
+ * Action to set or display logger level.
+ *
+ * @since 3.0
+ */
+@Named
+@Command(name='logger', scope = 'nexus', description = 'Set or display logger level')
+class LoggerAction
+ implements Action
+{
+ @Inject
+ LogManager logManager
+
+ @Option(name='-d', aliases = ['--delete'], description = 'Delete logger')
+ Boolean delete
+
+ @Option(name='-e', aliases = ['--effective'], description = 'Return effective logger level')
+ Boolean effective
+
+ // FIXME: Presently a strict flag is set on some Karaf stuff related to completion, and
+ // FIXME: ... unless you use the logger-name completer, then the level completion will not get picked up
+ // FIXME: ... unsure where, but looks like if a completer fails, all completers after it are ignored
+
+ @Argument(name="name", index = 0, required = true, description = 'Logger name')
+ @Completion(LoggerNameCompleter)
+ String name
+
+ @Argument(name="level", index = 1, description = 'Logger level')
+ LoggerLevel level
+
+ @Override
+ public Object execute() throws Exception {
+ if (delete) {
+ logManager.unsetLoggerLevel(name)
+ }
+ else if (level) {
+ logManager.setLoggerLevel(name, level)
+ }
+ else {
+ if (effective) {
+ level = logManager.getLoggerEffectiveLevel(name)
+ }
+ else {
+ level = logManager.getLoggerLevel(name)
+ }
+
+ if (level) {
+ println "$name = $level"
+ }
+ else {
+ println "$name is not set"
+ }
+ }
+ return null
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggerNameCompleter.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggerNameCompleter.java
new file mode 100644
index 0000000000000000000000000000000000000000..831de81af3c97f9464393029774b713431c0b529
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggerNameCompleter.java
@@ -0,0 +1,49 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.log;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.sonatype.nexus.common.log.LogManager;
+
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Logger name completer.
+ *
+ * @since 3.0
+ */
+@Named
+public class LoggerNameCompleter
+ implements Completer
+{
+ private final LogManager logManager;
+
+ @Inject
+ public LoggerNameCompleter(final LogManager logManager) {
+ this.logManager = checkNotNull(logManager);
+ }
+
+ @Override
+ public int complete(final Session session, final CommandLine commandLine, final List candidates) {
+ return new StringsCompleter(logManager.getLoggers().keySet()).complete(session, commandLine, candidates);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggerOverrides.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggerOverrides.java
new file mode 100644
index 0000000000000000000000000000000000000000..152350d3f0fc2e3ed4707177e028fbbeacdbec53
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggerOverrides.java
@@ -0,0 +1,65 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.log;
+
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+import org.sonatype.nexus.common.log.LoggerLevel;
+
+/**
+ * Manages user-configured logger overrides.
+ *
+ * @since 3.0
+ */
+public interface LoggerOverrides
+ extends Iterable>
+{
+ /**
+ * Load overrides configuration from storage.
+ */
+ void load();
+
+ /**
+ * Save current overrides configuration to storage.
+ */
+ void save();
+
+ /**
+ * Reset overrides configuration to default state.
+ */
+ void reset();
+
+ /**
+ * Set a logger level override.
+ */
+ void set(String name, LoggerLevel level);
+
+ /**
+ * Get the level of an overridden logger.
+ */
+ @Nullable
+ LoggerLevel get(final String name);
+
+ /**
+ * Remove override configuration for a logger.
+ */
+ @Nullable
+ LoggerLevel remove(final String name);
+
+ /**
+ * Check if a logger has been overridden.
+ */
+ boolean contains(final String name);
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggersAction.groovy b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggersAction.groovy
new file mode 100644
index 0000000000000000000000000000000000000000..e0b4dce64068ad2aac297559fb18d42d8d47f5e3
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggersAction.groovy
@@ -0,0 +1,60 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.log
+
+import javax.inject.Inject
+import javax.inject.Named
+
+import org.sonatype.nexus.common.log.LogManager
+
+import org.apache.karaf.shell.api.action.Action
+import org.apache.karaf.shell.api.action.Command
+import org.apache.karaf.shell.api.action.Option
+import org.apache.karaf.shell.support.table.ShellTable
+
+/**
+ * Action to display configured loggers.
+ *
+ * @since 3.0
+ */
+@Named
+@Command(name='loggers', scope = 'nexus', description = 'Display loggers')
+class LoggersAction
+ implements Action
+{
+ @Inject
+ LogManager logManager
+
+ @Option(name='-r', aliases = ['--reset'], description = 'Reset loggers')
+ Boolean reset
+
+ @Override
+ public Object execute() throws Exception {
+ if (reset) {
+ logManager.resetLoggers()
+ return null
+ }
+
+ def table = new ShellTable()
+ table.column('Name')
+ table.column('Level').alignRight()
+
+ def loggers = logManager.loggers
+ loggers.keySet().sort().each { name ->
+ table.addRow().addContent(name, loggers[name])
+ }
+
+ table.print System.out
+ return null
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggingSecurityContributor.groovy b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggingSecurityContributor.groovy
new file mode 100644
index 0000000000000000000000000000000000000000..c53d032204b22ea0ba2446757c67380ec0966f49
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/log/LoggingSecurityContributor.groovy
@@ -0,0 +1,76 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.log
+
+import javax.inject.Named
+import javax.inject.Singleton
+
+import org.sonatype.nexus.security.config.CPrivilege
+import org.sonatype.nexus.security.config.MemorySecurityConfiguration
+import org.sonatype.nexus.security.config.SecurityContributor
+
+/**
+ * Logging security configuration.
+ *
+ * @since 3.0
+ */
+@Named
+@Singleton
+class LoggingSecurityContributor
+ implements SecurityContributor
+{
+ @Override
+ MemorySecurityConfiguration getContribution() {
+ return new MemorySecurityConfiguration(
+ privileges: [
+ new CPrivilege(
+ id: 'nx-logging-all',
+ description: 'All permissions for Logging',
+ type: 'application',
+ properties: [
+ domain: 'logging',
+ actions: '*'
+ ]
+ ),
+ new CPrivilege(
+ id: 'nx-logging-read',
+ description: 'Read permission for Logging',
+ type: 'application',
+ properties: [
+ domain: 'logging',
+ actions: 'read'
+ ]
+ ),
+ new CPrivilege(
+ id: 'nx-logging-update',
+ description: 'Update permission for Logging',
+ type: 'application',
+ properties: [
+ domain: 'logging',
+ actions: 'update'
+ ]
+ ),
+ new CPrivilege(
+ id: 'nx-logging-mark',
+ description: 'Mark permission for Logging',
+ type: 'application',
+ properties: [
+ domain: 'logging',
+ actions: 'mark'
+ ]
+ ),
+ ]
+ )
+ }
+}
+
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/DeadlockHealthCheckProvider.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/DeadlockHealthCheckProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e0a74806854724eaf48f44970e2b3cad32cc23c
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/DeadlockHealthCheckProvider.java
@@ -0,0 +1,35 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.metrics;
+
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+import com.codahale.metrics.health.HealthCheck;
+import com.codahale.metrics.health.jvm.ThreadDeadlockHealthCheck;
+
+/**
+ * {@link ThreadDeadlockHealthCheck} provider.
+ *
+ * @since 2.8
+ */
+@Named("deadlocks")
+@Singleton
+public class DeadlockHealthCheckProvider
+ implements Provider
+{
+ public HealthCheck get() {
+ return new ThreadDeadlockHealthCheck();
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/HealthCheckMediator.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/HealthCheckMediator.java
new file mode 100644
index 0000000000000000000000000000000000000000..75d782b821a8d144a27f915b3aceb4b166457f11
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/HealthCheckMediator.java
@@ -0,0 +1,44 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.metrics;
+
+import javax.inject.Named;
+
+import org.sonatype.goodies.common.ComponentSupport;
+
+import com.codahale.metrics.health.HealthCheck;
+import com.codahale.metrics.health.HealthCheckRegistry;
+import org.eclipse.sisu.BeanEntry;
+import org.eclipse.sisu.Mediator;
+
+/**
+ * Manages {@link HealthCheck} registrations via Sisu component mediation.
+ *
+ * @since 2.8
+ */
+@Named
+public class HealthCheckMediator
+ extends ComponentSupport
+ implements Mediator
+{
+ public void add(final BeanEntry entry, final HealthCheckRegistry registry) throws Exception {
+ log.debug("Registering: {}", entry);
+ registry.register(entry.getKey().value(), entry.getValue());
+ }
+
+ public void remove(final BeanEntry entry, final HealthCheckRegistry registry) throws Exception {
+ log.debug("Un-registering: {}", entry);
+ registry.unregister(entry.getKey().value());
+ }
+}
+
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/HealthCheckServlet.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/HealthCheckServlet.java
new file mode 100644
index 0000000000000000000000000000000000000000..89fc2cafb7e782cc48855f3555faeb635c65fecf
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/HealthCheckServlet.java
@@ -0,0 +1,34 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.metrics;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import com.codahale.metrics.health.HealthCheckRegistry;
+
+/**
+ * Customized {@link com.codahale.metrics.servlets.HealthCheckServlet} to support injection.
+ *
+ * @see HealthCheckMediator
+ * @since 3.0
+ */
+@Singleton
+public class HealthCheckServlet
+ extends com.codahale.metrics.servlets.HealthCheckServlet
+{
+ @Inject
+ public HealthCheckServlet(final HealthCheckRegistry registry) {
+ super(registry);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/MetricMediator.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/MetricMediator.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f08af4dd98f938b9290dde9d3122d0ee3a3d710
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/MetricMediator.java
@@ -0,0 +1,43 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.metrics;
+
+import javax.inject.Named;
+
+import org.sonatype.goodies.common.ComponentSupport;
+
+import com.codahale.metrics.Metric;
+import com.codahale.metrics.MetricRegistry;
+import org.eclipse.sisu.BeanEntry;
+import org.eclipse.sisu.Mediator;
+
+/**
+ * Manages {@link Metric} registrations via Sisu component mediation.
+ *
+ * @since 3.6
+ */
+@Named
+public class MetricMediator
+ extends ComponentSupport
+ implements Mediator
+{
+ public void add(final BeanEntry entry, final MetricRegistry registry) throws Exception {
+ log.debug("Registering: {}", entry);
+ registry.register(entry.getKey().value(), entry.getValue());
+ }
+
+ public void remove(final BeanEntry entry, final MetricRegistry registry) throws Exception {
+ log.debug("Un-registering: {}", entry);
+ registry.remove(entry.getKey().value());
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/MetricsModule.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/MetricsModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..6329e2cb0ab2e8b57ba9d2a1e07116ba22196ee9
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/MetricsModule.java
@@ -0,0 +1,100 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.metrics;
+
+import org.sonatype.nexus.security.FilterChainModule;
+import org.sonatype.nexus.security.SecurityFilter;
+import org.sonatype.nexus.security.anonymous.AnonymousFilter;
+import org.sonatype.nexus.security.authc.NexusAuthenticationFilter;
+import org.sonatype.nexus.security.authz.PermissionsFilter;
+
+import com.codahale.metrics.Clock;
+import com.codahale.metrics.servlet.InstrumentedFilter;
+import com.codahale.metrics.servlets.PingServlet;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.inject.AbstractModule;
+import com.google.inject.servlet.ServletModule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Dropwizard Metrics guice configuration.
+ *
+ * Installs servlet endpoints:
+ *
+ *
+ *
/service/metrics/ping
+ *
/service/metrics/threads
+ *
/service/metrics/data
+ *
/service/metrics/healthcheck
+ *
+ *
+ * Protected by {@code nexus:metrics:read} permission.
+ *
+ * @since 2.5
+ */
+public class MetricsModule
+ extends AbstractModule
+{
+ private static final Logger log = LoggerFactory.getLogger(MetricsModule.class);
+
+ private static final String MOUNT_POINT = "/service/metrics";
+
+ @Override
+ protected void configure() {
+ // NOTE: AdminServletModule (metrics-guice integration) generates invalid links, so wire up servlets ourselves
+
+ final Clock clock = Clock.defaultClock();
+ bind(Clock.class).toInstance(clock);
+
+ final JsonFactory jsonFactory = new JsonFactory(new ObjectMapper());
+ bind(JsonFactory.class).toInstance(jsonFactory);
+
+ install(new ServletModule()
+ {
+ @Override
+ protected void configureServlets() {
+ bind(MetricsServlet.class);
+ bind(HealthCheckServlet.class);
+
+ serve(MOUNT_POINT + "/ping").with(new PingServlet());
+ serve(MOUNT_POINT + "/threads").with(new ThreadDumpServlet());
+ serve(MOUNT_POINT + "/data").with(MetricsServlet.class);
+ serve(MOUNT_POINT + "/healthcheck").with(HealthCheckServlet.class);
+
+ // record metrics for all webapp access
+ filter("/*").through(new InstrumentedFilter());
+
+ bind(SecurityFilter.class);
+
+ // configure security
+ filter(MOUNT_POINT + "/*").through(SecurityFilter.class);
+ }
+ });
+
+ // require permission to use endpoints
+ install(new FilterChainModule()
+ {
+ @Override
+ protected void configure() {
+ addFilterChain(MOUNT_POINT + "/**",
+ NexusAuthenticationFilter.NAME,
+ AnonymousFilter.NAME,
+ PermissionsFilter.config("nexus:metrics:read"));
+ }
+ });
+
+ log.info("Metrics support configured");
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/MetricsSecurityContributor.groovy b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/MetricsSecurityContributor.groovy
new file mode 100644
index 0000000000000000000000000000000000000000..30eb16b062a3a32cffd2d5ff9704beb4d462a847
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/MetricsSecurityContributor.groovy
@@ -0,0 +1,49 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.metrics
+
+import javax.inject.Named
+import javax.inject.Singleton
+
+import org.sonatype.nexus.security.config.CPrivilege
+import org.sonatype.nexus.security.config.MemorySecurityConfiguration
+import org.sonatype.nexus.security.config.SecurityContributor
+
+/**
+ * Metrics security configuration.
+ *
+ * @since 3.0
+ */
+@Named
+@Singleton
+class MetricsSecurityContributor
+ implements SecurityContributor
+{
+ @Override
+ MemorySecurityConfiguration getContribution() {
+ return new MemorySecurityConfiguration(
+ privileges: [
+ new CPrivilege(
+ id: 'nx-metrics-all',
+ description: 'All permissions for Metrics',
+ type: 'application',
+ properties: [
+ domain: 'metrics',
+ actions: '*'
+ ]
+ )
+ ]
+ )
+ }
+}
+
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/MetricsServlet.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/MetricsServlet.java
new file mode 100644
index 0000000000000000000000000000000000000000..80008590e02e8c8255b46ee90802213a75e2abf2
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/MetricsServlet.java
@@ -0,0 +1,68 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.metrics;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.codahale.metrics.JvmAttributeGaugeSet;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.jvm.BufferPoolMetricSet;
+import com.codahale.metrics.jvm.FileDescriptorRatioGauge;
+import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
+import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
+import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
+
+import static com.codahale.metrics.MetricRegistry.name;
+import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
+
+/**
+ * Customized {@link com.codahale.metrics.servlets.MetricsServlet} to support injection and download.
+ *
+ * @since 3.0
+ */
+@Singleton
+public class MetricsServlet
+ extends com.codahale.metrics.servlets.MetricsServlet
+{
+ @Inject
+ public MetricsServlet(final MetricRegistry registry) {
+ super(registry);
+
+ // JVM metrics are no longer automatically added in codahale-metrics
+ registry.register(name("jvm", "vm"), new JvmAttributeGaugeSet());
+ registry.register(name("jvm", "memory"), new MemoryUsageGaugeSet());
+ registry.register(name("jvm", "buffers"), new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()));
+ registry.register(name("jvm", "fd_usage"), new FileDescriptorRatioGauge());
+ registry.register(name("jvm", "thread-states"), new ThreadStatesGaugeSet());
+ registry.register(name("jvm", "garbage-collectors"), new GarbageCollectorMetricSet());
+ }
+
+ @Override
+ protected void doGet(final HttpServletRequest req, final HttpServletResponse resp)
+ throws ServletException, IOException
+ {
+ boolean download = Boolean.parseBoolean(req.getParameter("download"));
+ if (download) {
+ resp.addHeader(CONTENT_DISPOSITION, "attachment; filename='metrics.json'");
+ }
+
+ super.doGet(req, resp);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/ThreadDumpServlet.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/ThreadDumpServlet.java
new file mode 100644
index 0000000000000000000000000000000000000000..7dedfb0cc01e8a47168d07ca896e598840d55191
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/metrics/ThreadDumpServlet.java
@@ -0,0 +1,42 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.metrics;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import static com.google.common.net.HttpHeaders.CONTENT_DISPOSITION;
+
+/**
+ * Customized {@link com.codahale.metrics.servlets.ThreadDumpServlet} to support download.
+ *
+ * @since 3.0
+ */
+public class ThreadDumpServlet
+ extends com.codahale.metrics.servlets.ThreadDumpServlet
+{
+ @Override
+ protected void doGet(final HttpServletRequest req, final HttpServletResponse resp)
+ throws ServletException, IOException
+ {
+ boolean download = Boolean.parseBoolean(req.getParameter("download"));
+ if (download) {
+ resp.addHeader(CONTENT_DISPOSITION, "attachment; filename='threads.txt'");
+ }
+
+ super.doGet(req, resp);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/FileKeyStoreStorage.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/FileKeyStoreStorage.java
new file mode 100644
index 0000000000000000000000000000000000000000..256229d18e2a79d6ac42735c477064491fe45276
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/FileKeyStoreStorage.java
@@ -0,0 +1,89 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.node;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+
+import org.sonatype.nexus.ssl.spi.KeyStoreStorage;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Implementation of {@link KeyStoreStorage} backed by local filesystem.
+ *
+ * @since 3.1
+ */
+public class FileKeyStoreStorage
+ implements KeyStoreStorage
+{
+ private final File keyStoreFile;
+
+ private long lastRead;
+
+ public FileKeyStoreStorage(final File keyStoreFile) {
+ this.keyStoreFile = checkNotNull(keyStoreFile);
+ }
+
+ @VisibleForTesting
+ public File getKeyStoreFile() {
+ return keyStoreFile;
+ }
+
+ @Override
+ public boolean exists() {
+ return keyStoreFile.exists();
+ }
+
+ @Override
+ public boolean modified() {
+ return lastRead < keyStoreFile.lastModified();
+ }
+
+ @Override
+ public void load(final KeyStore keyStore, final char[] password)
+ throws NoSuchAlgorithmException, CertificateException, IOException
+ {
+ long readStart = System.currentTimeMillis();
+ try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(keyStoreFile))) {
+ keyStore.load(bis, password);
+ }
+ lastRead = readStart;
+ }
+
+ @Override
+ public void save(final KeyStore keyStore, final char[] password)
+ throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException
+ {
+ keyStoreFile.getParentFile().mkdirs(); // NOSONAR
+ try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(keyStoreFile))) {
+ keyStore.store(bos, password);
+ }
+ lastRead = System.currentTimeMillis();
+ }
+
+ @Override
+ public String toString() {
+ return keyStoreFile.toURI().toString();
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/KeyStoreManagerConfigurationImpl.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/KeyStoreManagerConfigurationImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d9d3f81ea7169a7ff2c32e250194846977ca281
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/KeyStoreManagerConfigurationImpl.java
@@ -0,0 +1,80 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.node;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.sonatype.goodies.common.Time;
+import org.sonatype.nexus.ssl.KeyStoreManagerConfiguration;
+import org.sonatype.nexus.ssl.KeyStoreManagerConfigurationSupport;
+
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * Node {@link KeyStoreManagerConfiguration}.
+ *
+ * @since 3.0
+ */
+@Named(KeyStoreManagerImpl.NAME)
+@Singleton
+public class KeyStoreManagerConfigurationImpl
+ extends KeyStoreManagerConfigurationSupport
+{
+ private static final String CPREFIX = "${node.keyStoreManager";
+
+ /**
+ * Private key-store password.
+ */
+ private static final char[] PKSP = "uuPWrk3UEQRaolpd".toCharArray();
+
+ /**
+ * Trusted key-store password.
+ */
+ private static final char[] TKSP = "1bmcqcHV3sp6fVKD".toCharArray();
+
+ /**
+ * Private-key password.
+ */
+ private static final char[] PKP = "CyQM8zCFeorarTA8".toCharArray();
+
+ @Inject
+ public KeyStoreManagerConfigurationImpl(
+ @Named(CPREFIX + ".keyStoreType:-JKS}") final String keyStoreType,
+ @Named(CPREFIX + ".keyAlgorithm:-RSA}") final String keyAlgorithm,
+ @Named(CPREFIX + ".keyAlgorithmSize:-2048}") final int keyAlgorithmSize,
+ @Named(CPREFIX + ".certificateValidity:-36500d}") final Time certificateValidity,
+ @Named(CPREFIX + ".signatureAlgorithm:-SHA1WITHRSA}") final String signatureAlgorithm,
+ @Named(CPREFIX + ".keyManagerAlgorithm:-DEFAULT}") final String keyManagerAlgorithm,
+ @Named(CPREFIX + ".trustManagerAlgorithm:-DEFAULT}") final String trustManagerAlgorithm)
+ {
+ setPrivateKeyStorePassword(PKSP);
+ setTrustedKeyStorePassword(TKSP);
+ setPrivateKeyPassword(PKP);
+ setKeyStoreType(keyStoreType);
+ setKeyAlgorithm(keyAlgorithm);
+ setKeyAlgorithmSize(keyAlgorithmSize);
+ setCertificateValidity(certificateValidity);
+ setSignatureAlgorithm(signatureAlgorithm);
+ setKeyManagerAlgorithm(keyManagerAlgorithm);
+ setTrustManagerAlgorithm(trustManagerAlgorithm);
+ }
+
+ @VisibleForTesting
+ public KeyStoreManagerConfigurationImpl() {
+ setPrivateKeyStorePassword(PKSP);
+ setTrustedKeyStorePassword(TKSP);
+ setPrivateKeyPassword(PKP);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/KeyStoreManagerImpl.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/KeyStoreManagerImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..5bef1641d330d232818fe9f91a9909b78fe0e2fd
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/KeyStoreManagerImpl.java
@@ -0,0 +1,43 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.node;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.sonatype.nexus.crypto.CryptoHelper;
+import org.sonatype.nexus.ssl.KeyStoreManager;
+import org.sonatype.nexus.ssl.KeyStoreManagerConfiguration;
+import org.sonatype.nexus.ssl.spi.KeyStoreStorageManager;
+
+/**
+ * Node {@link KeyStoreManager}.
+ *
+ * @since 3.0
+ */
+@Named(KeyStoreManagerImpl.NAME)
+@Singleton
+public class KeyStoreManagerImpl
+ extends org.sonatype.nexus.ssl.KeyStoreManagerImpl
+{
+ public static final String NAME = "node";
+
+ @Inject
+ public KeyStoreManagerImpl(final CryptoHelper crypto,
+ @Named(NAME) final KeyStoreStorageManager storageManager,
+ @Named(NAME) final KeyStoreManagerConfiguration config)
+ {
+ super(crypto, storageManager, config);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/KeyStoreStorageManagerImpl.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/KeyStoreStorageManagerImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..723a880a011326db74d46aa8b4a154f93ba93e5c
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/KeyStoreStorageManagerImpl.java
@@ -0,0 +1,57 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.node;
+
+import java.io.File;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.sonatype.nexus.common.app.ApplicationDirectories;
+import org.sonatype.nexus.ssl.spi.KeyStoreStorage;
+import org.sonatype.nexus.ssl.spi.KeyStoreStorageManager;
+
+import com.google.common.annotations.VisibleForTesting;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Implementation of {@link KeyStoreStorageManager} for the node identity. Uses local filesystem as backing storage so
+ * that node identity is specific to each node.
+ *
+ * @since 3.1
+ */
+@Named(KeyStoreManagerImpl.NAME)
+@Singleton
+public class KeyStoreStorageManagerImpl
+ implements KeyStoreStorageManager
+{
+ private final File basedir;
+
+ @Inject
+ public KeyStoreStorageManagerImpl(final ApplicationDirectories directories) {
+ this.basedir = new File(directories.getWorkDirectory("keystores"), KeyStoreManagerImpl.NAME);
+ }
+
+ @VisibleForTesting
+ public KeyStoreStorageManagerImpl(final File basedir) {
+ this.basedir = checkNotNull(basedir);
+ }
+
+ @Override
+ public KeyStoreStorage createStorage(final String keyStoreName) {
+ checkNotNull(keyStoreName);
+ return new FileKeyStoreStorage(new File(basedir, keyStoreName));
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/LocalNodeAccess.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/LocalNodeAccess.java
new file mode 100644
index 0000000000000000000000000000000000000000..e451a8421a8041ed7780639c31321b4d8c52201e
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/LocalNodeAccess.java
@@ -0,0 +1,155 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.node;
+
+import java.security.cert.Certificate;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+import org.sonatype.nexus.common.node.NodeAccess;
+import org.sonatype.nexus.common.stateguard.Guarded;
+import org.sonatype.nexus.common.stateguard.StateGuardLifecycleSupport;
+import org.sonatype.nexus.ssl.CertificateUtil;
+import org.sonatype.nexus.ssl.KeyStoreManager;
+
+import com.google.common.collect.ImmutableMap;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.sonatype.nexus.common.stateguard.StateGuardLifecycleSupport.State.STARTED;
+
+/**
+ * Local {@link NodeAccess}.
+ *
+ * @since 3.0
+ */
+@Named("local")
+@Singleton
+public class LocalNodeAccess
+ extends StateGuardLifecycleSupport
+ implements NodeAccess
+{
+ private final Provider keyStoreProvider;
+
+ private Certificate certificate;
+
+ private String fingerprint;
+
+ private String id;
+
+ private boolean freshNode;
+
+ private Map memberAliases = Collections.emptyMap();
+
+ @Inject
+ public LocalNodeAccess(@Named(KeyStoreManagerImpl.NAME) final Provider keyStoreProvider) {
+ this.keyStoreProvider = checkNotNull(keyStoreProvider);
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ KeyStoreManager keyStoreManager = keyStoreProvider.get();
+
+ // Generate identity key-pair if not already created
+ if (!keyStoreManager.isKeyPairInitialized()) {
+ log.info("Generating certificate");
+
+ // For now give something unique to the cert for additional identification purposes
+ UUID cn = UUID.randomUUID();
+ keyStoreManager.generateAndStoreKeyPair(
+ cn.toString(),
+ "Nexus",
+ "Sonatype",
+ "Silver Spring",
+ "MD",
+ "US");
+
+ freshNode = true; // nodes with newly created identities are considered 'fresh'
+ }
+
+ certificate = keyStoreManager.getCertificate();
+ log.trace("Certificate:\n{}", certificate);
+
+ fingerprint = CertificateUtil.calculateFingerprint(certificate);
+ log.debug("Fingerprint: {}", fingerprint);
+
+ id = NodeIdEncoding.nodeIdForCertificate(certificate);
+ log.info("ID: {}", id);
+
+ memberAliases = ImmutableMap.of(id, id);
+ }
+
+ @Override
+ protected void doStop() throws Exception {
+ certificate = null;
+ fingerprint = null;
+ id = null;
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public Certificate getCertificate() {
+ return certificate;
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public String getFingerprint() {
+ return fingerprint;
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public boolean isClustered() {
+ return false;
+ }
+
+ @Override
+ public Set getMemberIds() {
+ return memberAliases.keySet();
+ }
+
+ @Override
+ public boolean isFreshNode() {
+ return freshNode;
+ }
+
+ @Override
+ public boolean isOldestNode() {
+ return true;
+ }
+
+ @Override
+ public Map getMemberAliases() {
+ return memberAliases;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "{" +
+ "id='" + id + '\'' +
+ '}';
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/NodeIdEncoding.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/NodeIdEncoding.java
new file mode 100644
index 0000000000000000000000000000000000000000..56840558eb7d8683297ac224e1925f56f6106d3c
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/node/NodeIdEncoding.java
@@ -0,0 +1,69 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.node;
+
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.util.Locale;
+
+import org.sonatype.nexus.common.text.Strings2;
+
+import com.google.common.hash.Hashing;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Node ID encoding helpers.
+ *
+ * @since 3.0
+ */
+public class NodeIdEncoding
+{
+ private NodeIdEncoding() {
+ // empty
+ }
+
+ /**
+ * Encode plain Certificate SHA1 into node-id string.
+ */
+ public static String nodeIdForSha1(final String input) {
+ checkNotNull(input);
+ return Strings2.encodeSeparator(input, '-', 8);
+ }
+
+ /**
+ * Decode node-id into plain SHA1 string.
+ */
+ public static String sha1ForNodeId(final String input) {
+ checkNotNull(input);
+ return input.replaceAll("-", "");
+ }
+
+ /**
+ * Return node-id for certificate.
+ */
+ public static String nodeIdForCertificate(final Certificate cert) throws CertificateEncodingException {
+ checkNotNull(cert);
+ String sha1 = Hashing.sha1().hashBytes(cert.getEncoded()).toString().toUpperCase(Locale.US);
+ return nodeIdForSha1(sha1);
+ }
+
+ /**
+ * Return node-id for certificate fingerprint.
+ */
+ public static String nodeIdForFingerprint(final String fingerprint) {
+ checkNotNull(fingerprint);
+ String sha1 = fingerprint.replace(":", "");
+ return nodeIdForSha1(sha1);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/ConfigDatabase.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/ConfigDatabase.java
new file mode 100644
index 0000000000000000000000000000000000000000..eec4a281c8dbc9224cc3141e1d7d041304774837
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/ConfigDatabase.java
@@ -0,0 +1,92 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.orient;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+import org.sonatype.goodies.common.ComponentSupport;
+import org.sonatype.nexus.orient.DatabaseExternalizer;
+import org.sonatype.nexus.orient.DatabaseInstance;
+import org.sonatype.nexus.orient.DatabaseManager;
+import org.sonatype.nexus.supportzip.SupportBundle;
+import org.sonatype.nexus.supportzip.SupportBundle.ContentSource.Type;
+import org.sonatype.nexus.supportzip.SupportBundleCustomizer;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Shared {@code config} database components.
+ *
+ * @since 3.0
+ */
+@SuppressWarnings("UnusedDeclaration")
+public class ConfigDatabase
+{
+ private ConfigDatabase() {
+ // empty
+ }
+
+ public static final String NAME = "config";
+
+ /**
+ * Shared {@code config} database instance provider.
+ */
+ @Named(NAME)
+ @Singleton
+ public static class ProviderImpl
+ implements Provider
+ {
+ private final DatabaseManager databaseManager;
+
+ @Inject
+ public ProviderImpl(final DatabaseManager databaseManager) {
+ this.databaseManager = checkNotNull(databaseManager);
+ }
+
+ @Override
+ public DatabaseInstance get() {
+ return databaseManager.instance(NAME);
+ }
+ }
+
+ /**
+ * Includes export of the {@code config} database in support-zip.
+ */
+ @Named
+ @Singleton
+ public static class SupportBundleCustomizerImpl
+ extends ComponentSupport
+ implements SupportBundleCustomizer
+ {
+ private final Provider databaseInstance;
+
+ @Inject
+ public SupportBundleCustomizerImpl(@Named(NAME) final Provider databaseInstance) {
+ this.databaseInstance = checkNotNull(databaseInstance);
+ }
+
+ @Override
+ public void customize(final SupportBundle supportBundle) {
+ String path = String.format("work/%s/%s/%s",
+ DatabaseManagerImpl.WORK_PATH,
+ databaseInstance.get().getName(),
+ DatabaseExternalizer.EXPORT_FILENAME
+ );
+
+ supportBundle.add(new PasswordSanitizedJsonSource(Type.CONFIG, path, databaseInstance));
+ }
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/ConfigDatabaseCheckpoint.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/ConfigDatabaseCheckpoint.java
new file mode 100644
index 0000000000000000000000000000000000000000..3e93ac7b378213f128b7181180e0206444e6ddfd
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/ConfigDatabaseCheckpoint.java
@@ -0,0 +1,42 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.orient;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+import org.sonatype.nexus.common.app.ApplicationDirectories;
+import org.sonatype.nexus.common.upgrade.Checkpoints;
+import org.sonatype.nexus.orient.DatabaseCheckpointSupport;
+import org.sonatype.nexus.orient.DatabaseInstance;
+
+/**
+ * Upgrade checkpoint for the "config" database.
+ *
+ * @since 3.1
+ */
+@Named
+@Singleton
+@Checkpoints(model = ConfigDatabase.NAME)
+public class ConfigDatabaseCheckpoint
+ extends DatabaseCheckpointSupport
+{
+ @Inject
+ public ConfigDatabaseCheckpoint(@Named(ConfigDatabase.NAME) final Provider databaseInstance,
+ final ApplicationDirectories appDirectories)
+ {
+ super(ConfigDatabase.NAME, databaseInstance, appDirectories);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DatabaseManagerImpl.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DatabaseManagerImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..59f0abbd69f69ceaca6b8b3ff762f28eeab02bff
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DatabaseManagerImpl.java
@@ -0,0 +1,115 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.orient;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.sonatype.nexus.common.app.ApplicationDirectories;
+import org.sonatype.nexus.common.io.DirectoryHelper;
+import org.sonatype.nexus.jmx.reflect.ManagedAttribute;
+import org.sonatype.nexus.jmx.reflect.ManagedObject;
+import org.sonatype.nexus.orient.DatabaseExternalizer;
+import org.sonatype.nexus.orient.DatabaseExternalizerImpl;
+import org.sonatype.nexus.orient.DatabaseRestorer;
+import org.sonatype.nexus.orient.DatabaseManager;
+import org.sonatype.nexus.orient.DatabaseManagerSupport;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.orientechnologies.common.io.OFileUtils;
+import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Default {@code plocal} {@link DatabaseManager} implementation.
+ *
+ * @since 3.0
+ */
+@Named
+@Singleton
+@ManagedObject
+public class DatabaseManagerImpl
+ extends DatabaseManagerSupport
+{
+ public static final String WORK_PATH = "db";
+
+ private final File databasesDirectory;
+
+ private final DatabaseRestorer databaseRestorer;
+
+ @Inject
+ public DatabaseManagerImpl(final ApplicationDirectories applicationDirectories,
+ final DatabaseRestorer databaseRestorer) {
+ checkNotNull(applicationDirectories);
+ this.databasesDirectory = applicationDirectories.getWorkDirectory(WORK_PATH);
+ log.debug("Databases directory: {}", databasesDirectory);
+ this.databaseRestorer = checkNotNull(databaseRestorer);
+ }
+
+ @VisibleForTesting
+ public DatabaseManagerImpl(final File databasesDirectory,
+ final DatabaseRestorer databaseRestorer) {
+ this.databasesDirectory = checkNotNull(databasesDirectory);
+ log.debug("Databases directory: {}", databasesDirectory);
+ this.databaseRestorer = checkNotNull(databaseRestorer);
+ }
+
+ @ManagedAttribute
+ public File getDatabasesDirectory() {
+ return databasesDirectory;
+ }
+
+ /**
+ * Returns the directory for the given named database. Directory may or may not exist.
+ */
+ private File directory(final String name) throws IOException {
+ return new File(databasesDirectory, name).getCanonicalFile();
+ }
+
+ @Override
+ protected String connectionUri(final String name) {
+ try {
+ File dir = directory(name);
+ DirectoryHelper.mkdir(dir);
+
+ // OHazelcastPlugin.onOpen() assumes that dbUri.startsWith("plocal:" + dbDirectory)
+ // We're well advised to meet that assumption or clustering won't work, more specifically we need to form
+ // plocal:/data/dbName for Unix/OSX and plocal:D:/data/dbName for Win (no slash before drive letter)
+ return "plocal:" + OFileUtils.getPath(dir.getAbsolutePath()).replace("//", "/");
+ }
+ catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * When the database is being created, maybe import from the standard export location or restore backups.
+ *
+ * @see DatabaseExternalizer#EXPORT_FILENAME
+ * @see DatabaseExternalizer#EXPORT_GZ_FILENAME
+ * @see DatabaseExternalizerImpl#maybeImportFromStandardLocation(ODatabaseDocumentTx, File)
+ */
+ @Override
+ protected void created(final ODatabaseDocumentTx db, final String name) throws Exception {
+ File dir = directory(name);
+ if (!databaseRestorer.maybeRestoreDatabase(db, name)) {
+ DatabaseExternalizerImpl externalizer = externalizer(name);
+ externalizer.maybeImportFromStandardLocation(db, dir);
+ }
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DatabaseServerImpl.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DatabaseServerImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..6b766e51101b6950d04b2c3976529be6a05eb959
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DatabaseServerImpl.java
@@ -0,0 +1,395 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.orient;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+import java.util.logging.Logger;
+
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+import org.sonatype.nexus.common.app.ApplicationDirectories;
+import org.sonatype.nexus.common.event.EventAware;
+import org.sonatype.nexus.common.log.LoggerLevelChangedEvent;
+import org.sonatype.nexus.common.log.LoggersResetEvent;
+import org.sonatype.nexus.common.node.NodeAccess;
+import org.sonatype.nexus.common.stateguard.Guarded;
+import org.sonatype.nexus.common.stateguard.StateGuardLifecycleSupport;
+import org.sonatype.nexus.jmx.reflect.ManagedAttribute;
+import org.sonatype.nexus.jmx.reflect.ManagedObject;
+import org.sonatype.nexus.orient.DatabaseServer;
+import org.sonatype.nexus.orient.OrientConfigCustomizer;
+import org.sonatype.nexus.orient.entity.EntityHook;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.eventbus.Subscribe;
+import com.orientechnologies.common.log.OLogManager;
+import com.orientechnologies.orient.core.OConstants;
+import com.orientechnologies.orient.core.Orient;
+import com.orientechnologies.orient.core.config.OGlobalConfiguration;
+import com.orientechnologies.orient.server.OServer;
+import com.orientechnologies.orient.server.config.OServerCommandConfiguration;
+import com.orientechnologies.orient.server.config.OServerConfiguration;
+import com.orientechnologies.orient.server.config.OServerEntryConfiguration;
+import com.orientechnologies.orient.server.config.OServerHandlerConfiguration;
+import com.orientechnologies.orient.server.config.OServerNetworkConfiguration;
+import com.orientechnologies.orient.server.config.OServerNetworkListenerConfiguration;
+import com.orientechnologies.orient.server.config.OServerNetworkProtocolConfiguration;
+import com.orientechnologies.orient.server.config.OServerParameterConfiguration;
+import com.orientechnologies.orient.server.config.OServerSecurityConfiguration;
+import com.orientechnologies.orient.server.config.OServerStorageConfiguration;
+import com.orientechnologies.orient.server.config.OServerUserConfiguration;
+import com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary;
+import com.orientechnologies.orient.server.network.protocol.http.ONetworkProtocolHttpDb;
+import com.orientechnologies.orient.server.network.protocol.http.command.get.OServerCommandGetStaticContent;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.sonatype.nexus.common.stateguard.StateGuardLifecycleSupport.State.STARTED;
+
+/**
+ * Default {@link DatabaseServer} implementation.
+ *
+ * @since 3.0
+ */
+@Named
+@Singleton
+@ManagedObject
+public class DatabaseServerImpl
+ extends StateGuardLifecycleSupport
+ implements DatabaseServer, EventAware, EventAware.Asynchronous, Provider
+{
+ private static final String JUL_ROOT_LOGGER = "";
+
+ private static final String ORIENTDB_PARENT_LOGGER = "com";
+
+ private static final String ORIENTDB_LOGGER = ORIENTDB_PARENT_LOGGER + ".orientechnologies";
+
+ private final ApplicationDirectories applicationDirectories;
+
+ private final List injectedHandlers;
+
+ private final List configCustomizers;
+
+ private final EntityHook entityHook;
+
+ private final ClassLoader uberClassLoader;
+
+ private final boolean binaryListenerEnabled;
+
+ private final boolean httpListenerEnabled;
+
+ private boolean dynamicPlugins;
+
+ private final String binaryPortRange;
+
+ private final String httpPortRange;
+
+ private OServer orientServer;
+
+ @Inject
+ public DatabaseServerImpl(final ApplicationDirectories applicationDirectories,
+ final List injectedHandlers,
+ final List configCustomizers,
+ @Named("nexus-uber") final ClassLoader uberClassLoader,
+ @Named("${nexus.orient.binaryListenerEnabled:-false}") final boolean binaryListenerEnabled,
+ @Named("${nexus.orient.httpListenerEnabled:-false}") final boolean httpListenerEnabled,
+ @Named("${nexus.orient.dynamicPlugins:-false}") final boolean dynamicPlugins,
+ @Named("${nexus.orient.binaryListener.portRange:-2424-2430}") final String binaryPortRange,
+ @Named("${nexus.orient.httpListener.portRange:-2480-2490}") final String httpPortRange,
+ final NodeAccess nodeAccess,
+ final EntityHook entityHook)
+ {
+ this.applicationDirectories = checkNotNull(applicationDirectories);
+ this.injectedHandlers = checkNotNull(injectedHandlers);
+ this.configCustomizers = checkNotNull(configCustomizers);
+ this.uberClassLoader = checkNotNull(uberClassLoader);
+ this.httpListenerEnabled = httpListenerEnabled;
+ this.dynamicPlugins = dynamicPlugins;
+ this.binaryPortRange = binaryPortRange;
+ this.httpPortRange = httpPortRange;
+ this.entityHook = checkNotNull(entityHook);
+
+ if (nodeAccess.isClustered()) {
+ this.binaryListenerEnabled = true; // clustered mode requires binary listener
+ }
+ else {
+ this.binaryListenerEnabled = binaryListenerEnabled;
+ }
+
+ log.info("OrientDB version: {}", OConstants.getVersion());
+ }
+
+ @ManagedAttribute
+ public boolean isBinaryListenerEnabled() {
+ return binaryListenerEnabled;
+ }
+
+ @ManagedAttribute
+ public boolean isHttpListenerEnabled() {
+ return httpListenerEnabled;
+ }
+
+ // FIXME: May need to revisit embedded configuration strategy, this is quite nasty
+
+ @Override
+ protected void doStart() throws Exception {
+ // global startup
+ Orient.instance().startup();
+
+ // instance startup
+ OServer server = new OServer();
+ configureOrientMinimumLogLevel();
+ server.setExtensionClassLoader(uberClassLoader);
+ OServerConfiguration config = createConfiguration();
+ server.startup(config);
+
+ // remove Orient shutdown-hooks added during startup, we'll manage shutdown ourselves
+ Orient.instance().removeShutdownHook();
+ server.removeShutdownHook();
+
+ // create default root user to avoid orientdb prompt on console
+ server.addUser(OServerConfiguration.DEFAULT_ROOT_USER, null, "*");
+
+ // Log global configuration
+ if (log.isDebugEnabled()) {
+ // dumpConfiguration() only accepts ancient stream api
+ String encoding = StandardCharsets.UTF_8.name();
+ ByteArrayOutputStream buff = new ByteArrayOutputStream();
+ OGlobalConfiguration.dumpConfiguration(new PrintStream(buff, true, encoding));
+ log.debug("Global configuration:\n{}", new String(buff.toByteArray(), encoding));
+ }
+
+ Orient.instance().addDbLifecycleListener(entityHook);
+
+ server.activate();
+ log.info("Activated");
+
+ this.orientServer = server;
+ }
+
+ private OServerConfiguration createConfiguration() {
+ File configDir = applicationDirectories.getConfigDirectory("fabric");
+
+ // FIXME: Unsure what this directory is used for
+ File orientDir = applicationDirectories.getWorkDirectory("orient");
+ System.setProperty("orient.home", orientDir.getPath());
+ System.setProperty(Orient.ORIENTDB_HOME, orientDir.getPath());
+
+ OServerConfiguration config = new OServerConfiguration();
+
+ // FIXME: Unsure what this is used for, its apparently assigned to xml location, but forcing it here
+ config.location = "DYNAMIC-CONFIGURATION";
+
+ File databaseDir = applicationDirectories.getWorkDirectory("db");
+ File securityFile = new File(configDir, "orientdb-security.json");
+
+ config.properties = new OServerEntryConfiguration[]{
+ new OServerEntryConfiguration("server.database.path", databaseDir.getPath()),
+ new OServerEntryConfiguration("server.security.file", securityFile.getPath()),
+ new OServerEntryConfiguration("plugin.dynamic", String.valueOf(dynamicPlugins))
+ };
+
+ config.handlers = new ArrayList<>(injectedHandlers);
+ config.hooks = new ArrayList<>();
+
+ config.network = new OServerNetworkConfiguration();
+ config.network.protocols = Lists.newArrayList(
+ new OServerNetworkProtocolConfiguration("binary", ONetworkProtocolBinary.class.getName()),
+ new OServerNetworkProtocolConfiguration("http", ONetworkProtocolHttpDb.class.getName())
+ );
+
+ config.network.listeners = new ArrayList<>();
+
+ OServerNetworkListenerConfiguration binaryListener = null, httpListener = null;
+
+ if (binaryListenerEnabled) {
+ binaryListener = createBinaryListener(binaryPortRange);
+ config.network.listeners.add(binaryListener);
+ }
+
+ if (httpListenerEnabled) {
+ httpListener = createHttpListener(httpPortRange);
+ config.network.listeners.add(httpListener);
+ }
+
+ config.storages = new OServerStorageConfiguration[]{};
+
+ config.users = new OServerUserConfiguration[]{
+ new OServerUserConfiguration("admin", "admin", "*")
+ };
+
+ config.security = new OServerSecurityConfiguration();
+ config.security.users = new ArrayList<>();
+ config.security.resources = new ArrayList<>();
+
+ // latest advice is to disable DB compression as it doesn't buy much,
+ // also snappy has issues with use of native lib (unpacked under tmp)
+ OGlobalConfiguration.STORAGE_COMPRESSION_METHOD.setValue("nothing");
+
+ // ensure we don't set a file lock, which can behave badly on NFS https://issues.sonatype.org/browse/NEXUS-11289
+ OGlobalConfiguration.FILE_LOCK.setValue(false);
+
+ // disable auto removal of servers, SharedHazelcastPlugin removes gracefully shutdown nodes but for crashes and
+ // especially network partitions we don't want the write quorum getting lowered and endanger consistency
+ OGlobalConfiguration.DISTRIBUTED_AUTO_REMOVE_OFFLINE_SERVERS.setValue(-1);
+
+ // Apply customizations to server configuration
+ configCustomizers.forEach((it) -> it.apply(config));
+
+ if (binaryListener != null) {
+ log.info("Binary listener enabled: {}:[{}]", binaryListener.ipAddress, binaryListener.portRange);
+ }
+
+ if (httpListener != null) {
+ log.info("HTTP listener enabled: {}:[{}]", httpListener.ipAddress, httpListener.portRange);
+ }
+
+ return config;
+ }
+
+ private OServerNetworkListenerConfiguration createBinaryListener(final String binaryPortRange) {
+ OServerNetworkListenerConfiguration listener;
+ listener = new OServerNetworkListenerConfiguration();
+ listener.ipAddress = "0.0.0.0";
+ listener.portRange = binaryPortRange;
+ listener.protocol = "binary";
+ listener.socket = "default";
+ return listener;
+ }
+
+ private OServerNetworkListenerConfiguration createHttpListener(final String httpPortRange) {
+ OServerNetworkListenerConfiguration listener;
+ listener = new OServerNetworkListenerConfiguration();
+ listener.ipAddress = "0.0.0.0";
+ listener.portRange = httpPortRange;
+ listener.protocol = "http";
+ listener.socket = "default";
+ listener.parameters = new OServerParameterConfiguration[] {
+ new OServerParameterConfiguration("network.http.charset", "UTF-8"),
+ new OServerParameterConfiguration("network.http.jsonResponseError", "true")
+ };
+
+ OServerCommandConfiguration getCommand = new OServerCommandConfiguration();
+ getCommand.implementation = OServerCommandGetStaticContent.class.getName();
+ getCommand.pattern = "GET|www GET|studio/ GET| GET|*.htm GET|*.html GET|*.xml GET|*.jpeg GET|*.jpg GET|*.png GET|*.gif GET|*.js GET|*.css GET|*.swf GET|*.ico GET|*.txt GET|*.otf GET|*.pjs GET|*.svg GET|*.json GET|*.woff GET|*.ttf GET|*.svgz";
+ getCommand.parameters = new OServerEntryConfiguration[] {
+ new OServerEntryConfiguration("http.cache:*.htm *.html", "Cache-Control: no-cache, no-store, max-age=0, must-revalidate\\r\\nPragma: no-cache"),
+ new OServerEntryConfiguration("http.cache:default", "Cache-Control: max-age=120")
+ };
+ listener.commands = new OServerCommandConfiguration[] {
+ getCommand
+ };
+ return listener;
+ }
+
+ @Override
+ protected void doStop() throws Exception {
+ // instance shutdown
+ orientServer.shutdown();
+ orientServer = null;
+
+ // global shutdown
+ Orient.instance().shutdown();
+
+ log.info("Shutdown");
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public List databases() {
+ return ImmutableList.copyOf(orientServer.getAvailableStorageNames().keySet());
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public OServer get() {
+ return orientServer;
+ }
+
+ @Subscribe
+ public void onLoggerLevelChanged(final LoggerLevelChangedEvent event) {
+ String logger = event.getLogger();
+ if (ORIENTDB_LOGGER.startsWith(logger) || logger.startsWith(ORIENTDB_LOGGER)
+ || org.slf4j.Logger.ROOT_LOGGER_NAME.equals(logger)) {
+ configureOrientMinimumLogLevel();
+ }
+ }
+
+ @Subscribe
+ public void onLoggersReset(final LoggersResetEvent event) {
+ configureOrientMinimumLogLevel();
+ }
+
+ /**
+ * Until OrientDB cleans up its logging infrastructure, this synchronizes its global minimum log level to the minimum
+ * log level configured for any of its loggers.
+ *
+ * @see http://www.prjhub.com/#/issues/3744
+ * @see http://www.prjhub.com/#/issues/5327
+ */
+ private void configureOrientMinimumLogLevel() {
+ int minimumLevel = getOrientMininumLogLevel();
+ log.debug("Configuring OrientDB global minimum log level to {}", minimumLevel);
+ OLogManager logManager = OLogManager.instance();
+ logManager.setDebugEnabled(minimumLevel <= Level.FINE.intValue());
+ logManager.setInfoEnabled(minimumLevel <= Level.INFO.intValue());
+ logManager.setWarnEnabled(minimumLevel <= Level.WARNING.intValue());
+ logManager.setErrorEnabled(minimumLevel <= Level.SEVERE.intValue());
+ }
+
+ private int getOrientMininumLogLevel() {
+ int minimumLogLevel = 0;
+ for (String loggerName : new String[] { ORIENTDB_LOGGER, ORIENTDB_PARENT_LOGGER, JUL_ROOT_LOGGER }) {
+ Integer logLevel = getSafeLogLevel(loggerName);
+ if (logLevel != null) {
+ minimumLogLevel = logLevel;
+ break;
+ }
+ }
+ String orientLoggerPrefix = ORIENTDB_LOGGER + '.';
+ for (Enumeration en = LogManager.getLogManager().getLoggerNames(); en.hasMoreElements()
+ && minimumLogLevel > Level.FINE.intValue();) {
+ String loggerName = en.nextElement();
+ if (!loggerName.startsWith(orientLoggerPrefix)) {
+ continue;
+ }
+ Integer logLevel = getSafeLogLevel(loggerName);
+ if (logLevel != null && logLevel < minimumLogLevel) {
+ minimumLogLevel = logLevel;
+ }
+ }
+ return minimumLogLevel;
+ }
+
+ @Nullable
+ private Integer getSafeLogLevel(final String loggerName) {
+ Logger logger = LogManager.getLogManager().getLogger(loggerName);
+ if (logger == null) {
+ return null;
+ }
+ Level level = logger.getLevel();
+ return (level != null) ? level.intValue() : null;
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DeploymentAccessImpl.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DeploymentAccessImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..5939f5cd5837f459dab60e7ca652c1255d531a3c
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DeploymentAccessImpl.java
@@ -0,0 +1,111 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+
+package org.sonatype.nexus.internal.orient;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+import org.sonatype.nexus.common.app.ManagedLifecycle;
+import org.sonatype.nexus.common.node.DeploymentAccess;
+import org.sonatype.nexus.common.node.NodeAccess;
+import org.sonatype.nexus.common.stateguard.Guarded;
+import org.sonatype.nexus.common.stateguard.StateGuardLifecycleSupport;
+import org.sonatype.nexus.orient.DatabaseInstance;
+
+import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.sonatype.nexus.common.app.ManagedLifecycle.Phase.SCHEMAS;
+import static org.sonatype.nexus.common.stateguard.StateGuardLifecycleSupport.State.STARTED;
+import static org.sonatype.nexus.orient.DatabaseInstanceNames.CONFIG;
+import static org.sonatype.nexus.orient.transaction.OrientTransactional.inTx;
+import static org.sonatype.nexus.orient.transaction.OrientTransactional.inTxRetry;
+
+/**
+ * Class used to identify a deployment uniquely and permanently.
+ *
+ * {@link DeploymentIdentifier#getId()} is generated at first run and not modifiable.
+ *
+ * @since 3.6.1
+ */
+@Named
+@ManagedLifecycle(phase = SCHEMAS)
+@Singleton
+public class DeploymentAccessImpl
+ extends StateGuardLifecycleSupport
+ implements DeploymentAccess
+{
+ private final Provider databaseInstance;
+
+ private final DeploymentIdentifierEntityAdapter entityAdapter;
+
+ private final NodeAccess nodeAccess;
+
+ // cached local copy; initialized by #doStart
+ private String id;
+
+ @Inject
+ public DeploymentAccessImpl(@Named(CONFIG) final Provider databaseInstance,
+ final NodeAccess nodeAccess)
+ {
+ this.databaseInstance = checkNotNull(databaseInstance);
+ this.entityAdapter = new DeploymentIdentifierEntityAdapter();
+ this.nodeAccess = nodeAccess;
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ try (ODatabaseDocumentTx tx = databaseInstance.get().connect()) {
+ entityAdapter.register(tx);
+ }
+
+ this.id = inTxRetry(databaseInstance).call(db -> {
+ DeploymentIdentifier identifier = entityAdapter.get(db);
+ if (identifier == null) {
+ identifier = new DeploymentIdentifier();
+ identifier.setId(nodeAccess.getId());
+ entityAdapter.set(db, identifier);
+ log.info("Created new deployment identifier: {}", identifier);
+ }
+ return identifier.getId();
+ });
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public String getAlias() {
+ return inTx(databaseInstance).call(db -> {
+ DeploymentIdentifier identifier = entityAdapter.get(db);
+ return identifier.getAlias();
+ });
+ }
+
+ @Override
+ @Guarded(by = STARTED)
+ public void setAlias(final String newAlias) {
+ inTxRetry(databaseInstance).run(db -> {
+ DeploymentIdentifier identifier = entityAdapter.get(db);
+ identifier.setAlias(newAlias);
+ entityAdapter.set(db, identifier);
+ });
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DeploymentIdentifier.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DeploymentIdentifier.java
new file mode 100644
index 0000000000000000000000000000000000000000..cba8eec8a380ed57c34cde9f8eb19a52fcdd0644
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DeploymentIdentifier.java
@@ -0,0 +1,55 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.orient;
+
+import org.sonatype.nexus.common.entity.AbstractEntity;
+
+/**
+ * Representation of a unique identifier for this NXRM deployment.
+ *
+ * {@link #getId()} is randomly generated at first launch for NXRM and is not modifiable.
+ *
+ * @since 3.6.1
+ */
+class DeploymentIdentifier
+ extends AbstractEntity
+{
+ private String id;
+ private String alias;
+
+ public String getId() {
+ return id;
+ }
+
+ DeploymentIdentifier setId(final String id) {
+ this.id = id;
+ return this;
+ }
+
+ public String getAlias() {
+ return alias;
+ }
+
+ public DeploymentIdentifier setAlias(final String alias) {
+ this.alias = alias;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "DeploymentIdentifier{" +
+ "id='" + id + '\'' +
+ ", alias='" + alias + '\'' +
+ '}';
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DeploymentIdentifierEntityAdapter.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DeploymentIdentifierEntityAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..b1693c434133f310f8023ce293ab26e050956535
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/DeploymentIdentifierEntityAdapter.java
@@ -0,0 +1,68 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.orient;
+
+import org.sonatype.nexus.orient.OClassNameBuilder;
+import org.sonatype.nexus.orient.entity.SingletonEntityAdapter;
+
+import com.orientechnologies.orient.core.metadata.schema.OClass;
+import com.orientechnologies.orient.core.metadata.schema.OType;
+import com.orientechnologies.orient.core.record.impl.ODocument;
+
+/**
+ * {@link SingletonEntityAdapter} to store our single {@link DeploymentIdentifier} record.
+ *
+ * @since 3.6.1
+ */
+class DeploymentIdentifierEntityAdapter
+ extends SingletonEntityAdapter
+{
+ private static final String DB_CLASS = new OClassNameBuilder()
+ .type("deploymentidentifier")
+ .build();
+
+ static final String P_ID = "id";
+
+ static final String P_ALIAS = "alias";
+
+ public DeploymentIdentifierEntityAdapter() {
+ super(DB_CLASS);
+ }
+
+ @Override
+ protected void defineType(final OClass type) {
+ type.createProperty(P_ID, OType.STRING)
+ .setMandatory(true)
+ .setNotNull(true);
+ type.createProperty(P_ALIAS, OType.STRING)
+ .setMandatory(false)
+ .setNotNull(false);
+ }
+
+ @Override
+ protected DeploymentIdentifier newEntity() {
+ return new DeploymentIdentifier();
+ }
+
+ @Override
+ protected void readFields(final ODocument document, final DeploymentIdentifier entity) {
+ entity.setId(document.field(P_ID, OType.STRING))
+ .setAlias(document.field(P_ALIAS, OType.STRING));
+ }
+
+ @Override
+ protected void writeFields(final ODocument document, final DeploymentIdentifier entity) {
+ document.field(P_ID, entity.getId());
+ document.field(P_ALIAS, entity.getAlias());
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/JmxHandlerConfiguration.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/JmxHandlerConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..984f097ce74a1cb93a2193489fcbc28feefdfe00
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/JmxHandlerConfiguration.java
@@ -0,0 +1,39 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.orient;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import com.orientechnologies.orient.server.config.OServerHandlerConfiguration;
+import com.orientechnologies.orient.server.config.OServerParameterConfiguration;
+import com.orientechnologies.orient.server.handler.OJMXPlugin;
+
+/**
+ * Enables the JMX plugin on the OrientDB server.
+ *
+ * @since 3.0
+ */
+@Named
+@Singleton
+public class JmxHandlerConfiguration
+ extends OServerHandlerConfiguration
+{
+ public JmxHandlerConfiguration() {
+ clazz = OJMXPlugin.class.getName();
+ parameters = new OServerParameterConfiguration[] {
+ new OServerParameterConfiguration("enabled", "true"),
+ new OServerParameterConfiguration("profilerManaged", "true")
+ };
+ }
+}
\ No newline at end of file
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/LogConfigurationCustomizerImpl.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/LogConfigurationCustomizerImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf7fcb767c47ca3330343aa5d677acec3da1e648
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/LogConfigurationCustomizerImpl.java
@@ -0,0 +1,49 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.orient;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import com.orientechnologies.orient.core.storage.impl.local.paginated.OLocalPaginatedStorage;
+
+import org.sonatype.nexus.common.log.LogConfigurationCustomizer;
+
+import static org.sonatype.nexus.common.log.LoggerLevel.DEFAULT;
+import static org.sonatype.nexus.common.log.LoggerLevel.INFO;
+import static org.sonatype.nexus.common.log.LoggerLevel.OFF;
+
+/**
+ * OrientDB {@link LogConfigurationCustomizer}.
+ *
+ * @since 3.0
+ */
+@Named
+@Singleton
+public class LogConfigurationCustomizerImpl
+ implements LogConfigurationCustomizer
+{
+ @Override
+ public void customize(final Configuration config) {
+ config.setLoggerLevel("org.sonatype.nexus.orient", DEFAULT);
+ config.setLoggerLevel("org.sonatype.nexus.internal.orient", DEFAULT);
+ config.setLoggerLevel("com.orientechnologies", DEFAULT);
+
+ // leave explain logging off by default regardless of root level because it incurs a penalty
+ // and disables the connection pool; so it's better to explicitly enable it when you need it
+ config.setLoggerLevel("org.sonatype.nexus.orient.explain", OFF);
+
+ // OLocalPaginatedStorage produces too much output if the ROOT logger is switched to DEBUG
+ config.setLoggerLevel(OLocalPaginatedStorage.class.getName(), INFO);
+ }
+}
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/OrientBootstrap.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/OrientBootstrap.java
new file mode 100644
index 0000000000000000000000000000000000000000..08cbb8f963f9428bf1b1d437a0319474d242e030
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/OrientBootstrap.java
@@ -0,0 +1,106 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.orient;
+
+import javax.annotation.Priority;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+import org.sonatype.goodies.lifecycle.Lifecycles;
+import org.sonatype.nexus.common.app.ManagedLifecycle;
+import org.sonatype.nexus.common.node.NodeAccess;
+import org.sonatype.nexus.common.stateguard.StateGuardLifecycleSupport;
+import org.sonatype.nexus.orient.DatabaseManager;
+import org.sonatype.nexus.orient.DatabaseServer;
+
+import com.orientechnologies.orient.core.compression.OCompression;
+import com.orientechnologies.orient.core.compression.OCompressionFactory;
+import com.orientechnologies.orient.core.sql.OSQLEngine;
+import com.orientechnologies.orient.core.sql.functions.OSQLFunctionAbstract;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.sonatype.nexus.common.app.ManagedLifecycle.Phase.STORAGE;
+
+/**
+ * Orient bootstrap.
+ *
+ * @since 3.0
+ */
+@Named
+@ManagedLifecycle(phase = STORAGE)
+@Priority(Integer.MAX_VALUE) // make sure this starts first
+@Singleton
+public class OrientBootstrap
+ extends StateGuardLifecycleSupport
+{
+ private final NodeAccess nodeAccess;
+
+ private final Provider databaseServer;
+
+ private final Provider databaseManager;
+
+ @Inject
+ public OrientBootstrap(final NodeAccess nodeAccess,
+ final Provider databaseServer,
+ final Provider databaseManager,
+ final Iterable managedCompressions,
+ final Iterable functions)
+ {
+ this.nodeAccess = checkNotNull(nodeAccess);
+ this.databaseServer = checkNotNull(databaseServer);
+ this.databaseManager = checkNotNull(databaseManager);
+ registerCompressions(checkNotNull(managedCompressions));
+ registerCustomFunctions(checkNotNull(functions));
+ }
+
+
+ @Override
+ protected void doStart() throws Exception {
+ nodeAccess.start();
+
+ databaseServer.get().start();
+
+ Lifecycles.start(databaseManager.get());
+ }
+
+ @Override
+ protected void doStop() throws Exception {
+ Lifecycles.stop(databaseManager.get());
+
+ databaseServer.get().stop();
+
+ nodeAccess.stop();
+ }
+
+ private void registerCompressions(final Iterable compressions) {
+ for (final OCompression compression : compressions) {
+ try {
+ log.debug("Registering OrientDB compression {} as '{}'", compression, compression.name());
+ OCompressionFactory.INSTANCE.register(compression);
+ }
+ catch (final IllegalArgumentException e) {
+ log.debug("An OrientDB compression named '{}' was already registered", compression.name(), e);
+ }
+ }
+ }
+
+ private void registerCustomFunctions(final Iterable functions) {
+ log.debug("Registering custom OrientDB functions");
+ for (OSQLFunctionAbstract function : functions) {
+ log.debug("Registering OrientDB function " + function.getName());
+ OSQLEngine.getInstance().registerFunction(function.getName(), function);
+ }
+ }
+}
\ No newline at end of file
diff --git a/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/OrientCommands.java b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/OrientCommands.java
new file mode 100644
index 0000000000000000000000000000000000000000..2333c1f623028edb9d2bdba2f94138e79d0d0ab1
--- /dev/null
+++ b/thirdparty-bundles/components/nexus-base/src/main/java/org/sonatype/nexus/internal/orient/OrientCommands.java
@@ -0,0 +1,156 @@
+/*
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2008-present Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.internal.orient;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import javax.annotation.Nullable;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.sonatype.nexus.commands.CommandSupport;
+import org.sonatype.nexus.common.text.Strings2;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.orientechnologies.common.console.annotation.ConsoleCommand;
+import com.orientechnologies.orient.console.OConsoleDatabaseApp;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Function;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.api.console.SessionFactory;
+import org.eclipse.sisu.EagerSingleton;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.CaseFormat.LOWER_CAMEL;
+import static com.google.common.base.CaseFormat.LOWER_UNDERSCORE;
+
+/**
+ * Registers OrientDB commands with Karaf's shell; handles execution requests and displays results.
+ *
+ * @since 3.0
+ */
+@Named
+@EagerSingleton
+public class OrientCommands
+ extends OConsoleDatabaseApp
+{
+ private static final Logger log = LoggerFactory.getLogger(OrientCommands.class);
+
+ private static final String SCOPE = "orient";
+
+ private final SessionFactory sessionFactory;
+
+ @Inject
+ public OrientCommands(@Nullable final SessionFactory sessionFactory) {
+ super(new String[0]);
+
+ this.sessionFactory = sessionFactory; // might be null during tests
+
+ for (Method method : getConsoleMethods().keySet()) {
+ if (method.isAnnotationPresent(ConsoleCommand.class)) {
+ register(createOrientCommand(method));
+ }
+ }
+
+ onBefore(); // set OrientDB command defaults
+ }
+
+ private void register(final Function command) {
+ log.debug("Registering command: {}", command);
+ if (sessionFactory != null) {
+ sessionFactory.getRegistry().register(command);
+ }
+ else {
+ log.warn("Unable to register command, sessionFactory is null: {}", command);
+ }
+ }
+
+ @Override
+ protected void printApplicationInfo() {
+ // hide banner as it doesn't apply here
+ }
+
+ private Function createOrientCommand(final Method method) {
+ return new CommandSupport(Action.class)
+ {
+ // OrientDB expects the method name to be transformed from camel-case into lower-case with spaces
+ private final String command = LOWER_CAMEL.to(LOWER_UNDERSCORE, method.getName()).replace('_', ' ');
+
+ @Override
+ public Object execute(final Session session, final List