Skip to content

Commit

Permalink
Merge branch 'master' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
jdubois committed Sep 12, 2017
2 parents 93018f0 + 69288a1 commit 26e1d8f
Show file tree
Hide file tree
Showing 7 changed files with 355 additions and 3 deletions.
39 changes: 39 additions & 0 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!--
- Please follow the issue template below for bug reports and feature requests.
- If you have a support request rather than a bug, please use [Stack Overflow](http://stackoverflow.com/questions/tagged/jhipster) with the JHipster tag.
- For bug reports it is mandatory to run the command `jhipster info` in your project's root folder, and paste the result here.
- Tickets opened without any of these pieces of information will be **closed** without any explanation.
-->

##### **Overview of the issue**

<!-- Explain the bug or feature request, if an error is being thrown a stack trace helps -->

##### **Motivation for or Use Case**

<!-- Explain why this is a bug or a new feature for you -->

##### **Reproduce the error**

<!-- For bug reports, an unambiguous set of steps to reproduce the error -->

##### **Related issues**

<!-- Has a similar issue been reported before? Please search both closed & open issues -->

##### **Suggest a Fix**

<!-- For bug reports, if you can't fix the bug yourself, perhaps you can point to what might be
causing the problem (line of code or commit) -->

##### **JHipster Registry Version(s)**

<!--
Which version of JHipster Registry are you using, is it a regression?
-->

##### **Browsers and Operating System**

<!-- What OS are you on? is this a problem with all browsers or only IE8? -->

- [ ] Checking this box is mandatory (this is just to show you read everything)
6 changes: 6 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- Please make sure the below checklist is followed for Pull Requests.

- [ ] [Travis tests](https://travis-ci.org/jhipster/jhipster-registry/pull_requests) are green
- [ ] Tests are added where necessary
- [ ] Documentation is added/updated where necessary
- [ ] Coding Rules & Commit Guidelines as per our [CONTRIBUTING.md document](https://github.com/jhipster/jhipster-registry/blob/master/CONTRIBUTING.md) are followed
126 changes: 126 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Contributing to the JHipster Registry

Are you ready to contribute to the JHipster Registry? We'd love to have you on board, and we will help you as much as we can.

Our contributing guidelines are basically the same as [the JHipster generator contributing guidelines](https://github.com/jhipster/generator-jhipster/blob/master/CONTRIBUTING.md).

Here are the guidelines we'd like you to follow so that we can be of more help:

- [Questions and help](#question)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Submission Guidelines](#submit)
- [Generator development setup](#setup)
- [Coding Rules](#rules)
- [Git Commit Guidelines](#commit)

## <a name="question"></a> Questions and help
This is the JHipster bug tracker, and it is used for [Issues and Bugs](#issue) and for [Feature Requests](#feature). It is **not** a help desk or a support forum.

If you have a question on using JHipster, or if you need help with your JHipster project, please [read our help page](http://www.jhipster.tech/help/) and use the [JHipster tag on StackOverflow](http://stackoverflow.com/tags/jhipster) or join our [Gitter.im chat room](https://gitter.im/jhipster/generator-jhipster).

## <a name="issue"></a> Issues and Bugs
If you find a bug in the source code or a mistake in the documentation, you can help us by [submitting a ticket](https://opensource.guide/how-to-contribute/#opening-an-issue) to our [GitHub issues](https://github.com/jhipster/jhipster-registry/issues). Even better, you can submit a Pull Request to our [JHipster Registry project](https://github.com/jhipster/jhipster-registry) or to our [Documentation project](https://github.com/jhipster/jhipster.github.io).

**Please see the Submission Guidelines below**.

## <a name="feature"></a> Feature Requests
You can request a new feature by submitting a ticket to our [GitHub issues](https://github.com/jhipster/jhipster-registry/issues). If you
would like to implement a new feature then consider what kind of change it is:

* **Major Changes** that you wish to contribute to the project should be discussed first. Please open a ticket which clearly states that it is a feature request in the title and explain clearly what you want to achieve in the description, and the JHipster team will discuss with you what should be done in that ticket. You can then start working on a Pull Request.
* **Small Changes** can be proposed without any discussion. Open up a ticket which clearly states that it is a feature request in the title. Explain your change in the description, and you can propose a Pull Request straight away.

## <a name="submit"></a> Submission Guidelines

### [Submitting an Issue](https://opensource.guide/how-to-contribute/#opening-an-issue)
Before you submit your issue search the [archive](https://github.com/jhipster/jhipster-registry/issues?utf8=%E2%9C%93&q=is%3Aissue), maybe your question was already answered.

If your issue appears to be a bug, and has not been reported, open a new issue.
Help us to maximize the effort we can spend fixing issues and adding new
features, by not reporting duplicate issues. Providing the following information will increase the
chances of your issue being dealt with quickly:

* **Overview of the issue** - if an error is being thrown a stack trace helps
* **Motivation for or Use Case** - explain why this is a bug for you
* **Reproduce the error** - an unambiguous set of steps to reproduce the error. If you have a JavaScript error, maybe you can provide a live example with
[JSFiddle](http://jsfiddle.net/)?
* **Related issues** - has a similar issue been reported before?
* **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
causing the problem (line of code or commit)
* **JHipster Registry Version(s)** - is it a regression?
* **Browsers and Operating System** - is this a problem with all browsers or only IE8?

Click [here](https://github.com/jhipster/jhipster-registry/issues/new) to open a bug issue with a pre-filled template. For feature requests and enquiries you can use [this template][feature-template].

Issues opened without any of these info will be **closed** without any explanation.

### [Submitting a Pull Request](https://opensource.guide/how-to-contribute/#opening-a-pull-request)
Before you submit your pull request consider the following guideline:

* Search [GitHub](https://github.com/jhipster/jhipster-registry/pulls?utf8=%E2%9C%93&q=is%3Apr) for an open or closed Pull Request
that relates to your submission.

## <a name="rules"></a> Coding Rules
To ensure consistency throughout the source code, keep these rules in mind as you are working:

* All features or bug fixes **must be tested** by one or more tests.
* All files must follow the [.editorconfig file](http://editorconfig.org/) located at the root of the JHipster Registry project. Please note that generated projects use the same `.editorconfig` file, so that both the generator and the generated projects share the same configuration.
* Java files **must be** formatted using [Intellij IDEA's code style](http://confluence.jetbrains.com/display/IntelliJIDEA/Code+Style+and+Formatting). Please note that JHipster committers have a free Intellij IDEA Ultimate Edition for developing the project.
* Generators JavaScript files **must follow** the eslint configuration defined at the project root, which is based on [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript).
* Web apps JavaScript files **must follow** [Google's JavaScript Style Guide](https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml).
* AngularJS files **must follow** [John Papa's Angular 1 style guide](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md).
* Angular 2+ Typescript files **must follow** [Official Angular style guide](https://angular.io/styleguide).

Please ensure to run `npm run lint` and `npm test` on the project root before submitting a pull request. You can also run `npm run lint-fix` to fix some of the lint issues automatically.

## <a name="commit"></a> Git Commit Guidelines

We have rules over how our git commit messages must be formatted. Please ensure to [squash](https://help.github.com/articles/about-git-rebase/#commands-available-while-rebasing) unnecessary commits so that your commit history is clean.

### <a name="commit-message-format"></a> Commit Message Format
Each commit message consists of a **header**, a **body** and a **footer**.

```
<header>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```

Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.

### Header
The Header contains a succinct description of the change:

* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize first letter
* no dot (.) at the end

### Body
If your change is simple, the Body is optional.

Just as in the Header, use the imperative, present tense: "change" not "changed" nor "changes".
The Body should include the motivation for the change and contrast this with previous behavior.

### Footer
The footer is the place to reference GitHub issues that this commit **Closes**.

You **must** use the [GitHub keywords](https://help.github.com/articles/closing-issues-via-commit-messages) for
automatically closing the issues referenced in your commit.

### Example
For example, here is a good commit message:

```
upgrade to Spring Boot 1.1.7
upgrade the Maven and Gradle builds to use the new Spring Boot 1.1.7,
see http://spring.io/blog/2014/09/26/spring-boot-1-1-7-released
Fix #1234
```

[feature-template]: https://github.com/jhipster/jhipster-registry/issues/new?body=*%20**Overview%20of%20the%20request**%0A%0A%3C!--%20what%20is%20the%20query%20or%20request%20--%3E%0A%0A*%20**Motivation%20for%20or%20Use%20Case**%20%0A%0A%3C!--%20explain%20why%20this%20is%20a%20required%20for%20you%20--%3E%0A%0A%0A*%20**Browsers%20and%20Operating%20System**%20%0A%0A%3C!--%20is%20this%20a%20problem%20with%20all%20browsers%20or%20only%20IE8%3F%20--%3E%0A%0A%0A*%20**Related%20issues**%20%0A%0A%3C!--%20has%20a%20similar%20issue%20been%20reported%20before%3F%20--%3E%0A%0A*%20**Suggest%20a%20Fix**%20%0A%0A%3C!--%20if%20you%20can%27t%20fix%20this%20yourself%2C%20perhaps%20you%20can%20point%20to%20what%20might%20be%0A%20%20causing%20the%20problem%20(line%20of%20code%20or%20commit)%20--%3E
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# JHipster Registry

[![Build Status][travis-image]][travis-url]
[![Build Status][travis-image]][travis-url] [![Docker Pulls](https://img.shields.io/docker/pulls/jhipster/jhipster-registry.svg)](https://hub.docker.com/r/jhipster/jhipster-registry/)

This is the [JHipster](http://jhipster.github.io/) registry service, based on [Spring Cloud Netflix](http://cloud.spring.io/spring-cloud-netflix/), [Eureka](https://github.com/Netflix/eureka) and [Spring Cloud Config](http://cloud.spring.io/spring-cloud-config/).

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<frontend-maven-plugin.version>1.3</frontend-maven-plugin.version>
<jacoco-maven-plugin.version>0.7.9</jacoco-maven-plugin.version>
<java.version>1.8</java.version>
<jhipster.server.version>1.1.7</jhipster.server.version>
<jhipster.server.version>1.1.9</jhipster.server.version>
<jjwt.version>0.7.0</jjwt.version>
<logstash-logback-encoder.version>4.9</logstash-logback-encoder.version>
<lz4.version>1.3.0</lz4.version>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
package io.github.jhipster.registry.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.stream.Collectors;

import static com.sun.nio.file.SensitivityWatchEventModifier.HIGH;
import static io.github.jhipster.config.JHipsterConstants.SPRING_PROFILE_K8S;
import static java.nio.file.FileVisitOption.FOLLOW_LINKS;
import static java.nio.file.FileVisitResult.CONTINUE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

/**
* Kubernetes (K8s) cloud config refresher service
*/
@Service
@Profile(SPRING_PROFILE_K8S)
public class CloudConfigRefreshService {

private final Logger log = LoggerFactory.getLogger(CloudConfigRefreshService.class);

private final ContextRefresher refresher;

private final String configPath;

private ScheduledExecutorService taskExecutor;

/**
* Constructor
*
* @param refresher ContextRefresher
* @param configPath String
*/
public CloudConfigRefreshService(ContextRefresher refresher, @Value("${k8s.config.path}") String configPath) {
this.refresher = refresher;
this.configPath = configPath;
}

/**
* Creates a daemon thread when {@link #getConfigPath configPath} is specified through the environment
* variable {@code k8s.config.path}. Daemon thread will execute the watcher service asynchronously.
*/
@PostConstruct
public void configMapWatcher() {
if (getConfigPath() != null && !getConfigPath().isEmpty()) {
taskExecutor = Executors.newSingleThreadScheduledExecutor(
job -> {
Thread thread = new Thread(job, "CloudConfigMapRefresher");
thread.setDaemon(true);
return thread;
}
);
taskExecutor.execute(() -> {
try {
configMapRefreshContext();
} catch (IOException | InterruptedException ex) {
log.error("Unable to refresh K8s ConfigMap", ex);
}
});
} else {
log.error("ConfigMap directory path not specified. Specify value for the environment variable k8s.config.path");
}
}

/**
* {@code WatchService} object to monitor K8s configMap path. Mounted configMap path will be recursively
* registered with the {@code WatchService} instance to get notified for interested events.
*
* @throws IOException
* @throws InterruptedException
*/
public void configMapRefreshContext() throws IOException, InterruptedException {
List<File> fileList = new ArrayList();
List<Integer> hashList = new ArrayList();
WatchService watcherService = FileSystems.getDefault().newWatchService();
Path dirPath = Paths.get(getConfigPath());
Files.walkFileTree(dirPath, new HashSet<FileVisitOption>() {
{
add(FOLLOW_LINKS);
}
}, 2, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
log.debug("Registering" + dir + " in watcher service");
dir.register(watcherService, new WatchEvent.Kind[]{ENTRY_MODIFY}, HIGH);
return CONTINUE;
}

@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
File file = path.toFile();
if (isValidConfigFile(file.getName().toLowerCase())) {
log.debug("Adding file: " + file.getAbsolutePath());
fileList.add(file);
hashList.add(getHashValue(file));
}
return CONTINUE;
}
});
while (true) {
WatchKey key = watcherService.take();
List<WatchEvent<?>> events = key.pollEvents();
if (!events.isEmpty()) {
if (log.isDebugEnabled()) {
events.forEach(event -> log.debug("Event detected: " + event.kind().name() + ", Updated File: " + event.context()));
}
Collection<Integer> activeList = fileList.stream().map(entry -> getHashValue(entry)).collect(Collectors.toList());
if (!hashList.containsAll(activeList)) {
log.debug("File system updated. Hashed content matching failed");
hashList.clear();
hashList.addAll(activeList);
refresher.refresh();
log.debug("@Refreshscope context refreshed for ConfigMap update");
} else {
// do nothing
log.debug("Hashed content unchanged. Ignore and continue");
}
if (!key.reset()) {
log.error("Unable to reset the watcher service. Try restarting the running instance");
break;
}
} else {
// do nothing
log.debug("Event list is empty. Ignore and continue.");
}
}
}

@PreDestroy
public void destroy() {
if (taskExecutor != null) {
taskExecutor.shutdown();
}
}

/**
* Generates hash value
* @param file File
* @return hasCode int
*/
private int getHashValue(File file) {
return (37 * 21 + (file.getAbsolutePath().hashCode() + (int) (file.length() ^ (file.length() >>> 32))
+ (int) (file.lastModified() ^ (file.lastModified() >>> 32))));
}

/**
* Checks for valid file extension
*
* @param name String - file name
* @return boolean
*/
private boolean isValidConfigFile(String name) {
return name.endsWith(".yml") || name.endsWith(".yaml") || name.endsWith(".properties");
}

/**
* Returns config path
*
* @return configPath String
*/
public String getConfigPath() {
return configPath;
}
}
2 changes: 1 addition & 1 deletion src/main/resources/config/bootstrap-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ spring:
fail-fast: true
# name of the config server's property source (file.yml) that we want to use
name: jhipster-registry
profile: dev # profile(s) of the property source
profile: prod # profile(s) of the property source
label: master # toggle to switch to a different version of the configuration as stored in git
# it can be set to any label, branch or commit of the config source git repository

Expand Down

0 comments on commit 26e1d8f

Please sign in to comment.