[CCSDK-1985]GR Toolkit Refactor
[ccsdk/sli/plugins.git] / grToolkit / provider / src / main / java / org / onap / ccsdk / sli / plugins / grtoolkit / resolver / ThreeNodeHealthResolver.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 org.onap.ccsdk.sli.core.dblib.DbLibService;
25 import org.onap.ccsdk.sli.plugins.grtoolkit.data.AdminHealth;
26 import org.onap.ccsdk.sli.plugins.grtoolkit.data.ClusterActor;
27 import org.onap.ccsdk.sli.plugins.grtoolkit.data.ClusterHealth;
28 import org.onap.ccsdk.sli.plugins.grtoolkit.data.DatabaseHealth;
29 import org.onap.ccsdk.sli.plugins.grtoolkit.data.FailoverStatus;
30 import org.onap.ccsdk.sli.plugins.grtoolkit.data.Health;
31 import org.onap.ccsdk.sli.plugins.grtoolkit.data.SiteHealth;
32
33 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.FailoverInput;
34
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import java.util.Collections;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Properties;
42
43 /**
44  * Implementation of {@code HealthResolver} for a three node controller
45  * architecture, where all nodes are located within the same data center or
46  * geographic region. The nodes are assumed to be in an Active/Active/Active
47  * voting configuration.
48  *
49  * @author Anthony Haddox
50  * @see HealthResolver
51  */
52 public class ThreeNodeHealthResolver extends HealthResolver {
53     private final Logger log = LoggerFactory.getLogger(ThreeNodeHealthResolver.class);
54
55     /**
56      * Constructs the health resolver used by the {@code GrToolkitProvider} to
57      * determine the health of the application components.
58      *
59      * @param map a HashMap containing all of the nodes in the akka cluster
60      * @param properties the properties passed ino the provider
61      * @param dbLib a reference to the {@code DbLibService} of the provider
62      * @see HealthResolver
63      * @see org.onap.ccsdk.sli.plugins.grtoolkit.GrToolkitProvider
64      */
65     public ThreeNodeHealthResolver(Map<String, ClusterActor> map, Properties properties, DbLibService dbLib) {
66         super(map, properties, dbLib);
67         resolveSites();
68     }
69
70     /**
71      * Implementation of {@code getClusterHealth()}. Uses the
72      * {@code ShardResolver} to gather health information about the controller.
73      * If 2 of 3 members are healthy, the cluster is deemed healthy.
74      *
75      * @return an {@code ClusterHealth} object with health of the akka cluster
76      * @see org.onap.ccsdk.sli.plugins.grtoolkit.GrToolkitProvider
77      * @see HealthResolver
78      * @see ClusterHealth
79      * @see ShardResolver
80      */
81     @Override
82     public ClusterHealth getClusterHealth() {
83         log.info("getClusterHealth(): Getting cluster health...");
84         shardResolver.getControllerHealth(memberMap);
85         long healthyMembers = memberMap.values().stream().filter(member -> member.isUp() && ! member.isUnreachable()).count();
86         return (healthyMembers > 1) ? new ClusterHealth().withHealth(Health.HEALTHY) : new ClusterHealth().withHealth(Health.FAULTY);
87     }
88
89     /**
90      * Implementation of {@code getSiteHealth()}. Uses the results from
91      * {@code getAdminHealth}, {@code getDatabaseHealth}, and
92      * {@code getClusterHealth} to determine the health of the site. If all
93      * components are healthy, the site is healthy.
94      *
95      * @return a List of {@code SiteHealth} objects with health of the site
96      * @see org.onap.ccsdk.sli.plugins.grtoolkit.GrToolkitProvider
97      * @see HealthResolver
98      * @see SiteHealth
99      * @see ShardResolver
100      */
101     @Override
102     public List<SiteHealth> getSiteHealth() {
103         log.info("getSiteHealth(): Getting site health...");
104         AdminHealth adminHealth = getAdminHealth();
105         DatabaseHealth databaseHealth = getDatabaseHealth();
106         ClusterHealth clusterHealth = getClusterHealth();
107         SiteHealth siteHealth = new SiteHealth()
108                                         .withAdminHealth(adminHealth)
109                                         .withDatabaseHealth(databaseHealth)
110                                         .withClusterHealth(clusterHealth)
111                                         .withRole("ACTIVE")
112                                         .withId(getSiteIdentifier());
113         log.info("getSiteHealth(): Admin Health: {}", adminHealth.getHealth().toString());
114         log.info("getSiteHealth(): Database Health: {}", databaseHealth.getHealth().toString());
115         log.info("getSiteHealth(): Cluster Health: {}", clusterHealth.getHealth().toString());
116         if(isHealthy(adminHealth.getHealth()) && isHealthy(databaseHealth.getHealth()) && isHealthy(clusterHealth.getHealth())) {
117             siteHealth.setHealth(Health.HEALTHY);
118         }
119
120         return Collections.singletonList(siteHealth);
121     }
122
123     /**
124      * Implementation of {@code tryFailover()}. No controller-level failover
125      * options are available in a three node architecture, so 400 Bad Request
126      * is returned, and no action is taken.
127      *
128      * @return an {@code SiteHealth} object with health of the site
129      * @see org.onap.ccsdk.sli.plugins.grtoolkit.GrToolkitProvider
130      * @see HealthResolver
131      * @see FailoverStatus
132      * @see FailoverInput
133      */
134     @Override
135     public FailoverStatus tryFailover(FailoverInput input) {
136         log.info("tryFailover(): Failover not supported in the current configuration.");
137         return new FailoverStatus().withStatusCode(400).withMessage("Failover not supported in current configuration.");
138     }
139
140     /**
141      * Implementation of {@code resolveSites()}. Calls
142      * {@code resolveSiteForMember()} to resolve which site a member belongs to.
143      *
144      * @see HealthResolver
145      */
146     @Override
147     public void resolveSites() {
148         log.info("Map contains {} entries", memberMap.size());
149         memberMap.forEach((key, value) -> resolveSiteForMember(value));
150     }
151
152     /**
153      * Resolves which site a member belongs to. Since this is a three node
154      * co-located architecture, it is defaulted to <i>Site 1</i>.
155      *
156      * @see HealthResolver
157      */
158     private void resolveSiteForMember(ClusterActor actor) {
159         actor.setSite("Site 1");
160         log.info("resolveSiteForMember(): {} belongs to {}", actor.getNode(), actor.getSite());
161     }
162 }