Merge branch 'develop' into 0.1-release
diff --git a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/LoadBalanceController.java b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/LoadBalanceController.java
index b314aed..4325731 100644
--- a/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/LoadBalanceController.java
+++ b/dubbo-admin-backend/src/main/java/org/apache/dubbo/admin/controller/LoadBalanceController.java
@@ -120,10 +120,10 @@
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public boolean deleteLoadBalance(@PathVariable String id, @PathVariable String env) {
- id = id.replace(Constants.ANY_VALUE, Constants.PATH_SEPARATOR);
if (id == null) {
throw new IllegalArgumentException("Argument of id is null!");
}
+ id = id.replace(Constants.ANY_VALUE, Constants.PATH_SEPARATOR);
overrideService.deleteBalance(id);
return true;
}
diff --git a/dubbo-admin-backend/src/test/java/org/apache/dubbo/admin/AbstractSpringIntegrationTest.java b/dubbo-admin-backend/src/test/java/org/apache/dubbo/admin/AbstractSpringIntegrationTest.java
index 5640c30..074373f 100644
--- a/dubbo-admin-backend/src/test/java/org/apache/dubbo/admin/AbstractSpringIntegrationTest.java
+++ b/dubbo-admin-backend/src/test/java/org/apache/dubbo/admin/AbstractSpringIntegrationTest.java
@@ -21,43 +21,39 @@
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.RetryOneTime;
import org.apache.curator.test.TestingServer;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.web.client.RestTemplate;
-
-import java.io.IOException;
@ActiveProfiles("test")
@RunWith(SpringJUnit4ClassRunner.class)
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@SpringBootTest(classes = DubboAdminApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@ContextConfiguration(classes = DubboAdminApplication.class)
public abstract class AbstractSpringIntegrationTest {
- protected RestTemplate restTemplate = (new TestRestTemplate()).getRestTemplate();
+ @Autowired
+ protected TestRestTemplate restTemplate;
- protected static TestingServer zkServer;
- protected static CuratorFramework zkClient;
+ protected static final TestingServer zkServer;
+ protected static final CuratorFramework zkClient;
- @Value("${local.server.port}")
+ static {
+ try {
+ zkServer = new TestingServer(2182, true);
+ zkClient = CuratorFrameworkFactory.newClient(zkServer.getConnectString(), new RetryOneTime(2000));
+ zkClient.start();
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ @LocalServerPort
protected int port;
- @BeforeClass
- public static void beforeClass() throws Exception {
- zkServer = new TestingServer(2182, true);
- zkClient = CuratorFrameworkFactory.newClient(zkServer.getConnectString(), new RetryOneTime(2000));
- zkClient.start();
- }
-
- @AfterClass
- public static void afterClass() throws IOException {
- zkClient.close();
- zkServer.stop();
- }
-
protected String url(final String path) {
return "http://localhost:" + port + path;
}
diff --git a/dubbo-admin-backend/src/test/java/org/apache/dubbo/admin/controller/LoadBalanceControllerTest.java b/dubbo-admin-backend/src/test/java/org/apache/dubbo/admin/controller/LoadBalanceControllerTest.java
new file mode 100644
index 0000000..fe8878b
--- /dev/null
+++ b/dubbo-admin-backend/src/test/java/org/apache/dubbo/admin/controller/LoadBalanceControllerTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.dubbo.admin.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.dubbo.admin.AbstractSpringIntegrationTest;
+import org.apache.dubbo.admin.model.dto.BalancingDTO;
+import org.apache.dubbo.admin.service.OverrideService;
+import org.apache.dubbo.admin.service.ProviderService;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+
+public class LoadBalanceControllerTest extends AbstractSpringIntegrationTest {
+
+ private final String env = "whatever";
+
+ @MockBean
+ private OverrideService overrideService;
+ @MockBean
+ private ProviderService providerService;
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @Test
+ public void createLoadbalance() throws IOException {
+ BalancingDTO balancingDTO = new BalancingDTO();
+ ResponseEntity<String> response;
+
+ // service and application are all blank
+ response = restTemplate.postForEntity(url("/api/{env}/rules/balancing"), balancingDTO, String.class, env);
+ assertFalse("should return a fail response, when service and application are all blank", (Boolean) objectMapper.readValue(response.getBody(), Map.class).get("success"));
+ // dubbo version is 2.6
+ balancingDTO.setApplication("test application");
+ balancingDTO.setService("test service");
+ when(providerService.findVersionInApplication("test application")).thenReturn("2.6");
+ response = restTemplate.postForEntity(url("/api/{env}/rules/balancing"), balancingDTO, String.class, env);
+ assertFalse("should return a fail response, when dubbo version is 2.6", (Boolean) objectMapper.readValue(response.getBody(), Map.class).get("success"));
+ // dubbo version is 2.7
+ when(providerService.findVersionInApplication("test application")).thenReturn("2.7");
+ response = restTemplate.postForEntity(url("/api/{env}/rules/balancing"), balancingDTO, String.class, env);
+ assertEquals(HttpStatus.CREATED, response.getStatusCode());
+ assertTrue(Boolean.valueOf(response.getBody()));
+ }
+
+ @Test
+ public void updateLoadbalance() throws IOException {
+ String id = "1";
+ BalancingDTO balancingDTO = new BalancingDTO();
+ URI uri;
+ ResponseEntity<String> response;
+ // unknown id
+ response = restTemplate.exchange(url("/api/{env}/rules/balancing/{id}"), HttpMethod.PUT, new HttpEntity<>(balancingDTO, null), String.class, env, id);
+ assertFalse("should return a fail response, when id is null", (Boolean) objectMapper.readValue(response.getBody(), Map.class).get("success"));
+ // valid id
+ BalancingDTO balancing = mock(BalancingDTO.class);
+ when(overrideService.findBalance(id)).thenReturn(balancing);
+ assertTrue(restTemplate.exchange(url("/api/{env}/rules/balancing/{id}"), HttpMethod.PUT, new HttpEntity<>(balancingDTO, null), Boolean.class, env, id).getBody());
+ verify(overrideService).saveBalance(any(BalancingDTO.class));
+ }
+
+ @Test
+ public void searchLoadbalances() throws IOException {
+ String service = "test service", application = "test application";
+ ResponseEntity<String> response;
+ // service and application are all blank
+ response = restTemplate.getForEntity(url("/api/{env}/rules/balancing"), String.class, env);
+ assertFalse("should return a fail response, when service and application are all blank", (Boolean) objectMapper.readValue(response.getBody(), Map.class).get("success"));
+ // service is valid
+ response = restTemplate.getForEntity(url("/api/{env}/rules/balancing?service={service}&application={application}"), String.class, env, service, null);
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ verify(overrideService).findBalance(service);
+ // application is valid
+ response = restTemplate.getForEntity(url("/api/{env}/rules/balancing?service={service}&application={application}"), String.class, env, null, application);
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ verify(overrideService).findBalance(application);
+ // findBalance return a notnull
+ BalancingDTO balancingDTO = new BalancingDTO();
+ when(overrideService.findBalance(anyString())).thenReturn(balancingDTO);
+ response = restTemplate.getForEntity(url("/api/{env}/rules/balancing?service={service}&application={application}"), String.class, env, null, application);
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ assertEquals(1, objectMapper.readValue(response.getBody(), List.class).size());
+ }
+
+ @Test
+ public void detailLoadBalance() throws IOException {
+ String id = "1";
+ ResponseEntity<String> response;
+ // when balancing is not exist
+ response = restTemplate.getForEntity(url("/api/{env}/rules/balancing/{id}"), String.class, env, id);
+ assertFalse("should return a fail response, when id is null", (Boolean) objectMapper.readValue(response.getBody(), Map.class).get("success"));
+ // when balancing is not null
+ BalancingDTO balancingDTO = new BalancingDTO();
+ when(overrideService.findBalance(id)).thenReturn(balancingDTO);
+ response = restTemplate.getForEntity(url("/api/{env}/rules/balancing/{id}"), String.class, env, id);
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ }
+
+ @Test
+ public void deleteLoadBalance() {
+ String id = "1";
+ URI uri;
+ ResponseEntity<String> response;
+
+ response = restTemplate.exchange(url("/api/{env}/rules/balancing/{id}"), HttpMethod.DELETE, new HttpEntity<>(null), String.class, env, id);
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ assertTrue(Boolean.valueOf(response.getBody()));
+ }
+}