KEYCLOAK-1542 - Server Info page extended by info about DB and MongoDB.
Functional test for /serverinfo REST endpoint added.
This commit is contained in:
parent
dfb871c26a
commit
652b2fee86
10 changed files with 720 additions and 388 deletions
|
@ -1,23 +1,26 @@
|
||||||
package org.keycloak.connections.jpa;
|
package org.keycloak.connections.jpa;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.naming.InitialContext;
|
||||||
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.EntityManagerFactory;
|
||||||
|
import javax.persistence.Persistence;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.hibernate.ejb.AvailableSettings;
|
import org.hibernate.ejb.AvailableSettings;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.connections.jpa.updater.JpaUpdaterProvider;
|
import org.keycloak.connections.jpa.updater.JpaUpdaterProvider;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
import org.keycloak.provider.ProviderOperationalInfo;
|
||||||
import javax.naming.InitialContext;
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.EntityManagerFactory;
|
|
||||||
import javax.persistence.Persistence;
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -30,6 +33,8 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide
|
||||||
|
|
||||||
private Config.Scope config;
|
private Config.Scope config;
|
||||||
|
|
||||||
|
private DatabaseInfo databaseInfo;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JpaConnectionProvider create(KeycloakSession session) {
|
public JpaConnectionProvider create(KeycloakSession session) {
|
||||||
lazyInit(session);
|
lazyInit(session);
|
||||||
|
@ -120,6 +125,9 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide
|
||||||
properties.put("hibernate.show_sql", config.getBoolean("showSql", false));
|
properties.put("hibernate.show_sql", config.getBoolean("showSql", false));
|
||||||
properties.put("hibernate.format_sql", config.getBoolean("formatSql", true));
|
properties.put("hibernate.format_sql", config.getBoolean("formatSql", true));
|
||||||
|
|
||||||
|
connection = getConnection();
|
||||||
|
prepareDatabaseInfo(connection);
|
||||||
|
|
||||||
if (databaseSchema != null) {
|
if (databaseSchema != null) {
|
||||||
logger.trace("Updating database");
|
logger.trace("Updating database");
|
||||||
|
|
||||||
|
@ -128,8 +136,6 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide
|
||||||
throw new RuntimeException("Can't update database: JPA updater provider not found");
|
throw new RuntimeException("Can't update database: JPA updater provider not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
connection = getConnection();
|
|
||||||
|
|
||||||
if (databaseSchema.equals("update")) {
|
if (databaseSchema.equals("update")) {
|
||||||
String currentVersion = null;
|
String currentVersion = null;
|
||||||
try {
|
try {
|
||||||
|
@ -171,6 +177,19 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void prepareDatabaseInfo(Connection connection) {
|
||||||
|
try {
|
||||||
|
databaseInfo = new DatabaseInfo();
|
||||||
|
DatabaseMetaData md = connection.getMetaData();
|
||||||
|
databaseInfo.databaseDriver = md.getDriverName() + " " + md.getDriverVersion();
|
||||||
|
databaseInfo.databaseProduct = md.getDatabaseProductName() + " " + md.getDatabaseProductVersion();
|
||||||
|
databaseInfo.databaseUser = md.getUserName();
|
||||||
|
databaseInfo.jdbcUrl = md.getURL();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logger.warn("Unable to get database info due " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Connection getConnection() {
|
private Connection getConnection() {
|
||||||
try {
|
try {
|
||||||
String dataSourceLookup = config.get("dataSource");
|
String dataSourceLookup = config.get("dataSource");
|
||||||
|
@ -186,4 +205,38 @@ public class DefaultJpaConnectionProviderFactory implements JpaConnectionProvide
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DatabaseInfo getOperationalInfo() {
|
||||||
|
return databaseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DatabaseInfo implements ProviderOperationalInfo {
|
||||||
|
protected String jdbcUrl;
|
||||||
|
protected String databaseUser;
|
||||||
|
protected String databaseProduct;
|
||||||
|
protected String databaseDriver;
|
||||||
|
|
||||||
|
public String getJdbcUrl() {
|
||||||
|
return jdbcUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatabaseDriver() {
|
||||||
|
return databaseDriver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatabaseUser() {
|
||||||
|
return databaseUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatabaseProduct() {
|
||||||
|
return databaseProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOk() {
|
||||||
|
// TODO KEYCLOAK-1578 - implement operational monitoring of JPA DB connection
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package org.keycloak.connections.jpa;
|
package org.keycloak.connections.jpa;
|
||||||
|
|
||||||
import org.keycloak.provider.ProviderFactory;
|
import org.keycloak.provider.MonitorableProviderFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
public interface JpaConnectionProviderFactory extends ProviderFactory<JpaConnectionProvider> {
|
public interface JpaConnectionProviderFactory extends MonitorableProviderFactory<JpaConnectionProvider> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package org.keycloak.connections.mongo;
|
package org.keycloak.connections.mongo;
|
||||||
|
|
||||||
import com.mongodb.DB;
|
import java.lang.reflect.Method;
|
||||||
import com.mongodb.MongoClient;
|
import java.net.UnknownHostException;
|
||||||
import com.mongodb.MongoClientOptions;
|
import java.util.Collections;
|
||||||
import com.mongodb.MongoCredential;
|
|
||||||
import com.mongodb.ServerAddress;
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.connections.mongo.api.MongoStore;
|
import org.keycloak.connections.mongo.api.MongoStore;
|
||||||
|
@ -13,11 +14,13 @@ import org.keycloak.connections.mongo.impl.context.TransactionMongoStoreInvocati
|
||||||
import org.keycloak.connections.mongo.updater.MongoUpdaterProvider;
|
import org.keycloak.connections.mongo.updater.MongoUpdaterProvider;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
import org.keycloak.provider.ProviderOperationalInfo;
|
||||||
|
|
||||||
import javax.net.ssl.SSLSocketFactory;
|
import com.mongodb.DB;
|
||||||
import java.lang.reflect.Method;
|
import com.mongodb.MongoClient;
|
||||||
import java.net.UnknownHostException;
|
import com.mongodb.MongoClientOptions;
|
||||||
import java.util.Collections;
|
import com.mongodb.MongoCredential;
|
||||||
|
import com.mongodb.ServerAddress;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -25,30 +28,13 @@ import java.util.Collections;
|
||||||
public class DefaultMongoConnectionFactoryProvider implements MongoConnectionProviderFactory {
|
public class DefaultMongoConnectionFactoryProvider implements MongoConnectionProviderFactory {
|
||||||
|
|
||||||
// TODO Make configurable
|
// TODO Make configurable
|
||||||
private String[] entities = new String[]{
|
private String[] entities = new String[] { "org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity", "org.keycloak.models.mongo.keycloak.entities.MongoUserEntity", "org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity",
|
||||||
"org.keycloak.models.mongo.keycloak.entities.MongoRealmEntity",
|
"org.keycloak.models.entities.IdentityProviderEntity", "org.keycloak.models.entities.ClientIdentityProviderMappingEntity", "org.keycloak.models.entities.RequiredCredentialEntity", "org.keycloak.models.entities.CredentialEntity",
|
||||||
"org.keycloak.models.mongo.keycloak.entities.MongoUserEntity",
|
"org.keycloak.models.entities.FederatedIdentityEntity", "org.keycloak.models.mongo.keycloak.entities.MongoClientEntity", "org.keycloak.models.sessions.mongo.entities.MongoUsernameLoginFailureEntity",
|
||||||
"org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity",
|
"org.keycloak.models.sessions.mongo.entities.MongoUserSessionEntity", "org.keycloak.models.sessions.mongo.entities.MongoClientSessionEntity", "org.keycloak.models.entities.UserFederationProviderEntity",
|
||||||
"org.keycloak.models.entities.IdentityProviderEntity",
|
"org.keycloak.models.entities.UserFederationMapperEntity", "org.keycloak.models.entities.ProtocolMapperEntity", "org.keycloak.models.entities.IdentityProviderMapperEntity",
|
||||||
"org.keycloak.models.entities.ClientIdentityProviderMappingEntity",
|
"org.keycloak.models.mongo.keycloak.entities.MongoUserConsentEntity", "org.keycloak.models.mongo.keycloak.entities.MongoMigrationModelEntity", "org.keycloak.models.entities.AuthenticationExecutionEntity",
|
||||||
"org.keycloak.models.entities.RequiredCredentialEntity",
|
"org.keycloak.models.entities.AuthenticationFlowEntity", "org.keycloak.models.entities.AuthenticatorConfigEntity", "org.keycloak.models.entities.RequiredActionProviderEntity", };
|
||||||
"org.keycloak.models.entities.CredentialEntity",
|
|
||||||
"org.keycloak.models.entities.FederatedIdentityEntity",
|
|
||||||
"org.keycloak.models.mongo.keycloak.entities.MongoClientEntity",
|
|
||||||
"org.keycloak.models.sessions.mongo.entities.MongoUsernameLoginFailureEntity",
|
|
||||||
"org.keycloak.models.sessions.mongo.entities.MongoUserSessionEntity",
|
|
||||||
"org.keycloak.models.sessions.mongo.entities.MongoClientSessionEntity",
|
|
||||||
"org.keycloak.models.entities.UserFederationProviderEntity",
|
|
||||||
"org.keycloak.models.entities.UserFederationMapperEntity",
|
|
||||||
"org.keycloak.models.entities.ProtocolMapperEntity",
|
|
||||||
"org.keycloak.models.entities.IdentityProviderMapperEntity",
|
|
||||||
"org.keycloak.models.mongo.keycloak.entities.MongoUserConsentEntity",
|
|
||||||
"org.keycloak.models.mongo.keycloak.entities.MongoMigrationModelEntity",
|
|
||||||
"org.keycloak.models.entities.AuthenticationExecutionEntity",
|
|
||||||
"org.keycloak.models.entities.AuthenticationFlowEntity",
|
|
||||||
"org.keycloak.models.entities.AuthenticatorConfigEntity",
|
|
||||||
"org.keycloak.models.entities.RequiredActionProviderEntity",
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(DefaultMongoConnectionFactoryProvider.class);
|
private static final Logger logger = Logger.getLogger(DefaultMongoConnectionFactoryProvider.class);
|
||||||
|
|
||||||
|
@ -58,6 +44,8 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
|
||||||
private DB db;
|
private DB db;
|
||||||
protected Config.Scope config;
|
protected Config.Scope config;
|
||||||
|
|
||||||
|
private MongoDbInfo mongoDbInfo;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MongoConnectionProvider create(KeycloakSession session) {
|
public MongoConnectionProvider create(KeycloakSession session) {
|
||||||
lazyInit(session);
|
lazyInit(session);
|
||||||
|
@ -77,7 +65,6 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void lazyInit(KeycloakSession session) {
|
private void lazyInit(KeycloakSession session) {
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
@ -133,8 +120,8 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override this method if you want more possibility to configure Mongo client. It can be also used to inject mongo client
|
* Override this method if you want more possibility to configure Mongo client. It can be also used to inject mongo
|
||||||
* from different source.
|
* client from different source.
|
||||||
*
|
*
|
||||||
* This method can assume that "config" is already set and can use it.
|
* This method can assume that "config" is already set and can use it.
|
||||||
*
|
*
|
||||||
|
@ -160,6 +147,12 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
|
||||||
client = new MongoClient(new ServerAddress(host, port), clientOptions);
|
client = new MongoClient(new ServerAddress(host, port), clientOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mongoDbInfo = new MongoDbInfo();
|
||||||
|
mongoDbInfo.driverVersion = client.getVersion();
|
||||||
|
mongoDbInfo.address = client.getAddress().toString();
|
||||||
|
mongoDbInfo.database = dbName;
|
||||||
|
mongoDbInfo.user = user;
|
||||||
|
|
||||||
logger.debugv("Initialized mongo model. host: %s, port: %d, db: %s", host, port, dbName);
|
logger.debugv("Initialized mongo model. host: %s, port: %d, db: %s", host, port, dbName);
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +169,7 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
|
||||||
if (config.getLong("maxAutoConnectRetryTime") != null) {
|
if (config.getLong("maxAutoConnectRetryTime") != null) {
|
||||||
builder.maxAutoConnectRetryTime(config.getLong("maxAutoConnectRetryTime"));
|
builder.maxAutoConnectRetryTime(config.getLong("maxAutoConnectRetryTime"));
|
||||||
}
|
}
|
||||||
if(config.getBoolean("ssl", false)) {
|
if (config.getBoolean("ssl", false)) {
|
||||||
builder.socketFactory(SSLSocketFactory.getDefault());
|
builder.socketFactory(SSLSocketFactory.getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,4 +200,39 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProviderOperationalInfo getOperationalInfo() {
|
||||||
|
return mongoDbInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MongoDbInfo implements ProviderOperationalInfo {
|
||||||
|
|
||||||
|
public String address;
|
||||||
|
public String database;
|
||||||
|
public String driverVersion;
|
||||||
|
public String user;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isOk() {
|
||||||
|
// TODO KEYCLOAK-1578 - implement operational monitoring of Mongo DB connection
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatabase() {
|
||||||
|
return database;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDriverVersion() {
|
||||||
|
return driverVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package org.keycloak.connections.mongo;
|
package org.keycloak.connections.mongo;
|
||||||
|
|
||||||
import org.keycloak.provider.ProviderFactory;
|
import org.keycloak.provider.MonitorableProviderFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
public interface MongoConnectionProviderFactory extends ProviderFactory<MongoConnectionProvider> {
|
public interface MongoConnectionProviderFactory extends MonitorableProviderFactory<MongoConnectionProvider> {
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<table class="table table-striped table-bordered">
|
<table class="table table-striped table-bordered">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Version</td>
|
<td width="20%">Keycloak Version</td>
|
||||||
<td>{{serverInfo.version}}</td>
|
<td>{{serverInfo.version}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -14,8 +14,34 @@
|
||||||
<td>Server Uptime</td>
|
<td>Server Uptime</td>
|
||||||
<td>{{serverInfo.serverUptime}}</td>
|
<td>{{serverInfo.serverUptime}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend>Java VM Memory Statistics</legend>
|
||||||
|
<div class="form-group">
|
||||||
|
<table class="table table-striped table-bordered" style="margin-top: 0px;">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Current Working Directory</td>
|
<td width="20%">Total Memory</td>
|
||||||
|
<td>{{serverInfo.memoryInfo.totalFormated}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Free Memory</td>
|
||||||
|
<td>{{serverInfo.memoryInfo.freeFormated}} ({{serverInfo.memoryInfo.freePercentage}}%)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Used Memory</td>
|
||||||
|
<td>{{serverInfo.memoryInfo.usedFormated}}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend collapsed>System Info</legend>
|
||||||
|
<div class="form-group">
|
||||||
|
<table class="table table-striped table-bordered" style="margin-top: 0px;">
|
||||||
|
<tr>
|
||||||
|
<td width="20%">Current Working Directory</td>
|
||||||
<td>{{serverInfo.systemInfo.userDir}}</td>
|
<td>{{serverInfo.systemInfo.userDir}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -67,22 +93,58 @@
|
||||||
<td>{{serverInfo.systemInfo.osArchitecture}}</td>
|
<td>{{serverInfo.systemInfo.osArchitecture}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
<h3>Java VM Memory Statistics</h3>
|
|
||||||
<table class="table table-striped table-bordered">
|
<fieldset ng-show="serverInfo.jpaInfo">
|
||||||
|
<legend collapsed>Database Info</legend>
|
||||||
|
<div class="form-group">
|
||||||
|
<table class="table table-striped table-bordered" style="margin-top: 0px;">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Total Memory</td>
|
<td width="20%">Database URL</td>
|
||||||
<td>{{serverInfo.memoryInfo.totalFormated}}</td>
|
<td>{{serverInfo.jpaInfo.jdbcUrl}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Free Memory</td>
|
<td>Database User</td>
|
||||||
<td>{{serverInfo.memoryInfo.freeFormated}} ({{serverInfo.memoryInfo.freePercentage}}%)</td>
|
<td>{{serverInfo.jpaInfo.databaseUser}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Used Memory</td>
|
<td>Database Type</td>
|
||||||
<td>{{serverInfo.memoryInfo.usedFormated}}</td>
|
<td>{{serverInfo.jpaInfo.databaseProduct}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Database Driver</td>
|
||||||
|
<td>{{serverInfo.jpaInfo.databaseDriver}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset ng-show="serverInfo.mongoDbInfo">
|
||||||
|
<legend collapsed>Mongo DB Info</legend>
|
||||||
|
<div class="form-group">
|
||||||
|
<table class="table table-striped table-bordered" style="margin-top: 0px;">
|
||||||
|
<tr width="20%">
|
||||||
|
<td>Address</td>
|
||||||
|
<td>{{serverInfo.mongoDbInfo.address}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Database</td>
|
||||||
|
<td>{{serverInfo.mongoDbInfo.database}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>User</td>
|
||||||
|
<td>{{serverInfo.mongoDbInfo.user}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Driver Version</td>
|
||||||
|
<td>{{serverInfo.mongoDbInfo.driverVersion}}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend collapsed>Providers</legend>
|
<legend collapsed>Providers</legend>
|
||||||
|
|
||||||
|
@ -93,7 +155,7 @@
|
||||||
<table class="table table-striped table-bordered">
|
<table class="table table-striped table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>SPI</th>
|
<th width="20%">SPI</th>
|
||||||
<th>Providers</th>
|
<th>Providers</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -117,7 +179,7 @@
|
||||||
<table class="table table-striped table-bordered">
|
<table class="table table-striped table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>SPI</th>
|
<th width="20%">SPI</th>
|
||||||
<th>Providers</th>
|
<th>Providers</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package org.keycloak.provider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provider factory for provider which is monitorable. It means some info about it can be shown on "Server Info" page or accessed over Operational monitoring endpoint.
|
||||||
|
*
|
||||||
|
* @author Vlastimil Elias (velias at redhat dot com)
|
||||||
|
*/
|
||||||
|
public interface MonitorableProviderFactory<T extends Provider> extends ProviderFactory<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get operational info about given provider. This info contains informations about providers configuration and operational conditions (eg. errors in connection to remote systems etc).
|
||||||
|
* Is used to be shown on "Server Info" page or in Operational monitoring endpoint.
|
||||||
|
*
|
||||||
|
* @return extendion of {@link ProviderOperationalInfo}
|
||||||
|
*/
|
||||||
|
public ProviderOperationalInfo getOperationalInfo();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package org.keycloak.provider;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operational info about given Provider.
|
||||||
|
* Contains info about Provider that can be shown on "Server Info" page or accessed over Operational monitoring endpoint.
|
||||||
|
*
|
||||||
|
* @author Vlastimil Elias (velias at redhat dot com)
|
||||||
|
* @see MonitorableProviderFactory
|
||||||
|
*/
|
||||||
|
public interface ProviderOperationalInfo extends Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if provider is OK from operation point of view. It means it is able to perform necessary work.
|
||||||
|
* It can return false for example if remote DB of JPA provider is not available, or LDAP server of LDAP based user federation provider is not available.
|
||||||
|
*
|
||||||
|
* @return true if provider is OK to perform his operation.
|
||||||
|
*/
|
||||||
|
boolean isOk();
|
||||||
|
|
||||||
|
}
|
|
@ -39,6 +39,21 @@
|
||||||
<artifactId>keycloak-connections-http-client</artifactId>
|
<artifactId>keycloak-connections-http-client</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-connections-jpa</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-entitymanager</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.keycloak</groupId>
|
||||||
|
<artifactId>keycloak-connections-mongo</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-forms-common-freemarker</artifactId>
|
<artifactId>keycloak-forms-common-freemarker</artifactId>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.keycloak.services.resources.admin;
|
package org.keycloak.services.resources.admin;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -13,9 +14,13 @@ import java.util.Set;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.Version;
|
import org.keycloak.Version;
|
||||||
import org.keycloak.broker.provider.IdentityProvider;
|
import org.keycloak.broker.provider.IdentityProvider;
|
||||||
import org.keycloak.broker.provider.IdentityProviderFactory;
|
import org.keycloak.broker.provider.IdentityProviderFactory;
|
||||||
|
import org.keycloak.connections.jpa.JpaConnectionProvider;
|
||||||
|
import org.keycloak.connections.mongo.DefaultMongoConnectionFactoryProvider.MongoDbInfo;
|
||||||
|
import org.keycloak.connections.mongo.MongoConnectionProvider;
|
||||||
import org.keycloak.events.EventListenerProvider;
|
import org.keycloak.events.EventListenerProvider;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.events.admin.OperationType;
|
import org.keycloak.events.admin.OperationType;
|
||||||
|
@ -29,8 +34,10 @@ import org.keycloak.models.utils.ModelToRepresentation;
|
||||||
import org.keycloak.protocol.LoginProtocol;
|
import org.keycloak.protocol.LoginProtocol;
|
||||||
import org.keycloak.protocol.LoginProtocolFactory;
|
import org.keycloak.protocol.LoginProtocolFactory;
|
||||||
import org.keycloak.protocol.ProtocolMapper;
|
import org.keycloak.protocol.ProtocolMapper;
|
||||||
|
import org.keycloak.provider.MonitorableProviderFactory;
|
||||||
import org.keycloak.provider.ProviderConfigProperty;
|
import org.keycloak.provider.ProviderConfigProperty;
|
||||||
import org.keycloak.provider.ProviderFactory;
|
import org.keycloak.provider.ProviderFactory;
|
||||||
|
import org.keycloak.provider.ProviderOperationalInfo;
|
||||||
import org.keycloak.provider.Spi;
|
import org.keycloak.provider.Spi;
|
||||||
import org.keycloak.representations.idm.ConfigPropertyRepresentation;
|
import org.keycloak.representations.idm.ConfigPropertyRepresentation;
|
||||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||||
|
@ -42,6 +49,8 @@ import org.keycloak.social.SocialIdentityProvider;
|
||||||
*/
|
*/
|
||||||
public class ServerInfoAdminResource {
|
public class ServerInfoAdminResource {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(ServerInfoAdminResource.class);
|
||||||
|
|
||||||
private static final Map<String, List<String>> ENUMS = createEnumsMap(EventType.class, OperationType.class);
|
private static final Map<String, List<String>> ENUMS = createEnumsMap(EventType.class, OperationType.class);
|
||||||
|
|
||||||
@Context
|
@Context
|
||||||
|
@ -58,6 +67,8 @@ public class ServerInfoAdminResource {
|
||||||
info.version = Version.VERSION;
|
info.version = Version.VERSION;
|
||||||
info.serverTime = new Date().toString();
|
info.serverTime = new Date().toString();
|
||||||
info.serverStartupTime = session.getKeycloakSessionFactory().getServerStartupTimestamp();
|
info.serverStartupTime = session.getKeycloakSessionFactory().getServerStartupTimestamp();
|
||||||
|
info.memoryInfo = (new MemoryInfo()).init(Runtime.getRuntime());
|
||||||
|
info.systemInfo = (new SystemInfo()).init();
|
||||||
setSocialProviders(info);
|
setSocialProviders(info);
|
||||||
setIdentityProviders(info);
|
setIdentityProviders(info);
|
||||||
setThemes(info);
|
setThemes(info);
|
||||||
|
@ -68,6 +79,21 @@ public class ServerInfoAdminResource {
|
||||||
setProtocolMapperTypes(info);
|
setProtocolMapperTypes(info);
|
||||||
setBuiltinProtocolMappers(info);
|
setBuiltinProtocolMappers(info);
|
||||||
info.setEnums(ENUMS);
|
info.setEnums(ENUMS);
|
||||||
|
|
||||||
|
ProviderFactory<JpaConnectionProvider> jpf = session.getKeycloakSessionFactory().getProviderFactory(JpaConnectionProvider.class);
|
||||||
|
if(jpf!=null && jpf instanceof MonitorableProviderFactory){
|
||||||
|
info.jpaInfo = ((MonitorableProviderFactory<?>)jpf).getOperationalInfo();
|
||||||
|
} else {
|
||||||
|
logger.debug("JPA provider not found or is not monitorable");
|
||||||
|
}
|
||||||
|
|
||||||
|
ProviderFactory<MongoConnectionProvider> mpf = session.getKeycloakSessionFactory().getProviderFactory(MongoConnectionProvider.class);
|
||||||
|
if(mpf!=null && mpf instanceof MonitorableProviderFactory){
|
||||||
|
info.mongoDbInfo = ((MonitorableProviderFactory<?>)mpf).getOperationalInfo();
|
||||||
|
} else {
|
||||||
|
logger.debug("Mongo provider not found or is not monitorable");
|
||||||
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,10 +217,28 @@ public class ServerInfoAdminResource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MemoryInfo{
|
public static class MemoryInfo implements Serializable {
|
||||||
|
|
||||||
|
protected long total;
|
||||||
|
|
||||||
|
protected long used;
|
||||||
|
|
||||||
|
public MemoryInfo(){
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill object fwith info.
|
||||||
|
* @param runtime used to get memory info from.
|
||||||
|
* @return itself for chaining
|
||||||
|
*/
|
||||||
|
public MemoryInfo init(Runtime runtime){
|
||||||
|
total = runtime.maxMemory();
|
||||||
|
used = runtime.totalMemory() - runtime.freeMemory();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public long getTotal(){
|
public long getTotal(){
|
||||||
return Runtime.getRuntime().maxMemory();
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTotalFormated(){
|
public String getTotalFormated(){
|
||||||
|
@ -210,7 +254,7 @@ public class ServerInfoAdminResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getUsed(){
|
public long getUsed(){
|
||||||
return Runtime.getRuntime().totalMemory();
|
return used;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsedFormated(){
|
public String getUsedFormated(){
|
||||||
|
@ -218,7 +262,7 @@ public class ServerInfoAdminResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getFreePercentage(){
|
public long getFreePercentage(){
|
||||||
return getFree()*100/getTotal();
|
return getFree() * 100 / getTotal();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatMemory(long bytes){
|
private String formatMemory(long bytes){
|
||||||
|
@ -233,71 +277,109 @@ public class ServerInfoAdminResource {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SystemInfo {
|
public static class SystemInfo implements Serializable {
|
||||||
|
|
||||||
|
protected String javaVersion;
|
||||||
|
protected String javaVendor;
|
||||||
|
protected String javaVm;
|
||||||
|
protected String javaVmVersion;
|
||||||
|
protected String javaRuntime;
|
||||||
|
protected String javaHome;
|
||||||
|
protected String osName;
|
||||||
|
protected String osArchitecture;
|
||||||
|
protected String osVersion;
|
||||||
|
protected String fileEncoding;
|
||||||
|
protected String userName;
|
||||||
|
protected String userDir;
|
||||||
|
protected String userTimezone;
|
||||||
|
protected String userLocale;
|
||||||
|
|
||||||
|
public SystemInfo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill object with info about current system loaded from {@link System} properties.
|
||||||
|
* @return object itself for chaining
|
||||||
|
*/
|
||||||
|
protected SystemInfo init(){
|
||||||
|
javaVersion = System.getProperty("java.version");
|
||||||
|
javaVendor = System.getProperty("java.vendor");
|
||||||
|
javaVm = System.getProperty("java.vm.name");
|
||||||
|
javaVmVersion = System.getProperty("java.vm.version");
|
||||||
|
javaRuntime = System.getProperty("java.runtime.name");
|
||||||
|
javaHome = System.getProperty("java.home");
|
||||||
|
osName = System.getProperty("os.name");
|
||||||
|
osArchitecture = System.getProperty("os.arch");
|
||||||
|
osVersion = System.getProperty("os.version");
|
||||||
|
fileEncoding = System.getProperty("file.encoding");
|
||||||
|
userName = System.getProperty("user.name");
|
||||||
|
userDir = System.getProperty("user.dir");
|
||||||
|
userTimezone = System.getProperty("user.timezone");
|
||||||
|
userLocale = (new Locale(System.getProperty("user.country"),System.getProperty("user.language")).toString());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public String getJavaVersion(){
|
public String getJavaVersion(){
|
||||||
return System.getProperty("java.version");
|
return javaVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getJavaVendor(){
|
public String getJavaVendor(){
|
||||||
return System.getProperty("java.vendor");
|
return javaVendor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getJavaVm(){
|
public String getJavaVm(){
|
||||||
return System.getProperty("java.vm.name");
|
return javaVm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getJavaVmVersion(){
|
public String getJavaVmVersion(){
|
||||||
return System.getProperty("java.vm.version");
|
return javaVmVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getJavaRuntime(){
|
public String getJavaRuntime(){
|
||||||
return System.getProperty("java.runtime.name");
|
return javaRuntime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getJavaHome(){
|
public String getJavaHome(){
|
||||||
return System.getProperty("java.home");
|
return javaHome;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOsName(){
|
public String getOsName(){
|
||||||
return System.getProperty("os.name");
|
return osName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOsArchitecture(){
|
public String getOsArchitecture(){
|
||||||
return System.getProperty("os.arch");
|
return osArchitecture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOsVersion(){
|
public String getOsVersion(){
|
||||||
return System.getProperty("os.version");
|
return osVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFileEncoding(){
|
public String getFileEncoding(){
|
||||||
return System.getProperty("file.encoding");
|
return fileEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUserName(){
|
public String getUserName(){
|
||||||
return System.getProperty("user.name");
|
return userName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUserDir(){
|
public String getUserDir(){
|
||||||
return System.getProperty("user.dir");
|
return userDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUserTimezone(){
|
public String getUserTimezone(){
|
||||||
return System.getProperty("user.timezone");
|
return userTimezone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUserLocale(){
|
public String getUserLocale(){
|
||||||
return (new Locale(System.getProperty("user.country"),System.getProperty("user.language")).toString());
|
return userLocale;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
public static class ServerInfoRepresentation implements Serializable {
|
||||||
|
|
||||||
public static class ServerInfoRepresentation {
|
|
||||||
|
|
||||||
private String version;
|
private String version;
|
||||||
|
|
||||||
private String serverTime;
|
private String serverTime;
|
||||||
|
|
||||||
private long serverStartupTime;
|
private long serverStartupTime;
|
||||||
|
|
||||||
private Map<String, List<String>> themes;
|
private Map<String, List<String>> themes;
|
||||||
|
@ -315,25 +397,43 @@ public class ServerInfoAdminResource {
|
||||||
|
|
||||||
private Map<String, List<String>> enums;
|
private Map<String, List<String>> enums;
|
||||||
|
|
||||||
|
private MemoryInfo memoryInfo;
|
||||||
|
private SystemInfo systemInfo;
|
||||||
|
|
||||||
|
private ProviderOperationalInfo jpaInfo;
|
||||||
|
private ProviderOperationalInfo mongoDbInfo;
|
||||||
|
|
||||||
public ServerInfoRepresentation() {
|
public ServerInfoRepresentation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SystemInfo getSystemInfo(){
|
public SystemInfo getSystemInfo(){
|
||||||
return new SystemInfo();
|
return systemInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemoryInfo getMemoryInfo(){
|
public MemoryInfo getMemoryInfo(){
|
||||||
return new MemoryInfo();
|
return memoryInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProviderOperationalInfo getJpaInfo() {
|
||||||
|
return jpaInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProviderOperationalInfo getMongoDbInfo() {
|
||||||
|
return mongoDbInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getServerTime() {
|
public String getServerTime() {
|
||||||
return serverTime;
|
return serverTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getServerStartupTime() {
|
||||||
|
return serverStartupTime;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return server startup time formatted
|
* @return server startup time formatted
|
||||||
*/
|
*/
|
||||||
public String getServerStartupTime() {
|
public String getServerStartupTimeFormatted() {
|
||||||
return (new Date(serverStartupTime)).toString();
|
return (new Date(serverStartupTime)).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +520,7 @@ public class ServerInfoAdminResource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SpiInfoRepresentation {
|
public static class SpiInfoRepresentation implements Serializable {
|
||||||
private String name;
|
private String name;
|
||||||
private boolean internal;
|
private boolean internal;
|
||||||
private Set<String> implementations;
|
private Set<String> implementations;
|
||||||
|
|
|
@ -21,10 +21,27 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.testsuite.admin;
|
package org.keycloak.testsuite.admin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.ws.rs.client.Client;
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
import javax.ws.rs.client.ClientRequestContext;
|
||||||
|
import javax.ws.rs.client.ClientRequestFilter;
|
||||||
|
import javax.ws.rs.client.Entity;
|
||||||
|
import javax.ws.rs.client.WebTarget;
|
||||||
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.UriBuilder;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
|
import org.keycloak.Version;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.ClientSessionModel;
|
import org.keycloak.models.ClientSessionModel;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
|
@ -40,22 +57,8 @@ import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.resources.admin.AdminRoot;
|
import org.keycloak.services.resources.admin.AdminRoot;
|
||||||
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
|
|
||||||
import org.keycloak.testsuite.KeycloakServer;
|
import org.keycloak.testsuite.KeycloakServer;
|
||||||
|
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
|
||||||
import javax.ws.rs.client.Client;
|
|
||||||
import javax.ws.rs.client.ClientBuilder;
|
|
||||||
import javax.ws.rs.client.ClientRequestContext;
|
|
||||||
import javax.ws.rs.client.ClientRequestFilter;
|
|
||||||
import javax.ws.rs.client.Entity;
|
|
||||||
import javax.ws.rs.client.WebTarget;
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import javax.ws.rs.core.UriBuilder;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests Undertow Adapter
|
* Tests Undertow Adapter
|
||||||
|
@ -295,4 +298,34 @@ public class AdminAPITest {
|
||||||
testCreateRealm("/admin-test/testrealm.json");
|
testCreateRealm("/admin-test/testrealm.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testServerInfo() {
|
||||||
|
|
||||||
|
String token = createToken();
|
||||||
|
final String authHeader = "Bearer " + token;
|
||||||
|
ClientRequestFilter authFilter = new ClientRequestFilter() {
|
||||||
|
@Override
|
||||||
|
public void filter(ClientRequestContext requestContext) throws IOException {
|
||||||
|
requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Client client = ClientBuilder.newBuilder().register(authFilter).build();
|
||||||
|
UriBuilder authBase = UriBuilder.fromUri("http://localhost:8081/auth");
|
||||||
|
WebTarget target = client.target(AdminRoot.adminBaseUrl(authBase).path("serverinfo"));
|
||||||
|
|
||||||
|
Map<?, ?> response = target.request().accept("application/json").get(Map.class);
|
||||||
|
|
||||||
|
Assert.assertNotNull(response);
|
||||||
|
Assert.assertEquals(Version.VERSION, response.get("version"));
|
||||||
|
Assert.assertNotNull(response.get("serverTime"));
|
||||||
|
Assert.assertNotNull(response.get("serverStartupTime"));
|
||||||
|
|
||||||
|
Assert.assertNotNull(response.get("memoryInfo"));
|
||||||
|
Assert.assertNotNull(response.get("jpaInfo"));
|
||||||
|
Assert.assertNull(response.get("mongoDbInfo"));
|
||||||
|
|
||||||
|
System.out.println(response);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue