[CCSDK-1985]GR Toolkit Refactor
[ccsdk/sli/plugins.git] / grToolkit / provider / src / test / java / org / onap / ccsdk / sli / plugins / grtoolkit / resolver / SixNodeHealthResolverTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights
6  *                      reserved.
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
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
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=========================================================
20  */
21
22 package org.onap.ccsdk.sli.plugins.grtoolkit.resolver;
23
24 import com.github.tomakehurst.wiremock.junit.WireMockRule;
25
26 import org.junit.Before;
27 import org.junit.Rule;
28 import org.junit.Test;
29
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;
39
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;
47 import java.util.Map;
48 import java.util.Properties;
49 import java.util.stream.Collectors;
50 import java.util.stream.Stream;
51
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;
57
58 import static org.junit.Assert.*;
59
60 import static org.mockito.Mockito.mock;
61 import static org.mockito.Mockito.when;
62
63 public class SixNodeHealthResolverTest {
64     private Map<String, ClusterActor> memberMap;
65     private DbLibService dbLibService;
66     private DBLibConnection connection;
67     private SixNodeHealthResolver resolver;
68
69     @Rule
70     public WireMockRule wireMockRule = new WireMockRule(9999);
71
72     @Before
73     public void setUp() {
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) {
79             fail();
80         }
81
82         dbLibService = mock(DbLibService.class);
83         connection = mock(DBLibConnection.class);
84         resolver = new SixNodeHealthResolver(memberMap, properties, dbLibService);
85     }
86
87     private Map<String, ClusterActor> generateMemberMap(int memberCount) {
88         Map<String, ClusterActor> map = new HashMap<>();
89         ClusterActor actor;
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));
95             actor.setUp(true);
96             actor.setUnreachable(false);
97
98             map.put(actor.getNode(),  actor);
99         }
100         return map;
101     }
102
103     @Test
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());
110     }
111
112     @Test
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());
119     }
120
121     @Test
122     public void getDatabaseHealth() {
123         try {
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) {
129             fail();
130         }
131         DatabaseHealth health = resolver.getDatabaseHealth();
132         assertEquals(Health.HEALTHY, health.getHealth());
133     }
134
135     @Test
136     public void getDatabaseHealthFaulty() {
137         try {
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) {
143             fail();
144         }
145         DatabaseHealth health = resolver.getDatabaseHealth();
146         assertEquals(Health.FAULTY, health.getHealth());
147     }
148
149     @Test
150     public void getDatabaseHealthException() {
151         try {
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) {
157             fail();
158         }
159         DatabaseHealth health = resolver.getDatabaseHealth();
160         assertEquals(Health.FAULTY, health.getHealth());
161     }
162
163     @Test
164     public void siteIdentifier() {
165         assertEquals("TestODL", resolver.getSiteIdentifier());
166         resolver.setSiteIdentifier("NewTestODL");
167         assertEquals("NewTestODL", resolver.getSiteIdentifier());
168     }
169
170     @Test
171     public void getClusterHealth() {
172         stubController();
173         ClusterHealth health = resolver.getClusterHealth();
174         assertEquals(Health.HEALTHY, health.getHealth());
175     }
176
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) {
187             fail();
188         }
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) {
192             fail();
193         }
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) {
197             fail();
198         }
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) {
202             fail();
203         }
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) {
207             fail();
208         }
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) {
212             fail();
213         }
214
215         if(clusterBody == null || shardManagerBody == null || shardDefaultBody == null || shardOperationalBody == null
216             || componentBody == null || identifierBody == null) {
217             fail();
218         }
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)));
226     }
227
228     @Test
229     public void getSiteHealth() {
230         stubController();
231         stubFor(get(urlEqualTo("/adm/healthcheck")).willReturn(aResponse().withStatus(200)));
232         try {
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) {
238             fail();
239         }
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());
245     }
246
247     @Test
248     public void getSiteHealthFaulty() {
249         stubController();
250         stubFor(get(urlEqualTo("/adm/healthcheck")).willReturn(aResponse().withStatus(200)));
251         try {
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) {
257             fail();
258         }
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());
265     }
266
267     @Test
268     public void getSiteHealthFaultyShard() {
269         stubController();
270         stubFor(get(urlEqualTo("/adm/healthcheck")).willReturn(aResponse().withStatus(200)));
271         try {
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) {
277             fail();
278         }
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());
285     }
286
287     @Test
288     public void getSiteHealthFaultyCluster() {
289         stubController();
290         stubFor(get(urlEqualTo("/adm/healthcheck")).willReturn(aResponse().withStatus(200)));
291         try {
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) {
297             fail();
298         }
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());
305     }
306
307     @Test
308     public void getSiteHealthFaultyAdmin() {
309         stubController();
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")));
312         try {
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) {
318             fail();
319         }
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());
326     }
327
328     @Test
329     public void tryFailover() {
330         stubController();
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());
334     }
335 }