Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[JBTM-3294] adding version HTTP headers version handling to coordinat…
…or API
- Loading branch information
Showing
19 changed files
with
1,458 additions
and
215 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
367 changes: 229 additions & 138 deletions
367
rts/lra/coordinator/src/main/java/io/narayana/lra/coordinator/api/Coordinator.java
Large diffs are not rendered by default.
Oops, something went wrong.
51 changes: 47 additions & 4 deletions
51
rts/lra/coordinator/src/main/java/io/narayana/lra/coordinator/api/JaxRsActivator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,61 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source. | ||
* Copyright 2020, Red Hat, Inc., and individual contributors | ||
* as indicated by the @author tags. See the copyright.txt file in the | ||
* distribution for a full listing of individual contributors. | ||
* | ||
* This is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU Lesser General Public License as | ||
* published by the Free Software Foundation; either version 2.1 of | ||
* the License, or (at your option) any later version. | ||
* | ||
* This software is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this software; if not, write to the Free | ||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
* 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
*/ | ||
|
||
package io.narayana.lra.coordinator.api; | ||
|
||
import io.narayana.lra.LRAConstants; | ||
import io.narayana.lra.coordinator.internal.APIVersion; | ||
import org.eclipse.microprofile.openapi.annotations.Components; | ||
import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition; | ||
import org.eclipse.microprofile.openapi.annotations.enums.ParameterIn; | ||
import org.eclipse.microprofile.openapi.annotations.headers.Header; | ||
import org.eclipse.microprofile.openapi.annotations.info.Contact; | ||
import org.eclipse.microprofile.openapi.annotations.info.Info; | ||
import org.eclipse.microprofile.openapi.annotations.tags.Tag; | ||
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; | ||
|
||
import javax.ws.rs.ApplicationPath; | ||
import javax.ws.rs.core.Application; | ||
|
||
// mark the war as a JAX-RS archive | ||
@ApplicationPath("/") | ||
@OpenAPIDefinition( | ||
info = @Info(title = "LRA Coordinator", version = JaxRsActivator.LRA_API_VERSION), | ||
tags = @Tag(name = "LRA Coordinator") | ||
info = @Info(title = "LRA Coordinator", version = JaxRsActivator.LRA_API_VERSION_STRING, | ||
contact = @Contact(name = "Narayana", url = "https://narayana.io")), | ||
components = @Components( | ||
parameters = { | ||
@Parameter(name = LRAConstants.LRA_API_VERSION_HEADER_NAME, in = ParameterIn.HEADER, | ||
description = "API version string in format [major].[minor]-[prerelease]. Major and minor are required and to be numbers, prerelease part is optional.") | ||
}, | ||
headers = { | ||
@Header(name = LRAConstants.LRA_API_VERSION_HEADER_NAME, description = "Narayana LRA API version that processed the request") | ||
} | ||
) | ||
) | ||
public class JaxRsActivator extends Application { | ||
static final String LRA_API_VERSION = "1.0-RC1"; | ||
/** | ||
* The LRA API version supported for the release. | ||
* Any bigger version is considered as unimplemented and unknown. | ||
* Any lower version is considered as older, implemented but deprecated and in case not supported. | ||
*/ | ||
public static final String LRA_API_VERSION_STRING = "1.0-RC1"; | ||
public static final APIVersion LRA_API_VERSION = APIVersion.instanceOf(LRA_API_VERSION_STRING); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 125 additions & 0 deletions
125
rts/lra/coordinator/src/main/java/io/narayana/lra/coordinator/internal/APIVersion.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
/* | ||
* JBoss, Home of Professional Open Source. | ||
* Copyright 2020, Red Hat, Inc., and individual contributors | ||
* as indicated by the @author tags. See the copyright.txt file in the | ||
* distribution for a full listing of individual contributors. | ||
* | ||
* This is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU Lesser General Public License as | ||
* published by the Free Software Foundation; either version 2.1 of | ||
* the License, or (at your option) any later version. | ||
* | ||
* This software is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this software; if not, write to the Free | ||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
* 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
*/ | ||
|
||
package io.narayana.lra.coordinator.internal; | ||
|
||
import io.narayana.lra.coordinator.api.JaxRsActivator; | ||
|
||
import java.util.Objects; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
/** | ||
* <p> | ||
* The LRA API version. The most probably provided in header {@code io.narayana.lra.LRAConstants#LRA_API_VERSION_HEADER_NAME}. | ||
* The supported format is {@code #expectedFormat}. | ||
* </p> | ||
* <p> | ||
* The <code>major</code> and <code>minor</code> parts are numbers, the <code>preRelease</code> part is an arbitrary string. | ||
* Two instances of the {@link APIVersion} may be compared. | ||
* There is taken into account only the <code>major</code> and <code>minor</code> parts, | ||
* the <code>preRelease</code> is ignored. | ||
* But two {@link APIVersion} instances are {@link Object#equals(Object)} only if all three parts are the same. | ||
* </p> | ||
*/ | ||
public class APIVersion implements Comparable<APIVersion> { | ||
private static final String expectedFormat = "major.minor-preRelease"; | ||
private static final Pattern versionPattern = Pattern.compile("^(\\d+)\\.(\\d+)(?:-(.+))?"); | ||
|
||
private final int major, minor; | ||
private final String preRelease; | ||
|
||
/** | ||
* Parsing the version string and returns a {@link APIVersion} instance. | ||
* The expected version format is {@code #expectedFormat}. | ||
* If <code>null</code> is provided as String to parse then the most up-to-date | ||
* LRA API version is taken from {@link JaxRsActivator#LRA_API_VERSION}. | ||
* | ||
* @param versionString version string to be parsed; when null or empty the most up-to-date | ||
* {@link JaxRsActivator#LRA_API_VERSION} is returned | ||
* @return instance of the {@link APIVersion} class based on the parsed String | ||
* @throws IllegalArgumentException thrown when version string has a wrong format | ||
*/ | ||
public static APIVersion instanceOf(String versionString) { | ||
Matcher versionMatcher = versionPattern.matcher(versionString); | ||
if(versionString == null || versionString.isEmpty()) { | ||
return JaxRsActivator.LRA_API_VERSION; | ||
} | ||
if(!versionMatcher.matches()) { | ||
throw new IllegalArgumentException("Cannot parse provided version string " + versionString | ||
+ " as it does not match the expected format '" + expectedFormat + "'"); | ||
} | ||
try { | ||
int major = Integer.valueOf(versionMatcher.group(1)); | ||
int minor = Integer.valueOf(versionMatcher.group(2)); | ||
String preRelease = versionMatcher.group(3); | ||
return new APIVersion(major, minor, preRelease); | ||
} catch (NumberFormatException nfe) { | ||
throw new IllegalArgumentException("The version string " + versionString + " matches the expected format " + expectedFormat | ||
+ " but the major.minor cannot be converted to numbers", nfe); | ||
} | ||
} | ||
|
||
public APIVersion(int major, int minor, String preRelease) { | ||
this.major = major; | ||
this.minor = minor; | ||
this.preRelease = preRelease; | ||
} | ||
|
||
@Override | ||
public int compareTo(APIVersion anotherVersion) { | ||
int result = Integer.compare(major, anotherVersion.major); | ||
if (result == 0) { | ||
result = Integer.compare(minor, anotherVersion.minor); | ||
} | ||
return result; | ||
} | ||
@Override | ||
public String toString() { | ||
StringBuilder sb = new StringBuilder() | ||
.append(major).append(".").append(minor); | ||
if (preRelease != null) { | ||
sb.append("-").append(preRelease); | ||
} | ||
return sb.toString(); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
APIVersion that = (APIVersion) o; | ||
return major == that.major && | ||
minor == that.minor && | ||
((preRelease == null && that.preRelease == null) | ||
|| (preRelease != null && preRelease.equals(that.preRelease))); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
if (preRelease == null) { | ||
return Objects.hash(major, minor); | ||
} else { | ||
return Objects.hash(major, minor, preRelease); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.