This is an automated email from the ASF dual-hosted git repository. wujimin pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit ca84f1708aa09e0599c079ea1e12e7d1e718d5aa Author: zhengyangyong <[email protected]> AuthorDate: Thu Jan 4 17:58:27 2018 +0800 SCB-166 add health check implement Signed-off-by: zhengyangyong <[email protected]> --- .../common/DefaultHealthCheckExtraData.java | 69 ++++++++++++++++++ .../metrics/common/HealthCheckResult.java | 56 +++++++++++++++ .../servicecomb/metrics/common/HealthChecker.java | 24 +++++++ .../metrics/common/HealthCheckerPublisher.java | 26 +++++++ .../health/DefaultMicroserviceHealthChecker.java | 60 ++++++++++++++++ .../core/publish/DefaultHealthCheckerManager.java | 62 +++++++++++++++++ .../publish/DefaultHealthCheckerPublisher.java | 59 ++++++++++++++++ .../metrics/core/publish/HealthCheckerManager.java | 31 +++++++++ .../metrics/core/TestHealthCheckerManager.java | 81 ++++++++++++++++++++++ .../metrics/core/TestHealthCheckerPublisher.java | 59 ++++++++++++++++ 10 files changed, 527 insertions(+) diff --git a/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/DefaultHealthCheckExtraData.java b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/DefaultHealthCheckExtraData.java new file mode 100644 index 0000000..aa2c9b4 --- /dev/null +++ b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/DefaultHealthCheckExtraData.java @@ -0,0 +1,69 @@ +/* + * 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 io.servicecomb.metrics.common; + +public class DefaultHealthCheckExtraData { + private String instanceId; + + private String hostName; + + private String appId; + + private String serviceName; + + private String serviceVersion; + + private String endpoints; + + public String getInstanceId() { + return instanceId; + } + + public String getHostName() { + return hostName; + } + + public String getAppId() { + return appId; + } + + public String getServiceName() { + return serviceName; + } + + public String getServiceVersion() { + return serviceVersion; + } + + public String getEndpoints() { + return endpoints; + } + + public DefaultHealthCheckExtraData() { + } + + public DefaultHealthCheckExtraData(String instanceId, String hostName, String appId, String serviceName, + String serviceVersion, String endpoints) { + this.instanceId = instanceId; + this.hostName = hostName; + this.appId = appId; + this.serviceName = serviceName; + this.serviceVersion = serviceVersion; + this.endpoints = endpoints; + } +} diff --git a/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/HealthCheckResult.java b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/HealthCheckResult.java new file mode 100644 index 0000000..b44d8df --- /dev/null +++ b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/HealthCheckResult.java @@ -0,0 +1,56 @@ +/* + * 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 io.servicecomb.metrics.common; + +public class HealthCheckResult { + private boolean isHealth; + + private String information; + + //unsupport object or generic type,so string.. + private String extraData; + + private long timestamp; + + public boolean isHealth() { + return isHealth; + } + + public String getInformation() { + return information; + } + + public String getExtraData() { + return extraData; + } + + public long getTimestamp() { + return timestamp; + } + + public HealthCheckResult() { + } + + public HealthCheckResult(boolean isHealth, String information, String extraData) { + this(); + this.isHealth = isHealth; + this.information = information; + this.extraData = extraData; + this.timestamp = System.currentTimeMillis(); + } +} diff --git a/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/HealthChecker.java b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/HealthChecker.java new file mode 100644 index 0000000..69025e1 --- /dev/null +++ b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/HealthChecker.java @@ -0,0 +1,24 @@ +/* + * 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 io.servicecomb.metrics.common; + +public interface HealthChecker { + String getName(); + + HealthCheckResult check(); +} diff --git a/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/HealthCheckerPublisher.java b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/HealthCheckerPublisher.java new file mode 100644 index 0000000..68aacca --- /dev/null +++ b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/HealthCheckerPublisher.java @@ -0,0 +1,26 @@ +/* + * 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 io.servicecomb.metrics.common; + +import java.util.Map; + +public interface HealthCheckerPublisher { + Map<String, HealthCheckResult> health(); + + HealthCheckResult healthWithName(String name); +} diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/health/DefaultMicroserviceHealthChecker.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/health/DefaultMicroserviceHealthChecker.java new file mode 100644 index 0000000..1e96b11 --- /dev/null +++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/health/DefaultMicroserviceHealthChecker.java @@ -0,0 +1,60 @@ +/* + * 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 io.servicecomb.metrics.core.health; + +import com.fasterxml.jackson.core.JsonProcessingException; + +import io.servicecomb.foundation.common.exceptions.ServiceCombException; +import io.servicecomb.foundation.common.utils.JsonUtils; +import io.servicecomb.metrics.common.DefaultHealthCheckExtraData; +import io.servicecomb.metrics.common.HealthCheckResult; +import io.servicecomb.metrics.common.HealthChecker; +import io.servicecomb.serviceregistry.RegistryUtils; +import io.servicecomb.serviceregistry.api.registry.Microservice; +import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance; + +public class DefaultMicroserviceHealthChecker implements HealthChecker { + + private final String extraData; + + public DefaultMicroserviceHealthChecker() { + try { + Microservice microservice = RegistryUtils.getMicroservice(); + MicroserviceInstance instance = RegistryUtils.getMicroserviceInstance(); + extraData = JsonUtils.writeValueAsString(new DefaultHealthCheckExtraData( + instance.getInstanceId(), + instance.getHostName(), + microservice.getAppId(), + microservice.getServiceName(), + microservice.getVersion(), + String.join(",", instance.getEndpoints()))); + } catch (JsonProcessingException e) { + throw new ServiceCombException("unable load microservice info for healthchecker", e); + } + } + + @Override + public String getName() { + return "default"; + } + + @Override + public HealthCheckResult check() { + return new HealthCheckResult(true, "", extraData); + } +} diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/publish/DefaultHealthCheckerManager.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/publish/DefaultHealthCheckerManager.java new file mode 100644 index 0000000..0393ab9 --- /dev/null +++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/publish/DefaultHealthCheckerManager.java @@ -0,0 +1,62 @@ +/* + * 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 io.servicecomb.metrics.core.publish; + +import static javax.ws.rs.core.Response.Status.BAD_REQUEST; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Component; + +import io.servicecomb.metrics.common.HealthCheckResult; +import io.servicecomb.metrics.common.HealthChecker; +import io.servicecomb.metrics.core.health.DefaultMicroserviceHealthChecker; +import io.servicecomb.swagger.invocation.exception.InvocationException; + +@Component +public class DefaultHealthCheckerManager implements HealthCheckerManager { + private final Map<String, HealthChecker> healthCheckers; + + public DefaultHealthCheckerManager() { + this.healthCheckers = new ConcurrentHashMap<>(); + HealthChecker defaultHealthChecker = new DefaultMicroserviceHealthChecker(); + this.healthCheckers.put(defaultHealthChecker.getName(), defaultHealthChecker); + } + + @Override + public void register(HealthChecker checker) { + healthCheckers.put(checker.getName(), checker); + } + + @Override + public Map<String, HealthCheckResult> check() { + return healthCheckers.entrySet().stream().collect(Collectors.toMap(Entry::getKey, e -> e.getValue().check())); + } + + @Override + public HealthCheckResult check(String name) { + HealthChecker checker = healthCheckers.get(name); + if (checker != null) { + return checker.check(); + } + throw new InvocationException(BAD_REQUEST, "HealthChecker name : " + name + " unregister"); + } +} diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/publish/DefaultHealthCheckerPublisher.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/publish/DefaultHealthCheckerPublisher.java new file mode 100644 index 0000000..69eb6b1 --- /dev/null +++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/publish/DefaultHealthCheckerPublisher.java @@ -0,0 +1,59 @@ +/* + * 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 io.servicecomb.metrics.core.publish; + +import java.util.Map; + +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import io.servicecomb.metrics.common.HealthCheckResult; +import io.servicecomb.metrics.common.HealthCheckerPublisher; +import io.servicecomb.provider.rest.common.RestSchema; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; + +@RestSchema(schemaId = "metricsEndpoint") +@RequestMapping(path = "/health") +public class DefaultHealthCheckerPublisher implements HealthCheckerPublisher { + + private final HealthCheckerManager manager; + + public DefaultHealthCheckerPublisher(HealthCheckerManager manager) { + this.manager = manager; + } + + @RequestMapping(path = "/", method = RequestMethod.GET) + @CrossOrigin + @Override + public Map<String, HealthCheckResult> health() { + return manager.check(); + } + + @ApiResponses({ + @ApiResponse(code = 400, response = String.class, message = "illegal request content"), + }) + @RequestMapping(path = "/{name}", method = RequestMethod.GET) + @CrossOrigin + @Override + public HealthCheckResult healthWithName(@PathVariable(name = "name") String name) { + return manager.check(name); + } +} diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/publish/HealthCheckerManager.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/publish/HealthCheckerManager.java new file mode 100644 index 0000000..693a7fd --- /dev/null +++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/publish/HealthCheckerManager.java @@ -0,0 +1,31 @@ +/* + * 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 io.servicecomb.metrics.core.publish; + +import java.util.Map; + +import io.servicecomb.metrics.common.HealthCheckResult; +import io.servicecomb.metrics.common.HealthChecker; + +public interface HealthCheckerManager { + void register(HealthChecker checker); + + Map<String,HealthCheckResult> check(); + + HealthCheckResult check(String name); +} diff --git a/metrics/metrics-core/src/test/java/io/servicecomb/metrics/core/TestHealthCheckerManager.java b/metrics/metrics-core/src/test/java/io/servicecomb/metrics/core/TestHealthCheckerManager.java new file mode 100644 index 0000000..4beaf66 --- /dev/null +++ b/metrics/metrics-core/src/test/java/io/servicecomb/metrics/core/TestHealthCheckerManager.java @@ -0,0 +1,81 @@ +/* + * 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 io.servicecomb.metrics.core; + +import java.io.IOException; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +import com.google.common.collect.Lists; + +import io.servicecomb.foundation.common.utils.JsonUtils; +import io.servicecomb.metrics.common.DefaultHealthCheckExtraData; +import io.servicecomb.metrics.common.HealthCheckResult; +import io.servicecomb.metrics.core.publish.DefaultHealthCheckerManager; +import io.servicecomb.metrics.core.publish.HealthCheckerManager; +import io.servicecomb.serviceregistry.RegistryUtils; +import io.servicecomb.serviceregistry.api.registry.Microservice; +import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance; +import mockit.Expectations; + +public class TestHealthCheckerManager { + + @Test + public void testRegistry() throws IOException { + + Microservice microservice = new Microservice(); + microservice.setAppId("appId"); + microservice.setServiceName("serviceName"); + microservice.setVersion("0.0.1"); + + MicroserviceInstance microserviceInstance = new MicroserviceInstance(); + microserviceInstance.setEndpoints(Lists.newArrayList("127.0.0.1", "192.168.0.100")); + microserviceInstance.setInstanceId("001"); + microserviceInstance.setHostName("localhost"); + + new Expectations(RegistryUtils.class) { + { + RegistryUtils.getMicroservice(); + result = microservice; + } + }; + + new Expectations(RegistryUtils.class) { + { + RegistryUtils.getMicroserviceInstance(); + result = microserviceInstance; + } + }; + + HealthCheckerManager manager = new DefaultHealthCheckerManager(); + Map<String, HealthCheckResult> results = manager.check(); + + Assert.assertTrue(results.get("default").isHealth()); + + DefaultHealthCheckExtraData data = JsonUtils.OBJ_MAPPER + .readValue(results.get("default").getExtraData(), DefaultHealthCheckExtraData.class); + Assert.assertTrue(data.getAppId().equals("appId")); + Assert.assertTrue(data.getServiceName().equals("serviceName")); + Assert.assertTrue(data.getServiceVersion().equals("0.0.1")); + Assert.assertTrue(data.getInstanceId().equals("001")); + Assert.assertTrue(data.getHostName().equals("localhost")); + Assert.assertTrue(data.getEndpoints().equals("127.0.0.1,192.168.0.100")); + } +} diff --git a/metrics/metrics-core/src/test/java/io/servicecomb/metrics/core/TestHealthCheckerPublisher.java b/metrics/metrics-core/src/test/java/io/servicecomb/metrics/core/TestHealthCheckerPublisher.java new file mode 100644 index 0000000..44978df --- /dev/null +++ b/metrics/metrics-core/src/test/java/io/servicecomb/metrics/core/TestHealthCheckerPublisher.java @@ -0,0 +1,59 @@ +/* + * 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 io.servicecomb.metrics.core; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +import com.fasterxml.jackson.core.JsonProcessingException; + +import io.servicecomb.foundation.common.utils.JsonUtils; +import io.servicecomb.metrics.common.HealthCheckResult; +import io.servicecomb.metrics.common.HealthCheckerPublisher; +import io.servicecomb.metrics.core.publish.DefaultHealthCheckerPublisher; +import io.servicecomb.metrics.core.publish.HealthCheckerManager; + +public class TestHealthCheckerPublisher { + + @Test + public void testPublisher() throws JsonProcessingException { + HealthCheckerManager manager = mock(HealthCheckerManager.class); + + Map<String, HealthCheckResult> results = new HashMap<>(); + HealthCheckResult result = new HealthCheckResult(true, "ok", "extra"); + results.put("default", result); + + when(manager.check()).thenReturn(results); + when(manager.check("default")).thenReturn(result); + + HealthCheckerPublisher publisher = new DefaultHealthCheckerPublisher(manager); + Map<String, HealthCheckResult> content = publisher.health(); + Assert.assertTrue(JsonUtils.writeValueAsString(content.get("default")) + .equals(JsonUtils.writeValueAsString(result))); + + HealthCheckResult checkResult = publisher.healthWithName("default"); + Assert.assertTrue(JsonUtils.writeValueAsString(checkResult) + .equals(JsonUtils.writeValueAsString(result))); + } +} -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
