| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * 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.apache.servicecomb.huaweicloud.dashboard.monitor; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| |
| import org.apache.commons.io.IOUtils; |
| import org.apache.servicecomb.deployment.Deployment; |
| import org.apache.servicecomb.deployment.SystemBootstrapInfo; |
| import org.apache.servicecomb.foundation.auth.SignRequest; |
| import org.apache.servicecomb.foundation.common.event.EventManager; |
| import org.apache.servicecomb.foundation.common.net.IpPort; |
| import org.apache.servicecomb.foundation.common.net.NetUtils; |
| import org.apache.servicecomb.foundation.ssl.SSLCustom; |
| import org.apache.servicecomb.foundation.ssl.SSLOption; |
| import org.apache.servicecomb.foundation.ssl.SSLOptionFactory; |
| import org.apache.servicecomb.foundation.vertx.AddressResolverConfig; |
| import org.apache.servicecomb.foundation.vertx.VertxTLSBuilder; |
| import org.apache.servicecomb.foundation.vertx.VertxUtils; |
| import org.apache.servicecomb.foundation.vertx.client.ClientPoolManager; |
| import org.apache.servicecomb.foundation.vertx.client.ClientVerticle; |
| import org.apache.servicecomb.foundation.vertx.client.http.HttpClientPoolFactory; |
| import org.apache.servicecomb.foundation.vertx.client.http.HttpClientWithContext; |
| import org.apache.servicecomb.huaweicloud.dashboard.monitor.data.MonitorConstant; |
| import org.apache.servicecomb.huaweicloud.dashboard.monitor.event.MonitorFailEvent; |
| import org.apache.servicecomb.huaweicloud.dashboard.monitor.event.MonitorSuccEvent; |
| import org.apache.servicecomb.huaweicloud.dashboard.monitor.model.MonitorDaraProvider; |
| import org.apache.servicecomb.huaweicloud.dashboard.monitor.model.MonitorDataPublisher; |
| import org.apache.servicecomb.serviceregistry.RegistryUtils; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import io.netty.handler.codec.http.HttpResponseStatus; |
| import io.vertx.core.DeploymentOptions; |
| import io.vertx.core.Future; |
| import io.vertx.core.Vertx; |
| import io.vertx.core.VertxOptions; |
| import io.vertx.core.http.HttpClientOptions; |
| import io.vertx.core.http.HttpMethod; |
| import io.vertx.core.json.Json; |
| import io.vertx.core.net.ProxyOptions; |
| |
| public class DefaultMonitorDataPublisher implements MonitorDataPublisher { |
| private static final Logger LOGGER = LoggerFactory.getLogger(DefaultMonitorDataPublisher.class); |
| |
| private static final String SSL_KEY = "mc.consumer"; |
| |
| private static final int MAX_WAIT_QUEUE_SIZE = 50; |
| |
| private static ClientPoolManager<HttpClientWithContext> clientMgr; |
| |
| private AddressManager addressManager; |
| |
| @Override |
| public void init() { |
| try { |
| List<String> addresses = new ArrayList<>(); |
| SystemBootstrapInfo info = Deployment.getSystemBootStrapInfo( |
| MonitorConstant.SYSTEM_KEY_DASHBOARD_SERVICE); |
| if (info != null && info.getAccessURL() != null) { |
| addresses.addAll(info.getAccessURL()); |
| } |
| |
| addressManager = new AddressManager(addresses, EventManager.getEventBus()); |
| deployMonitorClient(); |
| } catch (Exception e) { |
| LOGGER.warn("Deploy monitor data publisher failed will not send monitor data."); |
| } |
| } |
| |
| @Override |
| public void publish(MonitorDaraProvider provider) { |
| Object data = provider.getData(); |
| if (data == null) { |
| return; |
| } |
| String endpoint = addressManager.address(); |
| if (endpoint == null) { |
| return; |
| } |
| |
| String jasonData = Json.encode(data); |
| String url = provider.getURL(); |
| IpPort host = NetUtils.parseIpPortFromURI(endpoint); |
| |
| doSend(endpoint, jasonData, url, host, 0); |
| } |
| |
| private void doSend(String endpoint, String jsonData, String url, IpPort host, int times) { |
| clientMgr.findThreadBindClientPool().runOnContext(client -> { |
| client.request(HttpMethod.POST, host.getPort(), host.getHostOrIp(), url).compose(request -> { |
| request.headers().add("environment", RegistryUtils.getMicroservice().getEnvironment()); |
| request.setTimeout(MonitorConstant.getInterval() / MonitorConstant.MAX_RETRY_TIMES); |
| try { |
| SignRequest signReq = SignUtil.createSignRequest(request.getMethod().toString(), |
| endpoint + url, |
| new HashMap<>(), |
| IOUtils.toInputStream(jsonData, "UTF-8")); |
| SignUtil.getAuthHeaderProviders().forEach(authHeaderProvider -> { |
| request.headers().addAll(authHeaderProvider.getSignAuthHeaders(signReq)); |
| }); |
| } catch (Exception e) { |
| LOGGER.error("sign request error!", e); |
| } |
| return request.send(jsonData).compose(rsp -> { |
| if (rsp.statusCode() != HttpResponseStatus.OK.code()) { |
| addressManager.recordSuccessState(endpoint); |
| if (times < MonitorConstant.MAX_RETRY_TIMES |
| && rsp.statusCode() == HttpResponseStatus.BAD_GATEWAY.code()) { |
| doSend(endpoint, jsonData, url, host, times + 1); |
| return Future.succeededFuture(); |
| } |
| return rsp.body().compose(buffer -> { |
| LOGGER.warn("Send data to url {} failed and status line is {}", |
| url, |
| rsp.statusCode()); |
| LOGGER.warn("message: {}", buffer); |
| return Future.succeededFuture(); |
| }); |
| } else { |
| addressManager.recordSuccessState(endpoint); |
| EventManager.post(new MonitorSuccEvent()); |
| } |
| return Future.succeededFuture(); |
| }).onFailure(failure -> { |
| EventManager.post(new MonitorFailEvent("send monitor data fail.")); |
| addressManager.recordFailState(endpoint); |
| LOGGER.warn("Send monitor data to {} failed , {}", endpoint, failure); |
| }); |
| }); |
| }); |
| } |
| |
| private void deployMonitorClient() throws InterruptedException { |
| VertxOptions vertxOptions = new VertxOptions(); |
| vertxOptions.setAddressResolverOptions(AddressResolverConfig.getAddressResover(SSL_KEY)); |
| Vertx vertx = VertxUtils.getOrCreateVertxByName("monitor-center", vertxOptions); |
| |
| HttpClientOptions httpClientOptions = createHttpClientOptions(); |
| httpClientOptions.setMaxWaitQueueSize(MAX_WAIT_QUEUE_SIZE); |
| clientMgr = new ClientPoolManager<>(vertx, new HttpClientPoolFactory(httpClientOptions)); |
| |
| DeploymentOptions deploymentOptions = VertxUtils.createClientDeployOptions(clientMgr, 1); |
| VertxUtils.blockDeploy(vertx, ClientVerticle.class, deploymentOptions); |
| } |
| |
| private HttpClientOptions createHttpClientOptions() { |
| HttpClientOptions httpClientOptions = new HttpClientOptions(); |
| if (MonitorConstant.isProxyEnable()) { |
| ProxyOptions proxy = new ProxyOptions(); |
| proxy.setHost(MonitorConstant.getProxyHost()); |
| proxy.setPort(MonitorConstant.getProxyPort()); |
| proxy.setUsername(MonitorConstant.getProxyUsername()); |
| proxy.setPassword(MonitorConstant.getProxyPasswd()); |
| httpClientOptions.setProxyOptions(proxy); |
| } |
| |
| httpClientOptions.setConnectTimeout(MonitorConstant.getConnectionTimeout()); |
| if (MonitorConstant.sslEnabled()) { |
| SSLOptionFactory factory = SSLOptionFactory.createSSLOptionFactory(SSL_KEY, null); |
| SSLOption sslOption; |
| if (factory == null) { |
| sslOption = SSLOption.buildFromYaml(SSL_KEY); |
| } else { |
| sslOption = factory.createSSLOption(); |
| } |
| SSLCustom sslCustom = SSLCustom.createSSLCustom(sslOption.getSslCustomClass()); |
| VertxTLSBuilder.buildHttpClientOptions(sslOption, sslCustom, httpClientOptions); |
| } |
| return httpClientOptions; |
| } |
| } |