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
+
+mQINBFLPJmEBEAC9d/dUZCXeyhB0fVGmJAjdjXfLebav4VqGdNZC+M1T9C3dcVsh
+X/JGme5bjJeIgVwiH5UsdNceYn1+hyxs8jXuRAWEWKP76gD+pNrp8Az0ZdBkJoAy
+zCywOPtJV2PCOz7+S5ri2nUA2+1Kgcu6IlSLMmYAGO0IAmRrjBEzxy9iGaxiNGTc
+LvQt/iVtIXWkKKI8yvpoJ8iFf3TGhpjgaC/h7cJP3zpy0SScmhJJASLXRsfocLv9
+sle6ndN9IPbDtRW8cL7Fk3VQlzp1ToVjmnQTyZZ6S1WafsjzCZ9hLN+k++o8VbvY
+v3icY6Sy0BKz0J6KwaxTkuZ6w1K7oUkVOQboKaWFIEdO+jwrEmU+Puyd8Np8jLnF
+Q0Y5GPfyMlqM3S/zaDm1t4D1eb5FLciStkxfg5wPVK6TkqB325KVD3aio5C7E7kt
+aQechHxaJXCQOtCtVY4X+L4iClnMSuk+hcSc8W8MYRTSVansItK0vI9eQZXMnpan
+w9/jk5rS4Gts1rHB7+kdjT3QRJmkyk6fEFT0fz5tfMC7N8waeEUhCaRW6lAoiqDW
+NW1h+0UGxJw+9YcGxBC0kkt3iofNOWQWmuf/BS3DHPKT7XV/YtBHe44wW0sF5L5P
+nfQUHpnA3pcZ0En6bXAvepKVZTNdOWWJqMyHV+436DA+33h45QL6lWb/GwARAQAB
+tDVTdW5lZWwgTWFydGhpIChDT0RFIFNJR05JTkcgS0VZKSA8c21hcnRoaUBhcGFj
+aGUub3JnPokCNwQTAQoAIQUCUs8mYQIbAwULCQgHAwUVCgkICwUWAgMBAAIeAQIX
+gAAKCRC08czE01QYCOKKEAChRtHBoYNTX+RZbFO0Kl1GlN+i1Ik0shEm5ZJ56XHv
+AnFx/gRK7CfZzJswWo7kf2s/dvJiFfs+rrolYVuO6E8gNhAaTEomSuvWQAMHdPcR
+9G5APRKCSkbZYugElqplEbSphk78FKoFO+sml52M7Pr9jj88ApBjoFVVY8njdnNq
+6DVlaDsg8YninCD78Z7PNFnRGwxyZ8Qd4Dh0rG+MUTfAWopZu6/MxpQxU7QpeVeX
+SIMLg7ClFrGfXnZcszYF4dnav1aa0i7W88PAdYNPko7tC5qz5yv2ep7t2gRbcYKf
+RXhYC2FHQey3wPhMKjA8V436lAqmfYnY/YdmhEy9Xq/1EdX1nHsQ7OEkfgXK14WM
+F+rnqXRAl/0cwiyb41eocdg5kpZFIKgCYT02usLWxwNnd3jOCe109Ze3y3acN/G8
++xOf9YRfNVAe6pD8H6ieRbv9gRjBmsbz9bXQCmxFnDqxNri5Me6gBAQPNmYTJD0h
+jgJTK6o0vJ0pwjBLauasJsLu+1tR3Cb0dxPE+JVaTF26FCd7pM7W6KdVfod9ZfrN
+cSyJ/cECc2KvYVGmTjQNVo1dYG0awBachlWnYNt+0Qx4opLsczZOLtPKtFY4BJA7
+aZoXT4Qf9yB8km7x2/cgNExVbFummToJ/IP3M39/EaryspsQQuM5Qu5Q5lZp8Qnn
+ybkCDQRSzyZhARAA7bAawFzbJaghYnm6mTZyGG5hQmfAynbF6cPAE+g2SnXcNQjP
+6kjYx3tSpb7rEzmjQqs46ztqdec6PIVBMhakON6z27Zz+IviAtO/TcaZHWNuCAjw
+FXVQZ+tYsSeiKInttfkrQc8jXAHWwSkSjLqNpvQpBdBEX80MYkFB6ZPOeON2+/Ta
+GC1H/HU2YngF0qQSmG33KKG6ezihBJdKxU6t2tsQfTlCmZW6R6MGpS9fVurYMKBk
+vR+7RGZ/H6dSjWPcpxhusGg92J9uz7r5SopN1wSdyPMUCMAFGeyoxcAuBDl38quU
+H/ENG3x5LDPq2aEH2AJ6yvZfIXbeJ1zmXf2cAHv+HbmvZaTSp0XIjq8Yxh8NkYEC
+ZdfRWmsGLIpU16TkBijpK3Dn9MDXjHGT3V8/qfdpURtMvIaL8WFrq9ejcy/vGRFn
+mCYqxIIPH+vLiMXKWtuMc61GN3ES21msKQH6IuQxxfQLyhK44L/pv7FpF4E+6LaE
+8uRwAex5HIDpR1v4aJq089rRtye9VXTJJLZ7lYs0HctdZ30QbBRWT4jS9d9rj3cr
+HgQ7mIGO9TAfK2kWc6AJN/EvxPWNbOwptsTUzAF/adiy9ax8C18iw7nKczC+2eN6
+UcbxXiPdytuKYK7O9A8S9e1w89GwpxYN7Xfn2o6QfpSbL9cLKiinOeV+xikAEQEA
+AYkCHwQYAQoACQUCUs8mYQIbDAAKCRC08czE01QYCG7yD/471dmyOD+go8cZkdqR
+3CHhjH03odtI0EJNVy4VGEC0r9paz3BWYTy18LqWYkw3ygphOIU1r8/7QK3H5Ke3
+c4yCSUxaMk5SlAJ+iVRek5TABkR8+zI+ZN5pQtqRH+ya5JxV4F/Sx5Q3KWMzpvgY
+n6AgSSc3hEfkgdI7SalIeyLaLDWv+RFdGZ5JU5gD28C0G8BeH8L62x6sixZcqoGT
+oy9rwkjs45/ZmmvBZhd1wLvC/au8l2Ecou6O8+8m26W8Z7vCuGKxuWn0KV3DLLWe
+66uchDVlakGoMJSPIK06JWYUlE+gL0CW+U2ekt/v2qb8hGgMVET3CBAMq+bFWuJ6
+juX7hJd7wHtCFfjnFDDAkdp2IIIZAlBW6FZGv7pJ82xsW6pSAg0A7VrV6nTtMtDv
+T8esOfo/t4t0gaL7bivy9DVVdATbUBcJJFpoVoe5MxiyjptveqPzIRwzt04n52Ph
+ordVWAnX5AokXWTg+Glem/EWEuf7jUuZArfqCSl/sZoQdXGTjR7G4iFscispji4+
+kNjVQsItqFbgDpuc6n+GcFxlKQ7YMCnu5MVtTV01U4lFs0qy0NTUqsuR35DM4z14
+DkFmj1upWAayCoXTpKzsHBvJZPC+Wqf9Pl3O47apelg7KxU3S011YfXpVPvCTKBv
+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)
+ }
+}
+