1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.exchangesimple;
35
36 import info.magnolia.cms.core.ItemType;
37 import info.magnolia.cms.exchange.ActivationManagerFactory;
38 import info.magnolia.cms.exchange.ExchangeException;
39 import info.magnolia.cms.exchange.Subscriber;
40 import info.magnolia.cms.exchange.Subscription;
41 import info.magnolia.cms.security.SecurityUtil;
42
43 import java.io.IOException;
44 import java.net.MalformedURLException;
45 import java.net.URLConnection;
46 import java.util.ArrayList;
47 import java.util.Collection;
48 import java.util.Iterator;
49 import java.util.List;
50
51 import org.apache.commons.lang.StringUtils;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 import EDU.oswego.cs.dl.util.concurrent.CountDown;
56 import EDU.oswego.cs.dl.util.concurrent.Sync;
57
58
59
60
61
62
63 public class SimpleSyndicator extends BaseSyndicatorImpl {
64 private static final Logger log = LoggerFactory.getLogger(SimpleSyndicator.class);
65
66 @Override
67 public void activate(final ActivationContent activationContent, String nodePath) throws ExchangeException {
68 List<Exception> errors = new ArrayList<Exception>();
69 try {
70 String nodeUUID = activationContent.getproperty(NODE_UUID);
71 final ExchangeTask task;
72
73 if (Boolean.parseBoolean(activationContent.getproperty(ItemType.DELETED_NODE_MIXIN))) {
74 task = getDeactivateTask(nodeUUID, nodePath);
75 } else {
76 task = getActivateTask(activationContent, nodePath);
77 }
78 errors.addAll(executeExchangeTask(task));
79
80
81 executeInPool(new Runnable() {
82 @Override
83 public void run() {
84 cleanTemporaryStore(activationContent);
85 }
86 });
87 } finally {
88 activationContent.removeTempFile();
89 }
90 handleErrors(errors);
91 long end = System.currentTimeMillis();
92 }
93
94 protected void handleErrors(List<Exception> errors) throws ExchangeException {
95
96 if (!errors.isEmpty()) {
97 Exception e = errors.get(0);
98 log.error(e.getMessage(), e);
99 throw new ExchangeException("1 error detected: \n" + e.getMessage(), e);
100 }
101 }
102
103 private ExchangeTask getActivateTask(final ActivationContent activationContent, final String nodePath) {
104 ExchangeTask r = new ExchangeTask() {
105 @Override
106 public void runTask(Subscriber subscriber) throws ExchangeException {
107 activate(subscriber, activationContent, nodePath);
108 }
109 };
110 return r;
111 }
112
113 @Override
114 public void doDeactivate(String nodeUUID, String nodePath) throws ExchangeException {
115 List<Exception> errors = executeExchangeTask(getDeactivateTask(nodeUUID, nodePath));
116 handleErrors(errors);
117 }
118
119 private List<Exception> executeExchangeTask(ExchangeTask runnable) throws ExchangeException {
120 Collection<Subscriber> allSubscribers = getSubscribers();
121 Iterator<Subscriber> subscriberIterator = allSubscribers.iterator();
122 final Sync done = new CountDown(allSubscribers.size());
123 final List<Exception> errors = new ArrayList<Exception>();
124 int count = 0;
125 while (subscriberIterator.hasNext()) {
126 count++;
127 final Subscriber subscriber = subscriberIterator.next();
128 if (subscriber.isActive()) {
129
130 runnable.setErrors(errors);
131 runnable.setSubscriber(subscriber);
132 runnable.setSync(done);
133
134 executeInPool(runnable);
135 break;
136 } else {
137 done.release();
138 }
139 }
140
141
142 for (; count < allSubscribers.size(); count++) {
143 done.release();
144 }
145
146
147 acquireIgnoringInterruption(done);
148
149 return errors;
150 }
151
152 private ExchangeTask getDeactivateTask(final String nodeUUID, final String nodePath) {
153 ExchangeTask r = new ExchangeTask() {
154 @Override
155 public void runTask(Subscriber subscriber) throws ExchangeException {
156 doDeactivate(subscriber, nodeUUID, nodePath);
157 }
158 };
159 return r;
160 }
161
162
163
164
165
166
167
168 @Override
169 public String doDeactivate(Subscriber subscriber, String nodeUUID, String path) throws ExchangeException {
170 Subscription subscription = subscriber.getMatchedSubscription(path, this.repositoryName);
171 boolean success = true;
172 if (null != subscription) {
173 String urlString = getDeactivationURL(subscriber);
174 URLConnection urlConnection = null;
175 try {
176 urlConnection = prepareConnection(subscriber, urlString);
177
178 this.addDeactivationHeaders(urlConnection, nodeUUID, null);
179 String status = urlConnection.getHeaderField(ACTIVATION_ATTRIBUTE_STATUS);
180
181 if (StringUtils.equals(status, ACTIVATION_HANDSHAKE)) {
182 String handshakeKey = urlConnection.getHeaderField(ACTIVATION_AUTH);
183
184 urlConnection.getContent();
185 releaseConnection(urlConnection);
186
187
188 urlConnection = prepareConnection(subscriber, getActivationURL(subscriber));
189
190 this.addDeactivationHeaders(urlConnection, nodeUUID, handshakeKey);
191 status = urlConnection.getHeaderField(ACTIVATION_ATTRIBUTE_STATUS);
192 }
193
194
195 if (StringUtils.equals(status, ACTIVATION_FAILED)) {
196 String message = urlConnection.getHeaderField(ACTIVATION_ATTRIBUTE_MESSAGE);
197 throw new ExchangeException("Message received from subscriber: " + message);
198 }
199
200 urlConnection.getContent();
201
202 } catch (MalformedURLException e) {
203 success = false;
204 activationMonitor.logError(path, user.getName(), workspaceName, subscriber.getName(), e, true);
205 throw new ExchangeException("Incorrect URL for subscriber " + subscriber + "[" + SecurityUtil.stripPasswordFromUrl(urlString) + "]");
206 } catch (IOException e) {
207 success = false;
208 activationMonitor.logError(path, user.getName(), workspaceName, subscriber.getName(), e, true);
209 throw new ExchangeException("Not able to send the deactivation request [" + SecurityUtil.stripPasswordFromUrl(urlString) + "]: " + e.getMessage());
210 } catch (Exception e) {
211 success = false;
212 activationMonitor.logError(path, user.getName(), workspaceName, subscriber.getName(), e, true);
213 throw new ExchangeException(e);
214 } finally {
215 releaseConnection(urlConnection);
216 activationMonitor.logActivation(path, user.getName(), workspaceName, subscriber.getName(), true, success);
217 }
218 }
219 return null;
220 }
221
222 protected Collection<Subscriber> getSubscribers() {
223 return ActivationManagerFactory.getActivationManager().getSubscribers();
224 }
225 }