Skip to content

Commit

Permalink
Add command-line interface
Browse files Browse the repository at this point in the history
to ease generating a keypair and sending a notification.
  • Loading branch information
martijndwars committed May 29, 2017
1 parent ba06937 commit 184c34b
Show file tree
Hide file tree
Showing 15 changed files with 406 additions and 66 deletions.
61 changes: 60 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,66 @@ For Maven, add the following dependency to `pom.xml`:
</dependency>
```

## Usage
## Building

To build the project yourself, clone this repository and build a run:

```
./gradlew assemble
```

To build a fat JAR in `build/libs` (e.g. to use the CLI):

```
./gradlew shadowJar
```

## CLI

A command-line interface is available to easily generate a keypair (for VAPID) and to try sending a notification.

```
Usage: <main class> [command] [command options]
Commands:
generate-key Generate a VAPID keypair
Usage: generate-key
send-notification Send a push notification
Usage: send-notification [options]
Options:
--subscription
A subscription in JSON format.
--publicKey
The public key as base64url encoded string.
--privateKey
The private key as base64url encoded string.
--payload
The message to send.
Default: Hello, world!
```

For example, to generate a keypair and output the keys in base64url encoding:

```
$ java -jar build/libs/web-push-3.0.0-all.jar generate-key
PublicKey:
BGgL7I82SAQM78oyGwaJdrQFhVfZqL9h4Y18BLtgJQ-9pSGXwxqAWQudqmcv41RcWgk1ssUeItv4-8khxbhYveM=
PrivateKey:
ANlfcVVFB4JiMYcI74_h9h04QZ1Ks96AyEa1yrMgDwn3
```

Use the public key in the call to `pushManager.subscribe` to get a subscription. Then, to send a notification:

```
$ java -jar build/libs/web-push-3.0.0-all.jar send-notification \
--subscription="{'endpoint':'https://fcm.googleapis.com/fcm/send/fH-M3xRoLms:APA91bGB0rkNdxTFsXaJGyyyY7LtEmtHJXy8EqW48zSssxDXXACWCvc9eXjBVU54nrBkARTj4Xvl303PoNc0_rwAMrY9dvkQzi9fkaKLP0vlwoB0uqKygPeL77Y19VYHbj_v_FolUlHa','keys':{'p256dh':'BOtBVgsHVWXzwhDAoFE8P2IgQvabz_tuJjIlNacmS3XZ3fRDuVWiBp8bPR3vHCA78edquclcXXYb-olcj3QtIZ4=','auth':'IOScBh9LW5mJ_K2JwXyNqQ=='}}" \
--publicKey="BGgL7I82SAQM78oyGwaJdrQFhVfZqL9h4Y18BLtgJQ-9pSGXwxqAWQudqmcv41RcWgk1ssUeItv4-8khxbhYveM=" \
--privateKey="ANlfcVVFB4JiMYcI74_h9h04QZ1Ks96AyEa1yrMgDwn3"
--payload="Hello, lovely world!"
```

## API

First, create an instance of the push service:

Expand Down
67 changes: 44 additions & 23 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0-M4'
classpath 'io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.8.0'
}
}

plugins {
id 'com.github.johnrengelman.shadow' version '2.0.0'
}

group 'nl.martijndwars'
version '3.0.0'

apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'signing'
apply plugin: 'org.junit.platform.gradle.plugin'
apply plugin: 'io.codearte.nexus-staging'

task wrapper(type: Wrapper) {
gradleVersion = '3.0'
}

compileJava {
sourceCompatibility = 1.7
Expand All @@ -20,12 +39,22 @@ jar {
version = '3.0.0'
}

buildscript {
repositories {
mavenCentral()
}
shadowJar {
// BouncyCastle JAR is signed; it cannot be extracted and merged into the fat JAR.
dependencies {
classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0-M4'
exclude(
dependency(group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.54')
)
}
manifest {
attributes 'Main-Class': 'nl.martijndwars.webpush.cli.Cli',
'Class-Path': '../../lib/bcprov-jdk15on-154.jar'
}
}

junitPlatform {
selectors {
aClass 'nl.martijndwars.webpush.selenium.SeleniumTests'
}
}

Expand All @@ -40,14 +69,10 @@ task sourcesJar(type: Jar) {
}

artifacts {
archives jar

archives javadocJar
archives sourcesJar
archives javadocJar, sourcesJar
}

signing {
required { gradle.taskGraph.hasTask("uploadArchives") }
sign configurations.archives
}

Expand All @@ -57,17 +82,11 @@ uploadArchives {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }

repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
authentication(
userName: project.hasProperty('ossrhUsername') ? ossrhUsername : '',
password: project.hasProperty('ossrhPassword') ? ossrhPassword : ''
)
authentication(userName: ossrhUsername, password: ossrhPassword)
}

snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
authentication(
userName: project.hasProperty('ossrhUsername') ? ossrhUsername : '',
password: project.hasProperty('ossrhPassword') ? ossrhPassword : ''
)
authentication(userName: ossrhUsername, password: ossrhPassword)
}

pom.project {
Expand Down Expand Up @@ -107,8 +126,11 @@ repositories {
}

dependencies {
// For making HTTP requests
testCompile group: 'org.apache.httpcomponents', name: 'fluent-hc', version: '4.5.2'
// For CLI
compile group: 'com.beust', name: 'jcommander', version: '1.69'

// For parsing JSON
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.0'

// For making async HTTP requests
compile group: 'org.apache.httpcomponents', name: 'httpasyncclient', version: '4.1.3'
Expand All @@ -122,6 +144,8 @@ dependencies {
// For creating and signing JWT
compile group: 'org.bitbucket.b_c', name: 'jose4j', version: '0.5.2'

// For making HTTP requests
testCompile group: 'org.apache.httpcomponents', name: 'fluent-hc', version: '4.5.2'

// For testing, obviously
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.0.0-M4'
Expand All @@ -132,9 +156,6 @@ dependencies {
// For turning InputStream to String
testCompile group: 'commons-io', name: 'commons-io', version: '2.5'

// For parsing JSON
testCompile group: 'com.google.code.gson', name: 'gson', version: '2.8.0'

// For reading the demo vapid keypair from a pem file
testCompile group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: '1.55'
}
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Thu Sep 15 19:54:55 CEST 2016
#Mon May 29 11:45:53 PDT 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-3.0-all.zip
57 changes: 31 additions & 26 deletions gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,30 @@
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

Expand All @@ -30,6 +48,7 @@ die ( ) {
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
Expand All @@ -40,31 +59,11 @@ case "`uname`" in
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac

# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
Expand All @@ -90,7 +89,7 @@ location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
Expand All @@ -114,6 +113,7 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`

# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
Expand Down Expand Up @@ -161,4 +161,9 @@ function splitJvmOpts() {
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then
cd "$(dirname "$0")"
fi

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
14 changes: 4 additions & 10 deletions gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

Expand Down Expand Up @@ -46,10 +46,9 @@ echo location of your Java installation.
goto fail

:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
Expand All @@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line
Expand Down
Binary file added lib/bcprov-jdk15on-154.jar
Binary file not shown.
Loading

0 comments on commit 184c34b

Please sign in to comment.