sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tomm...@apache.org
Subject svn commit: r1629691 - in /sling/trunk/contrib/extensions/replication: core/src/main/java/org/apache/sling/replication/agent/impl/ core/src/main/java/org/apache/sling/replication/packaging/impl/importer/ core/src/main/java/org/apache/sling/replication/...
Date Mon, 06 Oct 2014 16:03:21 GMT
Author: tommaso
Date: Mon Oct  6 16:03:20 2014
New Revision: 1629691

URL: http://svn.apache.org/r1629691
Log:
SLING-4008 - added JcrEventReplicationTrigger

Added:
    sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/trigger/impl/JcrEventReplicationTrigger.java
  (with props)
Modified:
    sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/CoordinatingReplicationAgentFactory.java
    sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentFactory.java
    sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/SimpleReplicationAgentFactory.java
    sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/packaging/impl/importer/RemoteReplicationPackageImporter.java
    sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/serialization/impl/vlt/FileVaultReplicationPackageBuilder.java
    sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/trigger/impl/ResourceEventReplicationTrigger.java
    sling/trunk/contrib/extensions/replication/it/src/main/resources/SLING-CONTENT/libs/test/install.author/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-test-content-event.json
    sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-content-changed.json
    sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.SimpleReplicationAgentFactory-reverse.json

Modified: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/CoordinatingReplicationAgentFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/CoordinatingReplicationAgentFactory.java?rev=1629691&r1=1629690&r2=1629691&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/CoordinatingReplicationAgentFactory.java
(original)
+++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/CoordinatingReplicationAgentFactory.java
Mon Oct  6 16:03:20 2014
@@ -52,7 +52,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * An OSGi service factory for {@link org.apache.sling.replication.agent.ReplicationAgent}s
which references already existing OSGi services.
+ * An OSGi service factory for 'Coordinate' {@link org.apache.sling.replication.agent.ReplicationAgent}s.
  */
 @Component(metatype = true,
         label = "Coordinating Replication Agents Factory",
@@ -99,7 +99,6 @@ public class CoordinatingReplicationAgen
     @Reference(name = "transportAuthenticationProvider")
     private volatile TransportAuthenticationProvider transportAuthenticationProvider;
 
-
     @Reference
     private ReplicationEventFactory replicationEventFactory;
 
@@ -109,18 +108,11 @@ public class CoordinatingReplicationAgen
     @Reference
     private ReplicationComponentFactory componentFactory;
 
-
-
     private ServiceRegistration componentReg;
-    private BundleContext savedContext;
-    private Map<String, Object> savedConfig;
 
     @Activate
     public void activate(BundleContext context, Map<String, Object> config) {
 
-        savedContext = context;
-        savedConfig = config;
-
         // inject configuration
         Dictionary<String, Object> props = new Hashtable<String, Object>();
 
@@ -152,7 +144,7 @@ public class CoordinatingReplicationAgen
                     List<String> packageImporterPropertiesList = new ArrayList<String>();
                     packageImporterPropertiesList.addAll(Arrays.asList(packageImporterProperties));
                     packageImporterPropertiesList.add("type=remote");
-                    packageImporterProperties = packageImporterPropertiesList.toArray(new
String[0]);
+                    packageImporterProperties = packageImporterPropertiesList.toArray(new
String[packageImporterPropertiesList.size()]);
                     properties.put(PACKAGE_IMPORTER, packageImporterProperties);
                 }
 
@@ -161,7 +153,7 @@ public class CoordinatingReplicationAgen
                     List<String> packageExporterPropertiesList = new ArrayList<String>();
                     packageExporterPropertiesList.addAll(Arrays.asList(packageExporterProperties));
                     packageExporterPropertiesList.add("type=remote");
-                    packageExporterProperties = packageExporterPropertiesList.toArray(new
String[0]);
+                    packageExporterProperties = packageExporterPropertiesList.toArray(new
String[packageExporterPropertiesList.size()]);
                     properties.put(PACKAGE_EXPORTER, packageExporterProperties);
                 }
 
@@ -178,7 +170,6 @@ public class CoordinatingReplicationAgen
                     // register agent service
                     componentReg = context.registerService(ReplicationAgent.class.getName(),
agent, props);
 
-
                     if (agent instanceof ReplicationComponent) {
                         ((ReplicationComponent) agent).enable();
                     }
@@ -203,7 +194,6 @@ public class CoordinatingReplicationAgen
 
     }
 
-
     public <ComponentType> ComponentType getComponent(Class<ComponentType> type,
String componentName) {
         if (type.isAssignableFrom(ReplicationQueueProvider.class)) {
             return (ComponentType) queueProvider;
@@ -217,4 +207,4 @@ public class CoordinatingReplicationAgen
         }
         return null;
     }
-}
+}
\ No newline at end of file

Modified: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentFactory.java?rev=1629691&r1=1629690&r2=1629691&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentFactory.java
(original)
+++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentFactory.java
Mon Oct  6 16:03:20 2014
@@ -50,6 +50,7 @@ import org.apache.sling.replication.tran
 import org.apache.sling.replication.transport.authentication.impl.UserCredentialsTransportAuthenticationProvider;
 import org.apache.sling.replication.trigger.ReplicationTrigger;
 import org.apache.sling.replication.trigger.impl.ChainReplicateReplicationTrigger;
+import org.apache.sling.replication.trigger.impl.JcrEventReplicationTrigger;
 import org.apache.sling.replication.trigger.impl.RemoteEventReplicationTrigger;
 import org.apache.sling.replication.trigger.impl.ResourceEventReplicationTrigger;
 import org.apache.sling.replication.trigger.impl.ScheduledReplicationTrigger;
@@ -117,7 +118,6 @@ public class DefaultReplicationComponent
         return null;
     }
 
-
     public ReplicationAgent createAgent(Map<String, Object> properties, ReplicationComponentProvider
componentProvider) {
 
         String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "simple");
@@ -155,7 +155,6 @@ public class DefaultReplicationComponent
 
     }
 
-
     public ReplicationPackageExporter createExporter(Map<String, Object> properties,
ReplicationComponentProvider componentProvider) {
 
         String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service");
@@ -268,6 +267,8 @@ public class DefaultReplicationComponent
             return new ScheduledReplicationTrigger(properties, scheduler);
         } else if (ChainReplicateReplicationTrigger.TYPE.equals(factory)) {
             return new ChainReplicateReplicationTrigger(properties, bundleContext);
+        } else if (JcrEventReplicationTrigger.TYPE.equals(factory)) {
+            return new JcrEventReplicationTrigger(properties, repository);
         }
 
         return null;
@@ -297,4 +298,4 @@ public class DefaultReplicationComponent
         return result;
     }
 
-}
+}
\ No newline at end of file

Modified: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/SimpleReplicationAgentFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/SimpleReplicationAgentFactory.java?rev=1629691&r1=1629690&r2=1629691&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/SimpleReplicationAgentFactory.java
(original)
+++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/SimpleReplicationAgentFactory.java
Mon Oct  6 16:03:20 2014
@@ -80,7 +80,7 @@ public class SimpleReplicationAgentFacto
     @Property(boolValue = true, label = "Replicate using aggregated paths")
     public static final String USE_AGGREGATE_PATHS = "useAggregatePaths";
 
-    @Property(boolValue = false, label = "Replicate using aggregated paths")
+    @Property(boolValue = false, label = "Use this agent as a passive one (only queueing)")
     public static final String IS_PASSIVE = "isPassive";
 
 
@@ -141,7 +141,7 @@ public class SimpleReplicationAgentFacto
             String distribution = PropertiesUtil.toString(config.get(QUEUE_DISTRIBUTION_TARGET),
DEFAULT_DISTRIBUTION);
             props.put(QUEUE_DISTRIBUTION_TARGET, distribution);
 
-            if (componentReg == null) {
+            if (componentReg == null && componentFactory != null) {
                 Map<String, Object> properties = new HashMap<String, Object>();
                 properties.putAll(config);
 
@@ -183,7 +183,6 @@ public class SimpleReplicationAgentFacto
     public <ComponentType> ComponentType getComponent(Class<ComponentType> type,
String componentName) {
         if (type.isAssignableFrom(ReplicationQueueProvider.class)) {
             return (ComponentType) queueProvider;
-
         }
         else if (type.isAssignableFrom(ReplicationQueueDistributionStrategy.class)) {
             return (ComponentType) queueDistributionStrategy;

Modified: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/packaging/impl/importer/RemoteReplicationPackageImporter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/packaging/impl/importer/RemoteReplicationPackageImporter.java?rev=1629691&r1=1629690&r2=1629691&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/packaging/impl/importer/RemoteReplicationPackageImporter.java
(original)
+++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/packaging/impl/importer/RemoteReplicationPackageImporter.java
Mon Oct  6 16:03:20 2014
@@ -71,7 +71,7 @@ public class RemoteReplicationPackageImp
             transportHandler.deliverPackage(replicationPackage);
             result = true;
         } catch (Exception e) {
-            log.error("failed in importing package {} due to {}", replicationPackage, e);
+            log.error("failed in importing package {} ", replicationPackage, e);
         }
         return result;
     }

Modified: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/serialization/impl/vlt/FileVaultReplicationPackageBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/serialization/impl/vlt/FileVaultReplicationPackageBuilder.java?rev=1629691&r1=1629690&r2=1629691&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/serialization/impl/vlt/FileVaultReplicationPackageBuilder.java
(original)
+++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/serialization/impl/vlt/FileVaultReplicationPackageBuilder.java
Mon Oct  6 16:03:20 2014
@@ -54,6 +54,8 @@ import org.slf4j.LoggerFactory;
 public class FileVaultReplicationPackageBuilder extends AbstractReplicationPackageBuilder
implements
         ReplicationPackageBuilder {
 
+    public static final String USER_DATA = "vlt.pb.data";
+
     private final Logger log = LoggerFactory.getLogger(getClass());
 
     private SlingRepository repository;
@@ -114,7 +116,9 @@ public class FileVaultReplicationPackage
 
     @Override
     protected Session getSession() throws RepositoryException {
-        return repository.loginService(subServiceName, null);
+        Session session = repository.loginService(subServiceName, null);
+        session.getWorkspace().getObservationManager().setUserData(USER_DATA);
+        return session;
     }
 
     @Override

Added: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/trigger/impl/JcrEventReplicationTrigger.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/trigger/impl/JcrEventReplicationTrigger.java?rev=1629691&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/trigger/impl/JcrEventReplicationTrigger.java
(added)
+++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/trigger/impl/JcrEventReplicationTrigger.java
Mon Oct  6 16:03:20 2014
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.replication.trigger.impl;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+import java.util.Map;
+
+import org.apache.sling.commons.osgi.PropertiesUtil;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.replication.communication.ReplicationActionType;
+import org.apache.sling.replication.communication.ReplicationRequest;
+import org.apache.sling.replication.serialization.impl.vlt.FileVaultReplicationPackageBuilder;
+import org.apache.sling.replication.trigger.ReplicationTrigger;
+import org.apache.sling.replication.trigger.ReplicationTriggerRequestHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A JCR observation based {@link org.apache.sling.replication.trigger.ReplicationTrigger}.
+ * It filters events having {@link javax.jcr.observation.ObservationManager#setUserData(String)}
set to
+ * {@link org.apache.sling.replication.serialization.impl.vlt.FileVaultReplicationPackageBuilder#USER_DATA}
+ */
+public class JcrEventReplicationTrigger implements ReplicationTrigger {
+
+    public static final String TYPE = "jcrEvent";
+
+    private final Logger log = LoggerFactory.getLogger(this.getClass());
+
+    private final SlingRepository repository;
+    private final String path;
+
+    private Session adminSession;
+
+    public JcrEventReplicationTrigger(SlingRepository repository, String path) {
+        this.repository = repository;
+        this.path = path;
+    }
+
+    public JcrEventReplicationTrigger(Map<String, Object> properties, SlingRepository
repository) {
+        this(repository, PropertiesUtil.toString(properties.get("path"), null));
+    }
+
+    public void register(String handlerId, ReplicationTriggerRequestHandler requestHandler)
{
+        log.info("activating ExampleObservation");
+        try {
+            adminSession = repository.loginService("replicationService", null);
+            adminSession.getWorkspace().getObservationManager().addEventListener(
+                    new JcrEventReplicationTriggerHandler(requestHandler), Event.NODE_ADDED
| Event.NODE_MOVED | Event.NODE_REMOVED | Event.PROPERTY_CHANGED |
+                            Event.PROPERTY_ADDED | Event.PROPERTY_REMOVED, path, true, null,
null, false);
+        } catch (RepositoryException e) {
+            log.error("unable to register session", e);
+        }
+    }
+
+    public void unregister(String handlerId) {
+        if (adminSession != null) {
+            adminSession.logout();
+        }
+    }
+
+    private class JcrEventReplicationTriggerHandler implements EventListener {
+        private final ReplicationTriggerRequestHandler requestHandler;
+
+        public JcrEventReplicationTriggerHandler(ReplicationTriggerRequestHandler requestHandler)
{
+            this.requestHandler = requestHandler;
+        }
+
+        public void onEvent(EventIterator eventIterator) {
+            try {
+                while (eventIterator.hasNext()) {
+                    Event event = eventIterator.nextEvent();
+                    // TODO : check for JackrabbitEvent#isExternal
+                    String userData = event.getUserData();
+                    log.info("event userData is {}", userData);
+                    if (!FileVaultReplicationPackageBuilder.USER_DATA.equals(userData)) {
+                        log.info("triggering replication from jcr event {}", event);
+
+                        Object pathProperty = event.getPath();
+                        if (pathProperty != null) {
+                            String replicatingPath = String.valueOf(pathProperty);
+                            requestHandler.handle(new ReplicationRequest(System.currentTimeMillis(),
Event.NODE_MOVED ==
+                                    event.getType() ? ReplicationActionType.DELETE : ReplicationActionType.ADD,
replicatingPath));
+                        }
+                    }
+                }
+            } catch (RepositoryException e) {
+                log.error("Error while treating events", e);
+            }
+        }
+
+    }
+}

Propchange: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/trigger/impl/JcrEventReplicationTrigger.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/trigger/impl/ResourceEventReplicationTrigger.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/trigger/impl/ResourceEventReplicationTrigger.java?rev=1629691&r1=1629690&r2=1629691&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/trigger/impl/ResourceEventReplicationTrigger.java
(original)
+++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/trigger/impl/ResourceEventReplicationTrigger.java
Mon Oct  6 16:03:20 2014
@@ -39,7 +39,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * {@link org.apache.sling.replication.trigger.ReplicationTrigger} for triggering a specific
agent upon node / properties being changed under a certain path
+ * {@link org.apache.sling.replication.trigger.ReplicationTrigger} for triggering a specific
handler (e.g. agent) upon
+ * node / properties being changed under a certain path
  */
 public class ResourceEventReplicationTrigger implements ReplicationTrigger, ReplicationComponent
{
 

Modified: sling/trunk/contrib/extensions/replication/it/src/main/resources/SLING-CONTENT/libs/test/install.author/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-test-content-event.json
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/it/src/main/resources/SLING-CONTENT/libs/test/install.author/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-test-content-event.json?rev=1629691&r1=1629690&r2=1629691&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/replication/it/src/main/resources/SLING-CONTENT/libs/test/install.author/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-test-content-event.json
(original)
+++ sling/trunk/contrib/extensions/replication/it/src/main/resources/SLING-CONTENT/libs/test/install.author/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-test-content-event.json
Mon Oct  6 16:03:20 2014
@@ -5,7 +5,7 @@
     "componentType": "trigger",
 
     "properties": [
-        "type=resourceEvent",
+        "type=jcrEvent",
         "path=/content"
 
     ]

Modified: sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-content-changed.json
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-content-changed.json?rev=1629691&r1=1629690&r2=1629691&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-content-changed.json
(original)
+++ sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-content-changed.json
Mon Oct  6 16:03:20 2014
@@ -5,7 +5,7 @@
     "componentType": "trigger",
 
     "properties": [
-        "type=resourceEvent",
+        "type=jcrEvent",
         "path=/content/usergenerated"
     ]
 

Modified: sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.SimpleReplicationAgentFactory-reverse.json
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.SimpleReplicationAgentFactory-reverse.json?rev=1629691&r1=1629690&r2=1629691&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.SimpleReplicationAgentFactory-reverse.json
(original)
+++ sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.SimpleReplicationAgentFactory-reverse.json
Mon Oct  6 16:03:20 2014
@@ -22,7 +22,7 @@
     "queueDistributionStrategy": "(name=error)",
 
     "trigger0": [
-        "type=resourceEvent",
+        "type=jcrEvent",
         "path=/content/usergenerated"
     ]
 }



Mime
View raw message