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.Content;
37 import info.magnolia.cms.core.HierarchyManager;
38 import info.magnolia.cms.core.ItemType;
39 import info.magnolia.cms.core.MetaData;
40 import info.magnolia.cms.core.Path;
41 import info.magnolia.cms.core.SystemProperty;
42 import info.magnolia.cms.core.version.ContentVersion;
43 import info.magnolia.cms.exchange.ExchangeException;
44 import info.magnolia.cms.exchange.Subscriber;
45 import info.magnolia.cms.exchange.Subscription;
46 import info.magnolia.cms.exchange.Syndicator;
47 import info.magnolia.cms.security.AccessDeniedException;
48 import info.magnolia.cms.security.User;
49 import info.magnolia.cms.util.ContentUtil;
50 import info.magnolia.cms.util.Rule;
51 import info.magnolia.cms.util.RuleBasedContentFilter;
52 import info.magnolia.context.MgnlContext;
53 import info.magnolia.logging.AuditLoggingUtil;
54 import info.magnolia.repository.RepositoryConstants;
55
56 import java.io.File;
57 import java.io.FileInputStream;
58 import java.io.FileOutputStream;
59 import java.io.IOException;
60 import java.io.OutputStream;
61 import java.io.UnsupportedEncodingException;
62 import java.net.HttpURLConnection;
63 import java.net.MalformedURLException;
64 import java.net.URL;
65 import java.net.URLConnection;
66 import java.net.URLEncoder;
67 import java.util.Calendar;
68 import java.util.Iterator;
69 import java.util.List;
70 import java.util.zip.GZIPOutputStream;
71
72 import javax.jcr.RepositoryException;
73 import javax.jcr.Session;
74
75 import org.apache.commons.codec.binary.Base64;
76 import org.apache.commons.io.IOUtils;
77 import org.apache.commons.lang.StringUtils;
78 import org.apache.xml.serialize.OutputFormat;
79 import org.apache.xml.serialize.XMLSerializer;
80 import org.jdom.Document;
81 import org.jdom.Element;
82 import org.jdom.output.XMLOutputter;
83 import org.slf4j.Logger;
84 import org.slf4j.LoggerFactory;
85 import org.xml.sax.InputSource;
86 import org.xml.sax.SAXException;
87 import org.xml.sax.XMLReader;
88 import org.xml.sax.helpers.XMLReaderFactory;
89
90 import EDU.oswego.cs.dl.util.concurrent.Sync;
91
92
93
94
95
96
97 public abstract class BaseSyndicatorImpl implements Syndicator {
98 private static final Logger log = LoggerFactory.getLogger(BaseSyndicatorImpl.class);
99
100
101
102
103 public static final String DEFAULT_HANDLER = ".magnolia/activation";
104
105 public static final String PARENT_PATH = "mgnlExchangeParentPath";
106
107 public static final String MAPPED_PARENT_PATH = "mgnlExchangeMappedParent";
108
109
110
111
112 public static final String PATH = "mgnlExchangePath";
113
114 public static final String NODE_UUID = "mgnlExchangeNodeUUID";
115
116
117
118
119 public static final String REPOSITORY_NAME = "mgnlExchangeRepositoryName";
120
121 public static final String WORKSPACE_NAME = "mgnlExchangeWorkspaceName";
122
123 public static final String VERSION_NAME = "mgnlExchangeVersionName";
124
125
126
127
128 public static final String RESOURCE_MAPPING_FILE = "mgnlExchangeResourceMappingFile";
129
130 public static final String UTF8_STATUS = "mgnlUTF8Status";
131
132
133
134
135
136
137 public static final String SIBLINGS_ROOT_ELEMENT = "NodeSiblings";
138
139 public static final String SIBLINGS_ELEMENT = "sibling";
140
141 public static final String SIBLING_UUID = "siblingUUID";
142
143 public static final String RESOURCE_MAPPING_FILE_ELEMENT = "File";
144
145 public static final String RESOURCE_MAPPING_NAME_ATTRIBUTE = "name";
146
147 public static final String RESOURCE_MAPPING_UUID_ATTRIBUTE = "contentUUID";
148
149 public static final String RESOURCE_MAPPING_ID_ATTRIBUTE = "resourceId";
150
151 public static final String RESOURCE_MAPPING_ROOT_ELEMENT = "Resources";
152
153 public static final String ACTION = "mgnlExchangeAction";
154
155 public static final String ACTIVATE = "activate";
156
157 public static final String DEACTIVATE = "deactivate";
158
159 public static final String COMMIT = "commit";
160
161 public static final String ROLLBACK = "rollback";
162
163 public static final String AUTHORIZATION = "Authorization";
164
165 public static final String AUTH_CREDENTIALS= "mgnlUserPSWD";
166
167 public static final String AUTH_USER = "mgnlUserId";
168
169 public static final String CONTENT_FILTER_RULE = "mgnlExchangeFilterRule";
170
171 public static final String ACTIVATION_SUCCESSFUL = "sa_success";
172
173 public static final String ACTIVATION_FAILED = "sa_failed";
174
175 public static final String ACTIVATION_ATTRIBUTE_STATUS = "sa_attribute_status";
176
177 public static final String ACTIVATION_ATTRIBUTE_MESSAGE = "sa_attribute_message";
178
179 public static final String ACTIVATION_ATTRIBUTE_VERSION = "sa_attribute_version";
180
181
182
183
184
185
186
187 protected static void executeInPool(Runnable job) throws ExchangeException {
188 try {
189 ThreadPool.getInstance().execute(job);
190 } catch (InterruptedException e) {
191
192
193
194
195 String message = "could not execute job in pool";
196 log.error(message, e);
197 throw new ExchangeException(message, e);
198 }
199 }
200
201
202
203
204
205
206
207
208
209
210 protected static void acquireIgnoringInterruption(Sync latch) {
211 try {
212 latch.acquire();
213 } catch (InterruptedException e) {
214
215 acquireIgnoringInterruption(latch);
216
217 Thread.currentThread().interrupt();
218 }
219 }
220
221
222
223
224 protected String repositoryName;
225
226 protected String workspaceName;
227
228 protected String parent;
229
230 protected Content.ContentFilter contentFilter;
231
232 protected Rule contentFilterRule;
233
234 protected User user;
235
236 protected String basicCredentials;
237
238 private Calendar contentVersionDate;
239
240
241
242
243
244
245
246
247
248 @Override
249 public void init(User user, String repositoryName, String workspaceName, Rule rule) {
250 this.user = user;
251 this.basicCredentials = "Basic "
252 + new String(Base64.encodeBase64((this.user.getName() + ":" + this.user.getPassword()).getBytes()));
253 this.contentFilter = new RuleBasedContentFilter(rule);
254 this.contentFilterRule = rule;
255 this.repositoryName = repositoryName;
256 this.workspaceName = workspaceName;
257 }
258
259
260
261
262
263
264
265
266
267 @Override
268 public void activate(String parent, Content content) throws ExchangeException, RepositoryException {
269 this.activate(parent, content, null);
270 }
271
272
273
274
275
276
277
278
279
280
281
282 @Override
283 public void activate(String parent, Content content, List<String> orderBefore) throws ExchangeException, RepositoryException {
284 this.activate(null, parent, content, orderBefore);
285 }
286
287
288
289
290
291
292
293
294
295
296 @Override
297 public void activate(Subscriber subscriber, String parent, Content content) throws ExchangeException, RepositoryException {
298 this.activate(subscriber, parent, content, null);
299 }
300
301
302
303
304
305
306
307
308
309
310
311 @Override
312 public void activate(Subscriber subscriber, String parent, Content content, List<String> orderBefore) throws ExchangeException, RepositoryException {
313 this.parent = parent;
314 String path = content.getHandle();
315
316 if (content instanceof ContentVersion) {
317 contentVersionDate = ((ContentVersion)content).getCreated();
318 }
319
320 ActivationContent activationContent = null;
321 try {
322 activationContent = this.collect(content, orderBefore);
323 if (null == subscriber) {
324 this.activate(activationContent, path);
325 } else {
326 this.activate(subscriber, activationContent, path);
327 }
328 if (Boolean.parseBoolean(activationContent.getproperty(ItemType.DELETED_NODE_MIXIN))) {
329 final HierarchyManager hm = content.getHierarchyManager();
330 final Session session = content.getJCRNode().getSession();
331 String uuid = content.getUUID();
332 if (StringUtils.isNotBlank(uuid)) {
333 if (content instanceof ContentVersion) {
334
335 content = hm.getContentByUUID(uuid);
336 }
337 Content parentContent = content.getParent();
338 content.delete();
339 parentContent.save();
340 } else {
341 log.warn("Content {}:{} was already removed.", new String[] {content.getWorkspace().getName(), path});
342 }
343 } else {
344 this.updateActivationDetails(path);
345 }
346 log.info("Exchange: activation succeeded [{}]", path);
347 } catch (Exception e) {
348 if (log.isDebugEnabled()) {
349 log.error("Exchange: activation failed for path:" + ((path != null) ? path : "[null]"), e);
350 long timestamp = System.currentTimeMillis();
351 log.warn("moving files from failed activation to *.failed" + timestamp );
352 Iterator<File> keys = activationContent.getFiles().values().iterator();
353 while (keys.hasNext()) {
354 File f = keys.next();
355 f.renameTo(new File(f.getAbsolutePath()+".failed" + timestamp));
356 }
357 activationContent.getFiles().clear();
358
359 }
360 throw new ExchangeException(e);
361 } finally {
362 log.debug("Cleaning temporary files");
363 cleanTemporaryStore(activationContent);
364 }
365 }
366
367
368
369
370 public abstract void activate(ActivationContent activationContent, String nodePath) throws ExchangeException;
371
372
373
374
375
376 public String activate(Subscriber subscriber, ActivationContent activationContent, String nodePath) throws ExchangeException {
377
378 log.debug("activate");
379 if (null == subscriber) {
380 throw new ExchangeException("Null Subscriber");
381 }
382
383 String parentPath = null;
384
385
386 Subscription subscription = subscriber.getMatchedSubscription(nodePath, this.repositoryName);
387 if (null != subscription) {
388
389 parentPath = this.getMappedPath(this.parent, subscription);
390 activationContent.setProperty(PARENT_PATH, parentPath);
391 } else {
392 log.debug("Exchange : subscriber [{}] is not subscribed to {}", subscriber.getName(), nodePath);
393 return "not subscribed";
394 }
395 log.debug("Exchange : sending activation request to {} with user {}", subscriber.getName(), this.user.getName());
396
397 URLConnection urlConnection = null;
398 String versionName = null;
399 try {
400 urlConnection = prepareConnection(subscriber, getActivationURL(subscriber));
401 this.addActivationHeaders(urlConnection, activationContent);
402
403 Transporter.transport((HttpURLConnection) urlConnection, activationContent);
404
405 String status = urlConnection.getHeaderField(ACTIVATION_ATTRIBUTE_STATUS);
406 versionName = urlConnection.getHeaderField(ACTIVATION_ATTRIBUTE_VERSION);
407
408
409 if (StringUtils.equals(status, ACTIVATION_FAILED)) {
410 String message = urlConnection.getHeaderField(ACTIVATION_ATTRIBUTE_MESSAGE);
411 throw new ExchangeException("Message received from subscriber: " + message);
412 }
413 urlConnection.getContent();
414 log.debug("Exchange : activation request sent to {}", subscriber.getName());
415 }
416 catch (ExchangeException e) {
417 throw e;
418 }
419 catch (IOException e) {
420 log.debug("Failed to transport following activated content {" + StringUtils.join(activationContent.getProperties().keySet().iterator(), ',') + "} due to " + e.getMessage(), e);
421 String url = (urlConnection == null ? null : urlConnection.getURL().toString());
422 url = stripPasswordFromUrl(url);
423
424 throw new ExchangeException("Not able to send the activation request [" + url + "]: " + e.getMessage(), e);
425 }
426 catch (Exception e) {
427 throw new ExchangeException(e);
428 }
429 return versionName;
430 }
431
432 public static String stripPasswordFromUrl(String escapedUrl) {
433 if (escapedUrl != null) {
434 int idx = escapedUrl.indexOf("mgnlUserPSWD");
435 if (idx > 0) {
436 int endIdx = escapedUrl.indexOf("&", idx);
437 if (endIdx > 0) {
438 escapedUrl = escapedUrl.substring(0, idx) + escapedUrl.substring(endIdx + 1);
439 } else {
440 escapedUrl = escapedUrl.substring(0, idx - 1);
441 }
442 }
443 }
444 return escapedUrl;
445 }
446
447
448
449
450
451 protected void cleanTemporaryStore(ActivationContent activationContent) {
452 if (activationContent == null) {
453 log.debug("Clean temporary store - nothing to do");
454 return;
455 }
456 if (log.isDebugEnabled()) {
457 log.debug("Debugging is enabled. Keeping temporary files in store for debugging purposes. Clean the store manually once done with debugging.");
458 return;
459 }
460
461 Iterator<String> keys = activationContent.getFiles().keySet().iterator();
462 while (keys.hasNext()) {
463 String key = keys.next();
464 log.debug("Removing temporary file {}", key);
465 activationContent.getFile(key).delete();
466 }
467 }
468
469 public synchronized void deactivate(String path) throws ExchangeException, RepositoryException {
470 final Content node = getHierarchyManager().getContent(path);
471 deactivate(node);
472 }
473
474
475
476
477
478
479 @Override
480 public synchronized void deactivate(Content node) throws ExchangeException, RepositoryException {
481 String nodeUUID = node.getUUID();
482 String path = node.getHandle();
483 this.doDeactivate(nodeUUID, path);
484 updateDeactivationDetails(nodeUUID);
485 }
486
487
488
489
490
491
492
493 @Override
494 public synchronized void deactivate(Subscriber subscriber, Content node) throws ExchangeException, RepositoryException {
495 String nodeUUID = node.getUUID();
496 String path = node.getHandle();
497 this.doDeactivate(subscriber, nodeUUID, path);
498 updateDeactivationDetails(nodeUUID);
499 }
500
501
502
503
504 public abstract void doDeactivate(String nodeUUID, String nodePath) throws ExchangeException;
505
506
507
508
509
510
511 public abstract String doDeactivate(Subscriber subscriber, String nodeUUID, String nodePath) throws ExchangeException;
512
513
514
515
516
517 protected String getDeactivationURL(Subscriber subscriberInfo) {
518 return getActivationURL(subscriberInfo);
519 }
520
521
522
523
524
525 protected void addDeactivationHeaders(URLConnection connection, String nodeUUID) {
526 connection.addRequestProperty(REPOSITORY_NAME, this.repositoryName);
527 connection.addRequestProperty(WORKSPACE_NAME, this.workspaceName);
528 if (nodeUUID != null) {
529 connection.addRequestProperty(NODE_UUID, nodeUUID);
530 }
531 connection.addRequestProperty(ACTION, DEACTIVATE);
532 }
533
534
535
536
537 protected String getActivationURL(Subscriber subscriberInfo) {
538 final String url = subscriberInfo.getURL();
539 if (!url.endsWith("/")) {
540 return url + "/" + DEFAULT_HANDLER;
541 }
542 return url + DEFAULT_HANDLER;
543 }
544
545
546
547
548 protected void addActivationHeaders(URLConnection connection, ActivationContent activationContent) {
549 Iterator<String> headerKeys = activationContent.getProperties().keySet().iterator();
550 while (headerKeys.hasNext()) {
551 String key = headerKeys.next();
552 String value = activationContent.getproperty(key);
553 if(SystemProperty.getBooleanProperty(SystemProperty.MAGNOLIA_UTF8_ENABLED)) {
554 try {
555 value = URLEncoder.encode(value, "UTF-8");
556 }
557 catch (UnsupportedEncodingException e) {
558
559 }
560 }
561 connection.setRequestProperty(key, value);
562 }
563 }
564
565
566
567
568 protected void updateActivationDetails(String path) throws RepositoryException {
569
570 Content page = getSystemHierarchyManager().getContent(path);
571 updateMetaData(page, ACTIVATE);
572 page.save();
573 AuditLoggingUtil.log(AuditLoggingUtil.ACTION_ACTIVATE, this.workspaceName, page.getItemType(), path );
574 }
575
576
577
578
579 protected void updateDeactivationDetails(String nodeUUID) throws RepositoryException {
580
581 Content page = getSystemHierarchyManager().getContentByUUID(nodeUUID);
582 updateMetaData(page, DEACTIVATE);
583 page.save();
584 AuditLoggingUtil.log(AuditLoggingUtil.ACTION_DEACTIVATE, this.workspaceName, page.getItemType(), page.getHandle() );
585 }
586
587
588 private HierarchyManager getHierarchyManager() {
589 return MgnlContext.getHierarchyManager(this.workspaceName);
590 }
591
592 private HierarchyManager getSystemHierarchyManager() {
593 return MgnlContext.getSystemContext().getHierarchyManager(this.workspaceName);
594 }
595
596
597
598
599
600 protected void updateMetaData(Content node, String type) throws AccessDeniedException {
601
602 MetaData md = node.getMetaData();
603 if (type.equals(ACTIVATE)) {
604 md.setActivated();
605 }
606 else {
607 md.setUnActivated();
608 }
609 md.setActivatorId(this.user.getName());
610 md.setLastActivationActionDate();
611
612 if(type.equals(ACTIVATE)){
613 if(md.getModificationDate() != null && md.getModificationDate().after(contentVersionDate)){
614 try {
615 Thread.sleep(1);
616 } catch (InterruptedException e) {
617 e.printStackTrace();
618 }
619 md.setModificationDate();
620 }
621 }
622
623 Iterator<Content> children;
624 if (type.equals(ACTIVATE)) {
625
626 children = node.getChildren(this.contentFilter).iterator();
627 }
628 else {
629
630 children = node.getChildren(ContentUtil.EXCLUDE_META_DATA_CONTENT_FILTER).iterator();
631 }
632
633 while (children.hasNext()) {
634 Content child = children.next();
635 this.updateMetaData(child, type);
636 }
637
638
639 }
640
641
642
643
644
645 protected ActivationContent collect(Content node, List<String> orderBefore) throws Exception {
646
647 File resourceFile = File.createTempFile("resources", ".xml", Path.getTempDirectory());
648
649 ActivationContent activationContent = new ActivationContent();
650
651 activationContent.addProperty(PARENT_PATH, this.parent);
652 activationContent.addProperty(WORKSPACE_NAME, this.workspaceName);
653 activationContent.addProperty(REPOSITORY_NAME, this.repositoryName);
654 activationContent.addProperty(RESOURCE_MAPPING_FILE, resourceFile.getName());
655 activationContent.addProperty(ACTION, ACTIVATE);
656 activationContent.addProperty(CONTENT_FILTER_RULE, this.contentFilterRule.toString());
657 activationContent.addProperty(NODE_UUID, node.getUUID());
658 activationContent.addProperty(UTF8_STATUS, SystemProperty.getProperty(SystemProperty.MAGNOLIA_UTF8_ENABLED));
659
660
661 Document document = new Document();
662 Element root = new Element(RESOURCE_MAPPING_ROOT_ELEMENT);
663 document.setRootElement(root);
664
665 addOrderingInfo(root, orderBefore);
666
667 this.addResources(root, node.getWorkspace().getSession(), node, this.contentFilter, activationContent);
668 XMLOutputter outputter = new XMLOutputter();
669 outputter.output(document, new FileOutputStream(resourceFile));
670
671 activationContent.addFile(resourceFile.getName(), resourceFile);
672
673
674 activationContent.addProperty(ItemType.DELETED_NODE_MIXIN, "" + node.hasMixin(ItemType.DELETED_NODE_MIXIN));
675
676 return activationContent;
677 }
678
679
680
681
682
683
684 protected void addOrderingInfo(Element root, List<String> orderBefore) {
685
686 Element siblingRoot = new Element(SIBLINGS_ROOT_ELEMENT);
687 root.addContent(siblingRoot);
688 if (orderBefore == null) {
689 return;
690 }
691 Iterator<String> siblings = orderBefore.iterator();
692 while (siblings.hasNext()) {
693 String uuid = siblings.next();
694 Element e = new Element(SIBLINGS_ELEMENT);
695 e.setAttribute(SIBLING_UUID, uuid);
696 siblingRoot.addContent(e);
697 }
698 }
699
700 protected void addResources(Element resourceElement, Session session, final Content content, Content.ContentFilter filter, ActivationContent activationContent) throws IOException, RepositoryException, SAXException, Exception {
701 final String workspaceName = content.getWorkspace().getName();
702 log.debug("Preparing content {}:{} for publishing.", new String[] {workspaceName, content.getHandle()});
703 final String uuid = content.getUUID();
704
705 File file = File.createTempFile("exchange_" + uuid, ".xml.gz", Path.getTempDirectory());
706 GZIPOutputStream gzipOutputStream = new GZIPOutputStream(new FileOutputStream(file));
707
708
709 if (content.isNodeType("nt:frozenNode") || workspaceName.equals(RepositoryConstants.VERSION_STORE)) {
710 XMLReader elementfilter = new FrozenElementFilter(XMLReaderFactory
711 .createXMLReader(org.apache.xerces.parsers.SAXParser.class.getName()));
712 ((FrozenElementFilter) elementfilter).setNodeName(content.getName());
713
714
715
716 boolean noRecurse = !content.isNodeType(ItemType.NT_FILE);
717 exportAndParse(session, content, elementfilter, gzipOutputStream, noRecurse);
718 } else {
719
720
721
722 if (content.isNodeType(ItemType.NT_FILE)) {
723 session.exportSystemView(content.getJCRNode().getPath(), gzipOutputStream, false, false);
724 } else {
725 session.exportSystemView(content.getJCRNode().getPath(), gzipOutputStream, false, true);
726 }
727 }
728
729 IOUtils.closeQuietly(gzipOutputStream);
730
731 Element element = new Element(RESOURCE_MAPPING_FILE_ELEMENT);
732 element.setAttribute(RESOURCE_MAPPING_NAME_ATTRIBUTE, content.getName());
733 element.setAttribute(RESOURCE_MAPPING_UUID_ATTRIBUTE, uuid);
734 element.setAttribute(RESOURCE_MAPPING_ID_ATTRIBUTE, file.getName());
735 resourceElement.addContent(element);
736
737 activationContent.addFile(file.getName(), file);
738
739 Iterator<Content> children = content.getChildren(filter).iterator();
740 while (children.hasNext()) {
741 Content child = children.next();
742 this.addResources(element, session, child, filter, activationContent);
743 }
744 }
745
746 protected void exportAndParse(Session session, Content content, XMLReader elementfilter, OutputStream os, boolean noRecurse) throws Exception {
747 File tempFile = File.createTempFile("Frozen_"+content.getName(), ".xml");
748 OutputStream tmpFileOutStream = null;
749 FileInputStream tmpFileInStream = null;
750 try {
751 tmpFileOutStream = new FileOutputStream(tempFile);
752
753 session.exportSystemView(content.getJCRNode().getPath(), tmpFileOutStream, false, noRecurse);
754 tmpFileOutStream.flush();
755 tmpFileOutStream.close();
756
757 OutputFormat outputFormat = new OutputFormat();
758 outputFormat.setPreserveSpace(false);
759
760 tmpFileInStream = new FileInputStream(tempFile);
761 elementfilter.setContentHandler(new XMLSerializer(os, outputFormat));
762 elementfilter.parse(new InputSource(tmpFileInStream));
763 tmpFileInStream.close();
764 } catch (Throwable t) {
765 log.error("Failed to parse XML using FrozenElementFilter",t);
766 throw new Exception(t);
767 } finally {
768 IOUtils.closeQuietly(tmpFileInStream);
769 IOUtils.closeQuietly(tmpFileOutStream);
770 tempFile.delete();
771 }
772 }
773
774
775
776
777 protected String getMappedPath(String path, Subscription subscription) {
778 String toURI = subscription.getToURI();
779 if (null != toURI) {
780 String fromURI = subscription.getFromURI();
781
782 fromURI = StringUtils.removeEnd(fromURI, "/");
783 toURI = StringUtils.removeEnd(toURI, "/");
784
785 path = path.replaceFirst(fromURI, toURI);
786 if (path.equals("")) {
787 path = "/";
788 }
789 }
790 return path;
791 }
792
793 protected URLConnection prepareConnection(Subscriber subscriber, String urlString) throws ExchangeException {
794
795
796
797 try {
798 String authMethod = subscriber.getAuthenticationMethod();
799
800 if (authMethod != null && "form".equalsIgnoreCase(authMethod)) {
801 urlString += (urlString.indexOf('?') > 0 ? "&" : "?") + AUTH_USER + "=" + this.user.getName();
802 urlString += "&" + AUTH_CREDENTIALS + "=" + this.user.getPassword();
803 }
804 URL url = new URL(urlString);
805 URLConnection urlConnection = url.openConnection();
806 urlConnection.setConnectTimeout(subscriber.getConnectTimeout());
807 urlConnection.setReadTimeout(subscriber.getReadTimeout());
808
809 if (authMethod == null || "basic".equalsIgnoreCase(authMethod)) {
810 urlConnection.setRequestProperty(AUTHORIZATION, this.basicCredentials);
811 } else if (!"form".equalsIgnoreCase(subscriber.getAuthenticationMethod())) {
812 log.info("Unknown Authentication method for deactivation: " + subscriber.getAuthenticationMethod());
813 }
814
815 return urlConnection;
816 } catch (MalformedURLException e) {
817 throw new ExchangeException("Incorrect URL for subscriber " + subscriber + "[" + stripPasswordFromUrl(urlString) + "]");
818 } catch (IOException e) {
819 throw new ExchangeException("Not able to send the activation request [" + stripPasswordFromUrl(urlString) + "]: " + e.getMessage());
820 } catch (Exception e) {
821 throw new ExchangeException(e);
822 }
823 }
824
825
826 }