diff --git a/.gitignore b/.gitignore index d8b1d16..f86140d 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ release.properties dependency-reduced-pom.xml buildNumber.properties .mvn/timing.properties +.mvn/settings.xml diff --git a/.mvn/maven.config b/.mvn/maven.config new file mode 100644 index 0000000..ba42136 --- /dev/null +++ b/.mvn/maven.config @@ -0,0 +1 @@ +-s.mvn/settings.xml diff --git a/.mvn/settings.example.xml b/.mvn/settings.example.xml new file mode 100644 index 0000000..747ace6 --- /dev/null +++ b/.mvn/settings.example.xml @@ -0,0 +1,24 @@ + + + + + + central + *** + *** + + + + + central + + true + + + + *** + *** + + + + diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..1c8099f --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog + +1.0.0 (2015) +- Initial Release +1.0.8 +- add support for bearer tokens +1.0.9 +- fanout byte change diff --git a/README.md b/README.md index b01d146..5225e55 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Maven: org.fanout pubcontrol - 1.0.7 + 1.0.9 ``` @@ -37,7 +37,6 @@ Usage ```java import org.fanout.pubcontrol.*; -import javax.xml.bind.DatatypeConverter; import java.util.*; public class PubControlExample { @@ -76,9 +75,9 @@ public class PubControlExample { // Initialize PubControl with a single endpoint: List> config = new ArrayList>(); Map entry = new HashMap(); - entry.put("uri", "https://api.fanout.io/realm/"); - entry.put("iss", ""); - entry.put("key", DatatypeConverter.parseBase64Binary("")); + entry.put("uri", "https://api.fastly.com/service/"); + // The API token needs to have purge permission + entry.put("key", ""); config.add(entry); PubControl pub = new PubControl(config); @@ -96,7 +95,7 @@ public class PubControlExample { pub.removeAllClients(); // Explicitly add an endpoint as a PubControlClient instance: - PubControlClient pubClient = new PubControlClient(""); // Optionally set JWT auth: pubClient.setAuthJwt(, '') // Optionally set basic auth: pubClient.setAuthBasic('', '') pub.addClient(pubClient); diff --git a/RELEASING_TO_MAVEN.md b/RELEASING_TO_MAVEN.md new file mode 100644 index 0000000..9af6ee7 --- /dev/null +++ b/RELEASING_TO_MAVEN.md @@ -0,0 +1,81 @@ +## Releasing to Maven Central Repository + +This package is released to Maven Central Repository by using Maven with the `central-publishing-maven-plugin`. + +This process has been tested with OpenJDK 17.0.17 and Maven 3.9.12. + +This is released under the `org.fanout` group ID, which is maintained by Fastly. + +### Credentials + +This package is published to Maven Central using a User Token under a Maven Central Repository account. + +### GPG key + +Publishing requires you to prove your identity using GPG. Create a GPG keypair for the email associated with your Maven Central Repository account. + +Once you have published your GPG public key, note its key name and passphrase. + +## Configure Maven + +You will need copy `./.mvn/settings.example.xml` to `./.mvn/settings.xml`, and fill in the following using the User Token credentials and your GPG keyname and passphrase. Do not commit this file to source control. + +```xml + + + + central + + **USERNAME** + **PASSWORD** + + + + + central + + true + + + **KEYNAME** + **PASSPHRASE** + + + + +``` + +## Release + +The following steps should be taken on each release. + +1. Update docs + version + - Update `README.md` / `CHANGELOG.md` + - Bump `` in `pom.xml` + - Commit (replace 1.0.0 below with the version you're releasing) + ```shell + git commit -m "Release 1.0.0" + ``` +2. Tag the release + - Create a tag + ```shell + git tag v1.0.0 + ``` +3. Push commit + tag + ```shell + git push + git push --tags + ``` +4. Validate that tests pass, everything builds, sources/javadoc are valid, and GPG signing works. + ```shell + mvn clean verify + ``` +5. Release to Maven using the commands: + ```shell + mvn clean deploy + ``` +6. Complete publishing. + - Visit https://central.sonatype.com/publishing/deployments. You should see: + - Deployment ID, matching the deployment ID in the output above + - Status: Validated + - Click the **Publish** button. diff --git a/pom.xml b/pom.xml index 7836efc..9bc9d2f 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.fanout pubcontrol jar - 1.0.7 + 1.0.9 pubcontrol Java EPCP library. https://github.com/fanout/java-pubcontrol @@ -12,6 +12,10 @@ scm:git:git@github.com:fanout/java-pubcontrol.git git@github.com:fanout/java-pubcontrol.git + + UTF-8 + UTF-8 + Konstantin Bokarius @@ -45,32 +49,35 @@ 2.3.1 - - - sonatype-nexus-snapshots - Sonatype Nexus snapshot repository - https://oss.sonatype.org/content/repositories/snapshots - - - sonatype-nexus-staging - Sonatype Nexus release repository - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - org.apache.maven.plugins - maven-release-plugin - 2.2.2 - - -Dgpg.passphrase=${gpg.passphrase} - + org.sonatype.central + central-publishing-maven-plugin + 0.9.0 + true + + central + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-clean-plugin + 3.1.0 org.apache.maven.plugins maven-enforcer-plugin - 1.4.1 + 3.3.0 enforce-java @@ -80,69 +87,60 @@ - 1.6.0 + [1.8,) + + org.apache.maven.plugins + maven-source-plugin + 3.4.0 + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + ${java.home}/bin/javadoc + + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + ${gpg.keyName} + ${gpg.passphrase} + + + + sign-artifacts + verify + + sign + + + + - - - release-sign-artifacts - - - performRelease - true - - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.4 - - ${gpg.passphrase} - - - - sign-artifacts - verify - - sign - - - - - - - - diff --git a/src/main/java/org/fanout/pubcontrol/PubControl.java b/src/main/java/org/fanout/pubcontrol/PubControl.java index 042faf3..efb91e7 100644 --- a/src/main/java/org/fanout/pubcontrol/PubControl.java +++ b/src/main/java/org/fanout/pubcontrol/PubControl.java @@ -62,6 +62,8 @@ public void applyConfig(List> config) { Map claims = new HashMap(); claims.put("iss", (String)iss); client.setAuthJwt(claims, (byte[])key); + } else if (key != null) { + client.setAuthBearer((String)key); } this.clients.add(client); } diff --git a/src/main/java/org/fanout/pubcontrol/PubControlClient.java b/src/main/java/org/fanout/pubcontrol/PubControlClient.java index 053778c..c8281a9 100644 --- a/src/main/java/org/fanout/pubcontrol/PubControlClient.java +++ b/src/main/java/org/fanout/pubcontrol/PubControlClient.java @@ -7,6 +7,7 @@ package org.fanout.pubcontrol; +import java.nio.charset.StandardCharsets; import java.util.concurrent.locks.*; import java.util.*; import java.io.UnsupportedEncodingException; @@ -15,7 +16,6 @@ import java.io.*; import java.security.Key; -import javax.xml.bind.DatatypeConverter; import javax.crypto.spec.SecretKeySpec; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; @@ -37,9 +37,10 @@ public class PubControlClient implements Runnable { private Thread pubWorker; private Deque reqQueue = new LinkedList(); private String authBasicUser; - private String authBasicPass;; + private String authBasicPass; private Map authJwtClaim; private byte[] authJwtKey; + private String authBearerKey; /** * Initialize this class with a URL representing the publishing endpoint. @@ -68,6 +69,15 @@ public void setAuthJwt(Map claims, byte[] key) { this.lock.unlock(); } + /** + * Pass a key to use bearer authentication with the configured endpoint. + */ + public void setAuthBearer(String key) { + this.lock.lock(); + this.authBearerKey = key; + this.lock.unlock(); + } + /** * Publish the item synchronously to the specified channels. */ @@ -161,7 +171,7 @@ private void queueReq(Object[] req) { private String genAuthHeader() { if (this.authBasicUser != null && this.authBasicPass != null) { try { - return DatatypeConverter.printBase64Binary( + return Base64.getEncoder().encodeToString( (this.authBasicUser + ":" + this.authBasicPass).getBytes("utf-8")); } catch (UnsupportedEncodingException exception) { } @@ -176,6 +186,8 @@ else if (this.authJwtClaim != null) { String token = Jwts.builder().setClaims(claims). signWith(SignatureAlgorithm.HS256, decodedKey).compact(); return "Bearer " + token; + } else if (this.authBearerKey != null) { + return "Bearer " + this.authBearerKey; } return null; @@ -240,6 +252,7 @@ private void makeHttpRequest(URL url, String authHeader, URLConnection connection = null; int responseCode = 0; StringBuilder response = new StringBuilder(); + byte[] body = jsonContent.getBytes(StandardCharsets.UTF_8); try { connection = url.openConnection(); if (connection instanceof HttpURLConnection) @@ -251,13 +264,15 @@ private void makeHttpRequest(URL url, String authHeader, connection.setRequestProperty("Content-Type", "application/json"); connection.setRequestProperty("Content-Length", - Integer.toString(jsonContent.getBytes().length)); + Integer.toString(body.length)); connection.setUseCaches(false); connection.setDoOutput(true); + DataOutputStream dataOutputStream = new DataOutputStream ( connection.getOutputStream()); - dataOutputStream.writeBytes(jsonContent); + dataOutputStream.write(body); dataOutputStream.close(); + InputStream inputStream = connection.getInputStream(); BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));