├── .gitignore
├── LICENSE
├── README.md
├── alfresco-kafka-model
├── .gitignore
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── metaversant
│ └── kafka
│ └── model
│ ├── NodeEvent.java
│ ├── NodePermission.java
│ └── NodePermissions.java
├── alfresco-kafka-repo
├── .gitignore
├── README.md
├── docker
│ └── docker-compose.yml
├── pom.xml
└── src
│ └── main
│ ├── assembly
│ ├── amp.xml
│ ├── file-mapping.properties
│ └── web
│ │ └── README.md
│ ├── docker
│ ├── Dockerfile
│ ├── alfresco-global.properties
│ ├── dev-log4j.properties
│ ├── disable-webscript-caching-context.xml
│ ├── hotswap-agent.properties
│ └── license
│ │ └── README.md
│ ├── java
│ └── com
│ │ └── metaversant
│ │ └── kafka
│ │ ├── behavior
│ │ ├── GenerateNodeEvent.java
│ │ └── GenerateNodePermissionEvent.java
│ │ ├── service
│ │ ├── MessageService.java
│ │ └── MessageServiceScopedObject.java
│ │ └── transform
│ │ ├── NodeRefToNodeEvent.java
│ │ └── NodeRefToNodePermissions.java
│ └── resources
│ ├── META-INF
│ └── resources
│ │ └── test.html
│ ├── alfresco
│ ├── extension
│ │ └── templates
│ │ │ └── webscripts
│ │ │ └── com
│ │ │ └── metaversant
│ │ │ └── alfresco
│ │ │ └── kafka
│ │ │ ├── ping.get.desc.xml
│ │ │ ├── ping.get.js
│ │ │ └── ping.get.json.ftl
│ └── module
│ │ └── alfresco-kafka-repo
│ │ ├── alfresco-global.properties
│ │ ├── context
│ │ ├── bootstrap-context.xml
│ │ └── service-context.xml
│ │ ├── log4j.properties
│ │ ├── module-context.xml
│ │ └── module.properties
│ └── examples
│ ├── enable_inherit.json
│ ├── revoke.json
│ └── update.json
├── pom.xml
├── run.bat
└── run.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | alf_data_dev
3 | /target
4 | /.classpath
5 | /.project
6 | /.settings
7 | /*.log*
8 | /data/
9 | /logs/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright 2017-2023 Jeffrey T. Potts
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
204 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Alfresco Kafka Integration
2 |
3 | This is an Alfresco repository tier AMP that will publish events to an Apache
4 | Kafka topic when nodes are created, updated, or deleted. Events are also
5 | produced for permission changes, including when inheritance is enabled and
6 | disabled.
7 |
8 | Events are generated using an Alfresco behavior that is bound to various class
9 | policies such as: `onCreateNode`, `onUpdateProperties`, and `beforeDeleteNode`.
10 |
11 | ## Build
12 |
13 | This project uses the Alfresco Maven SDK to build. The output is an AMP that can
14 | be installed into your Alfresco WAR using the Alfresco Module Management Tool
15 | (MMT).
16 |
17 | ## Configure
18 |
19 | There are two configurable settings:
20 |
21 | * Topic: Set the topic that the events should be published to. (Default: alfresco-node-events)
22 | * Bootstrap Servers: Set the Kafka servers to publish to. (Default: kafka:9092). Here 'kafka' is the name of service.
23 |
24 | Both of these settings can be configured by setting the following in alfresco-global.properties:
25 |
26 | kafka.topic=alfresco-node-events
27 | kafka.server=kafka:9092
28 |
29 | See docker-compose.yml file for details.
30 |
31 | ## Example
32 |
33 | This section includes an example of the event JSON. The events are all the same format with the exception of the event
34 | type, which can be one of:
35 |
36 | * CREATE
37 | * UPDATE
38 | * DELETE
39 | * PING
40 | * GRANT
41 | * REVOKE
42 | * ENABLE_INHERIT
43 | * DISABLE_INHERIT
44 |
45 | Here is what an event looks like:
46 |
47 | {
48 | "nodeRef": "70c60aea-d390-4fc7-b836-210c2778035d",
49 | "eventType": "CREATE",
50 | "path": "/{http://www.alfresco.org/model/application/1.0}company_home/{http://www.alfresco.org/model/site/1.0}sites/{http://www.alfresco.org/model/content/1.0}jtp-test-site-1/{http://www.alfresco.org/model/content/1.0}documentLibrary/{http://www.alfresco.org/model/content/1.0}test2.txt",
51 | "created": 1567086666248,
52 | "modified": 1567086666248,
53 | "creator": "admin",
54 | "modifier": "admin",
55 | "mimetype": "text/plain",
56 | "contentType": "content",
57 | "siteId": "jtp-test-site-1",
58 | "size": 4,
59 | "parent": "244a089b-17ad-4a49-81f4-c8b17b7322a6",
60 | "permissions": {
61 | "permissions": [
62 | {
63 | "authority": "GROUP_site_jtp-test-site-1_SiteConsumer",
64 | "authorityType": "GROUP",
65 | "permission": "SiteConsumer",
66 | "inherited": true
67 | },
68 | {
69 | "authority": "GROUP_site_jtp-test-site-1_SiteCollaborator",
70 | "authorityType": "GROUP",
71 | "permission": "SiteCollaborator",
72 | "inherited": true
73 | },
74 | {
75 | "authority": "GROUP_site_jtp-test-site-1_SiteContributor",
76 | "authorityType": "GROUP",
77 | "permission": "SiteContributor",
78 | "inherited": true
79 | },
80 | {
81 | "authority": "GROUP_site_jtp-test-site-1_SiteManager",
82 | "authorityType": "GROUP",
83 | "permission": "SiteManager",
84 | "inherited": true
85 | }
86 | ],
87 | "inheritanceEnabled": true
88 | }
89 | }
90 |
91 | For folders, the size and mimetype are null and are not included in the JSON.
92 |
93 | {
94 | "nodeRef": "8d8396a1-b9f8-444d-b9ea-f3a1e6971285",
95 | "eventType": "UPDATE",
96 | "path": "/{http://www.alfresco.org/model/application/1.0}company_home/{http://www.alfresco.org/model/site/1.0}sites/{http://www.alfresco.org/model/content/1.0}jtp-test-site-1/{http://www.alfresco.org/model/content/1.0}documentLibrary/{http://www.alfresco.org/model/content/1.0}testfolder4",
97 | "created": 1567086551982,
98 | "modified": 1567088364629,
99 | "creator": "admin",
100 | "modifier": "admin",
101 | "contentType": "folder",
102 | "siteId": "jtp-test-site-1",
103 | "parent": "244a089b-17ad-4a49-81f4-c8b17b7322a6",
104 | "permissions": {
105 | "permissions": [
106 | {
107 | "authority": "GROUP_site_jtp-test-site-1_SiteConsumer",
108 | "authorityType": "GROUP",
109 | "permission": "SiteConsumer",
110 | "inherited": true
111 | },
112 | {
113 | "authority": "GROUP_site_jtp-test-site-1_SiteContributor",
114 | "authorityType": "GROUP",
115 | "permission": "SiteContributor",
116 | "inherited": true
117 | },
118 | {
119 | "authority": "GROUP_site_jtp-test-site-1_SiteCollaborator",
120 | "authorityType": "GROUP",
121 | "permission": "SiteCollaborator",
122 | "inherited": true
123 | },
124 | {
125 | "authority": "GROUP_site_jtp-test-site-1_SiteManager",
126 | "authorityType": "GROUP",
127 | "permission": "SiteManager",
128 | "inherited": true
129 | }
130 | ],
131 | "inheritanceEnabled": true
132 | },
133 | "tags": [
134 | "test1",
135 | "test2",
136 | "test3"
137 | ]
138 | }
139 |
140 | Permissions-related events are smaller. For GRANT, REVOKE, ENABLE_INHERIT, and
141 | DISABLE_INHERIT, the event contains only the node reference and the current
142 | access control list:
143 |
144 | {
145 | "nodeRef": "953e16c4-d1f7-421e-bbe1-4f1123429c2a",
146 | "eventType": "DISABLE_INHERIT",
147 | "permissions": {
148 | "permissions": [
149 | {
150 | "authority": "GROUP_site_jtp-test-site-1_SiteManager",
151 | "authorityType": "GROUP",
152 | "permission": "SiteManager",
153 | "inherited": false
154 | },
155 | {
156 | "authority": "tuser1",
157 | "authorityType": "USER",
158 | "permission": "SiteContributor",
159 | "inherited": false
160 | },
161 | {
162 | "authority": "tuser3",
163 | "authorityType": "USER",
164 | "permission": "SiteContributor",
165 | "inherited": false
166 | }
167 | ],
168 | "inheritanceEnabled": false
169 | }
170 | }
171 |
172 | In the example above, inheritance was turned off for a folder, which left the
173 | object with only locally-set permissions.
174 |
175 | ## Running via docker
176 |
177 | 1- Launch containers using `./run.sh build_start` or `./run.bat build_start` and verify that it
178 |
179 | * Runs Alfresco Content Service (ACS)
180 | * (Optional) Runs Alfresco Share
181 | * Runs Alfresco Search Service (ASS)
182 | * Runs PostgreSQL database
183 | * Deploys the JAR assembled module
184 | * Runs Zookeeper
185 | * Runs Kafka
186 |
187 | Additionally, you can use `docker ps` command to checked whether all containers are up and running correctly.
188 |
189 | 2- If you want to watch the messages as they are sent to Kafka, then from $KAFKA_HOME, run:
190 |
191 | `bin/kafka-console-consumer.sh --bootstrap-server localhost:9093 --topic alfresco-node-events --from-beginning`
192 |
193 | For windows:
194 |
195 | `bin\windows\kafka-console-consumer.bat --bootstrap-server localhost:9093 --topic alfresco-node-events --from-beginning`
196 |
197 | ## Consuming Events
198 |
199 | For an example showing how to consume these events from a Spring Boot app, see
200 | [this project](https://github.com/jpotts/alfresco-kafka-listener-example) on
201 | GitHub.
202 |
--------------------------------------------------------------------------------
/alfresco-kafka-model/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /.classpath
3 | /.project
4 | /.settings
5 | /*.log*
6 | /data/
7 | /logs/
8 |
--------------------------------------------------------------------------------
/alfresco-kafka-model/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | alfresco-kafka
9 | com.metaversant
10 | 0.0.3-SNAPSHOT
11 |
12 |
13 | alfresco-kafka-model
14 | jar
15 |
--------------------------------------------------------------------------------
/alfresco-kafka-model/src/main/java/com/metaversant/kafka/model/NodeEvent.java:
--------------------------------------------------------------------------------
1 | package com.metaversant.kafka.model;
2 |
3 | import java.util.Date;
4 | import java.util.List;
5 |
6 | import com.fasterxml.jackson.annotation.JsonInclude;
7 |
8 | import lombok.AllArgsConstructor;
9 | import lombok.Builder;
10 | import lombok.Data;
11 | import lombok.NoArgsConstructor;
12 |
13 |
14 | /**
15 | * Created by jpotts, Metaversant on 6/9/17.
16 | */
17 | @Data
18 | @Builder
19 | @AllArgsConstructor
20 | @NoArgsConstructor
21 | @JsonInclude(JsonInclude.Include.NON_NULL)
22 | public class NodeEvent {
23 |
24 | /**
25 | * The Enum EventType.
26 | */
27 | public enum EventType {
28 |
29 | /** The create. */
30 | CREATE,
31 |
32 | /** The update. */
33 | UPDATE,
34 |
35 | /** The delete. */
36 | DELETE,
37 |
38 | /** The ping. */
39 | PING,
40 |
41 | /** The grant. */
42 | GRANT,
43 |
44 | /** The revoke. */
45 | REVOKE,
46 |
47 | /** The enable inherit. */
48 | ENABLE_INHERIT,
49 |
50 | /** The disable inherit. */
51 | DISABLE_INHERIT
52 | }
53 |
54 | /** The node ref. */
55 | private String nodeRef;
56 |
57 | /** The event type. */
58 | private NodeEvent.EventType eventType;
59 |
60 | /** The path. */
61 | private String path;
62 |
63 | /** The created. */
64 | private Date created;
65 |
66 | /** The modified. */
67 | private Date modified;
68 |
69 | /** The creator. */
70 | private String creator;
71 |
72 | /** The modifier. */
73 | private String modifier;
74 |
75 | /** The mimetype. */
76 | private String mimetype;
77 |
78 | /** The content type. */
79 | private String contentType;
80 |
81 | /** The site id. */
82 | private String siteId;
83 |
84 | /** The size. */
85 | private Long size;
86 |
87 | /** The parent. */
88 | private String parent;
89 |
90 | /** The authority. */
91 | private String authority;
92 |
93 | /** The permission. */
94 | private String permission;
95 |
96 | /** The permissions. */
97 | private NodePermissions permissions;
98 |
99 | /** The tags. */
100 | private List tags;
101 | }
102 |
--------------------------------------------------------------------------------
/alfresco-kafka-model/src/main/java/com/metaversant/kafka/model/NodePermission.java:
--------------------------------------------------------------------------------
1 | package com.metaversant.kafka.model;
2 |
3 | import com.fasterxml.jackson.annotation.JsonInclude;
4 |
5 | import lombok.AllArgsConstructor;
6 | import lombok.Builder;
7 | import lombok.Data;
8 | import lombok.NoArgsConstructor;
9 |
10 | /**
11 | * Created by jpotts, Metaversant on 6/9/17.
12 | */
13 | @Data
14 | @Builder
15 | @AllArgsConstructor
16 | @NoArgsConstructor
17 | @JsonInclude(JsonInclude.Include.NON_NULL)
18 | public class NodePermission {
19 |
20 | /** The authority. */
21 | private String authority;
22 |
23 | /** The authority type. */
24 | private String authorityType;
25 |
26 | /** The permission. */
27 | private String permission;
28 |
29 | /** The is inherited. */
30 | private boolean isInherited;
31 | }
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/alfresco-kafka-model/src/main/java/com/metaversant/kafka/model/NodePermissions.java:
--------------------------------------------------------------------------------
1 | package com.metaversant.kafka.model;
2 |
3 | import java.util.Set;
4 |
5 | import com.fasterxml.jackson.annotation.JsonInclude;
6 |
7 | import lombok.AllArgsConstructor;
8 | import lombok.Builder;
9 | import lombok.Data;
10 | import lombok.NoArgsConstructor;
11 |
12 | /**
13 | * Created by jpotts, Metaversant on 6/9/17.
14 | */
15 | @Data
16 | @Builder
17 | @AllArgsConstructor
18 | @NoArgsConstructor
19 | @JsonInclude(JsonInclude.Include.NON_NULL)
20 | public class NodePermissions {
21 |
22 | /** The permissions. */
23 | private Set permissions;
24 |
25 | /** The is inheritance enabled. */
26 | private boolean isInheritanceEnabled;
27 | }
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /.classpath
3 | /.project
4 | /.settings
5 | /*.log*
6 | /data/
7 | /logs/
8 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/README.md:
--------------------------------------------------------------------------------
1 | # Alfresco ACS JAR Module - SDK 4.1
2 |
3 | This is an ACS project for Alfresco SDK 4.1.
4 |
5 | Run with `./run.sh build_start` or `./run.bat build_start` and verify that it
6 |
7 | * Runs Alfresco Content Service (ACS)
8 | * (Optional) Runs Alfresco Share
9 | * Runs Alfresco Search Service (ASS)
10 | * Runs PostgreSQL database
11 | * Deploys the JAR assembled module
12 | * Runs Zookeeper
13 | * Runs Kafka
14 |
15 | All the services of the project are now run as docker containers. The run script offers the next tasks:
16 |
17 | * `build_start`. Build the whole project, recreate the ACS docker image, start the dockerised environment composed by ACS, Share (optional), ASS
18 | and PostgreSQL and tail the logs of all the containers.
19 | * `build_start_it_supported`. Build the whole project including dependencies required for IT execution, recreate the ACS docker image, start the dockerised environment
20 | composed by ACS, Share (optional), ASS and PostgreSQL and tail the logs of all the containers.
21 | * `start`. Start the dockerised environment without building the project and tail the logs of all the containers.
22 | * `stop`. Stop the dockerised environment.
23 | * `purge`. Stop the dockerised container and delete all the persistent data (docker volumes).
24 | * `tail`. Tail the logs of all the containers.
25 | * `reload_acs`. Build the ACS module, recreate the ACS docker image and restart the ACS container.
26 | * `build_test`. Build the whole project, recreate the ACS docker image, start the dockerised environment, execute the integration tests and stop
27 | the environment.
28 | * `test`. Execute the integration tests (the environment must be already started).
29 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/docker/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.4'
2 | services:
3 |
4 | #Optional service to launch share interface
5 | alfresco-kafka-repo-share:
6 | image: ${docker.share.image}:${alfresco.share.version}
7 | environment:
8 | REPO_HOST: alfresco-kafka-repo-acs
9 | REPO_PORT: 8080
10 | ports:
11 | - "${share.port}:8080"
12 |
13 | alfresco-kafka-repo-acs:
14 | image: alfresco-content-services-alfresco-kafka-repo:development
15 | build:
16 | dockerfile: ./Dockerfile
17 | context: ../../../target
18 | environment:
19 | CATALINA_OPTS: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:8888"
20 | JAVA_OPTS: "
21 | -Dkafka.topic=alfresco-node-events
22 | -Dkafka.server=kafka:9092
23 | "
24 | ports:
25 | - "${acs.port}:8080"
26 | - "${acs.debug.port}:8888"
27 | volumes:
28 | - alfresco-kafka-repo-acs-volume:/usr/local/tomcat/alf_data
29 | - ../../../../logs/alfresco:/usr/local/tomcat/logs
30 | depends_on:
31 | - kafka
32 | - alfresco-kafka-repo-postgres
33 |
34 | alfresco-kafka-repo-postgres:
35 | image: postgres:11.7
36 | environment:
37 | POSTGRES_DB: alfresco
38 | POSTGRES_USER: alfresco
39 | POSTGRES_PASSWORD: alfresco
40 | command: postgres -c max_connections=300 -c log_min_messages=LOG
41 | ports:
42 | - "${postgres.port}:5432"
43 | volumes:
44 | - alfresco-kafka-repo-db-volume:/var/lib/postgresql/data
45 |
46 | alfresco-kafka-repo-ass:
47 | image: alfresco/alfresco-search-services:2.0.0.1
48 | environment:
49 | #Solr needs to know how to register itself with Alfresco
50 | - SOLR_ALFRESCO_HOST=alfresco-kafka-repo-acs
51 | - SOLR_ALFRESCO_PORT=8080
52 | #Alfresco needs to know how to call solr
53 | - SOLR_SOLR_HOST=alfresco-kafka-repo-ass
54 | - SOLR_SOLR_PORT=8983
55 | #Create the default alfresco and archive cores
56 | - SOLR_CREATE_ALFRESCO_DEFAULTS=alfresco,archive
57 | #HTTP by default
58 | - ALFRESCO_SECURE_COMMS=none
59 | ports:
60 | - "8983:8983"
61 | volumes:
62 | - alfresco-kafka-repo-ass-volume:/opt/alfresco-search-services/data
63 |
64 | zookeeper:
65 | image: bitnami/zookeeper:3.6.2
66 | environment:
67 | - ALLOW_ANONYMOUS_LOGIN=yes
68 | ports:
69 | - "2181:2181"
70 | volumes:
71 | - ../../../../data/alfresco-zk:/bitnami/zookeeper
72 | - ../../../../data/alfresco-zk-logs:/opt/bitnami/zookeeper/logs
73 |
74 | kafka:
75 | image: bitnami/kafka:2.6.0
76 | environment:
77 | KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:9092,OUTSIDE://localhost:9093
78 | KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
79 | KAFKA_LISTENERS: INSIDE://0.0.0.0:9092,OUTSIDE://0.0.0.0:9093
80 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
81 | ALLOW_PLAINTEXT_LISTENER: "yes"
82 | KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
83 | ports:
84 | - "9092:9092"
85 | - "9093:9093"
86 | volumes:
87 | - ../../../../data/alfresco-kafka:/bitnami/kafka
88 | - ../../../../data/alfresco-kafka-logs:/opt/bitnami/kafka/logs
89 | depends_on:
90 | - zookeeper
91 |
92 | volumes:
93 | alfresco-kafka-repo-acs-volume:
94 | external: true
95 | alfresco-kafka-repo-db-volume:
96 | external: true
97 | alfresco-kafka-repo-ass-volume:
98 | external: true
--------------------------------------------------------------------------------
/alfresco-kafka-repo/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | alfresco-kafka
8 | com.metaversant
9 | 0.0.3-SNAPSHOT
10 |
11 |
12 | alfresco-kafka-repo
13 | alfresco-kafka-repo Platform/Repository JAR Module
14 | Platform/Repo JAR Module (to be included in the alfresco.war)
15 | jar
16 |
17 |
18 |
19 | com.metaversant
20 | alfresco-kafka-model
21 | 0.0.3-SNAPSHOT
22 |
23 |
24 |
25 |
26 |
27 |
28 | org.apache.maven.plugins
29 | maven-assembly-plugin
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/assembly/amp.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
18 |
19 | build-amp-file
20 |
21 |
22 | amp
23 |
24 |
25 | false
26 |
27 |
28 |
29 |
30 | src/main/resources/alfresco/module/${project.artifactId}/module.properties
31 | true
32 |
33 |
34 |
35 | src/main/assembly/file-mapping.properties
36 | false
37 |
38 |
39 |
40 | src/main/resources/alfresco/module/${project.artifactId}/log4j.properties
41 | false
42 |
43 |
44 |
45 |
46 |
47 |
48 | src/main/assembly/web
49 | web
50 | true
51 |
52 | README.md
53 |
54 |
55 |
56 |
57 |
60 |
61 |
62 | lib
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/assembly/file-mapping.properties:
--------------------------------------------------------------------------------
1 | # Custom AMP to WAR location mappings
2 |
3 | #
4 | # The following property can be used to include the standard set of mappings.
5 | # The contents of this file will override any defaults. The default is
6 | # 'true', i.e. the default mappings will be augmented or modified by values in
7 | # this file.
8 | #
9 | # Default mappings are:
10 | #
11 | # /config=/WEB-INF/classes
12 | # /lib=/WEB-INF/lib
13 | # /licenses=/WEB-INF/licenses
14 | # /web/jsp=/jsp
15 | # /web/css=/css
16 | # /web/images=/images
17 | # /web/scripts=/scripts
18 | # /web/php=/php
19 | #
20 | include.default=true
21 |
22 | #
23 | # Custom mappings. If 'include.default' is false, then this is the complete set.
24 | # Map /web to / in AMP so we can override things like favicon.ico
25 | #
26 | /web=/
27 |
28 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/assembly/web/README.md:
--------------------------------------------------------------------------------
1 | # Web resources that should override out-of-the-box files
2 |
3 | Put here any web resources that should override out-of-the-box
4 | web resources, such as favicon.ico. They will then end up in the
5 | */web* directory in the AMP, and applied to the WAR, and override
6 | any existing web resources in the Alfresco.WAR.
7 |
8 | **Note**. Module dependency needs to be set to amp for the web resources to be applied by MMT:
9 |
10 | `
11 |
12 | ${project.groupId}
13 | some-platform-jar
14 | ${project.version}
15 | amp
16 |
17 | `
18 |
19 | **Important**. New web resources should not be located here, but instead
20 | in the usual place in the *src/main/resources/META-INF/resources* directory.
21 |
22 |
23 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ${docker.acs.image}:${alfresco.platform.version}
2 |
3 | ARG TOMCAT_DIR=/usr/local/tomcat
4 |
5 | USER root
6 |
7 | # Copy Dockerfile to avoid an error if no JARs exist
8 | COPY Dockerfile extensions/*.jar $TOMCAT_DIR/webapps/alfresco/WEB-INF/lib/
9 |
10 | # Copy Dockerfile to avoid an error if no AMPs exist
11 | COPY Dockerfile extensions/*.amp $TOMCAT_DIR/amps/
12 | RUN java -jar $TOMCAT_DIR/alfresco-mmt/alfresco-mmt*.jar install \
13 | $TOMCAT_DIR/amps $TOMCAT_DIR/webapps/alfresco -directory -nobackup -force
14 |
15 | COPY alfresco-global.properties $TOMCAT_DIR/shared/classes/alfresco-global.properties
16 | COPY dev-log4j.properties $TOMCAT_DIR/shared/classes/alfresco/extension
17 | COPY disable-webscript-caching-context.xml $TOMCAT_DIR/shared/classes/alfresco/extension
18 |
19 | COPY hotswap-agent.properties $TOMCAT_DIR/webapps/alfresco/WEB-INF/classes
20 |
21 | # Copy Dockerfile to avoid an error if no license file exists
22 | COPY Dockerfile license/*.* $TOMCAT_DIR/webapps/alfresco/WEB-INF/classes/alfresco/extension/license/
23 |
24 | USER ${USERNAME}
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/docker/alfresco-global.properties:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | # RUN TIME PROPERTIES
16 | # -------------------
17 |
18 | #
19 | # Alfresco configuration for running locally with PostgreSQL Database
20 | #
21 | # Configuration when running Tomcat embedded from Maven.
22 | # Property values from the POM but it can also be edited here.
23 | #
24 |
25 | # Alfresco Repo Webapp (alfresco.war) context, ports etc
26 | alfresco.context=alfresco
27 | alfresco.host=localhost
28 | alfresco.port=8080
29 | alfresco.protocol=http
30 |
31 | # Alfresco Share Webapp (share.war) context, ports etc
32 | share.context=share
33 | share.host=localhost
34 | share.port=8180
35 | share.protocol=http
36 |
37 | # Don't try and recover any index
38 | index.recovery.mode=NONE
39 |
40 | # These jobs seem to require Lucene (Unsupported Operation with Solr) so we disable them / set to future date
41 | # See https://forums.alfresco.com/en/viewtopic.php?f=52&t=41597
42 | # If you want to enable them (and so full WQS functionality), please also set index.subsystem.name=lucene
43 | wcmqs.dynamicCollectionProcessor.schedule=0 30 2 * * ? 2060
44 | wcmqs.feedbackProcessor.schedule=0 40 2 * * ? 2060
45 | wcmqs.publishQueueProcessor.schedule=0 50 2 * * ? 2060
46 |
47 | # Fail or not when there are node integrity checker errors
48 | integrity.failOnError=true
49 |
50 | # Alfresco Repository PostgreSQL Database configuration.
51 | # The PostgreSQL Driver is brought in via the tomcat7-maven-plugin as a dependency.
52 | db.driver=org.postgresql.Driver
53 |
54 | # This Alfresco Platform Configuration file should be used for custom properties that are introduced by this module.
55 | # Define default values for all properties here.
56 | # System Administrators can override these values in environment specific configurations in
57 | # alfresco/tomcat/shared/classes/alfresco-global.properties.
58 | #
59 | index.subsystem.name=solr6
60 | solr.host=alfresco-kafka-repo-ass
61 | solr.port=8983
62 | solr.secureComms=none
63 |
64 | db.username=alfresco
65 | db.password=alfresco
66 | db.pool.initial=10
67 | db.pool.max=100
68 |
69 | db.url=jdbc:postgresql://alfresco-kafka-repo-postgres:5432/alfresco
70 |
71 | # File servers related properties
72 | # For local runs we disable CIFS and FTP
73 | cifs.enabled=false
74 | ftp.enabled=false
75 |
76 | csrf.filter.enabled=false
77 |
78 | # Embedded broker without persistence
79 | messaging.broker.url=vm://localhost?broker.persistent=false
80 |
81 | # Disable ATS
82 | transform.service.enabled=false
83 | local.transform.service.enabled=false
84 | legacy.transform.service.enabled=false
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/docker/dev-log4j.properties:
--------------------------------------------------------------------------------
1 | # Set root logger level to error
2 | log4j.rootLogger=error,Console,File
3 |
4 |
5 | # All outputs currently set to be a ConsoleAppender.
6 | log4j.appender.Console=org.apache.log4j.ConsoleAppender
7 | log4j.appender.Console.layout=org.apache.log4j.PatternLayout
8 |
9 | # use log4j NDC to replace %x with tenant domain / username
10 | log4j.appender.Console.layout.ConversionPattern=%d{ISO8601} %x %-5p [%c{3}] [%t] %m%n
11 | #log4j.appender.Console.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c] %m%n
12 |
13 | log4j.appender.File=org.apache.log4j.DailyRollingFileAppender
14 | log4j.appender.File.File=/usr/local/tomcat/logs/alfresco.log
15 | log4j.appender.File.Append=true
16 | log4j.appender.File.DatePattern='.'yyyy-MM-dd
17 | log4j.appender.File.layout=org.apache.log4j.PatternLayout
18 | log4j.appender.File.layout.ConversionPattern=%d{yyyy-MM-dd} %d{ABSOLUTE} %-5p [%c] [%t] %m%n
19 |
20 | #log4j.appender.file=org.apache.log4j.FileAppender
21 | #log4j.appender.file.File=hibernate.log
22 | #log4j.appender.file.layout=org.apache.log4j.PatternLayout
23 | #log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
24 |
25 |
26 | # Commented-in loggers will be exposed as JMX MBeans (refer to org.alfresco.repo.admin.Log4JHierarchyInit)
27 | # Hence, generally useful loggers should be listed with at least ERROR level to allow simple runtime
28 | # control of the level via a suitable JMX Console. Also, any other loggers can be added transiently via
29 | # Log4j addLoggerMBean as long as the logger exists and has been loaded.
30 |
31 | # Hibernate
32 | log4j.logger.org.hibernate=error
33 | log4j.logger.org.hibernate.util.JDBCExceptionReporter=fatal
34 | log4j.logger.org.hibernate.event.def.AbstractFlushingEventListener=fatal
35 | log4j.logger.org.hibernate.type=warn
36 | log4j.logger.org.hibernate.cfg.SettingsFactory=warn
37 |
38 | # Spring
39 | log4j.logger.org.springframework=warn
40 | # Turn off Spring remoting warnings that should really be info or debug.
41 | log4j.logger.org.springframework.remoting.support=error
42 | log4j.logger.org.springframework.util=error
43 |
44 | # Axis/WSS4J
45 | log4j.logger.org.apache.axis=info
46 | log4j.logger.org.apache.ws=info
47 |
48 | # CXF
49 | log4j.logger.org.apache.cxf=error
50 |
51 | # MyFaces
52 | log4j.logger.org.apache.myfaces.util.DebugUtils=info
53 | log4j.logger.org.apache.myfaces.el.VariableResolverImpl=error
54 | log4j.logger.org.apache.myfaces.application.jsp.JspViewHandlerImpl=error
55 | log4j.logger.org.apache.myfaces.taglib=error
56 |
57 | # OpenOfficeConnection
58 | log4j.logger.net.sf.jooreports.openoffice.connection=fatal
59 |
60 | # log prepared statement cache activity log4j.logger.org.hibernate.ps.PreparedStatementCache=info
61 |
62 | # Alfresco
63 | log4j.logger.org.alfresco=error
64 | log4j.logger.org.alfresco.repo.admin=info
65 | log4j.logger.org.alfresco.repo.transaction=warn
66 | log4j.logger.org.alfresco.repo.cache.TransactionalCache=warn
67 | log4j.logger.org.alfresco.repo.model.filefolder=warn
68 | log4j.logger.org.alfresco.repo.tenant=info
69 | log4j.logger.org.alfresco.config=warn
70 | log4j.logger.org.alfresco.config.JndiObjectFactoryBean=warn
71 | log4j.logger.org.alfresco.config.JBossEnabledWebApplicationContext=warn
72 | log4j.logger.org.alfresco.repo.management.subsystems=warn
73 | log4j.logger.org.alfresco.repo.management.subsystems.ChildApplicationContextFactory=info
74 | log4j.logger.org.alfresco.repo.management.subsystems.ChildApplicationContextFactory$ChildApplicationContext=warn
75 | log4j.logger.org.alfresco.repo.security.sync=info
76 | log4j.logger.org.alfresco.repo.security.person=info
77 |
78 | log4j.logger.org.alfresco.sample=info
79 | log4j.logger.org.alfresco.web=info
80 | #log4j.logger.org.alfresco.web.app.AlfrescoNavigationHandler=debug
81 | #log4j.logger.org.alfresco.web.ui.repo.component.UIActions=debug
82 | #log4j.logger.org.alfresco.web.ui.repo.tag.PageTag=debug
83 | #log4j.logger.org.alfresco.web.bean.clipboard=debug
84 | log4j.logger.org.alfresco.service.descriptor.DescriptorService=info
85 | #log4j.logger.org.alfresco.web.page=debug
86 |
87 | log4j.logger.org.alfresco.repo.importer.ImporterBootstrap=error
88 | #log4j.logger.org.alfresco.repo.importer.ImporterBootstrap=info
89 |
90 | log4j.logger.org.alfresco.repo.admin.patch.PatchExecuter=info
91 | log4j.logger.org.alfresco.repo.domain.patch.ibatis.PatchDAOImpl=info
92 |
93 | # Specific patches
94 | log4j.logger.org.alfresco.repo.admin.patch.impl.DeploymentMigrationPatch=info
95 | log4j.logger.org.alfresco.repo.version.VersionMigrator=info
96 |
97 | log4j.logger.org.alfresco.repo.module.ModuleServiceImpl=info
98 | log4j.logger.org.alfresco.repo.domain.schema.SchemaBootstrap=info
99 | log4j.logger.org.alfresco.repo.admin.ConfigurationChecker=info
100 | log4j.logger.org.alfresco.repo.node.index.AbstractReindexComponent=warn
101 | log4j.logger.org.alfresco.repo.node.index.IndexTransactionTracker=warn
102 | log4j.logger.org.alfresco.repo.node.index.FullIndexRecoveryComponent=info
103 | log4j.logger.org.alfresco.util.OpenOfficeConnectionTester=info
104 | log4j.logger.org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl=warn
105 | log4j.logger.org.alfresco.repo.domain.hibernate.DirtySessionMethodInterceptor=warn
106 | log4j.logger.org.alfresco.repo.transaction.RetryingTransactionHelper=warn
107 | log4j.logger.org.alfresco.util.transaction.SpringAwareUserTransaction.trace=warn
108 | log4j.logger.org.alfresco.util.AbstractTriggerBean=warn
109 | log4j.logger.org.alfresco.enterprise.repo.cluster=info
110 | log4j.logger.org.alfresco.repo.version.Version2ServiceImpl=warn
111 |
112 | #log4j.logger.org.alfresco.web.app.DebugPhaseListener=debug
113 | log4j.logger.org.alfresco.repo.node.db.NodeStringLengthWorker=info
114 |
115 | log4j.logger.org.alfresco.repo.workflow=info
116 |
117 | # CIFS server debugging
118 | log4j.logger.org.alfresco.smb.protocol=error
119 | #log4j.logger.org.alfresco.smb.protocol.auth=debug
120 | #log4j.logger.org.alfresco.acegi=debug
121 |
122 | # FTP server debugging
123 | log4j.logger.org.alfresco.ftp.protocol=error
124 | #log4j.logger.org.alfresco.ftp.server=debug
125 |
126 | # WebDAV debugging
127 | #log4j.logger.org.alfresco.webdav.protocol=debug
128 | log4j.logger.org.alfresco.webdav.protocol=info
129 |
130 | # NTLM servlet filters
131 | #log4j.logger.org.alfresco.web.app.servlet.NTLMAuthenticationFilter=debug
132 | #log4j.logger.org.alfresco.repo.webdav.auth.NTLMAuthenticationFilter=debug
133 |
134 | # Kerberos servlet filters
135 | #log4j.logger.org.alfresco.web.app.servlet.KerberosAuthenticationFilter=debug
136 | #log4j.logger.org.alfresco.repo.webdav.auth.KerberosAuthenticationFilter=debug
137 |
138 | # File servers
139 | log4j.logger.org.alfresco.fileserver=warn
140 |
141 | # Repo filesystem debug logging
142 | #log4j.logger.org.alfresco.filesys.repo.ContentDiskDriver=debug
143 |
144 | # Integrity message threshold - if 'failOnViolation' is off, then WARNINGS are generated
145 | log4j.logger.org.alfresco.repo.node.integrity=ERROR
146 |
147 | # Indexer debugging
148 | log4j.logger.org.alfresco.repo.search.Indexer=error
149 | #log4j.logger.org.alfresco.repo.search.Indexer=debug
150 |
151 | log4j.logger.org.alfresco.repo.search.impl.lucene.index=error
152 | log4j.logger.org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexerImpl=warn
153 | #log4j.logger.org.alfresco.repo.search.impl.lucene.index=DEBUG
154 |
155 | # Audit debugging
156 | # log4j.logger.org.alfresco.repo.audit=DEBUG
157 | # log4j.logger.org.alfresco.repo.audit.model=DEBUG
158 |
159 | # Property sheet and modelling debugging
160 | # change to error to hide the warnings about missing properties and associations
161 | log4j.logger.alfresco.missingProperties=warn
162 |
163 | # Dictionary/Model debugging
164 | log4j.logger.org.alfresco.repo.dictionary=warn
165 | log4j.logger.org.alfresco.repo.dictionary.types.period=warn
166 |
167 | # Virtualization Server Registry
168 | log4j.logger.org.alfresco.mbeans.VirtServerRegistry=error
169 |
170 | # Spring context runtime property setter
171 | log4j.logger.org.alfresco.util.RuntimeSystemPropertiesSetter=info
172 |
173 | # Debugging options for clustering
174 | log4j.logger.org.alfresco.repo.content.ReplicatingContentStore=error
175 | log4j.logger.org.alfresco.repo.content.replication=error
176 |
177 | #log4j.logger.org.alfresco.repo.deploy.DeploymentServiceImpl=debug
178 |
179 | # Activity service
180 | log4j.logger.org.alfresco.repo.activities=warn
181 |
182 | # User usage tracking
183 | log4j.logger.org.alfresco.repo.usage=info
184 |
185 | # Sharepoint
186 | log4j.logger.org.alfresco.module.vti=info
187 |
188 | # Forms Engine
189 | log4j.logger.org.alfresco.web.config.forms=info
190 | log4j.logger.org.alfresco.web.scripts.forms=info
191 |
192 | # CMIS
193 | log4j.logger.org.alfresco.opencmis=error
194 | log4j.logger.org.alfresco.opencmis.AlfrescoCmisServiceInterceptor=error
195 | log4j.logger.org.alfresco.cmis=error
196 | log4j.logger.org.alfresco.cmis.dictionary=warn
197 | log4j.logger.org.apache.chemistry.opencmis=info
198 | log4j.logger.org.apache.chemistry.opencmis.server.impl.browser.CmisBrowserBindingServlet=OFF
199 | log4j.logger.org.apache.chemistry.opencmis.server.impl.atompub.CmisAtomPubServlet=OFF
200 |
201 | # IMAP
202 | log4j.logger.org.alfresco.repo.imap=info
203 |
204 | # JBPM
205 | # Note: non-fatal errors (eg. logged during job execution) should be handled by Alfresco's retrying transaction handler
206 | log4j.logger.org.jbpm.graph.def.GraphElement=fatal
207 |
208 | #log4j.logger.org.alfresco.repo.googledocs=debug
209 |
210 |
211 | # Web Framework
212 | log4j.logger.org.springframework.extensions.webscripts=info
213 | log4j.logger.org.springframework.extensions.webscripts.ScriptLogger=warn
214 | log4j.logger.org.springframework.extensions.webscripts.ScriptDebugger=off
215 |
216 | # Repository
217 | log4j.logger.org.alfresco.repo.web.scripts=warn
218 | log4j.logger.org.alfresco.repo.web.scripts.BaseWebScriptTest=info
219 | log4j.logger.org.alfresco.repo.web.scripts.AlfrescoRhinoScriptDebugger=off
220 | log4j.logger.org.alfresco.repo.jscript=error
221 | log4j.logger.org.alfresco.repo.jscript.ScriptLogger=debug
222 | log4j.logger.org.alfresco.repo.cmis.rest.CMISTest=info
223 |
224 | log4j.logger.org.alfresco.repo.domain.schema.script.ScriptBundleExecutorImpl=off
225 | log4j.logger.org.alfresco.repo.domain.schema.script.ScriptExecutorImpl=info
226 |
227 | log4j.logger.org.alfresco.repo.search.impl.solr.facet.SolrFacetServiceImpl=info
228 |
229 | # Bulk Filesystem Import Tool
230 | log4j.logger.org.alfresco.repo.bulkimport=warn
231 |
232 | # Freemarker
233 | # Note the freemarker.runtime logger is used to log non-fatal errors that are handled by Alfresco's retrying transaction handler
234 | log4j.logger.freemarker.runtime=
235 |
236 | # Metadata extraction
237 | log4j.logger.org.alfresco.repo.content.metadata.AbstractMappingMetadataExtracter=info
238 |
239 |
240 | # Reduces PDFont error level due to ALF-7105
241 | log4j.logger.org.apache.pdfbox.pdmodel.font.PDSimpleFont=fatal
242 | log4j.logger.org.apache.pdfbox.pdmodel.font.PDFont=fatal
243 | log4j.logger.org.apache.pdfbox.pdmodel.font.PDCIDFont=fatal
244 |
245 | # no index support
246 | log4j.logger.org.alfresco.repo.search.impl.noindex.NoIndexIndexer=fatal
247 | log4j.logger.org.alfresco.repo.search.impl.noindex.NoIndexSearchService=fatal
248 |
249 | # lucene index warnings
250 | log4j.logger.org.alfresco.repo.search.impl.lucene.index.IndexInfo=warn
251 |
252 | # Warn about RMI socket bind retries.
253 | log4j.logger.org.alfresco.util.remote.server.socket.HostConfigurableSocketFactory=warn
254 |
255 | log4j.logger.org.alfresco.repo.usage.RepoUsageMonitor=info
256 |
257 | # Authorization
258 | log4j.logger.org.alfresco.enterprise.repo.authorization.AuthorizationService=info
259 | log4j.logger.org.alfresco.enterprise.repo.authorization.AuthorizationsConsistencyMonitor=warn
260 |
261 | #-----------------------------------------------------------------------
262 | # Platform module logging
263 | #-----------------------------------------------------------------------
264 | log4j.logger.com.metaversant.kafka=debug,alfkafka
265 |
266 | #Solr specific logs
267 | log4j.logger.org.alfresco.solr.query.AbstractQParser=DEBUG,alfkafka
268 | log4j.logger.org.alfresco.repo.search.impl.solr.SolrQueryHTTPClient=DEBUG,alfkafka
269 |
270 | #Kafka logs
271 | log4j.logger.org.apache.kafka.clients.producer.KafkaProducer=debug,alfkafka
272 | log4j.logger.org.apache.kafka.clients.producer.ProducerRecord=debug,alfkafka
273 |
274 | log4j.appender.alfkafka=org.apache.log4j.DailyRollingFileAppender
275 | log4j.appender.alfkafka.File=/usr/local/tomcat/logs/alfresco-kafka.log
276 | log4j.appender.alfkafka.Append=true
277 | log4j.appender.alfkafka.DatePattern='.'yyyy-MM-dd
278 | log4j.appender.alfkafka.layout=org.apache.log4j.PatternLayout
279 | log4j.appender.alfkafka.layout.ConversionPattern=%d{yyyy-MM-dd} %d{ABSOLUTE} %-5p [%c] [%t] %m%n
280 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/docker/disable-webscript-caching-context.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
20 |
31 |
32 |
33 | javascript
34 |
35 |
36 | js
37 |
38 |
39 |
40 | false
41 |
42 |
43 |
44 |
45 | true
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | ${spaces.store}
56 |
57 |
58 | ${spaces.company_home.childname}
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/docker/hotswap-agent.properties:
--------------------------------------------------------------------------------
1 | # Enable hotswap so that changes in this module will be automatically reloaded
2 | # Watch for changed class files on watchResources path and reload class definition in the running application.
3 | autoHotswap=true
4 | #autoHotswap.port=8000
5 |
6 | # Add a directory prior to application classpath (load classes and resources).
7 | #
8 | # This may be useful for example in multi module maven project to load class changes from upstream project
9 | # classes. Set extraClasspath to upstream project compiler output and .class file will have precedence to
10 | # classes from built JAR file.
11 | # i.e. monitor /target/classes
12 | # should work with extraClasspath=${project.build.outputDirectory}
13 | # If not try
14 | extraClasspath=/usr/local/tomcat/hotswap-agent
15 |
16 | # Comma separated list of disabled plugins
17 | # Use plugin name - e.g.
18 | # Hotswapper, AnonymousClassPatch, WatchResources, Hibernate, Spring, Jersey2, Jetty, Tomcat,
19 | # ZK, Logback, JSF, Seam, ELResolver, OsgiEquinox, Proxy, WebObjects, Weld, JBossModules, Resteasy, Gae
20 | disabledPlugins=Hibernate,Spring
21 |
22 | # Add a directory prior to webapp path (load webapp resources).
23 | #
24 | # Load web application resources (such as HTML, JSP, CSS, ...) from this directory prior to default processing.
25 | # Use this setting to set to serve resources from source directory directly (e.g. src/main/webapp).
26 | extraWebappContext=/usr/local/tomcat/hotswap-agent/alfresco-kafka-repo/target/classes/META-INF/resources;
27 |
28 | # Load static web resources from different directory.
29 | #
30 | # This setting is dependent on application server plugin(Jetty, Tomcat, JBoss, ...)
31 | webappDir=/usr/local/tomcat/hotswap-agent/alfresco-kafka-repo/target/classes/META-INF/resources;
32 |
33 | # Watch for changes in a directory (resources only).
34 | #
35 | # Similar to extraClasspath this property adds classpath when searching for resources (not classes).
36 | # While extra classpath just modifies the classloader, this setting does nothing until the resource
37 | # is really changed.
38 | #
39 | # Sometimes it is not possible to point extraClasspath to your i.e. src/main/resources, because there are multiple
40 | # replacements of resources in a building step (maven filtering resource option).
41 | # This setting will leave i.e. src/target/classes as default source for resources, but after the resource is modified
42 | # in src/main/resources, the new changed resource is served instead.
43 | # watchResources=
44 |
45 | LOGGER.org.hotswap.agent=DEBUG
46 | #LOGGER.org.hotswap.agent.plugin=TRACE
47 | #LOGGER.org.hotswap.agent.watch=TRACE
48 | #LOGGER.org.hotswap.agent.command=TRACE
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/docker/license/README.md:
--------------------------------------------------------------------------------
1 | # Enterprise License location
2 |
3 | Put the Alfresco Enterprise license file in this directory.
4 | It will then be copied into the ACS container in the
5 | $TOMCAT_DIR/WEB-INF/classes/alfresco/extension/license directory.
6 |
7 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/java/com/metaversant/kafka/behavior/GenerateNodeEvent.java:
--------------------------------------------------------------------------------
1 | package com.metaversant.kafka.behavior;
2 |
3 | import java.io.Serializable;
4 | import java.util.Map;
5 |
6 | import org.alfresco.model.ContentModel;
7 | import org.alfresco.repo.node.NodeServicePolicies;
8 | import org.alfresco.repo.policy.Behaviour;
9 | import org.alfresco.repo.policy.JavaBehaviour;
10 | import org.alfresco.repo.policy.PolicyComponent;
11 | import org.alfresco.service.cmr.repository.ChildAssociationRef;
12 | import org.alfresco.service.cmr.repository.NodeRef;
13 | import org.alfresco.service.cmr.repository.NodeService;
14 | import org.alfresco.service.namespace.QName;
15 | import org.apache.log4j.Logger;
16 |
17 | import com.metaversant.kafka.model.NodeEvent;
18 | import com.metaversant.kafka.service.MessageService;
19 | import com.metaversant.kafka.transform.NodeRefToNodeEvent;
20 | import com.metaversant.kafka.transform.NodeRefToNodePermissions;
21 |
22 | /**
23 | * Created by jpotts, Metaversant on 6/9/17.
24 | */
25 | public class GenerateNodeEvent implements NodeServicePolicies.BeforeDeleteNodePolicy,
26 | NodeServicePolicies.OnCreateNodePolicy, NodeServicePolicies.OnUpdatePropertiesPolicy {
27 |
28 | /** The Constant LOGGER. */
29 | private static final Logger LOGGER = Logger.getLogger(GenerateNodeEvent.class);
30 |
31 | ///////////////////// Dependencies [Start] ////////////////
32 | /** The node service. */
33 | private NodeService nodeService;
34 |
35 | /** The policy component. */
36 | private PolicyComponent policyComponent;
37 |
38 | /** The message service. */
39 | private MessageService messageService;
40 |
41 | /** The node transformer. */
42 | private NodeRefToNodeEvent nodeTransformer;
43 |
44 | /** The node permissions transformer. */
45 | private NodeRefToNodePermissions nodePermissionsTransformer;
46 | ///////////////////// Dependencies [End] //////////////////
47 |
48 | ///////////////////// Behaviours [Start] //////////////////
49 | /** The on create node. */
50 | private Behaviour onCreateNode;
51 |
52 | /** The before delete node. */
53 | private Behaviour beforeDeleteNode;
54 |
55 | /** The on update properties. */
56 | private Behaviour onUpdateProperties;
57 | ///////////////////// Behaviours [End] //////////////////
58 |
59 | /**
60 | * Inits the.
61 | */
62 | public void init() {
63 |
64 | if (LOGGER.isDebugEnabled()) {
65 | LOGGER.debug("Initializing GenerateNodeEvent behaviors");
66 | }
67 |
68 | // Create behaviours
69 | this.onCreateNode = new JavaBehaviour(this, "onCreateNode", Behaviour.NotificationFrequency.TRANSACTION_COMMIT);
70 | this.beforeDeleteNode = new JavaBehaviour(this, "beforeDeleteNode", Behaviour.NotificationFrequency.FIRST_EVENT);
71 | this.onUpdateProperties = new JavaBehaviour(this, "onUpdateProperties", Behaviour.NotificationFrequency.TRANSACTION_COMMIT);
72 |
73 | // Bind behaviours to node policies
74 | this.policyComponent.bindClassBehaviour(
75 | NodeServicePolicies.OnCreateNodePolicy.QNAME,
76 | ContentModel.TYPE_CMOBJECT,
77 | this.onCreateNode);
78 |
79 | this.policyComponent.bindClassBehaviour(
80 | NodeServicePolicies.BeforeDeleteNodePolicy.QNAME,
81 | ContentModel.TYPE_CMOBJECT,
82 | this.beforeDeleteNode);
83 |
84 | this.policyComponent.bindClassBehaviour(
85 | NodeServicePolicies.OnUpdatePropertiesPolicy.QNAME,
86 | ContentModel.TYPE_CMOBJECT,
87 | this.onUpdateProperties);
88 |
89 | }
90 |
91 | /**
92 | * On create node.
93 | *
94 | * @param childAssocRef the child assoc ref
95 | */
96 | @Override
97 | public void onCreateNode(final ChildAssociationRef childAssocRef) {
98 | if (LOGGER.isDebugEnabled()) {
99 | LOGGER.debug("Inside onCreateNode");
100 | }
101 | final NodeRef nodeRef = childAssocRef.getChildRef();
102 | if (nodeService.exists(nodeRef)) {
103 | final NodeEvent nodeEvent = nodeTransformer.transform(nodeRef);
104 | nodeEvent.setEventType(NodeEvent.EventType.CREATE);
105 | nodeEvent.setPermissions(nodePermissionsTransformer.transform(nodeRef));
106 | messageService.publish(nodeEvent);
107 | }
108 | }
109 |
110 | /**
111 | * Before delete node.
112 | *
113 | * @param nodeRef the node ref
114 | */
115 | @Override
116 | public void beforeDeleteNode(final NodeRef nodeRef) {
117 | if (LOGGER.isDebugEnabled()) {
118 | LOGGER.debug("Inside onDeleteNode");
119 | }
120 | if (nodeService.exists(nodeRef)) {
121 | final NodeEvent nodeEvent = nodeTransformer.transform(nodeRef);
122 | nodeEvent.setEventType(NodeEvent.EventType.DELETE);
123 | nodeEvent.setPermissions(nodePermissionsTransformer.transform(nodeRef));
124 | messageService.publish(nodeEvent);
125 | }
126 | }
127 |
128 | /**
129 | * On update properties.
130 | *
131 | * @param nodeRef the node ref
132 | * @param beforeProps the before props
133 | * @param afterProps the after props
134 | */
135 | @Override
136 | public void onUpdateProperties(final NodeRef nodeRef, final Map beforeProps,
137 | final Map afterProps) {
138 | if (LOGGER.isDebugEnabled()) {
139 | LOGGER.debug("Inside onUpdateProperties");
140 | }
141 | if (nodeService.exists(nodeRef)) {
142 | final NodeEvent nodeEvent = nodeTransformer.transform(nodeRef);
143 | nodeEvent.setEventType(NodeEvent.EventType.UPDATE);
144 | nodeEvent.setPermissions(nodePermissionsTransformer.transform(nodeRef));
145 | messageService.publish(nodeEvent);
146 | }
147 | }
148 |
149 | /**
150 | * Sets the node service.
151 | *
152 | * @param nodeService the new node service
153 | */
154 | public void setNodeService(final NodeService nodeService) {
155 | this.nodeService = nodeService;
156 | }
157 |
158 | /**
159 | * Sets the policy component.
160 | *
161 | * @param policyComponent the new policy component
162 | */
163 | public void setPolicyComponent(final PolicyComponent policyComponent) {
164 | this.policyComponent = policyComponent;
165 | }
166 |
167 | /**
168 | * Sets the message service.
169 | *
170 | * @param messageService the new message service
171 | */
172 | public void setMessageService(final MessageService messageService) {
173 | this.messageService = messageService;
174 | }
175 |
176 | /**
177 | * Sets the node transformer.
178 | *
179 | * @param nodeTransformer the new node transformer
180 | */
181 | public void setNodeTransformer(final NodeRefToNodeEvent nodeTransformer) {
182 | this.nodeTransformer = nodeTransformer;
183 | }
184 |
185 | /**
186 | * Sets the node permissions transformer.
187 | *
188 | * @param nodePermissionsTransformer the new node permissions transformer
189 | */
190 | public void setNodePermissionsTransformer(final NodeRefToNodePermissions nodePermissionsTransformer) {
191 | this.nodePermissionsTransformer = nodePermissionsTransformer;
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/java/com/metaversant/kafka/behavior/GenerateNodePermissionEvent.java:
--------------------------------------------------------------------------------
1 | package com.metaversant.kafka.behavior;
2 |
3 | import org.alfresco.model.ContentModel;
4 | import org.alfresco.repo.policy.Behaviour;
5 | import org.alfresco.repo.policy.JavaBehaviour;
6 | import org.alfresco.repo.policy.PolicyComponent;
7 | import org.alfresco.repo.security.permissions.PermissionServicePolicies;
8 | import org.alfresco.service.cmr.repository.NodeRef;
9 | import org.apache.log4j.Logger;
10 |
11 | import com.metaversant.kafka.model.NodeEvent;
12 | import com.metaversant.kafka.service.MessageService;
13 | import com.metaversant.kafka.transform.NodeRefToNodePermissions;
14 |
15 |
16 | /**
17 | * Created by jpotts, Metaversant on 8/28/19.
18 | */
19 | public class GenerateNodePermissionEvent
20 | implements PermissionServicePolicies.OnGrantLocalPermission, PermissionServicePolicies.OnRevokeLocalPermission,
21 | PermissionServicePolicies.OnInheritPermissionsDisabled, PermissionServicePolicies.OnInheritPermissionsEnabled {
22 |
23 | /** The LOGGER. */
24 | private static final Logger LOGGER = Logger.getLogger(GenerateNodePermissionEvent.class);
25 |
26 | ///////////////////// Dependencies [Start] ////////////////
27 | /** The policy component. */
28 | private PolicyComponent policyComponent;
29 |
30 | /** The message service. */
31 | private MessageService messageService;
32 |
33 | /** The node permissions transformer. */
34 | private NodeRefToNodePermissions nodePermissionsTransformer;
35 | ///////////////////// Dependencies [End] //////////////////
36 |
37 | ///////////////////// Behaviours [Start] //////////////////
38 | /** The on grant local permission. */
39 | private Behaviour onGrantLocalPermission;
40 |
41 | /** The on revoke local permission. */
42 | private Behaviour onRevokeLocalPermission;
43 |
44 | /** The on inherit permissions enabled. */
45 | private Behaviour onInheritPermissionsEnabled;
46 |
47 | /** The on inherit permissions disabled. */
48 | private Behaviour onInheritPermissionsDisabled;
49 | ///////////////////// Behaviours [End] //////////////////
50 |
51 | /**
52 | * Inits the.
53 | */
54 | public void init() {
55 |
56 | if (LOGGER.isDebugEnabled()) {
57 | LOGGER.debug("Initializing GenerateNodePermissionEvent behaviors");
58 | }
59 |
60 | // Create behaviours
61 | this.onGrantLocalPermission = new JavaBehaviour(this, "onGrantLocalPermission", Behaviour.NotificationFrequency.EVERY_EVENT);
62 | this.onRevokeLocalPermission = new JavaBehaviour(this, "onRevokeLocalPermission", Behaviour.NotificationFrequency.EVERY_EVENT);
63 | this.onInheritPermissionsEnabled = new JavaBehaviour(this, "onInheritPermissionsEnabled", Behaviour.NotificationFrequency.EVERY_EVENT);
64 | this.onInheritPermissionsDisabled = new JavaBehaviour(this, "onInheritPermissionsDisabled", Behaviour.NotificationFrequency.EVERY_EVENT);
65 |
66 | // Bind behaviours to node policies
67 | this.policyComponent.bindClassBehaviour(
68 | PermissionServicePolicies.OnGrantLocalPermission.QNAME,
69 | ContentModel.TYPE_CMOBJECT,
70 | this.onGrantLocalPermission);
71 |
72 | this.policyComponent.bindClassBehaviour(
73 | PermissionServicePolicies.OnRevokeLocalPermission.QNAME,
74 | ContentModel.TYPE_CMOBJECT,
75 | this.onRevokeLocalPermission);
76 |
77 | this.policyComponent.bindClassBehaviour(
78 | PermissionServicePolicies.OnInheritPermissionsEnabled.QNAME,
79 | ContentModel.TYPE_BASE,
80 | this.onInheritPermissionsEnabled);
81 |
82 | this.policyComponent.bindClassBehaviour(
83 | PermissionServicePolicies.OnInheritPermissionsDisabled.QNAME,
84 | ContentModel.TYPE_BASE,
85 | this.onInheritPermissionsDisabled);
86 |
87 | }
88 |
89 | /**
90 | * On grant local permission.
91 | *
92 | * @param nodeRef the node ref
93 | * @param authority the authority
94 | * @param permission the permission
95 | */
96 | @Override
97 | public void onGrantLocalPermission(final NodeRef nodeRef, final String authority, final String permission) {
98 | if (LOGGER.isDebugEnabled()) {
99 | LOGGER.debug("inside onGrantLocalPermission");
100 | }
101 | final NodeEvent nodeEvent = NodeEvent.builder()
102 | .eventType(NodeEvent.EventType.GRANT)
103 | .nodeRef(nodeRef.getId())
104 | .authority(authority)
105 | .permission(permission)
106 | .build();
107 | nodeEvent.setPermissions(nodePermissionsTransformer.transform(nodeRef));
108 | messageService.publish(nodeEvent);
109 | }
110 |
111 | /**
112 | * On revoke local permission.
113 | *
114 | * @param nodeRef the node ref
115 | * @param authority the authority
116 | * @param permission the permission
117 | */
118 | @Override
119 | public void onRevokeLocalPermission(final NodeRef nodeRef, final String authority, final String permission) {
120 | if (LOGGER.isDebugEnabled()) {
121 | LOGGER.debug("inside onRevokeLocalPermission");
122 | }
123 | final NodeEvent nodeEvent = NodeEvent.builder()
124 | .eventType(NodeEvent.EventType.REVOKE)
125 | .nodeRef(nodeRef.getId())
126 | .authority(authority)
127 | .permission(permission)
128 | .build();
129 | nodeEvent.setPermissions(nodePermissionsTransformer.transform(nodeRef));
130 | messageService.publish(nodeEvent);
131 | }
132 |
133 | /**
134 | * On inherit permissions disabled.
135 | *
136 | * @param nodeRef the node ref
137 | * @param async the async
138 | */
139 | @Override
140 | public void onInheritPermissionsDisabled(final NodeRef nodeRef, final boolean async) {
141 | if (LOGGER.isDebugEnabled()) {
142 | LOGGER.debug("inside onInheritPermissionsDisabled");
143 | }
144 | final NodeEvent nodeEvent = NodeEvent.builder()
145 | .eventType(NodeEvent.EventType.DISABLE_INHERIT)
146 | .nodeRef(nodeRef.getId())
147 | .build();
148 | nodeEvent.setPermissions(nodePermissionsTransformer.transform(nodeRef));
149 | messageService.publish(nodeEvent);
150 | }
151 |
152 | /**
153 | * On inherit permissions enabled.
154 | *
155 | * @param nodeRef the node ref
156 | */
157 | @Override
158 | public void onInheritPermissionsEnabled(final NodeRef nodeRef) {
159 | if (LOGGER.isDebugEnabled()) {
160 | LOGGER.debug("inside onInheritPermissionsEnabled");
161 | }
162 | final NodeEvent nodeEvent = NodeEvent.builder()
163 | .eventType(NodeEvent.EventType.ENABLE_INHERIT)
164 | .nodeRef(nodeRef.getId())
165 | .build();
166 | nodeEvent.setPermissions(nodePermissionsTransformer.transform(nodeRef));
167 | messageService.publish(nodeEvent);
168 | }
169 |
170 | /**
171 | * Sets the policy component.
172 | *
173 | * @param policyComponent the new policy component
174 | */
175 | public void setPolicyComponent(final PolicyComponent policyComponent) {
176 | this.policyComponent = policyComponent;
177 | }
178 |
179 | /**
180 | * Sets the message service.
181 | *
182 | * @param messageService the new message service
183 | */
184 | public void setMessageService(final MessageService messageService) {
185 | this.messageService = messageService;
186 | }
187 |
188 | /**
189 | * Sets the node permissions transformer.
190 | *
191 | * @param nodePermissionsTransformer the new node permissions transformer
192 | */
193 | public void setNodePermissionsTransformer(final NodeRefToNodePermissions nodePermissionsTransformer) {
194 | this.nodePermissionsTransformer = nodePermissionsTransformer;
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/java/com/metaversant/kafka/service/MessageService.java:
--------------------------------------------------------------------------------
1 | package com.metaversant.kafka.service;
2 |
3 | import java.util.Properties;
4 |
5 | import javax.annotation.PostConstruct;
6 |
7 | import org.alfresco.service.cmr.repository.NodeRef;
8 | import org.apache.kafka.clients.producer.KafkaProducer;
9 | import org.apache.kafka.clients.producer.ProducerRecord;
10 | import org.apache.log4j.Logger;
11 |
12 | import com.fasterxml.jackson.core.JsonProcessingException;
13 | import com.fasterxml.jackson.databind.ObjectMapper;
14 | import com.metaversant.kafka.model.NodeEvent;
15 | import com.metaversant.kafka.transform.NodeRefToNodeEvent;
16 | import com.metaversant.kafka.transform.NodeRefToNodePermissions;
17 |
18 | /**
19 | * Created by jpotts, Metaversant on 6/9/17.
20 | */
21 | public class MessageService {
22 |
23 | /** The LOGGER. */
24 | private static final Logger LOGGER = Logger.getLogger(MessageService.class);
25 |
26 | ///////////////////// Dependencies [Start] ////////////////
27 | /** The node transformer. */
28 | private NodeRefToNodeEvent nodeTransformer;
29 |
30 | /** The node permissions transformer. */
31 | private NodeRefToNodePermissions nodePermissionsTransformer;
32 | ///////////////////// Dependencies [End] ////////////////
33 |
34 | ///////////////////// Settings [Start] ////////////////
35 | /** The topic. */
36 | private String topic = "alfresco-node-events";
37 |
38 | /** The bootstrap servers. */
39 | private String bootstrapServers = "localhost:9092";
40 |
41 | /** The producer. */
42 | private KafkaProducer producer;
43 |
44 | /** The mapper. */
45 | private ObjectMapper mapper = new ObjectMapper();
46 | ///////////////////// Settings [End] ////////////////
47 |
48 | /**
49 | * Inits the.
50 | */
51 | @PostConstruct
52 | public void init() {
53 | if (LOGGER.isDebugEnabled()) {
54 | LOGGER.debug("init invoked, topic: " + this.topic + " | bootstrapServers: " + this.bootstrapServers);
55 | }
56 | producer = new KafkaProducer<>(createProducerConfig());
57 | }
58 |
59 | /**
60 | * Ping.
61 | *
62 | * @param nodeRef the node ref
63 | */
64 | public void ping(final NodeRef nodeRef) {
65 | if (LOGGER.isDebugEnabled()) {
66 | LOGGER.debug("ping invoked for nodeRef: " + nodeRef);
67 | }
68 | final NodeEvent nodeEvent = nodeTransformer.transform(nodeRef);
69 | nodeEvent.setEventType(NodeEvent.EventType.PING);
70 | nodeEvent.setPermissions(nodePermissionsTransformer.transform(nodeRef));
71 | publish(nodeEvent);
72 | }
73 |
74 | /**
75 | * Publish.
76 | *
77 | * @param event the event
78 | */
79 | public void publish(final NodeEvent event) {
80 | if (LOGGER.isDebugEnabled()) {
81 | LOGGER.debug("publish invoked for event: " + event);
82 | }
83 | try {
84 | final String message = mapper.writeValueAsString(event);
85 | if (LOGGER.isDebugEnabled()) {
86 | LOGGER.debug("Publishing message: " + message);
87 | }
88 | if (message != null && message.length() != 0) {
89 | producer.send(new ProducerRecord(topic, message));
90 | }
91 | } catch (JsonProcessingException jpe) {
92 | LOGGER.error("Error occurred while publishing the event", jpe);
93 | }
94 | }
95 |
96 | /**
97 | * Creates the producer config.
98 | *
99 | * @return the properties
100 | */
101 | private Properties createProducerConfig() {
102 | final Properties props = new Properties();
103 | props.put("bootstrap.servers", bootstrapServers);
104 | props.put("acks", "all");
105 | props.put("retries", 0);
106 | props.put("batch.size", 16384);
107 | props.put("linger.ms", 1);
108 | props.put("buffer.memory", 33554432);
109 | props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
110 | props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
111 | if (LOGGER.isDebugEnabled()) {
112 | LOGGER.debug("Props for initialization: " + props);
113 | }
114 | return props;
115 | }
116 |
117 | /**
118 | * Sets the topic.
119 | *
120 | * @param topic the new topic
121 | */
122 | public void setTopic(final String topic) {
123 | this.topic = topic;
124 | }
125 |
126 | /**
127 | * Sets the bootstrap servers.
128 | *
129 | * @param bootstrapServers the new bootstrap servers
130 | */
131 | public void setBootstrapServers(final String bootstrapServers) {
132 | this.bootstrapServers = bootstrapServers;
133 | }
134 |
135 | /**
136 | * Sets the node transformer.
137 | *
138 | * @param nodeTransformer the new node transformer
139 | */
140 | public void setNodeTransformer(final NodeRefToNodeEvent nodeTransformer) {
141 | this.nodeTransformer = nodeTransformer;
142 | }
143 |
144 | /**
145 | * Sets the node permissions transformer.
146 | *
147 | * @param nodePermissionsTransformer the new node permissions transformer
148 | */
149 | public void setNodePermissionsTransformer(final NodeRefToNodePermissions nodePermissionsTransformer) {
150 | this.nodePermissionsTransformer = nodePermissionsTransformer;
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/java/com/metaversant/kafka/service/MessageServiceScopedObject.java:
--------------------------------------------------------------------------------
1 | package com.metaversant.kafka.service;
2 |
3 | import org.alfresco.repo.jscript.BaseScopableProcessorExtension;
4 | import org.alfresco.repo.jscript.ScriptNode;
5 | import org.apache.log4j.Logger;
6 |
7 | /**
8 | * Created by jpotts, Metaversant on 6/9/17.
9 | */
10 | public class MessageServiceScopedObject extends BaseScopableProcessorExtension {
11 |
12 | /** The LOGGER. */
13 | private static final Logger LOGGER = Logger.getLogger(MessageServiceScopedObject.class);
14 |
15 | ///////////////////// Dependencies [Start] ////////////////
16 | /** The message service. */
17 | private MessageService messageService;
18 | ///////////////////// Dependencies [End] ////////////////
19 |
20 | /**
21 | * Ping.
22 | *
23 | * @param scriptNode the script node
24 | */
25 | public void ping(final ScriptNode scriptNode) {
26 | if (LOGGER.isDebugEnabled()) {
27 | LOGGER.debug("ping invoked for scriptNode: " + scriptNode);
28 | }
29 | messageService.ping(scriptNode.getNodeRef());
30 | }
31 |
32 | /**
33 | * Sets the message service.
34 | *
35 | * @param messageService the new message service
36 | */
37 | public void setMessageService(final MessageService messageService) {
38 | this.messageService = messageService;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/java/com/metaversant/kafka/transform/NodeRefToNodeEvent.java:
--------------------------------------------------------------------------------
1 | package com.metaversant.kafka.transform;
2 |
3 | import static org.alfresco.model.ContentModel.PROP_CONTENT;
4 | import static org.alfresco.model.ContentModel.PROP_CREATED;
5 | import static org.alfresco.model.ContentModel.PROP_CREATOR;
6 | import static org.alfresco.model.ContentModel.PROP_MODIFIED;
7 | import static org.alfresco.model.ContentModel.PROP_MODIFIER;
8 |
9 | import java.io.Serializable;
10 | import java.util.Date;
11 | import java.util.List;
12 | import java.util.Map;
13 |
14 | import org.alfresco.service.cmr.repository.ContentReader;
15 | import org.alfresco.service.cmr.repository.ContentService;
16 | import org.alfresco.service.cmr.repository.NodeRef;
17 | import org.alfresco.service.cmr.repository.NodeService;
18 | import org.alfresco.service.cmr.site.SiteInfo;
19 | import org.alfresco.service.cmr.site.SiteService;
20 | import org.alfresco.service.cmr.tagging.TaggingService;
21 | import org.alfresco.service.namespace.QName;
22 | import org.apache.log4j.Logger;
23 |
24 | import com.metaversant.kafka.model.NodeEvent;
25 |
26 | /**
27 | * Created by jpotts, Metaversant on 6/9/17.
28 | */
29 | public class NodeRefToNodeEvent {
30 |
31 | /** The LOGGER. */
32 | private static final Logger LOGGER = Logger.getLogger(NodeRefToNodeEvent.class);
33 |
34 | ///////////////////// Dependencies [Start] ////////////////
35 | /** The content service. */
36 | private ContentService contentService;
37 |
38 | /** The node service. */
39 | private NodeService nodeService;
40 |
41 | /** The site service. */
42 | private SiteService siteService;
43 |
44 | /** The tagging service. */
45 | private TaggingService taggingService;
46 | ///////////////////// Dependencies [End] ////////////////
47 |
48 | /**
49 | * Transform.
50 | *
51 | * @param nodeRef the node ref
52 | * @return the node event
53 | */
54 | public NodeEvent transform(final NodeRef nodeRef) {
55 | if (LOGGER.isDebugEnabled()) {
56 | LOGGER.debug("NodeEvent transform invoked for nodeRef: " + nodeRef);
57 | }
58 | final Map props = nodeService.getProperties(nodeRef);
59 | final NodeEvent nodeEvent = NodeEvent.builder()
60 | .nodeRef(nodeRef.getId())
61 | .creator((String) props.get(PROP_CREATOR))
62 | .created((Date) props.get(PROP_CREATED))
63 | .modifier((String) props.get(PROP_MODIFIER))
64 | .modified((Date) props.get(PROP_MODIFIED))
65 | .path(nodeService.getPath(nodeRef).toString())
66 | .parent(nodeService.getPrimaryParent(nodeRef).getParentRef().getId())
67 | .contentType(nodeService.getType(nodeRef).toPrefixString())
68 | .build();
69 |
70 | // If this node is in a site, add the site ID to the event
71 | final SiteInfo siteInfo = siteService.getSite(nodeRef);
72 | if (siteInfo != null) {
73 | nodeEvent.setSiteId(siteInfo.getShortName());
74 | }
75 |
76 | // Retrieve the tags from the node and add them to the event
77 | final List tags = taggingService.getTags(nodeRef);
78 | nodeEvent.setTags(tags);
79 |
80 | // If this is a content object, set the mimetype and size props
81 | if (props.get(PROP_CONTENT) != null) {
82 | ContentReader reader = null;
83 | try {
84 | reader = contentService.getReader(nodeRef, PROP_CONTENT);
85 | } catch (Exception excp) {
86 | LOGGER.error("Error reading content: " + excp.getMessage(), excp);
87 | }
88 |
89 | if (reader != null) {
90 | nodeEvent.setMimetype(reader.getMimetype());
91 | nodeEvent.setSize(reader.getContentData().getSize());
92 | }
93 | }
94 | return nodeEvent;
95 | }
96 |
97 | /**
98 | * Sets the content service.
99 | *
100 | * @param contentService the new content service
101 | */
102 | public void setContentService(final ContentService contentService) {
103 | this.contentService = contentService;
104 | }
105 |
106 | /**
107 | * Sets the node service.
108 | *
109 | * @param nodeService the new node service
110 | */
111 | public void setNodeService(final NodeService nodeService) {
112 | this.nodeService = nodeService;
113 | }
114 |
115 | /**
116 | * Sets the site service.
117 | *
118 | * @param siteService the new site service
119 | */
120 | public void setSiteService(final SiteService siteService) {
121 | this.siteService = siteService;
122 | }
123 |
124 | /**
125 | * Sets the tagging service.
126 | *
127 | * @param taggingService the new tagging service
128 | */
129 | public void setTaggingService(final TaggingService taggingService) {
130 | this.taggingService = taggingService;
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/java/com/metaversant/kafka/transform/NodeRefToNodePermissions.java:
--------------------------------------------------------------------------------
1 | package com.metaversant.kafka.transform;
2 |
3 | import java.util.HashSet;
4 | import java.util.Set;
5 |
6 | import org.alfresco.service.cmr.repository.NodeRef;
7 | import org.alfresco.service.cmr.security.AccessPermission;
8 | import org.alfresco.service.cmr.security.PermissionService;
9 | import org.apache.log4j.Logger;
10 |
11 | import com.metaversant.kafka.model.NodePermission;
12 | import com.metaversant.kafka.model.NodePermissions;
13 |
14 | /**
15 | * Created by jpotts, Metaversant on 8/28/19.
16 | */
17 | public class NodeRefToNodePermissions {
18 |
19 | /** The LOGGER. */
20 | private static final Logger LOGGER = Logger.getLogger(NodeRefToNodePermissions.class);
21 |
22 | ///////////////////// Dependencies [Start] ////////////////
23 | /** The permission service. */
24 | private PermissionService permissionService;
25 | ///////////////////// Dependencies [End] ////////////////
26 |
27 | /**
28 | * Transform.
29 | *
30 | * @param nodeRef the node ref
31 | * @return the node permissions
32 | */
33 | public NodePermissions transform(final NodeRef nodeRef) {
34 | if (LOGGER.isDebugEnabled()) {
35 | LOGGER.debug("NodePermissions transform invoked for nodeRef: " + nodeRef);
36 | }
37 | // determine if the node inherits its ACL from the parent
38 | final boolean inherits = permissionService.getInheritParentPermissions(nodeRef);
39 | final NodePermissions perms = new NodePermissions();
40 | perms.setInheritanceEnabled(inherits);
41 |
42 | // convert the Alfresco object into our own
43 | final Set permissionSet = permissionService.getAllSetPermissions(nodeRef);
44 | final Set set = new HashSet<>();
45 | for (final AccessPermission perm : permissionSet) {
46 | final NodePermission nodePerm = NodePermission.builder()
47 | .authority(perm.getAuthority())
48 | .authorityType(perm.getAuthorityType().name())
49 | .permission(perm.getPermission())
50 | .isInherited(perm.isInherited())
51 | .build();
52 | set.add(nodePerm);
53 | }
54 | perms.setPermissions(set);
55 | return perms;
56 | }
57 |
58 | /**
59 | * Sets the permission service.
60 | *
61 | * @param permissionService the new permission service
62 | */
63 | public void setPermissionService(final PermissionService permissionService) {
64 | this.permissionService = permissionService;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/resources/META-INF/resources/test.html:
--------------------------------------------------------------------------------
1 | Test 123
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/resources/alfresco/extension/templates/webscripts/com/metaversant/alfresco/kafka/ping.get.desc.xml:
--------------------------------------------------------------------------------
1 |
2 | Alfresco Kafka Ping
3 | Pings a node to cause it to get added to the stream.
4 | /metaversant/kafka/ping?nodeRef={nodeRef}&recurse={recurse}
5 | Metaversant
6 | extension
7 | admin
8 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/resources/alfresco/extension/templates/webscripts/com/metaversant/alfresco/kafka/ping.get.js:
--------------------------------------------------------------------------------
1 | function main() {
2 | var recurse = false;
3 | if (args.recurse != null && args.recurse === 'true') {
4 | recurse = true;
5 | }
6 | if (args.nodeRef == null || args.nodeRef.length == 0) {
7 | logger.log("NodeRef arg not set");
8 | status.code = 400;
9 | status.message = "NodeRef has not been provided";
10 | status.redirect = true;
11 | } else {
12 | logger.log("Getting current node");
13 | var curNode = search.findNode(args.nodeRef);
14 | if (curNode == null) {
15 | logger.log("Node not found");
16 | status.code = 404;
17 | status.message = "No node found for nodeRef: " + args.nodeRef;
18 | status.redirect = true;
19 | } else {
20 | messageService.ping(curNode);
21 | model.nodeRef = args.nodeRef;
22 | }
23 | if (recurse && curNode.hasChildren) {
24 | logger.log("Recursing into list of children");
25 | handleChildren(curNode.children);
26 | }
27 | }
28 | }
29 |
30 | function handleChildren(children) {
31 | for (var i = 0; i < children.length; i++) {
32 | logger.log("Pinging " + children[i].nodeRef.toString());
33 | messageService.ping(children[i]);
34 | if (children[i].hasChildren) {
35 | handleChildren(children[i].children);
36 | }
37 | }
38 | }
39 |
40 | main();
41 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/resources/alfresco/extension/templates/webscripts/com/metaversant/alfresco/kafka/ping.get.json.ftl:
--------------------------------------------------------------------------------
1 | {
2 | "nodeRef": "${nodeRef}"
3 | }
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/resources/alfresco/module/alfresco-kafka-repo/alfresco-global.properties:
--------------------------------------------------------------------------------
1 | ## This Alfresco Platform Configuration file should be used for custom properties that are introduced by this module.
2 | ## Define default values for all properties here.
3 | ## System Administrators can override these values in environment specific configurations in
4 | ## alfresco/tomcat/shared/classes/alfresco-global.properties.
5 | ##
6 |
7 | kafka.topic=alfresco-node-events
8 | kafka.server=localhost:9092
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/resources/alfresco/module/alfresco-kafka-repo/context/bootstrap-context.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/resources/alfresco/module/alfresco-kafka-repo/context/service-context.xml:
--------------------------------------------------------------------------------
1 |
2 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/resources/alfresco/module/alfresco-kafka-repo/log4j.properties:
--------------------------------------------------------------------------------
1 | # Add here module-specific custom log4j.properties configuration
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/resources/alfresco/module/alfresco-kafka-repo/module-context.xml:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
23 |
24 |
25 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/resources/alfresco/module/alfresco-kafka-repo/module.properties:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one or more
2 | # contributor license agreements. See the NOTICE file distributed with
3 | # this work for additional information regarding copyright ownership.
4 | # The ASF licenses this file to You under the Apache License, Version 2.0
5 | # (the "License"); you may not use this file except in compliance with
6 | # the License. You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 |
17 |
18 | # SDK Sample module
19 |
20 | # ==== Beginning of Alfresco required/optional properties ====== #
21 | # NB: These properties are filtered at build time by Maven, single
22 | # sourcing from POM properties
23 | module.id=${project.artifactId}
24 | #module.aliases=myModule-123, my-module
25 | module.title=${project.name}
26 | module.description=${project.description}
27 | module.version=${project.version}
28 |
29 | # The following optional properties can be used to prevent the module from being added
30 | # to inappropriate versions of the WAR file.
31 | # module.repo.version.min=2.0
32 | # module.repo.version.max=2.1
33 |
34 | # FIXME: This dependencies should come out of mvn dependencies on amp
35 |
36 | # The following describe dependencies on other modules
37 | # Depends on net.sf.myproject.module.SupportModuleA version ${version} or later
38 | # module.depends.net.sf.myproject.module.SupportModuleA=${version}-*
39 | # Depends on net.sf.myproject.module.SupportModuleA version ${version} to 2.0
40 | # module.depends.net.sf.myproject.module.SupportModuleB=${version}-2.0
41 | # Depends on net.sf.myproject.module.SupportModuleC - any version
42 | # module.depends.net.sf.myproject.module.SupportModuleB=*
43 |
44 |
45 | # ==== End of Alfresco required/optional properties ======= #
46 |
47 |
48 | # ==== Beginning of module required properties/optional ====== #
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/resources/examples/enable_inherit.json:
--------------------------------------------------------------------------------
1 | {
2 | "nodeRef": "2b69af4a-9b11-486b-b192-0e676b6b1c8c",
3 | "eventType": "ENABLE_INHERIT",
4 | "permissions": {
5 | "permissions": [
6 | {
7 | "authority": "GROUP_site_jtp-test-site-1_SiteManager",
8 | "authorityType": "GROUP",
9 | "permission": "SiteManager",
10 | "inherited": true
11 | },
12 | {
13 | "authority": "GROUP_site_jtp-test-site-1_SiteConsumer",
14 | "authorityType": "GROUP",
15 | "permission": "SiteConsumer",
16 | "inherited": true
17 | },
18 | {
19 | "authority": "GROUP_site_jtp-test-site-1_SiteContributor",
20 | "authorityType": "GROUP",
21 | "permission": "SiteContributor",
22 | "inherited": true
23 | },
24 | {
25 | "authority": "GROUP_site_jtp-test-site-1_SiteManager",
26 | "authorityType": "GROUP",
27 | "permission": "SiteManager",
28 | "inherited": false
29 | },
30 | {
31 | "authority": "GROUP_site_jtp-test-site-1_SiteCollaborator",
32 | "authorityType": "GROUP",
33 | "permission": "SiteCollaborator",
34 | "inherited": true
35 | }
36 | ],
37 | "inheritanceEnabled": true
38 | }
39 | }
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/resources/examples/revoke.json:
--------------------------------------------------------------------------------
1 | {
2 | "nodeRef": "2b69af4a-9b11-486b-b192-0e676b6b1c8c",
3 | "eventType": "REVOKE",
4 | "authority": "GROUP_site_jtp-test-site-1_SiteManager",
5 | "permission": "SiteManager",
6 | "permissions": {
7 | "permissions": [
8 | {
9 | "authority": "GROUP_site_jtp-test-site-1_SiteManager",
10 | "authorityType": "GROUP",
11 | "permission": "SiteManager",
12 | "inherited": true
13 | },
14 | {
15 | "authority": "GROUP_site_jtp-test-site-1_SiteConsumer",
16 | "authorityType": "GROUP",
17 | "permission": "SiteConsumer",
18 | "inherited": true
19 | },
20 | {
21 | "authority": "GROUP_site_jtp-test-site-1_SiteContributor",
22 | "authorityType": "GROUP",
23 | "permission": "SiteContributor",
24 | "inherited": true
25 | },
26 | {
27 | "authority": "GROUP_site_jtp-test-site-1_SiteCollaborator",
28 | "authorityType": "GROUP",
29 | "permission": "SiteCollaborator",
30 | "inherited": true
31 | }
32 | ],
33 | "inheritanceEnabled": true
34 | }
35 | }
--------------------------------------------------------------------------------
/alfresco-kafka-repo/src/main/resources/examples/update.json:
--------------------------------------------------------------------------------
1 | {
2 | "nodeRef": "8fe391f7-374d-4d10-aef7-9301f2c7e903",
3 | "eventType": "UPDATE",
4 | "path": "/{http://www.alfresco.org/model/application/1.0}company_home/{http://www.alfresco.org/model/site/1.0}sites/{http://www.alfresco.org/model/content/1.0}jtp-test-site-1/{http://www.alfresco.org/model/content/1.0}documentLibrary/{http://www.alfresco.org/model/content/1.0}testfolder2",
5 | "created": 1567032687513,
6 | "modified": 1567032687513,
7 | "creator": "admin",
8 | "modifier": "admin",
9 | "contentType": "folder",
10 | "siteId": "jtp-test-site-1",
11 | "parent": "244a089b-17ad-4a49-81f4-c8b17b7322a6",
12 | "permissions": {
13 | "permissions": [
14 | {
15 | "authority": "GROUP_site_jtp-test-site-1_SiteConsumer",
16 | "authorityType": "GROUP",
17 | "permission": "SiteConsumer",
18 | "inherited": true
19 | },
20 | {
21 | "authority": "GROUP_site_jtp-test-site-1_SiteContributor",
22 | "authorityType": "GROUP",
23 | "permission": "SiteContributor",
24 | "inherited": true
25 | },
26 | {
27 | "authority": "GROUP_site_jtp-test-site-1_SiteCollaborator",
28 | "authorityType": "GROUP",
29 | "permission": "SiteCollaborator",
30 | "inherited": true
31 | },
32 | {
33 | "authority": "GROUP_site_jtp-test-site-1_SiteManager",
34 | "authorityType": "GROUP",
35 | "permission": "SiteManager",
36 | "inherited": true
37 | }
38 | ],
39 | "inheritanceEnabled": true
40 | }
41 | }
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | com.metaversant
6 | alfresco-kafka
7 | 0.0.3-SNAPSHOT
8 | alfresco-kafka Platform/Repository Module
9 | pom
10 |
11 |
12 |
13 | 4.1.0
14 |
15 | UTF-8
16 |
17 |
18 | org.alfresco
19 | acs-community-packaging
20 | 6.2.1-A8
21 | 6.2.1
22 |
23 |
24 | alfresco/alfresco-content-repository-community
25 | alfresco/alfresco-share
26 |
27 |
28 | 1.1.8
29 |
30 |
31 | 8180
32 | alfresco-kafka-repo-acs
33 | 8080
34 | 8888
35 | 5555
36 |
37 |
38 |
39 |
40 |
41 |
42 |
44 |
45 |
46 | junit
47 | junit
48 | 4.13.1
49 | test
50 |
51 |
52 | org.mockito
53 | mockito-all
54 | 1.9.5
55 | test
56 |
57 |
58 | org.apache.httpcomponents
59 | httpclient
60 | test
61 |
62 |
63 |
64 |
65 | ${alfresco.groupId}
66 | alfresco-remote-api
67 | provided
68 |
69 |
70 |
71 |
72 | org.alfresco.maven
73 | alfresco-rad
74 | ${alfresco.sdk.version}
75 | test
76 |
77 |
78 |
79 |
80 | org.projectlombok
81 | lombok
82 | 1.18.12
83 |
84 |
85 |
86 |
87 | org.apache.kafka
88 | kafka-clients
89 | 2.6.3
90 |
91 |
92 |
93 |
94 |
95 |
96 |
102 |
103 | ${alfresco.groupId}
104 | ${alfresco.bomDependencyArtifactId}
105 | ${alfresco.platform.version}
106 | pom
107 | import
108 |
109 |
110 |
111 |
112 |
113 |
114 |
121 |
148 |
149 |
151 |
152 | org.apache.maven.plugins
153 | maven-resources-plugin
154 | 3.1.0
155 |
156 | UTF-8
157 |
158 | ftl
159 | acp
160 | svg
161 | pdf
162 | doc
163 | docx
164 | xls
165 | xlsx
166 | ppt
167 | pptx
168 | bin
169 | lic
170 | swf
171 | zip
172 | msg
173 | jar
174 | ttf
175 | eot
176 | woff
177 | woff2
178 | css
179 | ico
180 | psd
181 | js
182 |
183 |
184 |
185 |
186 | copy-and-filter-docker-compose-resources
187 | validate
188 |
189 | copy-resources
190 |
191 |
192 | ${project.build.outputDirectory}/docker
193 |
194 |
195 | docker
196 | true
197 |
198 |
199 |
200 |
201 |
202 | copy-and-filter-docker-resources
203 | validate
204 |
205 | copy-resources
206 |
207 |
208 | ${project.build.directory}
209 |
210 |
211 | src/main/docker
212 | true
213 |
214 | **/*.jar
215 | **/*.so
216 | **/*.gz
217 |
218 |
219 |
220 |
221 |
222 |
223 | copy-and-filter-docker-resources-non-filtered
224 | validate
225 |
226 | copy-resources
227 |
228 |
229 | ${project.build.directory}
230 |
231 |
232 | src/main/docker
233 | false
234 |
235 | **/*.jar
236 | **/*.so
237 | **/*.gz
238 |
239 |
240 |
241 |
242 |
243 |
244 | copy-repository-extension
245 | package
246 |
247 | copy-resources
248 |
249 |
250 | ${project.build.directory}/extensions
251 |
252 |
253 | target
254 |
255 | ${project.build.finalName}.jar
256 |
257 | false
258 |
259 |
260 |
261 |
262 |
263 | copy-repository-tests
264 | pre-integration-test
265 |
266 | copy-resources
267 |
268 |
269 | ${project.build.directory}/extensions
270 |
271 |
272 | target
273 |
274 | ${project.build.finalName}-tests.jar
275 |
276 | false
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 | org.apache.maven.plugins
286 | maven-dependency-plugin
287 | 3.1.1
288 |
289 |
290 |
291 | collect-test-artifacts
292 | pre-integration-test
293 |
294 | copy-dependencies
295 |
296 |
297 | ${project.build.directory}/extensions
298 | compile
299 |
300 |
301 |
302 |
303 | collect-extensions
304 | package
305 |
306 | copy-dependencies
307 |
308 |
309 | ${project.build.directory}/extensions
310 | runtime
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 | org.apache.maven.plugins
320 | maven-jar-plugin
321 | 3.1.0
322 |
323 |
324 |
325 | test-jar
326 |
327 |
328 |
329 |
330 |
331 |
333 |
334 | org.apache.maven.plugins
335 | maven-failsafe-plugin
336 | 3.0.0-M1
337 |
338 |
339 | ${test.acs.endpoint.path}
340 |
341 |
342 |
343 |
344 | integration-test
345 | integration-test
346 |
347 | integration-test
348 |
349 |
350 |
351 | verify-test
352 | verify
353 |
354 | verify
355 |
356 |
357 |
358 |
359 |
360 | org.apache.maven.surefire
361 | surefire-junit47
362 | 3.0.0-M1
363 |
364 |
365 |
366 |
367 |
368 |
369 | net.alchim31.maven
370 | yuicompressor-maven-plugin
371 | 1.5.1
372 |
373 |
374 |
375 | compress-assembly
376 |
377 | compress
378 |
379 |
380 | ${project.basedir}/src/main/assembly/web
381 | ${project.basedir}/src/main/assembly/web
382 |
383 | **/webscripts/**
384 | **/site-webscripts/**
385 | **/META-INF/**
386 | **/*.lib.js
387 | **/*.css
388 | **/*-min.js
389 | **/*-min.css
390 |
391 | true
392 | false
393 |
394 |
395 |
396 |
397 | compress-resources
398 |
399 | compress
400 |
401 |
402 |
403 | **/webscripts/**
404 | **/site-webscripts/**
405 | **/*.lib.js
406 | **/*.css
407 | **/*-min.js
408 | **/*-min.css
409 |
410 | true
411 | false
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 | org.zeroturnaround
420 | jrebel-maven-plugin
421 | ${jrebel.version}
422 |
423 |
424 | generate-rebel-xml
425 | process-resources
426 |
427 | generate
428 |
429 |
430 |
431 |
432 |
434 |
435 | all
436 |
437 |
438 | ${project.build.outputDirectory}
439 | ${project.build.testOutputDirectory}
440 |
441 |
442 |
443 |
444 |
449 | true
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 | src/main/resources
458 | true
459 |
460 |
461 |
462 |
463 |
464 | src/test/resources
465 | true
466 |
467 |
468 |
469 |
470 |
471 |
472 | java8
473 |
474 | [1.8,11.0)
475 |
476 |
477 |
478 |
479 | org.apache.maven.plugins
480 | maven-compiler-plugin
481 | 3.8.0
482 |
483 | 1.8
484 | 1.8
485 |
486 |
487 |
488 |
489 |
490 |
491 | java11
492 |
493 | [11.0,)
494 |
495 |
496 |
497 |
498 | org.apache.maven.plugins
499 | maven-compiler-plugin
500 | 3.8.0
501 |
502 | 11
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
513 |
514 |
515 | alfresco-public
516 | https://artifacts.alfresco.com/nexus/content/groups/public
517 |
518 |
519 | alfresco-public-snapshots
520 | https://artifacts.alfresco.com/nexus/content/groups/public-snapshots
521 |
522 | true
523 | daily
524 |
525 |
526 |
527 |
528 | alfresco-private-repository
529 | https://artifacts.alfresco.com/nexus/content/groups/private
530 |
531 |
532 |
533 |
534 |
535 | alfresco-plugin-public
536 | https://artifacts.alfresco.com/nexus/content/groups/public
537 |
538 |
539 | alfresco-plugin-public-snapshots
540 | https://artifacts.alfresco.com/nexus/content/groups/public-snapshots
541 |
542 | true
543 | daily
544 |
545 |
546 |
547 |
548 |
549 | alfresco-kafka-model
550 | alfresco-kafka-repo
551 |
552 |
--------------------------------------------------------------------------------
/run.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | SET COMPOSE_FILE_PATH=%CD%\alfresco-kafka-repo\target\classes\docker\docker-compose.yml
4 |
5 | IF [%M2_HOME%]==[] (
6 | SET MVN_EXEC=mvn
7 | )
8 |
9 | IF NOT [%M2_HOME%]==[] (
10 | SET MVN_EXEC=%M2_HOME%\bin\mvn
11 | )
12 |
13 | IF [%1]==[] (
14 | echo "Usage: %0 {build_start|build_start_it_supported|start|stop|purge|tail|build_test|test}"
15 | GOTO END
16 | )
17 |
18 | IF %1==build_start (
19 | CALL :down
20 | CALL :build
21 | CALL :start
22 | CALL :tail
23 | GOTO END
24 | )
25 | IF %1==build_start_it_supported (
26 | CALL :down
27 | CALL :build
28 | CALL :prepare_test
29 | CALL :start
30 | CALL :tail
31 | GOTO END
32 | )
33 | IF %1==start (
34 | CALL :start
35 | CALL :tail
36 | GOTO END
37 | )
38 | IF %1==stop (
39 | CALL :down
40 | GOTO END
41 | )
42 | IF %1==purge (
43 | CALL:down
44 | CALL:purge
45 | GOTO END
46 | )
47 | IF %1==tail (
48 | CALL :tail
49 | GOTO END
50 | )
51 | IF %1==build_test (
52 | CALL :down
53 | CALL :build
54 | CALL :prepare_test
55 | CALL :start
56 | CALL :test
57 | CALL :tail_all
58 | CALL :down
59 | GOTO END
60 | )
61 | IF %1==test (
62 | CALL :test
63 | GOTO END
64 | )
65 | echo "Usage: %0 {build_start|start|stop|purge|tail|build_test|test}"
66 | :END
67 | EXIT /B %ERRORLEVEL%
68 |
69 | :start
70 | docker volume create alfresco-kafka-repo-acs-volume
71 | docker volume create alfresco-kafka-repo-db-volume
72 | docker volume create alfresco-kafka-repo-ass-volume
73 | docker-compose -f "%COMPOSE_FILE_PATH%" up --build -d
74 | EXIT /B 0
75 | :down
76 | if exist "%COMPOSE_FILE_PATH%" (
77 | docker-compose -f "%COMPOSE_FILE_PATH%" down
78 | )
79 | EXIT /B 0
80 | :build
81 | call %MVN_EXEC% clean package
82 | EXIT /B 0
83 | :tail
84 | docker-compose -f "%COMPOSE_FILE_PATH%" logs -f
85 | EXIT /B 0
86 | :tail_all
87 | docker-compose -f "%COMPOSE_FILE_PATH%" logs --tail="all"
88 | EXIT /B 0
89 | :prepare_test
90 | call %MVN_EXEC% verify -DskipTests=true
91 | EXIT /B 0
92 | :test
93 | call %MVN_EXEC% verify
94 | EXIT /B 0
95 | :purge
96 | docker volume rm -f alfresco-kafka-repo-acs-volume
97 | docker volume rm -f alfresco-kafka-repo-db-volume
98 | docker volume rm -f alfresco-kafka-repo-ass-volume
99 | EXIT /B 0
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | export COMPOSE_FILE_PATH="${PWD}/alfresco-kafka-repo/target/classes/docker/docker-compose.yml"
4 |
5 | if [ -z "${M2_HOME}" ]; then
6 | export MVN_EXEC="mvn"
7 | else
8 | export MVN_EXEC="${M2_HOME}/bin/mvn"
9 | fi
10 |
11 | start() {
12 | docker volume create alfresco-kafka-repo-acs-volume
13 | docker volume create alfresco-kafka-repo-db-volume
14 | docker volume create alfresco-kafka-repo-ass-volume
15 | docker-compose -f "$COMPOSE_FILE_PATH" up --build -d
16 | }
17 |
18 | down() {
19 | if [ -f "$COMPOSE_FILE_PATH" ]; then
20 | docker-compose -f "$COMPOSE_FILE_PATH" down
21 | fi
22 | }
23 |
24 | purge() {
25 | docker volume rm -f alfresco-kafka-repo-acs-volume
26 | docker volume rm -f alfresco-kafka-repo-db-volume
27 | docker volume rm -f alfresco-kafka-repo-ass-volume
28 | }
29 |
30 | build() {
31 | $MVN_EXEC clean package
32 | }
33 |
34 | tail() {
35 | docker-compose -f "$COMPOSE_FILE_PATH" logs -f
36 | }
37 |
38 | tail_all() {
39 | docker-compose -f "$COMPOSE_FILE_PATH" logs --tail="all"
40 | }
41 |
42 | prepare_test() {
43 | $MVN_EXEC verify -DskipTests=true
44 | }
45 |
46 | test() {
47 | $MVN_EXEC verify
48 | }
49 |
50 | case "$1" in
51 | build_start)
52 | down
53 | build
54 | start
55 | tail
56 | ;;
57 | build_start_it_supported)
58 | down
59 | build
60 | prepare_test
61 | start
62 | tail
63 | ;;
64 | start)
65 | start
66 | tail
67 | ;;
68 | stop)
69 | down
70 | ;;
71 | purge)
72 | down
73 | purge
74 | ;;
75 | tail)
76 | tail
77 | ;;
78 | build_test)
79 | down
80 | build
81 | prepare_test
82 | start
83 | test
84 | tail_all
85 | down
86 | ;;
87 | test)
88 | test
89 | ;;
90 | *)
91 | echo "Usage: $0 {build_start|build_start_it_supported|start|stop|purge|tail|build_test|test}"
92 | esac
--------------------------------------------------------------------------------