Skip to content

Commit

Permalink
Updates 11/21/2023
Browse files Browse the repository at this point in the history
  • Loading branch information
mpredli01 committed Nov 21, 2023
1 parent 8f8b295 commit 8524c7e
Show file tree
Hide file tree
Showing 23 changed files with 329 additions and 101 deletions.
2 changes: 1 addition & 1 deletion README.adoc
Expand Up @@ -2,7 +2,7 @@

== Introduction

This repository complements the presentation, *Jakarta EE 11: Going Beyond the Era of Java EE* which will be debuted at the Philly Java Users Group on November 15, 2023.
This repository complements the presentation, *Jakarta EE 11: Going Beyond the Era of Java EE* which will be debuted at the https://www.meetup.com/phillyjug/events/294593853/[Philly Java Users Group] on November 15, 2023.

Corresponding documentation is shown under the `spec` directory and will be automatically built upon executing `mvn clean package`.

Expand Down
191 changes: 191 additions & 0 deletions data/beer.txt
@@ -0,0 +1,191 @@
[APP] --------------------------------------------------------
[APP] Welcome to the Beer Application using Jakarta Data
[APP] --------------------------------------------------------
[APP] ------------------------------------------------------------------------------------------
[APP] Let's start by obtaining the number of documents in the Beer and Brewer collections:
[APP] ------------------------------------------------------------------------------------------
[APP] There are 32 beers in the Beer collection
[APP] There are 34 brewers in the Brewer collection
[APP] --------------------------------------------------------
[APP] Let's find beers by using a query named parameter:
[APP] --------------------------------------------------------
Beer { id = '1', name = 'Pumking', type = 'ALE', brewer_id = '1', abv = '8.6' }

Brewer { id = '32', name = 'Apponaug Brewing', city = 'Warwick', state = 'Rhode Island' }

[APP] -------------------------------------------
[APP] Let's find a beer by its primary key:
[APP] -------------------------------------------
[APP] Optional[Beer { id = '5', name = 'Purple Monkey Dishwasher', type = 'PORTER', brewer_id = '11', abv = '6.7' }
]
[APP] -----------------------------------
[APP] Let's find a beer by its name
[APP] -----------------------------------
Beer { id = '30', name = 'Power Plant Amber Lager', type = 'LAGER', brewer_id = '34', abv = '5.4' }

[APP] -------------------------------------------
[APP] Let's find a beer by its `brewer_id`:
[APP] -------------------------------------------
Beer { id = '1', name = 'Pumking', type = 'ALE', brewer_id = '1', abv = '8.6' }

Beer { id = '4', name = 'Warlock Imperial Stout', type = 'STOUT', brewer_id = '1', abv = '8.6' }

Beer { id = '34', name = 'Caramel Pumpkin Imperial Ale', type = 'ALE', brewer_id = '1', abv = '8.6' }

Beer { id = '32', name = 'Caramel Pumpkin Imperial Ale', type = 'ALE', brewer_id = '1', abv = '8.6' }

[APP] ------------------------------------------------------------
[APP] Let's find all beers and paginate with ascending sort:
[APP] ------------------------------------------------------------
[APP] ---------------------
[APP] Here is page 1:
[APP] ---------------------
Beer { id = '25', name = 'Bourbon Barrel Quad', type = 'ALE', brewer_id = '30', abv = '12.2' }

Beer { id = '19', name = 'Brandy Barrel-Aged Pumpkin Imperial Ale', type = 'ALE', brewer_id = '27', abv = '13.4' }

Beer { id = '6', name = 'Budweiser', type = 'LAGER', brewer_id = '12', abv = '6.0' }

Beer { id = '28', name = 'Busy Beaver', type = 'ALE', brewer_id = '32', abv = '5.5' }

Beer { id = '32', name = 'Caramel Pumpkin Imperial Ale', type = 'ALE', brewer_id = '1', abv = '8.6' }

Beer { id = '34', name = 'Caramel Pumpkin Imperial Ale', type = 'ALE', brewer_id = '1', abv = '8.6' }

Beer { id = '27', name = 'Convection', type = 'IPA', brewer_id = '32', abv = '8.0' }

Beer { id = '15', name = 'ESB (Extra Stockton Bitter)', type = 'ALE', brewer_id = '23', abv = '4.3' }

Beer { id = '16', name = 'Extraordinary Machine', type = 'IPA', brewer_id = '23', abv = '6.4' }

Beer { id = '22', name = 'Focal Banger', type = 'IPA', brewer_id = '16', abv = '7.0' }

[APP] ---------------------
[APP] Here is page 2:
[APP] ---------------------
Beer { id = '29', name = 'Freedom Torch Milk Stout', type = 'STOUT', brewer_id = '34', abv = '6.0' }

Beer { id = '14', name = 'Golden Boi', type = 'ALE', brewer_id = '21', abv = '5.0' }

Beer { id = '21', name = 'Heady Topper', type = 'IPA', brewer_id = '16', abv = '8.0' }

Beer { id = '9', name = 'Hopitoulas', type = 'IPA', brewer_id = '17', abv = '6.5' }

Beer { id = '12', name = 'IPA1A', type = 'IPA', brewer_id = '19', abv = '6.4' }

Beer { id = '10', name = 'Irish Channel Stout', type = 'STOUT', brewer_id = '17', abv = '6.8' }

Beer { id = '2', name = 'Liquid Truth Serum IPA', type = 'IPA', brewer_id = '2', abv = '7.0' }

Beer { id = '31', name = 'Lunch', type = 'IPA', brewer_id = '33', abv = '7.0' }

Beer { id = '33', name = 'Lunch', type = 'IPA', brewer_id = '33', abv = '7.0' }

Beer { id = '7', name = 'Michelob Ultra', type = 'LAGER', brewer_id = '12', abv = '4.2' }

[APP] ---------------------
[APP] Here is page 3:
[APP] ---------------------
Beer { id = '13', name = 'Monstera', type = 'IPA', brewer_id = '21', abv = '8.0' }

Beer { id = '20', name = 'New Grist Gose with Lime', type = 'GOSE', brewer_id = '27', abv = '5.1' }

Beer { id = '3', name = 'Oatmeal Milk Stout', type = 'STOUT', brewer_id = '3', abv = '6.7' }

Beer { id = '18', name = 'Oktoberfest', type = 'LAGER', brewer_id = '25', abv = '6.0' }

Beer { id = '30', name = 'Power Plant Amber Lager', type = 'LAGER', brewer_id = '34', abv = '5.4' }

Beer { id = '1', name = 'Pumking', type = 'ALE', brewer_id = '1', abv = '8.6' }

Beer { id = '17', name = 'Pumpkin Pickin' Ale', type = 'ALE', brewer_id = '25', abv = '7.0' }

Beer { id = '5', name = 'Purple Monkey Dishwasher', type = 'PORTER', brewer_id = '11', abv = '6.7' }

Beer { id = '23', name = 'Tank 7', type = 'ALE', brewer_id = '30', abv = '8.5' }

Beer { id = '24', name = 'The Calling IPA', type = 'IPA', brewer_id = '30', abv = '8.5' }

[APP] -----------------------------
[APP] Let's find all brewers:
[APP] -----------------------------
[APP] ---------------------
[APP] Here is page 4:
[APP] ---------------------
Brewer { id = '19', name = '26 Degree Brewing', city = 'Pompano Beach', state = 'Florida' }

Brewer { id = '16', name = 'Alchemist Brewery', city = 'Stowe', state = 'Vermont' }

Brewer { id = '34', name = 'American Icon Brewery', city = 'Vero Beach', state = 'Florida' }

Brewer { id = '12', name = 'Anheuser-Busch', city = 'St. Louis', state = 'Missouri' }

Brewer { id = '32', name = 'Apponaug Brewing', city = 'Warwick', state = 'Rhode Island' }

Brewer { id = '30', name = 'Boulevard Brewing', city = 'Kansas City', state = 'Missouri' }

Brewer { id = '13', name = 'Conclave Brewing', city = 'Flemington', state = 'New Jersey' }

Brewer { id = '7', name = 'Czig Meister', city = 'Hackettstown', state = 'New Jersey' }

Brewer { id = '18', name = 'Dangerous Minds Brewing', city = 'Pompano Beach', state = 'Florida' }

Brewer { id = '2', name = 'Dogfish Head', city = 'Milton', state = 'Delaware' }

Brewer { id = '6', name = 'DuClaw', city = 'Rosedale', state = 'Maryland' }

Brewer { id = '11', name = 'Evil Genius Beer Company', city = 'Philadelphia', state = 'Pennsylvania' }

Brewer { id = '28', name = 'Highrail', city = 'High Bridge', state = 'New Jersey' }

Brewer { id = '27', name = 'Lakefront Brewery', city = 'Milwaukee', state = 'Wisconsin' }

Brewer { id = '5', name = 'Lone Eagle Brewing', city = 'Flemington', state = 'New Jersey' }

Brewer { id = '33', name = 'Maine Beer Company', city = 'Freeport', state = 'Maine' }

Brewer { id = '21', name = 'Miel Brewery & Taproom', city = 'New Orleans', state = 'Louisiana' }

Brewer { id = '17', name = 'NOLA Brewing', city = 'New Orleans', state = 'Louisiana' }

Brewer { id = '31', name = 'Narragansett Brewing', city = 'Providence', state = 'Rhode Island' }

Brewer { id = '22', name = 'Newport Storm Brewing', city = 'Newport', state = 'Rhode Island' }

Brewer { id = '23', name = 'Odd Bird Brewing', city = 'Stockton', state = 'New Jersey' }

Brewer { id = '24', name = 'Port Orleans', city = 'New Orleans', state = 'Louisiana' }

Brewer { id = '29', name = 'Readington Brewery', city = 'Readington', state = 'New Jersey' }

Brewer { id = '3', name = 'River Horse', city = 'Ewing', state = 'New Jersey' }

Brewer { id = '25', name = 'Screamin' Hill Brewery', city = 'Cream Ridge', state = 'New Jersey' }

Brewer { id = '26', name = 'Second Line Brewing', city = 'New Orleans', state = 'Louisiana' }

Brewer { id = '1', name = 'Southern Tier', city = 'Lakewood', state = 'New York' }

Brewer { id = '10', name = 'Strange Days Brewing', city = 'Kansas City', state = 'Missouri' }

Brewer { id = '14', name = 'Sunken Silo', city = 'Lebanon', state = 'New Jersey' }

Brewer { id = '20', name = 'The Courtyard Brewery', city = 'New Orleans', state = 'Louisiana' }

Brewer { id = '9', name = 'Torn Label Brewing', city = 'Kansas City', state = 'Missouri' }

Brewer { id = '15', name = 'Urban South Brewing', city = 'New Orleans', state = 'Louisiana' }

Brewer { id = '4', name = 'Victory', city = 'Downington', state = 'Pennsylvania' }

Brewer { id = '8', name = 'Weyerbacher', city = 'Easton', state = 'Pennsylvania' }

[APP] ---------------------------------------------
[APP] Let's delete a beer by its primary key:
[APP] ---------------------------------------------
[APP] -----------------------------------------------
[APP] Let's delete a brewer by its primary key:
[APP] -----------------------------------------------
[APP] ----------------------------------------------------------
[APP] COMING SOON: Let's update a document in the database
[APP] ----------------------------------------------------------
8 changes: 6 additions & 2 deletions data/src/main/java/org/redlich/data/BeerApp.java
Expand Up @@ -97,11 +97,15 @@ public static void main(String[] args) {
Page<Beer> page1 = beerRepository.findAll(page);
page1.forEach(System.out::println);

app.delay(3000);

app.displayTitle("[APP] Here is page 2:");
Pageable secondPage = page.next();
Page<Beer> page2 = beerRepository.findAll(secondPage);
page2.forEach(System.out::println);

app.delay(3000);

app.displayTitle("[APP] Here is page 3:");
Pageable thirdPage = secondPage.next();
Page<Beer> page3 = beerRepository.findAll(thirdPage);
Expand All @@ -118,10 +122,10 @@ public static void main(String[] args) {
app.delay(3000);

app.displayTitle("[APP] Let's delete a beer by its primary key:");
beerRepository.deleteById(31);
// beerRepository.deleteById(33);

app.displayTitle("[APP] Let's delete a brewer by its primary key:");
brewerRepository.deleteById(35);
// brewerRepository.deleteById(35);

app.displayTitle("[APP] COMING SOON: Let's update a document in the database");
/*/
Expand Down
Binary file added jwtbridge/src/main/.DS_Store
Binary file not shown.
Expand Up @@ -35,8 +35,8 @@ public CredentialValidationResult validate(UsernamePasswordCredential usernamePa
* store can be defined.
*/

if (usernamePasswordCredential.compareTo("Mike", "secret2")) {
return new CredentialValidationResult("Mike", new HashSet<>(asList("foo", "bar")));
if (usernamePasswordCredential.compareTo("Mike", "password")) {
return new CredentialValidationResult("Mike", new HashSet<>(asList("admin", "audit")));
}

return CredentialValidationResult.INVALID_RESULT;
Expand Down
Expand Up @@ -14,7 +14,6 @@
import jakarta.annotation.security.DeclareRoles;
import jakarta.inject.Inject;
import jakarta.security.enterprise.SecurityContext;
import jakarta.security.enterprise.identitystore.openid.JwtClaims;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.HttpConstraint;
import jakarta.servlet.annotation.ServletSecurity;
Expand All @@ -38,16 +37,16 @@
import java.util.Set;

@WebServlet("/jwtbridge")
@DeclareRoles({ "foo", "bar", "kaz" })
@ServletSecurity(@HttpConstraint(rolesAllowed = "foo"))
@DeclareRoles({ "admin", "audit", "user" })
@ServletSecurity(@HttpConstraint(rolesAllowed = "admin"))
@JwtAuthenticationMechanismDefinition(
jwtClaimsDefinition = @JwtClaimsDefinition(callerNameClaim = "upn", callerGroupsClaim = "groups"),
publicKeyDefinition = @PublicKeyDefinition(key = "key", location = "location", algorithm = "RS256"),
decryptionKeyDefinition = @PrivateKeyDefinition(location = "location", algorithm = "RS256"),
jwtClaimsVerification = @JwtClaimsVerification(issuer = "issuer", audiences = "aud", tokenAge = 0, tokenAgeExpression = "", clockSkew = 0, clockSkewExpression = ""),
httpHeadersDefinition = @HttpHeadersDefinition(tokenHeader = "Authorization", cookieName = "Bearer"),
jwksDefinition = @JwksDefinition(jwksConnectTimeout = 500, jwksConnectTimeoutExpression = "", jwksReadTimeout = 500, jwksReadTimeoutExpression = ""))
public class JwtSecuredServlet extends HttpServlet {
public class JwtBridgeApplication extends HttpServlet {

@Inject
SecurityContext securityContext;
Expand All @@ -62,30 +61,30 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
// JwtClaims jwtClaims = securityContext.getPrincipalsByType(ptype);
// Set<JwtClaims> jwtClaims = securityContext.getPrincipalsByType(JwtClaims.class);

// Example 1: Is the caller is one of the three roles: admin, user and demo
// Example 1: Is the caller is one of the three roles: admin, audit and user
PrintWriter pw = response.getWriter();

pw.write(message);
pw.write(message + "\n\n");

boolean role = securityContext.isCallerInRole("admin");
pw.write("User has role 'admin': " + role + "\n");

role = securityContext.isCallerInRole("audit");
pw.write("User has role 'audit': " + role + "\n");

role = securityContext.isCallerInRole("user");
pw.write("User has role 'user': " + role + "\n");

role = securityContext.isCallerInRole("demo");
pw.write("User has role 'demo': " + role + "\n");

// Example 2: What is the caller principal name
String contextName = null;
if (securityContext.getCallerPrincipal() != null) {
contextName = securityContext.getCallerPrincipal().getName();
}
response.getWriter().write("context username: " + contextName + "\n");
response.getWriter().write("Context username: " + contextName + "\n");

Set<Principal> principals = securityContext.getPrincipalsByType(Principal.class);
for(Principal customPrincipal : principals) {
response.getWriter().write((customPrincipal.getName()));
response.getWriter().write((customPrincipal.getName() + "\n"));
}
}
}
Binary file added jwtbridge/src/main/webapp/.DS_Store
Binary file not shown.
Binary file added jwtbridge/src/main/webapp/images/gsjug-logo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added jwtbridge/src/main/webapp/images/payara-logo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 17 additions & 19 deletions jwtbridge/src/main/webapp/index.html
@@ -1,37 +1,35 @@
<html lang="en">
<head>
<title>MicroProfile JWT Bridge Demo Application</title>
<style>
li, a, p, h2, h3 { font-family: Arial; color: white;}
body { background-color: black;}
</style>
</head>

<body>

<h2>Welcome to the MicroProfil JWT Bridge Demo Application</h2>
<h2>Welcome to the MicroProfile JWT Bridge Demo Application</h2>

<h3>Hosted on the serverless Payara Cloud</h3>

<p>
Welcome to <a href="https://jakarta.ee">Jakarta EE</a>!
This is a very simple Jakarta EE application generated by the official Eclipse Starter.
<a href="https://www.payara.fish/" target="_blank"><img width="200" height="72" src="images/payara-logo.png" alt="Payara Logo" /></a>
<a href="https://gsjug.org/" target="_blank"><img width="150" height="149" src="images/gsjug-logo.png" alt="Garden State Java User Group Logo"></a>
<a href="https://jakarta.ee" target="_blank"><img width="200" width="152" src="images/jakartaee-logo.png" alt="Jakarta EE Logo" /></a>
</p>

<p><a href="https://jakarta.ee"><img width="100%" src="images/jakartaee_logo.jpg" alt="Jakarta EE Logo"></a></p>

<!-- <p>The REST endpoint for this demo is available at <a href="servlet">servlet</a>.</p> -->

<h4>Learn more!</h4>
<h3>Please proceed to the <a href="jwtbridge" target="_blank">main application</a>.</h3>

<p>
There are many excellent free resources to learn Jakarta EE!
The following are some that you should begin exploring alongside the starter.
</p>
<h2>Resources</h2>

<ul>
<li>The <a target="_blank" href="https://eclipse-ee4j.github.io/jakartaee-tutorial">Jakarta EE Tutorial</a> is a comprehensive reference for developing applications with Jakarta EE.</li>
<li>The <a target="_blank" href="https://eclipse-ee4j.github.io/jakartaee-firstcup/">First Cup</a> is part of the Tutorial and is a gentle hands-on introduction to Jakarta EE.</li>
<li>You can further explore the <a target="_blank" href="https://github.com/eclipse-ee4j/jakartaee-firstcup-examples">First Cup Examples</a>to get a feel for how Jakarta EE applications look like.</li>
<li>The <a target="_blank" href="https://github.com/eclipse-ee4j/jakartaee-tutorial-examples">Jakarta EE Tutorial Examples</a> is a very comprehensive resource showing you how to use many Jakarta EE APIs and features.</li>
<li>The <a target="_blank" href="https://eclipse-ee4j.github.io/cargotracker/">Eclipse Cargo Tracker</a> project demo nstrates first-hand how you can develop applications with Jakarta EE using widely adopted architectural best practices like Domain-Driven Design (DDD).</li>
<li>Jakarta EE <a href="https://jakarta.ee/specifications/" target="_blank">specifications</a></li>
<li><a href="https://jakarta.ee/specifications/security" target="_blank">Jakarta Security</a> specification</li>
<li><a href="https://github.com/eclipse/microprofile-jwt-auth/blob/main/README.adoc" target="_blank">MicroProfile JWT Authentication</a> specification</li>
<li><a href="https://github.com/eclipse/microprofile-jwt-bridge#microprofile-jwt-bridge" target="_blank">MicroProfile JWT Bridge</a> specification</li>
<li>GitHub <a href="https://github.com/mpredli01/jakartaee-11" target="_blank">repository</a> for all the demos</li>
</ul>

<p><strong>We hope you enjoy your Jakarta EE journey!</strong></p>

</body>
</html>
Expand Up @@ -21,7 +21,7 @@
import jakarta.security.enterprise.identitystore.IdentityStore;

@ApplicationScoped
public class TestIdentityStore implements IdentityStore {
public class ApplicationIdentityStore implements IdentityStore {

public CredentialValidationResult validate(UsernamePasswordCredential usernamePasswordCredential) {

Expand All @@ -34,8 +34,8 @@ public CredentialValidationResult validate(UsernamePasswordCredential usernamePa
* store can be defined.
*/

if (usernamePasswordCredential.compareTo("Joe", "secret1")) {
return new CredentialValidationResult("Joe", new HashSet<>(asList("foo", "bar")));
if (usernamePasswordCredential.compareTo("Mike", "password")) {
return new CredentialValidationResult("Mike", new HashSet<>(asList("admin", "audit")));
}

return CredentialValidationResult.INVALID_RESULT;
Expand Down

0 comments on commit 8524c7e

Please sign in to comment.