[ISSUE #16]Use an object pool to manage DefaultMQAdminExt objects. (#17)

* [ISSUE #16]Use an object pool to manage DefaultMQAdminExt objects.

* Modify the code

* Optimize the code

Co-authored-by: zhangjidi2016 <zhangjidi@cmss.chinamobile.com>
This commit is contained in:
zhangjidi2016
2021-09-09 00:13:44 +08:00
committed by GitHub
parent 5b2a027cd8
commit 975449e268
19 changed files with 393 additions and 146 deletions

View File

@@ -19,13 +19,16 @@ package org.apache.rocketmq.dashboard.admin;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.rocketmq.dashboard.aspect.admin.MQAdminAspect;
import org.apache.rocketmq.dashboard.aspect.admin.annotation.MultiMQAdminCmdMethod;
import org.apache.rocketmq.dashboard.config.RMQConfigure;
import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
import org.apache.rocketmq.tools.admin.MQAdminExt;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.junit.Test;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -37,19 +40,20 @@ public class MQAdminAspectTest {
ProceedingJoinPoint joinPoint = mock(ProceedingJoinPoint.class);
MethodSignature signature = mock(MethodSignature.class);
Method method = mock(Method.class);
MultiMQAdminCmdMethod annotationValue = mock(MultiMQAdminCmdMethod.class);
when(annotationValue.timeoutMillis()).thenReturn(0L).thenReturn(3000L);
when(method.getAnnotation(MultiMQAdminCmdMethod.class)).thenReturn(annotationValue);
when(signature.getMethod()).thenReturn(method);
when(joinPoint.getSignature()).thenReturn(signature);
RMQConfigure rmqConfigure = mock(RMQConfigure.class);
when(rmqConfigure.getAccessKey()).thenReturn("rocketmq");
when(rmqConfigure.getSecretKey()).thenReturn("12345678");
Field field = mqAdminAspect.getClass().getDeclaredField("rmqConfigure");
GenericObjectPool<MQAdminExt> mqAdminExtPool = mock(GenericObjectPool.class);
when(mqAdminExtPool.borrowObject())
.thenThrow(new RuntimeException("borrowObject exception"))
.thenReturn(new DefaultMQAdminExt());
doNothing().doThrow(new RuntimeException("returnObject exception"))
.when(mqAdminExtPool).returnObject(any());
Field field = mqAdminAspect.getClass().getDeclaredField("mqAdminExtPool");
field.setAccessible(true);
field.set(mqAdminAspect, rmqConfigure);
field.set(mqAdminAspect, mqAdminExtPool);
// exception
mqAdminAspect.aroundMQAdminMethod(joinPoint);
mqAdminAspect.aroundMQAdminMethod(joinPoint);
}
}

View File

@@ -65,7 +65,6 @@ import org.apache.rocketmq.store.stats.BrokerStatsManager;
import org.apache.rocketmq.tools.admin.DefaultMQAdminExt;
import org.apache.rocketmq.tools.admin.DefaultMQAdminExtImpl;
import org.apache.rocketmq.tools.admin.api.MessageTrack;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -121,24 +120,12 @@ public class MQAdminExtImplTest {
defaultMQAdminExt = mock(DefaultMQAdminExt.class);
threadLocal.set(defaultMQAdminExt);
field = MQAdminInstance.class.getDeclaredField("INIT_COUNTER");
field.setAccessible(true);
object = field.get(mqAdminExtImpl);
assertNotNull(object);
ThreadLocal<Integer> threadLocal1 = (ThreadLocal<Integer>) object;
threadLocal1.set(1);
ReflectionTestUtils.setField(defaultMQAdminExt, "defaultMQAdminExtImpl", defaultMQAdminExtImpl);
ReflectionTestUtils.setField(defaultMQAdminExtImpl, "mqClientInstance", mqClientInstance);
ReflectionTestUtils.setField(mqClientInstance, "mQClientAPIImpl", mQClientAPIImpl);
ReflectionTestUtils.setField(mQClientAPIImpl, "remotingClient", remotingClient);
}
@After
public void destroy() {
MQAdminInstance.destroyMQAdminInstance();
}
@Test
public void testUpdateBrokerConfig() throws Exception {
assertNotNull(mqAdminExtImpl);

View File

@@ -0,0 +1,99 @@
/*
* 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.rocketmq.dashboard.admin;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.rocketmq.common.protocol.body.ClusterInfo;
import org.apache.rocketmq.dashboard.config.RMQConfigure;
import org.apache.rocketmq.dashboard.util.MockObjectUtil;
import org.apache.rocketmq.tools.admin.MQAdminExt;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.test.util.ReflectionTestUtils;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class MQAdminPoolTest {
private MqAdminExtObjectPool mqAdminExtObjectPool;
private GenericObjectPool<MQAdminExt> pool;
private MQAdminPooledObjectFactory mqAdminPooledObjectFactory;
@Before
public void init() {
mqAdminExtObjectPool = new MqAdminExtObjectPool();
RMQConfigure rmqConfigure = mock(RMQConfigure.class);
when(rmqConfigure.getNamesrvAddr()).thenReturn("127.0.0.1:9876");
when(rmqConfigure.getAccessKey()).thenReturn("rocketmq");
when(rmqConfigure.getSecretKey()).thenReturn("12345678");
ReflectionTestUtils.setField(mqAdminExtObjectPool, "rmqConfigure", rmqConfigure);
pool = mqAdminExtObjectPool.mqAdminExtPool();
mqAdminPooledObjectFactory = (MQAdminPooledObjectFactory) pool.getFactory();
}
@Test
public void testMakeObject() throws Exception {
PooledObject<MQAdminExt> mqAdmin = mqAdminPooledObjectFactory.makeObject();
Assert.assertNotNull(mqAdmin);
}
@Test
public void testDestroyObject() {
PooledObject<MQAdminExt> mqAdmin = mock(PooledObject.class);
Assert.assertNotNull(mqAdmin);
MQAdminExt mqAdminExt = mock(MQAdminExt.class);
doNothing().doThrow(new RuntimeException("shutdown exception")).when(mqAdminExt).shutdown();
when(mqAdmin.getObject()).thenReturn(mqAdminExt);
// shutdown
mqAdminPooledObjectFactory.destroyObject(mqAdmin);
// exception
mqAdminPooledObjectFactory.destroyObject(mqAdmin);
}
@Test
public void testValidateObject() throws Exception {
PooledObject<MQAdminExt> mqAdmin = mock(PooledObject.class);
Assert.assertNotNull(mqAdmin);
MQAdminExt mqAdminExt = mock(MQAdminExt.class);
ClusterInfo clusterInfo = MockObjectUtil.createClusterInfo();
clusterInfo.getBrokerAddrTable().clear();
when(mqAdminExt.examineBrokerClusterInfo())
.thenThrow(new RuntimeException("examineBrokerClusterInfo exception"))
.thenReturn(null)
.thenReturn(new ClusterInfo())
.thenReturn(clusterInfo)
.thenReturn(MockObjectUtil.createClusterInfo());
when(mqAdmin.getObject()).thenReturn(mqAdminExt);
// exception
Assert.assertFalse(mqAdminPooledObjectFactory.validateObject(mqAdmin));
// clusterInfo == null
Assert.assertFalse(mqAdminPooledObjectFactory.validateObject(mqAdmin));
// clusterInfo.getBrokerAddrTable() == null
Assert.assertFalse(mqAdminPooledObjectFactory.validateObject(mqAdmin));
// clusterInfo.getBrokerAddrTable().size() <= 0
Assert.assertFalse(mqAdminPooledObjectFactory.validateObject(mqAdmin));
// pass validate
Assert.assertTrue(mqAdminPooledObjectFactory.validateObject(mqAdmin));
}
}

View File

@@ -40,6 +40,7 @@ public class RMQConfigureTest {
rmqConfigure.setLoginRequired(true);
rmqConfigure.setMsgTrackTopicName(null);
rmqConfigure.setNamesrvAddr("127.0.0.1:9876");
rmqConfigure.setTimeoutMillis(3000L);
}
@Test
@@ -56,6 +57,7 @@ public class RMQConfigureTest {
Assert.assertTrue(rmqConfigure.isLoginRequired());
Assert.assertEquals(rmqConfigure.getMsgTrackTopicNameOrDefault(), TopicValidator.RMQ_SYS_TRACE_TOPIC);
Assert.assertEquals(rmqConfigure.getNamesrvAddr(), "127.0.0.1:9876");
Assert.assertEquals(rmqConfigure.getTimeoutMillis().longValue(), 3000L);
ErrorPageRegistrar registrar = rmqConfigure.errorPageRegistrar();
registrar.registerErrorPages(new ErrorPageRegistry() {
@Override

View File

@@ -19,14 +19,17 @@ package org.apache.rocketmq.dashboard.controller;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.rocketmq.dashboard.service.checker.RocketMqChecker;
import org.apache.rocketmq.dashboard.service.checker.impl.ClusterHealthCheckerImpl;
import org.apache.rocketmq.dashboard.service.checker.impl.TopicOnlyOneBrokerCheckerImpl;
import org.apache.rocketmq.dashboard.service.impl.OpsServiceImpl;
import org.apache.rocketmq.tools.admin.MQAdminExt;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
@@ -44,6 +47,9 @@ public class OpsControllerTest extends BaseControllerTest {
@Spy
private OpsServiceImpl opsService;
@Mock
private GenericObjectPool<MQAdminExt> mqAdminExtPool;
@Before
public void init() {
super.mockRmqConfigure();
@@ -67,6 +73,7 @@ public class OpsControllerTest extends BaseControllerTest {
final String url = "/ops/updateNameSvrAddr.do";
{
doNothing().when(configure).setNamesrvAddr(anyString());
doNothing().when(mqAdminExtPool).clear();
}
requestBuilder = MockMvcRequestBuilders.post(url);
requestBuilder.param("nameSvrAddrList", "127.0.0.1:9876");
@@ -89,6 +96,20 @@ public class OpsControllerTest extends BaseControllerTest {
.andExpect(jsonPath("$.data").value(true));
}
@Test
public void testUpdateUseTLS() throws Exception {
final String url = "/ops/updateUseTLS.do";
{
doNothing().when(configure).setUseTLS(true);
}
requestBuilder = MockMvcRequestBuilders.post(url);
requestBuilder.param("useTLS", "true");
perform = mockMvc.perform(requestBuilder);
perform.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(true));
}
@Test
public void testClusterStatus() throws Exception {
final String url = "/ops/rocketMqStatus.query";