From f208c016e6be7b86860bbc6c034c392de366d8a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BB=96=E5=B8=88=E5=85=84?= Date: Mon, 5 Feb 2018 15:02:05 +0800 Subject: [PATCH] handler for the gitee webhook format. https://gitee.com is the most popular git server in China. Fixes https://github.com/spring-cloud/spring-cloud-config/issues/898 --- .../main/asciidoc/spring-cloud-config.adoc | 6 +- .../EnvironmentMonitorAutoConfiguration.java | 5 ++ ...iteePropertyPathNotificationExtractor.java | 49 ++++++++++++++ ...ironmentMonitorAutoConfigurationTests.java | 4 +- ...ropertyPathNotificationExtractorTests.java | 64 +++++++++++++++++++ .../src/test/resources/gitee.json | 45 +++++++++++++ 6 files changed, 168 insertions(+), 5 deletions(-) create mode 100644 spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/GiteePropertyPathNotificationExtractor.java create mode 100644 spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/GiteePropertyPathNotificationExtractorTests.java create mode 100644 spring-cloud-config-monitor/src/test/resources/gitee.json diff --git a/docs/src/main/asciidoc/spring-cloud-config.adoc b/docs/src/main/asciidoc/spring-cloud-config.adoc index 5edc3687..2589332f 100644 --- a/docs/src/main/asciidoc/spring-cloud-config.adoc +++ b/docs/src/main/asciidoc/spring-cloud-config.adoc @@ -1220,7 +1220,7 @@ annotation (just set `spring.cloud.config.server.bootstrap=true`). == Push Notifications and Spring Cloud Bus -Many source code repository providers (like Github, Gitlab or Bitbucket +Many source code repository providers (like Github, Gitlab, Gitee or Bitbucket for instance) will notify you of changes in a repository through a webhook. You can configure the webhook via the provider's user interface as a URL and a set of events in which you are @@ -1242,8 +1242,8 @@ if you want to override the behaviour is `PropertyPathNotificationExtractor` which accepts the request headers and body as parameters and returns a list of file paths that changed. -The default configuration works out of the box with Github, Gitlab or -Bitbucket. In addition to the JSON notifications from Github, Gitlab +The default configuration works out of the box with Github, Gitlab, Gitee or +Bitbucket. In addition to the JSON notifications from Github, Gitlab, Gitee or Bitbucket you can trigger a change notification by POSTing to "/monitor" with a form-encoded body parameters `path={name}`. This will broadcast to applications matching the "{name}" pattern (can contain diff --git a/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfiguration.java b/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfiguration.java index 510621f6..6ecbe029 100644 --- a/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfiguration.java +++ b/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfiguration.java @@ -64,6 +64,11 @@ public class EnvironmentMonitorAutoConfiguration { return new BitbucketPropertyPathNotificationExtractor(); } + @Bean + @ConditionalOnProperty(value="spring.cloud.config.server.monitor.gitee.enabled", havingValue="true", matchIfMissing=true) + public GiteePropertyPathNotificationExtractor giteePropertyPathNotificationExtractor() { + return new GiteePropertyPathNotificationExtractor(); + } } } diff --git a/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/GiteePropertyPathNotificationExtractor.java b/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/GiteePropertyPathNotificationExtractor.java new file mode 100644 index 00000000..a3d38cb6 --- /dev/null +++ b/spring-cloud-config-monitor/src/main/java/org/springframework/cloud/config/monitor/GiteePropertyPathNotificationExtractor.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015 the original author or authors. + * + * 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 + * + * 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.springframework.cloud.config.monitor; + +import java.util.Collection; +import java.util.Map; + +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.util.MultiValueMap; + +/** + * @author lly835 + * + */ +@Order(Ordered.LOWEST_PRECEDENCE - 100) +public class GiteePropertyPathNotificationExtractor + implements PropertyPathNotificationExtractor { + + private static final String HEADERS_KEY = "x-git-oschina-event"; + + private static final String HEADERS_VALUE = "Push Hook"; + + @Override + public PropertyPathNotification extract(MultiValueMap headers, + Map request) { + if (HEADERS_VALUE.equals(headers.getFirst(HEADERS_KEY))) { + if (request.get("commits") instanceof Collection && + ((Collection>) request.get("commits")).size() > 0) { + return new PropertyPathNotification("application.yml"); + } + } + return null; + } +} diff --git a/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfigurationTests.java b/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfigurationTests.java index 58a54f2e..4a2feab6 100644 --- a/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfigurationTests.java +++ b/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/EnvironmentMonitorAutoConfigurationTests.java @@ -47,7 +47,7 @@ public class EnvironmentMonitorAutoConfigurationTests { PropertyPlaceholderAutoConfiguration.class).properties("server.port=-1") .run(); PropertyPathEndpoint endpoint = context.getBean(PropertyPathEndpoint.class); - assertEquals(4, + assertEquals(5, ((Collection) ReflectionTestUtils.getField( ReflectionTestUtils.getField(endpoint, "extractor"), "extractors")).size()); @@ -63,7 +63,7 @@ public class EnvironmentMonitorAutoConfigurationTests { PropertyPlaceholderAutoConfiguration.class).properties("server.port=-1") .run(); PropertyPathEndpoint endpoint = context.getBean(PropertyPathEndpoint.class); - assertEquals(5, + assertEquals(6, ((Collection) ReflectionTestUtils.getField( ReflectionTestUtils.getField(endpoint, "extractor"), "extractors")).size()); diff --git a/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/GiteePropertyPathNotificationExtractorTests.java b/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/GiteePropertyPathNotificationExtractorTests.java new file mode 100644 index 00000000..42ff145d --- /dev/null +++ b/spring-cloud-config-monitor/src/test/java/org/springframework/cloud/config/monitor/GiteePropertyPathNotificationExtractorTests.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015 the original author or authors. + * + * 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 + * + * 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.springframework.cloud.config.monitor; + +import java.util.Map; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.HttpHeaders; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +/** + * @author lly835 + * + */ +public class GiteePropertyPathNotificationExtractorTests { + + private GiteePropertyPathNotificationExtractor extractor = new GiteePropertyPathNotificationExtractor(); + + private HttpHeaders headers = new HttpHeaders(); + + @Test + public void githubSample() throws Exception { + // See http://git.mydoc.io/?t=154711 + Map value = new ObjectMapper().readValue( + new ClassPathResource("gitee.json").getInputStream(), + new TypeReference>() { + }); + this.headers.set("x-git-oschina-event", "Push Hook"); + PropertyPathNotification extracted = this.extractor.extract(this.headers, value); + assertNotNull(extracted); + assertEquals("application.yml", extracted.getPaths()[0]); + } + + @Test + public void notAPushNotDetected() throws Exception { + Map value = new ObjectMapper().readValue( + new ClassPathResource("github.json").getInputStream(), + new TypeReference>() { + }); + this.headers.set("x-git-oschina-event", "Issue Hook"); + PropertyPathNotification extracted = this.extractor.extract(this.headers, value); + assertNull(extracted); + } + +} diff --git a/spring-cloud-config-monitor/src/test/resources/gitee.json b/spring-cloud-config-monitor/src/test/resources/gitee.json new file mode 100644 index 00000000..3b05e12a --- /dev/null +++ b/spring-cloud-config-monitor/src/test/resources/gitee.json @@ -0,0 +1,45 @@ +{ + "before": "fb32ef5812dc132ece716a05c50c7531c6dc1b4d", + "after": "ac63b9ba95191a1bf79d60bc262851a66c12cda1", + "ref": "refs/heads/master", + "user_id": 13, + "user_name": "123", + "user": { + "name": "123", + "username": "test123", + "url": "https://gitee.com/oschina" + }, + "repository": { + "name": "webhook", + "url": "http://git.oschina.net/oschina/webhook", + "description": "", + "homepage": "https://gitee.com/oschina/webhook" + }, + "commits": [{ + "id": "ac63b9ba95191a1bf79d60bc262851a66c12cda1", + "message": "1234 bug fix", + "timestamp": "2016-12-09T17:28:02 08:00", + "url": "https://gitee.com/oschina/webhook/commit/ac63b9ba95191a1bf79d60bc262851a66c12cda1", + "author": { + "name": "123", + "email": "123@123.com", + "time": "2016-12-09T17:28:02 08:00" + } + }], + "total_commits_count": 1, + "commits_more_than_ten": false, + "project": { + "name": "webhook", + "path": "webhook", + "url": "https://gitee.com/oschina/webhook", + "git_ssh_url": "git@gitee.com:oschina/webhook.git", + "git_http_url": "https://gitee.com/oschina/webhook.git", + "git_svn_url": "svn://gitee.com/oschina/webhook", + "namespace": "oschina", + "name_with_namespace": "oschina/webhook", + "path_with_namespace": "oschina/webhook", + "default_branch": "master" + }, + "hook_name": "push_hooks", + "password": "pwd" +} \ No newline at end of file