Return-Path: X-Original-To: apmail-helix-commits-archive@minotaur.apache.org Delivered-To: apmail-helix-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 09D8FFE1D for ; Tue, 7 May 2013 03:13:26 +0000 (UTC) Received: (qmail 79177 invoked by uid 500); 7 May 2013 03:13:25 -0000 Delivered-To: apmail-helix-commits-archive@helix.apache.org Received: (qmail 79146 invoked by uid 500); 7 May 2013 03:13:25 -0000 Mailing-List: contact commits-help@helix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@helix.apache.org Delivered-To: mailing list commits@helix.apache.org Received: (qmail 79128 invoked by uid 99); 7 May 2013 03:13:25 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 May 2013 03:13:25 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 May 2013 03:13:22 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 3E8DD2388C29; Tue, 7 May 2013 03:12:05 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1479756 [27/39] - in /incubator/helix/site-content: ./ apidocs/reference/org/apache/helix/ apidocs/reference/org/apache/helix/agent/ apidocs/reference/org/apache/helix/manager/zk/ apidocs/reference/org/apache/helix/messaging/handling/ apid... Date: Tue, 07 May 2013 03:11:00 -0000 To: commits@helix.incubator.apache.org From: kishoreg@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130507031205.3E8DD2388C29@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: incubator/helix/site-content/xref-test/org/apache/helix/ExternalCommand.html URL: http://svn.apache.org/viewvc/incubator/helix/site-content/xref-test/org/apache/helix/ExternalCommand.html?rev=1479756&view=auto ============================================================================== --- incubator/helix/site-content/xref-test/org/apache/helix/ExternalCommand.html (added) +++ incubator/helix/site-content/xref-test/org/apache/helix/ExternalCommand.html Tue May 7 03:10:53 2013 @@ -0,0 +1,413 @@ + + + + +ExternalCommand xref + + + +
+
+1   package org.apache.helix;
+2   
+3   /*
+4    * Licensed to the Apache Software Foundation (ASF) under one
+5    * or more contributor license agreements.  See the NOTICE file
+6    * distributed with this work for additional information
+7    * regarding copyright ownership.  The ASF licenses this file
+8    * to you under the Apache License, Version 2.0 (the
+9    * "License"); you may not use this file except in compliance
+10   * with the License.  You may obtain a copy of the License at
+11   *
+12   *   http://www.apache.org/licenses/LICENSE-2.0
+13   *
+14   * Unless required by applicable law or agreed to in writing,
+15   * software distributed under the License is distributed on an
+16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+17   * KIND, either express or implied.  See the License for the
+18   * specific language governing permissions and limitations
+19   * under the License.
+20   */
+21  
+22  import java.io.BufferedInputStream;
+23  import java.io.ByteArrayOutputStream;
+24  import java.io.File;
+25  import java.io.IOException;
+26  import java.io.InputStream;
+27  import java.io.UnsupportedEncodingException;
+28  import java.util.ArrayList;
+29  import java.util.Arrays;
+30  import java.util.List;
+31  import java.util.Map;
+32  import java.util.concurrent.TimeoutException;
+33  
+34  import org.apache.log4j.Logger;
+35  
+36  public class ExternalCommand
+37  {
+38    public static final String MODULE = ExternalCommand.class.getName();
+39    public static final Logger LOG = Logger.getLogger(MODULE);
+40  
+41    private final ProcessBuilder _processBuilder;
+42  
+43    private Process _process;
+44    private InputReader _out;
+45    private InputReader _err;
+46  
+47    private static class InputReader extends Thread
+48    {
+49      private static final int BUFFER_SIZE = 2048;
+50  
+51      private final InputStream _in;
+52      private final ByteArrayOutputStream _out;
+53      private boolean _running = false;
+54  
+55      InputReader(InputStream in)
+56      {
+57        _in = in;
+58        _out = new ByteArrayOutputStream();
+59      }
+60  
+61      @Override
+62      public void run()
+63      {
+64        _running = true;
+65  
+66        byte[] buf = new byte[BUFFER_SIZE];
+67        int n = 0;
+68        try
+69        {
+70          while((n = _in.read(buf)) != -1)
+71            _out.write(buf, 0, n);
+72        }
+73        catch(IOException e)
+74        {
+75          LOG.error("error while reading external command", e);
+76        }
+77  
+78        _running = false;
+79      }
+80  
+81      public byte[] getOutput()
+82      {
+83        if(_running)
+84          throw new IllegalStateException("wait for process to be completed");
+85  
+86        return _out.toByteArray();
+87      }
+88    }
+89    /**
+90  * Constructor */
+91    public ExternalCommand(ProcessBuilder processBuilder)
+92    {
+93      _processBuilder = processBuilder;
+94    }
+95  
+96    /**
+97  * After creating the command, you have to start it...
+98  *
+99  * @throws IOException
+100 */
+101   public void start() throws IOException
+102   {
+103     _process = _processBuilder.start();
+104     _out = new InputReader(new BufferedInputStream(_process.getInputStream()));
+105     _err = new InputReader(new BufferedInputStream(_process.getErrorStream()));
+106 
+107     _out.start();
+108     _err.start();
+109   }
+110 
+111   /**
+112 * @see ProcessBuilder
+113 */
+114   public Map<String, String> getEnvironment()
+115   {
+116     return _processBuilder.environment();
+117   }
+118 
+119   /**
+120 * @see ProcessBuilder
+121 */
+122   public File getWorkingDirectory()
+123   {
+124     return _processBuilder.directory();
+125   }
+126 
+127   /**
+128 * @see ProcessBuilder
+129 */
+130   public void setWorkingDirectory(File directory)
+131   {
+132     _processBuilder.directory(directory);
+133   }
+134 
+135   /**
+136 * @see ProcessBuilder
+137 */
+138   public boolean getRedirectErrorStream()
+139   {
+140     return _processBuilder.redirectErrorStream();
+141   }
+142 
+143   /**
+144 * @see ProcessBuilder
+145 */
+146   public void setRedirectErrorStream(boolean redirectErrorStream)
+147   {
+148     _processBuilder.redirectErrorStream(redirectErrorStream);
+149   }
+150 
+151   public byte[] getOutput() throws InterruptedException
+152   {
+153     waitFor();
+154     return _out.getOutput();
+155   }
+156 
+157   public byte[] getError() throws InterruptedException
+158   {
+159     waitFor();
+160     return _err.getOutput();
+161   }
+162 
+163   /**
+164 * Returns the output as a string.
+165 *
+166 * @param encoding
+167 * @return encoded string
+168 * @throws InterruptedException
+169 * @throws UnsupportedEncodingException
+170 */
+171   public String getStringOutput(String encoding) throws InterruptedException,
+172                                                         UnsupportedEncodingException
+173   {
+174     return new String(getOutput(), encoding);
+175   }
+176 
+177   /**
+178 * Returns the output as a string. Uses encoding "UTF-8".
+179 *
+180 * @return utf8 encoded string
+181 * @throws InterruptedException
+182 */
+183   public String getStringOutput() throws InterruptedException
+184   {
+185     try
+186     {
+187       return getStringOutput("UTF-8");
+188     }
+189     catch(UnsupportedEncodingException e)
+190     {
+191       // should not happen
+192       throw new RuntimeException(e);
+193     }
+194   }
+195 
+196   /**
+197 * Returns the error as a string.
+198 *
+199 * @param encoding
+200 * @return error as string
+201 * @throws InterruptedException
+202 * @throws UnsupportedEncodingException
+203 */
+204   public String getStringError(String encoding) throws InterruptedException,
+205                                                        UnsupportedEncodingException
+206   {
+207     return new String(getError(), encoding);
+208   }
+209 
+210   /**
+211 * Returns the error as a string. Uses encoding "UTF-8".
+212 *
+213 * @return error as string
+214 * @throws InterruptedException
+215 */
+216   public String getStringError() throws InterruptedException
+217   {
+218     try
+219     {
+220       return getStringError("UTF-8");
+221     }
+222     catch(UnsupportedEncodingException e)
+223     {
+224       // should not happen
+225       throw new RuntimeException(e);
+226     }
+227   }
+228 
+229   /**
+230 * Properly waits until everything is complete: joins on the thread that
+231 * reads the output, joins on the thread that reads the error and finally
+232 * wait for the process to be finished.
+233 * @return the status code of the process.
+234 *
+235 * @throws InterruptedException
+236 */
+237   public int waitFor() throws InterruptedException
+238   {
+239     if(_process == null)
+240       throw new IllegalStateException("you must call start first");
+241 
+242     _out.join();
+243     _err.join();
+244     return _process.waitFor();
+245   }
+246 
+247   /**
+248 * Properly waits until everything is complete: joins on the thread that
+249 * reads the output, joins on the thread that reads the error and finally
+250 * wait for the process to be finished.
+251 * If the process has not completed before the timeout, throws a
+252 * {@link TimeoutException}
+253 * @return the status code of the process.
+254 *
+255 * @throws TimeoutException
+256 * @throws InterruptedException
+257 */
+258   public int waitFor(long timeout) throws InterruptedException, TimeoutException
+259   {
+260     if(_process == null)
+261       throw new IllegalStateException("you must call start first");
+262 
+263 //    Chronos c = new Chronos();
+264     _out.join(timeout);
+265 //    timeout -= c.tick();
+266     if (timeout <= 0)
+267       throw new TimeoutException("Wait timed out");
+268     _err.join(timeout);
+269 //    timeout -= c.tick();
+270     if (timeout <= 0)
+271       throw new TimeoutException("Wait timed out");
+272 
+273     // there is no timeout in this API, not much we can do here
+274     // waiting on the other two threads should give us some safety
+275     return _process.waitFor();
+276   }
+277 
+278   public int exitValue()
+279   {
+280     if(_process == null)
+281       throw new IllegalStateException("you must call start first");
+282 
+283     return _process.exitValue();
+284   }
+285 
+286   public void destroy()
+287   {
+288     if(_process == null)
+289       throw new IllegalStateException("you must call start first");
+290 
+291     _process.destroy();
+292   }
+293 
+294   /**
+295 * Creates an external process from the command. It is not started and you have to call
+296 * start on it!
+297 *
+298 * @param commands the command to execute
+299 * @return the process */
+300   public static ExternalCommand create(String... commands)
+301   {
+302     ExternalCommand ec = new ExternalCommand(new ProcessBuilder(commands));
+303     return ec;
+304   }
+305 
+306   /**
+307 * Creates an external process from the command. It is not started and you have to call
+308 * start on it!
+309 *
+310 * @param commands the command to execute
+311 * @return the process */
+312   public static ExternalCommand create(List<String> commands)
+313   {
+314     ExternalCommand ec = new ExternalCommand(new ProcessBuilder(commands));
+315     return ec;
+316   }
+317 
+318   /**
+319 * Creates an external process from the command. The command is executed.
+320 *
+321 * @param commands the commands to execute
+322 * @return the process
+323 * @throws IOException if there is an error */
+324   public static ExternalCommand start(String... commands) throws IOException
+325   {
+326     ExternalCommand ec = new ExternalCommand(new ProcessBuilder(commands));
+327     ec.start();
+328     return ec;
+329   }
+330 
+331   /**
+332 * Executes the external command in the given working directory and waits for it to be
+333 * finished.
+334 *
+335 * @param workingDirectory the root directory from where to run the command
+336 * @param command the command to execute (should be relative to the working directory
+337 * @param args the arguments to the command
+338 * @return the process */
+339   public static ExternalCommand execute(File workingDirectory,
+340                                         String command,
+341                                         String... args)
+342       throws IOException, InterruptedException
+343   {
+344     try
+345     {
+346       return executeWithTimeout(workingDirectory, command, 0, args);
+347     }
+348     catch (TimeoutException e)
+349     {
+350       // Can't happen!
+351       throw new IllegalStateException(MODULE + ".execute: Unexpected timeout occurred!");
+352     }
+353   }
+354 
+355 /**
+356 * Executes the external command in the given working directory and waits (until timeout
+357 * is elapsed) for it to be finished.
+358 *
+359 * @param workingDirectory
+360 * the root directory from where to run the command
+361 * @param command
+362 * the command to execute (should be relative to the working directory
+363 * @param timeout
+364 * the maximum amount of time to wait for this external command (in ms). If
+365 * this value is less than or equal to 0, timeout is ignored
+366 * @param args
+367 * the arguments to the command
+368 * @return the process
+369 */
+370   public static ExternalCommand executeWithTimeout(File workingDirectory,
+371                                                    String command,
+372                                                    long timeout,
+373                                                    String... args)
+374       throws IOException, InterruptedException, TimeoutException
+375   {
+376     List<String> arguments = new ArrayList<String>(args.length + 1);
+377 
+378     arguments.add(new File(workingDirectory, command).getAbsolutePath());
+379     arguments.addAll(Arrays.asList(args));
+380 
+381     ExternalCommand cmd = ExternalCommand.create(arguments);
+382 
+383     cmd.setWorkingDirectory(workingDirectory);
+384 
+385     cmd.setRedirectErrorStream(true);
+386 
+387     cmd.start();
+388 
+389     /* Use timeout if it is a valid value! */
+390     if (timeout <= 0)
+391       cmd.waitFor();
+392     else
+393       cmd.waitFor(timeout);
+394 
+395     if (LOG.isDebugEnabled())
+396       LOG.debug(cmd.getStringOutput());
+397 
+398     return cmd;
+399   }
+400 }
+
+
+ Added: incubator/helix/site-content/xref-test/org/apache/helix/TestZkBasis.html URL: http://svn.apache.org/viewvc/incubator/helix/site-content/xref-test/org/apache/helix/TestZkBasis.html?rev=1479756&view=auto ============================================================================== --- incubator/helix/site-content/xref-test/org/apache/helix/TestZkBasis.html (added) +++ incubator/helix/site-content/xref-test/org/apache/helix/TestZkBasis.html Tue May 7 03:10:53 2013 @@ -0,0 +1,193 @@ + + + + +TestZkBasis xref + + + +
+
+1   package org.apache.helix;
+2   
+3   /*
+4    * Licensed to the Apache Software Foundation (ASF) under one
+5    * or more contributor license agreements.  See the NOTICE file
+6    * distributed with this work for additional information
+7    * regarding copyright ownership.  The ASF licenses this file
+8    * to you under the Apache License, Version 2.0 (the
+9    * "License"); you may not use this file except in compliance
+10   * with the License.  You may obtain a copy of the License at
+11   *
+12   *   http://www.apache.org/licenses/LICENSE-2.0
+13   *
+14   * Unless required by applicable law or agreed to in writing,
+15   * software distributed under the License is distributed on an
+16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+17   * KIND, either express or implied.  See the License for the
+18   * specific language governing permissions and limitations
+19   * under the License.
+20   */
+21  
+22  import org.I0Itec.zkclient.IZkChildListener;
+23  import org.I0Itec.zkclient.IZkDataListener;
+24  import org.apache.helix.TestHelper;
+25  import org.apache.helix.ZkTestHelper;
+26  import org.apache.helix.ZkUnitTestBase;
+27  import org.apache.helix.manager.zk.ZNRecordSerializer;
+28  import org.apache.helix.manager.zk.ZkClient;
+29  import org.testng.Assert;
+30  import org.testng.annotations.Test;
+31  
+32  import java.util.Collections;
+33  import java.util.List;
+34  import java.util.Map;
+35  import java.util.Set;
+36  import java.util.concurrent.CountDownLatch;
+37  import java.util.concurrent.TimeUnit;
+38  
+39  /**
+40   * test zookeeper basis
+41   */
+42  public class TestZkBasis extends ZkUnitTestBase {
+43      class ZkListener implements  IZkDataListener, IZkChildListener {
+44          String _parentPath = null;
+45          String _dataDeletePath = null;
+46          List<String> _currentChilds = Collections.emptyList();  // make sure it's set to null in #handleChildChange()
+47  
+48          CountDownLatch _childChangeCountDown = new CountDownLatch(1);
+49          CountDownLatch _dataDeleteCountDown = new CountDownLatch(1);
+50  
+51          @Override
+52          public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
+53              _parentPath = parentPath;
+54              _currentChilds = currentChilds;
+55              _childChangeCountDown.countDown();
+56          }
+57  
+58          @Override
+59          public void handleDataChange(String dataPath, Object data) throws Exception {
+60              //To change body of implemented methods use File | Settings | File Templates.
+61          }
+62  
+63          @Override
+64          public void handleDataDeleted(String dataPath) throws Exception {
+65              _dataDeletePath = dataPath;
+66              _dataDeleteCountDown.countDown();
+67          }
+68      }
+69      /**
+70       * test zk watchers are renewed automatically after session expiry
+71       *
+72       * zookeeper-client side keeps all registered watchers see ZooKeeper.WatchRegistration.register()
+73       * after session expiry, all watchers are renewed
+74       * if a path that has watches on it has been removed during session expiry,
+75       * the watchers on that path will still get callbacks after session renewal, especially:
+76       *  a data-watch will get data-deleted callback
+77       *  a child-watch will get a child-change callback with current-child-list = null
+78       *
+79       * this can be used for cleanup watchers on the zookeeper-client side
+80       */
+81      @Test
+82      public void testWatchRenew() throws Exception {
+83  
+84          String className = TestHelper.getTestClassName();
+85          String methodName = TestHelper.getTestMethodName();
+86          String testName = className + "_" + methodName;
+87  
+88          final ZkClient client = new ZkClient(ZK_ADDR, ZkClient.DEFAULT_SESSION_TIMEOUT,
+89                  ZkClient.DEFAULT_CONNECTION_TIMEOUT, new ZNRecordSerializer());
+90          // make sure "/testName/test" doesn't exist
+91          final String path = "/" + testName + "/test";
+92          client.delete(path);
+93  
+94          ZkListener listener = new ZkListener();
+95          client.subscribeDataChanges(path, listener);
+96          client.subscribeChildChanges(path, listener);
+97  
+98          ZkTestHelper.expireSession(client);
+99  
+100         boolean succeed = listener._childChangeCountDown.await(10, TimeUnit.SECONDS);
+101         Assert.assertTrue(succeed, "fail to wait on child-change count-down in 10 seconds after session-expiry");
+102         Assert.assertEquals(listener._parentPath, path, "fail to get child-change callback after session-expiry");
+103         Assert.assertNull(listener._currentChilds, "fail to get child-change callback with currentChilds=null after session expiry");
+104 
+105         succeed = listener._dataDeleteCountDown.await(10, TimeUnit.SECONDS);
+106         Assert.assertTrue(succeed, "fail to wait on data-delete count-down in 10 seconds after session-expiry");
+107         Assert.assertEquals(listener._dataDeletePath, path, "fail to get data-delete callback after session-expiry");
+108 
+109         client.close();
+110     }
+111 
+112     /**
+113      * after calling zkclient#unsubscribeXXXListener()
+114      * an already registered watch will not be removed from ZooKeeper#watchManager#XXXWatches immediately.
+115      * the watch will get removed on the following conditions:
+116      *  1) there is a set/delete on the listening path via the zkclient
+117      *  2) session expiry on the zkclient (i.e. the watch will not be renewed after session expiry)
+118      *
+119      * @throws Exception
+120      */
+121     @Test
+122     public void testWatchRemove() throws Exception {
+123         String className = TestHelper.getTestClassName();
+124         String methodName = TestHelper.getTestMethodName();
+125         String testName = className + "_" + methodName;
+126 
+127         final ZkClient client = new ZkClient(ZK_ADDR, ZkClient.DEFAULT_SESSION_TIMEOUT,
+128                 ZkClient.DEFAULT_CONNECTION_TIMEOUT, new ZNRecordSerializer());
+129         // make sure "/testName/test" doesn't exist
+130         final String path = "/" + testName + "/test";
+131         client.createPersistent(path, true);
+132 
+133         ZkListener listener = new ZkListener();
+134         client.subscribeDataChanges(path, listener);
+135         client.subscribeChildChanges(path, listener);
+136 
+137         // listener should be in both ZkClient#_dataListener and ZkClient#_childListener set
+138         Map<String, Set<IZkDataListener>> dataListenerMap = ZkTestHelper.getZkDataListener(client);
+139         Assert.assertEquals(dataListenerMap.size(), 1, "ZkClient#_dataListener should have 1 listener");
+140         Set<IZkDataListener> dataListenerSet = dataListenerMap.get(path);
+141         Assert.assertNotNull(dataListenerSet, "ZkClient#_dataListener should have 1 listener on path: " + path);
+142         Assert.assertEquals(dataListenerSet.size(), 1, "ZkClient#_dataListener should have 1 listener on path: " + path);
+143 
+144 
+145         Map<String, Set<IZkChildListener>> childListenerMap = ZkTestHelper.getZkChildListener(client);
+146         Assert.assertEquals(childListenerMap.size(), 1, "ZkClient#_childListener should have 1 listener");
+147         Set<IZkChildListener> childListenerSet = childListenerMap.get(path);
+148         Assert.assertNotNull(childListenerSet, "ZkClient#_childListener should have 1 listener on path: " + path);
+149         Assert.assertEquals(childListenerSet.size(), 1, "ZkClient#_childListener should have 1 listener on path: " + path);
+150 
+151         // watch should be in ZooKeeper#watchManager#XXXWatches
+152         Map<String, List<String>> watchMap = ZkTestHelper.getZkWatch(client);
+153         // System.out.println("watchMap1: " + watchMap);
+154         List<String> dataWatch = watchMap.get("dataWatches");
+155         Assert.assertNotNull(dataWatch, "ZooKeeper#watchManager#dataWatches should have 1 data watch on path: " + path);
+156         Assert.assertEquals(dataWatch.size(), 1, "ZooKeeper#watchManager#dataWatches should have 1 data watch on path: " + path);
+157         Assert.assertEquals(dataWatch.get(0), path, "ZooKeeper#watchManager#dataWatches should have 1 data watch on path: " + path);
+158 
+159         List<String> childWatch = watchMap.get("childWatches");
+160         Assert.assertNotNull(childWatch, "ZooKeeper#watchManager#childWatches should have 1 child watch on path: " + path);
+161         Assert.assertEquals(childWatch.size(), 1, "ZooKeeper#watchManager#childWatches should have 1 child watch on path: " + path);
+162         Assert.assertEquals(childWatch.get(0), path, "ZooKeeper#watchManager#childWatches should have 1 child watch on path: " + path);
+163 
+164 
+165         client.unsubscribeDataChanges(path, listener);
+166         client.unsubscribeChildChanges(path, listener);
+167         // System.out.println("watchMap2: " + watchMap);
+168         ZkTestHelper.expireSession(client);
+169 
+170         // after session expiry, those watches should be removed
+171         watchMap = ZkTestHelper.getZkWatch(client);
+172         // System.out.println("watchMap3: " + watchMap);
+173         dataWatch = watchMap.get("dataWatches");
+174         Assert.assertTrue(dataWatch.isEmpty(), "ZooKeeper#watchManager#dataWatches should be empty");
+175         childWatch = watchMap.get("childWatches");
+176         Assert.assertTrue(childWatch.isEmpty(), "ZooKeeper#watchManager#childWatches should be empty");
+177 
+178         client.close();
+179     }
+180 }
+
+
+