Merge pull request #1331 from stianst/master
KEYCLOAK-1325 Public/private SPI
This commit is contained in:
commit
d875b9885d
38 changed files with 111 additions and 85 deletions
|
@ -10,8 +10,8 @@ import org.keycloak.provider.Spi;
|
||||||
public class IdentityProviderMapperSpi implements Spi {
|
public class IdentityProviderMapperSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class IdentityProviderSpi implements Spi {
|
||||||
public static final String IDENTITY_PROVIDER_SPI_NAME = "identity_provider";
|
public static final String IDENTITY_PROVIDER_SPI_NAME = "identity_provider";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class FileConnectionSpi implements Spi {
|
public class FileConnectionSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class HttpClientSpi implements Spi {
|
public class HttpClientSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class InfinispanConnectionSpi implements Spi {
|
public class InfinispanConnectionSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class JpaConnectionSpi implements Spi {
|
public class JpaConnectionSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class JpaUpdaterSpi implements Spi {
|
public class JpaUpdaterSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class MongoConnectionSpi implements Spi {
|
public class MongoConnectionSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class MongoUpdaterSpi implements Spi {
|
public class MongoUpdaterSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class EventListenerSpi implements Spi {
|
public class EventListenerSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class EventStoreSpi implements Spi {
|
public class EventStoreSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class ExportSpi implements Spi {
|
public class ExportSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class ImportSpi implements Spi {
|
public class ImportSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class AccountSpi implements Spi {
|
public class AccountSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class ThemeSpi implements Spi {
|
public class ThemeSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,11 @@
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend collapsed>Providers</legend>
|
<legend collapsed>Providers</legend>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
<h3>Public SPIs</h3>
|
||||||
|
<kc-tooltip>For public SPIs there are built-in providers, but it's also supported to write your own custom providers.</kc-tooltip>
|
||||||
|
|
||||||
<table class="table table-striped table-bordered">
|
<table class="table table-striped table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -23,10 +27,34 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr data-ng-repeat="(spi, providers) in serverInfo.providers">
|
<tr data-ng-repeat="spi in (serverInfo.providers | filter:{internal:false} | orderBy:'name')">
|
||||||
<td>{{spi}}</td>
|
<td>{{spi.name}}</td>
|
||||||
<td>
|
<td>
|
||||||
<div data-ng-repeat="provider in providers">
|
<div data-ng-repeat="provider in (spi.implementations | orderBy:'toString()')">
|
||||||
|
{{provider}}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<h3>Internal SPIs</h3>
|
||||||
|
<kc-tooltip>For internal SPIs there are only built-in providers. It's not recommended to write your own custom providers as internal SPIs may change or be removed without notice.</kc-tooltip>
|
||||||
|
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>SPI</th>
|
||||||
|
<th>Providers</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr data-ng-repeat="spi in (serverInfo.providers | filter:{internal:true} | orderBy:'name')">
|
||||||
|
<td>{{spi.name}}</td>
|
||||||
|
<td>
|
||||||
|
<div data-ng-repeat="provider in (spi.implementations | orderBy:'toString()')">
|
||||||
{{provider}}
|
{{provider}}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class EmailSpi implements Spi {
|
public class EmailSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class LoginFormsSpi implements Spi {
|
public class LoginFormsSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class UserFederationMapperSpi implements Spi {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class MigrationSpi implements Spi {
|
public class MigrationSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class RealmSpi implements Spi {
|
public class RealmSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class UserFederationSpi implements Spi {
|
public class UserFederationSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ public class UserSessionSpi implements Spi {
|
||||||
public static final String NAME = "userSessions";
|
public static final String NAME = "userSessions";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class UserSpi implements Spi {
|
public class UserSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@ package org.keycloak.provider;
|
||||||
*/
|
*/
|
||||||
public interface Spi {
|
public interface Spi {
|
||||||
|
|
||||||
public boolean isPrivate();
|
boolean isInternal();
|
||||||
public String getName();
|
String getName();
|
||||||
public Class<? extends Provider> getProviderClass();
|
Class<? extends Provider> getProviderClass();
|
||||||
public Class<? extends ProviderFactory> getProviderFactoryClass();
|
Class<? extends ProviderFactory> getProviderFactoryClass();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class CacheRealmProviderSpi implements Spi {
|
public class CacheRealmProviderSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class CacheUserProviderSpi implements Spi {
|
public class CacheUserProviderSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class AuthenticatorSpi implements Spi {
|
public class AuthenticatorSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class ClientImportSpi implements Spi {
|
public class ClientImportSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class MessagesSpi implements Spi {
|
public class MessagesSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class LoginProtocolSpi implements Spi {
|
public class LoginProtocolSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ import org.keycloak.provider.Spi;
|
||||||
public class ProtocolMapperSpi implements Spi {
|
public class ProtocolMapperSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,8 +4,6 @@ import org.jboss.logging.Logger;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.RealmProvider;
|
|
||||||
import org.keycloak.provider.Provider;
|
import org.keycloak.provider.Provider;
|
||||||
import org.keycloak.provider.ProviderEvent;
|
import org.keycloak.provider.ProviderEvent;
|
||||||
import org.keycloak.provider.ProviderEventListener;
|
import org.keycloak.provider.ProviderEventListener;
|
||||||
|
@ -66,7 +64,7 @@ public class DefaultKeycloakSessionFactory implements KeycloakSessionFactory {
|
||||||
Config.Scope scope = Config.scope(spi.getName(), provider);
|
Config.Scope scope = Config.scope(spi.getName(), provider);
|
||||||
factory.init(scope);
|
factory.init(scope);
|
||||||
|
|
||||||
if (spi.isPrivate() && !isInternal(factory)) {
|
if (spi.isInternal() && !isInternal(factory)) {
|
||||||
log.warnv("{0} ({1}) is implementing the internal SPI {2}. This SPI is internal and may change without notice", factory.getId(), factory.getClass().getName(), spi.getName());
|
log.warnv("{0} ({1}) is implementing the internal SPI {2}. This SPI is internal and may change without notice", factory.getId(), factory.getClass().getName(), spi.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +76,7 @@ public class DefaultKeycloakSessionFactory implements KeycloakSessionFactory {
|
||||||
Config.Scope scope = Config.scope(spi.getName(), factory.getId());
|
Config.Scope scope = Config.scope(spi.getName(), factory.getId());
|
||||||
factory.init(scope);
|
factory.init(scope);
|
||||||
|
|
||||||
if (spi.isPrivate() && !isInternal(factory)) {
|
if (spi.isInternal() && !isInternal(factory)) {
|
||||||
log.warnv("{0} ({1}) is implementing the internal SPI {2}. This SPI is internal and may change without notice", factory.getId(), factory.getClass().getName(), spi.getName());
|
log.warnv("{0} ({1}) is implementing the internal SPI {2}. This SPI is internal and may change without notice", factory.getId(), factory.getClass().getName(), spi.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,9 +69,13 @@ public class ServerInfoAdminResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setProviders(ServerInfoRepresentation info) {
|
private void setProviders(ServerInfoRepresentation info) {
|
||||||
Map<String, Set<String>> providers = new HashMap<String, Set<String>>();
|
List<SpiInfoRepresentation> providers = new LinkedList<>();
|
||||||
for (Spi spi : ServiceLoader.load(Spi.class)) {
|
for (Spi spi : ServiceLoader.load(Spi.class)) {
|
||||||
providers.put(spi.getName(), session.listProviderIds(spi.getProviderClass()));
|
SpiInfoRepresentation spiRep = new SpiInfoRepresentation();
|
||||||
|
spiRep.setName(spi.getName());
|
||||||
|
spiRep.setInternal(spi.isInternal());
|
||||||
|
spiRep.setImplementations(session.listProviderIds(spi.getProviderClass()));
|
||||||
|
providers.add(spiRep);
|
||||||
}
|
}
|
||||||
info.providers = providers;
|
info.providers = providers;
|
||||||
}
|
}
|
||||||
|
@ -197,7 +201,7 @@ public class ServerInfoAdminResource {
|
||||||
private List<String> protocols;
|
private List<String> protocols;
|
||||||
private List<Map<String, String>> clientImporters;
|
private List<Map<String, String>> clientImporters;
|
||||||
|
|
||||||
private Map<String, Set<String>> providers;
|
private List<SpiInfoRepresentation> providers;
|
||||||
|
|
||||||
private List<String> eventListeners;
|
private List<String> eventListeners;
|
||||||
private Map<String, List<ProtocolMapperTypeRepresentation>> protocolMapperTypes;
|
private Map<String, List<ProtocolMapperTypeRepresentation>> protocolMapperTypes;
|
||||||
|
@ -240,7 +244,7 @@ public class ServerInfoAdminResource {
|
||||||
return clientImporters;
|
return clientImporters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Set<String>> getProviders() {
|
public List<SpiInfoRepresentation> getProviders() {
|
||||||
return providers;
|
return providers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,6 +269,36 @@ public class ServerInfoAdminResource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class SpiInfoRepresentation {
|
||||||
|
private String name;
|
||||||
|
private boolean internal;
|
||||||
|
private Set<String> implementations;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInternal() {
|
||||||
|
return internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInternal(boolean internal) {
|
||||||
|
this.internal = internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getImplementations() {
|
||||||
|
return implementations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImplementations(Set<String> implementations) {
|
||||||
|
this.implementations = implementations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Map<String, List<String>> createEnumsMap(Class... enums) {
|
private static Map<String, List<String>> createEnumsMap(Class... enums) {
|
||||||
Map<String, List<String>> m = new HashMap<>();
|
Map<String, List<String>> m = new HashMap<>();
|
||||||
for (Class e : enums) {
|
for (Class e : enums) {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class WellKnownSpi implements Spi {
|
public class WellKnownSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class SocialProviderSpi implements Spi {
|
||||||
public static final String SOCIAL_SPI_NAME = "social";
|
public static final String SOCIAL_SPI_NAME = "social";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
package org.keycloak.testsuite.utils;
|
|
||||||
|
|
||||||
import org.keycloak.provider.Spi;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ServiceLoader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
|
||||||
*/
|
|
||||||
public class ListSpi {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
List<String> l = new LinkedList<>();
|
|
||||||
for (Spi s : ServiceLoader.load(Spi.class)) {
|
|
||||||
l.add(fixedLength(s.getName()) + s.isPrivate());
|
|
||||||
}
|
|
||||||
Collections.sort(l);
|
|
||||||
System.out.println(fixedLength("SPI") + "Private");
|
|
||||||
System.out.println("-------------------------------------");
|
|
||||||
for (String s : l) {
|
|
||||||
System.out.println(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String fixedLength(String s) {
|
|
||||||
while (s.length() < 30) {
|
|
||||||
s = s + " ";
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,7 +10,7 @@ import org.keycloak.provider.Spi;
|
||||||
public class TimerSpi implements Spi {
|
public class TimerSpi implements Spi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPrivate() {
|
public boolean isInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue