2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.be.switchover.detector;
23 import com.google.common.annotations.VisibleForTesting;
24 import org.apache.http.entity.ContentType;
25 import org.apache.http.entity.StringEntity;
26 import org.openecomp.sdc.be.config.BeEcompErrorManager;
27 import org.openecomp.sdc.be.config.Configuration.SwitchoverDetectorConfig;
28 import org.openecomp.sdc.be.config.ConfigurationManager;
29 import org.openecomp.sdc.common.http.client.api.HttpRequest;
30 import org.openecomp.sdc.common.log.wrappers.Logger;
31 import org.springframework.stereotype.Component;
33 import javax.annotation.PostConstruct;
34 import javax.annotation.PreDestroy;
35 import java.net.InetAddress;
36 import java.util.Properties;
37 import java.util.concurrent.ExecutorService;
38 import java.util.concurrent.Executors;
39 import java.util.concurrent.ScheduledExecutorService;
40 import java.util.concurrent.ScheduledFuture;
41 import java.util.concurrent.ThreadFactory;
42 import java.util.concurrent.TimeUnit;
44 @Component("switchover-detector")
45 public class SwitchoverDetector {
47 protected static String SWITCHOVER_DETECTOR_LOG_CONTEXT = "switchover.detector";
49 private SwitchoverDetectorConfig switchoverDetectorConfig;
51 private Properties authHeader = null;
53 private long detectorInterval = 60;
55 private int maxBeQueryAttempts = 3;
57 private int maxFeQueryAttempts = 3;
59 private Boolean beMatch = null;
61 private Boolean feMatch = null;
63 private static final Logger logger = Logger.getLogger(SwitchoverDetector.class);
65 private volatile String siteMode = SwitchoverDetectorState.UNKNOWN.getState();
67 private ScheduledFuture<?> scheduledFuture = null;
69 ScheduledExecutorService switchoverDetectorScheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
71 public Thread newThread(Runnable r) {
72 return new Thread(r, "Switchover-Detector-Task");
76 SwitchoverDetectorScheduledTask switchoverDetectorScheduledTask = null;
78 public enum SwitchoverDetectorState {
80 UNKNOWN("unknown"), ACTIVE("active"), STANDBY("standby");
84 SwitchoverDetectorState(String state) {
88 public String getState() {
93 public enum SwitchoverDetectorGroup {
95 BE_SET("beSet"), FE_SET("feSet");
99 SwitchoverDetectorGroup(String group) {
103 public String getGroup() {
108 public String getSiteMode() {
112 public void setSiteMode(String mode) {
113 this.siteMode = mode;
116 private Boolean queryBe() {
117 return queryGss(switchoverDetectorConfig.getgBeFqdn(), switchoverDetectorConfig.getBeVip(), maxBeQueryAttempts);
120 private Boolean queryFe() {
121 return queryGss(switchoverDetectorConfig.getgFeFqdn(), switchoverDetectorConfig.getFeVip(), maxFeQueryAttempts);
124 private void initializeSiteMode() {
125 while (siteMode.equals(SwitchoverDetectorState.UNKNOWN.getState())) {
130 if (beMatch == feMatch && beMatch != null) {
132 setSiteMode(SwitchoverDetectorState.ACTIVE.getState());
134 setSiteMode(SwitchoverDetectorState.STANDBY.getState());
140 private Boolean queryGss(String fqdn, String vip, int maxAttempts) {
142 Boolean result = null;
145 while (result == null && (++attempts < maxAttempts)) {
147 InetAddress inetAddress = InetAddress.getByName(fqdn);
148 result = inetAddress.getHostAddress().equals(vip);
150 } catch (Exception e) {
151 String message = e.getMessage();
152 if (message == null) {
153 message = e.getClass().getName();
155 logger.debug("Error occured during switchover detector query, Result is {}", message, e);
158 if (null == result) {
159 BeEcompErrorManager.getInstance().logFqdnResolveError(SWITCHOVER_DETECTOR_LOG_CONTEXT, "host " + fqdn + " not resolved after " + attempts + " attempts");
164 public class SwitchoverDetectorScheduledTask implements Runnable {
166 public SwitchoverDetectorScheduledTask() {
172 logger.trace("Executing Switchover Detector Task - Start");
174 initializeSiteMode();
176 Boolean beRes = queryBe();
177 Boolean feRes = queryFe();
179 if (null == beRes || null == feRes) {
183 Boolean updateRequired = siteMode.equals(SwitchoverDetectorState.STANDBY.getState()) && (beRes || feRes) && (beMatch != beRes || feMatch != feRes);
184 Boolean prevModeStandby = siteMode.equals(SwitchoverDetectorState.STANDBY.getState());
186 updateSiteModeAndPriority(beRes && feRes, prevModeStandby, updateRequired);
192 ExecutorService switchoverDetectorExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
194 public Thread newThread(Runnable r) {
195 return new Thread(r, "Switchover-Detector-Thread");
199 private void updateSiteModeAndPriority(Boolean bothMatch, Boolean previousModeStandby, Boolean updateRequired) {
200 if (bothMatch && previousModeStandby) {
201 logger.trace("Site switch over was done. Site is now in active mode");
202 setSiteMode(SwitchoverDetectorState.ACTIVE.getState());
203 BeEcompErrorManager.getInstance().logSiteSwitchoverInfo(SWITCHOVER_DETECTOR_LOG_CONTEXT, siteMode);
204 } else if (!bothMatch && !previousModeStandby) {
205 logger.trace("Site switch over was done. Site is now in stand-by mode");
206 setSiteMode(SwitchoverDetectorState.STANDBY.getState());
207 BeEcompErrorManager.getInstance().logSiteSwitchoverInfo(SWITCHOVER_DETECTOR_LOG_CONTEXT, siteMode);
209 if (updateRequired) {
210 changeSitePriority(SwitchoverDetectorGroup.BE_SET.getGroup());
211 changeSitePriority(SwitchoverDetectorGroup.FE_SET.getGroup());
216 private void changeSitePriority(String groupToSet) {
218 String url = switchoverDetectorConfig.getGroups().get(groupToSet).getChangePriorityUrl();
219 String body = switchoverDetectorConfig.getGroups().get(groupToSet).getChangePriorityBody();
222 HttpRequest.put(url, authHeader, new StringEntity(body, ContentType.APPLICATION_JSON));
223 } catch (Exception e) {
224 String message = e.getMessage();
225 if (message == null) {
226 message = e.getClass().getName();
228 logger.debug("Error occured during change site priority request, Result is {}", message, e);
233 private void publishNetwork() {
235 String url = switchoverDetectorConfig.getPublishNetworkUrl();
236 String body = switchoverDetectorConfig.getPublishNetworkBody();
238 HttpRequest.post(url, authHeader, new StringEntity(body, ContentType.APPLICATION_JSON));
239 } catch (Exception e) {
240 String message = e.getMessage();
241 if (message == null) {
242 message = e.getClass().getName();
244 logger.debug("Error occured during publish network request, Result is {}", message, e);
251 void setSwitchoverDetectorConfig(SwitchoverDetectorConfig switchoverDetectorConfig) {
252 this.switchoverDetectorConfig = switchoverDetectorConfig;
256 private void init() {
257 logger.info("Enter init method of SwitchoverDetector");
259 switchoverDetectorConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getSwitchoverDetector();
261 if (!switchoverDetectorConfig.getEnabled()) {
262 logger.info("switchover detector service is disabled");
266 Long detectorIntervalConfig = switchoverDetectorConfig.getInterval();
267 if (detectorIntervalConfig != null) {
268 detectorInterval = detectorIntervalConfig.longValue();
271 Integer maxAttempts = switchoverDetectorConfig.getBeResolveAttempts();
272 if (maxAttempts != null) {
273 maxBeQueryAttempts = maxAttempts.intValue();
275 maxAttempts = switchoverDetectorConfig.getFeResolveAttempts();
276 if (maxAttempts != null) {
277 maxFeQueryAttempts = maxAttempts.intValue();
280 logger.info("switchover detector service is enabled, interval is {} seconds", detectorInterval);
282 this.switchoverDetectorScheduledTask = new SwitchoverDetectorScheduledTask();
283 startSwitchoverDetectorTask();
284 logger.trace("Exit init method of SwitchoverDetector");
289 private void destroy() {
291 if (scheduledFuture != null) {
292 scheduledFuture.cancel(true);
293 scheduledFuture = null;
296 if (switchoverDetectorScheduler != null) {
297 switchoverDetectorScheduler.shutdown();
302 public void startSwitchoverDetectorTask() {
303 if (this.scheduledFuture == null) {
304 this.scheduledFuture = this.switchoverDetectorScheduler.scheduleAtFixedRate(switchoverDetectorScheduledTask, 0, detectorInterval, TimeUnit.SECONDS);