├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── jwt-auth
├── README.md
├── basic-authentication
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── org
│ │ │ │ └── eclipse
│ │ │ │ └── microprofile14
│ │ │ │ └── jwtauth
│ │ │ │ └── basic
│ │ │ │ ├── ApplicationInit.java
│ │ │ │ └── Servlet.java
│ │ └── resources
│ │ │ ├── META-INF
│ │ │ ├── microprofile-config.properties
│ │ │ └── public-key.pem
│ │ │ └── project-defaults.yml
│ │ └── test
│ │ ├── etc
│ │ └── alt-public-key.pem
│ │ ├── java
│ │ └── org
│ │ │ └── eclipse
│ │ │ └── microprofile14
│ │ │ └── jwtauth
│ │ │ └── basic
│ │ │ ├── BasicAuthenticationAltLocationTest.java
│ │ │ └── BasicAuthenticationTest.java
│ │ └── resources
│ │ ├── jwt-token.json
│ │ └── privateKey.pem
├── jaxrs
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── org
│ │ │ │ └── eclipse
│ │ │ │ └── microprofile14
│ │ │ │ └── jwtauth
│ │ │ │ └── jaxrs
│ │ │ │ ├── ApplicationInit.java
│ │ │ │ └── Resource.java
│ │ └── resources
│ │ │ ├── META-INF
│ │ │ ├── microprofile-config.properties
│ │ │ └── public-key.pem
│ │ │ └── project-defaults.yml
│ │ └── test
│ │ ├── java
│ │ └── org
│ │ │ └── eclipse
│ │ │ └── microprofile14
│ │ │ └── jwtauth
│ │ │ └── jaxrs
│ │ │ └── JaxRsTest.java
│ │ └── resources
│ │ ├── jwt-token.json
│ │ └── privateKey.pem
└── pom.xml
├── open-api
├── README.md
├── basic-hello
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── org
│ │ │ │ └── eclipse
│ │ │ │ └── microprofile14
│ │ │ │ └── openapi
│ │ │ │ └── basichello
│ │ │ │ ├── ApplicationInit.java
│ │ │ │ ├── HelloModelReader.java
│ │ │ │ ├── HelloResource.java
│ │ │ │ └── OperationHyphenFilter.java
│ │ └── resources
│ │ │ └── META-INF
│ │ │ └── microprofile-config.properties
│ │ └── test
│ │ └── java
│ │ └── org
│ │ └── eclipse
│ │ └── microprofile14
│ │ └── openapi
│ │ └── basichello
│ │ └── BasicHelloTest.java
└── pom.xml
├── pom.xml
├── rest-client
├── README.md
├── client-server-async
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── org
│ │ │ └── eclipse
│ │ │ └── microprofile14
│ │ │ └── restclient
│ │ │ └── clientserver
│ │ │ ├── config
│ │ │ └── ApplicationInit.java
│ │ │ └── remote
│ │ │ └── HelloRemoteResource.java
│ │ └── test
│ │ └── java
│ │ └── org
│ │ └── eclipse
│ │ └── microprofile14
│ │ └── restclient
│ │ └── clientserver
│ │ ├── ClientServerAsyncTest.java
│ │ └── client
│ │ └── HelloService.java
├── client-server
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── java
│ │ │ └── org
│ │ │ └── eclipse
│ │ │ └── microprofile14
│ │ │ └── restclient
│ │ │ └── clientserver
│ │ │ ├── config
│ │ │ └── ApplicationInit.java
│ │ │ └── remote
│ │ │ └── HelloRemoteResource.java
│ │ └── test
│ │ └── java
│ │ └── org
│ │ └── eclipse
│ │ └── microprofile14
│ │ └── restclient
│ │ └── clientserver
│ │ ├── ClientServerTest.java
│ │ └── client
│ │ └── HelloService.java
├── pom.xml
├── server-internal-async
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── org
│ │ │ │ └── eclipse
│ │ │ │ └── microprofile14
│ │ │ │ └── restclient
│ │ │ │ └── serverinternal
│ │ │ │ └── async
│ │ │ │ ├── client
│ │ │ │ ├── ClientResourceAsync.java
│ │ │ │ └── HelloService.java
│ │ │ │ ├── config
│ │ │ │ ├── ApplicationInit.java
│ │ │ │ └── URLServiceConfigSource.java
│ │ │ │ └── remote
│ │ │ │ └── HelloRemoteResource.java
│ │ └── resources
│ │ │ └── META-INF
│ │ │ └── services
│ │ │ └── org.eclipse.microprofile.config.spi.ConfigSource
│ │ └── test
│ │ └── java
│ │ └── org
│ │ └── eclipse
│ │ └── microprofile14
│ │ └── restclient
│ │ └── serverinternal
│ │ └── async
│ │ └── ServerInternalAsyncTest.java
└── server-internal
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── eclipse
│ │ │ └── microprofile14
│ │ │ └── restclient
│ │ │ └── serverinternal
│ │ │ ├── client
│ │ │ ├── ClientResource.java
│ │ │ └── HelloService.java
│ │ │ ├── config
│ │ │ ├── ApplicationInit.java
│ │ │ └── URLServiceConfigSource.java
│ │ │ └── remote
│ │ │ └── HelloRemoteResource.java
│ └── resources
│ │ └── META-INF
│ │ └── services
│ │ └── org.eclipse.microprofile.config.spi.ConfigSource
│ └── test
│ └── java
│ └── org
│ └── eclipse
│ └── microprofile14
│ └── restclient
│ └── serverinternal
│ └── ServerInternalTest.java
└── test-utils
├── .gitignore
├── pom.xml
└── src
└── main
├── java
└── org
│ └── eclipse
│ └── microprofile14
│ ├── CliCommands.java
│ ├── JwtTokenGenerator.java
│ ├── Libraries.java
│ ├── Parameter.java
│ ├── ParameterRule.java
│ └── ServerOperations.java
└── resources
├── arquillian-thorntail.xml
├── arquillian.xml
├── key.jks
├── logging.properties
└── server.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Directories #
2 | build/
3 | bin/
4 | target/
5 | libs/
6 | tmp/
7 | node_modules/
8 |
9 | # OS Files #
10 | .DS_Store
11 |
12 | *.class
13 |
14 | # Package Files #
15 | *.jar
16 | *.war
17 | *.ear
18 | *.db
19 | rebel.xml
20 |
21 | ######################
22 | # Windows
23 | ######################
24 |
25 | # Windows image file caches
26 | Thumbs.db
27 |
28 | # Folder config file
29 | Desktop.ini
30 |
31 | ######################
32 | # OSX
33 | ######################
34 |
35 | .DS_Store
36 | .svn
37 |
38 | # Thumbnails
39 | ._*
40 |
41 | # Files that might appear on external disk
42 | .Spotlight-V100
43 | .Trashes
44 |
45 | ######################
46 | # NetBeans
47 | ######################
48 | nbproject/
49 | build/
50 | nbbuild/
51 | dist/
52 | nbdist/
53 | nbactions.xml
54 | nb-configuration.xml
55 |
56 | ######################
57 | # IDEA
58 | ######################
59 | *.iml
60 | *.ipr
61 | *.iws
62 | .idea/
63 | atlassian-ide-plugin.xml
64 |
65 |
66 | ######################
67 | # Eclipse
68 | ######################
69 |
70 | *.pydevproject
71 | .project
72 | .metadata
73 | *.tmp
74 | *.bak
75 | *.swp
76 | *~.nib
77 | local.properties
78 | .classpath
79 | .settings/
80 | .loadpath
81 |
82 | # External tool builders
83 | .externalToolBuilders/
84 |
85 | # Locally stored "Eclipse launch configurations"
86 | *.launch
87 |
88 | # CDT-specific
89 | .cproject
90 |
91 | # PDT-specific
92 | .buildpath
93 |
94 | # Testing environment specific
95 | derby.log
96 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - oraclejdk8
4 |
5 | env:
6 | - SERVER=payara-ci-managed
7 | - SERVER=payara-micro-managed
8 | - SERVER=liberty-ci-managed
9 | - SERVER=wildfly-ci-managed
10 |
11 | install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V -Pnothing
12 |
13 | script: mvn clean install -P $SERVER --fail-at-end
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 JavaEE Samples
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # microprofile1.4-samples
2 | Eclipse MicroProfile 1.4 Samples
3 |
--------------------------------------------------------------------------------
/jwt-auth/README.md:
--------------------------------------------------------------------------------
1 | # Eclipse MicroProfile 1.4 Samples - JWT Auth 1.1
2 |
3 | - [Wiki project page](https://wiki.eclipse.org/MicroProfile/JWT_Auth)
4 | - [Spec, API, TCK GitHub repo](https://github.com/eclipse/microprofile-jwt-auth)
5 |
6 | ## Samples ##
7 |
8 | - **basic-authentication** The test sends a very basic signed JWT token to a protected servlet. The MP-JWT Auth implementation
9 | checks if the token is valid and sets the authenticated identity from the `upn` field and `groups` field. Has a variant where the required public key is in the archive, and one where the key is obtained externally (from outside the archive).
10 | **jaxrs ** Just like basic-authentication, but uses a JAX-RS endpoint. Specifically demonstrates the support of @RolesAllowed to secure and endpoint.
11 |
12 |
13 |
14 | ## Implementation config ##
15 |
16 | New in JWT Auth 1.1 is that implementation specific config is not longer mandated. Note that WildFly still needs implementation specific config, but this is not mandated by the spec.
17 |
18 |
19 | ## TCK ##
20 |
21 | The public/private keys are taken from the MP-Auth TCK.
22 | See the following URLs:
23 |
24 | - [MP-Auth TCK](https://github.com/eclipse/microprofile-jwt-auth/tree/master/tck)
25 | - [Payara TCK Ext](https://github.com/payara/Payara/tree/Payara-5/appserver/payara-appserver-modules/microprofile/jwt-auth-tck)
26 | - [Liberty TCK](https://github.com/OpenLiberty/open-liberty/tree/master/dev/com.ibm.ws.security.mp.jwt_fat_tck)
27 | - [WildFly TCK Ext](https://github.com/MicroProfileJWT/wfswarm-jwt-auth-tck)
28 |
29 |
--------------------------------------------------------------------------------
/jwt-auth/basic-authentication/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | org.eclipse.microprofile.samples14
7 | jwt-auth
8 | 1.0-SNAPSHOT
9 |
10 |
11 | basic-authentication
12 | war
13 | MicroProfile 1.4: JWT-AUTH - Basic Authentication
14 |
15 |
16 |
--------------------------------------------------------------------------------
/jwt-auth/basic-authentication/src/main/java/org/eclipse/microprofile14/jwtauth/basic/ApplicationInit.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.jwtauth.basic;
3 |
4 | import javax.enterprise.context.ApplicationScoped;
5 |
6 | import org.eclipse.microprofile.auth.LoginConfig;
7 |
8 | @LoginConfig(
9 | authMethod = "MP-JWT",
10 | // Even though specified being only for HTTP Basic auth, JBoss/WildFly/Swarm mandates this
11 | // to refer to its proprietary "security domain" concept.
12 | realmName = "MP-JWT"
13 | )
14 | @ApplicationScoped
15 | public class ApplicationInit {
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/jwt-auth/basic-authentication/src/main/java/org/eclipse/microprofile14/jwtauth/basic/Servlet.java:
--------------------------------------------------------------------------------
1 | /* Copyright Payara Services Limited */
2 | package org.eclipse.microprofile14.jwtauth.basic;
3 |
4 | import java.io.IOException;
5 |
6 | import javax.annotation.security.DeclareRoles;
7 | import javax.servlet.ServletException;
8 | import javax.servlet.annotation.HttpConstraint;
9 | import javax.servlet.annotation.ServletSecurity;
10 | import javax.servlet.annotation.WebServlet;
11 | import javax.servlet.http.HttpServlet;
12 | import javax.servlet.http.HttpServletRequest;
13 | import javax.servlet.http.HttpServletResponse;
14 |
15 |
16 | @WebServlet("/servlet")
17 | @ServletSecurity(@HttpConstraint(rolesAllowed = "architect"))
18 | @DeclareRoles({"architect", "bar", "kaz"})
19 | public class Servlet extends HttpServlet {
20 |
21 | private static final long serialVersionUID = 1L;
22 |
23 | @Override
24 | public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
25 |
26 | String webName = null;
27 | if (request.getUserPrincipal() != null) {
28 | webName = request.getUserPrincipal().getName();
29 | }
30 |
31 | response.setContentType("text/plain");
32 |
33 | response.getWriter().write(
34 | "This is a protected servlet \n" +
35 |
36 | "web username: " + webName + "\n" +
37 |
38 | "web user has role \"architect\": " + request.isUserInRole("architect") + "\n" +
39 | "web user has role \"bar\": " + request.isUserInRole("bar") + "\n" +
40 | "web user has role \"kaz\": " + request.isUserInRole("kaz") + "\n"
41 | );
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/jwt-auth/basic-authentication/src/main/resources/META-INF/microprofile-config.properties:
--------------------------------------------------------------------------------
1 | mp.jwt.verify.publickey.location=/META-INF/public-key.pem
2 | mp.jwt.verify.issuer=org.eclipse.microprofile12
--------------------------------------------------------------------------------
/jwt-auth/basic-authentication/src/main/resources/META-INF/public-key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PUBLIC KEY-----
2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq
3 | Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR
4 | TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e
5 | UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9
6 | AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn
7 | sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x
8 | nQIDAQAB
9 | -----END RSA PUBLIC KEY-----
10 |
--------------------------------------------------------------------------------
/jwt-auth/basic-authentication/src/main/resources/project-defaults.yml:
--------------------------------------------------------------------------------
1 | # A project defaults for use with MP-JWT auth-method
2 | # Based on https://github.com/MicroProfileJWT/wfswarm-jwt-auth-tck/blob/master/src/main/resources/project-defaults.yml
3 | swarm:
4 | bind:
5 | address: localhost
6 | microprofile:
7 | jwtauth:
8 | token:
9 | issuedBy: "org.eclipse.microprofile12"
10 | logging:
11 | loggers:
12 | io.undertow.request.security:
13 | level: TRACE
14 | security:
15 | security-domains:
16 | MP-JWT:
17 | jaspi-authentication:
18 | login-module-stacks:
19 | roles-lm-stack:
20 | login-modules:
21 | # This stack performs the token verification and group to role mapping
22 | - login-module: rm
23 | code: org.wildfly.swarm.microprofile.jwtauth.deployment.auth.jaas.JWTLoginModule
24 | flag: required
25 | auth-modules:
26 | # This module integrates the MP-JWT custom authentication mechanism into the web container
27 | http:
28 | code: org.wildfly.extension.undertow.security.jaspi.modules.HTTPSchemeServerAuthModule
29 | module: org.wildfly.extension.undertow
30 | flag: required
31 | login-module-stack-ref: roles-lm-stack
--------------------------------------------------------------------------------
/jwt-auth/basic-authentication/src/test/etc/alt-public-key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PUBLIC KEY-----
2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq
3 | Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR
4 | TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e
5 | UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9
6 | AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn
7 | sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x
8 | nQIDAQAB
9 | -----END RSA PUBLIC KEY-----
10 |
--------------------------------------------------------------------------------
/jwt-auth/basic-authentication/src/test/java/org/eclipse/microprofile14/jwtauth/basic/BasicAuthenticationAltLocationTest.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.jwtauth.basic;
3 |
4 | import static java.nio.file.Files.write;
5 | import static java.nio.file.Paths.get;
6 | import static javax.ws.rs.client.ClientBuilder.newClient;
7 | import static javax.ws.rs.core.HttpHeaders.AUTHORIZATION;
8 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
9 | import static org.eclipse.microprofile14.JwtTokenGenerator.generateJWTString;
10 | import static org.jboss.shrinkwrap.api.ShrinkWrap.create;
11 | import static org.junit.Assert.assertFalse;
12 | import static org.junit.Assert.assertTrue;
13 |
14 | import java.io.File;
15 | import java.io.IOException;
16 | import java.net.URI;
17 | import java.net.URL;
18 |
19 | import javax.ws.rs.core.Response;
20 |
21 | import org.jboss.arquillian.container.test.api.Deployment;
22 | import org.jboss.arquillian.container.test.api.RunAsClient;
23 | import org.jboss.arquillian.junit.Arquillian;
24 | import org.jboss.arquillian.test.api.ArquillianResource;
25 | import org.jboss.shrinkwrap.api.spec.WebArchive;
26 | import org.junit.Test;
27 | import org.junit.runner.RunWith;
28 |
29 | @RunWith(Arquillian.class)
30 | public class BasicAuthenticationAltLocationTest {
31 |
32 | @ArquillianResource
33 | private URL base;
34 |
35 | @Deployment(testable = false)
36 | public static WebArchive createDeployment() throws IOException {
37 |
38 | // Gets the file location of the alternative key
39 | String fileLocation = new File("src/test/etc/alt-public-key.pem").toPath().toAbsolutePath().toString();
40 | System.out.println("Key file is at: " + fileLocation);
41 |
42 | // Put this location in a new configuration file
43 | String configFileContent =
44 | "mp.jwt.verify.publickey.location=file://" + fileLocation + "\n" +
45 | "mp.jwt.verify.issuer=org.eclipse.microprofile12";
46 |
47 |
48 | // Write this new configuration file to target.
49 | write(get("target/microprofile-config.properties"), configFileContent.getBytes());
50 |
51 | WebArchive archive =
52 | create(WebArchive.class)
53 | .addClasses(
54 | ApplicationInit.class,
55 | Servlet.class
56 | ).addAsResource(
57 | // Supply the generated file we just created to the archive. This will have the local on disk
58 | // location of the key file in it, which means the key will be loaded externall from the archive.
59 | // (this will work only if the target server is on the same filesystem, of course)
60 | new File("target/microprofile-config.properties"), "META-INF/microprofile-config.properties"
61 | ).addAsResource(
62 | // WildFly file setting up the security system (domain) such that all artifacts to support
63 | // MP-Auth JWT are installed
64 | "project-defaults.yml")
65 | ;
66 |
67 | System.out.println("************************************************************");
68 | System.out.println(archive.toString(true));
69 | System.out.println("************************************************************");
70 |
71 | return archive;
72 |
73 | }
74 |
75 | @Test
76 | @RunAsClient
77 | public void testProtectedPageNotLoggedin() throws IOException {
78 |
79 | Response response =
80 | newClient()
81 | .target(
82 | URI.create(new URL(base, "servlet").toExternalForm()))
83 | .request(TEXT_PLAIN)
84 | .get();
85 |
86 | // Not logged-in thus should not be accessible.
87 | assertFalse(
88 | "Not authenticated, so should not have been able to access protected resource",
89 | response.readEntity(String.class).contains("This is a protected servlet")
90 | );
91 | }
92 |
93 | @Test
94 | @RunAsClient
95 | public void testProtectedPageLoggedin() throws Exception {
96 |
97 | String response =
98 | newClient()
99 | .target(
100 | URI.create(new URL(base, "servlet").toExternalForm()))
101 | .request(TEXT_PLAIN)
102 | .header(AUTHORIZATION, "Bearer " + generateJWTString("jwt-token.json"))
103 | .get(String.class);
104 |
105 | // Now has to be logged-in so page is accessible
106 | assertTrue(
107 | "Should have been authenticated, but could not access protected resource",
108 | response.contains("This is a protected servlet")
109 | );
110 |
111 | // Not only does the page needs to be accessible, the caller should have
112 | // the correct name and roles as well
113 |
114 | // Being able to access a page protected by a role but then seeing the un-authenticated
115 | // (anonymous) user would normally be impossible, but could happen if the authorization
116 | // system checks roles on the authenticated subject, but does not correctly expose
117 | // or propagate these to the HttpServletRequest
118 | assertFalse(
119 | "Protected resource could be accessed, but the user appears to be the unauthenticated user. " +
120 | "This should not be possible",
121 | response.contains("web username: null")
122 | );
123 |
124 | // An authenticated user should have the exact name "test" and nothing else.
125 | assertTrue(
126 | "Protected resource could be accessed, but the username is not correct.",
127 | response.contains("web username: test")
128 | );
129 |
130 | // Being able to access a page protected by role "architect" but failing
131 | // the test for this role would normally be impossible, but could happen if the
132 | // authorization system checks roles on the authenticated subject, but does not
133 | // correctly expose or propagate these to the HttpServletRequest
134 | assertTrue(
135 | "Resource protected by role \"architect\" could be accessed, but user fails test for this role." +
136 | "This should not be possible",
137 | response.contains("web user has role \"architect\": true")
138 | );
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/jwt-auth/basic-authentication/src/test/java/org/eclipse/microprofile14/jwtauth/basic/BasicAuthenticationTest.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.jwtauth.basic;
3 |
4 | import static javax.ws.rs.client.ClientBuilder.newClient;
5 | import static javax.ws.rs.core.HttpHeaders.AUTHORIZATION;
6 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
7 | import static org.eclipse.microprofile14.JwtTokenGenerator.generateJWTString;
8 | import static org.jboss.shrinkwrap.api.ShrinkWrap.create;
9 | import static org.junit.Assert.assertFalse;
10 | import static org.junit.Assert.assertTrue;
11 |
12 | import java.io.IOException;
13 | import java.net.URI;
14 | import java.net.URL;
15 |
16 | import javax.ws.rs.core.Response;
17 |
18 | import org.eclipse.microprofile14.jwtauth.basic.ApplicationInit;
19 | import org.eclipse.microprofile14.jwtauth.basic.Servlet;
20 | import org.jboss.arquillian.container.test.api.Deployment;
21 | import org.jboss.arquillian.container.test.api.RunAsClient;
22 | import org.jboss.arquillian.junit.Arquillian;
23 | import org.jboss.arquillian.test.api.ArquillianResource;
24 | import org.jboss.shrinkwrap.api.spec.WebArchive;
25 | import org.junit.Test;
26 | import org.junit.runner.RunWith;
27 |
28 | /**
29 | * @author Arjan Tijms
30 | */
31 | @RunWith(Arquillian.class)
32 | public class BasicAuthenticationTest {
33 |
34 | @ArquillianResource
35 | private URL base;
36 |
37 | @Deployment(testable = false)
38 | public static WebArchive createDeployment() {
39 | WebArchive archive =
40 | create(WebArchive.class)
41 | .addClasses(
42 | ApplicationInit.class,
43 | Servlet.class
44 | ).addAsResource(
45 | // Main Properties file configuring that "org.eclipse.microprofile12" is the valid issuer
46 | // and META-INF/public-key.pem is the public key
47 | "META-INF/microprofile-config.properties"
48 | ).addAsResource(
49 | // Public key to verify the incoming signed JWT's signature
50 | "META-INF/public-key.pem"
51 | ).addAsResource(
52 | // WildFly file configuring that "org.eclipse.microprofile12" is the valid issuer and setting up
53 | // the security system (domain) such that all artifacts to support MP-Auth JWT are installed
54 | "project-defaults.yml")
55 | ;
56 |
57 | System.out.println("************************************************************");
58 | System.out.println(archive.toString(true));
59 | System.out.println("************************************************************");
60 |
61 | return archive;
62 |
63 | }
64 |
65 | @Test
66 | @RunAsClient
67 | public void testProtectedPageNotLoggedin() throws IOException {
68 |
69 | Response response =
70 | newClient()
71 | .target(
72 | URI.create(new URL(base, "servlet").toExternalForm()))
73 | .request(TEXT_PLAIN)
74 | .get();
75 |
76 | // Not logged-in thus should not be accessible.
77 | assertFalse(
78 | "Not authenticated, so should not have been able to access protected resource",
79 | response.readEntity(String.class).contains("This is a protected servlet")
80 | );
81 | }
82 |
83 | @Test
84 | @RunAsClient
85 | public void testProtectedPageLoggedin() throws Exception {
86 |
87 | String response =
88 | newClient()
89 | .target(
90 | URI.create(new URL(base, "servlet").toExternalForm()))
91 | .request(TEXT_PLAIN)
92 | .header(AUTHORIZATION, "Bearer " + generateJWTString("jwt-token.json"))
93 | .get(String.class);
94 |
95 | // Now has to be logged-in so page is accessible
96 | assertTrue(
97 | "Should have been authenticated, but could not access protected resource",
98 | response.contains("This is a protected servlet")
99 | );
100 |
101 | // Not only does the page needs to be accessible, the caller should have
102 | // the correct name and roles as well
103 |
104 | // Being able to access a page protected by a role but then seeing the un-authenticated
105 | // (anonymous) user would normally be impossible, but could happen if the authorization
106 | // system checks roles on the authenticated subject, but does not correctly expose
107 | // or propagate these to the HttpServletRequest
108 | assertFalse(
109 | "Protected resource could be accessed, but the user appears to be the unauthenticated user. " +
110 | "This should not be possible",
111 | response.contains("web username: null")
112 | );
113 |
114 | // An authenticated user should have the exact name "test" and nothing else.
115 | assertTrue(
116 | "Protected resource could be accessed, but the username is not correct.",
117 | response.contains("web username: test")
118 | );
119 |
120 | // Being able to access a page protected by role "architect" but failing
121 | // the test for this role would normally be impossible, but could happen if the
122 | // authorization system checks roles on the authenticated subject, but does not
123 | // correctly expose or propagate these to the HttpServletRequest
124 | assertTrue(
125 | "Resource protected by role \"architect\" could be accessed, but user fails test for this role." +
126 | "This should not be possible",
127 | response.contains("web user has role \"architect\": true")
128 | );
129 | }
130 |
131 | }
132 |
--------------------------------------------------------------------------------
/jwt-auth/basic-authentication/src/test/resources/jwt-token.json:
--------------------------------------------------------------------------------
1 | {
2 | "iss": "org.eclipse.microprofile12",
3 | "jti": "a-123",
4 | "sub": "24400320",
5 | "aud": "s6BhdRkqt3",
6 | "exp": 1311281970,
7 | "iat": 1311280970,
8 | "auth_time": 1311280969,
9 | "upn": "test",
10 | "groups": [
11 | "architect",
12 | "master",
13 | "leader",
14 | "dev"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/jwt-auth/basic-authentication/src/test/resources/privateKey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCWK8UjyoHgPTLa
3 | PLQJ8SoXLLjpHSjtLxMqmzHnFscqhTVVaDpCRCb6e3Ii/WniQTWw8RA7vf4djz4H
4 | OzvlfBFNgvUGZHXDwnmGaNVaNzpHYFMEYBhE8VGGiveSkzqeLZI+Y02G6sQAfDtN
5 | qqzM/l5QX8X34oQFaTBW1r49nftvCpITiwJvWyhkWtXP9RP8sXi1im5Vi3dhupOh
6 | nelk5n0BfajUYIbfHA6ORzjHRbt7NtBl0L2J+0/FUdHyKs6KMlFGNw8O0Dq88qnM
7 | uXoLJiewhg9332W3DFMeOveel+//cvDnRsCRtPgd4sXFPHh+UShkso7+DRsChXa6
8 | oGGQD3GdAgMBAAECggEAAjfTSZwMHwvIXIDZB+yP+pemg4ryt84iMlbofclQV8hv
9 | 6TsI4UGwcbKxFOM5VSYxbNOisb80qasb929gixsyBjsQ8284bhPJR7r0q8h1C+jY
10 | URA6S4pk8d/LmFakXwG9Tz6YPo3pJziuh48lzkFTk0xW2Dp4SLwtAptZY/+ZXyJ6
11 | 96QXDrZKSSM99Jh9s7a0ST66WoxSS0UC51ak+Keb0KJ1jz4bIJ2C3r4rYlSu4hHB
12 | Y73GfkWORtQuyUDa9yDOem0/z0nr6pp+pBSXPLHADsqvZiIhxD/O0Xk5I6/zVHB3
13 | zuoQqLERk0WvA8FXz2o8AYwcQRY2g30eX9kU4uDQAQKBgQDmf7KGImUGitsEPepF
14 | KH5yLWYWqghHx6wfV+fdbBxoqn9WlwcQ7JbynIiVx8MX8/1lLCCe8v41ypu/eLtP
15 | iY1ev2IKdrUStvYRSsFigRkuPHUo1ajsGHQd+ucTDf58mn7kRLW1JGMeGxo/t32B
16 | m96Af6AiPWPEJuVfgGV0iwg+HQKBgQCmyPzL9M2rhYZn1AozRUguvlpmJHU2DpqS
17 | 34Q+7x2Ghf7MgBUhqE0t3FAOxEC7IYBwHmeYOvFR8ZkVRKNF4gbnF9RtLdz0DMEG
18 | 5qsMnvJUSQbNB1yVjUCnDAtElqiFRlQ/k0LgYkjKDY7LfciZl9uJRl0OSYeX/qG2
19 | tRW09tOpgQKBgBSGkpM3RN/MRayfBtmZvYjVWh3yjkI2GbHA1jj1g6IebLB9SnfL
20 | WbXJErCj1U+wvoPf5hfBc7m+jRgD3Eo86YXibQyZfY5pFIh9q7Ll5CQl5hj4zc4Y
21 | b16sFR+xQ1Q9Pcd+BuBWmSz5JOE/qcF869dthgkGhnfVLt/OQzqZluZRAoGAXQ09
22 | nT0TkmKIvlza5Af/YbTqEpq8mlBDhTYXPlWCD4+qvMWpBII1rSSBtftgcgca9XLB
23 | MXmRMbqtQeRtg4u7dishZVh1MeP7vbHsNLppUQT9Ol6lFPsd2xUpJDc6BkFat62d
24 | Xjr3iWNPC9E9nhPPdCNBv7reX7q81obpeXFMXgECgYEAmk2Qlus3OV0tfoNRqNpe
25 | Mb0teduf2+h3xaI1XDIzPVtZF35ELY/RkAHlmWRT4PCdR0zXDidE67L6XdJyecSt
26 | FdOUH8z5qUraVVebRFvJqf/oGsXc4+ex1ZKUTbY0wqY1y9E39yvB3MaTmZFuuqk8
27 | f3cg+fr8aou7pr9SHhJlZCU=
28 | -----END RSA PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/jwt-auth/jaxrs/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | org.eclipse.microprofile.samples14
7 | jwt-auth
8 | 1.0-SNAPSHOT
9 |
10 |
11 | jaxrs
12 | war
13 | MicroProfile 1.4: JWT-AUTH - JAX-RS
14 |
15 |
16 |
--------------------------------------------------------------------------------
/jwt-auth/jaxrs/src/main/java/org/eclipse/microprofile14/jwtauth/jaxrs/ApplicationInit.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.jwtauth.jaxrs;
3 |
4 | import javax.annotation.security.DeclareRoles;
5 | import javax.ws.rs.ApplicationPath;
6 | import javax.ws.rs.core.Application;
7 |
8 | import org.eclipse.microprofile.auth.LoginConfig;
9 |
10 | @LoginConfig(
11 | authMethod = "MP-JWT",
12 | // Even though specified being only for HTTP Basic auth, JBoss/WildFly/Swarm mandates this
13 | // to refer to its proprietary "security domain" concept.
14 | realmName = "MP-JWT"
15 | )
16 | @DeclareRoles({"architect", "bar", "kaz"})
17 | @ApplicationPath("/")
18 | public class ApplicationInit extends Application {
19 |
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/jwt-auth/jaxrs/src/main/java/org/eclipse/microprofile14/jwtauth/jaxrs/Resource.java:
--------------------------------------------------------------------------------
1 | /* Copyright Payara Services Limited */
2 | package org.eclipse.microprofile14.jwtauth.jaxrs;
3 |
4 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
5 |
6 | import java.security.Principal;
7 |
8 | import javax.annotation.security.RolesAllowed;
9 | import javax.enterprise.context.ApplicationScoped;
10 | import javax.inject.Inject;
11 | import javax.ws.rs.GET;
12 | import javax.ws.rs.Path;
13 | import javax.ws.rs.Produces;
14 |
15 | @ApplicationScoped
16 | @Path("/resource")
17 | @Produces(TEXT_PLAIN)
18 | public class Resource {
19 |
20 | @Inject
21 | private Principal principal;
22 |
23 | @GET
24 | @Path("/protected")
25 | @RolesAllowed("architect")
26 | public String protectedResource() {
27 | return
28 | "This is a protected resource \n" +
29 | "web username: " + principal.getName() + "\n";
30 | }
31 |
32 | @GET
33 | @Path("public")
34 | public String publicResource() {
35 | return
36 | "This is a public resource \n" +
37 | "web username: " + principal.getName() + "\n";
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/jwt-auth/jaxrs/src/main/resources/META-INF/microprofile-config.properties:
--------------------------------------------------------------------------------
1 | mp.jwt.verify.publickey.location=/META-INF/public-key.pem
2 | mp.jwt.verify.issuer=org.eclipse.microprofile12
--------------------------------------------------------------------------------
/jwt-auth/jaxrs/src/main/resources/META-INF/public-key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PUBLIC KEY-----
2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq
3 | Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR
4 | TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e
5 | UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9
6 | AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn
7 | sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x
8 | nQIDAQAB
9 | -----END RSA PUBLIC KEY-----
10 |
--------------------------------------------------------------------------------
/jwt-auth/jaxrs/src/main/resources/project-defaults.yml:
--------------------------------------------------------------------------------
1 | # A project defaults for use with MP-JWT auth-method
2 | # Based on https://github.com/MicroProfileJWT/wfswarm-jwt-auth-tck/blob/master/src/main/resources/project-defaults.yml
3 | thorntail:
4 | bind:
5 | address: localhost
6 | microprofile:
7 | jwt:
8 | default-missing-method-permissions-deny-access: false
9 | token:
10 | issued-by: "org.eclipse.microprofile12"
11 | logging:
12 | loggers:
13 | io.undertow.request.security:
14 | level: TRACE
15 | security:
16 | security-domains:
17 | MP-JWT:
18 | jaspi-authentication:
19 | login-module-stacks:
20 | roles-lm-stack:
21 | login-modules:
22 | # This stack performs the token verification and group to role mapping
23 | - login-module: rm
24 | code: org.wildfly.swarm.microprofile.jwtauth.deployment.auth.jaas.JWTLoginModule
25 | flag: required
26 | auth-modules:
27 | # This module integrates the MP-JWT custom authentication mechanism into the web container
28 | http:
29 | code: org.wildfly.extension.undertow.security.jaspi.modules.HTTPSchemeServerAuthModule
30 | module: org.wildfly.extension.undertow
31 | flag: required
32 | login-module-stack-ref: roles-lm-stack
--------------------------------------------------------------------------------
/jwt-auth/jaxrs/src/test/java/org/eclipse/microprofile14/jwtauth/jaxrs/JaxRsTest.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.jwtauth.jaxrs;
3 |
4 | import static javax.ws.rs.client.ClientBuilder.newClient;
5 | import static javax.ws.rs.core.HttpHeaders.AUTHORIZATION;
6 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
7 | import static org.eclipse.microprofile14.JwtTokenGenerator.generateJWTString;
8 | import static org.jboss.shrinkwrap.api.ShrinkWrap.create;
9 | import static org.jboss.shrinkwrap.api.asset.EmptyAsset.INSTANCE;
10 | import static org.junit.Assert.assertFalse;
11 | import static org.junit.Assert.assertTrue;
12 |
13 | import java.io.IOException;
14 | import java.net.URI;
15 | import java.net.URL;
16 |
17 | import javax.ws.rs.core.Response;
18 |
19 | import org.jboss.arquillian.container.test.api.Deployment;
20 | import org.jboss.arquillian.container.test.api.RunAsClient;
21 | import org.jboss.arquillian.junit.Arquillian;
22 | import org.jboss.arquillian.test.api.ArquillianResource;
23 | import org.jboss.shrinkwrap.api.asset.EmptyAsset;
24 | import org.jboss.shrinkwrap.api.spec.WebArchive;
25 | import org.junit.Test;
26 | import org.junit.runner.RunWith;
27 |
28 | /**
29 | * @author Arjan Tijms
30 | */
31 | @RunWith(Arquillian.class)
32 | public class JaxRsTest {
33 |
34 | @ArquillianResource
35 | private URL base;
36 |
37 | @Deployment(testable = false)
38 | public static WebArchive createDeployment() {
39 | WebArchive archive =
40 | create(WebArchive.class)
41 | .addClasses(
42 | ApplicationInit.class,
43 | Resource.class
44 | ).addAsResource(
45 | // Main Properties file configuring that "org.eclipse.microprofile12" is the valid issuer
46 | // and META-INF/public-key.pem is the public key
47 | "META-INF/microprofile-config.properties"
48 | ).addAsResource(
49 | // Public key to verify the incoming signed JWT's signature
50 | "META-INF/public-key.pem"
51 | ).addAsResource(
52 | // WildFly file configuring that "org.eclipse.microprofile12" is the valid issuer and setting up
53 | // the security system (domain) such that all artifacts to support MP-Auth JWT are installed
54 | "project-defaults.yml")
55 | .addAsWebInfResource(
56 | // Make CDI look at ApplicationInit and discover LoginConfig
57 | INSTANCE, "beans.xml")
58 | ;
59 |
60 | System.out.println("************************************************************");
61 | System.out.println(archive.toString(true));
62 | System.out.println("************************************************************");
63 |
64 | return archive;
65 |
66 | }
67 |
68 | @Test
69 | @RunAsClient
70 | public void testProtectedResourceNotLoggedin() throws IOException {
71 |
72 | System.out.println("-------------------------------------------------------------------------");
73 | System.out.println("Base URL: " + base);
74 | System.out.println("-------------------------------------------------------------------------");
75 |
76 | Response response =
77 | newClient()
78 | .target(
79 | URI.create(new URL(base, "resource/protected").toExternalForm()))
80 | .request(TEXT_PLAIN)
81 | .get();
82 |
83 | // Not logged-in thus should not be accessible.
84 | assertFalse(
85 | "Not authenticated, so should not have been able to access protected resource",
86 | response.readEntity(String.class).contains("This is a protected resource")
87 | );
88 | }
89 |
90 | @Test
91 | @RunAsClient
92 | public void testPublicResourceNotLoggedin() throws IOException {
93 |
94 | Response response =
95 | newClient()
96 | .target(
97 | URI.create(new URL(base, "resource/public").toExternalForm()))
98 | .request(TEXT_PLAIN)
99 | .get();
100 |
101 | // Public resource, no log-in needed
102 | assertTrue(
103 | "Public resource is not constrained (protected) so should be accessible without sending the JWT token",
104 | response.readEntity(String.class).contains("This is a public resource")
105 | );
106 | }
107 |
108 | @Test
109 | @RunAsClient
110 | public void testProtectedResourceLoggedin() throws Exception {
111 |
112 | String response =
113 | newClient()
114 | .target(
115 | URI.create(new URL(base, "resource/protected").toExternalForm()))
116 | .request(TEXT_PLAIN)
117 | .header(AUTHORIZATION, "Bearer " + generateJWTString("jwt-token.json"))
118 | .get(String.class);
119 |
120 |
121 | System.out.println("-------------------------------------------------------------------------");
122 | System.out.println("Response: " + response);
123 | System.out.println("-------------------------------------------------------------------------");
124 |
125 | // Now has to be logged-in so page is accessible
126 | assertTrue(
127 | "Should have been authenticated, but could not access protected resource",
128 | response.contains("This is a protected resource")
129 | );
130 |
131 | // Not only does the resource needs to be accessible, the caller should have
132 | // the correct name
133 |
134 | // Being able to access a page protected by a role but then seeing the un-authenticated
135 | // (anonymous) user would normally be impossible, but could happen if the authorization
136 | // system checks roles on the authenticated subject, but does not correctly expose
137 | // or propagate these to the injected Principal
138 | assertFalse(
139 | "Protected resource could be accessed, but the user appears to be the unauthenticated user. " +
140 | "This should not be possible",
141 | response.contains("web username: null")
142 | );
143 |
144 | // An authenticated user should have the exact name "test" and nothing else.
145 | assertTrue(
146 | "Protected resource could be accessed, but the username is not correct.",
147 | response.contains("web username: test")
148 | );
149 |
150 | }
151 |
152 | }
153 |
--------------------------------------------------------------------------------
/jwt-auth/jaxrs/src/test/resources/jwt-token.json:
--------------------------------------------------------------------------------
1 | {
2 | "iss": "org.eclipse.microprofile12",
3 | "jti": "a-123",
4 | "sub": "24400320",
5 | "aud": "s6BhdRkqt3",
6 | "exp": 1311281970,
7 | "iat": 1311280970,
8 | "auth_time": 1311280969,
9 | "upn": "test",
10 | "groups": [
11 | "architect",
12 | "master",
13 | "leader",
14 | "dev"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/jwt-auth/jaxrs/src/test/resources/privateKey.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCWK8UjyoHgPTLa
3 | PLQJ8SoXLLjpHSjtLxMqmzHnFscqhTVVaDpCRCb6e3Ii/WniQTWw8RA7vf4djz4H
4 | OzvlfBFNgvUGZHXDwnmGaNVaNzpHYFMEYBhE8VGGiveSkzqeLZI+Y02G6sQAfDtN
5 | qqzM/l5QX8X34oQFaTBW1r49nftvCpITiwJvWyhkWtXP9RP8sXi1im5Vi3dhupOh
6 | nelk5n0BfajUYIbfHA6ORzjHRbt7NtBl0L2J+0/FUdHyKs6KMlFGNw8O0Dq88qnM
7 | uXoLJiewhg9332W3DFMeOveel+//cvDnRsCRtPgd4sXFPHh+UShkso7+DRsChXa6
8 | oGGQD3GdAgMBAAECggEAAjfTSZwMHwvIXIDZB+yP+pemg4ryt84iMlbofclQV8hv
9 | 6TsI4UGwcbKxFOM5VSYxbNOisb80qasb929gixsyBjsQ8284bhPJR7r0q8h1C+jY
10 | URA6S4pk8d/LmFakXwG9Tz6YPo3pJziuh48lzkFTk0xW2Dp4SLwtAptZY/+ZXyJ6
11 | 96QXDrZKSSM99Jh9s7a0ST66WoxSS0UC51ak+Keb0KJ1jz4bIJ2C3r4rYlSu4hHB
12 | Y73GfkWORtQuyUDa9yDOem0/z0nr6pp+pBSXPLHADsqvZiIhxD/O0Xk5I6/zVHB3
13 | zuoQqLERk0WvA8FXz2o8AYwcQRY2g30eX9kU4uDQAQKBgQDmf7KGImUGitsEPepF
14 | KH5yLWYWqghHx6wfV+fdbBxoqn9WlwcQ7JbynIiVx8MX8/1lLCCe8v41ypu/eLtP
15 | iY1ev2IKdrUStvYRSsFigRkuPHUo1ajsGHQd+ucTDf58mn7kRLW1JGMeGxo/t32B
16 | m96Af6AiPWPEJuVfgGV0iwg+HQKBgQCmyPzL9M2rhYZn1AozRUguvlpmJHU2DpqS
17 | 34Q+7x2Ghf7MgBUhqE0t3FAOxEC7IYBwHmeYOvFR8ZkVRKNF4gbnF9RtLdz0DMEG
18 | 5qsMnvJUSQbNB1yVjUCnDAtElqiFRlQ/k0LgYkjKDY7LfciZl9uJRl0OSYeX/qG2
19 | tRW09tOpgQKBgBSGkpM3RN/MRayfBtmZvYjVWh3yjkI2GbHA1jj1g6IebLB9SnfL
20 | WbXJErCj1U+wvoPf5hfBc7m+jRgD3Eo86YXibQyZfY5pFIh9q7Ll5CQl5hj4zc4Y
21 | b16sFR+xQ1Q9Pcd+BuBWmSz5JOE/qcF869dthgkGhnfVLt/OQzqZluZRAoGAXQ09
22 | nT0TkmKIvlza5Af/YbTqEpq8mlBDhTYXPlWCD4+qvMWpBII1rSSBtftgcgca9XLB
23 | MXmRMbqtQeRtg4u7dishZVh1MeP7vbHsNLppUQT9Ol6lFPsd2xUpJDc6BkFat62d
24 | Xjr3iWNPC9E9nhPPdCNBv7reX7q81obpeXFMXgECgYEAmk2Qlus3OV0tfoNRqNpe
25 | Mb0teduf2+h3xaI1XDIzPVtZF35ELY/RkAHlmWRT4PCdR0zXDidE67L6XdJyecSt
26 | FdOUH8z5qUraVVebRFvJqf/oGsXc4+ex1ZKUTbY0wqY1y9E39yvB3MaTmZFuuqk8
27 | f3cg+fr8aou7pr9SHhJlZCU=
28 | -----END RSA PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/jwt-auth/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | org.eclipse.microprofile.samples14
7 | samples-parent
8 | 1.0-SNAPSHOT
9 |
10 |
11 | jwt-auth
12 | pom
13 |
14 | MicroProfile 1.4: JWT-AUTH
15 |
16 |
17 | basic-authentication
18 | jaxrs
19 |
20 |
21 |
22 |
23 | org.eclipse.microprofile.samples14
24 | test-utils
25 | ${project.version}
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/open-api/README.md:
--------------------------------------------------------------------------------
1 | # Eclipse MicroProfile 1.4 Samples - Open API 1.0
2 |
3 | - [Wiki project page](https://wiki.eclipse.org/MicroProfile/OpenAPI)
4 | - [Spec, API, TCK GitHub repo](https://github.com/eclipse/microprofile-open-api)
5 |
6 | ## Samples ##
7 |
8 | - **basic-hello** A trivially simple hello-style JAX-RS resource for which an OpenAPI document is created
9 |
10 |
11 |
--------------------------------------------------------------------------------
/open-api/basic-hello/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4.0.0
5 |
6 |
7 | org.eclipse.microprofile.samples14
8 | open-api
9 | 1.0-SNAPSHOT
10 |
11 |
12 | basic-hello
13 | war
14 |
15 | MicroProfile 1.4: Open API - Basic hello
16 |
17 |
18 |
--------------------------------------------------------------------------------
/open-api/basic-hello/src/main/java/org/eclipse/microprofile14/openapi/basichello/ApplicationInit.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.openapi.basichello;
3 |
4 | import javax.ws.rs.ApplicationPath;
5 | import javax.ws.rs.core.Application;
6 |
7 | @ApplicationPath("/api")
8 | public class ApplicationInit extends Application {
9 |
10 | }
--------------------------------------------------------------------------------
/open-api/basic-hello/src/main/java/org/eclipse/microprofile14/openapi/basichello/HelloModelReader.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.openapi.basichello;
3 |
4 | import org.eclipse.microprofile.openapi.OASFactory;
5 | import org.eclipse.microprofile.openapi.OASModelReader;
6 | import org.eclipse.microprofile.openapi.models.OpenAPI;
7 |
8 | /**
9 | * Generates a base model to be used by the OpenAPI.
10 | */
11 | public class HelloModelReader implements OASModelReader {
12 |
13 | @Override
14 | public OpenAPI buildModel() {
15 | return OASFactory.createObject(OpenAPI.class);
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/open-api/basic-hello/src/main/java/org/eclipse/microprofile14/openapi/basichello/HelloResource.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.openapi.basichello;
3 |
4 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
5 |
6 | import javax.ws.rs.GET;
7 | import javax.ws.rs.Path;
8 | import javax.ws.rs.Produces;
9 |
10 | import org.eclipse.microprofile.openapi.annotations.Operation;
11 |
12 | @Path("/hello")
13 | public class HelloResource {
14 |
15 | @GET
16 | @Operation(
17 | operationId = "hello world",
18 | description = "This is a well know Hello World service. It will output a variant of the expected 'Hello, world!' phrase.")
19 | @Produces(TEXT_PLAIN)
20 | public String helloWorld() {
21 | return "Hello World!";
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/open-api/basic-hello/src/main/java/org/eclipse/microprofile14/openapi/basichello/OperationHyphenFilter.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.openapi.basichello;
3 |
4 | import org.eclipse.microprofile.openapi.OASFilter;
5 | import org.eclipse.microprofile.openapi.models.Operation;
6 |
7 | /**
8 | * A filter to make final configuration changes to the produced OpenAPI document.
9 | */
10 | public class OperationHyphenFilter implements OASFilter {
11 |
12 | /**
13 | * Replaces all spaces in each operation id with a hyphen.
14 | */
15 | @Override
16 | public Operation filterOperation(Operation operation) {
17 | if (operation.getOperationId().contains((" "))) {
18 | operation.setOperationId(operation.getOperationId().replace(" ", "-"));
19 | }
20 |
21 | return operation;
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/open-api/basic-hello/src/main/resources/META-INF/microprofile-config.properties:
--------------------------------------------------------------------------------
1 | # Configure the processing classed defined to edit the OpenAPI document.
2 | mp.openapi.model.reader=org.eclipse.microprofile14.openapi.basichello.HelloModelReader
3 | mp.openapi.filter=org.eclipse.microprofile14.openapi.basichello.OperationHyphenFilter
4 |
5 | # Whether to disable the scanning of application classes
6 | mp.openapi.scan.disable=false
--------------------------------------------------------------------------------
/open-api/basic-hello/src/test/java/org/eclipse/microprofile14/openapi/basichello/BasicHelloTest.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.openapi.basichello;
3 |
4 | import static javax.ws.rs.client.ClientBuilder.newClient;
5 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
6 | import static org.jboss.shrinkwrap.api.ShrinkWrap.create;
7 | import static org.junit.Assert.assertTrue;
8 |
9 | import java.io.IOException;
10 | import java.net.URI;
11 | import java.net.URL;
12 |
13 | import org.eclipse.microprofile14.openapi.basichello.ApplicationInit;
14 | import org.eclipse.microprofile14.openapi.basichello.HelloResource;
15 | import org.eclipse.microprofile14.openapi.basichello.OperationHyphenFilter;
16 | import org.jboss.arquillian.container.test.api.Deployment;
17 | import org.jboss.arquillian.container.test.api.RunAsClient;
18 | import org.jboss.arquillian.junit.Arquillian;
19 | import org.jboss.arquillian.test.api.ArquillianResource;
20 | import org.jboss.shrinkwrap.api.asset.EmptyAsset;
21 | import org.jboss.shrinkwrap.api.spec.WebArchive;
22 | import org.junit.Test;
23 | import org.junit.runner.RunWith;
24 |
25 | /**
26 | * @author Arjan Tijms
27 | */
28 | @RunWith(Arquillian.class)
29 | public class BasicHelloTest {
30 |
31 | @ArquillianResource
32 | private URL base;
33 |
34 | @Deployment(testable = false)
35 | public static WebArchive createDeployment() {
36 | WebArchive archive =
37 | create(WebArchive.class)
38 | .addClasses(
39 | ApplicationInit.class,
40 | HelloResource.class,
41 | HelloModelReader.class,
42 | OperationHyphenFilter.class
43 | ).addAsResource(
44 | "META-INF/microprofile-config.properties"
45 | ).addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
46 | ;
47 |
48 | System.out.println("************************************************************");
49 | System.out.println(archive.toString(true));
50 | System.out.println("************************************************************");
51 |
52 | return archive;
53 | }
54 |
55 | @Test
56 | @RunAsClient
57 | public void testServerInternal() throws IOException {
58 | String response =
59 | newClient()
60 | .target(
61 | URI.create(new URL(base.getProtocol(), base.getHost(), base.getPort(), "/openapi").toExternalForm()))
62 | .request(TEXT_PLAIN)
63 | .get(String.class);
64 |
65 | System.out.println("-------------------------------------------------------------------------");
66 | System.out.println("Response: " + response);
67 | System.out.println("-------------------------------------------------------------------------");
68 |
69 | assertTrue(
70 | response.contains("hello-world")
71 | );
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/open-api/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4.0.0
5 |
6 |
7 | org.eclipse.microprofile.samples14
8 | samples-parent
9 | 1.0-SNAPSHOT
10 |
11 |
12 | open-api
13 | pom
14 |
15 | MicroProfile 1.4: Open API
16 |
17 |
18 | basic-hello
19 |
20 |
21 |
22 |
23 | org.eclipse.microprofile.samples14
24 | test-utils
25 | ${project.version}
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 | 4.0.0
8 |
9 |
10 | 3.5
11 |
12 |
13 | org.eclipse.microprofile.samples14
14 | samples-parent
15 | 1.0-SNAPSHOT
16 | pom
17 |
18 | Eclipse MicroProfile 1.4 Samples: root
19 |
20 |
21 | 1.8
22 | 3.5
23 | UTF-8
24 |
25 | false
26 | false
27 |
28 | ${skipTests}
29 | ${skipTests}
30 | ${skipTests}
31 | ${skipTests}
32 |
33 |
35 | 5.183
36 | 5.183
37 | 18.0.0.2
38 | 2.3.0.Final
39 |
40 | 1.0.Beta3
41 | 5.Beta3
42 |
43 |
44 |
45 |
46 | central
47 | Central Repository
48 | https://repo.maven.apache.org/maven2
49 |
50 | true
51 |
52 |
53 | false
54 |
55 |
56 |
57 |
58 | payara-milestones
59 | Payara Milestones
60 | https://raw.github.com/payara/Payara_PatchedProjects/master
61 |
62 | true
63 |
64 |
65 | false
66 |
67 |
68 |
69 |
70 | payara-milestones-eclipse
71 | Payara Milestones Eclipse
72 | https://raw.github.com/payara/Payara_PatchedProjects/eclipse
73 |
74 | true
75 |
76 |
77 | false
78 |
79 |
80 |
81 |
82 | ossrh
83 | Sonatype-snapshot
84 | https://oss.sonatype.org/content/repositories/snapshots
85 |
86 | false
87 |
88 |
89 | true
90 |
91 |
92 |
93 |
94 | jvnet-nexus-staging
95 | Java.net Staging Repositories
96 | https://maven.java.net/content/repositories/staging
97 |
98 | true
99 |
100 |
101 | false
102 |
103 |
104 |
105 |
106 |
107 |
109 |
110 | jwt-auth
111 | rest-client
112 | open-api
113 | test-utils
114 |
115 |
116 |
117 |
118 |
119 | org.jboss.arquillian
120 | arquillian-bom
121 | 1.4.1.Final
122 | import
123 | pom
124 |
125 |
126 | org.jboss.arquillian.container
127 | arquillian-container-test-api
128 | 1.4.1.Final
129 |
130 |
131 | com.h2database
132 | h2
133 | 1.4.199
134 |
135 |
136 | fish.payara.arquillian
137 | payara-client-ee8
138 | 1.0.Beta3
139 | test
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 | javax
148 | javaee-api
149 | 8.0.1
150 | provided
151 |
152 |
153 |
154 |
155 |
156 |
157 | junit
158 | junit
159 | 4.13-beta-3
160 | test
161 |
162 |
163 | org.jboss.arquillian.junit
164 | arquillian-junit-container
165 | test
166 |
167 |
168 | org.jboss.arquillian.protocol
169 | arquillian-protocol-servlet
170 | test
171 |
172 |
173 | org.jboss.shrinkwrap.resolver
174 | shrinkwrap-resolver-impl-maven
175 | test
176 |
177 |
178 | org.jboss.shrinkwrap.resolver
179 | shrinkwrap-resolver-impl-maven-archive
180 | test
181 |
182 |
183 | net.sourceforge.htmlunit
184 | htmlunit
185 | 2.35.0
186 | test
187 |
188 |
189 |
190 | org.eclipse.microprofile
191 | microprofile
192 | 1.4
193 | pom
194 | provided
195 |
196 |
197 |
198 |
199 | jakarta.xml.bind
200 | jakarta.xml.bind-api
201 | 2.3.2
202 |
203 |
204 | org.glassfish.jaxb
205 | jaxb-runtime
206 | 2.3.2
207 |
208 |
209 |
210 |
211 |
212 | ${project.artifactId}
213 |
214 |
215 |
216 | src/test/resources
217 | true
218 |
219 |
220 |
221 |
222 |
223 | org.apache.maven.plugins
224 | maven-compiler-plugin
225 | 3.7.0
226 |
227 | ${java.min.version}
228 | ${java.min.version}
229 |
230 |
231 |
232 | org.apache.maven.plugins
233 | maven-surefire-report-plugin
234 | 2.21.0
235 |
236 | true
237 | true
238 |
239 |
240 |
241 | org.apache.maven.plugins
242 | maven-surefire-plugin
243 | 2.21.0
244 |
245 |
246 | javax.annotation
247 | javax.annotation-api
248 | 1.3.2
249 |
250 |
251 |
252 |
253 | org.apache.maven.plugins
254 | maven-war-plugin
255 | 3.2.0
256 |
257 | true
258 | false
259 |
260 |
261 |
262 | org.apache.maven.plugins
263 | maven-enforcer-plugin
264 | 3.0.0-M1
265 |
266 |
267 |
268 | At least Maven in version
269 | ${maven.min.version} is
270 | required.
271 | ${maven.min.version}
272 |
273 |
274 | At least a JDK in version
275 | ${java.min.version} is
276 | required.
277 | ${java.min.version}
278 |
279 |
280 |
281 |
282 |
283 |
284 | enforce
285 |
286 |
287 |
288 |
289 |
290 | org.apache.maven.plugins
291 | maven-dependency-plugin
292 | 3.1.0
293 |
294 |
295 | org.apache.maven.plugins
296 | maven-resources-plugin
297 | 3.1.0
298 |
299 |
300 | org.wildfly.plugins
301 | wildfly-maven-plugin
302 | 1.2.1.Final
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 | payara-ci-managed
319 |
320 |
321 | true
322 |
323 |
324 |
325 |
326 |
327 | fish.payara.arquillian
328 | payara-client-ee8
329 |
330 |
331 |
332 |
333 | fish.payara.arquillian
334 | arquillian-payara-server-4-managed
335 | ${payara.container.version}
336 | test
337 |
338 |
339 |
340 |
341 |
342 |
343 | org.apache.maven.plugins
344 | maven-dependency-plugin
345 |
346 |
347 | unpack
348 | process-test-classes
349 |
350 | unpack
351 |
352 |
353 | ${session.executionRootDirectory}/target
354 | ${session.executionRootDirectory}/target/dependency-maven-plugin-markers
355 |
356 |
357 | fish.payara.distributions
358 | payara-web
359 | ${payara.version}
360 | zip
361 | false
362 | ${session.executionRootDirectory}/target
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 | org.apache.maven.plugins
371 | maven-surefire-plugin
372 |
373 |
374 |
375 | javax.annotation
376 | javax.annotation-api
377 | 1.3.1
378 |
379 |
380 |
381 | ${session.executionRootDirectory}/target/payara5
382 |
383 |
384 |
385 | ${session.executionRootDirectory}/target/payara5
386 | payara-remote
387 | payara
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 | payara-micro-managed
397 |
398 |
399 | true
400 | true
401 |
402 |
403 |
404 |
405 |
406 |
407 | fish.payara.arquillian
408 | payara-client-ee8
409 |
410 |
411 |
412 |
413 | fish.payara.arquillian
414 | arquillian-payara-micro-5-managed
415 | ${payara.container.version}
416 | test
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 | org.apache.maven.plugins
425 | maven-dependency-plugin
426 |
427 |
428 | process-test-classes
429 |
430 | copy
431 |
432 |
433 |
434 |
435 | fish.payara.extras
436 | payara-micro
437 | ${payara.micro.version}
438 | false
439 | ${session.executionRootDirectory}/target/
440 | payara-micro-${payara.micro.version}.jar
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 | maven-surefire-plugin
450 |
451 |
452 | ${session.executionRootDirectory}/target/payara-micro-${payara.micro.version}.jar
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 | payara-remote
462 |
463 |
464 |
465 | fish.payara.arquillian
466 | payara-client-ee8
467 |
468 |
469 |
470 |
471 | fish.payara.arquillian
472 | arquillian-payara-server-4-remote
473 | ${payara.container.version}
474 | test
475 |
476 |
477 |
478 |
479 |
480 | maven-surefire-plugin
481 |
482 |
483 | payara-remote
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 | liberty-ci-managed
497 |
498 |
499 |
500 | fish.payara.arquillian
501 | payara-client-ee8
502 |
503 |
504 |
505 | org.jboss.arquillian.container
506 | arquillian-wlp-managed-8.5
507 | 1.0.0.CR1
508 | test
509 |
510 |
511 |
512 |
513 |
514 |
515 | org.apache.maven.plugins
516 | maven-dependency-plugin
517 |
518 |
519 | unpack
520 | test-compile
521 |
522 | unpack
523 |
524 |
525 |
526 |
527 |
528 | io.openliberty
529 | openliberty-runtime
530 | ${liberty.version}
531 |
532 |
533 |
535 | zip
536 | false
537 | ${session.executionRootDirectory}/target/
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 | org.apache.maven.plugins
546 | maven-antrun-plugin
547 | 1.8
548 |
549 |
550 | unpack
551 | process-test-classes
552 |
553 | run
554 |
555 |
556 |
557 |
559 | Copying server.xml
560 |
563 | Copying key.jks
564 |
566 |
569 |
570 |
571 |
572 |
573 |
574 |
575 | org.apache.maven.plugins
576 | maven-surefire-plugin
577 |
578 |
579 | liberty-ci-managed
580 |
581 | ${session.executionRootDirectory}/target/wlp
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 | thorntail
595 |
596 |
597 |
598 |
599 |
600 | io.thorntail
601 | bom
602 | ${thorntail.version}
603 | import
604 | pom
605 |
606 |
607 |
608 |
609 |
610 |
612 |
613 | io.thorntail
614 | arquillian
615 | test
616 |
617 |
618 |
619 | io.thorntail
620 | microprofile
621 |
622 |
623 |
624 |
625 |
626 | maven-surefire-plugin
627 |
628 |
629 |
630 |
631 | arquillian-thorntail.xml
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 | nothing
641 |
642 |
643 |
646 |
647 | javadocs
648 |
649 |
650 | javadocs
651 |
652 |
653 |
654 |
655 |
656 | org.apache.maven.plugins
657 | maven-dependency-plugin
658 | 2.4
659 |
660 |
661 | sources
662 | process-resources
663 |
664 | sources
665 | resolve
666 |
667 |
668 | javadoc
669 | false
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 | org.apache.maven.plugins
683 | maven-surefire-report-plugin
684 | 2.19.1
685 |
686 | true
687 | true
688 |
689 |
690 |
691 |
692 |
693 |
694 |
--------------------------------------------------------------------------------
/rest-client/README.md:
--------------------------------------------------------------------------------
1 | # Eclipse MicroProfile 1.4 Samples - Rest Client 1.1
2 |
3 | - [Wiki project page](https://wiki.eclipse.org/MicroProfile/RESTClient)
4 | - [Spec, API, TCK GitHub repo](https://github.com/eclipse/microprofile-rest-client)
5 |
6 | ## Samples ##
7 |
8 | - **client-server** A standalone (Java SE) client creates a type-safe local service from an interface definition and uses it to contact a remote JAX-RS resource
9 | - **client-server-async** Variant of client-server where the type-safe service has an async signature, while still connecting to same backend JAX-RS resource
10 | - **server-internal** Injects an internal JAX-RS resource as a type-safe service into another JAX-RS resource
11 | - **server-internal-async** Variant of server-internal where the type-safe service has an async signature, while still connecting to same backend JAX-RS resource
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/rest-client/client-server-async/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4.0.0
5 |
6 |
7 | org.eclipse.microprofile.samples14
8 | rest-client
9 | 1.0-SNAPSHOT
10 |
11 |
12 | client-server-async
13 | war
14 |
15 | MicroProfile 1.4: Rest Client - Client-server async
16 |
17 |
18 |
--------------------------------------------------------------------------------
/rest-client/client-server-async/src/main/java/org/eclipse/microprofile14/restclient/clientserver/config/ApplicationInit.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.clientserver.config;
3 |
4 | import javax.ws.rs.ApplicationPath;
5 | import javax.ws.rs.core.Application;
6 |
7 | @ApplicationPath("/api")
8 | public class ApplicationInit extends Application {
9 |
10 | }
--------------------------------------------------------------------------------
/rest-client/client-server-async/src/main/java/org/eclipse/microprofile14/restclient/clientserver/remote/HelloRemoteResource.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.clientserver.remote;
3 |
4 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
5 |
6 | import javax.ws.rs.Consumes;
7 | import javax.ws.rs.GET;
8 | import javax.ws.rs.Path;
9 | import javax.ws.rs.PathParam;
10 | import javax.ws.rs.Produces;
11 |
12 | @Path("/hello")
13 | @Produces(TEXT_PLAIN)
14 | @Consumes(TEXT_PLAIN)
15 | public class HelloRemoteResource {
16 |
17 | @GET
18 | @Path("{name}")
19 | public String hello(@PathParam("name") String name) {
20 | return "Hello " + name + "!";
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/rest-client/client-server-async/src/test/java/org/eclipse/microprofile14/restclient/clientserver/ClientServerAsyncTest.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.clientserver;
3 |
4 | import static org.jboss.shrinkwrap.api.ShrinkWrap.create;
5 | import static org.junit.Assert.assertTrue;
6 |
7 | import java.io.IOException;
8 | import java.net.URISyntaxException;
9 | import java.net.URL;
10 | import java.util.concurrent.ExecutionException;
11 |
12 | import org.eclipse.microprofile.rest.client.RestClientBuilder;
13 | import org.eclipse.microprofile.rest.client.RestClientDefinitionException;
14 | import org.eclipse.microprofile14.restclient.clientserver.client.HelloService;
15 | import org.eclipse.microprofile14.restclient.clientserver.config.ApplicationInit;
16 | import org.eclipse.microprofile14.restclient.clientserver.remote.HelloRemoteResource;
17 | import org.jboss.arquillian.container.test.api.Deployment;
18 | import org.jboss.arquillian.container.test.api.RunAsClient;
19 | import org.jboss.arquillian.junit.Arquillian;
20 | import org.jboss.arquillian.test.api.ArquillianResource;
21 | import org.jboss.shrinkwrap.api.asset.EmptyAsset;
22 | import org.jboss.shrinkwrap.api.spec.WebArchive;
23 | import org.junit.Test;
24 | import org.junit.runner.RunWith;
25 |
26 | /**
27 | * @author Arjan Tijms
28 | */
29 | @RunWith(Arquillian.class)
30 | public class ClientServerAsyncTest {
31 |
32 | @ArquillianResource
33 | private URL base;
34 |
35 | @Deployment(testable = false)
36 | public static WebArchive createDeployment() {
37 | WebArchive archive =
38 | create(WebArchive.class)
39 | .addClasses(
40 | ApplicationInit.class,
41 | HelloRemoteResource.class
42 | ).addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
43 | ;
44 |
45 | System.out.println("************************************************************");
46 | System.out.println(archive.toString(true));
47 | System.out.println("************************************************************");
48 |
49 | return archive;
50 | }
51 |
52 | @Test
53 | @RunAsClient
54 | public void testClientServerAsync() throws IOException, IllegalStateException, RestClientDefinitionException, URISyntaxException, InterruptedException, ExecutionException {
55 |
56 | HelloService remoteApi = RestClientBuilder.newBuilder()
57 | .baseUrl(base)
58 | .build(HelloService.class);
59 |
60 |
61 | String response =
62 | remoteApi.helloAsync("Programmer (Async)")
63 | .thenApply(String::toUpperCase)
64 | .toCompletableFuture()
65 | .get();
66 |
67 | System.out.println("-------------------------------------------------------------------------");
68 | System.out.println("Response: " + response);
69 | System.out.println("-------------------------------------------------------------------------");
70 |
71 | assertTrue(
72 | response.contains("HELLO PROGRAMMER (ASYNC)!")
73 | );
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/rest-client/client-server-async/src/test/java/org/eclipse/microprofile14/restclient/clientserver/client/HelloService.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.clientserver.client;
3 |
4 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
5 |
6 | import java.util.concurrent.CompletionStage;
7 |
8 | import javax.enterprise.context.RequestScoped;
9 | import javax.ws.rs.Consumes;
10 | import javax.ws.rs.GET;
11 | import javax.ws.rs.Path;
12 | import javax.ws.rs.PathParam;
13 | import javax.ws.rs.Produces;
14 |
15 | import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
16 |
17 | /**
18 | *
19 | * @author Ondrej Mihalyi
20 | */
21 | @Path("/api/hello")
22 | @RequestScoped
23 | @RegisterRestClient // Required to enable injection of this interface
24 | public interface HelloService {
25 |
26 | @GET
27 | @Path("{name}")
28 | @Produces(TEXT_PLAIN)
29 | @Consumes(TEXT_PLAIN)
30 | CompletionStage helloAsync(@PathParam("name") String name);
31 |
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/rest-client/client-server/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4.0.0
5 |
6 |
7 | org.eclipse.microprofile.samples14
8 | rest-client
9 | 1.0-SNAPSHOT
10 |
11 |
12 | client-server
13 | war
14 |
15 | MicroProfile 1.4: Rest Client - Client-server
16 |
17 |
18 |
--------------------------------------------------------------------------------
/rest-client/client-server/src/main/java/org/eclipse/microprofile14/restclient/clientserver/config/ApplicationInit.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.clientserver.config;
3 |
4 | import javax.ws.rs.ApplicationPath;
5 | import javax.ws.rs.core.Application;
6 |
7 | @ApplicationPath("/api")
8 | public class ApplicationInit extends Application {
9 |
10 | }
--------------------------------------------------------------------------------
/rest-client/client-server/src/main/java/org/eclipse/microprofile14/restclient/clientserver/remote/HelloRemoteResource.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.clientserver.remote;
3 |
4 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
5 |
6 | import javax.ws.rs.Consumes;
7 | import javax.ws.rs.GET;
8 | import javax.ws.rs.Path;
9 | import javax.ws.rs.PathParam;
10 | import javax.ws.rs.Produces;
11 |
12 | @Path("/hello")
13 | @Produces(TEXT_PLAIN)
14 | @Consumes(TEXT_PLAIN)
15 | public class HelloRemoteResource {
16 |
17 | @GET
18 | @Path("{name}")
19 | public String hello(@PathParam("name") String name) {
20 | return "Hello " + name + "!";
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/rest-client/client-server/src/test/java/org/eclipse/microprofile14/restclient/clientserver/ClientServerTest.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.clientserver;
3 |
4 | import static org.jboss.shrinkwrap.api.ShrinkWrap.create;
5 | import static org.junit.Assert.assertTrue;
6 |
7 | import java.io.IOException;
8 | import java.net.URISyntaxException;
9 | import java.net.URL;
10 |
11 | import org.eclipse.microprofile.rest.client.RestClientBuilder;
12 | import org.eclipse.microprofile.rest.client.RestClientDefinitionException;
13 | import org.eclipse.microprofile14.restclient.clientserver.client.HelloService;
14 | import org.eclipse.microprofile14.restclient.clientserver.config.ApplicationInit;
15 | import org.eclipse.microprofile14.restclient.clientserver.remote.HelloRemoteResource;
16 | import org.jboss.arquillian.container.test.api.Deployment;
17 | import org.jboss.arquillian.container.test.api.RunAsClient;
18 | import org.jboss.arquillian.junit.Arquillian;
19 | import org.jboss.arquillian.test.api.ArquillianResource;
20 | import org.jboss.shrinkwrap.api.asset.EmptyAsset;
21 | import org.jboss.shrinkwrap.api.spec.WebArchive;
22 | import org.junit.Test;
23 | import org.junit.runner.RunWith;
24 |
25 | /**
26 | * @author Arjan Tijms
27 | */
28 | @RunWith(Arquillian.class)
29 | public class ClientServerTest {
30 |
31 | @ArquillianResource
32 | private URL base;
33 |
34 | @Deployment(testable = false)
35 | public static WebArchive createDeployment() {
36 | WebArchive archive =
37 | create(WebArchive.class)
38 | .addClasses(
39 | ApplicationInit.class,
40 | HelloRemoteResource.class
41 | ).addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
42 | ;
43 |
44 | System.out.println("************************************************************");
45 | System.out.println(archive.toString(true));
46 | System.out.println("************************************************************");
47 |
48 | return archive;
49 | }
50 |
51 | @Test
52 | @RunAsClient
53 | public void testClientServer() throws IOException, IllegalStateException, RestClientDefinitionException, URISyntaxException {
54 |
55 | HelloService remoteApi = RestClientBuilder.newBuilder()
56 | .baseUrl(base)
57 | .build(HelloService.class);
58 |
59 | String response = remoteApi.hello("Programmer");
60 |
61 |
62 |
63 | System.out.println("-------------------------------------------------------------------------");
64 | System.out.println("Response: " + response);
65 | System.out.println("-------------------------------------------------------------------------");
66 |
67 | assertTrue(
68 | response.contains("Hello Programmer!")
69 | );
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/rest-client/client-server/src/test/java/org/eclipse/microprofile14/restclient/clientserver/client/HelloService.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.clientserver.client;
3 |
4 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
5 |
6 | import javax.enterprise.context.RequestScoped;
7 | import javax.ws.rs.Consumes;
8 | import javax.ws.rs.GET;
9 | import javax.ws.rs.Path;
10 | import javax.ws.rs.PathParam;
11 | import javax.ws.rs.Produces;
12 |
13 | import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
14 |
15 | /**
16 | *
17 | * @author Ondrej Mihalyi
18 | */
19 | @Path("/api/hello")
20 | @RequestScoped
21 | @RegisterRestClient // Required to enable injection of this interface
22 | public interface HelloService {
23 |
24 | @GET
25 | @Path("{name}")
26 | @Produces(TEXT_PLAIN)
27 | @Consumes(TEXT_PLAIN)
28 | String hello(@PathParam("name") String name);
29 |
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/rest-client/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4.0.0
5 |
6 |
7 | org.eclipse.microprofile.samples14
8 | samples-parent
9 | 1.0-SNAPSHOT
10 |
11 |
12 | rest-client
13 | pom
14 |
15 | MicroProfile 1.4: Rest Client
16 |
17 |
18 | client-server
19 | client-server-async
20 | server-internal
21 | server-internal-async
22 |
23 |
24 |
25 |
26 | org.eclipse.microprofile.samples14
27 | test-utils
28 | ${project.version}
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/rest-client/server-internal-async/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4.0.0
5 |
6 |
7 | org.eclipse.microprofile.samples14
8 | rest-client
9 | 1.0-SNAPSHOT
10 |
11 |
12 | server-internal-async
13 | war
14 |
15 | MicroProfile 1.4: Rest Client - Server internal async
16 |
17 |
18 |
--------------------------------------------------------------------------------
/rest-client/server-internal-async/src/main/java/org/eclipse/microprofile14/restclient/serverinternal/async/client/ClientResourceAsync.java:
--------------------------------------------------------------------------------
1 | package org.eclipse.microprofile14.restclient.serverinternal.async.client;
2 |
3 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
4 |
5 | import java.util.concurrent.CompletionStage;
6 |
7 | import javax.enterprise.context.RequestScoped;
8 | import javax.inject.Inject;
9 | import javax.ws.rs.GET;
10 | import javax.ws.rs.Path;
11 | import javax.ws.rs.Produces;
12 |
13 | import org.eclipse.microprofile.rest.client.inject.RestClient;
14 |
15 | @Path("clientAsync")
16 | @RequestScoped
17 | public class ClientResourceAsync {
18 |
19 | @Inject
20 | @RestClient
21 | private HelloService helloService;
22 |
23 | @GET
24 | @Produces(TEXT_PLAIN)
25 | public CompletionStage helloWorld() {
26 | return helloService.helloAsync("World (Async)").thenApply(String::toUpperCase);
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/rest-client/server-internal-async/src/main/java/org/eclipse/microprofile14/restclient/serverinternal/async/client/HelloService.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.serverinternal.async.client;
3 |
4 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
5 |
6 | import java.util.concurrent.CompletionStage;
7 |
8 | import javax.enterprise.context.RequestScoped;
9 | import javax.ws.rs.Consumes;
10 | import javax.ws.rs.GET;
11 | import javax.ws.rs.Path;
12 | import javax.ws.rs.PathParam;
13 | import javax.ws.rs.Produces;
14 |
15 | import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
16 |
17 | /**
18 | *
19 | * @author Ondrej Mihalyi
20 | */
21 | @Path("/api/hello")
22 | @RequestScoped
23 | @RegisterRestClient // Required to enable injection of this interface
24 | public interface HelloService {
25 |
26 | @GET
27 | @Path("{name}")
28 | @Produces(TEXT_PLAIN)
29 | @Consumes(TEXT_PLAIN)
30 | CompletionStage helloAsync(@PathParam("name") String name);
31 |
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/rest-client/server-internal-async/src/main/java/org/eclipse/microprofile14/restclient/serverinternal/async/config/ApplicationInit.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.serverinternal.async.config;
3 |
4 | import javax.ws.rs.ApplicationPath;
5 | import javax.ws.rs.core.Application;
6 |
7 | @ApplicationPath("/api")
8 | public class ApplicationInit extends Application {
9 |
10 | }
--------------------------------------------------------------------------------
/rest-client/server-internal-async/src/main/java/org/eclipse/microprofile14/restclient/serverinternal/async/config/URLServiceConfigSource.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.serverinternal.async.config;
3 |
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | import javax.enterprise.inject.spi.CDI;
8 | import javax.servlet.http.HttpServletRequest;
9 |
10 | import org.eclipse.microprofile.config.spi.ConfigSource;
11 | import org.eclipse.microprofile14.restclient.serverinternal.async.client.HelloService;
12 |
13 | /**
14 | * This config source provides the URL MP Rest Client needs to locate the endpoint corresponding
15 | * to the {@link HelloService} interface.
16 | *
17 | * @author Arjan Tijms
18 | *
19 | */
20 | public class URLServiceConfigSource implements ConfigSource {
21 |
22 | @Override
23 | public Map getProperties() {
24 | Map properties = new HashMap<>();
25 | properties.put(HelloService.class + "/mp-rest/url", "");
26 | return properties;
27 | }
28 |
29 | @Override
30 | public String getValue(String propertyName) {
31 | if (propertyName.equals(HelloService.class.getName() + "/mp-rest/url")) {
32 |
33 | try {
34 | HttpServletRequest request = CDI.current().select(HttpServletRequest.class).get();
35 |
36 | StringBuffer url = request.getRequestURL();
37 | String uri = request.getRequestURI();
38 |
39 | return url.substring(0, url.length() - uri.length() + request.getContextPath().length()) + "/";
40 | } catch (Exception e) {
41 | // Ignore, thrown when the key is requested ahead of a request
42 | }
43 | }
44 |
45 | return null;
46 | }
47 |
48 | @Override
49 | public String getName() {
50 | return "URLServiceConfigSource";
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/rest-client/server-internal-async/src/main/java/org/eclipse/microprofile14/restclient/serverinternal/async/remote/HelloRemoteResource.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.serverinternal.async.remote;
3 |
4 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
5 |
6 | import javax.ws.rs.Consumes;
7 | import javax.ws.rs.GET;
8 | import javax.ws.rs.Path;
9 | import javax.ws.rs.PathParam;
10 | import javax.ws.rs.Produces;
11 |
12 | @Path("/hello")
13 | @Produces(TEXT_PLAIN)
14 | @Consumes(TEXT_PLAIN)
15 | public class HelloRemoteResource {
16 |
17 | @GET
18 | @Path("{name}")
19 | public String hello(@PathParam("name") String name) {
20 | return "Hello " + name + "!";
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/rest-client/server-internal-async/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource:
--------------------------------------------------------------------------------
1 | org.eclipse.microprofile14.restclient.serverinternal.async.config.URLServiceConfigSource
2 |
--------------------------------------------------------------------------------
/rest-client/server-internal-async/src/test/java/org/eclipse/microprofile14/restclient/serverinternal/async/ServerInternalAsyncTest.java:
--------------------------------------------------------------------------------
1 | package org.eclipse.microprofile14.restclient.serverinternal.async;
2 |
3 | import static javax.ws.rs.client.ClientBuilder.newClient;
4 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
5 | import static org.jboss.shrinkwrap.api.ShrinkWrap.create;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | import java.io.IOException;
9 | import java.net.URI;
10 | import java.net.URL;
11 |
12 | import org.eclipse.microprofile14.restclient.serverinternal.async.client.ClientResourceAsync;
13 | import org.eclipse.microprofile14.restclient.serverinternal.async.client.HelloService;
14 | import org.eclipse.microprofile14.restclient.serverinternal.async.config.ApplicationInit;
15 | import org.eclipse.microprofile14.restclient.serverinternal.async.config.URLServiceConfigSource;
16 | import org.eclipse.microprofile14.restclient.serverinternal.async.remote.HelloRemoteResource;
17 | import org.jboss.arquillian.container.test.api.Deployment;
18 | import org.jboss.arquillian.container.test.api.RunAsClient;
19 | import org.jboss.arquillian.junit.Arquillian;
20 | import org.jboss.arquillian.test.api.ArquillianResource;
21 | import org.jboss.shrinkwrap.api.spec.WebArchive;
22 | import org.junit.Test;
23 | import org.junit.runner.RunWith;
24 |
25 | /**
26 | * @author Arjan Tijms
27 | */
28 | @RunWith(Arquillian.class)
29 | public class ServerInternalAsyncTest {
30 |
31 | @ArquillianResource
32 | private URL base;
33 |
34 | @Deployment(testable = false)
35 | public static WebArchive createDeployment() {
36 | WebArchive archive =
37 | create(WebArchive.class)
38 | .addClasses(
39 | ApplicationInit.class,
40 | URLServiceConfigSource.class,
41 | HelloRemoteResource.class,
42 | ClientResourceAsync.class,
43 | HelloService.class
44 | ).addAsResource(
45 | "META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource"
46 | )
47 | ;
48 |
49 | System.out.println("************************************************************");
50 | System.out.println(archive.toString(true));
51 | System.out.println("************************************************************");
52 |
53 | return archive;
54 | }
55 |
56 | @Test
57 | @RunAsClient
58 | public void testServerInternalAsync() throws IOException {
59 |
60 | String response =
61 | newClient()
62 | .target(
63 | URI.create(new URL(base, "api/clientAsync").toExternalForm()))
64 | .request(TEXT_PLAIN)
65 | .get(String.class);
66 |
67 | System.out.println("-------------------------------------------------------------------------");
68 | System.out.println("Response: " + response);
69 | System.out.println("-------------------------------------------------------------------------");
70 |
71 | assertTrue(
72 | response.contains("HELLO WORLD (ASYNC)!")
73 | );
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/rest-client/server-internal/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4.0.0
5 |
6 |
7 | org.eclipse.microprofile.samples14
8 | rest-client
9 | 1.0-SNAPSHOT
10 |
11 |
12 | server-internal
13 | war
14 |
15 | MicroProfile 1.4: Rest Client - Server internal
16 |
17 |
18 |
--------------------------------------------------------------------------------
/rest-client/server-internal/src/main/java/org/eclipse/microprofile14/restclient/serverinternal/client/ClientResource.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.serverinternal.client;
3 |
4 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
5 |
6 | import javax.enterprise.context.RequestScoped;
7 | import javax.inject.Inject;
8 | import javax.ws.rs.GET;
9 | import javax.ws.rs.Path;
10 | import javax.ws.rs.Produces;
11 |
12 | import org.eclipse.microprofile.rest.client.inject.RestClient;
13 |
14 | @Path("client")
15 | @RequestScoped
16 | public class ClientResource {
17 |
18 | @Inject
19 | @RestClient
20 | private HelloService helloService;
21 |
22 | @GET
23 | @Produces(TEXT_PLAIN)
24 | public String helloWorld() {
25 | return helloService.hello("World");
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/rest-client/server-internal/src/main/java/org/eclipse/microprofile14/restclient/serverinternal/client/HelloService.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.serverinternal.client;
3 |
4 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
5 |
6 | import javax.enterprise.context.RequestScoped;
7 | import javax.ws.rs.Consumes;
8 | import javax.ws.rs.GET;
9 | import javax.ws.rs.Path;
10 | import javax.ws.rs.PathParam;
11 | import javax.ws.rs.Produces;
12 |
13 | import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
14 |
15 | /**
16 | *
17 | * @author Ondrej Mihalyi
18 | */
19 | @Path("/api/hello")
20 | @RequestScoped
21 | @RegisterRestClient // Required to enable injection of this interface
22 | public interface HelloService {
23 |
24 | @GET
25 | @Path("{name}")
26 | @Produces(TEXT_PLAIN)
27 | @Consumes(TEXT_PLAIN)
28 | String hello(@PathParam("name") String name);
29 |
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/rest-client/server-internal/src/main/java/org/eclipse/microprofile14/restclient/serverinternal/config/ApplicationInit.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.serverinternal.config;
3 |
4 | import javax.ws.rs.ApplicationPath;
5 | import javax.ws.rs.core.Application;
6 |
7 | @ApplicationPath("/api")
8 | public class ApplicationInit extends Application {
9 |
10 | }
--------------------------------------------------------------------------------
/rest-client/server-internal/src/main/java/org/eclipse/microprofile14/restclient/serverinternal/config/URLServiceConfigSource.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.serverinternal.config;
3 |
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | import javax.enterprise.inject.spi.CDI;
8 | import javax.servlet.http.HttpServletRequest;
9 |
10 | import org.eclipse.microprofile.config.spi.ConfigSource;
11 | import org.eclipse.microprofile14.restclient.serverinternal.client.HelloService;
12 |
13 | /**
14 | * This config source provides the URL MP Rest Client needs to locate the endpoint corresponding
15 | * to the {@link HelloService} interface.
16 | *
17 | * @author Arjan Tijms
18 | *
19 | */
20 | public class URLServiceConfigSource implements ConfigSource {
21 |
22 | @Override
23 | public Map getProperties() {
24 | Map properties = new HashMap<>();
25 | properties.put(HelloService.class + "/mp-rest/url", "");
26 | return properties;
27 | }
28 |
29 | @Override
30 | public String getValue(String propertyName) {
31 | if (propertyName.equals(HelloService.class.getName() + "/mp-rest/url")) {
32 |
33 | try {
34 | HttpServletRequest request = CDI.current().select(HttpServletRequest.class).get();
35 |
36 | StringBuffer url = request.getRequestURL();
37 | String uri = request.getRequestURI();
38 |
39 | return url.substring(0, url.length() - uri.length() + request.getContextPath().length()) + "/";
40 | } catch (Exception e) {
41 | // Ignore, thrown when the key is requested ahead of a request
42 | }
43 | }
44 |
45 | return null;
46 | }
47 |
48 | @Override
49 | public String getName() {
50 | return "URLServiceConfigSource";
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/rest-client/server-internal/src/main/java/org/eclipse/microprofile14/restclient/serverinternal/remote/HelloRemoteResource.java:
--------------------------------------------------------------------------------
1 | /** Copyright Payara Services Limited **/
2 | package org.eclipse.microprofile14.restclient.serverinternal.remote;
3 |
4 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
5 |
6 | import javax.ws.rs.Consumes;
7 | import javax.ws.rs.GET;
8 | import javax.ws.rs.Path;
9 | import javax.ws.rs.PathParam;
10 | import javax.ws.rs.Produces;
11 |
12 | @Path("/hello")
13 | @Produces(TEXT_PLAIN)
14 | @Consumes(TEXT_PLAIN)
15 | public class HelloRemoteResource {
16 |
17 | @GET
18 | @Path("{name}")
19 | public String hello(@PathParam("name") String name) {
20 | return "Hello " + name + "!";
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/rest-client/server-internal/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource:
--------------------------------------------------------------------------------
1 | org.eclipse.microprofile14.restclient.serverinternal.config.URLServiceConfigSource
2 |
--------------------------------------------------------------------------------
/rest-client/server-internal/src/test/java/org/eclipse/microprofile14/restclient/serverinternal/ServerInternalTest.java:
--------------------------------------------------------------------------------
1 | package org.eclipse.microprofile14.restclient.serverinternal;
2 |
3 | import static javax.ws.rs.client.ClientBuilder.newClient;
4 | import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
5 | import static org.jboss.shrinkwrap.api.ShrinkWrap.create;
6 | import static org.junit.Assert.assertTrue;
7 |
8 | import java.io.IOException;
9 | import java.net.URI;
10 | import java.net.URL;
11 |
12 | import org.eclipse.microprofile14.restclient.serverinternal.client.ClientResource;
13 | import org.eclipse.microprofile14.restclient.serverinternal.client.HelloService;
14 | import org.eclipse.microprofile14.restclient.serverinternal.config.ApplicationInit;
15 | import org.eclipse.microprofile14.restclient.serverinternal.config.URLServiceConfigSource;
16 | import org.eclipse.microprofile14.restclient.serverinternal.remote.HelloRemoteResource;
17 | import org.jboss.arquillian.container.test.api.Deployment;
18 | import org.jboss.arquillian.container.test.api.RunAsClient;
19 | import org.jboss.arquillian.junit.Arquillian;
20 | import org.jboss.arquillian.test.api.ArquillianResource;
21 | import org.jboss.shrinkwrap.api.spec.WebArchive;
22 | import org.junit.Test;
23 | import org.junit.runner.RunWith;
24 |
25 | /**
26 | * @author Arjan Tijms
27 | */
28 | @RunWith(Arquillian.class)
29 | public class ServerInternalTest {
30 |
31 | @ArquillianResource
32 | private URL base;
33 |
34 | @Deployment(testable = false)
35 | public static WebArchive createDeployment() {
36 | WebArchive archive =
37 | create(WebArchive.class)
38 | .addClasses(
39 | ApplicationInit.class,
40 | URLServiceConfigSource.class,
41 | HelloRemoteResource.class,
42 | ClientResource.class,
43 | HelloService.class
44 | ).addAsResource(
45 | "META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource"
46 | )
47 | ;
48 |
49 | System.out.println("************************************************************");
50 | System.out.println(archive.toString(true));
51 | System.out.println("************************************************************");
52 |
53 | return archive;
54 | }
55 |
56 | @Test
57 | @RunAsClient
58 | public void testServerInternal() throws IOException {
59 |
60 | String response =
61 | newClient()
62 | .target(
63 | URI.create(new URL(base, "api/client").toExternalForm()))
64 | .request(TEXT_PLAIN)
65 | .get(String.class);
66 |
67 | System.out.println("-------------------------------------------------------------------------");
68 | System.out.println("Response: " + response);
69 | System.out.println("-------------------------------------------------------------------------");
70 |
71 | assertTrue(
72 | response.contains("Hello World!")
73 | );
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/test-utils/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 |
--------------------------------------------------------------------------------
/test-utils/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | org.eclipse.microprofile.samples14
8 | samples-parent
9 | 1.0-SNAPSHOT
10 |
11 |
12 | test-utils
13 | MicroProfile 1.4: test-utils
14 |
15 |
16 |
17 | junit
18 | junit
19 | 4.12
20 |
21 |
22 | org.jboss.arquillian.container
23 | arquillian-container-test-api
24 |
25 |
26 | org.jboss.shrinkwrap.resolver
27 | shrinkwrap-resolver-api-maven
28 |
29 |
30 | com.nimbusds
31 | nimbus-jose-jwt
32 | 7.1
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/test-utils/src/main/java/org/eclipse/microprofile14/CliCommands.java:
--------------------------------------------------------------------------------
1 | package org.eclipse.microprofile14;
2 |
3 | import static java.lang.Runtime.getRuntime;
4 | import static java.lang.Thread.currentThread;
5 |
6 | import java.io.IOException;
7 | import java.nio.file.Path;
8 | import java.nio.file.Paths;
9 | import java.util.ArrayList;
10 | import java.util.List;
11 | import java.util.Scanner;
12 | import java.util.logging.Logger;
13 |
14 | /**
15 | * Methods to execute "cli commands" against various servers.
16 | *
17 | * @author Arjan Tijms
18 | *
19 | */
20 | public class CliCommands {
21 |
22 | private static final Logger logger = Logger.getLogger(CliCommands.class.getName());
23 | private static final String OS = System.getProperty("os.name").toLowerCase();
24 |
25 | public static int payaraGlassFish(List cliCommands) {
26 |
27 | String gfHome = System.getProperty("glassfishRemote_gfHome");
28 | if (gfHome == null) {
29 | logger.info("glassfishRemote_gfHome not specified");
30 | return -1;
31 | }
32 |
33 | Path gfHomePath = Paths.get(gfHome);
34 | if (!gfHomePath.toFile().exists()) {
35 | logger.severe("glassfishRemote_gfHome at " + gfHome + " does not exists");
36 | return -1;
37 | }
38 |
39 | if (!gfHomePath.toFile().isDirectory()) {
40 | logger.severe("glassfishRemote_gfHome at " + gfHome + " is not a directory");
41 | return -1;
42 | }
43 |
44 | Path asadminPath = gfHomePath.resolve(isWindows()? "bin/asadmin.bat" : "bin/asadmin");
45 |
46 | if (!asadminPath.toFile().exists()) {
47 | logger.severe("asadmin command at " + asadminPath.toAbsolutePath() + " does not exists");
48 | return -1;
49 | }
50 |
51 | List cmd = new ArrayList<>();
52 |
53 | cmd.add(asadminPath.toAbsolutePath().toString());
54 | cmd.addAll(cliCommands);
55 |
56 | ProcessBuilder processBuilder = new ProcessBuilder(cmd);
57 | processBuilder.redirectErrorStream(true);
58 |
59 | try {
60 | return
61 | waitToFinish(
62 | readAllInput(
63 | destroyAtShutDown(
64 | processBuilder.start())));
65 | } catch (IOException e) {
66 | return -1;
67 | }
68 | }
69 |
70 | public static Process destroyAtShutDown(final Process process) {
71 | getRuntime().addShutdownHook(new Thread(new Runnable() {
72 | @Override
73 | public void run() {
74 | if (process != null) {
75 | process.destroy();
76 | try {
77 | process.waitFor();
78 | } catch (InterruptedException e) {
79 | currentThread().interrupt();
80 | throw new RuntimeException(e);
81 | }
82 | }
83 | }
84 | }));
85 |
86 | return process;
87 | }
88 |
89 | public static Process readAllInput(Process process) {
90 | // Read any output from the process
91 | try (Scanner scanner = new Scanner(process.getInputStream())) {
92 | while (scanner.hasNextLine()) {
93 | System.out.println(scanner.nextLine());
94 | }
95 | }
96 |
97 | return process;
98 | }
99 |
100 | public static int waitToFinish(Process process) {
101 |
102 | // Wait up to 30s for the process to finish
103 | int startupTimeout = 30 * 1000;
104 | while (startupTimeout > 0) {
105 | startupTimeout -= 200;
106 | try {
107 | Thread.sleep(200);
108 | } catch (InterruptedException e1) {
109 | // Ignore
110 | }
111 |
112 | try {
113 | int exitValue = process.exitValue();
114 |
115 | System.out.println("Asadmin process exited with status " + exitValue);
116 | return exitValue;
117 |
118 | } catch (IllegalThreadStateException e) {
119 | // process is still running
120 | }
121 | }
122 |
123 | throw new IllegalStateException("Asadmin process seems stuck after waiting for 30 seconds");
124 | }
125 |
126 | public static boolean isWindows() {
127 | return OS.contains("win");
128 | }
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/test-utils/src/main/java/org/eclipse/microprofile14/JwtTokenGenerator.java:
--------------------------------------------------------------------------------
1 | package org.eclipse.microprofile14;
2 |
3 | import static com.nimbusds.jose.JOSEObjectType.JWT;
4 | import static com.nimbusds.jose.JWSAlgorithm.RS256;
5 | import static com.nimbusds.jwt.JWTClaimsSet.parse;
6 | import static java.lang.Thread.currentThread;
7 | import static net.minidev.json.parser.JSONParser.DEFAULT_PERMISSIVE_MODE;
8 |
9 | import java.security.KeyFactory;
10 | import java.security.PrivateKey;
11 | import java.security.spec.PKCS8EncodedKeySpec;
12 | import java.util.Base64;
13 |
14 | import org.eclipse.microprofile.jwt.Claims;
15 |
16 | import com.nimbusds.jose.JWSHeader;
17 | import com.nimbusds.jose.crypto.RSASSASigner;
18 | import com.nimbusds.jwt.SignedJWT;
19 |
20 | import net.minidev.json.JSONObject;
21 | import net.minidev.json.parser.JSONParser;
22 |
23 | public class JwtTokenGenerator {
24 |
25 | public static String generateJWTString(String jsonResource) throws Exception {
26 | byte[] byteBuffer = new byte[16384];
27 | currentThread().getContextClassLoader()
28 | .getResource(jsonResource)
29 | .openStream()
30 | .read(byteBuffer);
31 |
32 | JSONParser parser = new JSONParser(DEFAULT_PERMISSIVE_MODE);
33 | JSONObject jwtJson = (JSONObject) parser.parse(byteBuffer);
34 |
35 | long currentTimeInSecs = (System.currentTimeMillis() / 1000);
36 | long expirationTime = currentTimeInSecs + 1000;
37 |
38 | jwtJson.put(Claims.iat.name(), currentTimeInSecs);
39 | jwtJson.put(Claims.auth_time.name(), currentTimeInSecs);
40 | jwtJson.put(Claims.exp.name(), expirationTime);
41 |
42 | SignedJWT signedJWT = new SignedJWT(new JWSHeader
43 | .Builder(RS256)
44 | .keyID("/privateKey.pem")
45 | .type(JWT)
46 | .build(), parse(jwtJson));
47 |
48 | signedJWT.sign(new RSASSASigner(readPrivateKey("privateKey.pem")));
49 |
50 | return signedJWT.serialize();
51 | }
52 |
53 | public static PrivateKey readPrivateKey(String resourceName) throws Exception {
54 | byte[] byteBuffer = new byte[16384];
55 | int length = currentThread().getContextClassLoader()
56 | .getResource(resourceName)
57 | .openStream()
58 | .read(byteBuffer);
59 |
60 | String key = new String(byteBuffer, 0, length).replaceAll("-----BEGIN (.*)-----", "")
61 | .replaceAll("-----END (.*)----", "")
62 | .replaceAll("\r\n", "")
63 | .replaceAll("\n", "")
64 | .trim();
65 |
66 | return KeyFactory.getInstance("RSA")
67 | .generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(key)));
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/test-utils/src/main/java/org/eclipse/microprofile14/Libraries.java:
--------------------------------------------------------------------------------
1 | package org.eclipse.microprofile14;
2 |
3 | import org.jboss.shrinkwrap.api.spec.JavaArchive;
4 | import org.jboss.shrinkwrap.resolver.api.maven.Maven;
5 |
6 | public class Libraries {
7 |
8 | public static JavaArchive[] awaitability() {
9 | return Maven.resolver()
10 | .loadPomFromFile("pom.xml")
11 | .resolve("com.jayway.awaitility:awaitility")
12 | .withTransitivity()
13 | .as(JavaArchive.class);
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/test-utils/src/main/java/org/eclipse/microprofile14/Parameter.java:
--------------------------------------------------------------------------------
1 | package org.eclipse.microprofile14;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | @Retention(RetentionPolicy.RUNTIME)
9 | @Target({ElementType.FIELD})
10 | public @interface Parameter {
11 | }
12 |
13 |
--------------------------------------------------------------------------------
/test-utils/src/main/java/org/eclipse/microprofile14/ParameterRule.java:
--------------------------------------------------------------------------------
1 | package org.eclipse.microprofile14;
2 |
3 | import org.jboss.arquillian.container.test.api.Deployment;
4 |
5 | import org.junit.rules.MethodRule;
6 | import org.junit.runners.model.FrameworkMethod;
7 | import org.junit.runners.model.Statement;
8 |
9 | import javax.naming.InitialContext;
10 | import javax.naming.NamingException;
11 | import java.lang.reflect.Field;
12 | import java.lang.reflect.Method;
13 | import java.util.List;
14 |
15 | /**
16 | * Helper class for Parametrized tests as described here:
17 | * http://blog.schauderhaft.de/2012/12/16/writing-parameterized-tests-with-junit-rules/
18 | *
19 | * @param
20 | */
21 | public class ParameterRule implements MethodRule {
22 | private final List params;
23 |
24 | public ParameterRule(List params) {
25 | if (params == null || params.size() == 0) {
26 | throw new IllegalArgumentException("'params' must be specified and have more then zero length!");
27 | }
28 | this.params = params;
29 | }
30 |
31 | @Override
32 | public Statement apply(final Statement base, final FrameworkMethod method, final Object target) {
33 | return new Statement() {
34 | @Override
35 | public void evaluate() throws Throwable {
36 | boolean runInContainer = getDeploymentMethod(target).getAnnotation(Deployment.class).testable();
37 | if (runInContainer) {
38 | evaluateParametersInContainer(base, target);
39 | } else {
40 | evaluateParametersInClient(base, target);
41 | }
42 | }
43 | };
44 | }
45 |
46 | private Method getDeploymentMethod(Object target) throws NoSuchMethodException {
47 | Method[] methods = target.getClass().getDeclaredMethods();
48 | for (Method method : methods) {
49 | if (method.getAnnotation(Deployment.class) != null) return method;
50 | }
51 | throw new IllegalStateException("No method with @Deployment annotation found!");
52 | }
53 |
54 | private void evaluateParametersInContainer(Statement base, Object target) throws Throwable {
55 | if (isRunningInContainer()) {
56 | evaluateParamsToTarget(base, target);
57 | } else {
58 | ignoreStatementExecution(base);
59 | }
60 | }
61 |
62 | private void evaluateParametersInClient(Statement base, Object target) throws Throwable {
63 | if (isRunningInContainer()) {
64 | ignoreStatementExecution(base);
65 | } else {
66 | evaluateParamsToTarget(base, target);
67 | }
68 | }
69 |
70 | private boolean isRunningInContainer() {
71 | try {
72 | new InitialContext().lookup("java:comp/env");
73 | return true;
74 | } catch (NamingException e) {
75 | return false;
76 | }
77 | }
78 |
79 | private void evaluateParamsToTarget(Statement base, Object target) throws Throwable {
80 | for (Object param : params) {
81 | Field targetField = getTargetField(target);
82 | if (!targetField.isAccessible()) {
83 | targetField.setAccessible(true);
84 | }
85 | targetField.set(target, param);
86 | base.evaluate();
87 | }
88 | }
89 |
90 | private Field getTargetField(Object target) throws NoSuchFieldException {
91 | Field[] allFields = target.getClass().getDeclaredFields();
92 | for (Field field : allFields) {
93 | if (field.getAnnotation(Parameter.class) != null) return field;
94 | }
95 | throw new IllegalStateException("No field with @Parameter annotation found! Forgot to add it?");
96 | }
97 |
98 | private void ignoreStatementExecution(Statement base) {
99 | try {
100 | base.evaluate();
101 | } catch (Throwable ignored) {}
102 | }
103 | }
--------------------------------------------------------------------------------
/test-utils/src/main/java/org/eclipse/microprofile14/ServerOperations.java:
--------------------------------------------------------------------------------
1 | package org.eclipse.microprofile14;
2 |
3 | import java.nio.file.Paths;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | /**
8 | * Various high level Java EE 7 samples specific operations to execute against
9 | * the various servers used for running the samples
10 | *
11 | * @author arjan
12 | *
13 | */
14 | public class ServerOperations {
15 |
16 | /**
17 | * Add the default test user and credentials to the identity store of
18 | * supported containers
19 | */
20 | public static void addUsersToContainerIdentityStore() {
21 |
22 | // TODO: abstract adding container managed users to utility class
23 | // TODO: consider PR for sending CLI commands to Arquillian
24 |
25 | String javaEEServer = System.getProperty("javaEEServer");
26 |
27 | if ("glassfish-remote".equals(javaEEServer) || "payara-remote".equals(javaEEServer)) {
28 |
29 | System.out.println("Adding user for glassfish-remote");
30 |
31 | List cmd = new ArrayList<>();
32 |
33 | cmd.add("create-file-user");
34 | cmd.add("--groups");
35 | cmd.add("g1");
36 | cmd.add("--passwordfile");
37 | cmd.add(Paths.get("").toAbsolutePath() + "/src/test/resources/password.txt");
38 |
39 | cmd.add("u1");
40 |
41 | CliCommands.payaraGlassFish(cmd);
42 | } else {
43 | if (javaEEServer == null) {
44 | System.out.println("javaEEServer not specified");
45 | } else {
46 | System.out.println(javaEEServer + " not supported");
47 | }
48 | }
49 |
50 | // TODO: support other servers than Payara and GlassFish
51 |
52 | // WildFly ./bin/add-user.sh -a -u u1 -p p1 -g g1
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/test-utils/src/main/resources/arquillian-thorntail.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
11 |
12 |
13 | localhost
14 | ${thorntail.arquillian.daemon.port:12345}
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/test-utils/src/main/resources/arquillian.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 | production
11 |
12 |
13 |
14 |
15 |
16 | xml
17 | ${arquillian.liberty.wlpHome}
18 |
19 |
20 |
21 |
22 |
23 | xml
24 | ${arquillian.liberty.wlpHome}
25 | -Dwas.debug.mode=true -Dcom.ibm.websphere.ras.inject.at.transform=true -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/test-utils/src/main/resources/key.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/javaee-samples/microprofile1.4-samples/0be7890237d6cdc403d2c89ce5133a57d2c7bf16/test-utils/src/main/resources/key.jks
--------------------------------------------------------------------------------
/test-utils/src/main/resources/logging.properties:
--------------------------------------------------------------------------------
1 | handlers= java.util.logging.ConsoleHandler
2 | java.util.logging.ConsoleHandler.level = FINER
3 |
4 | org.jboss.arquillian.container.was.wlp_managed_8_5.WLPManagedContainer.level=FINER
--------------------------------------------------------------------------------
/test-utils/src/main/resources/server.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | microProfile-1.2
7 | localConnector-1.0
8 |
9 |
10 |
11 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------