You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streams.apache.org by sb...@apache.org on 2024/02/09 17:16:11 UTC

(streams-activitypub) 01/01: feat: initial commit (#550)

This is an automated email from the ASF dual-hosted git repository.

sblackmon pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/streams-activitypub.git

commit 1ed9896f948593bb1868011e4d7fcbc8695d667e
Author: Steve Blackmon <sb...@apache.org>
AuthorDate: Fri Feb 9 11:05:08 2024 -0600

    feat: initial commit (#550)
    
    fixes #550
    initial commit with project skeleton
    
    Signed-off-by: Steve Blackmon <sb...@apache.org>
---
 .gitignore                                         |    4 +
 .sdkmanrc                                          |   19 +
 KEYS                                               |  308 ++++
 LICENSE.txt                                        |  202 +++
 pom.xml                                            | 1736 ++++++++++++++++++++
 streams-activitypub-actors/pom.xml                 |  115 ++
 streams-activitypub-api/pom.xml                    |  101 ++
 .../api/pojo/WebfingerQueryRequest.json            |   22 +
 .../api/pojo/WebfingerQueryResponse.json           |   56 +
 .../streams/activitypub/api/WebfingerApi.scala     |   10 +
 streams-activitypub-api/streams-api.iml            |    9 +
 streams-activitypub-dist/Dockerfile                |    5 +
 streams-activitypub-dist/docker-compose.yml        |    9 +
 streams-activitypub-dist/pom.xml                   |  110 ++
 .../src/main/assembly/assembly-dist.xml            |   31 +
 streams-activitypub-remote/pom.xml                 |   91 +
 .../streams/activitypub/remote/WebfingerRest.scala |   16 +
 streams-activitypub-servlets/pom.xml               |  106 ++
 .../streams/activitypub/servlets/RootServlet.scala |   27 +
 .../activitypub/servlets/WebfingerServlet.scala    |  126 ++
 .../test/ActivityPubServletsTestSuite.scala        |   20 +
 .../servlets/test/cases/RootServletTest.scala      |   58 +
 streams-activitypub-webapp/Dockerfile              |   11 +
 streams-activitypub-webapp/pom.xml                 |  169 ++
 .../main/webapp/WEB-INF/classes/logging.properties |   10 +
 .../src/main/webapp/WEB-INF/context.xml            |   11 +
 .../src/main/webapp/WEB-INF/web.xml                |   45 +
 .../src/main/webapp/htdocs/images/asf.png          |  Bin 0 -> 8875 bytes
 .../src/main/webapp/htdocs/images/juneau.png       |  Bin 0 -> 3242 bytes
 .../src/main/webapp/htdocs/images/streams_logo.jpg |  Bin 0 -> 56578 bytes
 .../main/webapp/htdocs/styles/MenuItemWidget.css   |   17 +
 .../main/webapp/htdocs/styles/QueryMenuItem.css    |   13 +
 .../src/main/webapp/htdocs/styles/SwaggerUI.css    |  342 ++++
 .../src/main/webapp/htdocs/themes/streams.css      |    0
 .../webapp/test/ActivityPubWebappTestSuite.scala   |   31 +
 .../test/ActivityPubWebappTestSuiteExtension.scala |  104 ++
 .../webapp/test/cases/RootServletTest.scala        |   21 +
 .../webapp/test/cases/ServerAvailableTest.scala    |   33 +
 .../test/cases/ServletRegistrationTest.scala       |   23 +
 .../webapp/test/cases/WebfingerServletTest.scala   |   38 +
 40 files changed, 4049 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..aaaaba9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+target
+.idea
+*.iml
+**/src/site/resources
diff --git a/.sdkmanrc b/.sdkmanrc
new file mode 100644
index 0000000..bb64fd6
--- /dev/null
+++ b/.sdkmanrc
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+java=17.0.9-tem
+maven=3.9.6
+scala=3.3.1
diff --git a/KEYS b/KEYS
new file mode 100644
index 0000000..1993876
--- /dev/null
+++ b/KEYS
@@ -0,0 +1,308 @@
+This file contains the PGP keys of various developers.
+
+Users: pgp < KEYS
+       gpg --import KEYS
+Developers:
+        pgp -kxa <your name> and append it to this file.
+        (pgpk -ll <your name> && pgpk -xa <your name>) >> this file.
+        (gpg --list-sigs <your name>
+             && gpg --armor --export <your name>) >> this file.
+
+pub   2048R/3F94A968 2013-01-07
+uid                  Jason Letourneau <le...@apache.org>
+sig 3        3F94A968 2013-01-07  Jason Letourneau <le...@apache.org>
+sub   2048R/020FBED0 2013-01-07
+sig          3F94A968 2013-01-07  Jason Letourneau <le...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.12 (Darwin)
+
+mQENBFDrCSQBCADrCEd8fjnwpYn6aW7caXtwcrduZKbRPVisa+K+V9K1cm2zNg7Z
+unOk5cvlyLE3l8m2324I2cFml/ing/NaK6PY2+xJg+c9EXQ73/u5ccMU7NYuMYEG
+bPK5FMmr6B8q0UhpNIVZ0S2ZV1mfROGaLGPkQPuP36sU+u6Z6R/CruT7f6V/GVJ8
+66HQ087Lb24JTi1j5boLQlAIEFtF15eGxB45LT6IklEKAVf/B2TJK2TWDkcB6p0/
+j1EglDcOIPXcGBHTco4xC/qIDjpqAWd2N6KTcHB8ZHgpAQrq0PIC0iOqxWMfzdvA
+CFEhCKdH99Kqut9HGIl5++jwDlo2ntZh/52XABEBAAG0KEphc29uIExldG91cm5l
+YXUgPGxldG91cm5lYXVAYXBhY2hlLm9yZz6JATgEEwECACIFAlDrCSQCGwMGCwkI
+BwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEN+dqCk/lKlo50gIAN4MyxP4RAbgirEK
+j3wN0LnC7yzofi6+PMT03E4XKV9tTDB4xNROjxDAly5N6KuKk7F/QleQKVdQEQL1
+7YKnYV45QK1oYn2x06IkNwCFw4dNDqn41Gd2QpJY5twKTVFf0o3Fd7QBDCfoiW01
+Ke8ymubN9bdKN/LjjmkiCslhrweLScySDxv5upaPZvNP8cHrk8MsoDJRtsuxUQ7e
+/kQaNLLTNSW8bXevft5IEKUVky5YbPnPSea0iOjMR9gYaOE3N+Vik1NjixjKe3NF
+TnbJNSobHUkmVcD6xaNcAlX+0J9kaNH6+abp119a18Bg47rtN1EVLJYNKk5u8MJz
+EHNqTk25AQ0EUOsJJAEIAKWqm/hH97xE/re7HBz4PcSeXaYbaV4gYR6crfQNEUUF
+4xguHLVK/cpQBfB1aZJp/oJdB1v3ervYiN+PCSYOriTAK1SOj0zbOqEsmLmIOy/w
+FKGEJocVbNfpMlFcLKSL+Eq4Zz7FTUNvLksF5nI9llA/2spGncHj7DU1w0tvExjI
+EIaglfEpVsFlmehC1BMdoIeTDYnarY78A5hZ5ydDxbVk78qYpRJMC9N5Ez4IAY8N
+QGXNgA8wTpb2y86oCkEgNRl2RuEhRce0SjEZ+euttVvxRpzqEusdsQJbs8Eg5wpF
+h8+ZF63fUPTyqscZtkCeHbcskjMykow0pfB90xNtROkAEQEAAYkBHwQYAQIACQUC
+UOsJJAIbDAAKCRDfnagpP5SpaFbgCADNR6m7BdNs9lnpfVTjmgA5Bxg3ZoCJilbk
+7OM3QxvdcoDnb0iXJEgoAIO1QaiK395eQmam/dHupzVcwI/86Q2eDWUTx4zcUYRv
+m2C6P5yiEuH2792rLJ1SJbMy7AA3ZzBPwobjLmujHu9nO6SdX4hbpH3/LW+Xe3zV
+k+sS4gxii4SYQWqQyBf27nZIVVxcBVVdB0KmFcw6IEV7/LVho/tBpKV1BUoDeZj1
+BrhHUb9vCD16k6NX+gjQhKgRmZuljnC87ruUxLDEqhmiViVEjzrusx5uLVK7FmzF
+fLsE3mi3F0I3eJVwUFXji+nIeZXszGWvstmz8ADWWyvkEblYBv7H
+=iVYc
+-----END PGP PUBLIC KEY BLOCK-----
+
+pub  4096R/68D51867 2014-12-11 Steve Blackmon <sb...@apache.org>
+      Key fingerprint = F869 F111 9FCD 1952 E379  71CD F824 5949 68D5 1867
+sub  4096R/4EB79D36 2014-12-11
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: SKS 1.1.6
+Comment: Hostname: keys2.kfwebs.net
+
+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
+Ng==
+=X9Je
+-----END PGP PUBLIC KEY BLOCK-----
+pub   4096R/D3541808 2014-01-09
+uid       [ultimate] Suneel Marthi (CODE SIGNING KEY) <sm...@apache.org>
+sig 3        D3541808 2014-01-09  Suneel Marthi (CODE SIGNING KEY) <sm...@apache.org>
+sub   4096R/AF46E2DE 2014-01-09
+sig          D3541808 2014-01-09  Suneel Marthi (CODE SIGNING KEY) <sm...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Comment: GPGTools - https://gpgtools.org
+
+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
+kD2o/5GKWS5QkSUEUXXY1oDiLg==
+=f8kJ
+-----END PGP PUBLIC KEY BLOCK-----
+pub   rsa4096 2017-02-27 [SC]
+      AD270AD637D1405B3E42E790B5FAE7973E7A9A44
+uid           [ unknown] Trevor Grant (CODE SIGNING KEY) <ra...@apache.org>
+sub   rsa4096 2017-02-27 [E]
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+=5IrF
+-----END PGP PUBLIC KEY BLOCK-----
+pub   rsa4096 2018-04-06 [SC]
+      11AF5B4976E0FE1735BF4FCAC72AAA3860A421AE
+uid           [ultimate] Joey Frazee (CODE SIGNING KEY) <jf...@apache.org>
+sig 3        C72AAA3860A421AE 2018-04-06  Joey Frazee (CODE SIGNING KEY) <jf...@apache.org>
+uid           [ultimate] Joey Frazee (CODE SIGNING KEY) <jo...@icloud.com>
+sig 3        C72AAA3860A421AE 2018-04-06  Joey Frazee (CODE SIGNING KEY) <jf...@apache.org>
+sub   rsa4096 2018-04-06 [E]
+sig          C72AAA3860A421AE 2018-04-06  Joey Frazee (CODE SIGNING KEY) <jf...@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+=BpEQ
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) 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. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..5940755
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,1736 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache</groupId>
+        <artifactId>apache</artifactId>
+        <version>31</version>
+    </parent>
+
+    <groupId>org.apache.streams.activitypub</groupId>
+    <artifactId>apache-streams-activitypub</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+
+    <name>Apache Streams ActivityPub Server</name>
+    <description>Apache Streams ActivityPub Server</description>
+
+    <url>https://github.com/apache/streams-activitypub</url>
+
+    <licenses>
+        <license>
+            <name>Apache License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+            <comments>A business-friendly OSS license</comments>
+        </license>
+    </licenses>
+
+    <scm>
+        <connection>scm:git:https://github.com/apache/streams</connection>
+        <developerConnection>scm:git:git@github.com:apache/streams.git</developerConnection>
+        <url>scm:git:git@github.com:apache/streams.git</url>
+        <tag>HEAD</tag>
+    </scm>
+
+    <issueManagement>
+        <system>JIRA</system>
+        <url>https://issues.apache.org/jira/browse/STREAMS</url>
+    </issueManagement>
+
+    <ciManagement>
+        <system>jenkins</system>
+        <url>http://builds.apache.org/job/streams-project/</url>
+    </ciManagement>
+
+    <prerequisites>
+        <maven>3.0.5</maven>
+    </prerequisites>
+
+    <mailingLists>
+        <mailingList>
+            <name>Dev Mailing List</name>
+            <post>dev@streams.apache.org</post>
+            <subscribe>dev-subscribe@streams.apache.org</subscribe>
+            <unsubscribe>dev-unsubscribe@streams.apache.org</unsubscribe>
+            <archive>http://mail-archives.apache.org/mod_mbox/streams-dev/</archive>
+        </mailingList>
+        <mailingList>
+            <name>Commits Mailing List</name>
+            <post>commits@streams.apache.org</post>
+            <subscribe>commits-subscribe@streams.apache.org</subscribe>
+            <unsubscribe>commits-unsubscribe@streams.apache.org</unsubscribe>
+            <archive>http://mail-archives.apache.org/mod_mbox/streams-commits/</archive>
+        </mailingList>
+    </mailingLists>
+
+    <developers>
+        <developer>
+            <id>rbaxter85</id>
+            <name>Ryan Baxter</name>
+            <email>rbaxter85@apache.org</email>
+            <url>http://twitter.com/ryanjbaxter</url>
+            <roles>
+                <role>Committer</role>
+            </roles>
+        </developer>
+        <developer>
+            <id>sblackmon</id>
+            <name>Steve Blackmon</name>
+            <email>sblackmon@apache.org</email>
+            <url>http://twitter.com/steveblackmon</url>
+            <roles>
+                <role>PPMC Member</role>
+                <role>Committer</role>
+            </roles>
+            <properties>
+                <picUrl>https://avatars.githubusercontent.com/steveblackmon</picUrl>
+            </properties>
+        </developer>
+        <developer>
+            <id>rdouglas</id>
+            <name>Robert Douglas</name>
+            <email>rdouglas@apache.org</email>
+            <roles>
+                <role>PPMC Member</role>
+                <role>Committer</role>
+            </roles>
+        </developer>
+        <developer>
+            <id>ate</id>
+            <name>Ate Douma</name>
+            <email>ate@apache.org</email>
+            <url>http://twitter.com/atedouma</url>
+            <roles>
+                <role>Mentor</role>
+                <role>PPMC Member</role>
+                <role>Committer</role>
+            </roles>
+        </developer>
+        <developer>
+            <id>rebanks</id>
+            <name>Ryan Ebanks</name>
+            <email>rebanks@apache.org</email>
+            <url>http://twitter.com/ebanksre</url>
+            <roles>
+                <role>PPMC Member</role>
+                <role>Committer</role>
+            </roles>
+        </developer>
+        <developer>
+            <id>chansen</id>
+            <name>Carol Hansen</name>
+            <email>chansen@apache.org</email>
+            <url>http://twitter.com/carolbirgitta</url>
+            <roles>
+                <role>PPMC Member</role>
+                <role>Committer</role>
+            </roles>
+        </developer>
+        <developer>
+            <id>ahart</id>
+            <name>Andrew Hart</name>
+            <email>ahart@apache.org</email>
+            <url>http://twitter.com/andrewfhart</url>
+            <roles>
+                <role>Mentor</role>
+                <role>PPMC Member</role>
+                <role>Committer</role>
+            </roles>
+        </developer>
+        <developer>
+            <id>mfranklin</id>
+            <name>Matt Franklin</name>
+            <email>mfranklin@apache.org</email>
+            <url>http://twitter.com/mattfranklin</url>
+            <roles>
+                <role>Mentor</role>
+                <role>PPMC Member</role>
+                <role>Committer</role>
+            </roles>
+        </developer>
+        <developer>
+            <id>letourneau</id>
+            <name>Jason Letourneau</name>
+            <email>letourneau@apache.org</email>
+            <url>http://twitter.com/jletourneau8080</url>
+            <roles>
+                <role>PPMC Member</role>
+                <role>Committer</role>
+            </roles>
+        </developer>
+        <developer>
+            <id>craigmcc</id>
+            <name>Craig McClanahan</name>
+            <email>craigmcc@apache.org</email>
+            <url>http://twitter.com/craigmcclanahan</url>
+            <roles>
+                <role>Mentor</role>
+                <role>PPMC Member</role>
+                <role>Committer</role>
+            </roles>
+        </developer>
+        <developer>
+            <id>dsullivan</id>
+            <name>Danny Sullivan</name>
+            <email>dsullivan@apache.org</email>
+            <url>http://twitter.com/dbsullivan23</url>
+            <roles>
+                <role>PPMC Member</role>
+                <role>Committer</role>
+            </roles>
+        </developer>
+    </developers>
+
+    <repositories>
+        <repository>
+            <id>apache-repo</id>
+            <name>Apache Repository</name>
+            <url>https://repository.apache.org/content/repositories/releases</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+        <repository>
+            <id>apache-snapshots</id>
+            <name>Apache Repository</name>
+            <url>https://repository.apache.org/content/repositories/snapshots</url>
+            <releases>
+                <enabled>false</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
+        <repository>
+            <id>central-repo</id>
+            <name>Maven Repository</name>
+            <url>https://repo1.maven.org/maven2</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>apache-repo</id>
+            <name>Apache Repository</name>
+            <url>https://repository.apache.org/content/repositories/releases</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </pluginRepository>
+        <pluginRepository>
+            <id>apache-snapshots</id>
+            <name>Apache Repository</name>
+            <url>https://repository.apache.org/content/repositories/snapshots</url>
+            <releases>
+                <enabled>false</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </pluginRepository>
+        <pluginRepository>
+            <id>central-repo</id>
+            <name>Maven Repository</name>
+            <url>https://repo1.maven.org/maven2</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </pluginRepository>
+    </pluginRepositories>
+
+    <distributionManagement>
+        <repository>
+            <id>streams.releases</id>
+            <name>Streams Releases</name>
+            <url>${release.repository.url}</url>
+        </repository>
+        <!-- Snapshots (not-releases) are published to this repository -->
+        <snapshotRepository>
+            <id>streams.snapshots</id>
+            <name>Streams Snapshots</name>
+            <url>${snapshot.repository.url}</url>
+        </snapshotRepository>
+        <site>
+            <id>site.streams.project</id>
+            <url>scm:git:https://gitbox.apache.org/repos/asf/streams-activitypub.git</url>
+        </site>
+    </distributionManagement>
+
+    <properties>
+
+        <!-- Language Library Version Properties -->
+        <java.version>17</java.version>
+        <scala.version>3.3.1</scala.version>
+        <scala.binary.version>3</scala.binary.version>
+        <maven.version>3.9.3</maven.version>
+        <maven.compiler.source>${java.version}</maven.compiler.source>
+        <maven.compiler.target>${java.version}</maven.compiler.target>
+
+        <!-- Build Properties -->
+        <maven.javadoc.failOnError>false</maven.javadoc.failOnError>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <github.global.server>github</github.global.server>
+
+        <!-- Release Properties -->
+        <snapshot.repository.url>
+            https://repository.apache.org/content/repositories/snapshots
+        </snapshot.repository.url>
+        <release.repository.url>
+            https://repository.apache.org/service/local/staging/deploy/maven2
+        </release.repository.url>
+
+        <!-- Plugin and Plugin Dependency Versions -->
+        <apache-rat.plugin.version>0.13</apache-rat.plugin.version>
+        <build-helper.plugin.version>1.8</build-helper.plugin.version>
+        <bundle.plugin.version>1.4.3</bundle.plugin.version>
+        <checkstyle.plugin.version>3.3.1</checkstyle.plugin.version>
+        <compiler.plugin.version>3.11.0</compiler.plugin.version>
+        <clean.plugin.version>3.3.2</clean.plugin.version>
+        <dependency.plugin.version>3.6.1</dependency.plugin.version>
+        <depgraph.plugin.version>1.0.3</depgraph.plugin.version>
+        <docker.plugin.version>0.43.4</docker.plugin.version>
+        <download.plugin.version>1.2.1</download.plugin.version>
+        <enforcer.plugin.version>3.4.1</enforcer.plugin.version>
+        <jar.plugin.version>2.6</jar.plugin.version>
+        <javadoc.plugin.version>3.6.3</javadoc.plugin.version>
+        <license.plugin.version>2.4.0</license.plugin.version>
+        <pax.plugin.version>1.5</pax.plugin.version>
+        <remote-resources.plugin.version>1.4</remote-resources.plugin.version>
+        <reports.plugin.version>3.5.0</reports.plugin.version>
+        <resources.plugin.version>3.3.1</resources.plugin.version>
+        <scala.plugin.version>4.8.1</scala.plugin.version>
+        <scalastyle.plugin.version>0.8.0</scalastyle.plugin.version>
+        <scm.plugin.version>2.0.1</scm.plugin.version>
+        <scmpublish.plugin.version>3.2.1</scmpublish.plugin.version>
+        <shade.plugin.version>3.5.1</shade.plugin.version>
+        <site.plugin.version>4.0.0-M12</site.plugin.version>
+        <source.plugin.version>3.3.0</source.plugin.version>
+        <surefire.plugin.version>3.2.5</surefire.plugin.version>
+        <wagon.plugin.version>3.0.0</wagon.plugin.version>
+        <war.plugin.version>3.4.0</war.plugin.version>
+
+        <!-- Library Dependency Versions -->
+        <aalto.version>1.1.0</aalto.version>
+        <avro.version>1.11.3</avro.version>
+        <commons-codec.version>1.16.0</commons-codec.version>
+        <commons-collections.version>3.2.2</commons-collections.version>
+        <commons-collections4.version>4.4</commons-collections4.version>
+        <commons-io.version>2.15.1</commons-io.version>
+        <commons-lang3.version>3.14.0</commons-lang3.version>
+        <commons-text.version>1.11.0</commons-text.version>
+        <commons-validator.version>1.7</commons-validator.version>
+        <clojure.version>1.4.0</clojure.version>
+        <doxia.version>1.7</doxia.version>
+        <facebook4j.version>2.4.7</facebook4j.version>
+        <fmpp.version>0.9.16</fmpp.version>
+        <freemarker.version>2.3.32</freemarker.version>
+        <guava.version>32.1.3-jre</guava.version>
+        <httpcomponents.core.version>4.4.16</httpcomponents.core.version>
+        <httpcomponents.client.version>4.5.13</httpcomponents.client.version>
+        <jackson.version>2.16.0</jackson.version>
+        <jakarta.version>6.0.0</jakarta.version>
+        <jakarta-ws.version>3.1.0</jakarta-ws.version>
+        <joda-convert.version>1.8.1</joda-convert.version>
+        <joda-time.version>2.9.9</joda-time.version>
+        <json-path.version>2.8.0</json-path.version>
+        <json-schema-validator.version>1.1.0</json-schema-validator.version>
+        <juneau.version>9.0.1</juneau.version>
+        <jsonschema2pojo.version>1.2.1</jsonschema2pojo.version>
+        <jaxb2.version>0.15.3</jaxb2.version>
+        <jaxb2-basics.version>0.13.1</jaxb2-basics.version>
+        <jaxbutil.version>2.1.0</jaxbutil.version>
+        <netty.version>4.1.105.Final</netty.version>
+        <slf4j.version>2.0.9</slf4j.version>
+        <log4j.version>2.22.0</log4j.version>
+        <logback.version>1.4.14</logback.version>
+        <protobuf.version>3.16.3</protobuf.version>
+        <hamcrest.version>2.2</hamcrest.version>
+        <reflections.version>0.10.2</reflections.version>
+        <typesafe.config.version>1.4.2</typesafe.config.version>
+        <zookeeper.version>3.9.1</zookeeper.version>
+
+        <!-- Test Library Dependency Versions -->
+        <awaitility.version>4.2.0</awaitility.version>
+        <junit.version>5.10.1</junit.version>
+        <junit.platform.version>1.10.1</junit.platform.version>
+        <junit.surefire.version>1.3.2</junit.surefire.version>
+        <mockito.version>4.11.0</mockito.version>
+        <powermock.version>2.0.9</powermock.version>
+        <surefire.version>3.2.5</surefire.version>
+
+        <!-- maven plugin module helper versions -->
+        <maven-plugin.version>3.9.0</maven-plugin.version>
+        <maven-aether-provider.version>3.3.9</maven-aether-provider.version>
+        <maven-plugin-plugin.version>3.9.0</maven-plugin-plugin.version>
+        <maven-plugin-tools.version>3.9.0</maven-plugin-tools.version>
+        <maven-plugin-testing.version>3.3.0</maven-plugin-testing.version>
+        <maven-verifier.version>2.0.0-M1</maven-verifier.version>
+
+        <!-- osgi configuration -->
+        <org.osgi.service.http.port>8080</org.osgi.service.http.port>
+        <org.osgi.service.http.port.secure>8443</org.osgi.service.http.port.secure>
+
+        <skipTests>false</skipTests>
+        <skipExec>false</skipExec>
+
+        <!-- avoid intermittent build failures in streams-plugins -->
+        <jvm.options>--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.xml/jdk.xml.internal=ALL-UNNAMED -Djava.util.Arrays.useLegacyMergeSort=true</jvm.options>
+
+    </properties>
+
+    <modules>
+        <module>streams-activitypub-actors</module>
+        <module>streams-activitypub-api</module>
+        <module>streams-activitypub-dist</module>
+        <module>streams-activitypub-remote</module>
+        <module>streams-activitypub-servlets</module>
+        <module>streams-activitypub-webapp</module>
+    </modules>
+
+    <packaging>pom</packaging>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>org.apache.maven.wagon</groupId>
+                <artifactId>wagon-scm</artifactId>
+                <version>${wagon.plugin.version}</version>
+            </extension>
+            <extension>
+                <groupId>org.apache.maven.scm</groupId>
+                <artifactId>maven-scm-manager-plexus</artifactId>
+                <version>${scm.plugin.version}</version>
+            </extension>
+            <extension>
+                <groupId>org.apache.maven.scm</groupId>
+                <artifactId>maven-scm-provider-gitexe</artifactId>
+                <version>${scm.plugin.version}</version>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>net.alchim31.maven</groupId>
+                <artifactId>scala-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-site-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-remote-resources-plugin</artifactId>
+            </plugin>
+        </plugins>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <artifactId>maven-clean-plugin</artifactId>
+                    <version>${clean.plugin.version}</version>
+                    <executions>
+                        <execution>
+                            <id>auto-clean</id>
+                        </execution>
+                    </executions>
+                    <configuration>
+                        <filesets>
+                            <fileset>
+                                <directory>src/site/resources</directory>
+                                <followSymlinks>false</followSymlinks>
+                            </fileset>
+                            <!-- this is here because elasticsearch integration tests don't have a setting to change directory where temp index files get created -->
+                            <fileset>
+                                <directory>data</directory>
+                                <followSymlinks>false</followSymlinks>
+                            </fileset>
+                            <fileset>
+                                <directory>dist</directory>
+                            </fileset>
+                        </filesets>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-remote-resources-plugin</artifactId>
+                    <version>${remote-resources.plugin.version}</version>
+                    <executions>
+                        <execution>
+                            <goals>
+                                <goal>process</goal>
+                            </goals>
+                            <configuration>
+                                <resourceBundles combine.children="append">
+                                    <!-- Will generate META-INF/DEPENDENCIES META-INF/LICENSE.txt META-INF/NOTICE -->
+                                    <resourceBundle>org.apache:apache-jar-resource-bundle:1.4</resourceBundle>
+                                </resourceBundles>
+                                <properties>
+                                    <projectName>${notice.file.project.name}</projectName>
+                                </properties>
+                            </configuration>
+                        </execution>
+                    </executions>
+                </plugin>
+                <plugin>
+                    <artifactId>maven-resources-plugin</artifactId>
+                    <version>${resources.plugin.version}</version>
+                    <configuration>
+                        <encoding>${project.build.sourceEncoding}</encoding>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <id>copy-resources</id>
+                            <!-- validate is first to run-->
+                            <!-- copy these files to src/site/resources -->
+                            <phase>validate</phase>
+                            <goals>
+                                <goal>copy-resources</goal>
+                            </goals>
+                            <configuration>
+                                <outputDirectory>${basedir}/src/site/resources</outputDirectory>
+                                <resources>
+                                    <resource>
+                                        <directory>src/main/jsonschema</directory>
+                                    </resource>
+                                    <resource>
+                                        <directory>src/main/xmlschema</directory>
+                                    </resource>
+                                    <resource>
+                                        <directory>src/main/resources</directory>
+                                    </resource>
+                                    <resource>
+                                        <directory>src/main/templates</directory>
+                                    </resource>
+                                    <resource>
+                                        <directory>src/site/diagrams</directory>
+                                    </resource>
+                                    <resource>
+                                        <directory>src/test/resources</directory>
+                                    </resource>
+                                </resources>
+                            </configuration>
+                        </execution>
+                    </executions>
+                </plugin>
+                <plugin>
+                    <groupId>org.jsonschema2pojo</groupId>
+                    <artifactId>jsonschema2pojo-maven-plugin</artifactId>
+                    <version>${jsonschema2pojo.version}</version>
+                    <configuration>
+                        <annotationStyle>none</annotationStyle>
+                        <customAnnotator>org.apache.streams.plugins.JuneauPojoAnnotator</customAnnotator>
+                        <generateBuilders>true</generateBuilders>
+                        <includeGeneratedAnnotation>false</includeGeneratedAnnotation>
+                        <sourceDirectory>${project.basedir}/src/main/jsonschema</sourceDirectory>
+                        <outputDirectory>${project.build.directory}/generated-sources/pojo</outputDirectory>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <phase>generate-sources</phase>
+                            <goals>
+                                <goal>generate</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.apache.streams.plugins</groupId>
+                            <artifactId>streams-plugin-pojo</artifactId>
+                            <version>${project.version}</version>
+                        </dependency>
+                    </dependencies>
+                </plugin>
+                <plugin>
+                    <groupId>org.jvnet.jaxb2.maven2</groupId>
+                    <artifactId>maven-jaxb2-plugin</artifactId>
+                    <version>${jaxb2.version}</version>
+                    <configuration>
+                        <schemaDirectory>src/main/xmlschema</schemaDirectory>
+                        <generateDirectory>target/generated-sources/jaxb2</generateDirectory>
+                        <verbose>true</verbose>
+                        <debug>true</debug>
+                        <encoding>${project.build.sourceEncoding}</encoding>
+                        <forceRegenerate>true</forceRegenerate>
+                        <removeOldOutput>false</removeOldOutput>
+                    </configuration>
+                    <executions>
+                        <execution>
+                            <phase>generate-sources</phase>
+                            <goals>
+                                <goal>generate</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>build-helper-maven-plugin</artifactId>
+                    <executions>
+                        <execution>
+                            <id>add-schemas</id>
+                            <phase>generate-sources</phase>
+                            <goals>
+                                <goal>add-resource</goal>
+                            </goals>
+                            <configuration>
+                                <resources>
+                                    <resource>
+                                        <directory>${project.basedir}/src/main/jsonschema</directory>
+                                    </resource>
+                                </resources>
+                            </configuration>
+                        </execution>
+                        <execution>
+                            <id>add-generated-sources</id>
+                            <phase>generate-sources</phase>
+                            <goals>
+                                <goal>add-source</goal>
+                            </goals>
+                            <configuration>
+                                <sources>
+                                    <source>target/generated-sources/pojo</source>
+                                </sources>
+                            </configuration>
+                        </execution>
+                    </executions>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>${surefire.plugin.version}</version>
+                    <configuration>
+                        <!-- Skips tests if the value of skipTests property is true -->
+                        <argLine>${jvm.options}</argLine>
+                        <skipTests>${skipTests}</skipTests>
+                        <useUnlimitedThreads>true</useUnlimitedThreads>
+                        <forkCount>1</forkCount>
+                        <reuseForks>true</reuseForks>
+                        <includes>
+                            <include>**/*TestSuite.java</include>
+                        </includes>
+                        <reportFormat>xml</reportFormat>
+                    </configuration>
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.apache.maven.surefire</groupId>
+                            <artifactId>surefire-junit-platform</artifactId>
+                            <version>${surefire.version}</version>
+                        </dependency>
+                        <dependency>
+                            <groupId>org.junit.jupiter</groupId>
+                            <artifactId>junit-jupiter-engine</artifactId>
+                            <version>${junit.version}</version>
+                        </dependency>
+                        <dependency>
+                            <groupId>org.junit.platform</groupId>
+                            <artifactId>junit-platform-suite-engine</artifactId>
+                            <version>${junit.platform.version}</version>
+                        </dependency>
+                    </dependencies>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-jar-plugin</artifactId>
+                    <version>${jar.plugin.version}</version>
+                    <configuration>
+                        <skipIfEmpty>true</skipIfEmpty>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>com.googlecode.maven-download-plugin</groupId>
+                    <artifactId>download-maven-plugin</artifactId>
+                    <version>${download.plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.ops4j</groupId>
+                    <artifactId>maven-pax-plugin</artifactId>
+                    <version>${pax.plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.felix</groupId>
+                    <artifactId>maven-bundle-plugin</artifactId>
+                    <version>${bundle.plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-site-plugin</artifactId>
+                    <version>${site.plugin.version}</version>
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.apache.maven.doxia</groupId>
+                            <artifactId>doxia-module-markdown</artifactId>
+                            <version>${doxia.version}</version>
+                        </dependency>
+                        <dependency>
+                            <groupId>org.apache.maven.doxia</groupId>
+                            <artifactId>doxia-core</artifactId>
+                            <version>${doxia.version}</version>
+                        </dependency>
+                        <dependency>
+                            <groupId>org.apache.maven.doxia</groupId>
+                            <artifactId>doxia-module-xhtml</artifactId>
+                            <version>${doxia.version}</version>
+                        </dependency>
+                        <dependency>
+                            <groupId>org.apache.maven.scm</groupId>
+                            <artifactId>maven-scm-api</artifactId>
+                            <version>${scm.plugin.version}</version>
+                        </dependency>
+                        <dependency>
+                            <groupId>org.apache.maven.scm</groupId>
+                            <artifactId>maven-scm-provider-gitexe</artifactId>
+                            <version>${scm.plugin.version}</version>
+                        </dependency>
+                    </dependencies>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-scm-publish-plugin</artifactId>
+                    <version>${scmpublish.plugin.version}</version>
+                    <extensions>true</extensions>
+                    <configuration>
+                        <scmBranch>asf-site</scmBranch>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-source-plugin</artifactId>
+                    <version>${source.plugin.version}</version>
+                    <executions>
+                        <execution>
+                            <id>attach-sources</id>
+                            <goals>
+                                <goal>jar</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                </plugin>
+                <!-- Apache POM doesn't define default war-plugin version, so do it here -->
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-war-plugin</artifactId>
+                    <version>${war.plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <version>${dependency.plugin.version}</version>
+                    <executions>
+                        <execution>
+                            <id>unpack-schemas</id>
+                            <phase>generate-sources</phase>
+                            <goals>
+                                <goal>unpack-dependencies</goal>
+                            </goals>
+                            <configuration>
+                                <excludeTransitive>true</excludeTransitive>
+                                <includeGroupIds>org.apache.streams</includeGroupIds>
+                                <includeScope>compile</includeScope>
+                                <includeTypes>zip</includeTypes>
+                            </configuration>
+                        </execution>
+                        <execution>
+                            <id>unpack-test-resources</id>
+                            <phase>process-test-resources</phase>
+                            <goals>
+                                <goal>unpack-dependencies</goal>
+                            </goals>
+                            <configuration>
+                                <excludeTransitive>true</excludeTransitive>
+                                <includeGroupIds>org.apache.streams</includeGroupIds>
+                                <includeScope>test</includeScope>
+                                <includeTypes>zip</includeTypes>
+                            </configuration>
+                        </execution>
+                    </executions>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-shade-plugin</artifactId>
+                    <version>${shade.plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>com.github.ferstl</groupId>
+                    <artifactId>depgraph-maven-plugin</artifactId>
+                    <version>${depgraph.plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>io.fabric8</groupId>
+                    <artifactId>docker-maven-plugin</artifactId>
+                    <version>${docker.plugin.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>net.alchim31.maven</groupId>
+                    <artifactId>scala-maven-plugin</artifactId>
+                    <version>${scala.plugin.version}</version>
+                    <executions>
+                        <execution>
+                            <id>default-compile</id>
+                            <phase>compile</phase>
+                            <goals>
+                                <goal>compile</goal>
+                            </goals>
+                        </execution>
+                        <execution>
+                            <id>default-testCompile</id>
+                            <phase>test-compile</phase>
+                            <goals>
+                                <goal>testCompile</goal>
+                            </goals>
+                        </execution>
+                    </executions>
+                    <configuration>
+                        <args>
+                            <arg>-J--add-opens=java.base/java.io=ALL-UNNAMED</arg>
+                            <arg>-J--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED</arg>
+                        </args>
+                        <scalaVersion>${scala.version}</scalaVersion>
+                        <recompileMode>all</recompileMode>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.scala-lang</groupId>
+            <artifactId>scala3-library_3</artifactId>
+            <version>${scala.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>${logback.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.awaitility</groupId>
+            <artifactId>awaitility-scala</artifactId>
+            <version>${awaitility.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-suite-engine</artifactId>
+            <version>${junit.platform.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <dependencyManagement>
+    <dependencies>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+            <version>${protobuf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>${commons-codec.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>${commons-io.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-text</artifactId>
+            <version>${commons-text.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+            <version>${commons-collections4.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-validator</groupId>
+            <artifactId>commons-validator</artifactId>
+            <version>${commons-validator.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>${commons-lang3.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+            <version>${httpcomponents.core.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+            <version>${httpcomponents.client.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.juneau</groupId>
+            <artifactId>juneau-marshall</artifactId>
+            <version>${juneau.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.juneau</groupId>
+            <artifactId>juneau-marshall-rdf</artifactId>
+            <version>${juneau.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.juneau</groupId>
+            <artifactId>juneau-rest-client</artifactId>
+            <version>${juneau.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.juneau</groupId>
+            <artifactId>juneau-rest-server</artifactId>
+            <version>${juneau.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.juneau</groupId>
+            <artifactId>juneau-svl</artifactId>
+            <version>${juneau.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-core</artifactId>
+            <version>3.0.0-M4</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-impl</artifactId>
+            <version>3.0.0-M4</version>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe</groupId>
+            <artifactId>config</artifactId>
+            <version>${typesafe.config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.activation</groupId>
+            <artifactId>javax.activation</artifactId>
+            <version>1.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+            <version>2.4.0-b180830.0359</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+            <version>1.3.2</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+            <version>2.0.1.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>org.reflections</groupId>
+            <artifactId>reflections</artifactId>
+            <version>${reflections.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.freemarker</groupId>
+            <artifactId>freemarker</artifactId>
+            <version>${freemarker.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>net.sourceforge.fmpp</groupId>
+            <artifactId>fmpp</artifactId>
+            <version>${fmpp.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.avro</groupId>
+            <artifactId>avro</artifactId>
+            <version>${avro.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest</artifactId>
+            <version>${hamcrest.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.networknt</groupId>
+            <artifactId>json-schema-validator</artifactId>
+            <version>${json-schema-validator.version}</version>
+            <type>jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-inline</artifactId>
+            <version>${mockito.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-core</artifactId>
+            <version>${powermock.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+            <version>${powermock.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito2</artifactId>
+            <version>${powermock.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>${slf4j.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>${slf4j.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>log4j-over-slf4j</artifactId>
+            <version>${slf4j.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <version>${slf4j.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>${log4j.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+            <version>${logback.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>${logback.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>${guava.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+            <version>${netty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>${joda-time.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.joda</groupId>
+            <artifactId>joda-convert</artifactId>
+            <version>${joda-convert.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.fasterxml.jackson.datatype</groupId>-->
+<!--            <artifactId>jackson-datatype-joda</artifactId>-->
+<!--            <version>${jackson.version}</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>com.fasterxml.jackson.module</groupId>-->
+<!--            <artifactId>jackson-module-scala_${scala.binary.version}</artifactId>-->
+<!--            <version>${jackson.version}</version>-->
+<!--        </dependency>-->
+        <dependency>
+            <groupId>com.fasterxml.jackson.dataformat</groupId>
+            <artifactId>jackson-dataformat-xml</artifactId>
+            <version>${jackson.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>stax2-api</artifactId>
+                    <groupId>org.codehaus.woodstox</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.dataformat</groupId>
+            <artifactId>jackson-dataformat-yaml</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.module</groupId>
+            <artifactId>jackson-module-jaxb-annotations</artifactId>
+            <version>${jackson.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml</groupId>
+            <artifactId>aalto-xml</artifactId>
+            <version>${aalto.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>nz.net.ultraq.jaxb</groupId>
+            <artifactId>jaxb-utilities</artifactId>
+            <version>${jaxbutil.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.jayway.jsonpath</groupId>
+            <artifactId>json-path</artifactId>
+            <version>${json-path.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.jayway.jsonpath</groupId>
+            <artifactId>json-path-assert</artifactId>
+            <version>${json-path.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.zookeeper</groupId>
+            <artifactId>zookeeper</artifactId>
+            <version>${zookeeper.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>log4j</groupId>
+                    <artifactId>log4j</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-aether-provider</artifactId>
+            <version>${maven-aether-provider.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-resources-plugin</artifactId>
+            <version>${resources.plugin.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.maven</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-artifact</artifactId>
+            <version>${maven-plugin.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-compat</artifactId>
+            <version>${maven-plugin.version}</version>
+<!--            <scope>test</scope>-->
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.shared</groupId>
+            <artifactId>maven-verifier</artifactId>
+            <version>${maven-verifier.version}</version>
+<!--            <scope>test</scope>-->
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-core</artifactId>
+            <version>${maven-plugin.version}</version>
+            <scope>provided</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.sonatype.aether</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-plugin-plugin</artifactId>
+            <version>${maven-plugin-plugin.version}</version>
+            <scope>provided</scope>
+            <exclusions>
+                <exclusion>
+                    <artifactId>commons-logging</artifactId>
+                    <groupId>commons-logging</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-plugin-api</artifactId>
+            <version>${maven-plugin.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugin-tools</groupId>
+            <artifactId>maven-plugin-tools-api</artifactId>
+            <version>${maven-plugin-tools.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugin-tools</groupId>
+            <artifactId>maven-plugin-annotations</artifactId>
+            <version>${maven-plugin-tools.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugin-tools</groupId>
+            <artifactId>maven-plugin-tools-generators</artifactId>
+            <version>${maven-plugin-tools.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugin-testing</groupId>
+            <artifactId>maven-plugin-testing-harness</artifactId>
+            <version>${maven-plugin-testing.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    </dependencyManagement>
+
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <version>${checkstyle.plugin.version}</version>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>checkstyle</report>
+                            <report>checkstyle-aggregate</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <version>${reports.plugin.version}</version>
+                <configuration>
+                    <customBundle>${project.basedir}/src/site/custom/project-info-report.properties</customBundle>
+                    <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
+                    <skipEmptyReport>false</skipEmptyReport>
+                </configuration>
+                <reportSets>
+                    <reportSet>
+                        <inherited>false</inherited>
+                        <reports>
+                            <report>index</report>
+                            <report>modules</report>
+                            <report>license</report>
+                            <report>mailing-list</report>
+                            <report>project-team</report>
+                            <report>scm</report>
+                            <report>issue-tracking</report>
+                            <report>dependencies</report>
+                            <report>dependency-info</report>
+                            <report>dependency-management</report>
+                            <report>distribution-management</report>
+                            <report>plugin-management</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>license-maven-plugin</artifactId>
+                <version>${license.plugin.version}</version>
+                <configuration>
+                    <excludedGroups>org.apache.streams,org.apache.streams.plugins</excludedGroups>
+                    <missingFile>${project.basedir}/src/license/THIRD-PARTY.properties</missingFile>
+                    <useMissingFile>true</useMissingFile>
+                </configuration>
+                <reportSets>
+                    <reportSet>
+                        <inherited>false</inherited>
+                        <reports>
+                            <report>aggregate-third-party-report</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+            <plugin>
+                <artifactId>maven-site-plugin</artifactId>
+                <version>${site.plugin.version}</version>
+                <configuration>
+                    <generateSitemap>true</generateSitemap>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>com.github.ferstl</groupId>
+                <artifactId>depgraph-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>${javadoc.plugin.version}</version>
+                <configuration>
+                    <additionalOptions>-Xdoclint:none</additionalOptions>
+<!--                    <aggregate>false</aggregate>-->
+                    <failOnError>false</failOnError>
+                    <minmemory>128m</minmemory>
+                    <maxmemory>1g</maxmemory>
+                    <docfilessubdirs />
+                </configuration>
+                <reportSets>
+                    <reportSet>
+                        <reports>
+                            <report>javadoc-no-fork</report>
+                            <report>test-javadoc-no-fork</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+            <plugin>
+                <artifactId>maven-source-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </reporting>
+
+    <profiles>
+        <profile>
+            <id>java-11</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+                <jdk>(11,)</jdk>
+            </activation>
+            <properties>
+                <java.version>11</java.version>
+                <maven.compiler.source>${java.version}</maven.compiler.source>
+                <maven.compiler.target>${java.version}</maven.compiler.target>
+                <maven.compiler.release>${java.version}</maven.compiler.release>
+            </properties>
+        </profile>
+        <profile>
+            <id>java-17</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+                <jdk>(17,)</jdk>
+            </activation>
+            <properties>
+                <java.version>17</java.version>
+                <maven.compiler.source>${java.version}</maven.compiler.source>
+                <maven.compiler.target>${java.version}</maven.compiler.target>
+                <maven.compiler.release>${java.version}</maven.compiler.release>
+            </properties>
+        </profile>
+        <profile>
+            <id>apache-release</id>
+            <properties>
+                <skipTests>false</skipTests>
+                <maven.test.skip>false</maven.test.skip>
+            </properties>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-source-plugin</artifactId>
+                        <version>${source.plugin.version}</version>
+                        <configuration>
+                            <skipSource>true</skipSource>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>attach-sources</id>
+                                <goals>
+                                    <goal>jar-no-fork</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-jar-plugin</artifactId>
+                        <configuration>
+                            <skip>false</skip>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>test-jar</id>
+                                <goals>
+                                    <goal>test-jar</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <dependencies>
+                            <dependency>
+                                <groupId>org.apache.apache.resources</groupId>
+                                <artifactId>apache-source-release-assembly-descriptor</artifactId>
+                                <version>1.0.6</version>
+                            </dependency>
+                        </dependencies>
+                        <executions>
+                            <execution>
+                                <id>source-release-assembly</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <configuration>
+                                    <runOnlyAtExecutionRoot>true</runOnlyAtExecutionRoot>
+                                    <descriptorRefs>
+                                        <descriptorRef>source-release</descriptorRef>
+                                    </descriptorRefs>
+                                    <tarLongFileMode>gnu</tarLongFileMode>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-release-plugin</artifactId>
+                        <configuration>
+                            <releaseProfiles>apache-release</releaseProfiles>
+                            <preparationGoals>clean install</preparationGoals>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <argLine>--add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED</argLine>
+                            <skipTests>${skipTests}</skipTests>
+                            <skipExec>${skipExec}</skipExec>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+            <reporting>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.rat</groupId>
+                        <artifactId>apache-rat-plugin</artifactId>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-project-info-reports-plugin</artifactId>
+                        <configuration>
+                            <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-javadoc-plugin</artifactId>
+                        <reportSets>
+                            <reportSet>
+                                <id>aggregate</id>
+                                <reports>
+                                    <report>javadoc-no-fork</report>
+                                    <report>test-javadoc-no-fork</report>
+                                    <report>aggregate</report>
+                                </reports>
+                            </reportSet>
+                            <reportSet>
+                                <id>html</id>
+                                <reports>
+                                    <report>javadoc</report>
+                                </reports>
+                            </reportSet>
+                        </reportSets>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-site-plugin</artifactId>
+                    </plugin>
+                    <plugin>
+                        <groupId>com.github.ferstl</groupId>
+                        <artifactId>depgraph-maven-plugin</artifactId>
+                        <version>${depgraph.plugin.version}</version>
+                    </plugin>
+                </plugins>
+            </reporting>
+        </profile>
+        <profile>
+            <id>check</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-enforcer-plugin</artifactId>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.rat</groupId>
+                        <artifactId>apache-rat-plugin</artifactId>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-checkstyle-plugin</artifactId>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.scalastyle</groupId>
+                        <artifactId>scalastyle-maven-plugin</artifactId>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>license-maven-plugin</artifactId>
+                    </plugin>
+                </plugins>
+                <pluginManagement>
+                    <plugins>
+                        <plugin>
+                            <groupId>org.apache.maven.plugins</groupId>
+                            <artifactId>maven-enforcer-plugin</artifactId>
+                            <version>${enforcer.plugin.version}</version>
+                            <executions>
+                                <execution>
+                                    <id>enforce-java</id>
+                                    <goals>
+                                        <goal>enforce</goal>
+                                    </goals>
+                                    <configuration>
+                                        <rules>
+                                            <requireJavaVersion>
+                                                <message>Java ${java.version} or higher is required to compile this module</message>
+                                                <version>[${java.version},)</version>
+                                            </requireJavaVersion>
+                                            <requireMavenVersion>
+                                                <message>${maven.version} or higher is required to compile this module</message>
+                                                <version>[${maven.version},)</version>
+                                            </requireMavenVersion>
+                                        </rules>
+                                    </configuration>
+                                </execution>
+                                <execution>
+                                    <id>enforce-banned-dependencies</id>
+                                    <goals>
+                                        <goal>enforce</goal>
+                                    </goals>
+                                    <configuration>
+                                        <rules>
+                                            <bannedDependencies>
+                                                <excludes>
+                                                    <exclude>org.slf4j:slf4j-log4j12:*:jar:compile</exclude>
+                                                    <exclude>org.slf4j:slf4j-jcl:*:jar:compile</exclude>
+                                                    <exclude>org.slf4j:slf4j-jdk14:*:jar:compile</exclude>
+                                                    <exclude>org.log4j:log4j:*:jar:compile</exclude>
+                                                    <exclude>commons-logging:commons-logging:*:jar:compile</exclude>
+                                                </excludes>
+                                            </bannedDependencies>
+                                        </rules>
+                                        <fail>true</fail>
+                                    </configuration>
+                                </execution>
+                                <execution>
+                                    <id>enforce-no-snapshots</id>
+                                    <goals>
+                                        <goal>enforce</goal>
+                                    </goals>
+                                    <configuration>
+                                        <rules>
+                                            <requireReleaseDeps>
+                                                <message>No Snapshots Allowed!</message>
+                                                <excludes>
+                                                    <exclude>org.apache.streams:*</exclude>
+                                                    <exclude>org.apache.streams.*:*</exclude>
+                                                </excludes>
+                                                <failWhenParentIsSnapshot>false</failWhenParentIsSnapshot>
+                                                <onlyWhenRelease>true</onlyWhenRelease>
+                                            </requireReleaseDeps>
+                                        </rules>
+                                        <fail>true</fail>
+                                    </configuration>
+                                </execution>
+                            </executions>
+                        </plugin>
+                        <plugin>
+                            <groupId>org.apache.rat</groupId>
+                            <artifactId>apache-rat-plugin</artifactId>
+                            <version>${apache-rat.plugin.version}</version>
+                            <executions>
+                                <execution>
+                                    <phase>validate</phase>
+                                    <goals>
+                                        <goal>check</goal>
+                                    </goals>
+                                </execution>
+                            </executions>
+                            <configuration>
+                                <excludes>
+                                    <exclude>.git</exclude>
+                                    <exclude>.git/**</exclude>
+                                    <exclude>.idea/**</exclude>
+                                    <exclude>.java-version</exclude>
+                                    <exclude>*.conf</exclude>
+                                    <exclude>*.properties</exclude>
+                                    <exclude>**/.gitignore</exclude>
+                                    <exclude>**/*.iml</exclude>
+                                    <exclude>**/*.ini</exclude>
+                                    <exclude>**/*.jar</exclude>
+                                    <exclude>**/*.svg</exclude>
+                                    <exclude>**/MANIFEST.MF</exclude>
+                                    <exclude>**/src/test/resources/*</exclude>
+                                    <exclude>**/src/site/resources/**/*</exclude>
+                                    <exclude>**/target/**</exclude>
+                                    <exclude>apache-maven-*/**/*</exclude>
+                                    <exclude>**/src/license/*</exclude>
+                                    <exclude>**/src/license/licenses/*</exclude>
+                                </excludes>
+                            </configuration>
+                        </plugin>
+                        <plugin>
+                            <groupId>org.codehaus.mojo</groupId>
+                            <artifactId>license-maven-plugin</artifactId>
+                            <version>${license.plugin.version}</version>
+                            <configuration>
+                                <acceptPomPackaging>true</acceptPomPackaging>
+                                <excludedGroups>^org.apache.streams.*</excludedGroups>
+                                <failOnBlacklist>true</failOnBlacklist>
+                                <failOnMissing>true</failOnMissing>
+                                <licenseMergesUrl>file://${session.executionRootDirectory}/src/license/licenseMerges.txt</licenseMergesUrl>
+                                <missingFile>${session.executionRootDirectory}/src/license/licenseMissingFile.properties</missingFile>
+                                <outputDirectory>src/license</outputDirectory>
+                                <thirdPartyFilename>THIRD-PARTY.txt</thirdPartyFilename>
+                                <useMissingFile>true</useMissingFile>
+                            </configuration>
+                            <executions>
+                                <execution>
+                                    <id>aggregate-add-third-party</id>
+                                    <phase>validate</phase>
+                                    <goals>
+                                        <goal>aggregate-add-third-party</goal>
+                                    </goals>
+                                </execution>
+                                <execution>
+                                    <id>aggregate-download-licenses</id>
+                                    <phase>validate</phase>
+                                    <goals>
+                                        <goal>aggregate-download-licenses</goal>
+                                    </goals>
+                                </execution>
+                            </executions>
+                        </plugin>
+                        <plugin>
+                            <groupId>org.apache.maven.plugins</groupId>
+                            <artifactId>maven-checkstyle-plugin</artifactId>
+                            <version>${checkstyle.plugin.version}</version>
+                            <dependencies>
+                                <dependency>
+                                    <groupId>com.puppycrawl.tools</groupId>
+                                    <artifactId>checkstyle</artifactId>
+                                    <version>8.18</version>
+                                </dependency>
+                            </dependencies>
+                            <executions>
+                                <execution>
+                                    <id>validate</id>
+                                    <phase>validate</phase>
+                                    <configuration>
+                                        <configLocation>src/main/resources/streams-java-checkstyle.xml</configLocation>
+                                        <inputEncoding>UTF-8</inputEncoding>
+                                        <consoleOutput>true</consoleOutput>
+                                        <includeTestSourceDirectory>true</includeTestSourceDirectory>
+                                        <testSourceDirectories>${project.basedir}/src/test/java</testSourceDirectories>
+                                        <failsOnError>false</failsOnError>
+                                    </configuration>
+                                    <goals>
+                                        <goal>check</goal>
+                                    </goals>
+                                </execution>
+                            </executions>
+                        </plugin>
+                        <plugin>
+                            <groupId>org.scalastyle</groupId>
+                            <artifactId>scalastyle-maven-plugin</artifactId>
+                            <version>${scalastyle.plugin.version}</version>
+                            <executions>
+                                <execution>
+                                    <id>validate</id>
+                                    <phase>validate</phase>
+                                    <configuration>
+                                        <verbose>false</verbose>
+                                        <failOnViolation>false</failOnViolation>
+                                        <includeTestSourceDirectory>true</includeTestSourceDirectory>
+                                        <failOnWarning>false</failOnWarning>
+                                        <sourceDirectory>${project.basedir}/src/main/scala</sourceDirectory>
+                                        <testSourceDirectory>${project.basedir}/src/test/scala</testSourceDirectory>
+                                        <!--<configLocation>https://raw.githubusercontent.com/databricks/sbt-databricks/master/scalastyle-config.xml</configLocation>-->
+                                        <outputFile>${project.build.directory}/scalastyle-output.xml</outputFile>
+                                        <outputEncoding>UTF-8</outputEncoding>
+                                    </configuration>
+                                    <goals>
+                                        <goal>check</goal>
+                                    </goals>
+                                </execution>
+                            </executions>
+                        </plugin>
+                    </plugins>
+                </pluginManagement>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/streams-activitypub-actors/pom.xml b/streams-activitypub-actors/pom.xml
new file mode 100755
index 0000000..39a30c7
--- /dev/null
+++ b/streams-activitypub-actors/pom.xml
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>apache-streams-activitypub</artifactId>
+        <groupId>org.apache.streams.activitypub</groupId>
+        <version>0.8.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>streams-activitypub-actors</artifactId>
+    <description>Apache Streams Actors</description>
+    <name>${project.artifactId}</name>
+    <packaging>jar</packaging>
+
+    <properties>
+        <pekko.version>1.0.1</pekko.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.streams</groupId>
+            <artifactId>streams-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- streams-actors only dependencies -->
+        <dependency>
+            <groupId>org.apache.pekko</groupId>
+            <artifactId>pekko-actor-typed_${scala.binary.version}</artifactId>
+            <version>${pekko.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.pekko</groupId>
+            <artifactId>pekko-actor-testkit-typed_${scala.binary.version}</artifactId>
+            <version>${pekko.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.streams</groupId>
+            <artifactId>streams-testing</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+            <type>test-jar</type>
+        </dependency>
+    </dependencies>
+    <build>
+        <sourceDirectory>src/main/scala</sourceDirectory>
+        <testSourceDirectory>src/test/scala</testSourceDirectory>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+        </resources>
+        <testResources>
+            <testResource>
+                <directory>src/test/resources</directory>
+            </testResource>
+        </testResources>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>add-source</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-resource</goal>
+                        </goals>
+                        <configuration>
+                            <resources>
+                                <resource>
+                                    <directory>${project.basedir}/src/main/jsonschema</directory>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/streams-activitypub-api/pom.xml b/streams-activitypub-api/pom.xml
new file mode 100755
index 0000000..a759d5f
--- /dev/null
+++ b/streams-activitypub-api/pom.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>apache-streams-activitypub</artifactId>
+        <groupId>org.apache.streams.activitypub</groupId>
+        <version>0.8.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>streams-activitypub-api</artifactId>
+    <description>Apache Streams ActivityPub Server APIs</description>
+    <name>${project.artifactId}</name>
+    <packaging>jar</packaging>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.streams</groupId>
+            <artifactId>streams-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- streams-api only dependencies -->
+        <dependency>
+            <groupId>org.apache.juneau</groupId>
+            <artifactId>juneau-rest-common</artifactId>
+            <version>${juneau.version}</version>
+        </dependency>
+
+    </dependencies>
+    <build>
+        <sourceDirectory>src/main/scala</sourceDirectory>
+        <testSourceDirectory>src/test/scala</testSourceDirectory>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+        </resources>
+        <testResources>
+            <testResource>
+                <directory>src/test/resources</directory>
+            </testResource>
+        </testResources>
+        <plugins>
+            <plugin>
+                <groupId>net.alchim31.maven</groupId>
+                <artifactId>scala-maven-plugin</artifactId>
+                <configuration>
+                    <source>${project.basedir}/src/main/scala</source>
+                    <scalaVersion>${scala.version}</scalaVersion>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.jsonschema2pojo</groupId>
+                <artifactId>jsonschema2pojo-maven-plugin</artifactId>
+                <version>1.2.1</version>
+                <executions>
+                    <execution>
+                        <id>generate-sources</id>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                        <phase>generate-sources</phase>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/streams-activitypub-api/src/main/jsonschema/org/apache/streams/activitypub/api/pojo/WebfingerQueryRequest.json b/streams-activitypub-api/src/main/jsonschema/org/apache/streams/activitypub/api/pojo/WebfingerQueryRequest.json
new file mode 100755
index 0000000..507de49
--- /dev/null
+++ b/streams-activitypub-api/src/main/jsonschema/org/apache/streams/activitypub/api/pojo/WebfingerQueryRequest.json
@@ -0,0 +1,22 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema",
+  "id": "#",
+  "type": "object",
+  "javaType": "org.apache.streams.activitypub.api.pojo.WebfingerQueryRequest",
+  "javaInterfaces": [
+    "java.io.Serializable"
+  ],
+  "properties": {
+    "resource": {
+      "type": "string"
+    },
+    "rel": {
+      "type": "array",
+      "required": false,
+      "items": {
+        "type": "string",
+        "format": "uri"
+      }
+    }
+  }
+}
diff --git a/streams-activitypub-api/src/main/jsonschema/org/apache/streams/activitypub/api/pojo/WebfingerQueryResponse.json b/streams-activitypub-api/src/main/jsonschema/org/apache/streams/activitypub/api/pojo/WebfingerQueryResponse.json
new file mode 100755
index 0000000..cbd0c72
--- /dev/null
+++ b/streams-activitypub-api/src/main/jsonschema/org/apache/streams/activitypub/api/pojo/WebfingerQueryResponse.json
@@ -0,0 +1,56 @@
+{
+  "$schema": "http://json-schema.org/draft-07/schema",
+  "id": "#",
+  "type": "object",
+  "$license": [
+    "http://www.apache.org/licenses/LICENSE-2.0"
+  ],
+  "javaType" : "org.apache.streams.activitypub.api.pojo.WebfingerQueryResponse",
+  "javaInterfaces": ["java.io.Serializable"],
+  "properties": {
+    "subject": {
+      "type": "string"
+    },
+    "aliases": {
+      "type": "array",
+      "items": {
+        "type": "string",
+        "format": "uri"
+      }
+    },
+    "properties": {
+      "type": "object",
+      "additionalProperties": {
+        "type": "string"
+      }
+    },
+    "links": {
+      "type": "array",
+      "required": false,
+      "items": {
+        "type": "object",
+        "properties": {
+          "rel": {
+            "type": "string",
+            "required": false
+          },
+          "type": {
+            "type": "string",
+            "required": false
+          },
+          "href": {
+            "type": "string",
+            "format": "uri",
+            "required": false
+          },
+          "titles": {
+            "type": "object",
+            "additionalProperties": {
+              "type": "string"
+            }
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/streams-activitypub-api/src/main/scala/org/apache/streams/activitypub/api/WebfingerApi.scala b/streams-activitypub-api/src/main/scala/org/apache/streams/activitypub/api/WebfingerApi.scala
new file mode 100755
index 0000000..b7cd4d7
--- /dev/null
+++ b/streams-activitypub-api/src/main/scala/org/apache/streams/activitypub/api/WebfingerApi.scala
@@ -0,0 +1,10 @@
+package org.apache.streams.activitypub.api
+
+import org.apache.streams.activitypub.api.pojo.WebfingerQueryRequest
+import org.apache.streams.activitypub.api.pojo.WebfingerQueryResponse
+
+trait WebfingerApi {
+
+  def webfingerQuery(request: WebfingerQueryRequest): WebfingerQueryResponse;
+
+}
diff --git a/streams-activitypub-api/streams-api.iml b/streams-activitypub-api/streams-api.iml
new file mode 100755
index 0000000..944f78b
--- /dev/null
+++ b/streams-activitypub-api/streams-api.iml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module version="4">
+  <component name="AdditionalModuleElements">
+    <content url="file://$MODULE_DIR$" dumb="true">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/jsonschema" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/target/generated-sources/pojo" isTestSource="false" />
+    </content>
+  </component>
+</module>
\ No newline at end of file
diff --git a/streams-activitypub-dist/Dockerfile b/streams-activitypub-dist/Dockerfile
new file mode 100644
index 0000000..28f42c0
--- /dev/null
+++ b/streams-activitypub-dist/Dockerfile
@@ -0,0 +1,5 @@
+FROM tomcat:jre17-temurin
+MAINTAINER dev@streams.apache.org
+LABEL Description="apache-streams-activitypub-dist"
+WORKDIR /
+ADD target/exploded /usr/local/tomcat/webapps/ROOT
diff --git a/streams-activitypub-dist/docker-compose.yml b/streams-activitypub-dist/docker-compose.yml
new file mode 100644
index 0000000..bd3ac9b
--- /dev/null
+++ b/streams-activitypub-dist/docker-compose.yml
@@ -0,0 +1,9 @@
+version: "2.4"
+services:
+  streams-activitypub:
+    image: apache/streams-activitypub-webapp
+    build:
+      context: "."
+      dockerfile: Dockerfile
+    ports:
+      - "8080:8080"
diff --git a/streams-activitypub-dist/pom.xml b/streams-activitypub-dist/pom.xml
new file mode 100755
index 0000000..3616898
--- /dev/null
+++ b/streams-activitypub-dist/pom.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+  http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.streams.activitypub</groupId>
+        <artifactId>apache-streams-activitypub</artifactId>
+        <version>0.8.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>streams-activitypub-dist</artifactId>
+    <name>streams-activitypub-dist</name>
+    <packaging>docker</packaging>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.streams.activitypub</groupId>
+            <artifactId>streams-activitypub-webapp</artifactId>
+            <version>${project.version}</version>
+            <type>war</type>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+       <plugins>
+           <plugin>
+               <groupId>org.apache.maven.plugins</groupId>
+               <artifactId>maven-dependency-plugin</artifactId>
+               <executions>
+                   <execution>
+                       <id>unpack</id>
+                       <phase>prepare-package</phase>
+                       <goals>
+                           <goal>unpack</goal>
+                       </goals>
+                       <configuration>
+                           <outputDirectory>${project.build.directory}/exploded</outputDirectory>
+                           <artifactItems>
+                               <artifactItem>
+                                   <groupId>org.apache.streams.activitypub</groupId>
+                                   <artifactId>streams-activitypub-webapp</artifactId>
+                                   <version>${project.version}</version>
+                                   <type>war</type>
+                               </artifactItem>
+                           </artifactItems>
+                       </configuration>
+                   </execution>
+               </executions>
+           </plugin>
+            <plugin>
+                <groupId>io.fabric8</groupId>
+                <artifactId>docker-maven-plugin</artifactId>
+                <version>${docker.plugin.version}</version>
+                <extensions>true</extensions>
+                <executions>
+                    <execution>
+                        <id>package</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>build</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>deploy</id>
+                        <phase>deploy</phase>
+                        <goals>
+                            <goal>push</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration combine.self="override">
+                    <autoPull>on</autoPull>
+                    <images>
+                        <image>
+                            <external>
+                                <type>compose</type>
+                                <basedir>.</basedir>
+                                <composeFile>docker-compose.yml</composeFile>
+                            </external>
+                        </image>
+                    </images>
+                    <logDate>default</logDate>
+                    <verbose>true</verbose>
+                    <watchInterval>500</watchInterval>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/streams-activitypub-dist/src/main/assembly/assembly-dist.xml b/streams-activitypub-dist/src/main/assembly/assembly-dist.xml
new file mode 100644
index 0000000..b7b062c
--- /dev/null
+++ b/streams-activitypub-dist/src/main/assembly/assembly-dist.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <id>dist</id>
+    <formats>
+        <format>zip</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <fileSets>
+        <fileSet>
+            <directory>target/dist</directory>
+            <outputDirectory>/</outputDirectory>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/streams-activitypub-remote/pom.xml b/streams-activitypub-remote/pom.xml
new file mode 100755
index 0000000..19ffa4f
--- /dev/null
+++ b/streams-activitypub-remote/pom.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>apache-streams-activitypub</artifactId>
+        <groupId>org.apache.streams.activitypub</groupId>
+        <version>0.8.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>streams-activitypub-remote</artifactId>
+    <description>Apache Streams Remoting</description>
+    <name>${project.artifactId}</name>
+    <packaging>jar</packaging>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.streams.activitypub</groupId>
+            <artifactId>streams-activitypub-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- streams-remote only dependencies -->
+        <dependency>
+            <groupId>org.apache.juneau</groupId>
+            <artifactId>juneau-rest-client</artifactId>
+            <version>${juneau.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.streams</groupId>
+            <artifactId>streams-testing</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+            <type>test-jar</type>
+        </dependency>
+    </dependencies>
+    <build>
+        <sourceDirectory>src/main/scala</sourceDirectory>
+<!--        <resources>-->
+<!--            <resource>-->
+<!--                <directory>src/main/resources</directory>-->
+<!--            </resource>-->
+<!--        </resources>-->
+<!--        <testResources>-->
+<!--            <testResource>-->
+<!--                <directory>src/test/resources</directory>-->
+<!--            </testResource>-->
+<!--        </testResources>-->
+        <plugins>
+            <plugin>
+                <groupId>net.alchim31.maven</groupId>
+                <artifactId>scala-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>scala-compile</id>
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <addScalacArgs>--explain</addScalacArgs>
+                    <scalaVersion>${scala.version}</scalaVersion>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/streams-activitypub-remote/src/main/scala/org/apache/streams/activitypub/remote/WebfingerRest.scala b/streams-activitypub-remote/src/main/scala/org/apache/streams/activitypub/remote/WebfingerRest.scala
new file mode 100644
index 0000000..01fbd29
--- /dev/null
+++ b/streams-activitypub-remote/src/main/scala/org/apache/streams/activitypub/remote/WebfingerRest.scala
@@ -0,0 +1,16 @@
+package org.apache.streams.activitypub.remote
+
+import org.apache.juneau.annotation.Bean
+import org.apache.juneau.http.remote.Remote
+import org.apache.juneau.http.remote.RemoteGet
+import org.apache.streams.activitypub.api.WebfingerApi
+import org.apache.streams.activitypub.api.pojo.WebfingerQueryRequest
+import org.apache.streams.activitypub.api.pojo.WebfingerQueryResponse
+
+@Remote
+trait WebfingerRest extends WebfingerApi {
+
+  @RemoteGet(path="/.well-known/webfinger")
+  def webfingerQuery(@Bean request: WebfingerQueryRequest): WebfingerQueryResponse;
+
+}
diff --git a/streams-activitypub-servlets/pom.xml b/streams-activitypub-servlets/pom.xml
new file mode 100755
index 0000000..1d67334
--- /dev/null
+++ b/streams-activitypub-servlets/pom.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>apache-streams-activitypub</artifactId>
+        <groupId>org.apache.streams.activitypub</groupId>
+        <version>0.8.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>streams-activitypub-servlets</artifactId>
+    <name>${project.artifactId}</name>
+
+    <description>Apache Streams Resource Classes (Servlets)</description>
+
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.streams.activitypub</groupId>
+            <artifactId>streams-activitypub-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.streams</groupId>
+            <artifactId>streams-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.streams.activitypub</groupId>
+            <artifactId>streams-activitypub-remote</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.juneau</groupId>
+            <artifactId>juneau-rest-server</artifactId>
+            <version>${juneau.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.ws.rs</groupId>
+            <artifactId>jakarta.ws.rs-api</artifactId>
+            <version>${jakarta-ws.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.servlet</groupId>
+            <artifactId>jakarta.servlet-api</artifactId>
+            <version>${jakarta.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <!-- Thanks for using https://jar-download.com -->
+
+        <!-- streams-servlets test dependencies -->
+        <dependency>
+            <groupId>org.apache.juneau</groupId>
+            <artifactId>juneau-rest-mock</artifactId>
+            <version>${juneau.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <sourceDirectory>src/main/scala</sourceDirectory>
+        <testSourceDirectory>src/test/scala</testSourceDirectory>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+        </resources>
+        <testResources>
+            <testResource>
+                <directory>src/test/resources</directory>
+            </testResource>
+        </testResources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>jar</goal>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/streams-activitypub-servlets/src/main/scala/org/apache/streams/activitypub/servlets/RootServlet.scala b/streams-activitypub-servlets/src/main/scala/org/apache/streams/activitypub/servlets/RootServlet.scala
new file mode 100755
index 0000000..a2ce1d8
--- /dev/null
+++ b/streams-activitypub-servlets/src/main/scala/org/apache/streams/activitypub/servlets/RootServlet.scala
@@ -0,0 +1,27 @@
+package org.apache.streams.activitypub.servlets
+
+import jakarta.servlet.ServletConfig
+import org.apache.juneau.rest.RestRequest
+import org.apache.juneau.rest.annotation.Rest
+import org.apache.juneau.rest.beans.ChildResourceDescriptions
+import org.apache.juneau.rest.servlet.BasicRestServletGroup
+
+/**
+ * RootResource responds to requests to the root of the microservice.
+ */
+
+@Rest(
+  path = "/",
+  title=Array("Apache Streams ActivityPub Server"),
+  description=Array("Top-level resources page"),
+  children = Array(
+    classOf[WebfingerServlet]
+  )
+)
+class RootServlet extends BasicRestServletGroup {
+
+  override def init(servletConfig: ServletConfig) : Unit = {
+    super.init(servletConfig)
+  }
+  
+}
diff --git a/streams-activitypub-servlets/src/main/scala/org/apache/streams/activitypub/servlets/WebfingerServlet.scala b/streams-activitypub-servlets/src/main/scala/org/apache/streams/activitypub/servlets/WebfingerServlet.scala
new file mode 100755
index 0000000..cf7fb7d
--- /dev/null
+++ b/streams-activitypub-servlets/src/main/scala/org/apache/streams/activitypub/servlets/WebfingerServlet.scala
@@ -0,0 +1,126 @@
+package org.apache.streams.activitypub.servlets;
+
+import jakarta.servlet.ServletConfig
+import org.apache.commons.collections4.CollectionUtils
+import org.apache.commons.lang3.StringUtils
+import org.apache.juneau.html.HtmlSerializer
+import org.apache.juneau.http.annotation.Query
+import org.apache.juneau.json.JsonSerializer
+import org.apache.juneau.rest.RestRequest
+import org.apache.juneau.rest.RestResponse
+import org.apache.juneau.rest.annotation.Rest
+import org.apache.juneau.rest.annotation.RestGet
+import org.apache.juneau.rest.matcher.RestMatcher
+import org.apache.juneau.rest.servlet.BasicRestServlet
+import jakarta.ws.rs.core.MediaType
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
+import org.apache.http.client.utils.URIBuilder
+import org.apache.juneau.rest.httppart.RequestQueryParams
+import org.apache.streams.activitypub.api.pojo.Link
+import org.apache.streams.activitypub.api.pojo.Properties
+import org.apache.streams.activitypub.api.pojo.WebfingerQueryRequest
+import org.apache.streams.activitypub.api.pojo.WebfingerQueryResponse
+import org.apache.streams.activitypub.remote.WebfingerRest
+
+import java.util.ArrayList
+import java.net.URI
+import java.util.Optional
+import scala.collection.mutable.Buffer
+import scala.util.Try
+
+/**
+ * org.apache.streams.activitypub.servlets.WebfingerResource response to inquires about any URI, typically an item in one of the published feeds, or one of the
+ * entities referenced by those items.
+ *
+ * org.apache.streams.activitypub.servlets.WebfingerResource is always bound to '/.well-known/webfinger' per RFC 7033.
+ *
+ * org.apache.streams.activitypub.servlets.WebfingerResource often delegates the research needed to respond to the request to one of the actors
+ * running in the StreamsActorSystem.
+ *
+ * NOTE: RFC 7033 declares 'application/jrd+json' as the standard Accept Content-Type, but we use text/html
+ * as the default when no Accept is supplied, so that casual use through a
+ */
+
+@Rest(
+  title = Array("Webfinger Microservice"),
+  description = Array("Webfinger Microservice"),
+  defaultAccept = MediaType.TEXT_HTML,
+  produces = Array(
+    MediaType.APPLICATION_JSON,
+    "application/jrd+json",
+    MediaType.TEXT_HTML,
+  ),
+  serializers = Array(classOf[JsonSerializer], classOf[HtmlSerializer]),
+  debugOn = "true",
+  allowedHeaderParams = "*",
+  allowedMethodHeaders = "*",
+  allowedMethodParams = "*"
+)
+class WebfingerServlet extends BasicRestServlet with WebfingerRest {
+
+    override def init(servletConfig: ServletConfig): Unit = {
+      super.init(servletConfig)
+    }
+
+//    class WebfingerAcceptMatcher extends RestMatcher {
+//
+//        private final val ACCEPTABLE = Set(
+//          "application/jrd+json",
+//          MediaType.APPLICATION_JSON,
+//          MediaType.TEXT_HTML
+//        )
+//
+//        def matches( httpServletRequest: HttpServletRequest ) : Boolean = {
+//            val acceptHeaderString: String = httpServletRequest.getHeader("Accept")
+//            val acceptHeaders = StringUtils.split(acceptHeaderString, ',').toSet
+//            val matches = ACCEPTABLE.intersect(acceptHeaders).nonEmpty
+//            matches
+//        }
+
+//    }
+
+    def webfingerQueryRequestIsValid( request: WebfingerQueryRequest) : Boolean = {
+        !request.getResource().isEmpty()
+    }
+
+    @RestGet(
+            path = Array("/*"),
+            summary = "Lookup resources by URI",
+            description = Array("Lookup resources by URI"),
+            //matchers = Array(classOf[WebfingerAcceptMatcher])
+    )
+    def webfingerQueryGet(restRequest: RestRequest,
+                          restResponse: RestResponse ) = {
+
+      val resource = restRequest.getParameter("resource")
+
+      val webfingerQueryRequest = new WebfingerQueryRequest()
+             .withResource(resource);
+
+        if (webfingerQueryRequestIsValid(webfingerQueryRequest)) {
+            try {
+              restResponse.setContent(webfingerQuery(webfingerQueryRequest));
+              restResponse.setStatus(HttpServletResponse.SC_OK);
+            } catch {
+              case e : Exception => {
+                restResponse.setException(e);
+                restResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+              }
+            }
+        } else {
+          restResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+        }
+
+    }
+
+    def webfingerQuery( request : WebfingerQueryRequest) : WebfingerQueryResponse = {
+        val response = new WebfingerQueryResponse()
+                .withSubject(request.getResource())
+                .withProperties(
+                        new Properties()
+                                .withAdditionalProperty("propertyKey", "propertyValue")
+                )
+        response;
+    }
+}
diff --git a/streams-activitypub-servlets/src/test/scala/org/apache/streams/activitypub/servlets/test/ActivityPubServletsTestSuite.scala b/streams-activitypub-servlets/src/test/scala/org/apache/streams/activitypub/servlets/test/ActivityPubServletsTestSuite.scala
new file mode 100755
index 0000000..0fa088c
--- /dev/null
+++ b/streams-activitypub-servlets/src/test/scala/org/apache/streams/activitypub/servlets/test/ActivityPubServletsTestSuite.scala
@@ -0,0 +1,20 @@
+package org.apache.streams.activitypub.servlets.test
+
+import org.junit.jupiter.api.Order
+import org.junit.jupiter.api.extension.RegisterExtension
+import org.junit.platform.suite.api.SelectClasses
+import org.junit.platform.suite.api.Suite
+import org.junit.platform.suite.api.SuiteDisplayName;
+
+/**
+ * ActivityPubServletsTestSuite
+ */
+@Suite
+@SuiteDisplayName("ActivityPub Servlets Unit Tests")
+@Order(Order.DEFAULT)
+@SelectClasses(Array(
+  classOf[org.apache.streams.activitypub.servlets.test.cases.RootServletTest]
+))
+class ActivityPubServletsTestSuite {
+
+}
diff --git a/streams-activitypub-servlets/src/test/scala/org/apache/streams/activitypub/servlets/test/cases/RootServletTest.scala b/streams-activitypub-servlets/src/test/scala/org/apache/streams/activitypub/servlets/test/cases/RootServletTest.scala
new file mode 100755
index 0000000..2a70ab9
--- /dev/null
+++ b/streams-activitypub-servlets/src/test/scala/org/apache/streams/activitypub/servlets/test/cases/RootServletTest.scala
@@ -0,0 +1,58 @@
+package org.apache.streams.activitypub.servlets.test.cases
+
+import org.apache.http.HttpHeaders
+import org.apache.http.HttpStatus
+import org.apache.http.entity.ContentType
+import org.apache.juneau.collections.JsonList
+import org.apache.juneau.collections.JsonMap
+import org.apache.juneau.dto.html5.Body
+import org.apache.juneau.dto.html5.Head
+import org.apache.juneau.dto.html5.Html
+import org.apache.juneau.rest.mock.MockRestClient
+import org.apache.streams.activitypub.servlets.RootServlet
+import org.junit.jupiter.api.DisplayName
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.Assertions
+
+import scala.Option
+import scala.util.Try
+
+/**
+ * RootResourceTest tests that RootResource responds correctly to requests.
+ */
+
+
+class RootServletTest {
+
+  @Test
+  @DisplayName("Get RootServlet JSON")
+  @throws(classOf[Exception])
+  def testGetRootServletJson(): Unit = {
+    val request = MockRestClient.create(classOf[RootServlet])
+      .json.build.get("/")
+    val response = request.run
+    response.assertStatus(HttpStatus.SC_OK)
+    response.assertHeader(HttpHeaders.CONTENT_TYPE).is(ContentType.APPLICATION_JSON.getMimeType)
+    val attempt = Try(response.getEntity.as(classOf[JsonList]))
+    val content = attempt.get
+    Assertions.assertNotNull(content)
+    Assertions.assertTrue(content.size() > 0)
+  }
+
+  @Test
+  @DisplayName("Get RootServlet HTML")
+  @throws(classOf[Exception])
+  def testGetRootServletHtml(): Unit = {
+    val request = MockRestClient.create(classOf[RootServlet])
+      .html.build.get("/")
+    val response = request.run
+    response.assertStatus(HttpStatus.SC_OK)
+    response.assertHeader(HttpHeaders.CONTENT_TYPE).is(ContentType.TEXT_HTML.getMimeType)
+    val attempt = Try(response.getEntity.as(classOf[Html]))
+    val content = attempt.get
+    Assertions.assertNotNull(content)
+    Assertions.assertTrue(content.getChild(0).isInstanceOf[Head])
+    Assertions.assertTrue(content.getChild(1).isInstanceOf[Body])
+  }
+
+}
diff --git a/streams-activitypub-webapp/Dockerfile b/streams-activitypub-webapp/Dockerfile
new file mode 100755
index 0000000..5cfe424
--- /dev/null
+++ b/streams-activitypub-webapp/Dockerfile
@@ -0,0 +1,11 @@
+# Use a base image with JRE 17 and Tomcat runtime
+FROM tomcat:10.1.18-jre17-temurin
+
+# Copy the war file to the webapps directory in the container
+COPY maven/streams-webapp*.war /usr/local/tomcat/webapps/ROOT.war
+
+# Expose the default Tomcat port
+EXPOSE 8080
+
+# Start Tomcat when the container is launched
+CMD ["catalina.sh", "run"]
diff --git a/streams-activitypub-webapp/pom.xml b/streams-activitypub-webapp/pom.xml
new file mode 100755
index 0000000..4fbdbed
--- /dev/null
+++ b/streams-activitypub-webapp/pom.xml
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>apache-streams-activitypub</artifactId>
+        <groupId>org.apache.streams.activitypub</groupId>
+        <version>0.8.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>streams-activitypub-webapp</artifactId>
+    <name>${project.artifactId}</name>
+
+    <description>Apache Streams ActivityPub Server Webapp</description>
+
+    <packaging>war</packaging>
+
+    <!-- streams-server only properties -->
+    <properties>
+        <tomcat.version>10.1.18</tomcat.version>
+        <jsp.version>3.1.1</jsp.version>
+        <war.plugin.version>3.4.0</war.plugin.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.streams</groupId>
+            <artifactId>streams-config</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.streams.activitypub</groupId>
+            <artifactId>streams-activitypub-actors</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.streams.activitypub</groupId>
+            <artifactId>streams-activitypub-servlets</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.servlet</groupId>
+            <artifactId>jakarta.servlet-api</artifactId>
+            <version>${jakarta.version}</version>
+            <scope>provided</scope>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.apache.tomcat</groupId>-->
+<!--            <artifactId>tomcat-servlet-api</artifactId>-->
+<!--            <version>${tomcat.version}</version>-->
+<!--            <scope>provided</scope>-->
+<!--        </dependency>-->
+        <dependency>
+            <groupId>org.apache.tomcat.embed</groupId>
+            <artifactId>tomcat-embed-core</artifactId>
+            <version>${tomcat.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tomcat.embed</groupId>
+            <artifactId>tomcat-embed-jasper</artifactId>
+            <version>${tomcat.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.servlet.jsp</groupId>
+            <artifactId>jakarta.servlet.jsp-api</artifactId>
+            <version>${jsp.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tomcat</groupId>
+            <artifactId>tomcat-jsp-api</artifactId>
+            <version>${tomcat.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.juneau</groupId>
+            <artifactId>juneau-rest-client</artifactId>
+            <version>${juneau.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tomcat.embed</groupId>
+            <artifactId>tomcat-embed-core</artifactId>
+            <version>${tomcat.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <finalName>streams-activitypub-webapp</finalName>
+        <testSourceDirectory>src/test/scala</testSourceDirectory>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+        </resources>
+        <testResources>
+            <testResource>
+                <directory>src/test/resources</directory>
+            </testResource>
+            <testResource>
+                <directory>src/main/webapp</directory>
+            </testResource>
+        </testResources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <version>${war.plugin.version}</version>
+                <executions>
+                    <execution>
+                        <id>exploded</id>
+                        <phase>process-test-resources</phase>
+                        <goals>
+                            <goal>exploded</goal>
+                        </goals>
+                        <configuration>
+                            <archiveClasses>true</archiveClasses>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>war</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>war</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <addClasspath>true</addClasspath>
+                            <classpathPrefix>lib/</classpathPrefix>
+                        </manifest>
+                    </archive>
+                    <failOnMissingWebXml>true</failOnMissingWebXml>
+                    <packagingIncludes>htdocs/**,META-INF/**,WEB-INF/**</packagingIncludes>
+<!--                    <webappDirectory>${project.build.directory}/tomcat/webapps/${project.build.finalName}</webappDirectory>-->
+                    <warSourceDirectory>src/main/webapp</warSourceDirectory>
+                    <webXml>src/main/webapp/WEB-INF/web.xml</webXml>
+                    <webResources>
+                        <resource>
+                            <directory>src/main/webapp</directory>
+                        </resource>
+                    </webResources>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/streams-activitypub-webapp/src/main/webapp/WEB-INF/classes/logging.properties b/streams-activitypub-webapp/src/main/webapp/WEB-INF/classes/logging.properties
new file mode 100644
index 0000000..9cf5748
--- /dev/null
+++ b/streams-activitypub-webapp/src/main/webapp/WEB-INF/classes/logging.properties
@@ -0,0 +1,10 @@
+org.apache.catalina.core.ContainerBase.[Catalina].level = DEBUG
+org.apache.catalina.core.ContainerBase.[Catalina].handlers = java.util.logging.ConsoleHandler
+org.apache.catalina.core.StandardEngine.[Catalina].level = DEBUG
+org.apache.catalina.core.StandardEngine.[Catalina].handlers = java.util.logging.ConsoleHandler
+org.apache.catalina.core.StandardService.[Catalina].level = DEBUG
+org.apache.catalina.core.StandardService.[Catalina].handlers = java.util.logging.ConsoleHandler
+org.apache.catalina.mapper.MapperListener.[Catalina].level = DEBUG
+org.apache.catalina.mapper.MapperListener.[Catalina].handlers = java.util.logging.ConsoleHandler
+org.apache.catalina.session.level=ALL
+java.util.logging.ConsoleHandler.level=ALL
diff --git a/streams-activitypub-webapp/src/main/webapp/WEB-INF/context.xml b/streams-activitypub-webapp/src/main/webapp/WEB-INF/context.xml
new file mode 100755
index 0000000..301c46c
--- /dev/null
+++ b/streams-activitypub-webapp/src/main/webapp/WEB-INF/context.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Context>
+
+    <Resources>
+        <PreResources
+                      base="src/main/webapp/htdocs"
+                      internalPath="/htdocs"
+                      webAppMount="/htdocs" />
+    </Resources>
+
+</Context>
diff --git a/streams-activitypub-webapp/src/main/webapp/WEB-INF/web.xml b/streams-activitypub-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..788d453
--- /dev/null
+++ b/streams-activitypub-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<web-app>
+    <context-param>
+        <description>Enable debugging for the application</description>
+        <param-name>debug</param-name>
+        <param-value>true</param-value>
+    </context-param>
+    <display-name>Application Streams</display-name>
+    <servlet>
+        <display-name>RootServletGroup</display-name>
+        <servlet-name>root</servlet-name>
+        <servlet-class>org.apache.streams.activitypub.servlets.RootServlet</servlet-class>
+        <load-on-startup>5</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>root</servlet-name>
+        <url-pattern>/</url-pattern>
+    </servlet-mapping>
+    <servlet>
+        <display-name>WebfingerServlet</display-name>
+        <servlet-name>webfinger</servlet-name>
+        <servlet-class>org.apache.streams.activitypub.servlets.WebfingerServlet</servlet-class>
+        <load-on-startup>5</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>webfinger</servlet-name>
+        <url-pattern>/.well-known/webfinger</url-pattern>
+    </servlet-mapping>
+</web-app>
diff --git a/streams-activitypub-webapp/src/main/webapp/htdocs/images/asf.png b/streams-activitypub-webapp/src/main/webapp/htdocs/images/asf.png
new file mode 100755
index 0000000..ce28113
Binary files /dev/null and b/streams-activitypub-webapp/src/main/webapp/htdocs/images/asf.png differ
diff --git a/streams-activitypub-webapp/src/main/webapp/htdocs/images/juneau.png b/streams-activitypub-webapp/src/main/webapp/htdocs/images/juneau.png
new file mode 100755
index 0000000..3fc62b7
Binary files /dev/null and b/streams-activitypub-webapp/src/main/webapp/htdocs/images/juneau.png differ
diff --git a/streams-activitypub-webapp/src/main/webapp/htdocs/images/streams_logo.jpg b/streams-activitypub-webapp/src/main/webapp/htdocs/images/streams_logo.jpg
new file mode 100755
index 0000000..799ad58
Binary files /dev/null and b/streams-activitypub-webapp/src/main/webapp/htdocs/images/streams_logo.jpg differ
diff --git a/streams-activitypub-webapp/src/main/webapp/htdocs/styles/MenuItemWidget.css b/streams-activitypub-webapp/src/main/webapp/htdocs/styles/MenuItemWidget.css
new file mode 100755
index 0000000..430df88
--- /dev/null
+++ b/streams-activitypub-webapp/src/main/webapp/htdocs/styles/MenuItemWidget.css
@@ -0,0 +1,17 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ ***************************************************************************************************************************/
+.menu-item {
+	position: relative;
+	display: inline-block;
+}
diff --git a/streams-activitypub-webapp/src/main/webapp/htdocs/styles/QueryMenuItem.css b/streams-activitypub-webapp/src/main/webapp/htdocs/styles/QueryMenuItem.css
new file mode 100755
index 0000000..cdd96c3
--- /dev/null
+++ b/streams-activitypub-webapp/src/main/webapp/htdocs/styles/QueryMenuItem.css
@@ -0,0 +1,13 @@
+/***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations under the License.
+ *
+ ***************************************************************************************************************************/
diff --git a/streams-activitypub-webapp/src/main/webapp/htdocs/styles/SwaggerUI.css b/streams-activitypub-webapp/src/main/webapp/htdocs/styles/SwaggerUI.css
new file mode 100755
index 0000000..b55ffc6
--- /dev/null
+++ b/streams-activitypub-webapp/src/main/webapp/htdocs/styles/SwaggerUI.css
@@ -0,0 +1,342 @@
+/*
+ ***************************************************************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+ * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+ * with the License.  You may obtain a copy of the License at                                                              *
+ *                                                                                                                         *
+ *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+ *                                                                                                                         *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+ * specific language governing permissions and limitations under the License.                                              *
+ ***************************************************************************************************************************
+*/
+
+.swagger-ui {	
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Header key-value pairs
+ ----------------------------------------------------------------------------------------------------------*/
+
+.swagger-ui table.header {
+    margin-bottom: 15px;
+	width: 95%;
+	border: none;
+}
+
+.swagger-ui table.header * {
+	vertical-align: middle;
+}
+
+.swagger-ui table.header th {
+    font-weight: bold;
+    padding: 5px 10px;
+    text-align: left;
+    white-space: nowrap;
+	border: none;
+	border-radius: 3px;
+}
+
+.swagger-ui table.header td {
+	padding: 5px 10px;
+    text-align: left;
+    vertical-align: middle;
+	border: none;
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Method buttons (e.g GET/PUT/... buttons)                                                                
+ ----------------------------------------------------------------------------------------------------------*/
+.method-button {
+  	display: inline-block;
+    font-weight: bold;
+    min-width: 60px;
+    padding: 6px 15px;
+    text-align: center;
+    border-radius: 3px;
+    text-shadow: 0 1px 0 rgba(0,0,0,.1);
+    color: #fff;
+}
+.get .method-button        { background: rgb(97,175,254); }
+.put .method-button        { background: rgb(252,161,48); }
+.post .method-button       { background: rgb(73,204,144); }
+.delete .method-button     { background: rgb(249,62,62); }
+.options .method-button    { background: rgb(153,102,255); }
+.deprecated .method-button { background: rgb(170,170,170); }
+.model .method-button      { background: rgb(150,150,150); min-width: 120px;}
+.other .method-button      { background: rgb(230,230,0); }
+
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Tag block                                                                                                -
+ - Encapsulates one or more op-blocks.
+ ----------------------------------------------------------------------------------------------------------*/
+
+.tag-block {
+	min-width: 800px;
+}
+
+.tag-block-summary {
+	margin: 10px 0px;
+	padding: 5px 0px;
+    align-items: center;
+    cursor: pointer;
+	border-bottom: 1px solid rgba(59,65,81,.2);
+	user-select: none;
+	transition: all .2s;
+}
+.tag-block-summary:hover {
+	background-color: rgba(59,65,81,.1);
+}
+
+.tag-block-summary .name {
+	font-size: 18px;
+	padding: 0px 20px;
+}
+.tag-block-summary .description {
+	font-size: 14px;
+	padding: 0px 20px;
+}
+.tag-block-summary .extdocs {
+	float: right;
+	font-size: 14px;
+	padding: 0px 20px;
+}
+
+.tag-block-open .tag-block-contents { display: block; }
+.tag-block-closed .tag-block-contents { display: none; }
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Op block                                                                                          
+ - Encapsulates a single http-method + http-path
+ ----------------------------------------------------------------------------------------------------------*/
+
+.op-block {
+	margin-bottom: 10px;
+    align-items: center;
+    border-radius: 4px;
+}
+
+.op-block.get        { background: rgba(97,175,254,.1); border: 1px solid rgb(97,175,254); }
+.op-block.put        { background: rgba(252,161,48,.1); border: 1px solid rgb(252,161,48); }
+.op-block.post       { background: rgba(73,204,144,.1); border: 1px solid rgb(73,204,144); }
+.op-block.options    { background: rgba(153,102,255,.1); border: 1px solid rgb(153,102,255); }
+.op-block.delete     { background: rgba(249,62,62,.1); border: 1px solid rgb(249,62,62); }
+.op-block.deprecated { background: rgba(170,170,170,.1); border: 1px solid rgb(170,170,170); }
+.op-block.model      { background: rgba(0,0,0,.05); border: 1px solid rgb(170,170,170); }
+.op-block.other      { background: rgba(230,230,0,0.1); border: 1px solid rgb(230,230,0); }
+
+.op-block-summary {	
+	padding: 5px;
+    cursor: pointer;
+	user-select: none;
+}
+
+.op-block-summary .path {
+	font-size: 14px;
+	word-break: break-all;
+    font-family: monospace;
+    font-weight: bold;
+    padding:10px;
+}
+
+.op-block.deprecated .op-block-summary .path { color: #8f9199; text-decoration: line-through;}
+.op-block.deprecated .op-block-summary .description { color: #8f9199 }
+
+.op-block-summary .summary {
+    font-size: 14px;
+    padding: 10px;
+}
+
+.op-block-description {
+    font-size: 14px;
+    padding: 10px;
+}
+
+
+.op-block-open .op-block-contents { display: block; }
+.op-block-closed .op-block-contents { display: none; }
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Op block section header                                                                                               -
+ - 'Parameters' and 'Responses' subsections in an op-block
+ ----------------------------------------------------------------------------------------------------------*/
+
+.op-block-section-header {
+    padding: 8px 15px;
+    background: hsla(0,0%,100%,.3);
+    box-shadow: 1px 2px 3px rgba(0,0,0,.3);
+    margin: 10px;
+    border-radius: 4px;
+}
+
+.op-block-section-header .title {
+    font-size: 14px;
+    margin: 0px;
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Parameters and Responses sections
+ ----------------------------------------------------------------------------------------------------------*/
+
+table.parameters, table.responses {
+    border-collapse: collapse;
+    margin: 20px;
+	width: 95%;
+	border-bottom: 1px solid rgba(59,65,81,.2);
+}
+
+th.parameter-key, th.response-key {
+	font-size: 12px;
+    font-weight: bold;
+    text-align: left;
+	border: none;
+    border-bottom: 1px solid rgba(59,65,81,.2);
+	background-color: inherit;
+}
+
+td.parameter-key, td.response-key {
+	font-size: 12px;
+    padding: 10px;
+    text-align: left;
+	border: none;
+    border-bottom: 1px solid rgba(59,65,81,.2);
+	background-color: inherit;
+}
+
+td.parameter-value, td.response-value {
+    padding: 10px;
+    text-align: left;
+    border-bottom: 1px solid rgba(59,65,81,.2);
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Parameter name
+ ----------------------------------------------------------------------------------------------------------*/
+
+.parameter-key .in {
+	font-size: 12px;
+    font-family: monospace;
+    font-weight: bold;
+    font-style: italic;
+    color: gray;
+}
+
+.parameter-key .name {
+	font-size: 14px;
+}
+
+.parameter-key .name.required {
+    font-weight: bold;
+}
+
+.parameter-key .requiredlabel {
+	font-size: 10px;
+    color: rgba(255,0,0,.6);    
+    font-weight: bold;
+}
+
+.parameter-key .type {
+    font-size: 12px;
+    padding: 5px 0;
+    font-family: monospace;
+    font-weight: bold;
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Examples
+ ----------------------------------------------------------------------------------------------------------*/
+ 
+.op-block-contents .example-select {
+    margin: 10px 0 5px 0;
+	border-width: 1px;
+	font-weight:bold;
+    padding: 5px 40px 5px 10px;
+    border: 1px solid #41444e;
+    border-radius: 4px;
+    box-shadow: 0 1px 2px 0 rgba(0,0,0,.25);
+    background: hsla(0,0%,100%,.3);
+}
+
+.op-block-contents .example-select:disabled {
+    color: rgba(0,0,0,.50);
+    border: 1px solid rgba(0,0,0,.50);
+}
+
+.op-block-contents .example {
+    margin: 0;
+    padding: 5px 20px;
+    white-space: pre-wrap;
+    word-wrap: break-word;
+    hyphens: auto;
+    border-radius: 4px;
+    background: #41444e;
+    overflow-wrap: break-word;
+    font-family: monospace;
+    font-weight: 400;
+    color: limegreen;
+	display: none;
+	max-width: 800px;
+	max-height: 800px;
+	text-overflow: auto;
+	overflow: auto;
+}
+
+.op-block-contents .example.active {
+	display:block;
+}
+
+.op-block-contents .model {
+	display: none;
+}
+
+.op-block-contents .model.active {
+	display:block;
+}
+
+/*-----------------------------------------------------------------------------------------------------------
+ - Headers
+ ----------------------------------------------------------------------------------------------------------*/
+
+.section {
+    font-weight: bold;
+    padding: 5px 0;
+    text-align: left;
+}
+
+.headers .name {
+    padding: 5px 0;
+    font-family: monospace;
+    font-weight: bold;
+}
+
+div.headers {
+	margin: 20px 0px;
+}
+
+.headers .type {
+    padding: 5px 0;
+    font-family: monospace;
+    font-weight: bold;
+}
+
+.section-name {
+	display: inline-block;
+	vertical-align: top;
+	margin-right: 20px;
+    font-weight: bold;
+    padding: 5px 0;
+    text-align: left;
+}
+
+.section-table {
+/*	display: inline-block;*/
+}
+
+.responses .section-table td {
+	padding: 5px 20px 5px 0px;
+	text-align: left;
+    border-bottom: 1px solid rgba(59,65,81,.2);
+}
diff --git a/streams-activitypub-webapp/src/main/webapp/htdocs/themes/streams.css b/streams-activitypub-webapp/src/main/webapp/htdocs/themes/streams.css
new file mode 100755
index 0000000..e69de29
diff --git a/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/ActivityPubWebappTestSuite.scala b/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/ActivityPubWebappTestSuite.scala
new file mode 100755
index 0000000..87c736a
--- /dev/null
+++ b/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/ActivityPubWebappTestSuite.scala
@@ -0,0 +1,31 @@
+package org.apache.streams.activitypub.webapp.test
+
+import org.junit.jupiter.api.Order
+import org.junit.jupiter.api.extension.RegisterExtension
+import org.junit.platform.suite.api.SelectClasses
+import org.junit.platform.suite.api.Suite
+import org.junit.platform.suite.api.SuiteDisplayName;
+
+/**
+ * ActivityPubServletsTestSuite
+ */
+
+object ActivityPubWebappTestSuite {
+
+  @RegisterExtension
+  val helper: ActivityPubWebappTestSuiteExtension = new ActivityPubWebappTestSuiteExtension()
+
+}
+
+@Suite
+@SuiteDisplayName("ActivityPub Webapp Integration Tests")
+@Order(Order.DEFAULT)
+@SelectClasses(Array(
+  classOf[org.apache.streams.activitypub.webapp.test.cases.ServerAvailableTest],
+  classOf[org.apache.streams.activitypub.webapp.test.cases.ServletRegistrationTest],
+  classOf[org.apache.streams.activitypub.webapp.test.cases.RootServletTest],
+  classOf[org.apache.streams.activitypub.webapp.test.cases.WebfingerServletTest]
+))
+class ActivityPubWebappTestSuite {
+
+}
diff --git a/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/ActivityPubWebappTestSuiteExtension.scala b/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/ActivityPubWebappTestSuiteExtension.scala
new file mode 100644
index 0000000..40ce03b
--- /dev/null
+++ b/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/ActivityPubWebappTestSuiteExtension.scala
@@ -0,0 +1,104 @@
+package org.apache.streams.activitypub.webapp.test
+
+import org.apache.catalina.Context
+import org.apache.catalina.Loader
+import org.apache.catalina.Server
+import org.apache.catalina.loader.WebappClassLoaderBase
+import org.apache.catalina.loader.WebappLoader
+import org.apache.catalina.startup.Tomcat
+import org.apache.http.client.utils.URIBuilder
+import org.apache.http.impl.NoConnectionReuseStrategy
+import org.apache.juneau.rest.client.RestClient
+import org.junit.jupiter.api.extension.AfterAllCallback
+import org.junit.jupiter.api.extension.BeforeAllCallback
+import org.junit.jupiter.api.extension.ExtensionContext
+import org.junit.jupiter.api.extension.ParameterContext
+import org.junit.jupiter.api.extension.ParameterResolver
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+import java.io.File
+import java.net.URI
+import java.nio.file.Path
+import java.nio.file.Paths
+import java.nio.file.Files
+
+class ActivityPubWebappTestSuiteExtension extends ParameterResolver with BeforeAllCallback with AfterAllCallback {
+
+  private final val LOGGER: Logger = LoggerFactory.getLogger(classOf[ActivityPubWebappTestSuiteExtension])
+
+  private val userDir: String = System.getProperty("user.dir")
+  private val basePath: Path = Paths.get(userDir)
+  private val basePathDir: String = basePath.toAbsolutePath.toString
+  private val webappDir: String = basePath.getFileName.toString
+  private val webappPath: Path = webappDir match {
+    case "streams-activitypub" => Paths.get(basePathDir, "streams-activitypub-webapp/target/streams-activitypub-webapp")
+    case "streams-activitypub-webapp" => Paths.get(basePathDir, "target/streams-activitypub-webapp")
+  }
+  private val webapp: String = webappPath.toAbsolutePath.toString
+  
+  private val tomcat: Tomcat = new Tomcat()
+  tomcat.enableNaming()
+  tomcat.setBaseDir(basePathDir)
+  tomcat.setPort(18080)
+  tomcat.setAddDefaultWebXmlToWebapp(false)
+  tomcat.setSilent(false)
+  tomcat.getHost.getAppBaseFile.mkdir
+
+  private val appContext: Context = tomcat.addWebapp(tomcat.getHost, "", webapp)
+
+  tomcat.start()
+
+  def server: Server = tomcat.getServer
+  def context: Context = appContext
+  def host: String = tomcat.getHost.getName
+  def port: Int = tomcat.getConnector.getPort
+
+  val uriBuilder: URIBuilder = new URIBuilder()
+    .setPath("/")
+    .setScheme("http")
+    .setHost(host)
+    .setPort(port)
+
+  var rootUri: URI = uriBuilder.build()
+
+  def restClientBuilder: RestClient.Builder = RestClient.create()
+    .connectionReuseStrategy(new NoConnectionReuseStrategy())
+    .debug()
+    .disableAutomaticRetries()
+    .disableCookieManagement()
+    .disableRedirectHandling()
+    .maxConnTotal(10)
+    .rootUrl(rootUri.toURL)
+
+  def restClient: RestClient = restClientBuilder
+    .pooled()
+    .build();
+
+  override def beforeAll(context : ExtensionContext) : Unit = {
+    LOGGER.info("beforeAll()");
+  }
+
+  override def afterAll(extensionContext: ExtensionContext): Unit = {
+    LOGGER.info("afterAll()")
+    try {
+      tomcat.stop();
+    } catch {
+      case e: Exception => LOGGER.error("Exception while stopping tomcat", e);
+    } finally {
+      try {
+        tomcat.destroy();
+      } catch {
+        case e: Exception => LOGGER.error("Exception while destoying tomcat", e);
+      }
+    }
+  }
+
+  override def supportsParameter(parameterContext: ParameterContext, extensionContext: ExtensionContext): Boolean = {
+    false
+  }
+
+  override def resolveParameter(parameterContext: ParameterContext, extensionContext: ExtensionContext): AnyRef = {
+    null
+  }
+}
diff --git a/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/cases/RootServletTest.scala b/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/cases/RootServletTest.scala
new file mode 100755
index 0000000..f095b80
--- /dev/null
+++ b/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/cases/RootServletTest.scala
@@ -0,0 +1,21 @@
+package org.apache.streams.activitypub.webapp.test.cases
+
+import org.apache.streams.activitypub.webapp.test.ActivityPubWebappTestSuite
+import org.apache.streams.activitypub.webapp.test.ActivityPubWebappTestSuiteExtension
+import org.junit.jupiter.api.DisplayName
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.extension.ExtendWith
+import org.slf4j.LoggerFactory;
+
+class RootServletTest {
+
+    private final val LOGGER = LoggerFactory.getLogger(classOf[RootServletTest]);
+
+    @Test
+    @DisplayName("Root Resource Available")
+    @throws(classOf[Exception])
+    def testRootResourceAvailable() : Unit = {
+        val response = ActivityPubWebappTestSuite.helper.restClient.get().json().run();
+        assert(response.getStatusCode() == 200);
+    }
+}
diff --git a/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/cases/ServerAvailableTest.scala b/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/cases/ServerAvailableTest.scala
new file mode 100755
index 0000000..8eedc05
--- /dev/null
+++ b/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/cases/ServerAvailableTest.scala
@@ -0,0 +1,33 @@
+package org.apache.streams.activitypub.webapp.test.cases
+
+import org.awaitility.Awaitility.await
+import org.awaitility.Awaitility.waitAtMost
+import org.awaitility.core.ConditionTimeoutException
+import org.apache.streams.activitypub.webapp.test.ActivityPubWebappTestSuite
+import org.awaitility.scala.AwaitilitySupport
+import org.hamcrest.MatcherAssert.assertThat
+import org.junit.jupiter.api.Assertions
+import org.junit.jupiter.api.DisplayName
+import org.junit.jupiter.api.Test
+import org.slf4j.LoggerFactory
+
+import scala.concurrent.duration.MINUTES
+import scala.concurrent.duration.SECONDS
+import scala.util.Try;
+
+class ServerAvailableTest extends AwaitilitySupport {
+
+    private final val LOGGER = LoggerFactory.getLogger(classOf[ServerAvailableTest]);
+
+    @Test
+    @DisplayName("Test server is available")
+    @throws(classOf[Exception])
+    def testServerAvailable() : Unit = {
+        val testAttempt = Try {
+            await atMost(5, MINUTES) untilAsserted {
+                ActivityPubWebappTestSuite.helper.server.getStateName.matches("STARTED")
+            }
+        }
+        Assertions.assertTrue(testAttempt.isSuccess)
+    }
+}
diff --git a/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/cases/ServletRegistrationTest.scala b/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/cases/ServletRegistrationTest.scala
new file mode 100755
index 0000000..538a50b
--- /dev/null
+++ b/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/cases/ServletRegistrationTest.scala
@@ -0,0 +1,23 @@
+package org.apache.streams.activitypub.webapp.test.cases
+
+import org.apache.streams.activitypub.webapp.test.ActivityPubWebappTestSuite
+import org.junit.jupiter.api.Assertions
+import org.junit.jupiter.api.DisplayName
+import org.junit.jupiter.api.Test
+import org.slf4j.LoggerFactory;
+
+class ServletRegistrationTest {
+
+    private final val LOGGER = LoggerFactory.getLogger(classOf[ServletRegistrationTest]);
+
+    @Test
+    @DisplayName("All Servlets are registered")
+    @throws(classOf[Exception])
+    def testAllServletsRegistered() : Unit = {
+        val servletRegistations = ActivityPubWebappTestSuite.helper.context.getServletContext.getServletRegistrations()
+        Assertions.assertNotNull(servletRegistations)
+        Assertions.assertEquals(2, servletRegistations.size())
+        Assertions.assertTrue(servletRegistations.containsKey("root"))
+        Assertions.assertTrue(servletRegistations.containsKey("webfinger"))
+    }
+}
diff --git a/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/cases/WebfingerServletTest.scala b/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/cases/WebfingerServletTest.scala
new file mode 100755
index 0000000..2436980
--- /dev/null
+++ b/streams-activitypub-webapp/src/test/scala/org/apache/streams/activitypub/webapp/test/cases/WebfingerServletTest.scala
@@ -0,0 +1,38 @@
+package org.apache.streams.activitypub.webapp.test.cases
+
+import org.apache.http.HttpStatus
+import org.apache.http.client.utils.URIBuilder
+import org.apache.http.entity.ContentType
+import org.apache.juneau.rest.client.RestResponse
+import org.apache.streams.activitypub.webapp.test.ActivityPubWebappTestSuite
+import org.apache.streams.activitypub.webapp.test.ActivityPubWebappTestSuiteExtension
+import org.junit.jupiter.api.DisplayName
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.extension.ExtendWith
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+import java.nio.charset.Charset;
+
+class WebfingerServletTest {
+
+    private final val LOGGER = LoggerFactory.getLogger(classOf[WebfingerServletTest]);
+
+    private val uriBuilder : URIBuilder = ActivityPubWebappTestSuite.helper.uriBuilder
+      .setCharset(Charset.defaultCharset())
+      .setPath(".well-known/webfinger")
+
+    @Test
+    @DisplayName("WebfingerQuery With Abbreviated Resource Parameter")
+    @throws(classOf[Exception])
+    def testWebfingerQueryWithAbbreviatedResourceParameter() : Unit = {
+        val request = ActivityPubWebappTestSuite.helper.restClientBuilder
+          .accept(ContentType.APPLICATION_JSON.getMimeType)  
+          .json()
+          .build()
+          .get(uriBuilder.setParameter("resource", "acct:sblackmon@asf.social").build())
+        val response = request.run();
+        response.assertStatus(HttpStatus.SC_OK)
+    }
+}
+