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 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;
33 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.FailoverInput;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
38 import java.util.Collections;
39 import java.util.List;
41 import java.util.Properties;
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.
49 * @author Anthony Haddox
52 public class ThreeNodeHealthResolver extends HealthResolver {
53 private final Logger log = LoggerFactory.getLogger(ThreeNodeHealthResolver.class);
56 * Constructs the health resolver used by the {@code GrToolkitProvider} to
57 * determine the health of the application components.
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
63 * @see org.onap.ccsdk.sli.plugins.grtoolkit.GrToolkitProvider
65 public ThreeNodeHealthResolver(Map<String, ClusterActor> map, Properties properties, DbLibService dbLib) {
66 super(map, properties, dbLib);
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.
75 * @return an {@code ClusterHealth} object with health of the akka cluster
76 * @see org.onap.ccsdk.sli.plugins.grtoolkit.GrToolkitProvider
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);
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.
95 * @return a List of {@code SiteHealth} objects with health of the site
96 * @see org.onap.ccsdk.sli.plugins.grtoolkit.GrToolkitProvider
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)
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);
120 return Collections.singletonList(siteHealth);
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.
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
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.");
141 * Implementation of {@code resolveSites()}. Calls
142 * {@code resolveSiteForMember()} to resolve which site a member belongs to.
144 * @see HealthResolver
147 public void resolveSites() {
148 log.info("Map contains {} entries", memberMap.size());
149 memberMap.forEach((key, value) -> resolveSiteForMember(value));
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>.
156 * @see HealthResolver
158 private void resolveSiteForMember(ClusterActor actor) {
159 actor.setSite("Site 1");
160 log.info("resolveSiteForMember(): {} belongs to {}", actor.getNode(), actor.getSite());