Merge pull request #1331 from stianst/master

KEYCLOAK-1325 Public/private SPI
This commit is contained in:
Stian Thorgersen 2015-06-04 15:26:46 +01:00
commit d875b9885d
38 changed files with 111 additions and 85 deletions

View file

@ -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

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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>

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -25,7 +25,7 @@ public class UserFederationMapperSpi implements Spi {
} }
@Override @Override
public boolean isPrivate() { public boolean isInternal() {
return false; return true;
} }
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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();
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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

View file

@ -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());
} }

View file

@ -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) {

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
}
}

View file

@ -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;
} }