incubator-accumulo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bil...@apache.org
Subject svn commit: r1214447 - in /incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client: admin/ impl/ mock/
Date Wed, 14 Dec 2011 20:26:32 GMT
Author: billie
Date: Wed Dec 14 20:26:32 2011
New Revision: 1214447

URL: http://svn.apache.org/viewvc?rev=1214447&view=rev
Log:
ACCUMULO-216 extracted interface from InstanceOperations, implemented MockInstanceOperations

Added:
    incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperationsImpl.java
      - copied, changed from r1212505, incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperations.java
    incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockInstanceOperations.java
  (with props)
Modified:
    incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperations.java
    incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/impl/ConnectorImpl.java
    incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockAccumulo.java
    incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockConnector.java

Modified: incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperations.java
URL: http://svn.apache.org/viewvc/incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperations.java?rev=1214447&r1=1214446&r2=1214447&view=diff
==============================================================================
--- incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperations.java
(original)
+++ incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperations.java
Wed Dec 14 20:26:32 2011
@@ -1,4 +1,4 @@
-/*
+/**
  * 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.
@@ -16,49 +16,16 @@
  */
 package org.apache.accumulo.core.client.admin;
 
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.client.AccumuloException;
 import org.apache.accumulo.core.client.AccumuloSecurityException;
-import org.apache.accumulo.core.client.Instance;
-import org.apache.accumulo.core.client.TableNotFoundException;
-import org.apache.accumulo.core.client.impl.ClientExec;
-import org.apache.accumulo.core.client.impl.ClientExecReturn;
-import org.apache.accumulo.core.client.impl.MasterClient;
-import org.apache.accumulo.core.client.impl.ServerClient;
-import org.apache.accumulo.core.client.impl.thrift.ClientService;
-import org.apache.accumulo.core.client.impl.thrift.ConfigurationType;
-import org.apache.accumulo.core.master.thrift.MasterClientService;
-import org.apache.accumulo.core.security.thrift.AuthInfo;
-import org.apache.accumulo.core.tabletserver.thrift.TabletClientService;
-import org.apache.accumulo.core.tabletserver.thrift.TabletClientService.Iface;
-import org.apache.accumulo.core.util.ArgumentChecker;
-import org.apache.accumulo.core.util.ThriftUtil;
-import org.apache.accumulo.core.zookeeper.ZooCache;
-import org.apache.accumulo.core.zookeeper.ZooUtil;
 
 /**
- * Provides a class for administering the accumulo instance
+ * 
  */
-public class InstanceOperations {
-  private Instance instance;
-  private AuthInfo credentials;
-  
-  /**
-   * @param instance
-   *          the connection information for this instance
-   * @param credentials
-   *          the username/password for this connection
-   */
-  public InstanceOperations(Instance instance, AuthInfo credentials) {
-    ArgumentChecker.notNull(instance, credentials);
-    this.instance = instance;
-    this.credentials = credentials;
-  }
+public interface InstanceOperations {
   
   /**
    * Sets an instance property in zookeeper. Tablet servers will pull this setting and override
the equivalent setting in accumulo-site.xml
@@ -72,15 +39,7 @@ public class InstanceOperations {
    * @throws AccumuloSecurityException
    *           if the user does not have permission
    */
-  public void setProperty(final String property, final String value) throws AccumuloException,
AccumuloSecurityException {
-    ArgumentChecker.notNull(property, value);
-    MasterClient.execute(instance, new ClientExec<MasterClientService.Iface>() {
-      @Override
-      public void execute(MasterClientService.Iface client) throws Exception {
-        client.setSystemProperty(null, credentials, property, value);
-      }
-    });
-  }
+  public void setProperty(final String property, final String value) throws AccumuloException,
AccumuloSecurityException;
   
   /**
    * Removes a instance property from zookeeper
@@ -94,33 +53,11 @@ public class InstanceOperations {
    * @throws AccumuloSecurityException
    *           if the user does not have permission
    */
-  public void removeProperty(final String property) throws AccumuloException, AccumuloSecurityException
{
-    ArgumentChecker.notNull(property);
-    MasterClient.execute(instance, new ClientExec<MasterClientService.Iface>() {
-      @Override
-      public void execute(MasterClientService.Iface client) throws Exception {
-        client.removeSystemProperty(null, credentials, property);
-      }
-    });
-  }
-  
-  public Map<String,String> getSystemConfiguration() throws AccumuloException, AccumuloSecurityException
{
-    return ServerClient.execute(instance, new ClientExecReturn<Map<String,String>,ClientService.Iface>()
{
-      @Override
-      public Map<String,String> execute(ClientService.Iface client) throws Exception
{
-        return client.getConfiguration(ConfigurationType.CURRENT);
-      }
-    });
-  }
-  
-  public Map<String,String> getSiteConfiguration() throws AccumuloException, AccumuloSecurityException
{
-    return ServerClient.execute(instance, new ClientExecReturn<Map<String,String>,ClientService.Iface>()
{
-      @Override
-      public Map<String,String> execute(ClientService.Iface client) throws Exception
{
-        return client.getConfiguration(ConfigurationType.SITE);
-      }
-    });
-  }
+  public void removeProperty(final String property) throws AccumuloException, AccumuloSecurityException;
+  
+  public Map<String,String> getSystemConfiguration() throws AccumuloException, AccumuloSecurityException;
+  
+  public Map<String,String> getSiteConfiguration() throws AccumuloException, AccumuloSecurityException;
   
   /**
    * List the currently active tablet servers participating in the accumulo instance
@@ -128,23 +65,7 @@ public class InstanceOperations {
    * @return
    */
   
-  public List<String> getTabletServers() {
-    ZooCache cache = ZooCache.getInstance(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut());
-    String path = ZooUtil.getRoot(instance) + Constants.ZTSERVERS;
-    List<String> results = new ArrayList<String>();
-    for (String candidate : cache.getChildren(path)) {
-      List<String> children = cache.getChildren(path + "/" + candidate);
-      if (children != null && children.size() > 0) {
-        List<String> copy = new ArrayList<String>(children);
-        Collections.sort(copy);
-        byte[] data = cache.get(path + "/" + candidate + "/" + copy.get(0));
-        if (data != null && !"master".equals(new String(data))) {
-          results.add(candidate);
-        }
-      }
-    }
-    return results;
-  }
+  public List<String> getTabletServers();
   
   /**
    * List the active scans on tablet server. The tablet server address should be of the form
<ip address>:<port>
@@ -155,24 +76,7 @@ public class InstanceOperations {
    * @throws AccumuloSecurityException
    */
   
-  public List<ActiveScan> getActiveScans(String tserver) throws AccumuloException,
AccumuloSecurityException {
-    List<org.apache.accumulo.core.tabletserver.thrift.ActiveScan> tas = ThriftUtil.execute(tserver,
instance.getConfiguration(),
-        new ClientExecReturn<List<org.apache.accumulo.core.tabletserver.thrift.ActiveScan>,TabletClientService.Iface>()
{
-          @Override
-          public List<org.apache.accumulo.core.tabletserver.thrift.ActiveScan> execute(Iface
client) throws Exception {
-            return client.getActiveScans(null, credentials);
-          }
-        });
-    List<ActiveScan> as = new ArrayList<ActiveScan>();
-    for (org.apache.accumulo.core.tabletserver.thrift.ActiveScan activeScan : tas) {
-      try {
-        as.add(new ActiveScan(instance, activeScan));
-      } catch (TableNotFoundException e) {
-        throw new AccumuloException(e);
-      }
-    }
-    return as;
-  }
+  public List<ActiveScan> getActiveScans(String tserver) throws AccumuloException,
AccumuloSecurityException;
   
   /**
    * Test to see if the instance can load the given class as the given type.
@@ -182,12 +86,6 @@ public class InstanceOperations {
    * @return
    * @throws AccumuloException
    */
-  public boolean testClassLoad(final String className, final String asTypeName) throws AccumuloException,
AccumuloSecurityException {
-    return ServerClient.execute(instance, new ClientExecReturn<Boolean,ClientService.Iface>()
{
-      @Override
-      public Boolean execute(ClientService.Iface client) throws Exception {
-        return client.checkClass(null, className, asTypeName);
-      }
-    });
-  }
+  public boolean testClassLoad(final String className, final String asTypeName) throws AccumuloException,
AccumuloSecurityException;
+  
 }

Copied: incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperationsImpl.java
(from r1212505, incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperations.java)
URL: http://svn.apache.org/viewvc/incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperationsImpl.java?p2=incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperationsImpl.java&p1=incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperations.java&r1=1212505&r2=1214447&rev=1214447&view=diff
==============================================================================
--- incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperations.java
(original)
+++ incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/admin/InstanceOperationsImpl.java
Wed Dec 14 20:26:32 2011
@@ -44,7 +44,7 @@ import org.apache.accumulo.core.zookeepe
 /**
  * Provides a class for administering the accumulo instance
  */
-public class InstanceOperations {
+public class InstanceOperationsImpl implements InstanceOperations {
   private Instance instance;
   private AuthInfo credentials;
   
@@ -54,24 +54,16 @@ public class InstanceOperations {
    * @param credentials
    *          the username/password for this connection
    */
-  public InstanceOperations(Instance instance, AuthInfo credentials) {
+  public InstanceOperationsImpl(Instance instance, AuthInfo credentials) {
     ArgumentChecker.notNull(instance, credentials);
     this.instance = instance;
     this.credentials = credentials;
   }
   
-  /**
-   * Sets an instance property in zookeeper. Tablet servers will pull this setting and override
the equivalent setting in accumulo-site.xml
-   * 
-   * @param property
-   *          the name of a per-table property
-   * @param value
-   *          the value to set a per-table property to
-   * @throws AccumuloException
-   *           if a general error occurs
-   * @throws AccumuloSecurityException
-   *           if the user does not have permission
+  /* (non-Javadoc)
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#setProperty(java.lang.String,
java.lang.String)
    */
+  @Override
   public void setProperty(final String property, final String value) throws AccumuloException,
AccumuloSecurityException {
     ArgumentChecker.notNull(property, value);
     MasterClient.execute(instance, new ClientExec<MasterClientService.Iface>() {
@@ -82,18 +74,10 @@ public class InstanceOperations {
     });
   }
   
-  /**
-   * Removes a instance property from zookeeper
-   * 
-   * @param tableName
-   *          the name of the table
-   * @param property
-   *          the name of a per-table property
-   * @throws AccumuloException
-   *           if a general error occurs
-   * @throws AccumuloSecurityException
-   *           if the user does not have permission
+  /* (non-Javadoc)
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#removeProperty(java.lang.String)
    */
+  @Override
   public void removeProperty(final String property) throws AccumuloException, AccumuloSecurityException
{
     ArgumentChecker.notNull(property);
     MasterClient.execute(instance, new ClientExec<MasterClientService.Iface>() {
@@ -104,6 +88,10 @@ public class InstanceOperations {
     });
   }
   
+  /* (non-Javadoc)
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#getSystemConfiguration()
+   */
+  @Override
   public Map<String,String> getSystemConfiguration() throws AccumuloException, AccumuloSecurityException
{
     return ServerClient.execute(instance, new ClientExecReturn<Map<String,String>,ClientService.Iface>()
{
       @Override
@@ -113,6 +101,10 @@ public class InstanceOperations {
     });
   }
   
+  /* (non-Javadoc)
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#getSiteConfiguration()
+   */
+  @Override
   public Map<String,String> getSiteConfiguration() throws AccumuloException, AccumuloSecurityException
{
     return ServerClient.execute(instance, new ClientExecReturn<Map<String,String>,ClientService.Iface>()
{
       @Override
@@ -122,12 +114,11 @@ public class InstanceOperations {
     });
   }
   
-  /**
-   * List the currently active tablet servers participating in the accumulo instance
-   * 
-   * @return
+  /* (non-Javadoc)
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#getTabletServers()
    */
   
+  @Override
   public List<String> getTabletServers() {
     ZooCache cache = ZooCache.getInstance(instance.getZooKeepers(), instance.getZooKeepersSessionTimeOut());
     String path = ZooUtil.getRoot(instance) + Constants.ZTSERVERS;
@@ -146,15 +137,11 @@ public class InstanceOperations {
     return results;
   }
   
-  /**
-   * List the active scans on tablet server. The tablet server address should be of the form
<ip address>:<port>
-   * 
-   * @param tserver
-   * @return
-   * @throws AccumuloException
-   * @throws AccumuloSecurityException
+  /* (non-Javadoc)
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#getActiveScans(java.lang.String)
    */
   
+  @Override
   public List<ActiveScan> getActiveScans(String tserver) throws AccumuloException,
AccumuloSecurityException {
     List<org.apache.accumulo.core.tabletserver.thrift.ActiveScan> tas = ThriftUtil.execute(tserver,
instance.getConfiguration(),
         new ClientExecReturn<List<org.apache.accumulo.core.tabletserver.thrift.ActiveScan>,TabletClientService.Iface>()
{
@@ -174,14 +161,10 @@ public class InstanceOperations {
     return as;
   }
   
-  /**
-   * Test to see if the instance can load the given class as the given type.
-   * 
-   * @param className
-   * @param asTypeName
-   * @return
-   * @throws AccumuloException
+  /* (non-Javadoc)
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#testClassLoad(java.lang.String,
java.lang.String)
    */
+  @Override
   public boolean testClassLoad(final String className, final String asTypeName) throws AccumuloException,
AccumuloSecurityException {
     return ServerClient.execute(instance, new ClientExecReturn<Boolean,ClientService.Iface>()
{
       @Override

Modified: incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/impl/ConnectorImpl.java
URL: http://svn.apache.org/viewvc/incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/impl/ConnectorImpl.java?rev=1214447&r1=1214446&r2=1214447&view=diff
==============================================================================
--- incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/impl/ConnectorImpl.java
(original)
+++ incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/impl/ConnectorImpl.java
Wed Dec 14 20:26:32 2011
@@ -30,6 +30,7 @@ import org.apache.accumulo.core.client.S
 import org.apache.accumulo.core.client.TableNotFoundException;
 import org.apache.accumulo.core.client.TableOfflineException;
 import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.core.client.admin.InstanceOperationsImpl;
 import org.apache.accumulo.core.client.admin.SecurityOperations;
 import org.apache.accumulo.core.client.admin.SecurityOperationsImpl;
 import org.apache.accumulo.core.client.admin.TableOperations;
@@ -165,7 +166,7 @@ public class ConnectorImpl extends Conne
   @Override
   public synchronized InstanceOperations instanceOperations() {
     if (instanceops == null)
-      instanceops = new InstanceOperations(instance, credentials);
+      instanceops = new InstanceOperationsImpl(instance, credentials);
     
     return instanceops;
   }

Modified: incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockAccumulo.java
URL: http://svn.apache.org/viewvc/incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockAccumulo.java?rev=1214447&r1=1214446&r2=1214447&view=diff
==============================================================================
--- incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockAccumulo.java
(original)
+++ incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockAccumulo.java
Wed Dec 14 20:26:32 2011
@@ -47,6 +47,10 @@ public class MockAccumulo {
     systemProperties.put(key, value);
   }
   
+  String removeProperty(String key) {
+    return systemProperties.remove(key);
+  }
+  
   void createTable(String user, String table) {
     createTable(user, table, true, TimeType.MILLIS);
   }

Modified: incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockConnector.java
URL: http://svn.apache.org/viewvc/incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockConnector.java?rev=1214447&r1=1214446&r2=1214447&view=diff
==============================================================================
--- incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockConnector.java
(original)
+++ incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockConnector.java
Wed Dec 14 20:26:32 2011
@@ -95,7 +95,7 @@ public class MockConnector extends Conne
   
   @Override
   public InstanceOperations instanceOperations() {
-    return null;
+    return new MockInstanceOperations(acu);
   }
   
 }

Added: incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockInstanceOperations.java
URL: http://svn.apache.org/viewvc/incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockInstanceOperations.java?rev=1214447&view=auto
==============================================================================
--- incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockInstanceOperations.java
(added)
+++ incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockInstanceOperations.java
Wed Dec 14 20:26:32 2011
@@ -0,0 +1,117 @@
+/**
+ * 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.accumulo.core.client.mock;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.admin.ActiveScan;
+import org.apache.accumulo.core.client.admin.InstanceOperations;
+import org.apache.accumulo.start.classloader.AccumuloClassLoader;
+
+/**
+ * 
+ */
+public class MockInstanceOperations implements InstanceOperations {
+  MockAccumulo acu;
+  
+  /**
+   * @param acu
+   */
+  public MockInstanceOperations(MockAccumulo acu) {
+    this.acu = acu;
+  }
+  
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#setProperty(java.lang.String,
java.lang.String)
+   */
+  @Override
+  public void setProperty(String property, String value) throws AccumuloException, AccumuloSecurityException
{
+    acu.setProperty(property, value);
+  }
+  
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#removeProperty(java.lang.String)
+   */
+  @Override
+  public void removeProperty(String property) throws AccumuloException, AccumuloSecurityException
{
+    acu.removeProperty(property);
+  }
+  
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#getSystemConfiguration()
+   */
+  @Override
+  public Map<String,String> getSystemConfiguration() throws AccumuloException, AccumuloSecurityException
{
+    return acu.systemProperties;
+  }
+  
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#getSiteConfiguration()
+   */
+  @Override
+  public Map<String,String> getSiteConfiguration() throws AccumuloException, AccumuloSecurityException
{
+    return acu.systemProperties;
+  }
+  
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#getTabletServers()
+   */
+  @Override
+  public List<String> getTabletServers() {
+    return new ArrayList<String>();
+  }
+  
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#getActiveScans(java.lang.String)
+   */
+  @Override
+  public List<ActiveScan> getActiveScans(String tserver) throws AccumuloException,
AccumuloSecurityException {
+    return new ArrayList<ActiveScan>();
+  }
+  
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.accumulo.core.client.admin.InstanceOperations#testClassLoad(java.lang.String,
java.lang.String)
+   */
+  @Override
+  public boolean testClassLoad(String className, String asTypeName) throws AccumuloException,
AccumuloSecurityException {
+    try {
+      AccumuloClassLoader.loadClass(className, Class.forName(asTypeName));
+    } catch (ClassNotFoundException e) {
+      e.printStackTrace();
+      return false;
+    }
+    return true;
+  }
+}

Propchange: incubator/accumulo/branches/1.4/src/core/src/main/java/org/apache/accumulo/core/client/mock/MockInstanceOperations.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message