Skip to content

Commit 163cc92

Browse files
committed
[WFLY-22003] Replace JPA-based DB initialization with JDBC startup bean to fix Glow unbound datasource warning
1 parent 66f1a5e commit 163cc92

7 files changed

Lines changed: 231 additions & 100 deletions

File tree

servlet-security/README-source.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ The `servlet-security` quickstart demonstrates the use of Jakarta EE declarative
1818

1919
The `servlet-security` quickstart demonstrates the use of Jakarta EE declarative security to control access to Servlets and Security in {productNameFull}.
2020

21-
When you deploy this example, two users are automatically created for you: user `quickstartUser` with password `quickstartPwd1!` and user `guest` with password `guestPwd1!`. This data is located in the `src/main/resources/import.sql` file.
21+
When you deploy this example, two users are automatically created for you: user `quickstartUser` with password `quickstartPwd1!` and user `guest` with password `guestPwd1!`. This data is initialized by the `DatabaseInitializer` singleton EJB on application startup.
2222

2323
This quickstart takes the following steps to implement Servlet security:
2424

servlet-security/configure-server.cli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ batch
1414
# Configure Undertow's application security domain
1515
/subsystem=undertow/application-security-domain=servlet-security-quickstart:add(security-domain=servlet-security-quickstart-sd)
1616

17+
# Configure EJB's application security domain
18+
/subsystem=ejb3/application-security-domain=servlet-security-quickstart:add(security-domain=servlet-security-quickstart-sd)
19+
1720
# Run the batch commands
1821
run-batch
1922

servlet-security/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@
9393
</dependency>
9494

9595
<dependency>
96-
<groupId>jakarta.persistence</groupId>
97-
<artifactId>jakarta.persistence-api</artifactId>
96+
<groupId>jakarta.ejb</groupId>
97+
<artifactId>jakarta.ejb-api</artifactId>
9898
<scope>provided</scope>
9999
</dependency>
100100

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
/*
2+
* JBoss, Home of Professional Open Source
3+
* Copyright 2015, Red Hat, Inc. and/or its affiliates, and individual
4+
* contributors by the @authors tag. See the copyright.txt in the
5+
* distribution for a full listing of individual contributors.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.jboss.as.quickstarts.servlet_security;
18+
19+
import java.sql.Connection;
20+
import java.sql.PreparedStatement;
21+
import java.sql.ResultSet;
22+
import java.sql.SQLException;
23+
import java.sql.Statement;
24+
import java.util.logging.Level;
25+
import java.util.logging.Logger;
26+
27+
import javax.sql.DataSource;
28+
29+
import jakarta.annotation.PostConstruct;
30+
import jakarta.annotation.Resource;
31+
import jakarta.annotation.security.PermitAll;
32+
import jakarta.ejb.Singleton;
33+
import jakarta.ejb.Startup;
34+
35+
/**
36+
* Initializes the database schema and data for Elytron JDBC realm authentication.
37+
* This singleton EJB runs at application startup to create tables and populate
38+
* test user credentials if they don't already exist.
39+
*
40+
* @author Mohammed Abourass
41+
*/
42+
@Singleton
43+
@Startup
44+
@PermitAll
45+
public class DatabaseInitializer {
46+
47+
private static final Logger LOGGER = Logger.getLogger(DatabaseInitializer.class.getName());
48+
49+
@Resource(lookup = "java:jboss/datasources/ServletSecurityDS")
50+
private DataSource dataSource;
51+
52+
@PostConstruct
53+
public void initializeDatabase() {
54+
LOGGER.info("Initializing database schema for servlet-security...");
55+
56+
try {
57+
createTables();
58+
insertTestData();
59+
LOGGER.info("Database initialization completed successfully.");
60+
} catch (SQLException e) {
61+
LOGGER.log(Level.SEVERE, "Failed to initialize database", e);
62+
throw new RuntimeException("Database initialization failed", e);
63+
}
64+
}
65+
66+
private void createTables() throws SQLException {
67+
Connection conn = null;
68+
Statement stmt = null;
69+
70+
try {
71+
conn = dataSource.getConnection();
72+
stmt = conn.createStatement();
73+
74+
// Create USERS table if not exists
75+
stmt.executeUpdate(
76+
"CREATE TABLE IF NOT EXISTS USERS (" +
77+
"ID INT, " +
78+
"USERNAME VARCHAR(20), " +
79+
"PASSWORD VARCHAR(20))"
80+
);
81+
82+
// Create ROLES table if not exists
83+
stmt.executeUpdate(
84+
"CREATE TABLE IF NOT EXISTS ROLES (" +
85+
"ID INT, " +
86+
"NAME VARCHAR(20))"
87+
);
88+
89+
// Create USERS_ROLES junction table if not exists
90+
stmt.executeUpdate(
91+
"CREATE TABLE IF NOT EXISTS USERS_ROLES (" +
92+
"USER_ID INT, " +
93+
"ROLE_ID INT)"
94+
);
95+
96+
LOGGER.info("Database tables created or verified");
97+
98+
} finally {
99+
if (stmt != null) {
100+
try {
101+
stmt.close();
102+
} catch (SQLException e) {
103+
LOGGER.log(Level.WARNING, "Failed to close statement", e);
104+
}
105+
}
106+
if (conn != null) {
107+
try {
108+
conn.close();
109+
} catch (SQLException e) {
110+
LOGGER.log(Level.WARNING, "Failed to close connection", e);
111+
}
112+
}
113+
}
114+
}
115+
116+
private void insertTestData() throws SQLException {
117+
Connection conn = null;
118+
PreparedStatement insertStmt = null;
119+
120+
try {
121+
conn = dataSource.getConnection();
122+
123+
// Check if data already exists (avoid duplicates on redeployment)
124+
if (userExists(conn, "quickstartUser")) {
125+
LOGGER.info("Test data already exists, skipping insertion");
126+
return;
127+
}
128+
129+
// Insert users
130+
insertStmt = conn.prepareStatement(
131+
"INSERT INTO USERS (ID, USERNAME, PASSWORD) VALUES (?, ?, ?)"
132+
);
133+
134+
insertStmt.setInt(1, 1);
135+
insertStmt.setString(2, "quickstartUser");
136+
insertStmt.setString(3, "quickstartPwd1!");
137+
insertStmt.executeUpdate();
138+
139+
insertStmt.setInt(1, 2);
140+
insertStmt.setString(2, "guest");
141+
insertStmt.setString(3, "guestPwd1!");
142+
insertStmt.executeUpdate();
143+
144+
insertStmt.close();
145+
146+
// Insert roles
147+
insertStmt = conn.prepareStatement(
148+
"INSERT INTO ROLES (ID, NAME) VALUES (?, ?)"
149+
);
150+
151+
insertStmt.setInt(1, 1);
152+
insertStmt.setString(2, "quickstarts");
153+
insertStmt.executeUpdate();
154+
155+
insertStmt.setInt(1, 2);
156+
insertStmt.setString(2, "guest");
157+
insertStmt.executeUpdate();
158+
159+
insertStmt.close();
160+
161+
// Insert user-role mappings
162+
insertStmt = conn.prepareStatement(
163+
"INSERT INTO USERS_ROLES (USER_ID, ROLE_ID) VALUES (?, ?)"
164+
);
165+
166+
insertStmt.setInt(1, 1);
167+
insertStmt.setInt(2, 1);
168+
insertStmt.executeUpdate();
169+
170+
insertStmt.setInt(1, 2);
171+
insertStmt.setInt(2, 2);
172+
insertStmt.executeUpdate();
173+
174+
LOGGER.info("Test data inserted successfully");
175+
176+
} finally {
177+
if (insertStmt != null) {
178+
try {
179+
insertStmt.close();
180+
} catch (SQLException e) {
181+
LOGGER.log(Level.WARNING, "Failed to close insert statement", e);
182+
}
183+
}
184+
if (conn != null) {
185+
try {
186+
conn.close();
187+
} catch (SQLException e) {
188+
LOGGER.log(Level.WARNING, "Failed to close connection", e);
189+
}
190+
}
191+
}
192+
}
193+
194+
private boolean userExists(Connection conn, String username) throws SQLException {
195+
PreparedStatement stmt = null;
196+
ResultSet rs = null;
197+
198+
try {
199+
stmt = conn.prepareStatement("SELECT COUNT(*) FROM USERS WHERE USERNAME = ?");
200+
stmt.setString(1, username);
201+
rs = stmt.executeQuery();
202+
203+
if (rs.next()) {
204+
return rs.getInt(1) > 0;
205+
}
206+
return false;
207+
208+
} finally {
209+
if (rs != null) {
210+
try {
211+
rs.close();
212+
} catch (SQLException e) {
213+
LOGGER.log(Level.WARNING, "Failed to close result set", e);
214+
}
215+
}
216+
if (stmt != null) {
217+
try {
218+
stmt.close();
219+
} catch (SQLException e) {
220+
LOGGER.log(Level.WARNING, "Failed to close statement", e);
221+
}
222+
}
223+
}
224+
}
225+
}

servlet-security/src/main/java/org/jboss/as/quickstarts/servlet_security/DummyEntity.java

Lines changed: 0 additions & 33 deletions
This file was deleted.

servlet-security/src/main/resources/META-INF/persistence.xml

Lines changed: 0 additions & 35 deletions
This file was deleted.

servlet-security/src/main/resources/import.sql

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)