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 org.apache.commons.codec.binary.Base64;
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.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import org.springframework.stereotype.Component;
34 import javax.annotation.PostConstruct;
35 import javax.annotation.PreDestroy;
36 import java.net.InetAddress;
37 import java.util.Properties;
38 import java.util.concurrent.ExecutorService;
39 import java.util.concurrent.Executors;
40 import java.util.concurrent.ScheduledExecutorService;
41 import java.util.concurrent.ScheduledFuture;
42 import java.util.concurrent.ThreadFactory;
43 import java.util.concurrent.TimeUnit;
45 @Component("switchover-detector")
46 public class SwitchoverDetector {
48 protected static String SWITCHOVER_DETECTOR_LOG_CONTEXT = "switchover.detector";
50 private static final Logger switchoverLogger = LoggerFactory.getLogger(SWITCHOVER_DETECTOR_LOG_CONTEXT);
52 private SwitchoverDetectorConfig switchoverDetectorConfig;
54 private Properties authHeader = null;
56 private long detectorInterval = 60;
58 private int maxBeQueryAttempts = 3;
60 private int maxFeQueryAttempts = 3;
62 private Boolean beMatch = null;
64 private Boolean feMatch = null;
66 private static final Logger logger = LoggerFactory.getLogger(SwitchoverDetector.class);
68 private volatile String siteMode = SwitchoverDetectorState.UNKNOWN.getState();
70 private ScheduledFuture<?> scheduledFuture = null;
72 ScheduledExecutorService switchoverDetectorScheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
74 public Thread newThread(Runnable r) {
75 return new Thread(r, "Switchover-Detector-Task");
79 SwitchoverDetectorScheduledTask switchoverDetectorScheduledTask = null;
81 public enum SwitchoverDetectorState {
83 UNKNOWN("unknown"), ACTIVE("active"), STANDBY("standby");
87 SwitchoverDetectorState(String state) {
91 public String getState() {
96 public enum SwitchoverDetectorGroup {
98 BE_SET("beSet"), FE_SET("feSet");
100 private String group;
102 SwitchoverDetectorGroup(String group) {
106 public String getGroup() {
111 public String getSiteMode() {
115 public void setSiteMode(String mode) {
116 this.siteMode = mode;
119 private Boolean queryBe() {
120 return queryGss(switchoverDetectorConfig.getgBeFqdn(), switchoverDetectorConfig.getBeVip(), maxBeQueryAttempts);
123 private Boolean queryFe() {
124 return queryGss(switchoverDetectorConfig.getgFeFqdn(), switchoverDetectorConfig.getFeVip(), maxFeQueryAttempts);
127 private void setAuthorizationProperties() {
128 String userInfo = switchoverDetectorConfig.getChangePriorityUser() + ":" + switchoverDetectorConfig.getChangePriorityPassword();
129 String auth = "Basic " + new String(new Base64().encode(userInfo.getBytes()));
130 authHeader = new Properties();
131 authHeader.put("Authorization", auth);
134 private void initializeSiteMode() {
135 while (siteMode.equals(SwitchoverDetectorState.UNKNOWN.getState())) {
140 if (beMatch == feMatch && beMatch != null) {
142 setSiteMode(SwitchoverDetectorState.ACTIVE.getState());
144 setSiteMode(SwitchoverDetectorState.STANDBY.getState());
150 private Boolean queryGss(String fqdn, String vip, int maxAttempts) {
152 Boolean result = null;
155 while (result == null && (++attempts < maxAttempts)) {
157 InetAddress inetAddress = InetAddress.getByName(fqdn);
158 result = inetAddress.getHostAddress().equals(vip);
160 } catch (Exception e) {
161 String message = e.getMessage();
162 if (message == null) {
163 message = e.getClass().getName();
165 logger.debug("Error occured during switchover detector query, Result is {}", message, e);
168 if (null == result) {
169 BeEcompErrorManager.getInstance().logFqdnResolveError(SWITCHOVER_DETECTOR_LOG_CONTEXT, "host " + fqdn + " not resolved after " + attempts + " attempts");
174 public class SwitchoverDetectorScheduledTask implements Runnable {
176 public SwitchoverDetectorScheduledTask() {
182 logger.trace("Executing Switchover Detector Task - Start");
184 initializeSiteMode();
186 Boolean beRes = queryBe();
187 Boolean feRes = queryFe();
189 if (null == beRes || null == feRes) {
193 Boolean updateRequired = siteMode == SwitchoverDetectorState.STANDBY.getState() && (beRes || feRes) && (beMatch != beRes || feMatch != feRes);
195 updateSiteModeAndPriority(beRes && feRes, siteMode == SwitchoverDetectorState.STANDBY.getState(), updateRequired);
201 ExecutorService switchoverDetectorExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
203 public Thread newThread(Runnable r) {
204 return new Thread(r, "Switchover-Detector-Thread");
208 private void updateSiteModeAndPriority(Boolean bothMatch, Boolean previousModeStandby, Boolean updateRequired) {
209 if (bothMatch && previousModeStandby) {
210 logger.trace("Site switch over was done. Site is now in active mode");
211 setSiteMode(SwitchoverDetectorState.ACTIVE.getState());
212 BeEcompErrorManager.getInstance().logSiteSwitchoverInfo(SWITCHOVER_DETECTOR_LOG_CONTEXT, siteMode);
213 } else if (!bothMatch && !previousModeStandby) {
214 logger.trace("Site switch over was done. Site is now in stand-by mode");
215 setSiteMode(SwitchoverDetectorState.STANDBY.getState());
216 BeEcompErrorManager.getInstance().logSiteSwitchoverInfo(SWITCHOVER_DETECTOR_LOG_CONTEXT, siteMode);
218 if (updateRequired) {
219 changeSitePriority(SwitchoverDetectorGroup.BE_SET.getGroup());
220 changeSitePriority(SwitchoverDetectorGroup.FE_SET.getGroup());
225 private void changeSitePriority(String groupToSet) {
227 String url = switchoverDetectorConfig.getGroups().get(groupToSet).getChangePriorityUrl();
228 String body = switchoverDetectorConfig.getGroups().get(groupToSet).getChangePriorityBody();
231 HttpRequest.put(url, authHeader, new StringEntity(body, ContentType.APPLICATION_JSON));
232 } catch (Exception e) {
233 String message = e.getMessage();
234 if (message == null) {
235 message = e.getClass().getName();
237 logger.debug("Error occured during change site priority request, Result is {}", message, e);
242 private void publishNetwork() {
244 String url = switchoverDetectorConfig.getPublishNetworkUrl();
245 String body = switchoverDetectorConfig.getPublishNetworkBody();
247 HttpRequest.post(url, authHeader, new StringEntity(body, ContentType.APPLICATION_JSON));
248 } catch (Exception e) {
249 String message = e.getMessage();
250 if (message == null) {
251 message = e.getClass().getName();
253 logger.debug("Error occured during publish network request, Result is {}", message, e);
260 private void init() {
261 logger.info("Enter init method of SwitchoverDetector");
263 switchoverDetectorConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getSwitchoverDetector();
265 if (!switchoverDetectorConfig.getEnabled()) {
266 logger.info("switchover detector service is disabled");
270 Long detectorIntervalConfig = switchoverDetectorConfig.getInterval();
271 if (detectorIntervalConfig != null) {
272 detectorInterval = detectorIntervalConfig.longValue();
275 Integer maxAttempts = switchoverDetectorConfig.getBeResolveAttempts();
276 if (maxAttempts != null) {
277 maxBeQueryAttempts = maxAttempts.intValue();
279 maxAttempts = switchoverDetectorConfig.getFeResolveAttempts();
280 if (maxAttempts != null) {
281 maxFeQueryAttempts = maxAttempts.intValue();
284 setAuthorizationProperties();
285 logger.info("switchover detector service is enabled, interval is {} seconds", detectorInterval);
287 this.switchoverDetectorScheduledTask = new SwitchoverDetectorScheduledTask();
288 startSwitchoverDetectorTask();
289 logger.trace("Exit init method of SwitchoverDetector");
294 private void destroy() {
296 if (scheduledFuture != null) {
297 scheduledFuture.cancel(true);
298 scheduledFuture = null;
301 if (switchoverDetectorScheduler != null) {
302 switchoverDetectorScheduler.shutdown();
307 public void startSwitchoverDetectorTask() {
308 if (this.scheduledFuture == null) {
309 this.scheduledFuture = this.switchoverDetectorScheduler.scheduleAtFixedRate(switchoverDetectorScheduledTask, 0, detectorInterval, TimeUnit.SECONDS);