Skip to content

Commit fcf6e73

Browse files
authored
Merge pull request #268 from hivemq/develop
Release 1.0.1
2 parents 17c8eb8 + b0b029b commit fcf6e73

File tree

162 files changed

+3049
-436
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

162 files changed

+3049
-436
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
name: Bug report
3+
about: Create a report to help us improve
4+
title: ''
5+
labels: ''
6+
assignees: ''
7+
8+
---
9+
10+
## Expected behavior
11+
12+
## Actual behavior
13+
14+
## To Reproduce
15+
### Steps
16+
17+
### Reproducer code
18+
19+
## Details
20+
- Affected HiveMQ MQTT Client version(s):
21+
- Used JVM version:
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
name: Feature request
3+
about: Suggest an idea for this project
4+
title: ''
5+
labels: ''
6+
assignees: ''
7+
8+
---
9+
10+
## Problem or use case
11+
12+
## Preferred solution or suggestions

.travis.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,8 @@ jobs:
2121
- stage: release
2222
install: true
2323
script: ./gradlew bintrayUpload -x test
24+
25+
addons:
26+
apt:
27+
packages:
28+
- perl

CONTRIBUTING.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Contributing
2+
3+
## External contributors
4+
If you would like to contribute code, do the following:
5+
- Fork the repository on GitHub
6+
- Open a pull request targeting the `develop` branch
7+
8+
## License
9+
By contributing your code, you agree to license your contribution under the terms of the
10+
[Apache License, Version 2.0](https://github.com/hivemq/hivemq-mqtt-client/blob/develop/LICENSE).
11+
12+
All files must contain the license header from the
13+
[HEADER](https://github.com/hivemq/hivemq-mqtt-client/blob/develop/HEADER) file.
14+
15+
## Branching model
16+
17+
- `master`: release branch, protected
18+
- `develop` is merged into `master` by creating a merge commit if a new version is released
19+
- The release is tagged with the version `vX.Y.Z`
20+
- `develop`: snapshot branch, protected
21+
- Contains features for the next release
22+
- Feature/bugfix/... branches are merged into `develop` by rebasing and merging
23+
- Every feature/bugfix/... will have its own branch
24+
- Branched off from `develop`
25+
- Pull request targeting the `develop` branch
26+
- Mandatory code review of the pull request
27+
28+
## Branching guidelines
29+
30+
- Branch types: feature, bugfix, improvement, cleanup (same as the label of a corresponding GitHub Issue)
31+
- Branch names:
32+
- Starting with type: `feature/`, `bugfix/`, `improvement/`, `cleanup/`
33+
- \+ task: lower case, spaces replaced with `-`
34+
35+
## Commit guidelines
36+
37+
- Commits should be as atomic as possible.
38+
- Commit messages should describe the changes clearly.
39+
- Commit messages should start with a capital letter for consistency.
40+
- Commit messages should avoid exceeding the line length limit. Instead use multiple lines, each describing one specific
41+
change.
42+
43+
## Code style guidelines
44+
45+
- The project uses Nullability annotations to avoid NullPointerExceptions: `@NotNull`, `@Nullable`.
46+
Every non-primitive parameter/return type/field should be annotated with one of them.
47+
- For IntelliJ IDEA the codeStyleConfig and the inspectionProfile are provided in the `.idea` folder.

README.md

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# HiveMQ MQTT Client
22

3+
<img src="https://www.hivemq.com/img/svg/hivemq-mqtt-client.svg" width="500">
4+
35
[![Build Status](https://travis-ci.org/hivemq/hivemq-mqtt-client.svg?branch=develop)](https://travis-ci.org/hivemq/hivemq-mqtt-client)
6+
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.hivemq/hivemq-mqtt-client/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.hivemq/hivemq-mqtt-client)
47

58
MQTT 5.0 and 3.1.1 compatible and feature-rich high-performance Java client library with different API flavours and
69
backpressure support.
@@ -40,8 +43,6 @@ Java 8 or higher is required.
4043

4144
## Dependency
4245

43-
IMPORTANT: The library is not released to Maven Central yet, so only the snapshot versions are working for now.
44-
4546
### Gradle
4647

4748
If you use Gradle, just include the following inside your `build.gradle` file.
@@ -112,6 +113,8 @@ dependencies {
112113
Every time a PR is merged into the `develop` branch, a new snapshot is published.
113114
A snapshot can be included as a normal dependency if the snapshot repository is added to the build file.
114115

116+
IMPORTANT: The snapshot versions are not available for now.
117+
115118
#### Gradle
116119

117120
```groovy
@@ -577,29 +580,13 @@ API but return `Completable`.
577580

578581
`reauth()` method call is analog to the Async and Blocking API but return `Completable`.
579582

580-
# How to contribute
581-
582-
## Branching model
583-
584-
- `master`: release branch
585-
- `develop`: snapshot branch, branch where features for the next release are merged into
586-
- Every feature or bugfix will have its own branch, branched from develop, merged back into develop after the code
587-
review of the pull request
588-
589-
## Branching guidelines
590-
591-
- Branch types: feature, bugfix, improvement, cleanup (same as the label of a corresponding GitHub Issue)
592-
- Branch names:
593-
- Starting with type: `feature/`, `bugfix/`, `improvement/`, `cleanup/`
594-
- \+ task: lower case, spaces replaced with `-`
583+
# Versioning
595584

596-
## Commit message guidelines
585+
[Semantic Versioning](https://semver.org/) is used.
597586

598-
- Commits should be as atomic as possible.
599-
- Commits do not have to follow strict guidelines, but they should describe the changes clearly.
587+
All code inside `com.hivemq.client.internal` packages must not be used directly. It can change at any time and is not
588+
part of the public API.
600589

601-
## Code style guidelines
590+
# Contributing
602591

603-
- The project uses Nullability annotations to avoid NullPointerExceptions: `@NotNull`, `@Nullable`.
604-
Every non-primitive parameter/return type/field should be annotated with one of them.
605-
- For IntelliJ IDEA the codeStyleConfig and the inspectionProfile are provided in the `.idea` folder.
592+
See [CONTRIBUTING.md](CONTRIBUTING.md)

build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ plugins {
1313
}
1414

1515
group 'com.hivemq'
16-
version '1.0.0' + (Boolean.valueOf(System.getProperty("snapshot")) ? "-SNAPSHOT" : "")
16+
version '1.0.1' + (Boolean.valueOf(System.getProperty("snapshot")) ? "-SNAPSHOT" : "")
1717
description 'HiveMQ MQTT Client is a MQTT 5.0 and MQTT 3.1.1 compatible and feature-rich high-performance Java client ' +
1818
'library with different API flavours and backpressure support'
1919

@@ -76,7 +76,7 @@ dependencies {
7676
testRuntimeOnly group: 'org.junit.platform', name: 'junit-platform-runner', version: junitPlatformVersion
7777

7878
testImplementation group: 'org.eclipse.paho', name: 'org.eclipse.paho.client.mqttv3', version: '1.2.0'
79-
testImplementation group: 'nl.jqno.equalsverifier', name: 'equalsverifier', version: '2.4.1'
79+
testImplementation group: 'nl.jqno.equalsverifier', name: 'equalsverifier', version: '3.1.7'
8080
testImplementation group: 'org.mockito', name: 'mockito-core', version: '2.18.3'
8181
testImplementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.59'
8282
testImplementation group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: '1.59'
@@ -85,6 +85,7 @@ dependencies {
8585
}
8686

8787
apply from: 'publishing.gradle'
88+
apply from: 'japicc.gradle'
8889

8990
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
9091

japicc.gradle

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
task japicc {
2+
group 'verification'
3+
description 'Checks for binary and source incompatibility.'
4+
5+
dependsOn jar, shadowJar
6+
7+
def japiccVersion = '2.4'
8+
def workingDir = new File(project.buildDir, 'japicc')
9+
def executable = new File(workingDir, 'japi-compliance-checker-' + japiccVersion + '/japi-compliance-checker.pl')
10+
11+
def lastSemVer = lastSemVer()
12+
def shadedName = project.name + '-' + shadedAppendix
13+
def lastJar = new File(workingDir, project.name + '-' + lastSemVer + '.jar')
14+
def lastShadedJar = new File(workingDir, shadedName + '-' + lastSemVer + '.jar')
15+
16+
def nonImplFile = new File(workingDir, 'non-impl')
17+
18+
def reportDir = new File(workingDir, 'compat_reports')
19+
def versions = lastSemVer + '_to_' + project.version
20+
def report = new File(new File(new File(reportDir, project.name), versions), 'compat_report.html')
21+
def shadedReport = new File(new File(new File(reportDir, shadedName), versions), 'compat_report.html')
22+
23+
inputs.files jar, shadowJar
24+
outputs.files files(report, shadedReport)
25+
26+
doFirst {
27+
description 'Check if last semantic version is available'
28+
println(description)
29+
30+
if (project.version == lastSemVer) {
31+
throw new StopExecutionException('No last semantic version available')
32+
}
33+
}
34+
35+
doLast {
36+
description 'List non impl interfaces'
37+
println(description)
38+
39+
nonImplFile.delete()
40+
nonImplFile.createNewFile()
41+
42+
sourceSets.main.java.visit { FileTreeElement f ->
43+
if (f.file.isFile()) {
44+
def packageName = f.relativePath.parent.pathString.replace('/', '.').replace('\\', '.')
45+
46+
def content = f.file.getText("UTF-8")
47+
content = content.replaceAll('//.*\n', ' ') // remove line comments
48+
content = content.replaceAll('\n', ' ') // remove new lines
49+
content = content.replaceAll('/\\*.*?\\*/', ' ') // remove multi line comments
50+
content = content.replaceAll(' +', ' ') // remove unnecessary spaces
51+
52+
def index = 0
53+
def classNames = []
54+
while (true) {
55+
def start = content.indexOf(' interface ', index)
56+
if (start == -1) break
57+
58+
def sub = content.substring(0, start)
59+
def level = sub.count('{') - sub.count('}')
60+
while (level < classNames.size()) {
61+
classNames.remove(classNames.size() - 1)
62+
}
63+
64+
start += ' interface '.length()
65+
def end = content.indexOf('{', start)
66+
if (end == -1) break
67+
68+
def interfaceDef = content.substring(start, end)
69+
def className = interfaceDef.split('[ <{]', 2)[0]
70+
classNames.add(className)
71+
72+
def annotationIndex = content.indexOf('@DoNotImplement', index)
73+
if (annotationIndex == -1) break
74+
75+
if (annotationIndex < start) {
76+
def qualifiedName = packageName + "." + classNames.join('.')
77+
78+
def rest = interfaceDef.substring(className.length()).trim()
79+
if (rest.startsWith('<')) {
80+
rest = rest.replaceAll('extends [^ <,]+', '') // remove all extends ...
81+
rest = rest.replaceAll('@.*? ', '') // remove all annotations
82+
def generics = '<'
83+
def nesting = 0
84+
for (def c : rest.chars) {
85+
if (c == '<') {
86+
nesting++
87+
} else if (c == '>') {
88+
nesting--
89+
} else if (nesting == 1) {
90+
generics += c
91+
} else if (nesting == 0) {
92+
break
93+
}
94+
}
95+
generics += '>'
96+
generics = generics.replace(' ', '')
97+
qualifiedName += generics
98+
}
99+
100+
nonImplFile.append(qualifiedName + '\n')
101+
}
102+
103+
index = end + 1
104+
}
105+
}
106+
}
107+
}
108+
109+
doLast {
110+
description 'Download Java API Compliance Checker'
111+
println(description)
112+
113+
def archive = new File(workingDir, 'japi-compliance-checker-' + japiccVersion + '.zip')
114+
archive.parentFile.mkdirs()
115+
if (!archive.exists()) {
116+
new URL('https://github.com/lvc/japi-compliance-checker/archive/' + japiccVersion + '.zip')
117+
.withInputStream { i -> archive.withOutputStream { it << i } }
118+
119+
copy {
120+
from zipTree(archive)
121+
into workingDir
122+
}
123+
}
124+
}
125+
126+
doLast {
127+
description 'Download last version'
128+
println(description)
129+
130+
lastJar.parentFile.mkdirs()
131+
if (!lastJar.exists()) {
132+
String path = project.group.replace('.', '/')
133+
path += '/' + project.name + '/' + lastSemVer + '/'
134+
path += project.name + '-' + lastSemVer + '.jar'
135+
new URL('http://central.maven.org/maven2/' + path)
136+
.withInputStream { i -> lastJar.withOutputStream { it << i } }
137+
}
138+
}
139+
140+
doLast {
141+
description 'Download last shaded version'
142+
println(description)
143+
144+
lastShadedJar.parentFile.mkdirs()
145+
if (!lastShadedJar.exists()) {
146+
String path = project.group.replace('.', '/')
147+
path += '/' + shadedName + '/' + lastSemVer + '/'
148+
path += shadedName + '-' + lastSemVer + '.jar'
149+
new URL('http://central.maven.org/maven2/' + path)
150+
.withInputStream { i -> lastShadedJar.withOutputStream { it << i } }
151+
}
152+
}
153+
154+
doLast {
155+
description 'Check binary and source compatibility for last version'
156+
println(description)
157+
158+
def command = ['perl', executable.getPath(), '-lib', project.name,
159+
'-skip-internal-packages', 'com.hivemq.client.internal',
160+
'-non-impl', nonImplFile.getPath(),
161+
'-check-annotations', '-s',
162+
lastJar.getPath(), jar.archivePath.getPath()]
163+
164+
def process = new ProcessBuilder(command).directory(workingDir).start()
165+
def returnCode = process.waitFor()
166+
if (returnCode != 0) {
167+
throw new GradleException('Binary or source incompatibilities, code ' + returnCode)
168+
}
169+
}
170+
171+
doLast {
172+
description 'Check binary and source compatibility for last shaded version'
173+
println(description)
174+
175+
def command = ['perl', executable.getPath(), '-lib', shadedName,
176+
'-skip-internal-packages', 'com.hivemq.client.internal',
177+
'-skip-internal-packages', 'com.hivemq.shaded',
178+
'-non-impl', nonImplFile.getPath(),
179+
'-check-annotations', '-s',
180+
lastShadedJar.getPath(), shadowJar.archivePath.getPath()]
181+
182+
def process = new ProcessBuilder(command).directory(workingDir).start()
183+
def returnCode = process.waitFor()
184+
if (returnCode != 0) {
185+
throw new GradleException('Binary or source incompatibilities in shaded, code ' + returnCode)
186+
}
187+
}
188+
}
189+
190+
tasks.check.dependsOn(japicc)
191+
192+
String lastSemVer() {
193+
String version = project.version
194+
def split = version.split('-')[0].split('\\.')
195+
def major = Integer.valueOf(split[0])
196+
def minor = Integer.valueOf(split[1])
197+
def patch = Integer.valueOf(split[2])
198+
if (patch > 0) {
199+
patch--
200+
} else if (minor > 0) {
201+
minor--
202+
}
203+
return major + '.' + minor + '.' + patch
204+
}

0 commit comments

Comments
 (0)