2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.sli.plugins.grtoolkit.resolver;
24 import com.github.tomakehurst.wiremock.junit.WireMockRule;
26 import org.junit.Before;
27 import org.junit.Rule;
28 import org.junit.Test;
30 import org.onap.ccsdk.sli.core.dblib.DBLibConnection;
31 import org.onap.ccsdk.sli.core.dblib.DbLibService;
32 import org.onap.ccsdk.sli.plugins.grtoolkit.data.AdminHealth;
33 import org.onap.ccsdk.sli.plugins.grtoolkit.data.ClusterActor;
34 import org.onap.ccsdk.sli.plugins.grtoolkit.data.ClusterHealth;
35 import org.onap.ccsdk.sli.plugins.grtoolkit.data.DatabaseHealth;
36 import org.onap.ccsdk.sli.plugins.grtoolkit.data.FailoverStatus;
37 import org.onap.ccsdk.sli.plugins.grtoolkit.data.Health;
38 import org.onap.ccsdk.sli.plugins.grtoolkit.data.SiteHealth;
40 import java.io.FileInputStream;
41 import java.io.IOException;
42 import java.nio.file.Files;
43 import java.nio.file.Paths;
44 import java.sql.SQLException;
45 import java.util.HashMap;
46 import java.util.List;
48 import java.util.Properties;
49 import java.util.stream.Collectors;
50 import java.util.stream.Stream;
52 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
53 import static com.github.tomakehurst.wiremock.client.WireMock.get;
54 import static com.github.tomakehurst.wiremock.client.WireMock.post;
55 import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
56 import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
58 import static org.junit.Assert.*;
60 import static org.mockito.Mockito.mock;
61 import static org.mockito.Mockito.when;
63 public class SixNodeHealthResolverTest {
64 private Map<String, ClusterActor> memberMap;
65 private DbLibService dbLibService;
66 private DBLibConnection connection;
67 private SixNodeHealthResolver resolver;
70 public WireMockRule wireMockRule = new WireMockRule(9999);
74 memberMap = generateMemberMap(6);
75 Properties properties = new Properties();
76 try(FileInputStream fileInputStream = new FileInputStream("src/test/resources/six/gr-toolkit.properties")) {
77 properties.load(fileInputStream);
78 } catch(IOException e) {
82 dbLibService = mock(DbLibService.class);
83 connection = mock(DBLibConnection.class);
84 resolver = new SixNodeHealthResolver(memberMap, properties, dbLibService);
87 private Map<String, ClusterActor> generateMemberMap(int memberCount) {
88 Map<String, ClusterActor> map = new HashMap<>();
90 for(int ndx = 0; ndx < memberCount; ndx++) {
91 actor = new ClusterActor();
92 actor.setNode("127.0.1." + (ndx + 1));
93 actor.setAkkaPort("2550");
94 actor.setMember("member-" + (ndx + 1));
96 actor.setUnreachable(false);
98 map.put(actor.getNode(), actor);
104 public void getAdminHealthFaulty() {
105 stubFor(get(urlEqualTo("/adm/healthcheck")).willReturn(aResponse().withStatus(500)));
106 AdminHealth health = resolver.getAdminHealth();
107 assertNotNull(health);
108 assertEquals(500, health.getStatusCode());
109 assertEquals(Health.FAULTY, health.getHealth());
113 public void getAdminHealthHealthy() {
114 stubFor(get(urlEqualTo("/adm/healthcheck")).willReturn(aResponse().withStatus(200)));
115 AdminHealth health = resolver.getAdminHealth();
116 assertNotNull(health);
117 assertEquals(200, health.getStatusCode());
118 assertEquals(Health.HEALTHY, health.getHealth());
122 public void getDatabaseHealth() {
124 when(connection.isReadOnly()).thenReturn(false);
125 when(connection.isClosed()).thenReturn(false);
126 when(dbLibService.isActive()).thenReturn(true);
127 when(dbLibService.getConnection()).thenReturn(connection);
128 } catch(SQLException e) {
131 DatabaseHealth health = resolver.getDatabaseHealth();
132 assertEquals(Health.HEALTHY, health.getHealth());
136 public void getDatabaseHealthFaulty() {
138 when(connection.isReadOnly()).thenReturn(true);
139 when(connection.isClosed()).thenReturn(true);
140 when(dbLibService.isActive()).thenReturn(false);
141 when(dbLibService.getConnection()).thenReturn(connection);
142 } catch(SQLException e) {
145 DatabaseHealth health = resolver.getDatabaseHealth();
146 assertEquals(Health.FAULTY, health.getHealth());
150 public void getDatabaseHealthException() {
152 when(connection.isReadOnly()).thenThrow(new SQLException());
153 when(connection.isClosed()).thenReturn(true);
154 when(dbLibService.isActive()).thenReturn(false);
155 when(dbLibService.getConnection()).thenReturn(connection);
156 } catch(SQLException e) {
159 DatabaseHealth health = resolver.getDatabaseHealth();
160 assertEquals(Health.FAULTY, health.getHealth());
164 public void siteIdentifier() {
165 assertEquals("TestODL", resolver.getSiteIdentifier());
166 resolver.setSiteIdentifier("NewTestODL");
167 assertEquals("NewTestODL", resolver.getSiteIdentifier());
171 public void getClusterHealth() {
173 ClusterHealth health = resolver.getClusterHealth();
174 assertEquals(Health.HEALTHY, health.getHealth());
177 private void stubController() {
178 String clusterBody = null;
179 String shardManagerBody = null;
180 String shardDefaultBody = null;
181 String shardOperationalBody = null;
182 String componentBody = null;
183 String identifierBody = null;
184 try(Stream<String> stream = Files.lines(Paths.get("src/test/resources/six/cluster.json"))) {
185 clusterBody = stream.collect(Collectors.joining());
186 } catch(IOException e) {
189 try(Stream<String> stream = Files.lines(Paths.get("src/test/resources/six/shard-manager.json"))) {
190 shardManagerBody = stream.collect(Collectors.joining());
191 } catch(IOException e) {
194 try(Stream<String> stream = Files.lines(Paths.get("src/test/resources/six/default-config.json"))) {
195 shardDefaultBody = stream.collect(Collectors.joining());
196 } catch(IOException e) {
199 try(Stream<String> stream = Files.lines(Paths.get("src/test/resources/six/default-operational.json"))) {
200 shardOperationalBody = stream.collect(Collectors.joining());
201 } catch(IOException e) {
204 try(Stream<String> stream = Files.lines(Paths.get("src/test/resources/six/component-health.json"))) {
205 componentBody = stream.collect(Collectors.joining());
206 } catch(IOException e) {
209 try(Stream<String> stream = Files.lines(Paths.get("src/test/resources/six/site-identifier.json"))) {
210 identifierBody = stream.collect(Collectors.joining());
211 } catch(IOException e) {
215 if(clusterBody == null || shardManagerBody == null || shardDefaultBody == null || shardOperationalBody == null
216 || componentBody == null || identifierBody == null) {
219 stubFor(get(urlEqualTo("/jolokia/read/akka:type=Cluster")).willReturn(aResponse().withStatus(200).withBody(clusterBody)));
220 stubFor(get(urlEqualTo("/jolokia/read/org.opendaylight.controller:Category=ShardManager,name=shard-manager-config,type=DistributedConfigDatastore")).inScenario("testing").willReturn(aResponse().withStatus(200).withBody(shardManagerBody)).willSetStateTo("next"));
221 stubFor(get(urlEqualTo("/jolokia/read/org.opendaylight.controller:Category=Shards,name=member-1-shard-default-config,type=DistributedConfigDatastore")).inScenario("testing").willReturn(aResponse().withStatus(200).withBody(shardDefaultBody)).willSetStateTo("next"));
222 stubFor(get(urlEqualTo("/jolokia/read/org.opendaylight.controller:Category=Shards,name=member-1-shard-default-operational,type=DistributedOperationalDatastore")).willReturn(aResponse().withStatus(200).withBody(shardOperationalBody)));
223 stubFor(post(urlEqualTo("/restconf/operations/gr-toolkit:site-identifier")).willReturn(aResponse().withStatus(200).withBody(identifierBody)));
224 stubFor(post(urlEqualTo("/restconf/operations/gr-toolkit:admin-health")).inScenario("testing").willReturn(aResponse().withStatus(200).withBody(componentBody)).willSetStateTo("next"));
225 stubFor(post(urlEqualTo("/restconf/operations/gr-toolkit:database-health")).willReturn(aResponse().withStatus(200).withBody(componentBody)));
229 public void getSiteHealth() {
231 stubFor(get(urlEqualTo("/adm/healthcheck")).willReturn(aResponse().withStatus(200)));
233 when(connection.isReadOnly()).thenReturn(false);
234 when(connection.isClosed()).thenReturn(false);
235 when(dbLibService.isActive()).thenReturn(true);
236 when(dbLibService.getConnection()).thenReturn(connection);
237 } catch(SQLException e) {
240 List<SiteHealth> health = resolver.getSiteHealth();
241 assertNotNull(health);
242 assertNotEquals(0, health.size());
243 assertEquals(2, health.size());
244 assertEquals(Health.HEALTHY, health.get(0).getHealth());
248 public void getSiteHealthFaulty() {
250 stubFor(get(urlEqualTo("/adm/healthcheck")).willReturn(aResponse().withStatus(200)));
252 when(connection.isReadOnly()).thenReturn(false);
253 when(connection.isClosed()).thenReturn(false);
254 when(dbLibService.isActive()).thenReturn(true);
255 when(dbLibService.getConnection()).thenReturn(connection);
256 } catch(SQLException e) {
259 stubFor(get(urlEqualTo("/jolokia/read/org.opendaylight.controller:Category=ShardManager,name=shard-manager-config,type=DistributedConfigDatastore")).inScenario("testing").whenScenarioStateIs("next").willReturn(aResponse().withBodyFile("nonexistent")));
260 List<SiteHealth> health = resolver.getSiteHealth();
261 assertNotNull(health);
262 assertNotEquals(0, health.size());
263 assertEquals(2, health.size());
264 assertEquals(Health.FAULTY, health.get(0).getHealth());
268 public void getSiteHealthFaultyShard() {
270 stubFor(get(urlEqualTo("/adm/healthcheck")).willReturn(aResponse().withStatus(200)));
272 when(connection.isReadOnly()).thenReturn(false);
273 when(connection.isClosed()).thenReturn(false);
274 when(dbLibService.isActive()).thenReturn(true);
275 when(dbLibService.getConnection()).thenReturn(connection);
276 } catch(SQLException e) {
279 stubFor(get(urlEqualTo("/jolokia/read/org.opendaylight.controller:Category=Shards,name=member-1-shard-default-config,type=DistributedConfigDatastore")).inScenario("testing").willReturn(aResponse().withBodyFile("nonexistent")).willSetStateTo("next"));
280 List<SiteHealth> health = resolver.getSiteHealth();
281 assertNotNull(health);
282 assertNotEquals(0, health.size());
283 assertEquals(2, health.size());
284 assertEquals(Health.FAULTY, health.get(0).getHealth());
288 public void getSiteHealthFaultyCluster() {
290 stubFor(get(urlEqualTo("/adm/healthcheck")).willReturn(aResponse().withStatus(200)));
292 when(connection.isReadOnly()).thenReturn(false);
293 when(connection.isClosed()).thenReturn(false);
294 when(dbLibService.isActive()).thenReturn(true);
295 when(dbLibService.getConnection()).thenReturn(connection);
296 } catch(SQLException e) {
299 stubFor(get(urlEqualTo("/jolokia/read/akka:type=Cluster")).willReturn(aResponse().withStatus(200).withBodyFile("nonexistent")));
300 List<SiteHealth> health = resolver.getSiteHealth();
301 assertNotNull(health);
302 assertNotEquals(0, health.size());
303 assertEquals(2, health.size());
304 assertEquals(Health.FAULTY, health.get(0).getHealth());
308 public void getSiteHealthFaultyAdmin() {
310 stubFor(post(urlEqualTo("/restconf/operations/gr-toolkit:admin-health")).inScenario("testing").willReturn(aResponse().withBodyFile("nonexistent")).willSetStateTo("next"));
311 stubFor(get(urlEqualTo("/restconf/operations/gr-toolkit:admin-health")).inScenario("testing").whenScenarioStateIs("next").willReturn(aResponse().withBodyFile("nonexistent")));
313 when(connection.isReadOnly()).thenReturn(false);
314 when(connection.isClosed()).thenReturn(false);
315 when(dbLibService.isActive()).thenReturn(true);
316 when(dbLibService.getConnection()).thenReturn(connection);
317 } catch(SQLException e) {
320 List<SiteHealth> health = resolver.getSiteHealth();
321 assertNotNull(health);
322 assertNotEquals(0, health.size());
323 assertEquals(2, health.size());
324 assertEquals(Health.FAULTY, health.get(0).getHealth());
325 assertEquals(Health.FAULTY, health.get(1).getHealth());
329 public void tryFailover() {
331 stubFor(get(urlEqualTo("/restconf/operations/cluster-admin:change-member-voting-states-for-all-shards")).willReturn(aResponse().withStatus(200)));
332 FailoverStatus status = resolver.tryFailover(null);
333 assertEquals(500, status.getStatusCode());