[ 
https://issues.apache.org/jira/browse/SCB-1022?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16691452#comment-16691452
 ] 

ASF GitHub Bot commented on SCB-1022:
-------------------------------------

liubao68 closed pull request #993: [SCB-1022] measure tcpServer and tcpClient
URL: https://github.com/apache/servicecomb-java-chassis/pull/993
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpClientMetrics.java
 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpClientMetrics.java
index d8d5286b1..f2f2b75f3 100644
--- 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpClientMetrics.java
+++ 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpClientMetrics.java
@@ -20,77 +20,51 @@
 import 
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetricManager;
 import 
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultHttpSocketMetric;
 
-import io.vertx.core.http.HttpClient;
-import io.vertx.core.http.HttpClientOptions;
 import io.vertx.core.http.HttpClientRequest;
 import io.vertx.core.http.HttpClientResponse;
 import io.vertx.core.http.WebSocket;
 import io.vertx.core.net.SocketAddress;
-import io.vertx.core.net.impl.SocketAddressImpl;
 import io.vertx.core.spi.metrics.HttpClientMetrics;
 
 /**
  * important: not singleton, every HttpClient instance relate to a 
HttpClientMetrics instance
  */
 public class DefaultHttpClientMetrics implements
-    HttpClientMetrics<DefaultHttpSocketMetric, Object, 
DefaultHttpSocketMetric, DefaultClientEndpointMetric, Object> {
-
+    HttpClientMetrics<DefaultHttpSocketMetric, Object, 
DefaultHttpSocketMetric, Object, Object> {
   private final DefaultClientEndpointMetricManager clientEndpointMetricManager;
 
-  private final HttpClient client;
-
-  private final HttpClientOptions options;
-
-  public DefaultHttpClientMetrics(DefaultClientEndpointMetricManager 
clientEndpointMetricManager,
-      HttpClient client, HttpClientOptions options) {
+  public DefaultHttpClientMetrics(DefaultClientEndpointMetricManager 
clientEndpointMetricManager) {
     this.clientEndpointMetricManager = clientEndpointMetricManager;
-    this.client = client;
-    this.options = options;
-  }
-
-  public HttpClient getClient() {
-    return client;
-  }
-
-  public HttpClientOptions getOptions() {
-    return options;
   }
 
   @Override
-  public DefaultClientEndpointMetric createEndpoint(String host, int port, int 
maxPoolSize) {
-    SocketAddress address = new SocketAddressImpl(port, host);
-    return 
clientEndpointMetricManager.getOrCreateClientEndpointMetric(address);
+  public Object createEndpoint(String host, int port, int maxPoolSize) {
+    return null;
   }
 
   @Override
-  public void closeEndpoint(String host, int port, DefaultClientEndpointMetric 
endpointMetric) {
-    endpointMetric.decRefCount();
+  public void closeEndpoint(String host, int port, Object endpointMetric) {
   }
 
   @Override
-  public Object enqueueRequest(DefaultClientEndpointMetric endpointMetric) {
+  public Object enqueueRequest(Object endpointMetric) {
     return null;
   }
 
   @Override
-  public void dequeueRequest(DefaultClientEndpointMetric endpointMetric, 
Object taskMetric) {
+  public void dequeueRequest(Object endpointMetric, Object taskMetric) {
   }
 
   @Override
-  public void endpointConnected(DefaultClientEndpointMetric endpointMetric, 
DefaultHttpSocketMetric socketMetric) {
-    // as http2 client will not invoke this method, the endpointMetric info 
will lost.
-    // you can get more details from 
https://github.com/eclipse-vertx/vert.x/issues/2660
-    // hence, we will set endpointMetric info in the method 
connected(SocketAddress remoteAddress, String remoteName)
+  public void endpointConnected(Object endpointMetric, DefaultHttpSocketMetric 
socketMetric) {
   }
 
   @Override
-  public void endpointDisconnected(DefaultClientEndpointMetric endpointMetric, 
DefaultHttpSocketMetric socketMetric) {
-    endpointMetric.onDisconnect();
-    socketMetric.setConnected(false);
+  public void endpointDisconnected(Object endpointMetric, 
DefaultHttpSocketMetric socketMetric) {
   }
 
   @Override
-  public DefaultHttpSocketMetric requestBegin(DefaultClientEndpointMetric 
endpointMetric,
+  public DefaultHttpSocketMetric requestBegin(Object endpointMetric,
       DefaultHttpSocketMetric socketMetric, SocketAddress localAddress, 
SocketAddress remoteAddress,
       HttpClientRequest request) {
     socketMetric.requestBegin();
@@ -107,7 +81,7 @@ public void responseBegin(DefaultHttpSocketMetric 
requestMetric, HttpClientRespo
   }
 
   @Override
-  public DefaultHttpSocketMetric responsePushed(DefaultClientEndpointMetric 
endpointMetric,
+  public DefaultHttpSocketMetric responsePushed(Object endpointMetric,
       DefaultHttpSocketMetric socketMetric,
       SocketAddress localAddress,
       SocketAddress remoteAddress, HttpClientRequest request) {
@@ -123,7 +97,7 @@ public void responseEnd(DefaultHttpSocketMetric 
requestMetric, HttpClientRespons
   }
 
   @Override
-  public Object connected(DefaultClientEndpointMetric endpointMetric, 
DefaultHttpSocketMetric socketMetric,
+  public Object connected(Object endpointMetric, DefaultHttpSocketMetric 
socketMetric,
       WebSocket webSocket) {
     return null;
   }
@@ -135,26 +109,13 @@ public void disconnected(Object webSocketMetric) {
 
   @Override
   public DefaultHttpSocketMetric connected(SocketAddress remoteAddress, String 
remoteName) {
-    // when host of createEndpoint is not ip but a hostName
-    // get from remoteAddress will return null
-    // in this time need to try again with remoteName
-    // connected is a low frequency method, this try logic will not cause 
performance problem
-
-    DefaultClientEndpointMetric clientEndpointMetric = 
this.clientEndpointMetricManager
-        .getClientEndpointMetric(remoteAddress);
-    if (clientEndpointMetric == null) {
-      SocketAddressImpl address = new SocketAddressImpl(remoteAddress.port(), 
remoteName);
-      clientEndpointMetric = 
this.clientEndpointMetricManager.getClientEndpointMetric(address);
-    }
-    // it's better to be done in endpointConnected
-    // but there is bug before vertx 3.6.0 vertx not invoke endpointConnected 
for http2
-    // to avoid this bug, we move the logic here
-    clientEndpointMetric.onConnect();
-    return new DefaultHttpSocketMetric(clientEndpointMetric);
+    DefaultClientEndpointMetric endpointMetric = 
this.clientEndpointMetricManager.onConnect(remoteAddress);
+    return new DefaultHttpSocketMetric(endpointMetric);
   }
 
   @Override
   public void disconnected(DefaultHttpSocketMetric socketMetric, SocketAddress 
remoteAddress) {
+    socketMetric.onDisconnect();
   }
 
   @Override
diff --git 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpServerMetrics.java
 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpServerMetrics.java
index ddfb95870..76692dd15 100644
--- 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpServerMetrics.java
+++ 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultHttpServerMetrics.java
@@ -20,8 +20,6 @@
 import 
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultHttpSocketMetric;
 
 import io.vertx.core.http.HttpMethod;
-import io.vertx.core.http.HttpServer;
-import io.vertx.core.http.HttpServerOptions;
 import io.vertx.core.http.HttpServerRequest;
 import io.vertx.core.http.HttpServerResponse;
 import io.vertx.core.http.ServerWebSocket;
@@ -34,36 +32,14 @@
 public class DefaultHttpServerMetrics implements HttpServerMetrics<Object, 
Object, DefaultHttpSocketMetric> {
   private final DefaultEndpointMetric endpointMetric;
 
-  private final HttpServer server;
-
-  private final SocketAddress localAddress;
-
-  private final HttpServerOptions options;
-
-  public DefaultHttpServerMetrics(DefaultEndpointMetric endpointMetric, 
HttpServer server,
-      SocketAddress localAddress, HttpServerOptions options) {
+  public DefaultHttpServerMetrics(DefaultEndpointMetric endpointMetric) {
     this.endpointMetric = endpointMetric;
-    this.server = server;
-    this.localAddress = localAddress;
-    this.options = options;
   }
 
   public DefaultEndpointMetric getEndpointMetric() {
     return endpointMetric;
   }
 
-  public HttpServer getServer() {
-    return server;
-  }
-
-  public SocketAddress getLocalAddress() {
-    return localAddress;
-  }
-
-  public HttpServerOptions getOptions() {
-    return options;
-  }
-
   @Override
   public Object requestBegin(DefaultHttpSocketMetric socketMetric, 
HttpServerRequest request) {
     return null;
@@ -108,8 +84,7 @@ public DefaultHttpSocketMetric connected(SocketAddress 
remoteAddress, String rem
 
   @Override
   public void disconnected(DefaultHttpSocketMetric socketMetric, SocketAddress 
remoteAddress) {
-    endpointMetric.onDisconnect();
-    socketMetric.setConnected(false);
+    socketMetric.onDisconnect();
   }
 
   @Override
diff --git 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultTcpClientMetrics.java
 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultTcpClientMetrics.java
new file mode 100644
index 000000000..7233be289
--- /dev/null
+++ 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultTcpClientMetrics.java
@@ -0,0 +1,72 @@
+/*
+ * 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.servicecomb.foundation.vertx.metrics;
+
+import 
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetric;
+import 
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetricManager;
+import 
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultTcpSocketMetric;
+
+import io.vertx.core.net.SocketAddress;
+import io.vertx.core.spi.metrics.TCPMetrics;
+
+/**
+ * important: not singleton, every NetClient instance relate to a TCPMetrics 
instance
+ */
+public class DefaultTcpClientMetrics implements 
TCPMetrics<DefaultTcpSocketMetric> {
+  private final DefaultClientEndpointMetricManager clientEndpointMetricManager;
+
+  public DefaultTcpClientMetrics(DefaultClientEndpointMetricManager 
clientEndpointMetricManager) {
+    this.clientEndpointMetricManager = clientEndpointMetricManager;
+  }
+
+  @Override
+  public DefaultTcpSocketMetric connected(SocketAddress remoteAddress, String 
remoteName) {
+    DefaultClientEndpointMetric endpointMetric = 
this.clientEndpointMetricManager.onConnect(remoteAddress);
+    return new DefaultTcpSocketMetric(endpointMetric);
+  }
+
+  @Override
+  public void disconnected(DefaultTcpSocketMetric socketMetric, SocketAddress 
remoteAddress) {
+    socketMetric.onDisconnect();
+  }
+
+  @Override
+  public void bytesRead(DefaultTcpSocketMetric socketMetric, SocketAddress 
remoteAddress, long numberOfBytes) {
+    socketMetric.getEndpointMetric().addBytesRead(numberOfBytes);
+  }
+
+  @Override
+  public void bytesWritten(DefaultTcpSocketMetric socketMetric, SocketAddress 
remoteAddress, long numberOfBytes) {
+    socketMetric.getEndpointMetric().addBytesWritten(numberOfBytes);
+  }
+
+  @Override
+  public void exceptionOccurred(DefaultTcpSocketMetric socketMetric, 
SocketAddress remoteAddress, Throwable t) {
+
+  }
+
+  @Override
+  @Deprecated
+  public boolean isEnabled() {
+    return true;
+  }
+
+  @Override
+  public void close() {
+
+  }
+}
diff --git 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultTcpServerMetrics.java
 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultTcpServerMetrics.java
new file mode 100644
index 000000000..d208c6d9f
--- /dev/null
+++ 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultTcpServerMetrics.java
@@ -0,0 +1,75 @@
+/*
+ * 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.servicecomb.foundation.vertx.metrics;
+
+import 
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;
+import 
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultTcpSocketMetric;
+
+import io.vertx.core.net.SocketAddress;
+import io.vertx.core.spi.metrics.TCPMetrics;
+
+/**
+ * important: not singleton, every NetServer instance relate to a 
TcpServerMetrics instance
+ */
+public class DefaultTcpServerMetrics implements 
TCPMetrics<DefaultTcpSocketMetric> {
+  private final DefaultEndpointMetric endpointMetric;
+
+  public DefaultTcpServerMetrics(DefaultEndpointMetric endpointMetric) {
+    this.endpointMetric = endpointMetric;
+  }
+
+  public DefaultEndpointMetric getEndpointMetric() {
+    return endpointMetric;
+  }
+
+  @Override
+  public DefaultTcpSocketMetric connected(SocketAddress remoteAddress, String 
remoteName) {
+    endpointMetric.onConnect();
+    return new DefaultTcpSocketMetric(endpointMetric);
+  }
+
+  @Override
+  public void disconnected(DefaultTcpSocketMetric socketMetric, SocketAddress 
remoteAddress) {
+    socketMetric.onDisconnect();
+  }
+
+  @Override
+  public void bytesRead(DefaultTcpSocketMetric socketMetric, SocketAddress 
remoteAddress, long numberOfBytes) {
+    endpointMetric.addBytesRead(numberOfBytes);
+  }
+
+  @Override
+  public void bytesWritten(DefaultTcpSocketMetric socketMetric, SocketAddress 
remoteAddress, long numberOfBytes) {
+    endpointMetric.addBytesWritten(numberOfBytes);
+  }
+
+  @Override
+  public void exceptionOccurred(DefaultTcpSocketMetric socketMetric, 
SocketAddress remoteAddress, Throwable t) {
+
+  }
+
+  @Override
+  @Deprecated
+  public boolean isEnabled() {
+    return true;
+  }
+
+  @Override
+  public void close() {
+
+  }
+}
diff --git 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetrics.java
 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetrics.java
index e0dfcee9d..e68e41853 100644
--- 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetrics.java
+++ 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/DefaultVertxMetrics.java
@@ -29,9 +29,12 @@
 import io.vertx.core.http.HttpServer;
 import io.vertx.core.http.HttpServerOptions;
 import io.vertx.core.metrics.impl.DummyVertxMetrics;
+import io.vertx.core.net.NetClientOptions;
+import io.vertx.core.net.NetServerOptions;
 import io.vertx.core.net.SocketAddress;
 import io.vertx.core.spi.metrics.HttpClientMetrics;
 import io.vertx.core.spi.metrics.HttpServerMetrics;
+import io.vertx.core.spi.metrics.TCPMetrics;
 
 public class DefaultVertxMetrics extends DummyVertxMetrics {
   private final Vertx vertx;
@@ -46,6 +49,8 @@
   public DefaultVertxMetrics(Vertx vertx, VertxOptions vertxOptions) {
     this.vertx = vertx;
     this.vertxOptions = vertxOptions;
+    // can not create DefaultClientEndpointMetricManager in this time
+    // because vertx is not inited
   }
 
   public Vertx getVertx() {
@@ -56,16 +61,11 @@ public DefaultClientEndpointMetricManager 
getClientEndpointMetricManager() {
     return clientEndpointMetricManager;
   }
 
-  @Override
-  public HttpServerMetrics<?, ?, ?> createMetrics(HttpServer server, 
SocketAddress localAddress,
-      HttpServerOptions options) {
-    DefaultEndpointMetric endpointMetric = serverEndpointMetricMap
-        .computeIfAbsent(localAddress, DefaultEndpointMetric::new);
-    return new DefaultHttpServerMetrics(endpointMetric, server, localAddress, 
options);
+  public Map<SocketAddress, DefaultEndpointMetric> 
getServerEndpointMetricMap() {
+    return serverEndpointMetricMap;
   }
 
-  @Override
-  public HttpClientMetrics<?, ?, ?, ?, ?> createMetrics(HttpClient client, 
HttpClientOptions options) {
+  private void initClientEndpointMetricManager() {
     if (clientEndpointMetricManager == null) {
       synchronized (vertx) {
         if (clientEndpointMetricManager == null) {
@@ -74,8 +74,33 @@ public DefaultClientEndpointMetricManager 
getClientEndpointMetricManager() {
         }
       }
     }
+  }
 
-    return new DefaultHttpClientMetrics(clientEndpointMetricManager, client, 
options);
+  @Override
+  public HttpServerMetrics<?, ?, ?> createMetrics(HttpServer server, 
SocketAddress localAddress,
+      HttpServerOptions options) {
+    DefaultEndpointMetric endpointMetric = serverEndpointMetricMap
+        .computeIfAbsent(localAddress, DefaultEndpointMetric::new);
+    return new DefaultHttpServerMetrics(endpointMetric);
+  }
+
+  @Override
+  public HttpClientMetrics<?, ?, ?, ?, ?> createMetrics(HttpClient client, 
HttpClientOptions options) {
+    initClientEndpointMetricManager();
+    return new DefaultHttpClientMetrics(clientEndpointMetricManager);
+  }
+
+  @Override
+  public TCPMetrics<?> createMetrics(SocketAddress localAddress, 
NetServerOptions options) {
+    DefaultEndpointMetric endpointMetric = serverEndpointMetricMap
+        .computeIfAbsent(localAddress, DefaultEndpointMetric::new);
+    return new DefaultTcpServerMetrics(endpointMetric);
+  }
+
+  @Override
+  public TCPMetrics<?> createMetrics(NetClientOptions options) {
+    initClientEndpointMetricManager();
+    return new DefaultTcpClientMetrics(clientEndpointMetricManager);
   }
 
   @Override
diff --git 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetric.java
 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetric.java
index e4c1bfd88..41a995a02 100644
--- 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetric.java
+++ 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetric.java
@@ -16,8 +16,6 @@
  */
 package org.apache.servicecomb.foundation.vertx.metrics.metric;
 
-import java.util.concurrent.atomic.AtomicLong;
-
 import io.vertx.core.net.SocketAddress;
 
 
@@ -30,8 +28,6 @@
   // decRefCount no need to lock, because that only cause to be expired later.
   private long lastNanoTime;
 
-  private AtomicLong refCount = new AtomicLong();
-
   public DefaultClientEndpointMetric(SocketAddress address) {
     super(address);
   }
@@ -40,22 +36,14 @@ public long getLastNanoTime() {
     return lastNanoTime;
   }
 
-  public long getRefCount() {
-    return refCount.get();
-  }
-
-  public void incRefCount() {
-    lastNanoTime = System.nanoTime();
-    refCount.incrementAndGet();
-  }
-
-  public void decRefCount() {
+  @Override
+  public void onDisconnect() {
+    super.onDisconnect();
     lastNanoTime = System.nanoTime();
-    refCount.decrementAndGet();
   }
 
   public boolean isExpired(long nsTimeout) {
-    return refCount.get() == 0
+    return getCurrentConnectionCount() == 0
         && (System.nanoTime() - lastNanoTime) > nsTimeout;
   }
 }
diff --git 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetricManager.java
 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetricManager.java
index 8874c0382..c014d5761 100644
--- 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetricManager.java
+++ 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultClientEndpointMetricManager.java
@@ -17,6 +17,8 @@
 package org.apache.servicecomb.foundation.vertx.metrics.metric;
 
 import java.util.Map;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
 import org.apache.servicecomb.foundation.vertx.metrics.MetricsOptionsEx;
@@ -33,7 +35,7 @@
   // must check expired periodically
   private Map<SocketAddress, DefaultClientEndpointMetric> 
clientEndpointMetricMap = new ConcurrentHashMapEx<>();
 
-  private final Object lock = new Object();
+  private final ReadWriteLock rwlock = new ReentrantReadWriteLock();
 
   public DefaultClientEndpointMetricManager(Vertx vertx, MetricsOptionsEx 
metricsOptionsEx) {
     this.metricsOptionsEx = metricsOptionsEx;
@@ -42,31 +44,37 @@ public DefaultClientEndpointMetricManager(Vertx vertx, 
MetricsOptionsEx metricsO
   }
 
   @VisibleForTesting
+  public DefaultClientEndpointMetric getClientEndpointMetric(SocketAddress 
serverAddress) {
+    return clientEndpointMetricMap.get(serverAddress);
+  }
+
   public Map<SocketAddress, DefaultClientEndpointMetric> 
getClientEndpointMetricMap() {
     return clientEndpointMetricMap;
   }
 
-  public DefaultClientEndpointMetric 
getOrCreateClientEndpointMetric(SocketAddress serverAddress) {
-    synchronized (lock) {
-      DefaultClientEndpointMetric metric = clientEndpointMetricMap
+  public DefaultClientEndpointMetric onConnect(SocketAddress serverAddress) {
+    rwlock.readLock().lock();
+    try {
+      DefaultClientEndpointMetric clientEndpointMetric = 
clientEndpointMetricMap
           .computeIfAbsent(serverAddress, DefaultClientEndpointMetric::new);
-      metric.incRefCount();
-      return metric;
+      clientEndpointMetric.onConnect();
+      return clientEndpointMetric;
+    } finally {
+      rwlock.readLock().unlock();
     }
   }
 
-  public DefaultClientEndpointMetric getClientEndpointMetric(SocketAddress 
serverAddress) {
-    return clientEndpointMetricMap.get(serverAddress);
-  }
-
   @VisibleForTesting
   public void onCheckClientEndpointMetricExpired(long periodic) {
     for (DefaultClientEndpointMetric metric : 
clientEndpointMetricMap.values()) {
       if 
(metric.isExpired(metricsOptionsEx.getCheckClientEndpointMetricExpiredInNano()))
 {
-        synchronized (lock) {
+        rwlock.writeLock().lock();
+        try {
           if 
(metric.isExpired(metricsOptionsEx.getCheckClientEndpointMetricExpiredInNano()))
 {
             clientEndpointMetricMap.remove(metric.getAddress());
           }
+        } finally {
+          rwlock.writeLock().unlock();
         }
       }
     }
diff --git 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultHttpSocketMetric.java
 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultHttpSocketMetric.java
index b486b622b..307658e93 100644
--- 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultHttpSocketMetric.java
+++ 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultHttpSocketMetric.java
@@ -16,40 +16,13 @@
  */
 package org.apache.servicecomb.foundation.vertx.metrics.metric;
 
-public class DefaultHttpSocketMetric {
-  private DefaultEndpointMetric endpointMetric;
-
-  private boolean connected = true;
-
-  private long connectedTime = System.nanoTime();
-
+public class DefaultHttpSocketMetric extends DefaultTcpSocketMetric {
   private long requestBeginTime;
 
   private long requestEndTime;
 
   public DefaultHttpSocketMetric(DefaultEndpointMetric endpointMetric) {
-    this.endpointMetric = endpointMetric;
-  }
-
-  public void setEndpointMetric(DefaultEndpointMetric endpointMetric) {
-    this.endpointMetric = endpointMetric;
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T extends DefaultEndpointMetric> T getEndpointMetric() {
-    return (T) endpointMetric;
-  }
-
-  public boolean isConnected() {
-    return connected;
-  }
-
-  public void setConnected(boolean connected) {
-    this.connected = connected;
-  }
-
-  public long getConnectedTime() {
-    return connectedTime;
+    super(endpointMetric);
   }
 
   public long getRequestBeginTime() {
diff --git 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultTcpSocketMetric.java
 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultTcpSocketMetric.java
new file mode 100644
index 000000000..16adccf2e
--- /dev/null
+++ 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/metrics/metric/DefaultTcpSocketMetric.java
@@ -0,0 +1,47 @@
+/*
+ * 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.servicecomb.foundation.vertx.metrics.metric;
+
+public class DefaultTcpSocketMetric {
+  protected DefaultEndpointMetric endpointMetric;
+
+  protected boolean connected = true;
+
+  protected long connectedTime = System.nanoTime();
+
+  public DefaultTcpSocketMetric(DefaultEndpointMetric endpointMetric) {
+    this.endpointMetric = endpointMetric;
+  }
+
+  @SuppressWarnings("unchecked")
+  public <T extends DefaultEndpointMetric> T getEndpointMetric() {
+    return (T) endpointMetric;
+  }
+
+  public boolean isConnected() {
+    return connected;
+  }
+
+  public void onDisconnect() {
+    endpointMetric.onDisconnect();
+    this.connected = false;
+  }
+
+  public long getConnectedTime() {
+    return connectedTime;
+  }
+}
diff --git 
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpClientMetrics.java
 
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpClientMetrics.java
index 0f1de3188..caeb25e15 100644
--- 
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpClientMetrics.java
+++ 
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpClientMetrics.java
@@ -59,21 +59,27 @@
 
   int port2 = 2;
 
-  int maxPoolSize = 5;
-
   SocketAddress address1 = new SocketAddressImpl(port1, host);
 
   SocketAddress address2 = new SocketAddressImpl(port2, host);
 
   DefaultClientEndpointMetric endpointMetric_a_1;
 
+  DefaultHttpSocketMetric socketMetric_a_1;
+
   DefaultClientEndpointMetric endpointMetric_a_2;
 
+  DefaultHttpSocketMetric socketMetric_a_2;
+
   DefaultClientEndpointMetric endpointMetric_b_1;
 
+  DefaultHttpSocketMetric socketMetric_b_1;
+
   DefaultClientEndpointMetric endpointMetric_b_2;
 
-  static long nanoTime = 1;
+  DefaultHttpSocketMetric socketMetric_b_2;
+
+  static long nanoTime;
 
   @BeforeClass
   public static void classSetup() {
@@ -85,6 +91,11 @@ long nanoTime() {
     };
   }
 
+  private static DefaultHttpSocketMetric 
initSocketMetric(DefaultHttpClientMetrics metrics,
+      SocketAddress address) {
+    return metrics.connected(address, address.toString());
+  }
+
   @Before
   public void setup() {
     vertxOptions.setMetricsOptions(metricsOptionsEx);
@@ -92,11 +103,17 @@ public void setup() {
     clientMetrics_a = (DefaultHttpClientMetrics) 
defaultVertxMetrics.createMetrics(anyHttpClient, options);
     clientMetrics_b = (DefaultHttpClientMetrics) 
defaultVertxMetrics.createMetrics(anyHttpClient, options);
 
-    endpointMetric_a_1 = clientMetrics_a.createEndpoint(host, port1, 
maxPoolSize);
-    endpointMetric_a_2 = clientMetrics_a.createEndpoint(host, port2, 
maxPoolSize);
+    nanoTime = 1;
 
-    endpointMetric_b_1 = clientMetrics_b.createEndpoint(host, port1, 
maxPoolSize);
-    endpointMetric_b_2 = clientMetrics_b.createEndpoint(host, port2, 
maxPoolSize);
+    socketMetric_a_1 = initSocketMetric(clientMetrics_a, address1);
+    endpointMetric_a_1 = socketMetric_a_1.getEndpointMetric();
+    socketMetric_a_2 = initSocketMetric(clientMetrics_a, address2);
+    endpointMetric_a_2 = socketMetric_a_2.getEndpointMetric();
+
+    socketMetric_b_1 = initSocketMetric(clientMetrics_b, address1);
+    endpointMetric_b_1 = socketMetric_b_1.getEndpointMetric();
+    socketMetric_b_2 = initSocketMetric(clientMetrics_b, address2);
+    endpointMetric_b_2 = socketMetric_b_2.getEndpointMetric();
   }
 
   @Test
@@ -112,37 +129,25 @@ public void createEndpoint() {
     Assert.assertNotSame(endpointMetric_a_2, endpointMetric_b_1);
     Assert.assertSame(endpointMetric_a_2, endpointMetric_b_2);
 
-    Assert.assertEquals(1, endpointMetric_a_1.getLastNanoTime());
-    Assert.assertEquals(2, endpointMetric_a_1.getRefCount());
-
-    Assert.assertEquals(1, endpointMetric_a_2.getLastNanoTime());
-    Assert.assertEquals(2, endpointMetric_a_2.getRefCount());
-  }
-
-  @Test
-  public void closeEndpoint() {
-    nanoTime = 2;
-    endpointMetric_a_1.decRefCount();
-
-    Assert.assertEquals(2, endpointMetric_a_1.getLastNanoTime());
-    Assert.assertEquals(1, endpointMetric_a_1.getRefCount());
+    Assert.assertEquals(2, endpointMetric_a_1.getCurrentConnectionCount());
+    Assert.assertEquals(2, endpointMetric_a_2.getCurrentConnectionCount());
   }
 
   @Test
   public void expire() {
     metricsOptionsEx.setCheckClientEndpointMetricExpiredInNano(10);
-    
+
     nanoTime = 2;
-    clientMetrics_a.closeEndpoint(host, port1, endpointMetric_a_1);
-    clientMetrics_a.closeEndpoint(host, port1, endpointMetric_a_2);
+    clientMetrics_a.disconnected(socketMetric_a_1, null);
+    clientMetrics_a.disconnected(socketMetric_a_2, null);
 
     nanoTime = 13;
     
defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);
     
Assert.assertNotNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address1));
     
Assert.assertNotNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address2));
 
-    clientMetrics_b.closeEndpoint(host, port1, endpointMetric_b_1);
-    clientMetrics_b.closeEndpoint(host, port1, endpointMetric_b_2);
+    clientMetrics_b.disconnected(socketMetric_b_1, null);
+    clientMetrics_b.disconnected(socketMetric_b_2, null);
 
     nanoTime = 23;
     
defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);
@@ -158,91 +163,79 @@ public void expire() {
   @Test
   public void connect() {
     {
-      nanoTime = 1;
-      DefaultHttpSocketMetric socketMetric = 
clientMetrics_a.connected(address1, host);
-      clientMetrics_a.endpointConnected(endpointMetric_a_1, socketMetric);
-
-      Assert.assertSame(endpointMetric_a_1, socketMetric.getEndpointMetric());
-      Assert.assertTrue(socketMetric.isConnected());
-      Assert.assertEquals(1, socketMetric.getConnectedTime());
-      Assert.assertEquals(1, 
socketMetric.getEndpointMetric().getConnectCount());
-      Assert.assertEquals(0, 
socketMetric.getEndpointMetric().getDisconnectCount());
-      Assert.assertEquals(1, 
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+      Assert.assertSame(endpointMetric_a_1, 
socketMetric_a_1.getEndpointMetric());
+      Assert.assertTrue(socketMetric_a_1.isConnected());
+      Assert.assertEquals(1, socketMetric_a_1.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_a_1.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(0, 
socketMetric_a_1.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(2, 
socketMetric_a_1.getEndpointMetric().getCurrentConnectionCount());
 
       nanoTime = 2;
-      clientMetrics_a.endpointDisconnected(socketMetric.getEndpointMetric(), 
socketMetric);
-
-      Assert.assertFalse(socketMetric.isConnected());
-      Assert.assertEquals(1, socketMetric.getConnectedTime());
-      Assert.assertEquals(1, 
socketMetric.getEndpointMetric().getConnectCount());
-      Assert.assertEquals(1, 
socketMetric.getEndpointMetric().getDisconnectCount());
-      Assert.assertEquals(0, 
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+      clientMetrics_a.disconnected(socketMetric_a_1, null);
+
+      Assert.assertEquals(2, endpointMetric_a_1.getLastNanoTime());
+      Assert.assertFalse(socketMetric_a_1.isConnected());
+      Assert.assertEquals(1, socketMetric_a_1.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_a_1.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(1, 
socketMetric_a_1.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(1, 
socketMetric_a_1.getEndpointMetric().getCurrentConnectionCount());
     }
 
     {
-      nanoTime = 3;
-      DefaultHttpSocketMetric socketMetric = 
clientMetrics_a.connected(address2, host);
-      clientMetrics_a.endpointConnected(endpointMetric_a_2, socketMetric);
-
-      Assert.assertSame(endpointMetric_a_2, socketMetric.getEndpointMetric());
-      Assert.assertTrue(socketMetric.isConnected());
-      Assert.assertEquals(3, socketMetric.getConnectedTime());
-      Assert.assertEquals(1, 
socketMetric.getEndpointMetric().getConnectCount());
-      Assert.assertEquals(0, 
socketMetric.getEndpointMetric().getDisconnectCount());
-      Assert.assertEquals(1, 
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+      Assert.assertSame(endpointMetric_a_2, 
socketMetric_a_2.getEndpointMetric());
+      Assert.assertTrue(socketMetric_a_2.isConnected());
+      Assert.assertEquals(1, socketMetric_a_2.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_a_2.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(0, 
socketMetric_a_2.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(2, 
socketMetric_a_2.getEndpointMetric().getCurrentConnectionCount());
 
       nanoTime = 4;
-      clientMetrics_a.endpointDisconnected(socketMetric.getEndpointMetric(), 
socketMetric);
-
-      Assert.assertFalse(socketMetric.isConnected());
-      Assert.assertEquals(3, socketMetric.getConnectedTime());
-      Assert.assertEquals(1, 
socketMetric.getEndpointMetric().getConnectCount());
-      Assert.assertEquals(1, 
socketMetric.getEndpointMetric().getDisconnectCount());
-      Assert.assertEquals(0, 
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+      clientMetrics_a.disconnected(socketMetric_a_2, null);
+
+      Assert.assertEquals(4, endpointMetric_a_2.getLastNanoTime());
+      Assert.assertFalse(socketMetric_a_2.isConnected());
+      Assert.assertEquals(1, socketMetric_a_2.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_a_2.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(1, 
socketMetric_a_2.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(1, 
socketMetric_a_2.getEndpointMetric().getCurrentConnectionCount());
     }
 
     {
-      nanoTime = 5;
-      DefaultHttpSocketMetric socketMetric = 
clientMetrics_b.connected(address1, host);
-      clientMetrics_b.endpointConnected(endpointMetric_b_1, socketMetric);
-
-      Assert.assertSame(endpointMetric_b_1, socketMetric.getEndpointMetric());
-      Assert.assertTrue(socketMetric.isConnected());
-      Assert.assertEquals(5, socketMetric.getConnectedTime());
-      Assert.assertEquals(2, 
socketMetric.getEndpointMetric().getConnectCount());
-      Assert.assertEquals(1, 
socketMetric.getEndpointMetric().getDisconnectCount());
-      Assert.assertEquals(1, 
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+      Assert.assertSame(endpointMetric_b_1, 
socketMetric_b_1.getEndpointMetric());
+      Assert.assertTrue(socketMetric_b_1.isConnected());
+      Assert.assertEquals(1, socketMetric_b_1.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_b_1.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(1, 
socketMetric_b_1.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(1, 
socketMetric_b_1.getEndpointMetric().getCurrentConnectionCount());
 
       nanoTime = 6;
-      clientMetrics_b.endpointDisconnected(socketMetric.getEndpointMetric(), 
socketMetric);
-
-      Assert.assertFalse(socketMetric.isConnected());
-      Assert.assertEquals(5, socketMetric.getConnectedTime());
-      Assert.assertEquals(2, 
socketMetric.getEndpointMetric().getConnectCount());
-      Assert.assertEquals(2, 
socketMetric.getEndpointMetric().getDisconnectCount());
-      Assert.assertEquals(0, 
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+      clientMetrics_b.disconnected(socketMetric_b_1, null);
+
+      Assert.assertEquals(6, endpointMetric_b_1.getLastNanoTime());
+      Assert.assertFalse(socketMetric_b_1.isConnected());
+      Assert.assertEquals(1, socketMetric_b_1.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_b_1.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(2, 
socketMetric_b_1.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(0, 
socketMetric_b_1.getEndpointMetric().getCurrentConnectionCount());
     }
 
     {
-      nanoTime = 6;
-      DefaultHttpSocketMetric socketMetric = 
clientMetrics_b.connected(address2, host);
-      clientMetrics_b.endpointConnected(endpointMetric_b_2, socketMetric);
-
-      Assert.assertSame(endpointMetric_b_2, socketMetric.getEndpointMetric());
-      Assert.assertTrue(socketMetric.isConnected());
-      Assert.assertEquals(6, socketMetric.getConnectedTime());
-      Assert.assertEquals(2, 
socketMetric.getEndpointMetric().getConnectCount());
-      Assert.assertEquals(1, 
socketMetric.getEndpointMetric().getDisconnectCount());
-      Assert.assertEquals(1, 
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+      Assert.assertSame(endpointMetric_b_2, 
socketMetric_b_2.getEndpointMetric());
+      Assert.assertTrue(socketMetric_b_2.isConnected());
+      Assert.assertEquals(1, socketMetric_b_2.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_b_2.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(1, 
socketMetric_b_2.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(1, 
socketMetric_b_2.getEndpointMetric().getCurrentConnectionCount());
 
       nanoTime = 7;
-      clientMetrics_b.endpointDisconnected(socketMetric.getEndpointMetric(), 
socketMetric);
-
-      Assert.assertFalse(socketMetric.isConnected());
-      Assert.assertEquals(6, socketMetric.getConnectedTime());
-      Assert.assertEquals(2, 
socketMetric.getEndpointMetric().getConnectCount());
-      Assert.assertEquals(2, 
socketMetric.getEndpointMetric().getDisconnectCount());
-      Assert.assertEquals(0, 
socketMetric.getEndpointMetric().getCurrentConnectionCount());
+      clientMetrics_b.disconnected(socketMetric_b_2, null);
+
+      Assert.assertEquals(7, endpointMetric_b_2.getLastNanoTime());
+      Assert.assertFalse(socketMetric_b_2.isConnected());
+      Assert.assertEquals(1, socketMetric_b_2.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_b_2.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(2, 
socketMetric_b_2.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(0, 
socketMetric_b_2.getEndpointMetric().getCurrentConnectionCount());
     }
   }
 
@@ -290,23 +283,20 @@ public void requestBegin(@Mocked HttpClientRequest 
request) {
   @SuppressWarnings("deprecation")
   @Test
   public void meaningless() {
-    Assert.assertSame(anyHttpClient, clientMetrics_a.getClient());
-    Assert.assertSame(anyHttpClient, clientMetrics_b.getClient());
-
-    Assert.assertSame(options, clientMetrics_a.getOptions());
-    Assert.assertSame(options, clientMetrics_b.getOptions());
-
     Assert.assertTrue(clientMetrics_a.isEnabled());
 
     clientMetrics_a.enqueueRequest(endpointMetric_a_1);
     clientMetrics_a.dequeueRequest(endpointMetric_a_1, null);
+    clientMetrics_a.createEndpoint(null, 0, 0);
+    clientMetrics_a.closeEndpoint(null, 0, null);
+    clientMetrics_a.endpointConnected(endpointMetric_a_1, null);
+    clientMetrics_a.endpointDisconnected(endpointMetric_a_1, null);
     clientMetrics_a.responseBegin(null, null);
     clientMetrics_a.responsePushed(null, null, null, null, null);
     clientMetrics_a.requestReset(null);
     clientMetrics_a.responseEnd(null, null);
     clientMetrics_a.connected(null, null, null);
     clientMetrics_a.disconnected(null);
-    clientMetrics_a.disconnected(null, null);
     clientMetrics_a.exceptionOccurred(null, null, null);
     clientMetrics_a.close();
   }
diff --git 
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpServerMetrics.java
 
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpServerMetrics.java
index b039cdd91..b95ad5a6e 100644
--- 
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpServerMetrics.java
+++ 
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultHttpServerMetrics.java
@@ -191,9 +191,7 @@ public void bytesWritten() {
   @SuppressWarnings("deprecation")
   @Test
   public void meaningless() {
-    Assert.assertSame(listen1_server1, metrics_listen1_server1.getServer());
-    Assert.assertSame(listen1_addr, metrics_listen1_server1.getLocalAddress());
-    Assert.assertSame(options, metrics_listen1_server1.getOptions());
+    Assert.assertSame(listen1_addr, 
metrics_listen1_server1.getEndpointMetric().getAddress());
     Assert.assertTrue(metrics_listen1_server1.isEnabled());
 
     metrics_listen1_server1.requestBegin(null, null);
diff --git 
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultTcpClientMetrics.java
 
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultTcpClientMetrics.java
new file mode 100644
index 000000000..fbbe8dec9
--- /dev/null
+++ 
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultTcpClientMetrics.java
@@ -0,0 +1,265 @@
+/*
+ * 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.servicecomb.foundation.vertx.metrics;
+
+import 
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultClientEndpointMetric;
+import 
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultTcpSocketMetric;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.net.NetClientOptions;
+import io.vertx.core.net.SocketAddress;
+import io.vertx.core.net.impl.SocketAddressImpl;
+import mockit.Mock;
+import mockit.MockUp;
+import mockit.Mocked;
+
+public class TestDefaultTcpClientMetrics {
+  @Mocked
+  Vertx vertx;
+
+  VertxOptions vertxOptions = new VertxOptions();
+
+  MetricsOptionsEx metricsOptionsEx = new MetricsOptionsEx();
+
+  NetClientOptions options = new NetClientOptions();
+
+  DefaultVertxMetrics defaultVertxMetrics;
+
+  DefaultTcpClientMetrics clientMetrics_a;
+
+  DefaultTcpClientMetrics clientMetrics_b;
+
+  String host = "host";
+
+  int port1 = 1;
+
+  int port2 = 2;
+
+  SocketAddress address1 = new SocketAddressImpl(port1, host);
+
+  SocketAddress address2 = new SocketAddressImpl(port2, host);
+
+  DefaultClientEndpointMetric endpointMetric_a_1;
+
+  DefaultTcpSocketMetric socketMetric_a_1;
+
+  DefaultClientEndpointMetric endpointMetric_a_2;
+
+  DefaultTcpSocketMetric socketMetric_a_2;
+
+  DefaultClientEndpointMetric endpointMetric_b_1;
+
+  DefaultTcpSocketMetric socketMetric_b_1;
+
+  DefaultClientEndpointMetric endpointMetric_b_2;
+
+  DefaultTcpSocketMetric socketMetric_b_2;
+
+  static long nanoTime;
+
+  @BeforeClass
+  public static void classSetup() {
+    new MockUp<System>() {
+      @Mock
+      long nanoTime() {
+        return nanoTime;
+      }
+    };
+  }
+
+  private static DefaultTcpSocketMetric 
initSocketMetric(DefaultTcpClientMetrics metrics,
+      SocketAddress address) {
+    return metrics.connected(address, address.toString());
+  }
+
+  @Before
+  public void setup() {
+    vertxOptions.setMetricsOptions(metricsOptionsEx);
+    defaultVertxMetrics = new DefaultVertxMetrics(vertx, vertxOptions);
+    clientMetrics_a = (DefaultTcpClientMetrics) 
defaultVertxMetrics.createMetrics(options);
+    clientMetrics_b = (DefaultTcpClientMetrics) 
defaultVertxMetrics.createMetrics(options);
+
+    nanoTime = 1;
+
+    socketMetric_a_1 = initSocketMetric(clientMetrics_a, address1);
+    endpointMetric_a_1 = socketMetric_a_1.getEndpointMetric();
+    socketMetric_a_2 = initSocketMetric(clientMetrics_a, address2);
+    endpointMetric_a_2 = socketMetric_a_2.getEndpointMetric();
+
+    socketMetric_b_1 = initSocketMetric(clientMetrics_b, address1);
+    endpointMetric_b_1 = socketMetric_b_1.getEndpointMetric();
+    socketMetric_b_2 = initSocketMetric(clientMetrics_b, address2);
+    endpointMetric_b_2 = socketMetric_b_2.getEndpointMetric();
+  }
+
+  @Test
+  public void createMetrics() {
+    Assert.assertNotSame(clientMetrics_a, clientMetrics_b);
+  }
+
+  @Test
+  public void createEndpoint() {
+    Assert.assertSame(endpointMetric_a_1, endpointMetric_b_1);
+    Assert.assertNotSame(endpointMetric_a_1, endpointMetric_a_2);
+
+    Assert.assertNotSame(endpointMetric_a_2, endpointMetric_b_1);
+    Assert.assertSame(endpointMetric_a_2, endpointMetric_b_2);
+
+    Assert.assertEquals(2, endpointMetric_a_1.getCurrentConnectionCount());
+    Assert.assertEquals(2, endpointMetric_a_2.getCurrentConnectionCount());
+  }
+
+  @Test
+  public void expire() {
+    metricsOptionsEx.setCheckClientEndpointMetricExpiredInNano(10);
+
+    nanoTime = 2;
+    clientMetrics_a.disconnected(socketMetric_a_1, null);
+    clientMetrics_a.disconnected(socketMetric_a_2, null);
+
+    nanoTime = 13;
+    
defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);
+    
Assert.assertNotNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address1));
+    
Assert.assertNotNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address2));
+
+    clientMetrics_b.disconnected(socketMetric_b_1, null);
+    clientMetrics_b.disconnected(socketMetric_b_2, null);
+
+    nanoTime = 23;
+    
defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);
+    
Assert.assertNotNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address1));
+    
Assert.assertNotNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address2));
+
+    nanoTime = 24;
+    
defaultVertxMetrics.getClientEndpointMetricManager().onCheckClientEndpointMetricExpired(0);
+    
Assert.assertNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address1));
+    
Assert.assertNull(defaultVertxMetrics.getClientEndpointMetricManager().getClientEndpointMetric(address2));
+  }
+
+  @Test
+  public void connect() {
+    {
+      Assert.assertSame(endpointMetric_a_1, 
socketMetric_a_1.getEndpointMetric());
+      Assert.assertTrue(socketMetric_a_1.isConnected());
+      Assert.assertEquals(1, socketMetric_a_1.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_a_1.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(0, 
socketMetric_a_1.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(2, 
socketMetric_a_1.getEndpointMetric().getCurrentConnectionCount());
+
+      nanoTime = 2;
+      clientMetrics_a.disconnected(socketMetric_a_1, null);
+
+      Assert.assertEquals(2, endpointMetric_a_1.getLastNanoTime());
+      Assert.assertFalse(socketMetric_a_1.isConnected());
+      Assert.assertEquals(1, socketMetric_a_1.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_a_1.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(1, 
socketMetric_a_1.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(1, 
socketMetric_a_1.getEndpointMetric().getCurrentConnectionCount());
+    }
+
+    {
+      Assert.assertSame(endpointMetric_a_2, 
socketMetric_a_2.getEndpointMetric());
+      Assert.assertTrue(socketMetric_a_2.isConnected());
+      Assert.assertEquals(1, socketMetric_a_2.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_a_2.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(0, 
socketMetric_a_2.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(2, 
socketMetric_a_2.getEndpointMetric().getCurrentConnectionCount());
+
+      nanoTime = 4;
+      clientMetrics_a.disconnected(socketMetric_a_2, null);
+
+      Assert.assertEquals(4, endpointMetric_a_2.getLastNanoTime());
+      Assert.assertFalse(socketMetric_a_2.isConnected());
+      Assert.assertEquals(1, socketMetric_a_2.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_a_2.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(1, 
socketMetric_a_2.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(1, 
socketMetric_a_2.getEndpointMetric().getCurrentConnectionCount());
+    }
+
+    {
+      Assert.assertSame(endpointMetric_b_1, 
socketMetric_b_1.getEndpointMetric());
+      Assert.assertTrue(socketMetric_b_1.isConnected());
+      Assert.assertEquals(1, socketMetric_b_1.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_b_1.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(1, 
socketMetric_b_1.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(1, 
socketMetric_b_1.getEndpointMetric().getCurrentConnectionCount());
+
+      nanoTime = 6;
+      clientMetrics_b.disconnected(socketMetric_b_1, null);
+
+      Assert.assertEquals(6, endpointMetric_b_1.getLastNanoTime());
+      Assert.assertFalse(socketMetric_b_1.isConnected());
+      Assert.assertEquals(1, socketMetric_b_1.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_b_1.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(2, 
socketMetric_b_1.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(0, 
socketMetric_b_1.getEndpointMetric().getCurrentConnectionCount());
+    }
+
+    {
+      Assert.assertSame(endpointMetric_b_2, 
socketMetric_b_2.getEndpointMetric());
+      Assert.assertTrue(socketMetric_b_2.isConnected());
+      Assert.assertEquals(1, socketMetric_b_2.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_b_2.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(1, 
socketMetric_b_2.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(1, 
socketMetric_b_2.getEndpointMetric().getCurrentConnectionCount());
+
+      nanoTime = 7;
+      clientMetrics_b.disconnected(socketMetric_b_2, null);
+
+      Assert.assertEquals(7, endpointMetric_b_2.getLastNanoTime());
+      Assert.assertFalse(socketMetric_b_2.isConnected());
+      Assert.assertEquals(1, socketMetric_b_2.getConnectedTime());
+      Assert.assertEquals(2, 
socketMetric_b_2.getEndpointMetric().getConnectCount());
+      Assert.assertEquals(2, 
socketMetric_b_2.getEndpointMetric().getDisconnectCount());
+      Assert.assertEquals(0, 
socketMetric_b_2.getEndpointMetric().getCurrentConnectionCount());
+    }
+  }
+
+  @Test
+  public void bytesReadAndWritten() {
+    clientMetrics_a.bytesRead(socketMetric_a_1, address1, 1);
+    clientMetrics_a.bytesWritten(socketMetric_a_1, address1, 1);
+
+    clientMetrics_a.bytesRead(socketMetric_a_2, address2, 1);
+    clientMetrics_a.bytesWritten(socketMetric_a_2, address2, 1);
+
+    clientMetrics_b.bytesRead(socketMetric_b_1, address1, 1);
+    clientMetrics_b.bytesWritten(socketMetric_b_1, address1, 1);
+
+    clientMetrics_b.bytesRead(socketMetric_b_2, address2, 1);
+    clientMetrics_b.bytesWritten(socketMetric_b_2, address2, 1);
+
+    Assert.assertEquals(2, endpointMetric_a_1.getBytesRead());
+    Assert.assertEquals(2, endpointMetric_a_2.getBytesRead());
+    Assert.assertEquals(2, endpointMetric_a_1.getBytesWritten());
+    Assert.assertEquals(2, endpointMetric_a_2.getBytesWritten());
+  }
+
+  @SuppressWarnings("deprecation")
+  @Test
+  public void meaningless() {
+    Assert.assertTrue(clientMetrics_a.isEnabled());
+
+    clientMetrics_a.exceptionOccurred(null, null, null);
+    clientMetrics_a.close();
+  }
+}
diff --git 
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultTcpServerMetrics.java
 
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultTcpServerMetrics.java
new file mode 100644
index 000000000..c6ed45e3a
--- /dev/null
+++ 
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/metrics/TestDefaultTcpServerMetrics.java
@@ -0,0 +1,187 @@
+/*
+ * 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.servicecomb.foundation.vertx.metrics;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import 
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;
+import 
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultTcpSocketMetric;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+import io.vertx.core.net.NetServerOptions;
+import io.vertx.core.net.SocketAddress;
+import mockit.Mocked;
+
+public class TestDefaultTcpServerMetrics {
+  @Mocked
+  Vertx vertx;
+
+  VertxOptions vertxOptions = new VertxOptions();
+
+  MetricsOptionsEx metricsOptionsEx = new MetricsOptionsEx();
+
+  DefaultVertxMetrics defaultVertxMetrics;
+
+  @Mocked
+  SocketAddress listen1_addr;
+
+  @Mocked
+  SocketAddress listen2_addr;
+
+  @Mocked
+  NetServerOptions options;
+
+  DefaultTcpServerMetrics metrics_listen1_server1;
+
+  DefaultTcpServerMetrics metrics_listen1_server2;
+
+  DefaultEndpointMetric endpointMetric1;
+
+  DefaultTcpServerMetrics metrics_listen2_server1;
+
+  DefaultTcpServerMetrics metrics_listen2_server2;
+
+  DefaultEndpointMetric endpointMetric2;
+
+  @Mocked
+  SocketAddress anyRemoteAddr;
+
+  String remoteName = "remote";
+
+  DefaultTcpSocketMetric socketMetric_listen1_1;
+
+  DefaultTcpSocketMetric socketMetric_listen1_2;
+
+  DefaultTcpSocketMetric socketMetric_listen2_1;
+
+  DefaultTcpSocketMetric socketMetric_listen2_2;
+
+  DefaultTcpSocketMetric socketMetric_listen2_3;
+
+  @Before
+  public void setup() {
+    vertxOptions.setMetricsOptions(metricsOptionsEx);
+    defaultVertxMetrics = new DefaultVertxMetrics(vertx, vertxOptions);
+
+    metrics_listen1_server1 = (DefaultTcpServerMetrics) defaultVertxMetrics
+        .createMetrics(listen1_addr, options);
+    metrics_listen1_server2 = (DefaultTcpServerMetrics) defaultVertxMetrics
+        .createMetrics(listen1_addr, options);
+    endpointMetric1 = metrics_listen1_server1.getEndpointMetric();
+
+    metrics_listen2_server1 = (DefaultTcpServerMetrics) defaultVertxMetrics
+        .createMetrics(listen2_addr, options);
+    metrics_listen2_server2 = (DefaultTcpServerMetrics) defaultVertxMetrics
+        .createMetrics(listen2_addr, options);
+    endpointMetric2 = metrics_listen2_server1.getEndpointMetric();
+
+    socketMetric_listen1_1 = metrics_listen1_server1.connected(anyRemoteAddr, 
remoteName);
+    socketMetric_listen1_2 = metrics_listen1_server2.connected(anyRemoteAddr, 
remoteName);
+    socketMetric_listen2_1 = metrics_listen2_server1.connected(anyRemoteAddr, 
remoteName);
+    socketMetric_listen2_2 = metrics_listen2_server2.connected(anyRemoteAddr, 
remoteName);
+    socketMetric_listen2_3 = metrics_listen2_server2.connected(anyRemoteAddr, 
remoteName);
+  }
+
+  @Test
+  public void createMetrics() {
+    Map<Object, Object> instances = new IdentityHashMap<>();
+    instances.put(metrics_listen1_server1, null);
+    instances.put(metrics_listen1_server2, null);
+    instances.put(metrics_listen2_server1, null);
+    instances.put(metrics_listen2_server2, null);
+    Assert.assertEquals(4, instances.size());
+
+    Assert.assertSame(metrics_listen1_server1.getEndpointMetric(), 
metrics_listen1_server2.getEndpointMetric());
+    Assert.assertNotSame(metrics_listen1_server1.getEndpointMetric(), 
metrics_listen2_server1.getEndpointMetric());
+    Assert.assertSame(metrics_listen2_server1.getEndpointMetric(), 
metrics_listen2_server2.getEndpointMetric());
+  }
+
+  @Test
+  public void connectionCount() {
+    Map<Object, Object> instances = new IdentityHashMap<>();
+    instances.put(socketMetric_listen1_1, null);
+    instances.put(socketMetric_listen1_2, null);
+    instances.put(socketMetric_listen2_1, null);
+    instances.put(socketMetric_listen2_2, null);
+    instances.put(socketMetric_listen2_3, null);
+    Assert.assertEquals(5, instances.size());
+
+    Assert.assertTrue(socketMetric_listen1_1.isConnected());
+    Assert.assertTrue(socketMetric_listen1_2.isConnected());
+    Assert.assertTrue(socketMetric_listen2_1.isConnected());
+    Assert.assertTrue(socketMetric_listen2_2.isConnected());
+    Assert.assertTrue(socketMetric_listen2_3.isConnected());
+
+    Assert.assertEquals(2, endpointMetric1.getCurrentConnectionCount());
+    Assert.assertEquals(3, endpointMetric2.getCurrentConnectionCount());
+
+    // disconnect
+    metrics_listen1_server1.disconnected(socketMetric_listen1_1, 
anyRemoteAddr);
+    metrics_listen1_server2.disconnected(socketMetric_listen1_2, 
anyRemoteAddr);
+    metrics_listen2_server1.disconnected(socketMetric_listen2_1, 
anyRemoteAddr);
+    metrics_listen2_server2.disconnected(socketMetric_listen2_2, 
anyRemoteAddr);
+    metrics_listen2_server2.disconnected(socketMetric_listen2_3, 
anyRemoteAddr);
+
+    Assert.assertFalse(socketMetric_listen1_1.isConnected());
+    Assert.assertFalse(socketMetric_listen1_2.isConnected());
+    Assert.assertFalse(socketMetric_listen2_1.isConnected());
+    Assert.assertFalse(socketMetric_listen2_2.isConnected());
+    Assert.assertFalse(socketMetric_listen2_3.isConnected());
+
+    Assert.assertEquals(0, endpointMetric1.getCurrentConnectionCount());
+    Assert.assertEquals(0, endpointMetric2.getCurrentConnectionCount());
+  }
+
+  @Test
+  public void bytesRead() {
+    metrics_listen1_server1.bytesRead(socketMetric_listen1_1, anyRemoteAddr, 
1);
+    metrics_listen1_server2.bytesRead(socketMetric_listen1_2, anyRemoteAddr, 
2);
+    metrics_listen2_server1.bytesRead(socketMetric_listen2_1, anyRemoteAddr, 
3);
+    metrics_listen2_server2.bytesRead(socketMetric_listen2_2, anyRemoteAddr, 
4);
+    metrics_listen2_server2.bytesRead(socketMetric_listen2_3, anyRemoteAddr, 
5);
+
+    Assert.assertEquals(3, endpointMetric1.getBytesRead());
+    Assert.assertEquals(12, endpointMetric2.getBytesRead());
+  }
+
+  @Test
+  public void bytesWritten() {
+    metrics_listen1_server1.bytesWritten(socketMetric_listen1_1, 
anyRemoteAddr, 1);
+    metrics_listen1_server2.bytesWritten(socketMetric_listen1_2, 
anyRemoteAddr, 2);
+    metrics_listen2_server1.bytesWritten(socketMetric_listen2_1, 
anyRemoteAddr, 3);
+    metrics_listen2_server2.bytesWritten(socketMetric_listen2_2, 
anyRemoteAddr, 4);
+    metrics_listen2_server2.bytesWritten(socketMetric_listen2_3, 
anyRemoteAddr, 5);
+
+    Assert.assertEquals(3, endpointMetric1.getBytesWritten());
+    Assert.assertEquals(12, endpointMetric2.getBytesWritten());
+  }
+
+  @SuppressWarnings("deprecation")
+  @Test
+  public void meaningless() {
+    Assert.assertSame(listen1_addr, 
metrics_listen1_server1.getEndpointMetric().getAddress());
+    Assert.assertTrue(metrics_listen1_server1.isEnabled());
+
+    metrics_listen1_server1.exceptionOccurred(null, null, null);
+    metrics_listen1_server1.close();
+  }
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


> measure tcpServer and tcpClient
> -------------------------------
>
>                 Key: SCB-1022
>                 URL: https://issues.apache.org/jira/browse/SCB-1022
>             Project: Apache ServiceComb
>          Issue Type: Sub-task
>          Components: Java-Chassis
>            Reporter: wujimin
>            Assignee: wujimin
>            Priority: Major
>             Fix For: java-chassis-1.1.0
>
>




--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to