diff options
author | GuangrongFu <fu.guangrong@zte.com.cn> | 2021-05-10 11:09:56 +0800 |
---|---|---|
committer | GuangrongFu <fu.guangrong@zte.com.cn> | 2021-05-10 14:10:44 +0800 |
commit | 6af8af01fb0cdceb384cf47cf241736620510465 (patch) | |
tree | fa735121585e46bb0868116cc2b34ad2056fac3b /holmes-actions/src/main/java | |
parent | 459e4faa15c47f39c7400000cb15ca2d2123e70f (diff) |
Simplified HTTP(s) Related Tools
Change-Id: I3e5f3f12d0859be28b32406a28d4c5e62722936d
Issue-ID: HOLMES-307
Signed-off-by: GuangrongFu <fu.guangrong@zte.com.cn>
Diffstat (limited to 'holmes-actions/src/main/java')
7 files changed, 251 insertions, 184 deletions
diff --git a/holmes-actions/src/main/java/org/onap/holmes/common/aai/AaiQuery.java b/holmes-actions/src/main/java/org/onap/holmes/common/aai/AaiQuery.java index f409c27..4a4ffcb 100644 --- a/holmes-actions/src/main/java/org/onap/holmes/common/aai/AaiQuery.java +++ b/holmes-actions/src/main/java/org/onap/holmes/common/aai/AaiQuery.java @@ -14,18 +14,14 @@ package org.onap.holmes.common.aai; import lombok.extern.slf4j.Slf4j; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.CloseableHttpClient; import org.jvnet.hk2.annotations.Service; import org.onap.holmes.common.aai.config.AaiConfig; import org.onap.holmes.common.aai.entity.VmEntity; import org.onap.holmes.common.aai.entity.VnfEntity; import org.onap.holmes.common.exception.CorrelationException; -import org.onap.holmes.common.utils.HttpsUtils; +import org.onap.holmes.common.utils.JerseyClient; import javax.inject.Inject; -import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -95,26 +91,11 @@ public class AaiQuery { } private String getResponse(String url) throws CorrelationException { - String response; - CloseableHttpClient httpClient = null; - HttpGet httpGet = new HttpGet(url); try { - httpClient = HttpsUtils.getHttpsClient(HttpsUtils.DEFUALT_TIMEOUT); - HttpResponse httpResponse = HttpsUtils.get(httpGet, getHeaders(), httpClient); - response = HttpsUtils.extractResponseEntity(httpResponse); + return new JerseyClient().headers(getHeaders()).get(url); } catch (Exception e) { throw new CorrelationException("Failed to get data from aai", e); - } finally { - httpGet.releaseConnection(); - if (httpClient != null) { - try { - httpClient.close(); - } catch (IOException e) { - log.warn("Failed to close http client!"); - } - } } - return response; } private Map getHeaders() { diff --git a/holmes-actions/src/main/java/org/onap/holmes/common/aai/AaiQueryMdons.java b/holmes-actions/src/main/java/org/onap/holmes/common/aai/AaiQueryMdons.java index e2bc357..892638b 100644 --- a/holmes-actions/src/main/java/org/onap/holmes/common/aai/AaiQueryMdons.java +++ b/holmes-actions/src/main/java/org/onap/holmes/common/aai/AaiQueryMdons.java @@ -1,5 +1,5 @@ /** - * Copyright 2020 Fujitsu Limited. + * Copyright 2020 - 2021 Fujitsu Limited. * <p> * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -17,30 +17,22 @@ package org.onap.holmes.common.aai; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonParser; - -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; +import org.jvnet.hk2.annotations.Service; import org.onap.holmes.common.aai.config.AaiConfig; import org.onap.holmes.common.config.MicroServiceConfig; import org.onap.holmes.common.exception.CorrelationException; -import org.onap.holmes.common.utils.HttpsUtils; - -import static org.onap.holmes.common.aai.AaiJsonParserUtil.getInfo; -import static org.onap.holmes.common.aai.AaiJsonParserUtil.getPath; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; +import org.onap.holmes.common.utils.JerseyClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import javax.ws.rs.client.Entity; import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; +import java.util.HashMap; +import java.util.Map; -import org.jvnet.hk2.annotations.Service; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.onap.holmes.common.aai.AaiJsonParserUtil.getInfo; +import static org.onap.holmes.common.aai.AaiJsonParserUtil.getPath; @Service public class AaiQueryMdons { @@ -71,32 +63,17 @@ public class AaiQueryMdons { } return url; } - + private String getResponse(String url) throws CorrelationException { - String response; - CloseableHttpClient httpClient = null; - HttpGet httpGet = new HttpGet(url); try { - httpClient = HttpsUtils.getHttpsClient(HttpsUtils.DEFUALT_TIMEOUT); - HttpResponse httpResponse = HttpsUtils.get(httpGet, getHeaders(), httpClient); - response = HttpsUtils.extractResponseEntity(httpResponse); + return new JerseyClient().headers(getHeaders()).get(url); } catch (Exception e) { throw new CorrelationException("Failed to get data from aai", e); - } finally { - httpGet.releaseConnection(); - if (httpClient != null) { - try { - httpClient.close(); - } catch (IOException e) { - log.warn("Failed to close http client!"); - } - } } - return response; } - private Map<String, String> getHeaders() { - Map<String, String> headers = new HashMap<>(); + private Map<String, Object> getHeaders() { + Map<String, Object> headers = new HashMap<>(); headers.put("X-TransactionId", AaiConfig.X_TRANSACTION_ID); headers.put("X-FromAppId", AaiConfig.X_FROMAPP_ID); headers.put("Authorization", AaiConfig.getAuthenticationCredentials()); @@ -195,27 +172,11 @@ public class AaiQueryMdons { put(url, jsonObject.toString()); } - private HttpResponse put(String url, String content) throws CorrelationException { - CloseableHttpClient httpClient = null; - HttpPut httpPut = new HttpPut(url); + private void put(String url, String content) throws CorrelationException { try { - httpClient = HttpsUtils.getConditionalHttpsClient(HttpsUtils.DEFUALT_TIMEOUT); - return HttpsUtils.put(httpPut, getHeaders(), new HashMap<>(), new StringEntity(content), httpClient); + new JerseyClient().headers(getHeaders()).put(url, Entity.json(content)); } catch (Exception e) { throw new CorrelationException("Failed to put data in AAI", e); - } finally { - closeHttpClient(httpClient); - } - } - - private void closeHttpClient(CloseableHttpClient httpClient) { - if (httpClient != null) { - try { - httpClient.close(); - } catch (IOException e) { - log.warn("Failed to close http client!"); - } } } - } diff --git a/holmes-actions/src/main/java/org/onap/holmes/common/dmaap/DmaapService.java b/holmes-actions/src/main/java/org/onap/holmes/common/dmaap/DmaapService.java index 7e33bf9..e9eb003 100644 --- a/holmes-actions/src/main/java/org/onap/holmes/common/dmaap/DmaapService.java +++ b/holmes-actions/src/main/java/org/onap/holmes/common/dmaap/DmaapService.java @@ -67,12 +67,14 @@ public class DmaapService { .getTopicUrl()); publisher.publish(policyMsg); deleteRequestIdIfNecessary(policyMsg); + log.info("send policyMsg: " + GsonUtil.beanToJson(policyMsg)); - } catch (CorrelationException e) { - log.error("Failed to publish the control loop event to DMaaP", e); } catch (NullPointerException e) { log.error(String.format("DMaaP configurations do not exist!\n DCAE Configurations: \n %s", DcaeConfigurationsCache.getDcaeConfigurations()), e); + } catch (Exception e) { + log.error(String.format("An error occurred when publishing a message to Policy: %s", + e.getMessage()), e); } } @@ -83,7 +85,7 @@ public class DmaapService { } private PolicyMsg getEnrichedPolicyMsg(VmEntity vmEntity, VesAlarm rootAlarm, VesAlarm childAlarm, - String packageName) { + String packageName) { PolicyMsg policyMsg = new PolicyMsg(); policyMsg.setRequestID(getUniqueRequestId(rootAlarm)); if (rootAlarm.getAlarmIsCleared() == PolicyMassgeConstant.POLICY_MESSAGE_ONSET) { @@ -91,7 +93,7 @@ public class DmaapService { policyMsg.setClosedLoopEventStatus(EVENT_STATUS.ONSET); policyMsg.getAai().put("vserver.in-maint", vmEntity.getInMaint()); policyMsg.getAai().put("vserver.is-closed-loop-disabled", - vmEntity.getClosedLoopDisable()); + vmEntity.getClosedLoopDisable()); policyMsg.getAai().put("vserver.prov-status", vmEntity.getProvStatus()); policyMsg.getAai().put("vserver.resource-version", vmEntity.getResourceVersion()); } else { @@ -195,12 +197,12 @@ public class DmaapService { return vmEntity; } - private void deleteRequestIdIfNecessary(PolicyMsg policyMsg){ - EVENT_STATUS status = policyMsg.getClosedLoopEventStatus(); - if(EVENT_STATUS.ABATED.equals(status)) { + private void deleteRequestIdIfNecessary(PolicyMsg policyMsg) { + EVENT_STATUS status = policyMsg.getClosedLoopEventStatus(); + if (EVENT_STATUS.ABATED.equals(status)) { String requestId = policyMsg.getRequestID(); - for(Entry<String, String> kv: uniqueRequestIdCache.entrySet()) { - if(kv.getValue().equals(requestId)) { + for (Entry<String, String> kv : uniqueRequestIdCache.entrySet()) { + if (kv.getValue().equals(requestId)) { uniqueRequestIdCache.remove(kv.getKey()); break; } diff --git a/holmes-actions/src/main/java/org/onap/holmes/common/dmaap/Publisher.java b/holmes-actions/src/main/java/org/onap/holmes/common/dmaap/Publisher.java index d95853d..a4024ea 100644 --- a/holmes-actions/src/main/java/org/onap/holmes/common/dmaap/Publisher.java +++ b/holmes-actions/src/main/java/org/onap/holmes/common/dmaap/Publisher.java @@ -15,68 +15,23 @@ */
package org.onap.holmes.common.dmaap;
-import java.io.IOException;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.onap.holmes.common.dmaap.entity.PolicyMsg;
-import org.onap.holmes.common.exception.CorrelationException;
-import com.google.gson.Gson;
-import java.util.HashMap;
-import javax.ws.rs.core.MediaType;
import lombok.Getter;
import lombok.Setter;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.entity.StringEntity;
import org.jvnet.hk2.annotations.Service;
-import org.onap.holmes.common.utils.HttpsUtils;
+import org.onap.holmes.common.dmaap.entity.PolicyMsg;
+import org.onap.holmes.common.utils.JerseyClient;
+
+import javax.ws.rs.client.Entity;
+import java.util.concurrent.TimeUnit;
@Getter
@Setter
@Service
-@Slf4j
public class Publisher {
-
- private String topic;
private String url;
- private String authInfo;
- private String authExpDate;
-
- public boolean publish(PolicyMsg msg) throws CorrelationException {
- String content;
- try {
- //content = JSON.toJSONString(msg);
- content = new Gson().toJson(msg);
- } catch (Exception e) {
- throw new CorrelationException("Failed to convert the message object to a json string.",
- e);
- }
- HttpResponse httpResponse;
- HashMap<String, String> headers = new HashMap<>();
- headers.put("Accept", MediaType.APPLICATION_JSON);
- headers.put("Content-Type", MediaType.APPLICATION_JSON);
- CloseableHttpClient httpClient = null;
- HttpPost httpPost = new HttpPost(url);
- try {
- httpClient = HttpsUtils.getConditionalHttpsClient(HttpsUtils.DEFUALT_TIMEOUT);
- httpResponse = HttpsUtils.post(httpPost, headers, new HashMap<>(), new StringEntity(content, "utf-8"), httpClient);
- } catch (Exception e) {
- throw new CorrelationException("Failed to connect to DCAE.", e);
- } finally {
- httpPost.releaseConnection();
- if (httpClient != null) {
- try {
- httpClient.close();
- } catch (IOException e) {
- log.warn("Failed to close http client!");
- }
- }
- }
- return checkStatus(httpResponse);
- }
+ private JerseyClient client = new JerseyClient(TimeUnit.SECONDS.toMillis(30));
- private boolean checkStatus(HttpResponse httpResponse) {
- return (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) ? true : false;
+ public void publish(PolicyMsg msg) {
+ client.post(url, Entity.json(msg));
}
}
diff --git a/holmes-actions/src/main/java/org/onap/holmes/common/exception/HttpException.java b/holmes-actions/src/main/java/org/onap/holmes/common/exception/HttpException.java new file mode 100644 index 0000000..ad31dac --- /dev/null +++ b/holmes-actions/src/main/java/org/onap/holmes/common/exception/HttpException.java @@ -0,0 +1,27 @@ +/** + * Copyright 2021 ZTE Corporation. + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.holmes.common.exception; + +public class HttpException extends RuntimeException { + public HttpException(int statusCode, String msg) { + super(String.format("Status code: <%d>. Message: %s", statusCode, msg)); + } + + public HttpException(int statusCode, String msg, Throwable t) { + super(String.format("Status code: <%d>. Message: %s", statusCode, msg), t); + } +} diff --git a/holmes-actions/src/main/java/org/onap/holmes/common/utils/JerseyClient.java b/holmes-actions/src/main/java/org/onap/holmes/common/utils/JerseyClient.java index 2d770ad..09d9f64 100644 --- a/holmes-actions/src/main/java/org/onap/holmes/common/utils/JerseyClient.java +++ b/holmes-actions/src/main/java/org/onap/holmes/common/utils/JerseyClient.java @@ -16,33 +16,33 @@ package org.onap.holmes.common.utils; -import org.glassfish.jersey.client.ClientConfig; -import org.jvnet.hk2.annotations.Service; +import org.eclipse.jetty.http.HttpStatus; +import org.onap.holmes.common.exception.HttpException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.PostConstruct; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.*; +import javax.ws.rs.core.Response; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; +import java.util.*; +import java.util.concurrent.TimeUnit; -@Service public class JerseyClient { - private static Logger logger = LoggerFactory.getLogger(JerseyClient.class); - public static final String PROTOCOL_HTTP = "http"; - public static final String PROTOCOL_HTTPS = "https"; - private SSLContext sslcontext = null; + static final public String PROTOCOL_HTTP = "http"; + static final public String PROTOCOL_HTTPS = "https"; + static private Logger logger = LoggerFactory.getLogger(JerseyClient.class); + static private long DEFAULT_TIMEOUT = TimeUnit.SECONDS.toMillis(30); + static private SSLContext SSLCONTEXT; - @PostConstruct - private void init() { + static { try { - sslcontext = SSLContext.getInstance("TLS"); - sslcontext.init(null, new TrustManager[]{new X509TrustManager() { + SSLCONTEXT = SSLContext.getInstance("TLS"); + SSLCONTEXT.init(null, new TrustManager[]{new X509TrustManager() { public void checkClientTrusted(X509Certificate[] arg0, String arg1) { } @@ -58,18 +58,174 @@ public class JerseyClient { } } - public Client httpClient() { - return ClientBuilder.newClient(new ClientConfig()); + private Client client; + private Map<String, Object> headers = new HashMap(); + private Map<String, Object> parameters = new HashMap(); + private List<String> paths = new ArrayList(); + + + public JerseyClient() { + this(DEFAULT_TIMEOUT); } - public Client httpsClient() { - return ClientBuilder.newBuilder() - .sslContext(sslcontext) + public JerseyClient(long timeout) { + this.client = ClientBuilder.newBuilder() + .connectTimeout(timeout, TimeUnit.MILLISECONDS) + .readTimeout(timeout, TimeUnit.MILLISECONDS) + .sslContext(SSLCONTEXT) .hostnameVerifier((s1, s2) -> true) .build(); } - public Client client(boolean isHttps) { - return isHttps ? httpsClient() : httpClient(); + public JerseyClient header(String name, Object value) { + headers.put(name, value); + return this; + } + + public JerseyClient headers(Map<String, Object> hds) { + headers.putAll(hds); + return this; + } + + public JerseyClient queryParam(String name, Object value) { + parameters.put(name, value); + return this; + } + + public JerseyClient queryParams(Map<String, Object> params) { + parameters.putAll(params); + return this; + } + + public JerseyClient path(String path) { + paths.add(path); + return this; + } + + public String get(String url) { + return get(url, String.class); + } + + public <T> T get(String url, Class<T> clazz) { + + WebTarget target = appendPaths(client.target(url)); + + target = setParameters(target); + + Invocation.Builder builder = setHeaders(target.request()); + + Response response = builder.get(); + + if (isSuccessful(response)) { + return response2Target(response, clazz); + } + + return null; + } + + public String post(String url) { + return post(url, null); + } + + public String post(String url, Entity entity) { + return post(url, entity, String.class); + } + + public <T> T post(String url, Entity entity, Class<T> clazz) { + + WebTarget target = appendPaths(client.target(url)); + + setParameters(target); + + Invocation.Builder builder = setHeaders(target.request()); + + Response response = builder.post(entity); + + if (isSuccessful(response)) { + return response2Target(response, clazz); + } + + return null; + } + + public String put(String url, Entity entity) { + return put(url, entity, String.class); + } + + public <T> T put(String url, Entity entity, Class<T> clazz) { + WebTarget target = appendPaths(client.target(url)); + + setParameters(target); + + Invocation.Builder builder = setHeaders(target.request()); + + Response response = builder.put(entity); + + if (isSuccessful(response)) { + return response2Target(response, clazz); + } + + return null; + } + + public String delete(String url) { + return delete(url, String.class); + } + + public <T> T delete(String url, Class<T> clazz) { + WebTarget target = appendPaths(client.target(url)); + + setParameters(target); + + Invocation.Builder builder = setHeaders(target.request()); + + Response response = builder.delete(); + + if (isSuccessful(response)) { + return response2Target(response, clazz); + } + + return null; + } + + private boolean isSuccessful(Response response) { + int status = response.getStatus(); + if (!HttpStatus.isSuccess(status)) { + throw new HttpException(status, String.format("Failed to get response from the server. Info: %s", + response.readEntity(String.class))); + } + return true; + } + + private WebTarget appendPaths(WebTarget target) { + for (String path : paths) { + target = target.path(path); + } + return target; + } + + private Invocation.Builder setHeaders(Invocation.Builder builder) { + Set<Map.Entry<String, Object>> entries = headers.entrySet(); + for (Map.Entry<String, Object> entry : entries) { + builder = builder.header(entry.getKey(), entry.getValue()); + } + return builder; + } + + private WebTarget setParameters(WebTarget target) { + Set<Map.Entry<String, Object>> entries = parameters.entrySet(); + for (Map.Entry<String, Object> entry : entries) { + target = target.queryParam(entry.getKey(), entry.getValue()); + } + return target; + } + + private <T> T response2Target(Response response, Class<T> clazz) { + String responseText = response.readEntity(String.class); + if (clazz == null || clazz == String.class) { + return (T) responseText; + } else { + return GsonUtil.jsonToBean(responseText, clazz); + } } } diff --git a/holmes-actions/src/main/java/org/onap/holmes/common/utils/MsbRegister.java b/holmes-actions/src/main/java/org/onap/holmes/common/utils/MsbRegister.java index caff931..ff5b48a 100644 --- a/holmes-actions/src/main/java/org/onap/holmes/common/utils/MsbRegister.java +++ b/holmes-actions/src/main/java/org/onap/holmes/common/utils/MsbRegister.java @@ -17,7 +17,6 @@ package org.onap.holmes.common.utils; import org.apache.commons.lang3.StringUtils; -import org.eclipse.jetty.http.HttpStatus; import org.jvnet.hk2.annotations.Service; import org.onap.holmes.common.config.MicroServiceConfig; import org.onap.holmes.common.exception.CorrelationException; @@ -26,12 +25,8 @@ import org.onap.msb.sdk.discovery.entity.MicroServiceInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.inject.Inject; -import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; -import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; import java.util.concurrent.TimeUnit; import static org.onap.holmes.common.utils.JerseyClient.PROTOCOL_HTTP; @@ -41,22 +36,17 @@ import static org.onap.holmes.common.utils.JerseyClient.PROTOCOL_HTTPS; public class MsbRegister { private static final Logger log = LoggerFactory.getLogger(MsbRegister.class); - private JerseyClient jerseyClient; + private JerseyClient client = new JerseyClient(); - @Inject - public MsbRegister(JerseyClient jerseyClient) { - this.jerseyClient = jerseyClient; + public MsbRegister() { } public void register2Msb(MicroServiceInfo msinfo) throws CorrelationException { String[] msbAddrInfo = MicroServiceConfig.getMsbIpAndPort(); + boolean isHttpsEnabled = StringUtils.isNotBlank(msbAddrInfo[1]) && msbAddrInfo[1].equals("443"); - Client client = jerseyClient.client(isHttpsEnabled); - WebTarget target = client.target(String.format("%s://%s:%s/api/microservices/v1/services", - isHttpsEnabled ? PROTOCOL_HTTPS : PROTOCOL_HTTP, msbAddrInfo[0], msbAddrInfo[1])); - log.info("Start to register Holmes Service to MSB..."); MicroServiceFullInfo microServiceFullInfo = null; @@ -65,18 +55,13 @@ public class MsbRegister { while (null == microServiceFullInfo && retry < 20) { log.info("Holmes Service Registration. Retry: " + retry++); - Response response = target.queryParam("createOrUpdate", true) - .request(MediaType.APPLICATION_JSON) - .post(Entity.entity(msinfo, MediaType.APPLICATION_JSON)); - - if (response != null) { - String ret = response.readEntity(String.class); - int statusCode = response.getStatus(); - log.info(String.format("=========MSB REG=========\nStatus Code: %d\nInformation: %s", statusCode, ret)); - if (HttpStatus.isSuccess(statusCode)) { - microServiceFullInfo = GsonUtil.jsonToBean(ret, MicroServiceFullInfo.class); - } - } + microServiceFullInfo = client + .header("Accept", MediaType.APPLICATION_JSON) + .queryParam("createOrUpdate", true) + .post(String.format("%s://%s:%s/api/microservices/v1/services", + isHttpsEnabled ? PROTOCOL_HTTPS : PROTOCOL_HTTP, msbAddrInfo[0], msbAddrInfo[1]), + Entity.entity(msinfo, MediaType.APPLICATION_JSON), + MicroServiceFullInfo.class); if (null == microServiceFullInfo) { log.warn(String.format("Failed to register the service to MSB. Sleep %ds and try again.", interval)); |