You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tubemq.apache.org by yu...@apache.org on 2021/03/01 09:07:43 UTC

[incubator-tubemq] 29/29: [TUBEMQ-565]Replace simple scripts and code implementation (#432)

This is an automated email from the ASF dual-hosted git repository.

yuanbo pushed a commit to branch TUBEMQ-469
in repository https://gitbox.apache.org/repos/asf/incubator-tubemq.git

commit 2045feeba797c9fed827aa1c458157ab20e3215e
Author: gosonzhang <46...@qq.com>
AuthorDate: Mon Mar 1 14:22:18 2021 +0800

    [TUBEMQ-565]Replace simple scripts and code implementation (#432)
    
    Co-authored-by: gosonzhang <go...@tencent.com>
---
 LICENSE                                            |  20 +-
 NOTICE                                             |  17 --
 bin/broker.sh                                      | 151 --------------
 bin/master.sh                                      | 154 --------------
 bin/{tubemq => tubemq.sh}                          |   0
 pom.xml                                            |  10 +-
 tubemq-core/pom.xml                                |   4 +
 .../tubemq/corebase/utils/ConcurrentHashSet.java   |  59 ++++--
 .../apache/tubemq/corebase/utils/MapBackedSet.java |  76 -------
 .../apache/tubemq/corebase/utils/TStringUtils.java | 222 +--------------------
 .../corebase/utils/ConcurrentHashSetTest.java      |  49 +++++
 tubemq-docker/tubemq-all/tubemq.sh                 |   8 +-
 .../web/handler/WebAdminGroupCtrlHandler.java      |   2 -
 .../master/web/handler/WebOtherInfoHandler.java    |   3 +-
 14 files changed, 118 insertions(+), 657 deletions(-)

diff --git a/LICENSE b/LICENSE
index c6bfcd6..a883d4c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -340,31 +340,15 @@
  Source  : hbase 0.94.27 (Please note that the software have been modified.)
  License : https://github.com/apache/hbase/blob/rel/0.94.27/LICENSE.txt
 
-1.3.2 tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/MapBackedSet.java
-      tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/ConcurrentHashSet.java
- Source  : mina 2.0.12
- License : https://github.com/apache/mina/blob/2.0.12/LICENSE.txt
-
-1.3.3 bin/broker.sh
-      bin/master.sh
- Source  : Metamorphosis  metamorphosis-all-1.4.4 (Please note that the software have been modified.)
- License : https://github.com/killme2008/Metamorphosis/blob/metamorphosis-all-1.4.4/COPYING.txt
-
-1.3.4 tubemq-core/src/main/java/org/apache/tubemq/corerpc/netty/ByteBufferInputStream.java
+1.3.2 tubemq-core/src/main/java/org/apache/tubemq/corerpc/netty/ByteBufferInputStream.java
       tubemq-core/src/main/java/org/apache/tubemq/corerpc/netty/ByteBufferOutputStream.java
  Source  : Apache Avro 1.7.6
  License : https://github.com/apache/avro/blob/release-1.7.6/LICENSE.txt
 
-1.3.5 tubemq-client-twins/tubemq-client-cpp/src/future.h
+1.3.3 tubemq-client-twins/tubemq-client-cpp/src/future.h
  Source  : Apache Pulsar
  License : https://github.com/apache/pulsar/blob/master/LICENSE
 
-1.3.6 tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/TStringUtils.java
- Source  : commons-lang (Please note that the software have been modified.)
-           https://github.com/apache/commons-lang/blob/LANG_2_X/src/
-                 main/java/org/apache/commons/lang/StringUtils.java
- License : https://github.com/apache/commons-lang/blob/LANG_2_X/LICENSE.txt
-
 ----
 
 =========
diff --git a/NOTICE b/NOTICE
index 85f6960..e451d38 100644
--- a/NOTICE
+++ b/NOTICE
@@ -59,14 +59,6 @@ Apache HBase includes the following in its NOTICE file:
 | 'hbase-shaded-hbase-shaded-testing-util/src/main/resources/org/apache/hadoop/hbase/shaded/org/mortbay/jetty/webapp/webdefault.xml'
 
 
-Apache MINA includes the following in its NOTICE file:
-| Apache MINA
-| Copyright 2007-2016 The Apache Software Foundation.
-| 
-| This product includes software developed at
-| The Apache Software Foundation (http://www.apache.org/).
-
-
 Apache Avro includes the following in its NOTICE file:
 | Apache Avro
 | Copyright 2010-2019 The Apache Software Foundation
@@ -143,15 +135,6 @@ Apache Avro includes the following in its NOTICE file:
 | | 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.
 
-
-Apache Commons Lang includes the following in its NOTICE file:
-| Apache Commons Lang
-| Copyright 2001-2011 The Apache Software Foundation
-|
-| This product includes software developed by
-| The Apache Software Foundation (http://www.apache.org/).
-
-
 Apache Pulsar includes the following in its NOTICE file:
 | Apache Pulsar
 | Copyright 2017-2019 The Apache Software Foundation
diff --git a/bin/broker.sh b/bin/broker.sh
deleted file mode 100644
index 51684e5..0000000
--- a/bin/broker.sh
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/bin/bash
-
-#
-# 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.
-#
-
-#project directory
-if [ -z "$BASE_DIR" ] ; then
-  PRG="$0"
-
-  # need this for relative symlinks
-  while [ -h "$PRG" ] ; do
-    ls=`ls -ld "$PRG"`
-    link=`expr "$ls" : '.*-> \(.*\)$'`
-    if expr "$link" : '/.*' > /dev/null; then
-      PRG="$link"
-    else
-      PRG="`dirname "$PRG"`/$link"
-    fi
-  done
-  BASE_DIR=`dirname "$PRG"`/..
-
-  # make it fully qualified
-  BASE_DIR=`cd "$BASE_DIR" && pwd`
-  #echo "TubeMQ broker is at $BASE_DIR"
-fi
-
-source $BASE_DIR/bin/env.sh
-
-AS_USER=`whoami`
-LOG_DIR="$BASE_DIR/logs"
-LOG_FILE="$LOG_DIR/broker.log"
-PID_DIR="$BASE_DIR/logs"
-PID_FILE="$PID_DIR/.broker.run.pid"
-
-function running(){
-	if [ -f "$PID_FILE" ]; then
-		pid=$(cat "$PID_FILE")
-		process=`ps aux | grep " $pid "|grep "\-Dtubemq\.home=$BASE_DIR" | grep -v grep`;
-		if [ "$process" == "" ]; then
-	    		return 1;
-		else
-			return 0;
-		fi
-	else
-		return 1
-	fi
-}
-
-function start_server() {
-	if running; then
-		echo "Broker is running."
-		exit 1
-	fi
-
-    mkdir -p $PID_DIR
-    touch $LOG_FILE
-    mkdir -p $LOG_DIR
-    chown -R $AS_USER $PID_DIR
-    chown -R $AS_USER $LOG_DIR
-    
-    config_files="-f $BASE_DIR/conf/broker.ini"
-	
-	echo "Starting TubeMQ broker..."
-    
-   	echo "$JAVA $BROKER_ARGS  org.apache.tubemq.server.tools.BrokerStartup $config_files"
-    sleep 1
-    nohup $JAVA $BROKER_ARGS  org.apache.tubemq.server.tools.BrokerStartup $config_files 2>&1 >>$LOG_FILE &
-    echo $! > $PID_FILE
-    chmod 755 $PID_FILE
-}
-
-function status_server() {
-	if running; then
-		echo "Broker is running."
-		exit 0
-	else
-    echo "Broker is not running."
-		exit 1
-	fi
-}
-
-function stop_server() {
-	if ! running; then
-		echo "Broker is not running."
-		exit 1
-	fi
-	count=0
-	pid=$(cat $PID_FILE)
-	while running;
-	do
-	  let count=$count+1
-	  echo "Stopping TubeMQ Broker $count times"
-	  if [ $count -gt 10 ]; then
-	  	  echo "kill -9 $pid"
-	      kill -9 $pid
-	  else
-	      kill $pid
-	  fi
-	  sleep 8;
-	done
-	echo "Stop TubeMQ Broker successfully."
-	rm $PID_FILE
-}
-
-function help() {
-    echo "Usage: broker.sh {status|start|stop|restart}" >&2
-    echo "       status:            the status of broker server"
-    echo "       start:             start the broker server"
-    echo "       stop:              stop the broker server"
-    echo "       restart:           restart the broker server"
-}
-
-command=$1
-shift 1
-case $command in
-    status)
-        status_server $@;
-        ;;
-    start)
-        start_server $@;
-        ;;    
-    stop)
-        stop_server $@;
-        ;;
-    restart)
-        $0 stop $@
-        sleep 10
-        $0 start $@
-        ;;
-    help)
-        help;
-        ;;
-    *)
-        help;
-        exit 1;
-        ;;
-esac
diff --git a/bin/master.sh b/bin/master.sh
deleted file mode 100644
index bd311a9..0000000
--- a/bin/master.sh
+++ /dev/null
@@ -1,154 +0,0 @@
-#!/bin/bash
-
-#
-# 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.
-#
-
-#project directory
-if [ -z "$BASE_DIR" ] ; then
-  PRG="$0"
-
-  # need this for relative symlinks
-  while [ -h "$PRG" ] ; do
-    ls=`ls -ld "$PRG"`
-    link=`expr "$ls" : '.*-> \(.*\)$'`
-    if expr "$link" : '/.*' > /dev/null; then
-      PRG="$link"
-    else
-      PRG="`dirname "$PRG"`/$link"
-    fi
-  done
-  BASE_DIR=`dirname "$PRG"`/..
-
-  # make it fully qualified
-  BASE_DIR=`cd "$BASE_DIR" && pwd`
-  #echo "TubeMQ master is at $BASE_DIR"
-fi
-
-source $BASE_DIR/bin/env.sh
-
-AS_USER=`whoami`
-LOG_DIR="$BASE_DIR/logs"
-LOG_FILE="$LOG_DIR/master.log"
-PID_DIR="$BASE_DIR/logs"
-PID_FILE="$PID_DIR/.master.run.pid"
-
-function running(){
-	if [ -f "$PID_FILE" ]; then
-		pid=$(cat "$PID_FILE")
-		process=`ps aux | grep " $pid "|grep "\-Dtubemq\.home=$BASE_DIR" | grep -v grep`;
-		if [ "$process" == "" ]; then
-	    	return 1;
-		else
-			return 0;
-		fi
-	else
-		return 1
-	fi
-}
-
-function start_server() {
-	if running; then
-		echo "Master is running."
-		exit 1
-	fi
-
-    mkdir -p $PID_DIR
-    touch $LOG_FILE
-    mkdir -p $LOG_DIR
-    chown -R $AS_USER $PID_DIR
-    chown -R $AS_USER $LOG_DIR
-    
-    config_files="-f $BASE_DIR/conf/master.ini"
-    
-	echo "Starting Master server..."
-  pushd .
-    
-    cd $BASE_DIR
-   	echo "$JAVA $MASTER_ARGS  org.apache.tubemq.server.tools.MasterStartup $config_files"
-    sleep 1
-    nohup $JAVA $MASTER_ARGS  org.apache.tubemq.server.tools.MasterStartup $config_files 2>&1 >>$LOG_FILE &
-    echo $! > $PID_FILE
-    chmod 755 $PID_FILE
-  
-  popd
-}
-
-function status_server() {
-	if running; then
-		echo "Master is running."
-		exit 0
-	else
-	  echo "Master is not running."
-	  exit 1
-	fi
-}
-
-function stop_server() {
-	if ! running; then
-		echo "Master is not running."
-		exit 1
-	fi
-	count=0
-	pid=$(cat $PID_FILE)
-	while running;
-	do
-	  let count=$count+1
-	  echo "Stopping TubeMQ master $count times"
-	  if [ $count -gt 10 ]; then
-	  	  echo "kill -9 $pid"
-	      kill -9 $pid
-	  else
-	      kill $pid
-	  fi
-	  sleep 6;
-	done	
-	echo "Stop TubeMQ master successfully."
-	rm $PID_FILE
-}
-
-function help() {
-    echo "Usage: master.sh {status|start|stop|restart}" >&2
-    echo "       status:     the status of master server"
-    echo "       start:      start the master server"
-    echo "       stop:       stop the master server"
-    echo "       restart:    restart the master server"
-}
-
-command=$1
-shift 1
-case $command in
-    status)
-        status_server $@;
-        ;;
-    start)
-        start_server $@;
-        ;;    
-    stop)
-        stop_server $@;
-        ;;
-    restart)
-        $0 stop $@
-        $0 start $@
-        ;;
-    help)
-        help;
-        ;;
-    *)
-        help;
-        exit 1;
-        ;;
-esac
diff --git a/bin/tubemq b/bin/tubemq.sh
similarity index 100%
rename from bin/tubemq
rename to bin/tubemq.sh
diff --git a/pom.xml b/pom.xml
index fe34837..8bbcad6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -319,6 +319,11 @@
                 <version>1.10</version>
             </dependency>
             <dependency>
+                <groupId>commons-lang</groupId>
+                <artifactId>commons-lang</artifactId>
+                <version>2.6</version>
+            </dependency>
+            <dependency>
                 <groupId>com.sleepycat</groupId>
                 <artifactId>je</artifactId>
                 <version>${je.version}</version>
@@ -329,11 +334,6 @@
                 <version>${gson.version}</version>
             </dependency>
             <dependency>
-                <groupId>commons-lang</groupId>
-                <artifactId>commons-lang</artifactId>
-                <version>2.6</version>
-            </dependency>
-            <dependency>
                 <groupId>org.apache.httpcomponents</groupId>
                 <artifactId>httpclient</artifactId>
                 <version>4.5.2</version>
diff --git a/tubemq-core/pom.xml b/tubemq-core/pom.xml
index 21b1bf0..34a2349 100644
--- a/tubemq-core/pom.xml
+++ b/tubemq-core/pom.xml
@@ -114,6 +114,10 @@
             <artifactId>commons-codec</artifactId>
         </dependency>
         <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.googlecode.protobuf-java-format</groupId>
             <artifactId>protobuf-java-format</artifactId>
             <version>1.4</version>
diff --git a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/ConcurrentHashSet.java b/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/ConcurrentHashSet.java
index 9860d09..19173ee 100644
--- a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/ConcurrentHashSet.java
+++ b/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/ConcurrentHashSet.java
@@ -17,30 +17,63 @@
 
 package org.apache.tubemq.corebase.utils;
 
-import java.util.Collection;
+
+import java.util.AbstractSet;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * A Map-backed Set.
- *
- * Copied from <a href="http://mina.apache.org">Apache MINA Project</a>
+ * ConcurrentHashSet, construct the set collection through ConcurrentHashMap
+ *  to complete the operation management of the concurrent set
  */
-public class ConcurrentHashSet<E> extends MapBackedSet<E> {
+public class ConcurrentHashSet<E> extends AbstractSet<E> {
 
-    private static final long serialVersionUID = 8518578988740277828L;
+    private final ConcurrentHashMap<E, Long> keyValMap
+            = new ConcurrentHashMap<>();
 
     public ConcurrentHashSet() {
-        super(new ConcurrentHashMap<E, Boolean>());
+
+    }
+
+    @Override
+    public boolean add(E item) {
+        Long value =
+                keyValMap.putIfAbsent(item, System.currentTimeMillis());
+        return (value == null);
+    }
+
+    @Override
+    public boolean contains(Object item) {
+        return keyValMap.containsKey(item);
+    }
+
+    @Override
+    public boolean remove(Object item) {
+        return keyValMap.remove(item) != null;
+    }
+
+    @Override
+    public void clear() {
+        keyValMap.clear();
+    }
+
+    @Override
+    public int size() {
+        return keyValMap.size();
     }
 
-    public ConcurrentHashSet(Collection<E> c) {
-        super(new ConcurrentHashMap<E, Boolean>(), c);
+    @Override
+    public boolean isEmpty() {
+        return keyValMap.isEmpty();
     }
 
     @Override
-    public boolean add(E o) {
-        Boolean answer =
-                map.putIfAbsent(o, Boolean.TRUE);
-        return answer == null;
+    public Iterator<E> iterator() {
+        return new HashSet<>(keyValMap.keySet()).iterator();
+    }
+
+    public Long getItemAddTime(E item) {
+        return keyValMap.get(item);
     }
 }
diff --git a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/MapBackedSet.java b/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/MapBackedSet.java
deleted file mode 100644
index 554a731..0000000
--- a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/MapBackedSet.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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.tubemq.corebase.utils;
-
-import java.io.Serializable;
-import java.util.AbstractSet;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * A Map-backed Set.
- *
- * Copied from <a href="http://mina.apache.org">Apache MINA Project</a>
- */
-public class MapBackedSet<E> extends AbstractSet<E> implements Serializable {
-
-    private static final long serialVersionUID = -8347878570391674042L;
-
-    protected final ConcurrentHashMap<E, Boolean> map;
-
-    public MapBackedSet(ConcurrentHashMap<E, Boolean> map) {
-        this.map = map;
-    }
-
-    public MapBackedSet(ConcurrentHashMap<E, Boolean> map, Collection<E> c) {
-        this.map = map;
-        addAll(c);
-    }
-
-    @Override
-    public int size() {
-        return map.size();
-    }
-
-    @Override
-    public boolean contains(Object o) {
-        return map.containsKey(o);
-    }
-
-    @Override
-    public Iterator<E> iterator() {
-        return new ArrayList<>(map.keySet()).iterator();
-    }
-
-    @Override
-    public boolean add(E o) {
-        return map.put(o, Boolean.TRUE) == null;
-    }
-
-    @Override
-    public boolean remove(Object o) {
-        return map.remove(o) != null;
-    }
-
-    @Override
-    public void clear() {
-        map.clear();
-    }
-}
diff --git a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/TStringUtils.java b/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/TStringUtils.java
index b5dc005..5714b80 100644
--- a/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/TStringUtils.java
+++ b/tubemq-core/src/main/java/org/apache/tubemq/corebase/utils/TStringUtils.java
@@ -15,18 +15,13 @@
  * limitations under the License.
  */
 
-/*
- * Modified from commons-lang <a href="https://github.com/apache/commons-lang"> Project</a>
- *   file address: https://github.com/apache/commons-lang/blob/LANG_2_X/src/
- *                         main/java/org/apache/commons/lang/StringUtils.java
- */
-
 package org.apache.tubemq.corebase.utils;
 
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.codec.digest.HmacUtils;
+import org.apache.commons.lang.StringUtils;
 import org.apache.tubemq.corebase.TBaseConstants;
 import org.apache.tubemq.corebase.TokenConstants;
 
@@ -35,231 +30,28 @@ import org.apache.tubemq.corebase.TokenConstants;
  */
 public class TStringUtils {
 
-    public static final String EMPTY = "";
-
-    // Empty checks
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Checks if a String is empty ("") or null.</p>
-     *
-     * <pre>
-     * TStringUtils.isEmpty(null)      = true
-     * TStringUtils.isEmpty("")        = true
-     * TStringUtils.isEmpty(" ")       = false
-     * TStringUtils.isEmpty("bob")     = false
-     * TStringUtils.isEmpty("  bob  ") = false
-     * </pre>
-     *
-     * <p>NOTE: This method changed in Lang version 2.0.
-     * It no longer trims the String.
-     * That functionality is available in isBlank().</p>
-     *
-     * @param str  the String to check, may be null
-     * @return <code>true</code> if the String is empty or null
-     */
     public static boolean isEmpty(String str) {
-        return str == null || str.length() == 0;
+        return StringUtils.isEmpty(str);
     }
 
-    /**
-     * <p>Checks if a String is not empty ("") and not null.</p>
-     *
-     * <pre>
-     * TStringUtils.isNotEmpty(null)      = false
-     * TStringUtils.isNotEmpty("")        = false
-     * TStringUtils.isNotEmpty(" ")       = true
-     * TStringUtils.isNotEmpty("bob")     = true
-     * TStringUtils.isNotEmpty("  bob  ") = true
-     * </pre>
-     *
-     * @param str  the String to check, may be null
-     * @return <code>true</code> if the String is not empty and not null
-     */
     public static boolean isNotEmpty(String str) {
-        return !isEmpty(str);
+        return StringUtils.isNotEmpty(str);
     }
 
-    /**
-     * <p>Checks if a String is whitespace, empty ("") or null.</p>
-     *
-     * <pre>
-     * TStringUtils.isBlank(null)      = true
-     * TStringUtils.isBlank("")        = true
-     * TStringUtils.isBlank(" ")       = true
-     * TStringUtils.isBlank("bob")     = false
-     * TStringUtils.isBlank("  bob  ") = false
-     * </pre>
-     *
-     * @param str  the String to check, may be null
-     * @return <code>true</code> if the String is null, empty or whitespace
-     * @since 2.0
-     */
     public static boolean isBlank(String str) {
-        int strLen;
-        if (str == null || (strLen = str.length()) == 0) {
-            return true;
-        }
-        for (int i = 0; i < strLen; i++) {
-            if (!Character.isWhitespace(str.charAt(i))) {
-                return false;
-            }
-        }
-        return true;
+        return StringUtils.isBlank(str);
     }
 
-    /**
-     * <p>Checks if a String is not empty (""), not null and not whitespace only.</p>
-     *
-     * <pre>
-     * TStringUtils.isNotBlank(null)      = false
-     * TStringUtils.isNotBlank("")        = false
-     * TStringUtils.isNotBlank(" ")       = false
-     * TStringUtils.isNotBlank("bob")     = true
-     * TStringUtils.isNotBlank("  bob  ") = true
-     * </pre>
-     *
-     * @param str  the String to check, may be null
-     * @return <code>true</code> if the String is
-     *  not empty and not null and not whitespace
-     * @since 2.0
-     */
     public static boolean isNotBlank(String str) {
-        return !isBlank(str);
+        return StringUtils.isNotBlank(str);
     }
 
-    /**
-     * <p>Removes control characters (char &lt;= 32) from both
-     * ends of this String, handling <code>null</code> by returning
-     * <code>null</code>.</p>
-     *
-     * <p>The String is trimmed using {@link String#trim()}.
-     * Trim removes start and end characters &lt;= 32.</p>
-     *
-     * <pre>
-     * TStringUtils.trim(null)          = null
-     * TStringUtils.trim("")            = ""
-     * TStringUtils.trim("     ")       = ""
-     * TStringUtils.trim("abc")         = "abc"
-     * TStringUtils.trim("    abc    ") = "abc"
-     * </pre>
-     *
-     * @param str  the String to be trimmed, may be null
-     * @return the trimmed string, <code>null</code> if null String input
-     */
     public static String trim(String str) {
-        return str == null ? null : str.trim();
+        return StringUtils.trim(str);
     }
 
-    // Misc
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Find the Levenshtein distance between two Strings.</p>
-     *
-     * <p>This is the number of changes needed to change one String into
-     * another, where each change is a single character modification (deletion,
-     * insertion or substitution).</p>
-     *
-     * <p>The previous implementation of the Levenshtein distance algorithm
-     * was from <a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a></p>
-     *
-     * <p>Chas Emerick has written an implementation in Java, which avoids an OutOfMemoryError
-     * which can occur when my Java implementation is used with very large strings.<br>
-     * This implementation of the Levenshtein distance algorithm
-     * is from <a href="http://www.merriampark.com/ldjava.htm">http://www.merriampark.com/ldjava.htm</a></p>
-     *
-     * <pre>
-     * TStringUtils.getLevenshteinDistance(null, *)             = IllegalArgumentException
-     * TStringUtils.getLevenshteinDistance(*, null)             = IllegalArgumentException
-     * TStringUtils.getLevenshteinDistance("","")               = 0
-     * TStringUtils.getLevenshteinDistance("","a")              = 1
-     * TStringUtils.getLevenshteinDistance("aaapppp", "")       = 7
-     * TStringUtils.getLevenshteinDistance("frog", "fog")       = 1
-     * TStringUtils.getLevenshteinDistance("fly", "ant")        = 3
-     * TStringUtils.getLevenshteinDistance("elephant", "hippo") = 7
-     * TStringUtils.getLevenshteinDistance("hippo", "elephant") = 7
-     * TStringUtils.getLevenshteinDistance("hippo", "zzzzzzzz") = 8
-     * TStringUtils.getLevenshteinDistance("hello", "hallo")    = 1
-     * </pre>
-     *
-     * @param s  the first String, must not be null
-     * @param t  the second String, must not be null
-     * @return result distance
-     * @throws IllegalArgumentException if either String input <code>null</code>
-     */
     public static int getLevenshteinDistance(String s, String t) {
-        if (s == null || t == null) {
-            throw new IllegalArgumentException("Strings must not be null");
-        }
-
-        /*
-           The difference between this impl. and the previous is that, rather
-           than creating and retaining a matrix of size s.length()+1 by t.length()+1,
-           we maintain two single-dimensional arrays of length s.length()+1.  The first, d,
-           is the 'current working' distance array that maintains the newest distance cost
-           counts as we iterate through the characters of String s.  Each time we increment
-           the index of String t we are comparing, d is copied to p, the second int[].  Doing so
-           allows us to retain the previous cost counts as required by the algorithm (taking
-           the minimum of the cost count to the left, up one, and diagonally up and to the left
-           of the current cost count being calculated).  (Note that the arrays aren't really
-           copied anymore, just switched...this is clearly much better than cloning an array
-           or doing a System.arraycopy() each time  through the outer loop.)
-           Effectively, the difference between the two implementations is this one does not
-           cause an out of memory condition when calculating the LD over two very large strings.
-         */
-
-        int n = s.length(); // length of s
-        int m = t.length(); // length of t
-
-        if (n == 0) {
-            return m;
-        } else if (m == 0) {
-            return n;
-        }
-
-        if (n > m) {
-            // swap the input strings to consume less memory
-            String tmp = s;
-            s = t;
-            t = tmp;
-            n = m;
-            m = t.length();
-        }
-
-        int p[] = new int[n + 1]; //'previous' cost array, horizontally
-        int d[] = new int[n + 1]; // cost array, horizontally
-        int swap[]; //placeholder to assist in swapping p and d
-
-        // indexes into strings s and t
-        int i; // iterates through s
-        int j; // iterates through t
-
-        char chkChar; // jth character of t
-
-        int cost; // cost
-
-        for (i = 0; i <= n; i++) {
-            p[i] = i;
-        }
-
-        for (j = 1; j <= m; j++) {
-            chkChar = t.charAt(j - 1);
-            d[0] = j;
-
-            for (i = 1; i <= n; i++) {
-                cost = s.charAt(i - 1) == chkChar ? 0 : 1;
-                // minimum of cell to the left+1, to the top+1, diagonally left and up +cost
-                d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1),  p[i - 1] + cost);
-            }
-
-            // copy current distance counts to 'previous row' distance counts
-            swap = p;
-            p = d;
-            d = swap;
-        }
-
-        // our last action in the above loop was to switch d and p, so p now
-        // actually has the most recent cost counts
-        return p[n];
+        return StringUtils.getLevenshteinDistance(s, t);
     }
 
     public static boolean isLetter(char ch) {
diff --git a/tubemq-core/src/test/java/org/apache/tubemq/corebase/utils/ConcurrentHashSetTest.java b/tubemq-core/src/test/java/org/apache/tubemq/corebase/utils/ConcurrentHashSetTest.java
new file mode 100644
index 0000000..581c34c
--- /dev/null
+++ b/tubemq-core/src/test/java/org/apache/tubemq/corebase/utils/ConcurrentHashSetTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.tubemq.corebase.utils;
+
+import junit.framework.TestCase;
+import org.junit.Test;
+
+
+public class ConcurrentHashSetTest extends TestCase {
+
+    @Test
+    public void test() {
+        int count = 0;
+        ConcurrentHashSet<String> testSet =
+                new ConcurrentHashSet<>();
+        for (String item : testSet) {
+            System.out.println("Count = " + count++ + ", item = " + item);
+        }
+        testSet.add("test-1");
+        testSet.add("test-2");
+        System.out.println("test-2 add time is " + testSet.getItemAddTime("test-2"));
+        testSet.add("test-3");
+        testSet.add("test-4");
+        assertEquals(4, testSet.size());
+        assertFalse(testSet.add("test-2"));
+        assertEquals(4, testSet.size());
+        count = 0;
+        for (String item : testSet) {
+            System.out.println("Count = " + count++ + ", item = " + item);
+        }
+        System.out.println("test-2 add time is " + testSet.getItemAddTime("test-2"));
+    }
+
+}
\ No newline at end of file
diff --git a/tubemq-docker/tubemq-all/tubemq.sh b/tubemq-docker/tubemq-all/tubemq.sh
index c46a659..466154c 100644
--- a/tubemq-docker/tubemq-all/tubemq.sh
+++ b/tubemq-docker/tubemq-all/tubemq.sh
@@ -29,7 +29,7 @@ if [[ $TARGET == "standalone" ]]; then
   sleep 5
   # master start
 
-  ./master.sh start
+  ./tubemq.sh master start
   sleep 5
   # add broker
   curl -d "type=op_modify&method=admin_add_broker_configure&brokerId=1\
@@ -40,16 +40,16 @@ if [[ $TARGET == "standalone" ]]; then
   curl -d "type=op_modify&method=admin_online_broker_configure&brokerId=1\
     &modifyUser=docker&confModAuthToken=abc" http://127.0.0.1:8080/webapi.htm
   # broker start
-  ./broker.sh start
+  ./tubemq.sh broker start
   tail -F /opt/tubemq-server/logs/*
 fi
 # for master
 if [[ $TARGET == "master" ]]; then
-  ./master.sh start
+  ./tubemq.sh master start
   tail -F /opt/tubemq-server/logs/master.log
 fi
 # for broker
 if [[ $TARGET == "broker" ]]; then
-  ./broker.sh start
+  ./tubemq.sh broker start
   tail -F /opt/tubemq-server/logs/broker.log
 fi
\ No newline at end of file
diff --git a/tubemq-server/src/main/java/org/apache/tubemq/server/master/web/handler/WebAdminGroupCtrlHandler.java b/tubemq-server/src/main/java/org/apache/tubemq/server/master/web/handler/WebAdminGroupCtrlHandler.java
index 1c94cd8..028cd6b 100644
--- a/tubemq-server/src/main/java/org/apache/tubemq/server/master/web/handler/WebAdminGroupCtrlHandler.java
+++ b/tubemq-server/src/main/java/org/apache/tubemq/server/master/web/handler/WebAdminGroupCtrlHandler.java
@@ -66,8 +66,6 @@ public class WebAdminGroupCtrlHandler extends AbstractWebHandler {
         registerQueryWebMethod("admin_query_consume_group_setting",
                 "adminQueryConsumeGroupSetting");
         // register modify method
-        registerModifyWebMethod("admin_add_new_topic_record",
-                "adminAddTopicEntityInfo");
         registerModifyWebMethod("admin_add_black_consumergroup_info",
                 "adminAddBlackGroupInfo");
         registerModifyWebMethod("admin_bath_add_black_consumergroup_info",
diff --git a/tubemq-server/src/main/java/org/apache/tubemq/server/master/web/handler/WebOtherInfoHandler.java b/tubemq-server/src/main/java/org/apache/tubemq/server/master/web/handler/WebOtherInfoHandler.java
index c6c2213..2e7e993 100644
--- a/tubemq-server/src/main/java/org/apache/tubemq/server/master/web/handler/WebOtherInfoHandler.java
+++ b/tubemq-server/src/main/java/org/apache/tubemq/server/master/web/handler/WebOtherInfoHandler.java
@@ -30,7 +30,6 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.tubemq.corebase.TBaseConstants;
 import org.apache.tubemq.corebase.cluster.ConsumerInfo;
 import org.apache.tubemq.corebase.cluster.Partition;
-import org.apache.tubemq.corebase.utils.ConcurrentHashSet;
 import org.apache.tubemq.corebase.utils.TStringUtils;
 import org.apache.tubemq.server.common.utils.WebParameterUtils;
 import org.apache.tubemq.server.master.TMaster;
@@ -93,7 +92,7 @@ public class WebOtherInfoHandler extends AbstractWebHandler {
                     }
                 }
             } else {
-                ConcurrentHashSet<String> groupSet = topicPSInfoManager.getTopicSubInfo(strTopicName);
+                Set<String> groupSet = topicPSInfoManager.getTopicSubInfo(strTopicName);
                 if ((groupSet != null) && (!groupSet.isEmpty())) {
                     if (TStringUtils.isEmpty(strConsumeGroup)) {
                         for (String tmpGroup : groupSet) {