diff --git a/grouper-misc/grouper-authentication/README.md b/grouper-misc/grouper-authentication/README.md new file mode 100644 index 000000000000..2d23317f6d0d --- /dev/null +++ b/grouper-misc/grouper-authentication/README.md @@ -0,0 +1,5 @@ +Grouper External Authentication Plugin +====================================== + +## Introduction +The external authentication plugin allows for authentication from an external source. \ No newline at end of file diff --git a/grouper-misc/grouper-authentication/conf/grouper.external.authentication.example.properties b/grouper-misc/grouper-authentication/conf/grouper.external.authentication.example.properties index 7f6a4bdbaacf..5403f631cfcd 100644 --- a/grouper-misc/grouper-authentication/conf/grouper.external.authentication.example.properties +++ b/grouper-misc/grouper-authentication/conf/grouper.external.authentication.example.properties @@ -1,7 +1,7 @@ # these are properties to configure PAC4J with CAS # Enable External Authentication -external.authentication.enabled = true +# see: grouper.base.properties for plugin configuration description within grouper # External Authentication Mechanism (cas,saml,oidc) external.authentication.auth.mechanism = cas diff --git a/grouper-misc/grouper-authentication/plugin-pom.xml b/grouper-misc/grouper-authentication/plugin-pom.xml new file mode 100644 index 000000000000..eb0619075482 --- /dev/null +++ b/grouper-misc/grouper-authentication/plugin-pom.xml @@ -0,0 +1,171 @@ + + + + + + 4.0.0 + + + edu.internet2.middleware.grouper + grouper-parent + 2.6.0-SNAPSHOT + ../../grouper-parent + + + Grouper Authentication Plugin + Authentication Library Plugin + grouper-authentication-plugin + 0.0.1-SNAPSHOT + bundle + + + 4.3.1 + 5.0.0 + 2.6.0-SNAPSHOT + + + + + ${project.groupId} + grouperClient + ${grouper.version} + provided + + + edu.internet2.middleware.grouper + grouper + ${grouper.version} + provided + + + edu.internet2.middleware.grouper + grouper-ui + ${grouper.version} + test + + + org.apache.commons + commons-lang3 + + + org.pac4j + pac4j-core + ${pac4j.version} + + + org.pac4j + pac4j-cas + ${pac4j.version} + + + org.pac4j + jee-pac4j + ${jee-pac4j.version} + + + org.pac4j + pac4j-saml-opensamlv3 + ${pac4j.version} + + + org.slf4j + jcl-over-slf4j + + + org.springframework + spring-jcl + + + + + org.pac4j + pac4j-oidc + ${pac4j.version} + + + org.apache.tomcat + tomcat-catalina + 8.5.60 + provided + + + commons-logging + commons-logging + provided + + + ${project.groupId} + grouper + ${grouper.version} + test-jar + test + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + true + + ${project.name} + ${project.organization.name} + ${project.artifactId} + ${project.version} + ${project.url} + ${maven.build.timestamp} + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.groupId}.${project.artifactId} + ${project.artifactId}-bundle + ${project.version} + edu.internet2.middleware.grouper.authentication.plugin.GrouperAuthentication + edu.internet2.middleware.grouper.authentication.plugin.filter + edu.internet2.middleware.grouper.authentication.plugin.* + *;scope=compile|runtime + true + + *;resolution:=optional + + + + + + + + diff --git a/grouper-misc/grouper-authentication/pom.xml b/grouper-misc/grouper-authentication/pom.xml index 2f1620677552..e26ba589982e 100644 --- a/grouper-misc/grouper-authentication/pom.xml +++ b/grouper-misc/grouper-authentication/pom.xml @@ -16,6 +16,10 @@ limitations under the License. --> + @@ -24,18 +28,20 @@ edu.internet2.middleware.grouper grouper-parent - 2.5.0-SNAPSHOT + 2.6.0-SNAPSHOT ../../grouper-parent Grouper Authentication Authentication Library grouper-authentication + 0.0.1-SNAPSHOT jar 4.3.1 5.0.0 + 2.6.0-SNAPSHOT @@ -43,8 +49,7 @@ ${project.groupId} grouper-ui - ${project.version} - provided + ${grouper.version} org.pac4j @@ -75,17 +80,15 @@ org.apache.tomcat tomcat-catalina 8.5.60 - provided commons-logging commons-logging - provided ${project.groupId} grouper - ${project.version} + ${grouper.version} test-jar test @@ -105,12 +108,17 @@ ${project.artifactId} ${project.version} ${project.url} - edu.internet2.middleware.grouperBox.GrouperBoxSync ${maven.build.timestamp} + + + + + \ No newline at end of file diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/Pac4jServletContainerInitializer.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/Pac4jServletContainerInitializer.java deleted file mode 100644 index 32568444b895..000000000000 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/Pac4jServletContainerInitializer.java +++ /dev/null @@ -1,58 +0,0 @@ -package edu.internet2.middleware.grouper.authentication; - -import edu.internet2.middleware.grouper.authentication.filter.CallbackFilterFacade; -import edu.internet2.middleware.grouper.authentication.filter.SecurityFilterFacade; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.*; -import java.util.Map; -import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; -import java.util.regex.Pattern; - -public class Pac4jServletContainerInitializer implements ServletContainerInitializer { - private static final Logger LOGGER = LoggerFactory.getLogger(Pac4jServletContainerInitializer.class); - private Timer timer = new Timer(); - private Map config; - - @Override - public void onStartup(Set> c, ServletContext ctx) throws ServletException { - LOGGER.info("initializing pac4j"); - - CallbackFilterFacade callbackFilterFacade = new CallbackFilterFacade(); - FilterRegistration.Dynamic callbackFilter = ctx.addFilter("callbackFilter", callbackFilterFacade); - callbackFilter.addMappingForUrlPatterns(null, false, "/*"); - - SecurityFilterFacade securityFilterFacade = new SecurityFilterFacade(); - FilterRegistration.Dynamic securityFilter = ctx.addFilter("securityFilter", SecurityFilterFacade.class); - securityFilter.addMappingForUrlPatterns(null, false, "/*"); - - this.config = ConfigUtils.getBestGrouperConfiguration().propertiesMap(Pattern.compile("^external\\.authentication\\.([^.]+)$")); - - TimerTask timerTask = new TimerTask() { - @Override - public void run() { - Map curConfig = ConfigUtils.getBestGrouperConfiguration().propertiesMap(Pattern.compile("^external\\.authentication\\.([^.]+)$")); - if (!areEqual(config, curConfig)) { - config = curConfig; - callbackFilterFacade.initDelegate(); - securityFilterFacade.initDelegate(); - LOGGER.info("Pac4j External Authentication configuration reloaded"); - } - } - }; - - int period = ConfigUtils.getBestGrouperConfiguration().propertyValueInt("external.authentication.config.reload.milliseconds", 60 * 1000); - this.timer.schedule(timerTask, period, period); - } - - private boolean areEqual(Map first, Map second) { - if (first.size() != second.size()) { - return false; - } - return first.entrySet().stream() - .allMatch(e -> e.getValue().equals(second.get(e.getKey()))); - } -} diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/filter/CallbackFilterFacade.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/filter/CallbackFilterFacade.java deleted file mode 100644 index b0dac7ff77bf..000000000000 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/filter/CallbackFilterFacade.java +++ /dev/null @@ -1,50 +0,0 @@ -package edu.internet2.middleware.grouper.authentication.filter; - -import edu.internet2.middleware.grouper.authentication.ConfigUtils; -import edu.internet2.middleware.grouper.cfg.GrouperHibernateConfig; -import org.pac4j.jee.filter.CallbackFilter; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import java.io.IOException; - -public class CallbackFilterFacade implements Filter { - private CallbackFilter uiDelegate; - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - this.uiDelegate = new CallbackFilter(); - this.uiDelegate.init(filterConfig); - this.initDelegate(); - } - - public void initDelegate() { - this.uiDelegate.setDefaultUrl(ConfigUtils.getBestGrouperConfiguration().propertyValueString("external.authentication.defaultUrl", "/")); - this.uiDelegate.setRenewSession(true); - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - boolean runGrouperUi = GrouperHibernateConfig.retrieveConfig().propertyValueBoolean("grouper.is.ui", false); - - if (runGrouperUi && FilterFascadeUtils.isExternalAuthenticationEnabled() && isCallbackUrlCalled((HttpServletRequest) request)) { - this.uiDelegate.doFilter(request, response, chain); - } else { - chain.doFilter(request, response); - } - } - - private static boolean isCallbackUrlCalled(HttpServletRequest request) { - return FilterFascadeUtils.getRequestPathInContext(request).matches(ConfigUtils.getBestGrouperConfiguration().propertyValueString("external.authentication.callbackUrl", "/callback")); - } - - @Override - public void destroy() { - this.uiDelegate.destroy(); - } -} diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/filter/FilterFascadeUtils.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/filter/FilterFascadeUtils.java deleted file mode 100644 index 5acb2adcc2a3..000000000000 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/filter/FilterFascadeUtils.java +++ /dev/null @@ -1,20 +0,0 @@ -package edu.internet2.middleware.grouper.authentication.filter; - -import edu.internet2.middleware.grouper.authentication.ConfigUtils; -import edu.internet2.middleware.grouper.cfg.GrouperHibernateConfig; - -import javax.servlet.http.HttpServletRequest; - -public class FilterFascadeUtils { - protected static String getRequestPathInContext(HttpServletRequest request) { - return request.getRequestURI().replaceFirst(request.getServletContext().getContextPath(), ""); - } - - protected static boolean isExternalAuthenticationEnabled() { - return ConfigUtils.getBestGrouperConfiguration().propertyValueBoolean("external.authentication.enabled", false); - } - - protected static boolean isRunUi() { - return GrouperHibernateConfig.retrieveConfig().propertyValueBoolean("grouper.is.ui", false); - } -} diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/filter/SecurityFilterFacade.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/filter/SecurityFilterFacade.java deleted file mode 100644 index f194709b1f3d..000000000000 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/filter/SecurityFilterFacade.java +++ /dev/null @@ -1,50 +0,0 @@ -package edu.internet2.middleware.grouper.authentication.filter; - -import edu.internet2.middleware.grouper.authentication.ConfigUtils; -import edu.internet2.middleware.grouper.authentication.Pac4jConfigFactory; -import org.pac4j.core.authorization.authorizer.DefaultAuthorizers; -import org.pac4j.core.config.ConfigBuilder; -import org.pac4j.core.util.Pac4jConstants; -import org.pac4j.jee.filter.SecurityFilter; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import java.io.IOException; - -public class SecurityFilterFacade implements Filter { - private SecurityFilter uiDelegate; - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - this.uiDelegate = new SecurityFilter(); - this.uiDelegate.init(filterConfig); - this.initDelegate(); - } - - public void initDelegate() { - if (ConfigUtils.isGrouperUi() && FilterFascadeUtils.isExternalAuthenticationEnabled()) { - this.uiDelegate.setSharedConfig(ConfigBuilder.build(Pac4jConfigFactory.class.getCanonicalName())); - this.uiDelegate.setClients("client"); - this.uiDelegate.setMatchers(String.join(Pac4jConstants.ELEMENT_SEPARATOR, "securityExclusions")); - this.uiDelegate.setAuthorizers(DefaultAuthorizers.NONE); - } - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - if (ConfigUtils.isGrouperUi() && FilterFascadeUtils.isExternalAuthenticationEnabled()) { - this.uiDelegate.doFilter(request, response, chain); - } else { - chain.doFilter(request, response); - } - } - - @Override - public void destroy() { - this.uiDelegate.destroy(); - } -} diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/ConfigUtils.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/ConfigUtils.java similarity index 80% rename from grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/ConfigUtils.java rename to grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/ConfigUtils.java index b91e434ad8fc..341cba7498ec 100644 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/ConfigUtils.java +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/ConfigUtils.java @@ -1,13 +1,16 @@ -package edu.internet2.middleware.grouper.authentication; +package edu.internet2.middleware.grouper.authentication.plugin; import edu.internet2.middleware.grouper.cfg.GrouperHibernateConfig; import edu.internet2.middleware.grouperClient.config.ConfigPropertiesCascadeBase; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; import org.pac4j.core.client.config.BaseClientConfiguration; import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.ResourceLoader; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; import java.time.Period; import java.util.Arrays; @@ -19,6 +22,8 @@ public class ConfigUtils { final static ResourceLoader resourceLoader = new DefaultResourceLoader(); + final static BundleContext bundleContext = FrameworkUtil.getBundle(GrouperAuthentication.class).getBundleContext(); + public static ConfigPropertiesCascadeBase getBestGrouperConfiguration() { if (isGrouperUi()) { return getConfigPropertiesCascadeBase("ui"); @@ -33,17 +38,9 @@ public static ConfigPropertiesCascadeBase getBestGrouperConfiguration() { public static ConfigPropertiesCascadeBase getConfigPropertiesCascadeBase(String type) { try { - switch (type) { - case "ui": - return (ConfigPropertiesCascadeBase) Class.forName("edu.internet2.middleware.grouper.ui.util.GrouperUiConfigInApi").getMethod("retrieveConfig").invoke(null); - case "ws": - return (ConfigPropertiesCascadeBase) Class.forName("edu.internet2.middleware.grouper.ws.GrouperWsConfigInApi").getMethod("retrieveConfig").invoke(null); - case "daemon": - return (ConfigPropertiesCascadeBase) Class.forName("edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig").getMethod("retrieveConfig").invoke(null); - default: - throw new RuntimeException("no appropriate type found"); - } - } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e ) { + ServiceReference serviceReference = (ServiceReference) FrameworkUtil.getBundle(ConfigUtils.class.getClassLoader()).get().getBundleContext().getServiceReferences(ConfigPropertiesCascadeBase.class, "(type=" + type + ")").toArray()[0]; + return FrameworkUtil.getBundle(ConfigUtils.class.getClassLoader()).get().getBundleContext().getService(serviceReference); + } catch (InvalidSyntaxException e) { throw new RuntimeException(e); } } @@ -135,14 +132,14 @@ private static Object getProperty(ConfigPropertiesCascadeBase configPropertiesCa } public static boolean isGrouperUi() { - return GrouperHibernateConfig.retrieveConfig().propertyValueBoolean("grouper.is.ui", false); + return getConfigPropertiesCascadeBase("hibernate").propertyValueBoolean("grouper.is.ui", false); } public static boolean isGrouperWs() { - return GrouperHibernateConfig.retrieveConfig().propertyValueBoolean("grouper.is.ws", false); + return getConfigPropertiesCascadeBase("hibernate").propertyValueBoolean("grouper.is.ws", false); } public static boolean isGrouperDaemon() { - return GrouperHibernateConfig.retrieveConfig().propertyValueBoolean("grouper.is.daemon", false); + return getConfigPropertiesCascadeBase("hibernate").propertyValueBoolean("grouper.is.daemon", false); } } diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/ExternalAuthenticationServletContainerInitializer.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/ExternalAuthenticationServletContainerInitializer.java new file mode 100644 index 000000000000..c3f081c29355 --- /dev/null +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/ExternalAuthenticationServletContainerInitializer.java @@ -0,0 +1,41 @@ +package edu.internet2.middleware.grouper.authentication.plugin; + +import edu.internet2.middleware.grouper.authentication.plugin.filter.CallbackFilterDecorator; +import edu.internet2.middleware.grouper.authentication.plugin.filter.SecurityFilterDecorator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; + +import javax.servlet.FilterRegistration; +import javax.servlet.ServletContainerInitializer; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import java.util.Set; + +public class ExternalAuthenticationServletContainerInitializer implements ServletContainerInitializer { + private final Log log; + + public ExternalAuthenticationServletContainerInitializer(BundleContext bundleContext) { + try { + //TODO: figure out why this is weird + ServiceReference logfactoryReference = (ServiceReference) bundleContext.getAllServiceReferences("org.apache.commons.logging.LogFactory", null)[0]; + log = bundleContext.getService(logfactoryReference).getInstance(ExternalAuthenticationServletContainerInitializer.class); + } catch (InvalidSyntaxException e) { + throw new RuntimeException(e); + } + } + + @Override + public void onStartup(Set> c, ServletContext ctx) throws ServletException { + log.info("Initializing plugin security filters for external authentication"); + CallbackFilterDecorator callbackFilterDecorator = new CallbackFilterDecorator(); + FilterRegistration.Dynamic callbackFilter = ctx.addFilter("callbackFilter", callbackFilterDecorator); + callbackFilter.addMappingForUrlPatterns(null, false, "/*"); + + SecurityFilterDecorator securityFilterDecorator = new SecurityFilterDecorator(); + FilterRegistration.Dynamic securityFilter = ctx.addFilter("securityFilter", securityFilterDecorator); + securityFilter.addMappingForUrlPatterns(null, false, "/*"); + } +} diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/GrouperAuthentication.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/GrouperAuthentication.java new file mode 100644 index 000000000000..ece3cb1db83a --- /dev/null +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/GrouperAuthentication.java @@ -0,0 +1,30 @@ +package edu.internet2.middleware.grouper.authentication.plugin; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; + +import javax.servlet.ServletContainerInitializer; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +public class GrouperAuthentication implements BundleActivator { + private Map referenceMap = new HashMap<>(); + private Map registrationMap = new HashMap<>(); + + @Override + public void start(BundleContext context) throws Exception { + ExternalAuthenticationServletContainerInitializer externalAuthenticationServletContainerInitializer = new ExternalAuthenticationServletContainerInitializer(context); + ServiceRegistration easciRegistration = context.registerService(ServletContainerInitializer.class, externalAuthenticationServletContainerInitializer, new Hashtable<>()); + registrationMap.put(ExternalAuthenticationServletContainerInitializer.class.getCanonicalName(), easciRegistration); + } + + @Override + public void stop(BundleContext context) throws Exception { + for (ServiceRegistration registration : registrationMap.values()) { + registration.unregister(); + } + } +} diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/Pac4jConfigFactory.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/Pac4jConfigFactory.java similarity index 68% rename from grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/Pac4jConfigFactory.java rename to grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/Pac4jConfigFactory.java index cb523c6382b5..793f2b5fa911 100644 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/Pac4jConfigFactory.java +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/Pac4jConfigFactory.java @@ -1,10 +1,15 @@ -package edu.internet2.middleware.grouper.authentication; +package edu.internet2.middleware.grouper.authentication.plugin; -import edu.internet2.middleware.grouper.authentication.config.ClientProvider; -import edu.internet2.middleware.grouper.authentication.config.ClientProviders; +import edu.internet2.middleware.grouper.authentication.plugin.config.ClientProvider; +import edu.internet2.middleware.grouper.authentication.plugin.config.ClientProviders; import edu.internet2.middleware.grouperClient.config.ConfigPropertiesCascadeBase; import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Logger; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; import org.pac4j.core.client.Client; import org.pac4j.core.client.Clients; import org.pac4j.core.config.Config; @@ -12,7 +17,18 @@ import org.pac4j.core.matching.matcher.PathMatcher; public class Pac4jConfigFactory implements ConfigFactory { - private static final Logger LOGGER = Logger.getLogger(Pac4jConfigFactory.class); + // private static final Logger LOGGER = Logger.getLogger(Pac4jConfigFactory.class); + private static final Log LOGGER; + static { + try { + BundleContext bundleContext = FrameworkUtil.getBundle(Pac4jConfigFactory.class).getBundleContext(); + //TODO: figure out why this is weird + ServiceReference logfactoryReference = (ServiceReference) bundleContext.getAllServiceReferences("org.apache.commons.logging.LogFactory", null)[0]; + LOGGER = bundleContext.getService(logfactoryReference).getInstance(ExternalAuthenticationServletContainerInitializer.class); + } catch (InvalidSyntaxException e) { + throw new RuntimeException(e); + } + } @Override public Config build(Object... parameters) { diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/CasClientProvider.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/CasClientProvider.java similarity index 80% rename from grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/CasClientProvider.java rename to grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/CasClientProvider.java index 1647a5997578..1a04a91615a3 100644 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/CasClientProvider.java +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/CasClientProvider.java @@ -1,6 +1,6 @@ -package edu.internet2.middleware.grouper.authentication.config; +package edu.internet2.middleware.grouper.authentication.plugin.config; -import edu.internet2.middleware.grouper.authentication.ConfigUtils; +import edu.internet2.middleware.grouper.authentication.plugin.ConfigUtils; import org.pac4j.cas.client.CasClient; import org.pac4j.cas.config.CasConfiguration; import org.pac4j.core.client.Client; @@ -21,4 +21,4 @@ public Client getClient() { client.setName("client"); return client; } -} +} \ No newline at end of file diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/ClientProvider.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/ClientProvider.java similarity index 64% rename from grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/ClientProvider.java rename to grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/ClientProvider.java index c4604d92dc50..d14f75668516 100644 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/ClientProvider.java +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/ClientProvider.java @@ -1,8 +1,8 @@ -package edu.internet2.middleware.grouper.authentication.config; +package edu.internet2.middleware.grouper.authentication.plugin.config; import org.pac4j.core.client.Client; public interface ClientProvider { boolean supports(String type); Client getClient(); -} +} \ No newline at end of file diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/ClientProviders.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/ClientProviders.java similarity index 89% rename from grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/ClientProviders.java rename to grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/ClientProviders.java index cb55c5db5667..c107ba72d5be 100644 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/ClientProviders.java +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/ClientProviders.java @@ -1,4 +1,4 @@ -package edu.internet2.middleware.grouper.authentication.config; +package edu.internet2.middleware.grouper.authentication.plugin.config; import java.util.Locale; @@ -20,4 +20,4 @@ public Class getProviderClass() { public static ClientProviders fromString(String name) { return ClientProviders.valueOf(name.toUpperCase(Locale.ENGLISH)); } -} +} \ No newline at end of file diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/OidcClientProvider.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/OidcClientProvider.java similarity index 56% rename from grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/OidcClientProvider.java rename to grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/OidcClientProvider.java index 54bbd61eb6d8..2bb855818a7e 100644 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/OidcClientProvider.java +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/OidcClientProvider.java @@ -1,16 +1,33 @@ -package edu.internet2.middleware.grouper.authentication.config; +package edu.internet2.middleware.grouper.authentication.plugin.config; -import edu.internet2.middleware.grouper.authentication.ConfigUtils; -import edu.internet2.middleware.grouper.authentication.oidc.client.ClaimAsUsernameOidcClient; -import edu.internet2.middleware.grouper.authentication.oidc.config.ClaimAsUsernameOidcConfiguration; -import edu.internet2.middleware.grouperClient.config.ConfigPropertiesCascadeBase; +import edu.internet2.middleware.grouper.authentication.plugin.ConfigUtils; +import edu.internet2.middleware.grouper.authentication.plugin.ExternalAuthenticationServletContainerInitializer; +import edu.internet2.middleware.grouper.authentication.plugin.Pac4jConfigFactory; +import edu.internet2.middleware.grouper.authentication.plugin.oidc.client.ClaimAsUsernameOidcClient; +import edu.internet2.middleware.grouper.authentication.plugin.oidc.config.ClaimAsUsernameOidcConfiguration; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.log4j.Logger; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; import org.pac4j.core.client.Client; import org.pac4j.oidc.client.OidcClient; import org.pac4j.oidc.config.OidcConfiguration; public class OidcClientProvider implements ClientProvider { - private static Logger LOGGER = Logger.getLogger(OidcClientProvider.class); + private static final Log LOGGER; + static { + try { + BundleContext bundleContext = FrameworkUtil.getBundle(Pac4jConfigFactory.class).getBundleContext(); + //TODO: figure out why this is weird + ServiceReference logfactoryReference = (ServiceReference) bundleContext.getAllServiceReferences("org.apache.commons.logging.LogFactory", null)[0]; + LOGGER = bundleContext.getService(logfactoryReference).getInstance(ExternalAuthenticationServletContainerInitializer.class); + } catch (InvalidSyntaxException e) { + throw new RuntimeException(e); + } + } @Override public boolean supports(String type) { diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/SAML2ClientProvider.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/SAML2ClientProvider.java similarity index 81% rename from grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/SAML2ClientProvider.java rename to grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/SAML2ClientProvider.java index 35fcf2ea9927..c76c62dfa32c 100644 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/config/SAML2ClientProvider.java +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/config/SAML2ClientProvider.java @@ -1,6 +1,6 @@ -package edu.internet2.middleware.grouper.authentication.config; +package edu.internet2.middleware.grouper.authentication.plugin.config; -import edu.internet2.middleware.grouper.authentication.ConfigUtils; +import edu.internet2.middleware.grouper.authentication.plugin.ConfigUtils; import org.pac4j.core.client.Client; import org.pac4j.saml.client.SAML2Client; import org.pac4j.saml.config.SAML2Configuration; @@ -21,4 +21,4 @@ public Client getClient() { client.setName("client"); return client; } -} +} \ No newline at end of file diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/CallbackFilterDecorator.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/CallbackFilterDecorator.java new file mode 100644 index 000000000000..2c45f19e6091 --- /dev/null +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/CallbackFilterDecorator.java @@ -0,0 +1,50 @@ +package edu.internet2.middleware.grouper.authentication.plugin.filter; + +import edu.internet2.middleware.grouper.authentication.plugin.ConfigUtils; +import edu.internet2.middleware.grouper.cfg.GrouperHibernateConfig; +import org.pac4j.jee.filter.CallbackFilter; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.util.Timer; +import java.util.TimerTask; + +public class CallbackFilterDecorator extends CallbackFilter implements Reinitializable { + private Timer timer = new Timer(); + + private static boolean isCallbackUrlCalled(HttpServletRequest request) { + return getRequestPathInContext(request).matches(ConfigUtils.getBestGrouperConfiguration().propertyValueString("external.authentication.callbackUrl", "/callback")); + } + + private static String getRequestPathInContext(HttpServletRequest request) { + return request.getRequestURI().replaceFirst(request.getServletContext().getContextPath(), ""); + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + super.init(filterConfig); + this.initDecorator(); + TimerTask timerTask = new ReinitializingTimer(this); + int period = ConfigUtils.getBestGrouperConfiguration().propertyValueInt("external.authentication.config.reload.milliseconds", 60 * 1000); + this.timer.schedule(timerTask, period, period); + } + + public void initDecorator() { + this.setDefaultUrl(ConfigUtils.getBestGrouperConfiguration().propertyValueString("external.authentication.defaultUrl", "/")); + this.setRenewSession(true); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + if (FilterDecoratorUtils.isExternalAuthenticationEnabled() && isCallbackUrlCalled((HttpServletRequest) request)) { + super.doFilter(request, response, chain); + } else { + chain.doFilter(request, response); + } + } +} diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/FilterDecoratorUtils.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/FilterDecoratorUtils.java new file mode 100644 index 000000000000..55db5e3aa8ba --- /dev/null +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/FilterDecoratorUtils.java @@ -0,0 +1,10 @@ +package edu.internet2.middleware.grouper.authentication.plugin.filter; + +import edu.internet2.middleware.grouper.authentication.plugin.ConfigUtils; + +public class FilterDecoratorUtils { + protected static boolean isExternalAuthenticationEnabled() { + return ConfigUtils.getBestGrouperConfiguration().propertyValueBoolean("grouper.is.extAuth.enabled", false); + } + +} \ No newline at end of file diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/Reinitializable.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/Reinitializable.java new file mode 100644 index 000000000000..60e8d2c63e60 --- /dev/null +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/Reinitializable.java @@ -0,0 +1,5 @@ +package edu.internet2.middleware.grouper.authentication.plugin.filter; + +public interface Reinitializable { + void initDecorator(); +} \ No newline at end of file diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/ReinitializingTimer.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/ReinitializingTimer.java new file mode 100644 index 000000000000..9d98144501a0 --- /dev/null +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/ReinitializingTimer.java @@ -0,0 +1,54 @@ +package edu.internet2.middleware.grouper.authentication.plugin.filter; + +import edu.internet2.middleware.grouper.authentication.plugin.ConfigUtils; +import edu.internet2.middleware.grouper.authentication.plugin.ExternalAuthenticationServletContainerInitializer; +import edu.internet2.middleware.grouper.authentication.plugin.Pac4jConfigFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; + +import java.util.Map; +import java.util.TimerTask; +import java.util.regex.Pattern; + +public class ReinitializingTimer extends TimerTask { + private static final Log LOGGER; + static { + try { + BundleContext bundleContext = FrameworkUtil.getBundle(Pac4jConfigFactory.class).getBundleContext(); + //TODO: figure out why this is weird + ServiceReference logfactoryReference = (ServiceReference) bundleContext.getAllServiceReferences("org.apache.commons.logging.LogFactory", null)[0]; + LOGGER = bundleContext.getService(logfactoryReference).getInstance(ExternalAuthenticationServletContainerInitializer.class); + } catch (InvalidSyntaxException e) { + throw new RuntimeException(e); + } + } + + private Map config; + private final Reinitializable initTarget; + + public ReinitializingTimer(Reinitializable initTarget) { + this.initTarget = initTarget; + config = ConfigUtils.getBestGrouperConfiguration().propertiesMap(Pattern.compile("^external\\.authentication\\.([^.]+)$")); + } + + protected static boolean areEqual(Map first, Map second) { + if (first.size() != second.size()) { + return false; + } + return first.entrySet().stream().allMatch(e -> e.getValue().equals(second.get(e.getKey()))); + } + + @Override + public void run() { + Map curConfig = ConfigUtils.getBestGrouperConfiguration().propertiesMap(Pattern.compile("^external\\.authentication\\.([^.]+)$")); + if (!areEqual(config, curConfig)) { + config = curConfig; + initTarget.initDecorator(); + LOGGER.info("Pac4j External Authentication configuration reloaded"); + } + } +} diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/SecurityFilterDecorator.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/SecurityFilterDecorator.java new file mode 100644 index 000000000000..6f88fea922df --- /dev/null +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/filter/SecurityFilterDecorator.java @@ -0,0 +1,48 @@ +package edu.internet2.middleware.grouper.authentication.plugin.filter; + +import edu.internet2.middleware.grouper.authentication.plugin.ConfigUtils; +import edu.internet2.middleware.grouper.authentication.plugin.Pac4jConfigFactory; +import org.pac4j.core.authorization.authorizer.DefaultAuthorizers; +import org.pac4j.core.config.ConfigBuilder; +import org.pac4j.core.util.Pac4jConstants; +import org.pac4j.jee.filter.SecurityFilter; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.io.IOException; +import java.util.Timer; +import java.util.TimerTask; + +public class SecurityFilterDecorator extends SecurityFilter implements Reinitializable { + private Timer timer = new Timer(); + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + super.init(filterConfig); + this.initDecorator(); + TimerTask timerTask = new ReinitializingTimer(this); + int period = ConfigUtils.getBestGrouperConfiguration().propertyValueInt("external.authentication.config.reload.milliseconds", 60 * 1000); + this.timer.schedule(timerTask, period, period); + } + + public void initDecorator() { + if (ConfigUtils.isGrouperUi() && FilterDecoratorUtils.isExternalAuthenticationEnabled()) { + this.setSharedConfig(new Pac4jConfigFactory().build()); + this.setClients("client"); + this.setMatchers(String.join(Pac4jConstants.ELEMENT_SEPARATOR, "securityExclusions")); + this.setAuthorizers(DefaultAuthorizers.NONE); + } + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + if (ConfigUtils.isGrouperUi() && FilterDecoratorUtils.isExternalAuthenticationEnabled()) { + super.doFilter(request, response, chain); + } else { + chain.doFilter(request, response); + } + } +} diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/client/ClaimAsUsernameOidcClient.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/client/ClaimAsUsernameOidcClient.java similarity index 62% rename from grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/client/ClaimAsUsernameOidcClient.java rename to grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/client/ClaimAsUsernameOidcClient.java index 22f17df79c66..7cb2c3ec1aa9 100644 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/client/ClaimAsUsernameOidcClient.java +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/client/ClaimAsUsernameOidcClient.java @@ -1,7 +1,7 @@ -package edu.internet2.middleware.grouper.authentication.oidc.client; +package edu.internet2.middleware.grouper.authentication.plugin.oidc.client; -import edu.internet2.middleware.grouper.authentication.oidc.config.ClaimAsUsernameOidcConfiguration; -import edu.internet2.middleware.grouper.authentication.oidc.profile.ClaimAsUsernameProfileCreator; +import edu.internet2.middleware.grouper.authentication.plugin.oidc.config.ClaimAsUsernameOidcConfiguration; +import edu.internet2.middleware.grouper.authentication.plugin.oidc.profile.ClaimAsUsernameProfileCreator; import org.pac4j.oidc.client.OidcClient; public class ClaimAsUsernameOidcClient extends OidcClient { @@ -15,4 +15,4 @@ protected void clientInit() { super.clientInit(); } -} +} \ No newline at end of file diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/config/ClaimAsUsernameOidcConfiguration.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/config/ClaimAsUsernameOidcConfiguration.java similarity index 82% rename from grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/config/ClaimAsUsernameOidcConfiguration.java rename to grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/config/ClaimAsUsernameOidcConfiguration.java index 8fab2cfafa2f..e20e2cf2a3c8 100644 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/config/ClaimAsUsernameOidcConfiguration.java +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/config/ClaimAsUsernameOidcConfiguration.java @@ -1,4 +1,4 @@ -package edu.internet2.middleware.grouper.authentication.oidc.config; +package edu.internet2.middleware.grouper.authentication.plugin.oidc.config; import org.pac4j.oidc.config.OidcConfiguration; @@ -12,4 +12,4 @@ public String getClaimAsUsername() { public void setClaimAsUsername(String claimAsUsername) { this.claimAsUsername = claimAsUsername; } -} +} \ No newline at end of file diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/profile/ClaimAsUsernameProfile.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/profile/ClaimAsUsernameProfile.java similarity index 83% rename from grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/profile/ClaimAsUsernameProfile.java rename to grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/profile/ClaimAsUsernameProfile.java index df4068b5b043..fa2dfa9872c6 100644 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/profile/ClaimAsUsernameProfile.java +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/profile/ClaimAsUsernameProfile.java @@ -1,4 +1,4 @@ -package edu.internet2.middleware.grouper.authentication.oidc.profile; +package edu.internet2.middleware.grouper.authentication.plugin.oidc.profile; import org.pac4j.oidc.profile.OidcProfile; @@ -13,4 +13,4 @@ public ClaimAsUsernameProfile(final String claimAsUsername) { public String getUsername() { return this.getAttribute(this.claimAsUsername).toString(); } -} +} \ No newline at end of file diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/profile/ClaimAsUsernameProfileCreator.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/profile/ClaimAsUsernameProfileCreator.java similarity index 81% rename from grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/profile/ClaimAsUsernameProfileCreator.java rename to grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/profile/ClaimAsUsernameProfileCreator.java index 708297fb4b09..163c983e96ae 100644 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/profile/ClaimAsUsernameProfileCreator.java +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/profile/ClaimAsUsernameProfileCreator.java @@ -1,6 +1,6 @@ -package edu.internet2.middleware.grouper.authentication.oidc.profile; +package edu.internet2.middleware.grouper.authentication.plugin.oidc.profile; -import edu.internet2.middleware.grouper.authentication.oidc.config.ClaimAsUsernameOidcConfiguration; +import edu.internet2.middleware.grouper.authentication.plugin.oidc.config.ClaimAsUsernameOidcConfiguration; import org.pac4j.core.util.CommonHelper; import org.pac4j.oidc.client.OidcClient; import org.pac4j.oidc.config.OidcConfiguration; @@ -19,4 +19,4 @@ protected void internalInit() { super.internalInit(); } -} +} \ No newline at end of file diff --git a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/profile/ClaimAsUsernameProfileDefinition.java b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/profile/ClaimAsUsernameProfileDefinition.java similarity index 81% rename from grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/profile/ClaimAsUsernameProfileDefinition.java rename to grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/profile/ClaimAsUsernameProfileDefinition.java index 1e535f6297a2..8981c5a971bb 100644 --- a/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/oidc/profile/ClaimAsUsernameProfileDefinition.java +++ b/grouper-misc/grouper-authentication/src/main/java/edu/internet2/middleware/grouper/authentication/plugin/oidc/profile/ClaimAsUsernameProfileDefinition.java @@ -1,4 +1,4 @@ -package edu.internet2.middleware.grouper.authentication.oidc.profile; +package edu.internet2.middleware.grouper.authentication.plugin.oidc.profile; import org.pac4j.oidc.profile.OidcProfileDefinition; @@ -7,4 +7,4 @@ public ClaimAsUsernameProfileDefinition(final String claimAsUsername) { super(); setProfileFactory(x -> new ClaimAsUsernameProfile(claimAsUsername)); } -} +} \ No newline at end of file diff --git a/grouper-misc/grouper-authentication/src/test/java/edu/internet2/middleware/grouper/authentication/Pac4JConfigFactoryTest.java b/grouper-misc/grouper-authentication/src/test/java/edu/internet2/middleware/grouper/authentication/Pac4JConfigFactoryTest.java index fc04641cd8ff..51c084e52803 100644 --- a/grouper-misc/grouper-authentication/src/test/java/edu/internet2/middleware/grouper/authentication/Pac4JConfigFactoryTest.java +++ b/grouper-misc/grouper-authentication/src/test/java/edu/internet2/middleware/grouper/authentication/Pac4JConfigFactoryTest.java @@ -1,5 +1,6 @@ package edu.internet2.middleware.grouper.authentication; +import edu.internet2.middleware.grouper.authentication.plugin.Pac4jConfigFactory; import edu.internet2.middleware.grouper.ui.util.GrouperUiConfig; import junit.framework.TestCase; import junit.textui.TestRunner; @@ -252,7 +253,7 @@ public void testPac4jForManualProvider() { GrouperUiConfig.retrieveConfig().properties().clear(); GrouperUiConfig.retrieveConfig().propertiesOverrideMap().clear(); Map overrides = GrouperUiConfig.retrieveConfig().propertiesOverrideMap(); - overrides.put("external.authentication.provider", "edu.internet2.middleware.grouper.authentication.config.SAML2ClientProvider"); + overrides.put("external.authentication.provider", "edu.internet2.middleware.grouper.authentication.plugin.config.SAML2ClientProvider"); Pac4jConfigFactory pac4jConfigFactory = new Pac4jConfigFactory(); Config config = pac4jConfigFactory.build(); @@ -261,4 +262,4 @@ public void testPac4jForManualProvider() { Assert.assertTrue(true); } -} +} \ No newline at end of file diff --git a/grouper-misc/grouper-pspng/src/main/java/edu/internet2/middleware/grouper/pspng/LdapSystem.java b/grouper-misc/grouper-pspng/src/main/java/edu/internet2/middleware/grouper/pspng/LdapSystem.java index bf3ca6af664a..3b14e5863d8f 100644 --- a/grouper-misc/grouper-pspng/src/main/java/edu/internet2/middleware/grouper/pspng/LdapSystem.java +++ b/grouper-misc/grouper-pspng/src/main/java/edu/internet2/middleware/grouper/pspng/LdapSystem.java @@ -188,10 +188,11 @@ public void log(LdapEntry ldapEntry, String ldapEntryDescriptionFormat, Object.. // INFO log is a count of each attribute's values if ( LOG.isInfoEnabled() ) { StringBuilder sb = new StringBuilder(); - sb.append(String.format("dn=%s|", ldapEntry.getDn())); - - for (LdapAttribute attribute : ldapEntry.getAttributes()) { - sb.append(String.format("%d %s values|", attribute.size(), attribute.getName())); + sb.append(String.format("dn=%s|", ldapEntry == null ? "null" : ldapEntry.getDn())); + if (ldapEntry != null && ldapEntry.getAttributes() != null) { + for (LdapAttribute attribute : ldapEntry.getAttributes()) { + sb.append(String.format("%d %s values|", attribute.size(), attribute.getName())); + } } LOG.info("{}: {} Entry Summary: {}", ldapSystemName, ldapEntryDescription, sb.toString()); } @@ -210,11 +211,13 @@ public void log( ModifyRequest modifyRequest, String descriptionFormat, Object.. // INFO log is a count of each attribute's values if ( LOG.isInfoEnabled() ) { StringBuilder sb = new StringBuilder(); - sb.append(String.format("dn=%s|", modifyRequest.getDn())); + sb.append(String.format("dn=%s|", modifyRequest == null ? "null" : modifyRequest.getDn())); - for (AttributeModification mod : modifyRequest.getAttributeModifications()) { - sb.append(String.format("%s %d %s values|", - mod.getAttributeModificationType(), mod.getAttribute().size(), mod.getAttribute().getName())); + if (modifyRequest != null && modifyRequest.getAttributeModifications() != null) { + for (AttributeModification mod : modifyRequest.getAttributeModifications()) { + sb.append(String.format("%s %d %s values|", + mod.getAttributeModificationType(), mod.getAttribute().size(), mod.getAttribute().getName())); + } } LOG.info("{}: {} Mod Summary: {}", ldapSystemName, ldapEntryDescription, sb.toString()); } @@ -229,7 +232,15 @@ protected void performTestLdapRead(Connection conn) throws PspException { SearchRequestPropertySource srSource = new SearchRequestPropertySource(searchExecutor, getLdaptiveProperties()); srSource.initialize(); - SearchRequest read = new SearchRequest("", "objectclass=*"); + String baseDn = GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapSystemName + ".uiTestSearchDn", ""); + String filter = GrouperLoaderConfig.retrieveConfig().propertyValueString("ldap." + ldapSystemName + ".uiTestFilter", "objectclass=*"); + + filter = StringUtils.trim(filter); + if (filter.startsWith("(") && filter.endsWith(")")) { + filter = filter.substring(1, filter.length()-1); + } + + SearchRequest read = new SearchRequest(baseDn, filter); read.setSearchScope(SearchScope.OBJECT); // Turn on attribute-value paging if this is an active directory target diff --git a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/GcDbAccess.java b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/GcDbAccess.java index 1cfbd64a1cbb..6a6e60db2cba 100644 --- a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/GcDbAccess.java +++ b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/GcDbAccess.java @@ -2594,6 +2594,10 @@ private Object retrieveObjectFromResultSetByIndex(ResultSet resultSet, int colum // if we want to go down this path, need to check to see if has decimal and convert to long return bigDecimal; + case Types.BIT: + case Types.BOOLEAN: + return resultSet.getBoolean(columnNumberOneIndexed); + case Types.CHAR: case Types.VARCHAR: case Types.LONGVARCHAR: diff --git a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncGroup.java b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncGroup.java index 7ba224ba5786..3c13a139b7e7 100644 --- a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncGroup.java +++ b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncGroup.java @@ -69,13 +69,13 @@ public GcGrouperSyncGroup clone() { gcGrouperSyncGroup.errorCodeDb = this.errorCodeDb; gcGrouperSyncGroup.errorMessage = this.errorMessage; gcGrouperSyncGroup.errorTimestamp = this.errorTimestamp; - gcGrouperSyncGroup.groupFromId2 = this.groupFromId2; - gcGrouperSyncGroup.groupFromId3 = this.groupFromId3; + gcGrouperSyncGroup.groupAttributeValueCache0 = this.groupAttributeValueCache0; + gcGrouperSyncGroup.groupAttributeValueCache1 = this.groupAttributeValueCache1; gcGrouperSyncGroup.groupId = this.groupId; gcGrouperSyncGroup.groupIdIndex = this.groupIdIndex; gcGrouperSyncGroup.groupName = this.groupName; - gcGrouperSyncGroup.groupToId2 = this.groupToId2; - gcGrouperSyncGroup.groupToId3 = this.groupToId3; + gcGrouperSyncGroup.groupAttributeValueCache2 = this.groupAttributeValueCache2; + gcGrouperSyncGroup.groupAttributeValueCache3 = this.groupAttributeValueCache3; //grouperSync DONT CLONE gcGrouperSyncGroup.grouperSyncId = this.grouperSyncId; @@ -129,13 +129,13 @@ public boolean equalsDeep(Object obj) { .append(this.errorMessage, other.errorMessage) .append(this.errorTimestamp, other.errorTimestamp) - .append(this.groupFromId2, other.groupFromId2) - .append(this.groupFromId3, other.groupFromId3) + .append(this.groupAttributeValueCache0, other.groupAttributeValueCache0) + .append(this.groupAttributeValueCache1, other.groupAttributeValueCache1) .append(this.groupId, other.groupId) .append(this.groupIdIndex, other.groupIdIndex) .append(this.groupName, other.groupName) - .append(this.groupToId2, other.groupToId2) - .append(this.groupToId3, other.groupToId3) + .append(this.groupAttributeValueCache2, other.groupAttributeValueCache2) + .append(this.groupAttributeValueCache3, other.groupAttributeValueCache3) //grouperSync DONT EQUALS .append(this.grouperSyncId, other.grouperSyncId) @@ -835,70 +835,74 @@ public void setGroupIdIndex(Long groupIdIndex1) { /** * metadata on groups */ - private String groupFromId2; + @GcPersistableField(columnName = "group_from_id2") + private String groupAttributeValueCache0; /** * metadata on groups * @return group from id 2 */ - public String getGroupFromId2() { - return this.groupFromId2; + public String getGroupAttributeValueCache0() { + return this.groupAttributeValueCache0; } /** * metadata on groups - * @param groupFromId2_1 + * @param groupAttributeValueCache0_1 */ - public void setGroupFromId2(String groupFromId2_1) { - this.groupFromId2 = groupFromId2_1; + public void setGroupAttributeValueCache0(String groupAttributeValueCache0_1) { + this.groupAttributeValueCache0 = groupAttributeValueCache0_1; } /** * other metadata on groups */ - private String groupFromId3; + @GcPersistableField(columnName = "group_from_id3") + private String groupAttributeValueCache1; /** * other metadata on groups * @return id3 */ - public String getGroupFromId3() { - return this.groupFromId3; + public String getGroupAttributeValueCache1() { + return this.groupAttributeValueCache1; } /** * other metadata on groups - * @param groupFromId3_1 + * @param groupAttributeValueCache1_1 */ - public void setGroupFromId3(String groupFromId3_1) { - this.groupFromId3 = groupFromId3_1; + public void setGroupAttributeValueCache1(String groupAttributeValueCache1_1) { + this.groupAttributeValueCache1 = groupAttributeValueCache1_1; } /** * other metadata on groups */ - private String groupToId2; + @GcPersistableField(columnName = "group_to_id2") + private String groupAttributeValueCache2; /** * other metadata on groups * @return metadata */ - public String getGroupToId2() { - return this.groupToId2; + public String getGroupAttributeValueCache2() { + return this.groupAttributeValueCache2; } /** * other metadata on groups - * @param groupToId2_1 + * @param groupAttributeValueCache2_1 */ - public void setGroupToId2(String groupToId2_1) { - this.groupToId2 = groupToId2_1; + public void setGroupAttributeValueCache2(String groupAttributeValueCache2_1) { + this.groupAttributeValueCache2 = groupAttributeValueCache2_1; } /** * other metadata on groups */ - private String groupToId3; + @GcPersistableField(columnName = "group_to_id3") + private String groupAttributeValueCache3; // /** // * T if inserted on the in_grouper_start date, or F if it existed then and not sure when inserted @@ -1030,16 +1034,16 @@ public void setGroupToId2(String groupToId2_1) { * other metadata on groups * @return group id */ - public String getGroupToId3() { - return this.groupToId3; + public String getGroupAttributeValueCache3() { + return this.groupAttributeValueCache3; } /** * other metadata on groups - * @param groupToId3_1 + * @param groupAttributeValueCache3_1 */ - public void setGroupToId3(String groupToId3_1) { - this.groupToId3 = groupToId3_1; + public void setGroupAttributeValueCache3(String groupAttributeValueCache3_1) { + this.groupAttributeValueCache3 = groupAttributeValueCache3_1; } /** @@ -1060,14 +1064,14 @@ public boolean gcSqlAssignNewPrimaryKeyForInsert() { * @param result */ public void assignField(String syncField, Object result) { - if (GrouperClientUtils.equals("groupFromId2", syncField)) { - this.setGroupFromId2(GrouperClientUtils.stringValue(result)); - } else if (GrouperClientUtils.equals("groupFromId3", syncField)) { - this.setGroupFromId3(GrouperClientUtils.stringValue(result)); - } else if (GrouperClientUtils.equals("groupToId2", syncField)) { - this.setGroupToId2(GrouperClientUtils.stringValue(result)); - } else if (GrouperClientUtils.equals("groupToId3", syncField)) { - this.setGroupToId3(GrouperClientUtils.stringValue(result)); + if (GrouperClientUtils.equals("groupAttributeValueCache0", syncField)) { + this.setGroupAttributeValueCache0(GrouperClientUtils.stringValue(result)); + } else if (GrouperClientUtils.equals("groupAttributeValueCache1", syncField)) { + this.setGroupAttributeValueCache1(GrouperClientUtils.stringValue(result)); + } else if (GrouperClientUtils.equals("groupAttributeValueCache2", syncField)) { + this.setGroupAttributeValueCache2(GrouperClientUtils.stringValue(result)); + } else if (GrouperClientUtils.equals("groupAttributeValueCache3", syncField)) { + this.setGroupAttributeValueCache3(GrouperClientUtils.stringValue(result)); } else { throw new RuntimeException("Not expecting groupSyncField: '" + syncField + "'"); } @@ -1080,14 +1084,14 @@ public void assignField(String syncField, Object result) { * @param result */ public String retrieveField(String syncField) { - if (GrouperClientUtils.equals("groupFromId2", syncField)) { - return this.getGroupFromId2(); - } else if (GrouperClientUtils.equals("groupFromId3", syncField)) { - return this.getGroupFromId3(); - } else if (GrouperClientUtils.equals("groupToId2", syncField)) { - return this.getGroupToId2(); - } else if (GrouperClientUtils.equals("groupToId3", syncField)) { - return this.getGroupToId3(); + if (GrouperClientUtils.equals("groupAttributeValueCache0", syncField)) { + return this.getGroupAttributeValueCache0(); + } else if (GrouperClientUtils.equals("groupAttributeValueCache1", syncField)) { + return this.getGroupAttributeValueCache1(); + } else if (GrouperClientUtils.equals("groupAttributeValueCache2", syncField)) { + return this.getGroupAttributeValueCache2(); + } else if (GrouperClientUtils.equals("groupAttributeValueCache3", syncField)) { + return this.getGroupAttributeValueCache3(); } else { throw new RuntimeException("Not expecting groupSyncField: '" + syncField + "'"); } diff --git a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncLogDao.java b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncLogDao.java index 8d2a5bdc06dc..3da52b58ebe0 100644 --- a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncLogDao.java +++ b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncLogDao.java @@ -158,6 +158,37 @@ public int internal_logDeleteBatchByOwnerIds(Collection ownerIds) { return count; } + /** + * delete stuff with batches by id + * @param ids + * @return the number of records deleted + */ + public static int internal_logDeleteByIds(Collection ids) { + + int count = 0; + if (GrouperClientUtils.length(ids) > 0) { + + List> batchBindVars = new ArrayList>(); + + for (String ownerId : ids) { + List currentBindVarRow = new ArrayList(); + currentBindVarRow.add(ownerId); + batchBindVars.add(currentBindVarRow); + + } + + int[] rowDeleteCounts = new GcDbAccess().sql( + "delete from grouper_sync_log where id = ?") + .batchBindVars(batchBindVars).executeBatchSql(); + + for (int rowDeleteCount : rowDeleteCounts) { + count += rowDeleteCount; + } + + } + return count; + } + /** * delete batch * @param gcGrouperSyncLogs diff --git a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncMember.java b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncMember.java index 20bbd463b954..01850d549438 100644 --- a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncMember.java +++ b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncMember.java @@ -86,11 +86,11 @@ public GcGrouperSyncMember clone() { gcGrouperSyncMember.lastUserMetadataSync = this.lastUserMetadataSync; gcGrouperSyncMember.lastUserSyncStart = this.lastUserSyncStart; gcGrouperSyncMember.lastUserSync = this.lastUserSync; - gcGrouperSyncMember.memberFromId2 = this.memberFromId2; - gcGrouperSyncMember.memberFromId3 = this.memberFromId3; + gcGrouperSyncMember.entityAttributeValueCache0 = this.entityAttributeValueCache0; + gcGrouperSyncMember.entityAttributeValueCache1 = this.entityAttributeValueCache1; gcGrouperSyncMember.memberId = this.memberId; - gcGrouperSyncMember.memberToId2 = this.memberToId2; - gcGrouperSyncMember.memberToId3 = this.memberToId3; + gcGrouperSyncMember.entityAttributeValueCache2 = this.entityAttributeValueCache2; + gcGrouperSyncMember.entityAttributeValueCache3 = this.entityAttributeValueCache3; gcGrouperSyncMember.metadataUpdated = this.metadataUpdated; gcGrouperSyncMember.provisionableDb = this.provisionableDb; gcGrouperSyncMember.provisionableEnd = this.provisionableEnd; @@ -144,11 +144,11 @@ public boolean equalsDeep(Object obj) { .append(this.lastUserMetadataSyncStart, other.lastUserMetadataSyncStart) .append(this.lastUserSync, other.lastUserSync) .append(this.lastUserSyncStart, other.lastUserSyncStart) - .append(this.memberFromId2, other.memberFromId2) - .append(this.memberFromId3, other.memberFromId3) + .append(this.entityAttributeValueCache0, other.entityAttributeValueCache0) + .append(this.entityAttributeValueCache1, other.entityAttributeValueCache1) .append(this.memberId, other.memberId) - .append(this.memberToId2, other.memberToId2) - .append(this.memberToId3, other.memberToId3) + .append(this.entityAttributeValueCache2, other.entityAttributeValueCache2) + .append(this.entityAttributeValueCache3, other.entityAttributeValueCache3) .append(this.metadataUpdated, other.metadataUpdated) .append(this.provisionableDb, other.provisionableDb) .append(this.provisionableEnd, other.provisionableEnd) @@ -610,10 +610,10 @@ public static void main(String[] args) { gcGrouperSyncMember.sourceId = "sourceId"; gcGrouperSyncMember.subjectId = "subjectId"; gcGrouperSyncMember.subjectIdentifier = "subjectIdentifier"; - gcGrouperSyncMember.memberFromId2 = "from2"; - gcGrouperSyncMember.memberFromId3 = "from3"; - gcGrouperSyncMember.memberToId2 = "toId2"; - gcGrouperSyncMember.memberToId3 = "toId3"; + gcGrouperSyncMember.entityAttributeValueCache0 = "from2"; + gcGrouperSyncMember.entityAttributeValueCache1 = "from3"; + gcGrouperSyncMember.entityAttributeValueCache2 = "toId2"; + gcGrouperSyncMember.entityAttributeValueCache3 = "toId3"; gcGrouperSyncMember.inTargetDb = "T"; gcGrouperSyncMember.inTargetInsertOrExistsDb = "T"; gcGrouperSyncMember.inTargetEnd = new Timestamp(123L); @@ -629,7 +629,7 @@ public static void main(String[] args) { gcGrouperSyncMember = gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId("memId"); System.out.println(gcGrouperSyncMember); - gcGrouperSyncMember.setMemberToId2("from2a"); + gcGrouperSyncMember.setEntityAttributeValueCache2("from2a"); gcGrouperSync.getGcGrouperSyncMemberDao().internal_memberStore(gcGrouperSyncMember); System.out.println("updated"); @@ -957,74 +957,80 @@ public void setProvisionableStart(Timestamp provisionableStartMillis1) { /** * for users this is the group idIndex */ - private String memberFromId2; + @GcPersistableField(columnName = "member_from_id2") + private String entityAttributeValueCache0; /** * for users this is the group idIndex * @return group from id 2 */ - public String getMemberFromId2() { - return this.memberFromId2; + public String getEntityAttributeValueCache0() { + return this.entityAttributeValueCache0; } /** * for users this is the group idIndex - * @param groupFromId2_1 + * @param groupAttributeValueCache0_1 */ - public void setMemberFromId2(String groupFromId2_1) { - this.memberFromId2 = groupFromId2_1; + public void setEntityAttributeValueCache0(String groupAttributeValueCache0_1) { + this.entityAttributeValueCache0 = groupAttributeValueCache0_1; } /** * other metadata on users */ - private String memberFromId3; + @GcPersistableField(columnName = "member_from_id3") + private String entityAttributeValueCache1; /** * other metadata on users * @return id3 */ - public String getMemberFromId3() { - return this.memberFromId3; + public String getEntityAttributeValueCache1() { + return this.entityAttributeValueCache1; } /** * other metadata on users - * @param groupFromId3_1 + * @param groupAttributeValueCache1_1 */ - public void setMemberFromId3(String groupFromId3_1) { - this.memberFromId3 = groupFromId3_1; + public void setEntityAttributeValueCache1(String groupAttributeValueCache1_1) { + this.entityAttributeValueCache1 = groupAttributeValueCache1_1; } /** * other metadata on users */ - private String memberToId2; + @GcPersistableField(columnName = "member_to_id2") + private String entityAttributeValueCache2; /** * other metadata on users * @return metadata */ - public String getMemberToId2() { - return this.memberToId2; + public String getEntityAttributeValueCache2() { + return this.entityAttributeValueCache2; } /** * other metadata on users - * @param groupToId2_1 + * @param groupAttributeValueCache2_1 */ - public void setMemberToId2(String groupToId2_1) { - this.memberToId2 = groupToId2_1; + public void setEntityAttributeValueCache2(String groupAttributeValueCache2_1) { + this.entityAttributeValueCache2 = groupAttributeValueCache2_1; } /** * other metadata on users */ - private String memberToId3; + @GcPersistableField(columnName = "member_to_id3") + private String entityAttributeValueCache3; + /** * when this group was removed from target */ private Timestamp inTargetEnd; + /** * when this group was provisioned to target */ @@ -1034,16 +1040,16 @@ public void setMemberToId2(String groupToId2_1) { * other metadata on users * @return group id */ - public String getMemberToId3() { - return this.memberToId3; + public String getEntityAttributeValueCache3() { + return this.entityAttributeValueCache3; } /** * other metadata on users - * @param groupToId3_1 + * @param groupAttributeValueCache3_1 */ - public void setMemberToId3(String groupToId3_1) { - this.memberToId3 = groupToId3_1; + public void setEntityAttributeValueCache3(String groupAttributeValueCache3_1) { + this.entityAttributeValueCache3 = groupAttributeValueCache3_1; } /** @@ -1135,14 +1141,14 @@ public void setMetadataJson(String metadataJson) { * @param result */ public void assignField(String syncField, Object result) { - if (GrouperClientUtils.equals("memberFromId2", syncField)) { - this.setMemberFromId2(GrouperClientUtils.stringValue(result)); - } else if (GrouperClientUtils.equals("memberFromId3", syncField)) { - this.setMemberFromId3(GrouperClientUtils.stringValue(result)); - } else if (GrouperClientUtils.equals("memberToId2", syncField)) { - this.setMemberToId2(GrouperClientUtils.stringValue(result)); - } else if (GrouperClientUtils.equals("memberToId3", syncField)) { - this.setMemberToId3(GrouperClientUtils.stringValue(result)); + if (GrouperClientUtils.equals("entityAttributeValueCache0", syncField)) { + this.setEntityAttributeValueCache0(GrouperClientUtils.stringValue(result)); + } else if (GrouperClientUtils.equals("entityAttributeValueCache1", syncField)) { + this.setEntityAttributeValueCache1(GrouperClientUtils.stringValue(result)); + } else if (GrouperClientUtils.equals("entityAttributeValueCache2", syncField)) { + this.setEntityAttributeValueCache2(GrouperClientUtils.stringValue(result)); + } else if (GrouperClientUtils.equals("entityAttributeValueCache3", syncField)) { + this.setEntityAttributeValueCache3(GrouperClientUtils.stringValue(result)); } else { throw new RuntimeException("Not expecting groupSyncField: '" + syncField + "'"); } @@ -1155,14 +1161,14 @@ public void assignField(String syncField, Object result) { * @param result */ public String retrieveField(String syncField) { - if (GrouperClientUtils.equals("memberFromId2", syncField)) { - return this.getMemberFromId2(); - } else if (GrouperClientUtils.equals("memberFromId3", syncField)) { - return this.getMemberFromId3(); - } else if (GrouperClientUtils.equals("memberToId2", syncField)) { - return this.getMemberToId2(); - } else if (GrouperClientUtils.equals("memberToId3", syncField)) { - return this.getMemberToId3(); + if (GrouperClientUtils.equals("entityAttributeValueCache0", syncField)) { + return this.getEntityAttributeValueCache0(); + } else if (GrouperClientUtils.equals("entityAttributeValueCache1", syncField)) { + return this.getEntityAttributeValueCache1(); + } else if (GrouperClientUtils.equals("entityAttributeValueCache2", syncField)) { + return this.getEntityAttributeValueCache2(); + } else if (GrouperClientUtils.equals("entityAttributeValueCache3", syncField)) { + return this.getEntityAttributeValueCache3(); } else { throw new RuntimeException("Not expecting memberSyncField: '" + syncField + "'"); } diff --git a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncMembershipDao.java b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncMembershipDao.java index 55a0bdd6c3ba..5d4abc0a4b0a 100644 --- a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncMembershipDao.java +++ b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcGrouperSyncMembershipDao.java @@ -754,13 +754,13 @@ public List internal_membershipRetrieveFromDbBySyncGrou } /** - * select count of memberships in target for the given sync group id + * select count of memberships for the given sync group id * @param syncGroupId - * @return the count of memberships in target for the given sync group id + * @return the count of memberships for the given sync group id */ - public int internal_membershipRetrieveFromDbCountInTargetByGroupSyncId(String syncGroupId) { + public int internal_membershipRetrieveFromDbCountByGroupSyncId(String syncGroupId) { - String sql = "select count(1) from grouper_sync_membership where grouper_sync_group_id = ? and in_target = 'T' "; + String sql = "select count(1) from grouper_sync_membership where grouper_sync_group_id = ? "; GcDbAccess gcDbAccess = new GcDbAccess().connectionName(this.getGcGrouperSync().getConnectionName()); diff --git a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcTableSyncColumnMetadata.java b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcTableSyncColumnMetadata.java index 6db0c4abe944..7fd4d531fc0e 100644 --- a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcTableSyncColumnMetadata.java +++ b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcTableSyncColumnMetadata.java @@ -101,6 +101,30 @@ public Object convertToType(Object input) { }, + /** + * + */ + BOOLEAN { + + @Override + public Object readDataFromResultSet(GcTableSyncColumnMetadata gcTableSyncColumnMetadata, ResultSet resultSet) throws SQLException { + return resultSet.getBoolean(gcTableSyncColumnMetadata.getColumnName()); + } + + /** + * convert to type + */ + @Override + public Object convertToType(Object input) { + + if (GrouperClientUtils.isBlank(input)) { + return null; + } + return GrouperClientUtils.booleanValue(input); + } + + }, + /** * */ diff --git a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcTableSyncTableMetadata.java b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcTableSyncTableMetadata.java index 9cbf103ad417..18e2fdca9676 100644 --- a/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcTableSyncTableMetadata.java +++ b/grouper-misc/grouperClient/src/java/edu/internet2/middleware/grouperClient/jdbc/tableSync/GcTableSyncTableMetadata.java @@ -349,9 +349,21 @@ public Object callback(ResultSet resultSet) throws Exception { } break; + case Types.BIT: + case Types.BOOLEAN: + + gcTableSyncColumnMetadata.setColumnType(ColumnType.BOOLEAN); + { + int columnDisplaySize = resultSetMetaData.getColumnDisplaySize(i+1); + gcTableSyncColumnMetadata.setColumnDisplaySize(columnDisplaySize); + } + break; case Types.CHAR: case Types.VARCHAR: case Types.LONGVARCHAR: + case Types.NCHAR: + case Types.NVARCHAR: + case Types.LONGNVARCHAR: gcTableSyncColumnMetadata.setColumnType(ColumnType.STRING); { diff --git a/grouper-misc/webapp/grouper-ui-webapp/pom.xml b/grouper-misc/webapp/grouper-ui-webapp/pom.xml new file mode 100644 index 000000000000..816c966035d4 --- /dev/null +++ b/grouper-misc/webapp/grouper-ui-webapp/pom.xml @@ -0,0 +1,87 @@ + + + + + 4.0.0 + + + edu.internet2.middleware.grouper + grouper-parent + 2.6.0-SNAPSHOT + ../../../grouper-parent + + + Grouper UI webapp + grouper-ui-webapp + war + + + + ${project.groupId} + grouper-ui + ${project.version} + + + + + + + ../../../grouper/conf + + + + + org.apache.maven.plugins + maven-war-plugin + + false + + + ../../../grouper-ui/webapp + + + + + + org.eclipse.jetty + jetty-maven-plugin + 9.4.27.v20200227 + + + /grouper + + + + + + + + + test + + + + src/test/resources + + + + + + diff --git a/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper-loader.properties b/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper-loader.properties new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper-ui.properties b/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper-ui.properties new file mode 100644 index 000000000000..c48d31697eee --- /dev/null +++ b/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper-ui.properties @@ -0,0 +1,5 @@ +grouper.is.extAuth.enabled = true +external.authentication.provider = cas +external.authentication.grouperContextUrl = http://localhost:8888/grouper_ui/ + +external.authentication.cas.loginUrl = https://idp.unicon.local/idp/profile/cas/login diff --git a/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper.cache.properties b/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper.cache.properties new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper.client.properties b/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper.client.properties new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper.hibernate.properties b/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper.hibernate.properties new file mode 100644 index 000000000000..920739854164 --- /dev/null +++ b/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper.hibernate.properties @@ -0,0 +1,3 @@ +grouperPasswordConfigOverride_UI_GrouperSystem_pass.elConfig = ${elUtils.processEnvVarOrFile('GROUPERSYSTEM_QUICKSTART_PASS')} + +grouper.is.ui=true diff --git a/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper.properties b/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper.properties new file mode 100644 index 000000000000..5fad17680f03 --- /dev/null +++ b/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/grouper.properties @@ -0,0 +1,35 @@ +# directory of plugins, default to /opt/grouper/grouperWebapp/WEB-INF/grouperPlugins +# {valueType: "string", required: true, order: 1000} +grouper.osgi.jar.dir = C:/Users/jj-unicon/workspace/grouper.se/grouper/grouper-misc/grouper-authentication/target + +# directory of felix cache of plugins, default to /opt/grouper/grouperWebapp/WEB-INF/grouperFelixCache +# {valueType: "string", required: true, order: 2000} +grouper.felix.cache.rootdir = c:/tmp/grouperFelixCache + +grouperOsgiPlugin.extAuthPlugin.jarName = grouper-authentication-plugin-0.0.1-SNAPSHOT.jar +grouperOsgiPlugin.extAuthPlugin.numberOfImplementations = 2 +grouperOsgiPlugin.extAuthPlugin.osgiImplementation.0.implementationClass = edu.internet2.middleware.grouper.authentication.plugin.filter.SecurityFilterDecorator +grouperOsgiPlugin.extAuthPlugin.osgiImplementation.0.implementsInterface = javax.servlet.Filter +grouperOsgiPlugin.extAuthPlugin.osgiImplementation.1.implementationClass = edu.internet2.middleware.grouper.authentication.plugin.filter.CallbackFilterDecorator +grouperOsgiPlugin.extAuthPlugin.osgiImplementation.1.implementsInterface = javax.servlet.Filter + +############################################ +## External Authentication plugin +############################################ +# Enable external authorization security filters +# {valueType: "boolean", defaultValue: "false"} +grouper.is.extAuth.enabled=true + +# Name of the jar containing the external authorization plugin +# {valueType: "string", required: true} +grouper.extAuth.jarname=grouper-authentication-0.0.1-SNAPSHOT.jar + +# Callback filter implementation classname +# ex: edu.internet2.middleware.grouper.plugins.testImplementation.SamplePluginProviderServiceImpl +# ${valueType: "class", required: true} +grouper.extAuth.filter.callback.implmentation.className=edu.internet2.middleware.grouper.authentication.plugin.filter.CallbackFilterDecorator + +# Security filter implementation classname +# ex: edu.internet2.middleware.grouper.plugins.testImplementation.SamplePluginProviderServiceImpl +# ${valueType: "class", required: true} +grouper.extAuth.filter.security.implmentation.className=edu.internet2.middleware.grouper.authentication.plugin.filter.SecurityFilterDecorator diff --git a/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/morphString.properties b/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/morphString.properties new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/subject.properties b/grouper-misc/webapp/grouper-ui-webapp/src/test/resources/subject.properties new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/grouper-parent/pom.xml b/grouper-parent/pom.xml index f7c066e87057..2bae04d10ed6 100644 --- a/grouper-parent/pom.xml +++ b/grouper-parent/pom.xml @@ -46,8 +46,7 @@ ../grouper-misc/grouper-duo ../grouper-misc/googleapps-grouper-provisioner ../grouper-misc/grouper-azure - ../grouper-misc/grouper-authentication - ../grouper-webapp + ../grouper-misc/webapp/grouper-ui-webapp @@ -98,7 +97,7 @@ 0.9.5 0.2.15 3.3.0 - 7.0.3 + 7.0.4 2.81 1.4.9 0.1.55 diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiGcGrouperSyncMembership.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiGcGrouperSyncMembership.java new file mode 100644 index 000000000000..b3d17755e4bb --- /dev/null +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiGcGrouperSyncMembership.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright 2012 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +package edu.internet2.middleware.grouper.grouperUi.beans.api; + +import java.text.SimpleDateFormat; + +import edu.internet2.middleware.grouper.Group; +import edu.internet2.middleware.grouper.GroupFinder; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncMembership; + +/** + * + */ +public class GuiGcGrouperSyncMembership { + + private GcGrouperSyncMembership gcGrouperSyncMembership; + + /** + * @param gcGrouperSyncMembership + */ + public GuiGcGrouperSyncMembership(GcGrouperSyncMembership gcGrouperSyncMembership) { + this.gcGrouperSyncMembership = gcGrouperSyncMembership; + } + + /** + * @return gcGrouperSyncMembership + */ + public GcGrouperSyncMembership getGcGrouperSyncMembership() { + return gcGrouperSyncMembership; + } + + /** + * @param gcGrouperSyncMembership + */ + public void setGcGrouperSyncMembership(GcGrouperSyncMembership gcGrouperSyncMembership) { + this.gcGrouperSyncMembership = gcGrouperSyncMembership; + } + + /** + * start label string yyyy/MM/dd h:mm a + * @return the start label string yyyy/MM/dd h:mm:ss a + */ + public String getInTargetStartLabel() { + + if (this.gcGrouperSyncMembership == null) { + return null; + } + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd h:mm:ss a"); + + return simpleDateFormat.format(gcGrouperSyncMembership.getInTargetStart()); + } + + /** + * end label string yyyy/MM/dd h:mm a + * @return the end label string yyyy/MM/dd h:mm:ss a + */ + public String getInTargetEndLabel() { + + if (this.gcGrouperSyncMembership == null) { + return null; + } + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd h:mm:ss a"); + + return simpleDateFormat.format(gcGrouperSyncMembership.getInTargetEnd()); + } + + /** + * @return provisioner name + */ + public String getProvisionerName() { + if (this.gcGrouperSyncMembership == null) { + return null; + } + + return gcGrouperSyncMembership.getGrouperSync().getProvisionerName(); + } + + /** + * @return link if available otherwise name + */ + public String getGroupLinkOrName() { + Group group = GroupFinder.findByUuid(this.gcGrouperSyncMembership.getGrouperSyncGroup().getGroupId(), false); + if (group == null) { + // just return the name, there's no link + return this.gcGrouperSyncMembership.getGrouperSyncGroup().getGroupName(); + } + + return new GuiGroup(group).getLink(); + } +} diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiMembershipSubjectContainer.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiMembershipSubjectContainer.java index d30416e75803..c15c7382267f 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiMembershipSubjectContainer.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiMembershipSubjectContainer.java @@ -12,15 +12,29 @@ import org.apache.commons.lang.StringUtils; +import edu.internet2.middleware.grouper.GrouperSession; +import edu.internet2.middleware.grouper.Member; +import edu.internet2.middleware.grouper.MemberFinder; import edu.internet2.middleware.grouper.Membership; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningAttributeValue; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningService; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningSettings; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningTarget; +import edu.internet2.middleware.grouper.exception.GrouperSessionException; +import edu.internet2.middleware.grouper.grouperUi.beans.ui.GrouperRequestContainer; import edu.internet2.middleware.grouper.grouperUi.beans.ui.TextContainer; import edu.internet2.middleware.grouper.membership.MembershipResult; import edu.internet2.middleware.grouper.membership.MembershipSubjectContainer; +import edu.internet2.middleware.grouper.misc.GrouperObject; +import edu.internet2.middleware.grouper.misc.GrouperSessionHandler; import edu.internet2.middleware.grouper.privs.AccessPrivilege; import edu.internet2.middleware.grouper.privs.AttributeDefPrivilege; import edu.internet2.middleware.grouper.privs.NamingPrivilege; import edu.internet2.middleware.grouper.privs.Privilege; +import edu.internet2.middleware.grouper.privs.PrivilegeHelper; +import edu.internet2.middleware.grouper.ui.GrouperUiFilter; import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.subject.Subject; /** @@ -291,4 +305,61 @@ public Map> getAllGuiMemberships() { public void setAllGuiMemberships(Map> allGuiMemberships) { this.allGuiMemberships = allGuiMemberships; } + + public boolean isCanReadProvisioningForMembership() { + + Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn(); + + if (PrivilegeHelper.isWheelOrRootOrViewonlyRoot(loggedInSubject)) { + return true; + } + + if (guiGroup != null && guiMember != null) { +// if (!GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupContainer().isCanRead()) { +// return false; +// } +// +// Member member = (Member)GrouperSession.internal_callbackRootGrouperSession(new GrouperSessionHandler() { +// +// @Override +// public Object callback(GrouperSession theGrouperSession) throws GrouperSessionException { +// return MemberFinder.findBySubject(theGrouperSession, loggedInSubject, true); +// +// } +// }); +// + List provisioningAttributeValues = GrouperProvisioningService.getProvisioningAttributeValues(guiGroup.getGroup(), guiMember.getMember()); + + boolean canViewProvisioningMenu = canViewProvisioningMenu(provisioningAttributeValues, loggedInSubject, null); + if (canViewProvisioningMenu) { + return true; + } + + return false; + } + + return false; + + } + + private boolean canViewProvisioningMenu(List provisioningAttributeValues, Subject loggedInSubject, GrouperObject grouperObject) { + + Map targets = GrouperProvisioningSettings.getTargets(true); + + // out of all the provisioners that have been configured on this group/stem/subject/membership, if one of them is viewable by the logged in user + // we need to show the Provisioning option in the menu item + + for(GrouperProvisioningAttributeValue provisioningAttributeValue: provisioningAttributeValues) { + + String localTargetName = provisioningAttributeValue.getTargetName(); + GrouperProvisioningTarget provisioningTarget = targets.get(localTargetName); + if (provisioningTarget != null && GrouperProvisioningService.isTargetViewable(provisioningTarget, loggedInSubject, grouperObject)) { + return true; + } + + } + + return false; + } + } diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiPITGroup.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiPITGroup.java new file mode 100644 index 000000000000..ab8243fe738d --- /dev/null +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiPITGroup.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright 2019 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +package edu.internet2.middleware.grouper.grouperUi.beans.api; + +import edu.internet2.middleware.grouper.Group; +import edu.internet2.middleware.grouper.GroupFinder; +import edu.internet2.middleware.grouper.pit.PITGroup; + + +/** + * gui wrapper around pit group + */ +public class GuiPITGroup { + + + /** + * @param thePITGroup + */ + public GuiPITGroup(PITGroup thePITGroup) { + this.pitGroup = thePITGroup; + } + + /** + * pit group + */ + private PITGroup pitGroup; + + /** + * pit group + * @return pit group + */ + public PITGroup getPITGroup() { + return this.pitGroup; + } + + /** + * @return link if available otherwise name + */ + public String getLinkOrName() { + Group group = GroupFinder.findByUuid(this.pitGroup.getSourceId(), false); + if (group == null) { + // just return the name, there's no link for the pit group + return this.pitGroup.getName(); + } + + return new GuiGroup(group).getLink(); + } +} \ No newline at end of file diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiPITMembershipView.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiPITMembershipView.java index ba9834e4d580..d444a8b4bd66 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiPITMembershipView.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/api/GuiPITMembershipView.java @@ -26,7 +26,6 @@ import edu.internet2.middleware.grouper.misc.GrouperDAOFactory; import edu.internet2.middleware.grouper.pit.PITGroup; import edu.internet2.middleware.grouper.pit.PITMembershipView; -import edu.internet2.middleware.grouper.pit.finder.PITGroupFinder; /** @@ -86,6 +85,8 @@ public GuiPITMembershipView(PITMembershipView theMembership) { private PITMembershipView membership; private GuiSubject guiSubject; + + private String memberId; /** * membership @@ -136,4 +137,18 @@ public GuiSubject getGuiSubject() { public void setGuiSubject(GuiSubject guiSubject) { this.guiSubject = guiSubject; } + + /** + * @return memberId + */ + public String getMemberId() { + return memberId; + } + + /** + * @param memberId + */ + public void setMemberId(String memberId) { + this.memberId = memberId; + } } \ No newline at end of file diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/tree/DojoTreeItem.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/tree/DojoTreeItem.java index a2c9fd3156d5..cc328f0c9298 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/tree/DojoTreeItem.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/tree/DojoTreeItem.java @@ -26,7 +26,7 @@ public class DojoTreeItem { * @param args */ public static void main(String[] args) { - DojoTreeItem root = new DojoTreeItem("Root", "root", DojoTreeItemType.stem); + DojoTreeItem root = new DojoTreeItem("Root", "root", DojoTreeItemType.stem, true); DojoTreeItemChild child1 = new DojoTreeItemChild("Child1", "child1", DojoTreeItemType.group, true); DojoTreeItemChild child2 = new DojoTreeItemChild("Child2", "child2", DojoTreeItemType.stem, null); root.setChildren(new DojoTreeItemChild[]{child1, child2}); @@ -42,12 +42,14 @@ public static void main(String[] args) { * @param hasChildren * @param children * @param dojoTreeItemType + * @param root */ - public DojoTreeItem(String name, String id, DojoTreeItemType dojoTreeItemType) { + public DojoTreeItem(String name, String id, DojoTreeItemType dojoTreeItemType, boolean root) { super(); this.name = name; this.id = id; this.assignTheTypeEnum(dojoTreeItemType); + this.root = root; } /** @@ -75,6 +77,9 @@ public DojoTreeItem() { /** if group or folder */ private String theType = null; + + /** if this is the root in the tree */ + private boolean root = false; /** * what displays on the screen, display extension @@ -148,6 +153,17 @@ public void assignTheTypeEnum(DojoTreeItemType dojoTreeItemChildType1) { this.theType = dojoTreeItemChildType1 == null ? null : dojoTreeItemChildType1.name(); } - - + /** + * @return if this is the root folder + */ + public boolean isRoot() { + return root; + } + + /** + * @param root + */ + public void setRoot(boolean root) { + this.root = root; + } } diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/GrouperTemplatePolicyGroupLogic.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/GrouperTemplatePolicyGroupLogic.java index eee62b79dc19..a64ff3755c33 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/GrouperTemplatePolicyGroupLogic.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/GrouperTemplatePolicyGroupLogic.java @@ -262,9 +262,9 @@ public List getServiceActions() { String baseGroupFriendlyName = templateContainer.getTemplateFriendlyName(); // GRP-3559: Refactor UI templates to not depend on the UI - // Mystery how this works. Adding an EL variable stemTemplateContainer makes ${grouperRequestContainer.stemTemplateContainer} - // evaluate to stemTemplateContainer, even when grouperRequestContainer is null - GrouperTextContainer.assignThreadLocalVariable("stemTemplateContainer", templateContainer); + // Mystery how this works. Adding an EL variable groupStemTemplateContainer makes ${grouperRequestContainer.groupStemTemplateContainer} + // evaluate to groupStemTemplateContainer, even when grouperRequestContainer is null + GrouperTextContainer.assignThreadLocalVariable("groupStemTemplateContainer", templateContainer); if (StringUtils.isBlank(baseGroupFriendlyName)) { baseGroupFriendlyName = baseGroup; diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/GuiAuditEntry.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/GuiAuditEntry.java index 2114676b0016..61964125112a 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/GuiAuditEntry.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/GuiAuditEntry.java @@ -359,6 +359,17 @@ public String getGuiDate() { return guiDateFormat.format(this.auditEntry.getCreatedOn()); } + /** + * audit date string, format based on ui property uiV2.audit.dateFormatWithSeconds + * @return formatted audit entry date + */ + public String getGuiDateWithSeconds() { + String dateFormat = GrouperUiConfig.retrieveConfig().propertyValueString("uiV2.audit.dateFormatWithSeconds", "yyyy/MM/dd h:mm:ss aa"); + SimpleDateFormat guiDateFormat = new SimpleDateFormat(dateFormat); + + return guiDateFormat.format(this.auditEntry.getCreatedOn()); + } + /** * underlying audit entry */ @@ -1261,6 +1272,20 @@ private void setupMember() { this.setGuiMember(guiMember); } + /** + * + */ + public void internal_setupMember() { + setupMember(); + } + + /** + * + */ + public void internal_setupGroup() { + setupGroup(); + } + /** * setup privilege */ diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/MembershipGuiContainer.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/MembershipGuiContainer.java index 0d467437e3c3..fd32e6be18af 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/MembershipGuiContainer.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/MembershipGuiContainer.java @@ -15,14 +15,18 @@ ******************************************************************************/ package edu.internet2.middleware.grouper.grouperUi.beans.ui; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; import java.util.Set; import edu.internet2.middleware.grouper.Field; import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiAttributeAssign; import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiAttributeDef; +import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiGcGrouperSyncMembership; import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiGroup; import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiMembership; import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiMembershipSubjectContainer; +import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiPITGroup; import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiStem; @@ -245,6 +249,73 @@ public boolean isTraceMembershipFromSubject() { public void setTraceMembershipFromSubject(boolean traceMembershipFromSubject1) { this.traceMembershipFromSubject = traceMembershipFromSubject1; } + + /** + * if should show user audit + */ + private boolean traceMembershipTimelineShowUserAudit = true; + + /** + * if should show pit audit + */ + private boolean traceMembershipTimelineShowPITAudit = true; + + /** + * if should show provisioning events + */ + private boolean traceMembershipTimelineShowProvisioningEvents = true; + + + /** + * if should show provisioning events + * @return traceMembershipTimelineShowProvisioningEvents + */ + public boolean isTraceMembershipTimelineShowProvisioningEvents() { + return traceMembershipTimelineShowProvisioningEvents; + } + + /** + * if should show provisioning events + * @param traceMembershipTimelineShowProvisioningEvents + */ + public void setTraceMembershipTimelineShowProvisioningEvents( + boolean traceMembershipTimelineShowProvisioningEvents) { + this.traceMembershipTimelineShowProvisioningEvents = traceMembershipTimelineShowProvisioningEvents; + } + + /** + * if should show user audit + * @return traceMembershipTimelineShowUserAudit + */ + public boolean isTraceMembershipTimelineShowUserAudit() { + return traceMembershipTimelineShowUserAudit; + } + + /** + * if should show user audit + * @param traceMembershipTimelineShowUserAudit + */ + public void setTraceMembershipTimelineShowUserAudit( + boolean traceMembershipTimelineShowUserAudit) { + this.traceMembershipTimelineShowUserAudit = traceMembershipTimelineShowUserAudit; + } + + /** + * if should show pit audit + * @return traceMembershipTimelineShowPITAudit + */ + public boolean isTraceMembershipTimelineShowPITAudit() { + return traceMembershipTimelineShowPITAudit; + } + + /** + * if should show pit audit + * @param traceMembershipTimelineShowPITAudit + */ + public void setTraceMembershipTimelineShowPITAudit( + boolean traceMembershipTimelineShowPITAudit) { + this.traceMembershipTimelineShowPITAudit = traceMembershipTimelineShowPITAudit; + } /** * line number of trace starting with 0 @@ -406,6 +477,48 @@ public String getTraceMembershipsString() { public void setTraceMembershipsString(String traceMembershipsString1) { this.traceMembershipsString = traceMembershipsString1; } + + /** + * string of membership timeline + */ + private String traceMembershipTimelineString; + + + /** + * @return string of membership timeline + */ + public String getTraceMembershipTimelineString() { + return traceMembershipTimelineString; + } + + /** + * string of membership timeline + * @param traceMembershipTimelineString + */ + public void setTraceMembershipTimelineString(String traceMembershipTimelineString) { + this.traceMembershipTimelineString = traceMembershipTimelineString; + } + + /** + * string of trace pit membership + */ + private String tracePITMembershipString; + + /** + * string of trace pit membership + * @return trace pit membership + */ + public String getTracePITMembershipString() { + return this.tracePITMembershipString; + } + + /** + * string of trace pit membership + * @param tracePITMembershipString1 + */ + public void setTracePITMembershipString(String tracePITMembershipString1) { + this.tracePITMembershipString = tracePITMembershipString1; + } /** @@ -471,4 +584,94 @@ public void setGuiAttributeAssigns(Set guiAttributeAssigns) this.guiAttributeAssigns = guiAttributeAssigns; } + /** + * current gui pit group e.g. when tracing memberships + */ + private GuiPITGroup guiPITGroupCurrent; + + + /** + * current gui pit group e.g. when tracing memberships + * @return gui pit group + */ + public GuiPITGroup getGuiPITGroupCurrent() { + return this.guiPITGroupCurrent; + } + + /** + * current gui pit group e.g. when tracing memberships + * @param guiPITGroupCurrent1 + */ + public void setGuiPITGroupCurrent(GuiPITGroup guiPITGroupCurrent1) { + this.guiPITGroupCurrent = guiPITGroupCurrent1; + } + + /** + * current gui audit date + */ + private Timestamp guiAuditDateCurrent; + + /** + * current gui audit date + * @return timestamp + */ + public Timestamp getGuiAuditDateCurrent() { + return guiAuditDateCurrent; + } + + /** + * current gui audit date + * @param guiAuditDateCurrent + */ + public void setGuiAuditDateCurrent(Timestamp guiAuditDateCurrent) { + this.guiAuditDateCurrent = guiAuditDateCurrent; + } + + /** + * audit label string yyyy/MM/dd h:mm a + * @return the audit label string yyyy/MM/dd h:mm:ss a + */ + public String getGuiAuditDateLabelCurrent() { + + if (this.guiAuditDateCurrent == null) { + return null; + } + + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd h:mm:ss a"); + + return simpleDateFormat.format(guiAuditDateCurrent); + } + + private GuiAuditEntry guiAuditEntryCurrent; + + /** + * @return current gui audit entry + */ + public GuiAuditEntry getGuiAuditEntryCurrent() { + return guiAuditEntryCurrent; + } + + /** + * @param guiAuditEntryCurrent + */ + public void setGuiAuditEntryCurrent(GuiAuditEntry guiAuditEntryCurrent) { + this.guiAuditEntryCurrent = guiAuditEntryCurrent; + } + + private GuiGcGrouperSyncMembership guiGcGrouperSyncMembershipCurrent; + + /** + * @return current gui GcGrouperSyncMembership + */ + public GuiGcGrouperSyncMembership getGuiGcGrouperSyncMembershipCurrent() { + return guiGcGrouperSyncMembershipCurrent; + } + + /** + * @param guiGcGrouperSyncMembershipCurrent + */ + public void setGuiGcGrouperSyncMembershipCurrent( + GuiGcGrouperSyncMembership guiGcGrouperSyncMembershipCurrent) { + this.guiGcGrouperSyncMembershipCurrent = guiGcGrouperSyncMembershipCurrent; + } } diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/ProvisionerConfigurationContainer.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/ProvisionerConfigurationContainer.java index bc52900b0560..cb9e281ada8c 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/ProvisionerConfigurationContainer.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/ProvisionerConfigurationContainer.java @@ -3,14 +3,11 @@ import java.util.ArrayList; import java.util.List; -import org.apache.commons.lang.StringUtils; - import edu.internet2.middleware.grouper.app.provisioning.ProvisionerStartWithBase; import edu.internet2.middleware.grouper.app.provisioning.ProvisioningConfiguration; import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiPaging; import edu.internet2.middleware.grouper.privs.PrivilegeHelper; import edu.internet2.middleware.grouper.ui.GrouperUiFilter; -import edu.internet2.middleware.grouper.util.GrouperUtil; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncGroup; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncJob; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncMember; @@ -273,10 +270,10 @@ public String getCacheFieldPrefix() { private ProvisionerStartWithBase provisionerStartWith; + private boolean blankStartWithSelected; + private boolean showStartWithSection; - private ProvisionerStartWithBase previousProvisionerStartWith; - private String startWithSessionId; public String getCurrentConfigSuffix() { @@ -326,22 +323,23 @@ public void setShowStartWithSection(boolean showStartWithSection) { this.showStartWithSection = showStartWithSection; } - public void setPreviousProvisionerStartWith(ProvisionerStartWithBase previousProvisionerStartWith) { - this.previousProvisionerStartWith = previousProvisionerStartWith; + public void setStartWithSessionId(String startWithSessionId) { + this.startWithSessionId = startWithSessionId; } - public ProvisionerStartWithBase getPreviousProvisionerStartWith() { - return previousProvisionerStartWith; + public String getStartWithSessionId() { + return startWithSessionId; } - public void setStartWithSessionId(String startWithSessionId) { - this.startWithSessionId = startWithSessionId; + + public boolean isBlankStartWithSelected() { + return blankStartWithSelected; } - public String getStartWithSessionId() { - return startWithSessionId; + public void setBlankStartWithSelected(boolean blankStartWithSelected) { + this.blankStartWithSelected = blankStartWithSelected; } @@ -351,4 +349,5 @@ public String getStartWithSessionId() { + } diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/ProvisioningContainer.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/ProvisioningContainer.java index af007a2000df..32748b0f1737 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/ProvisioningContainer.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/ProvisioningContainer.java @@ -12,18 +12,28 @@ import org.apache.commons.lang3.StringUtils; +import edu.internet2.middleware.grouper.GrouperSession; +import edu.internet2.middleware.grouper.Member; +import edu.internet2.middleware.grouper.MemberFinder; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioner; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningAttributeValue; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningObjectMetadataItem; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningService; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningSettings; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningTarget; +import edu.internet2.middleware.grouper.exception.GrouperSessionException; import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiGroup; import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiStem; +import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiSubject; import edu.internet2.middleware.grouper.grouperUi.beans.api.provisioning.GuiGrouperProvisioningAttributeValue; import edu.internet2.middleware.grouper.grouperUi.beans.api.provisioning.GuiGrouperSyncObject; import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiPaging; +import edu.internet2.middleware.grouper.grouperUi.serviceLogic.UiV2Group; +import edu.internet2.middleware.grouper.grouperUi.serviceLogic.UiV2Stem; import edu.internet2.middleware.grouper.misc.GrouperObject; +import edu.internet2.middleware.grouper.misc.GrouperSessionHandler; +import edu.internet2.middleware.grouper.privs.AccessPrivilege; +import edu.internet2.middleware.grouper.privs.NamingPrivilege; import edu.internet2.middleware.grouper.privs.PrivilegeHelper; import edu.internet2.middleware.grouper.ui.GrouperUiFilter; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncGroup; @@ -214,52 +224,163 @@ public List getGuiGrouperProvisioningAttri public void setGuiGrouperProvisioningAttributeValues(List guiGrouperProvisioningAttributeValues) { this.guiGrouperProvisioningAttributeValues = guiGrouperProvisioningAttributeValues; } + + private boolean canViewProvisioningMenu(List provisioningAttributeValues, Subject loggedInSubject, GrouperObject grouperObject) { - /** - * - * @return true if can read - */ - public boolean isCanReadProvisioning() { + Map targets = GrouperProvisioningSettings.getTargets(true); + + // out of all the provisioners that have been configured on this group/stem/subject/membership, if one of them is viewable by the logged in user + // we need to show the Provisioning option in the menu item + + for(GrouperProvisioningAttributeValue provisioningAttributeValue: provisioningAttributeValues) { + + String localTargetName = provisioningAttributeValue.getTargetName(); + GrouperProvisioningTarget provisioningTarget = targets.get(localTargetName); + if (provisioningTarget != null && GrouperProvisioningService.isTargetViewable(provisioningTarget, loggedInSubject, grouperObject)) { + return true; + } + + } + + return false; + } + + + public boolean isCanReadProvisioningForMembership() { Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn(); - if (PrivilegeHelper.isWheelOrRoot(loggedInSubject)) { + + if (PrivilegeHelper.isWheelOrRootOrViewonlyRoot(loggedInSubject)) { return true; } + + GuiGroup guiGroup = GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupContainer().getGuiGroup(); + GuiSubject guiSubject = GrouperRequestContainer.retrieveFromRequestOrCreate().getSubjectContainer().getGuiSubject(); -// Boolean allowedInProvisioningGroup = null; -// if (!StringUtils.isBlank(GrouperUiConfig.retrieveConfig().propertyValueString("uiV2.provisioning.must.be.in.group"))) { -// String error = GrouperUiFilter.requireUiGroup("uiV2.provisioning.must.be.in.group", loggedInSubject, false); -// //null error means allow -// allowedInProvisioningGroup = ( error == null ); -// } -// -// GuiGroup guiGroup = GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupContainer().getGuiGroup(); -// -// if (guiGroup != null) { -// if (!GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupContainer().isCanRead()) { -// return false; -// } -// if (allowedInProvisioningGroup != null) { -// return allowedInProvisioningGroup; -// } -// return true; -// } -// -// GuiStem guiStem = GrouperRequestContainer.retrieveFromRequestOrCreate().getStemContainer().getGuiStem(); -// -// if (guiStem != null) { -// if (!GrouperRequestContainer.retrieveFromRequestOrCreate().getStemContainer().isCanAdminPrivileges()) { -// return false; -// } -// if (allowedInProvisioningGroup != null) { -// return allowedInProvisioningGroup; -// } -// return true; -// } + if (guiGroup != null && guiSubject != null) { + if (!GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupContainer().isCanRead()) { + return false; + } + + Member member = (Member)GrouperSession.internal_callbackRootGrouperSession(new GrouperSessionHandler() { + + @Override + public Object callback(GrouperSession theGrouperSession) throws GrouperSessionException { + return MemberFinder.findBySubject(theGrouperSession, guiSubject.getSubject(), true); + + } + }); + + List provisioningAttributeValues = GrouperProvisioningService.getProvisioningAttributeValues(guiGroup.getGroup(), member); + + boolean canViewProvisioningMenu = canViewProvisioningMenu(provisioningAttributeValues, loggedInSubject, null); + if (canViewProvisioningMenu) { + return true; + } + + return false; + } return false; + } + public boolean isCanReadProvisioningForGroup() { + + Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn(); + + if (PrivilegeHelper.isWheelOrRootOrViewonlyRoot(loggedInSubject)) { + return true; + } + + GuiGroup guiGroup = GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupContainer().getGuiGroup(); + + if (guiGroup != null) { + if (!GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupContainer().isCanView()) { + return false; + } + + List provisioningAttributeValues = GrouperProvisioningService.getProvisioningAttributeValues(guiGroup.getGroup()); + boolean canViewProvisioningMenu = canViewProvisioningMenu(provisioningAttributeValues, loggedInSubject, null); + if (canViewProvisioningMenu) { + return true; + } + + return false; + } + + return false; + + } + + public boolean isCanReadProvisioningForSubject() { + + Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn(); + + if (PrivilegeHelper.isWheelOrRootOrViewonlyRoot(loggedInSubject)) { + return true; + } + + GuiSubject guiSubject = GrouperRequestContainer.retrieveFromRequestOrCreate().getSubjectContainer().getGuiSubject(); + + if (guiSubject != null) { + + Member member = (Member)GrouperSession.internal_callbackRootGrouperSession(new GrouperSessionHandler() { + + @Override + public Object callback(GrouperSession theGrouperSession) throws GrouperSessionException { + + return MemberFinder.findBySubject(theGrouperSession, guiSubject.getSubject(), true); + + } + }); + + if (member != null) { + List provisioningAttributeValues = GrouperProvisioningService.getProvisioningAttributeValues(member); + boolean canViewProvisioningMenu = canViewProvisioningMenu(provisioningAttributeValues, loggedInSubject, null); + + if (canViewProvisioningMenu) { + return true; + } + } + + + return false; + } + + return false; + + } + + public boolean isCanReadProvisioningForStem() { + + Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn(); + + if (PrivilegeHelper.isWheelOrRootOrViewonlyRoot(loggedInSubject)) { + return true; + } + + GuiStem guiStem = GrouperRequestContainer.retrieveFromRequestOrCreate().getStemContainer().getGuiStem(); + + if (guiStem != null) { + + if (!GrouperRequestContainer.retrieveFromRequestOrCreate().getStemContainer().isCanViewPrivileges()) { + return false; + } + + List provisioningAttributeValues = GrouperProvisioningService.getProvisioningAttributeValues(guiStem.getStem()); + boolean canViewProvisioningMenu = canViewProvisioningMenu(provisioningAttributeValues, loggedInSubject, guiStem.getStem()); + if (canViewProvisioningMenu) { + return true; + } + + return false; + } + + return false; + + } + /** * * @return true if can write @@ -381,6 +502,38 @@ public Set getEditableTargets() { return editableTargets; } + /** + * get viewable targets for current group/stem and logged in subject + * @return + */ + public Set getViewableTargets() { + + GrouperObject grouperObject = null; + + GuiGroup guiGroup = GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupContainer().getGuiGroup(); + GuiStem guiStem = GrouperRequestContainer.retrieveFromRequestOrCreate().getStemContainer().getGuiStem(); + + if (guiGroup != null) { + grouperObject = guiGroup.getGrouperObject(); + } + if (guiStem != null) { + grouperObject = guiStem.getGrouperObject(); + } + + Map targets = GrouperProvisioningSettings.getTargets(true); + Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn(); + + Set viewableTargets = new HashSet(); + + for (GrouperProvisioningTarget target: targets.values()) { + if (GrouperProvisioningService.isTargetViewable(target, loggedInSubject, grouperObject)) { + viewableTargets.add(target); + } + } + + return viewableTargets; + } + /** * number of groups in a folder for a provisioner target * @return diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/StemContainer.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/StemContainer.java index 54c5b04b96f9..031edb7d7f8b 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/StemContainer.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/beans/ui/StemContainer.java @@ -278,6 +278,11 @@ public Object callback(GrouperSession grouperSession) throws GrouperSessionExcep */ private Boolean canAdminPrivileges; + /** + * if the logged in user can view privileges, lazy loaded + */ + private Boolean canViewPrivileges; + /** * if the logged in user can read attributes, lazy loaded * @return if can read attributes @@ -351,6 +356,30 @@ public Object callback(GrouperSession grouperSession) throws GrouperSessionExcep return this.canAdminPrivileges; } + + /** + * if the logged in user can view privileges, lazy loaded + * @return if can view privileges + */ + public boolean isCanViewPrivileges() { + + if (this.canViewPrivileges == null) { + + final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn(); + + this.canViewPrivileges = (Boolean)GrouperSession.callbackGrouperSession( + GrouperSession.staticGrouperSession().internal_getRootSession(), new GrouperSessionHandler() { + + @Override + public Object callback(GrouperSession grouperSession) throws GrouperSessionException { + return StemContainer.this.getGuiStem().getStem().canHavePrivilege(loggedInSubject, NamingPrivilege.STEM_VIEW.getName(), false); + } + }); + + } + + return this.canViewPrivileges; + } /** * subjects and what privs they have on this stem diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Admin.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Admin.java index 469436666b5f..67b0c1ddd908 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Admin.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Admin.java @@ -282,7 +282,15 @@ public void daemonJobsSubmit(HttpServletRequest request, HttpServletResponse res GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs(); - guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#daemonJobsResultsId", "/WEB-INF/grouperUi2/admin/adminDaemonJobsContents.jsp")); + String source = request.getParameter("source"); + if (StringUtils.equals(source, "logs")) { + guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#grouperMainContentDivId", + "/WEB-INF/grouperUi2/admin/adminDaemonJobsViewLogs.jsp")); + viewLogsHelper(request, response); + } else { + guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#daemonJobsResultsId", "/WEB-INF/grouperUi2/admin/adminDaemonJobsContents.jsp")); + } + } finally { @@ -320,8 +328,10 @@ private boolean daemonJobsHelper(HttpServletRequest request, HttpServletResponse scheduler.triggerJob(jobKey); } else if ("disable".equals(action)) { scheduler.pauseJob(jobKey); + guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.success, TextContainer.retrieveFromRequest().getText().get("daemonJobDisabledSuccess"))); } else if ("enable".equals(action)) { scheduler.resumeJob(jobKey); + guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.success, TextContainer.retrieveFromRequest().getText().get("daemonJobEnabledSuccess"))); } else if ("failsafeApprove".equals(action)) { GrouperFailsafe.assignApproveNextRun(jobName); guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.success, TextContainer.retrieveFromRequest().getText().get("failsafeApproved"))); @@ -336,6 +346,16 @@ private boolean daemonJobsHelper(HttpServletRequest request, HttpServletResponse AdminContainer adminContainer = GrouperRequestContainer.retrieveFromRequestOrCreate().getAdminContainer(); List guiDaemonJobs = new ArrayList(); + + // action was taken from logs screen + String source = request.getParameter("source"); + if (StringUtils.equals(source, "logs")) { + String jobName = request.getParameter("jobName"); + GuiDaemonJob guiDaemonJob = new GuiDaemonJob(jobName); + guiDaemonJobs.add(guiDaemonJob); + adminContainer.setGuiDaemonJobs(guiDaemonJobs); + return true; + } String daemonJobsFilter = StringUtils.trimToEmpty(request.getParameter("daemonJobsFilter")); adminContainer.setDaemonJobsFilter(daemonJobsFilter); diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2AttributeDef.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2AttributeDef.java index c53731368dd7..98f7a8156777 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2AttributeDef.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2AttributeDef.java @@ -390,7 +390,7 @@ public void viewAttributeDef(HttpServletRequest request, HttpServletResponse res * @param request * @param response */ - private void filterHelper(HttpServletRequest request, HttpServletResponse response, AttributeDef attributeDef) { + public static void filterHelper(HttpServletRequest request, HttpServletResponse response, AttributeDef attributeDef) { GrouperRequestContainer grouperRequestContainer = GrouperRequestContainer.retrieveFromRequestOrCreate(); GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs(); diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2AttributeDefName.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2AttributeDefName.java index 10a2d0cf4d4c..a1039a1d56be 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2AttributeDefName.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2AttributeDefName.java @@ -168,7 +168,7 @@ public void deleteAttributeDefName(HttpServletRequest request, HttpServletRespon * @param request * @param response */ - public void deleteAttributeDefNamesSubmit(HttpServletRequest request, HttpServletResponse response) { + public void deleteAttributeDefNames(HttpServletRequest request, HttpServletResponse response) { final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn(); @@ -236,6 +236,9 @@ public void deleteAttributeDefNamesSubmit(HttpServletRequest request, HttpServle GrouperRequestContainer.retrieveFromRequestOrCreate().getAttributeDefContainer().setSuccessCount(successes); GrouperRequestContainer.retrieveFromRequestOrCreate().getAttributeDefContainer().setFailureCount(failures); + UiV2AttributeDef.filterHelper(request, response, attributeDef); + //guiResponseJs.addAction(GuiScreenAction.newScript("guiV2link('operation=UiV2AttributeDef.viewAttributeDef&attributeDefId=" + attributeDef.getId() + "')")); + if (failures > 0) { guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.error, TextContainer.retrieveFromRequest().getText().get("attributeDefDeleteAttributeDefNamesErrors"))); @@ -244,9 +247,6 @@ public void deleteAttributeDefNamesSubmit(HttpServletRequest request, HttpServle TextContainer.retrieveFromRequest().getText().get("attributeDefDeleteAttributeDefNamesSuccesses"))); } - - //filterHelper(request, response, attributeDef); - GrouperUserDataApi.recentlyUsedAttributeDefAdd(GrouperUiUserData.grouperUiGroupNameForUserData(), loggedInSubject, attributeDef); @@ -1805,39 +1805,6 @@ public void removeFromMyFavorites(HttpServletRequest request, HttpServletRespons } - /** - * delete an attribute def name (show confirm screen) - * @param request - * @param response - */ - public void deleteAttributeDefNames(HttpServletRequest request, HttpServletResponse response) { - - final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn(); - - GrouperSession grouperSession = null; - - try { - - grouperSession = GrouperSession.start(loggedInSubject); - - AttributeDefName attributeDefName = null; - - attributeDefName = retrieveAttributeDefNameHelper(request, AttributeDefPrivilege.ATTR_ADMIN, true).getAttributeDefName(); - - if (attributeDefName == null) { - return; - } - - GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs(); - - guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#grouperMainContentDivId", - "/WEB-INF/grouperUi2/attributeDefName/attributeDefNamesDelete.jsp")); - - } finally { - GrouperSession.stopQuietly(grouperSession); - } - } - /** * show attribute def name inheritance screen * @param request diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Group.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Group.java index da5138739ecb..1420810bc896 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Group.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Group.java @@ -442,7 +442,11 @@ public void removeMembersForThisGroupsMemberships(HttpServletRequest request, Ht Subject groupSubject = group.toSubject(); for (String membershipId : membershipsIds) { try { - Membership membership = new MembershipFinder().addMembershipId(membershipId).findMembership(true); + Membership membership = new MembershipFinder().addMembershipId(membershipId).findMembership(false); + + if (membership == null) { + continue; + } Group ownerGroup = membership.getOwnerGroup(); //dont worry about if no change, thats a success ownerGroup.deleteMember(groupSubject, false); @@ -637,6 +641,7 @@ private void filterHelper(HttpServletRequest request, HttpServletResponse respon String memberId = pitMembershipView.getPITMember().getSourceId(); Subject subject = memberIdToSubject.get(memberId); guiPITMembershipView.setGuiSubject(new GuiSubject(subject)); + guiPITMembershipView.setMemberId(memberId); guiPITMembershipViews.add(guiPITMembershipView); } @@ -3025,8 +3030,11 @@ public void removeMembers(HttpServletRequest request, HttpServletResponse respon public Object callback(GrouperSession grouperSession2) throws GrouperSessionException { for (String membershipId : membershipsIds) { try { - Membership membership = new MembershipFinder().addMembershipId(membershipId).findMembership(true); - + Membership membership = new MembershipFinder().addMembershipId(membershipId).findMembership(false); + + if (membership == null) { + continue; + } Member member = membership.getMember(); group.deleteMember(member, false); diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2GrouperLoader.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2GrouperLoader.java index 69abc0d85c66..ad7de428892d 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2GrouperLoader.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2GrouperLoader.java @@ -1757,7 +1757,11 @@ public void editGrouperLoader(HttpServletRequest request, HttpServletResponse re grouperLoaderContainer.setEditLoaderRecentGroupUuidFrom(grouperLoaderContainer.getRecentGroupUuidFrom()); grouperLoaderContainer.setEditLoaderRecentDays(grouperLoaderContainer.getRecentDays()); - grouperLoaderContainer.setEditLoaderRecentIncludeCurrent(grouperLoaderContainer.getEditLoaderRecentIncludeCurrent()); + if (GrouperUtil.booleanValue(grouperLoaderContainer.getRecentIncludeCurrent(), true)) { + grouperLoaderContainer.setEditLoaderRecentIncludeCurrent("true"); + } else { + grouperLoaderContainer.setEditLoaderRecentIncludeCurrent("false"); + } } else if (StringUtils.equals("JEXL_SCRIPT", grouperLoaderContainer.getEditLoaderType())) { diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Main.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Main.java index 7ecda2855ec2..f145199795d6 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Main.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Main.java @@ -321,7 +321,7 @@ public void folderMenu(HttpServletRequest httpServletRequest, HttpServletRespons //the id has to be root or it will make another request String id = stem.isRootStem() ? "root" : stem.getUuid(); - DojoTreeItem dojoTreeItem = new DojoTreeItem(displayExtension, id, DojoTreeItemType.stem); + DojoTreeItem dojoTreeItem = new DojoTreeItem(displayExtension, id, DojoTreeItemType.stem, StringUtils.equals("root", folderQueryString)); DojoTreeItemChild[] childrenDojoTreeItems = new DojoTreeItemChild[GrouperUtil.length(childrenStems) + GrouperUtil.length(childrenGroups) + GrouperUtil.length(childrenAttributeDefs) + GrouperUtil.length(childrenAttributeDefNames)]; diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Membership.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Membership.java index f0fca7477d75..d3324e00d213 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Membership.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Membership.java @@ -15,19 +15,29 @@ ******************************************************************************/ package edu.internet2.middleware.grouper.grouperUi.serviceLogic; +import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; +import org.hibernate.criterion.Criterion; +import org.hibernate.criterion.Restrictions; import edu.internet2.middleware.grouper.Field; import edu.internet2.middleware.grouper.FieldFinder; import edu.internet2.middleware.grouper.FieldType; import edu.internet2.middleware.grouper.Group; +import edu.internet2.middleware.grouper.GroupFinder; import edu.internet2.middleware.grouper.GrouperSession; import edu.internet2.middleware.grouper.Member; import edu.internet2.middleware.grouper.MemberFinder; @@ -35,18 +45,31 @@ import edu.internet2.middleware.grouper.MembershipFinder; import edu.internet2.middleware.grouper.Stem; import edu.internet2.middleware.grouper.SubjectFinder; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningService; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningSettings; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningTarget; import edu.internet2.middleware.grouper.attr.AttributeDef; +import edu.internet2.middleware.grouper.audit.AuditEntry; +import edu.internet2.middleware.grouper.audit.AuditType; +import edu.internet2.middleware.grouper.audit.AuditTypeFinder; +import edu.internet2.middleware.grouper.audit.UserAuditQuery; +import edu.internet2.middleware.grouper.exception.GrouperSessionException; import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiAttributeDef; +import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiGcGrouperSyncMembership; import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiGroup; import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiMembership; import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiMembershipSubjectContainer; +import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiPITGroup; import edu.internet2.middleware.grouper.grouperUi.beans.api.GuiStem; import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiResponseJs; import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiScreenAction; import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiScreenAction.GuiMessageType; import edu.internet2.middleware.grouper.grouperUi.beans.ui.GrouperRequestContainer; +import edu.internet2.middleware.grouper.grouperUi.beans.ui.GuiAuditEntry; import edu.internet2.middleware.grouper.grouperUi.beans.ui.MembershipGuiContainer; import edu.internet2.middleware.grouper.grouperUi.beans.ui.TextContainer; +import edu.internet2.middleware.grouper.hibernate.HibUtils; +import edu.internet2.middleware.grouper.internal.dao.QueryOptions; import edu.internet2.middleware.grouper.membership.MembershipContainer; import edu.internet2.middleware.grouper.membership.MembershipPath; import edu.internet2.middleware.grouper.membership.MembershipPathGroup; @@ -54,13 +77,24 @@ import edu.internet2.middleware.grouper.membership.MembershipResult; import edu.internet2.middleware.grouper.membership.MembershipSubjectContainer; import edu.internet2.middleware.grouper.membership.MembershipType; +import edu.internet2.middleware.grouper.misc.GrouperDAOFactory; +import edu.internet2.middleware.grouper.misc.GrouperSessionHandler; +import edu.internet2.middleware.grouper.pit.PITField; +import edu.internet2.middleware.grouper.pit.PITGroup; +import edu.internet2.middleware.grouper.pit.PITGroupSet; +import edu.internet2.middleware.grouper.pit.PITMember; +import edu.internet2.middleware.grouper.pit.PITMembership; +import edu.internet2.middleware.grouper.pit.PITMembershipView; import edu.internet2.middleware.grouper.privs.AccessPrivilege; import edu.internet2.middleware.grouper.privs.AttributeDefPrivilege; +import edu.internet2.middleware.grouper.privs.PrivilegeHelper; import edu.internet2.middleware.grouper.subj.SubjectHelper; import edu.internet2.middleware.grouper.ui.GrouperUiFilter; +import edu.internet2.middleware.grouper.ui.util.GrouperUiConfig; import edu.internet2.middleware.grouper.ui.util.GrouperUiUserData; import edu.internet2.middleware.grouper.userData.GrouperUserDataApi; import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncMembership; import edu.internet2.middleware.subject.Subject; /** @@ -147,10 +181,6 @@ public void traceMembership(HttpServletRequest request, HttpServletResponse resp final Subject loggedInSubject = GrouperUiFilter.retrieveSubjectLoggedIn(); GrouperSession grouperSession = null; - - Group group = null; - Subject subject = null; - Field field = null; GrouperRequestContainer grouperRequestContainer = GrouperRequestContainer.retrieveFromRequestOrCreate(); @@ -160,13 +190,13 @@ public void traceMembership(HttpServletRequest request, HttpServletResponse resp GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs(); - group = UiV2Group.retrieveGroupHelper(request, AccessPrivilege.READ).getGroup(); + Group group = UiV2Group.retrieveGroupHelper(request, AccessPrivilege.READ).getGroup(); if (group == null) { return; } - subject = UiV2Subject.retrieveSubjectHelper(request, true); + Subject subject = UiV2Subject.retrieveSubjectHelper(request, true); if (subject == null) { return; @@ -182,7 +212,7 @@ public void traceMembership(HttpServletRequest request, HttpServletResponse resp return; } - field = UiV2Membership.retrieveFieldHelper(request, true); + Field field = UiV2Membership.retrieveFieldHelper(request, true); if (field == null) { return; @@ -197,133 +227,754 @@ public void traceMembership(HttpServletRequest request, HttpServletResponse resp if (StringUtils.equalsIgnoreCase(request.getParameter("backTo"), "membership")) { membershipGuiContainer.setTraceMembershipFromMembership(true); } + + membershipGuiContainer.setTraceMembershipTimelineShowUserAudit(GrouperUtil.booleanValue(request.getParameter("showUserAudit"), true)); + membershipGuiContainer.setTraceMembershipTimelineShowPITAudit(GrouperUtil.booleanValue(request.getParameter("showPITAudit"), true)); + membershipGuiContainer.setTraceMembershipTimelineShowProvisioningEvents(GrouperUtil.booleanValue(request.getParameter("showProvisioningEvents"), true)); //this is a subobject grouperRequestContainer.getGroupContainer().getGuiGroup().setShowBreadcrumbLink(true); grouperRequestContainer.getSubjectContainer().getGuiSubject().setShowBreadcrumbLink(true); - MembershipPathGroup membershipPathGroup = MembershipPathGroup.analyze(group, member, field); + // point in time objects + PITGroup pitGroup = GrouperDAOFactory.getFactory().getPITGroup().findBySourceIdActive(group.getId(), false); + PITMember pitMember = GrouperDAOFactory.getFactory().getPITMember().findBySourceIdActive(member.getId(), false); + PITField pitField = GrouperDAOFactory.getFactory().getPITField().findBySourceIdActive(field.getId(), true); - StringBuilder result = new StringBuilder(); + Set pitGroupsForTimelineStates = new LinkedHashSet(); + Set memberIdsForTimelineAuditQuery = new LinkedHashSet(); + memberIdsForTimelineAuditQuery.add(pitMember.getSourceId()); - //massage the paths to only consider the ones that are allowed - int membershipUnallowedCount = 0; - List membershipPathsAllowed = new ArrayList(); - for (MembershipPath membershipPath : GrouperUtil.nonNull(membershipPathGroup.getMembershipPaths())) { - if (membershipPath.isPathAllowed()) { - membershipPathsAllowed.add(membershipPath); - } else { - membershipUnallowedCount++; + MembershipPathGroup membershipPathGroup = MembershipPathGroup.analyze(group, member, field); + traceMembershipHelperCurrent(membershipPathGroup, subject, memberIdsForTimelineAuditQuery, pitGroupsForTimelineStates); + + // this should always be the members field, but check just in case + if (field.getId().equals(Group.getDefaultList().getUuid())) { + + if (GrouperUtil.nonNull(membershipPathGroup.getMembershipPaths()).size() == 0) { + traceMembershipsHelperFormer(pitGroup, pitMember, pitField, memberIdsForTimelineAuditQuery, pitGroupsForTimelineStates); + } + + if (GrouperUtil.booleanValue(request.getParameter("showTimeline"), false)) { + traceMembershipsHelperTimeline(pitMember, pitField, memberIdsForTimelineAuditQuery, pitGroupsForTimelineStates); } } + + guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#grouperMainContentDivId", + "/WEB-INF/grouperUi2/membership/traceMembership.jsp")); - if (membershipUnallowedCount > 0) { - membershipGuiContainer.setPathCountNotAllowed(membershipUnallowedCount); - guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.info, - TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupPathsNotAllowed"))); - } + } finally { + GrouperSession.stopQuietly(grouperSession); + } + + } + + private void traceMembershipsHelperFormer(PITGroup pitGroup, PITMember pitMember, PITField pitField, Set memberIdsForTimelineAuditQuery, Set pitGroupsForTimelineStates) { + + if (pitGroup == null || pitMember == null) { + // not in pit (yet?) + return; + } + + GrouperSession loggedInGrouperSession = GrouperSession.staticGrouperSession(); - if (GrouperUtil.length(membershipPathsAllowed) == 0) { + List endTimes = new ArrayList(); + List memberPITGroups = new ArrayList(); + + boolean proceed = (Boolean)GrouperSession.internal_callbackRootGrouperSession(new GrouperSessionHandler() { - if (membershipUnallowedCount > 0) { - guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.error, - TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupNoPathsAllowed"))); - - } else { - guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.error, - TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupNoPaths"))); - + @Override + public Object callback(GrouperSession theGrouperSession) throws GrouperSessionException { + + Set pitMemberships = GrouperDAOFactory.getFactory().getPITMembershipView().findAllByPITOwnerAndPITMemberAndPITField(pitGroup.getId(), pitMember.getId(), pitField.getId(), null, null, null); + PITMembershipView latestPITMembership = null; + + for (PITMembershipView pitMembership : pitMemberships) { + if (pitMembership.getEndTime() != null) { + if (latestPITMembership == null || latestPITMembership.getEndTime().getTime() < pitMembership.getEndTime().getTime()) { + latestPITMembership = pitMembership; + } + } } - } - - //

Danielle Knotts is an indirect member of

- //

Root : Departments : Information Technology : Staff

- //

which is a direct member of

- //

Root : Applications : Wiki : Editors

Back to previous page - //
- boolean firstPath = true; - // loop through each membership path - for (MembershipPath membershipPath : membershipPathsAllowed) { - if (!firstPath) { - result.append("
\n"); + if (latestPITMembership == null) { + // nothing to show + return false; } - int pathLineNumber = 0; - membershipGuiContainer.setLineNumber(pathLineNumber); - result.append(TextContainer.retrieveFromRequest().getText().get("membershipTracePathFirstLine")).append("\n"); - pathLineNumber++; - membershipGuiContainer.setLineNumber(pathLineNumber); + boolean isWheelOrRoot = PrivilegeHelper.isWheelOrRoot(loggedInGrouperSession.getSubject()); - boolean firstNode = true; + String pitGroupSetId = latestPITMembership.getGroupSetId(); + PITGroup previousMemberPITGroup = null; - Subject currentSubject = subject; + boolean firstNode = true; - //loop through each node in the path - for (MembershipPathNode membershipPathNode : membershipPath.getMembershipPathNodes()) { - - Group ownerGroup = membershipPathNode.getOwnerGroup(); + while (true) { + PITGroupSet pitGroupSet = GrouperDAOFactory.getFactory().getPITGroupSet().findById(pitGroupSetId, true); + PITGroup memberPITGroup = pitGroupSet.getMemberPITGroup(); + + // check access + if (!isWheelOrRoot) { + Group memberGroup = GroupFinder.findByUuid(memberPITGroup.getSourceId(), false); + if (memberGroup == null || !memberGroup.canHavePrivilege(loggedInGrouperSession.getSubject(), "read", false)) { + // no access so return + return false; + } + } + + if (firstNode) { + Set immediatePITMemberships = GrouperDAOFactory.getFactory().getPITMembership().findAllByPITOwnerAndPITMemberAndPITField(memberPITGroup.getId(), pitMember.getId(), pitField.getId()); + PITMembership mostRecentImmediatePITMembership = null; + for (PITMembership immediatePITMembership : immediatePITMemberships) { + if (mostRecentImmediatePITMembership == null || + immediatePITMembership.getEndTime() == null || + (mostRecentImmediatePITMembership.getEndTime() != null && immediatePITMembership.getEndTime().getTime() > mostRecentImmediatePITMembership.getEndTime().getTime())) { + mostRecentImmediatePITMembership = immediatePITMembership; + } + } + + endTimes.add(mostRecentImmediatePITMembership.getEndTime()); + } else { + Set immediatePITGroupSets = GrouperDAOFactory.getFactory().getPITGroupSet().findAllImmediateByPITOwnerAndPITMemberAndPITField(memberPITGroup.getId(), previousMemberPITGroup.getId(), pitField.getId()); + PITGroupSet mostRecentImmediatePITGroupSet = null; + for (PITGroupSet immediatePITGroupSet : immediatePITGroupSets) { + if (mostRecentImmediatePITGroupSet == null || + immediatePITGroupSet.getEndTime() == null || + (mostRecentImmediatePITGroupSet.getEndTime() != null && immediatePITGroupSet.getEndTime().getTime() > mostRecentImmediatePITGroupSet.getEndTime().getTime())) { + mostRecentImmediatePITGroupSet = immediatePITGroupSet; + } + } + + endTimes.add(mostRecentImmediatePITGroupSet.getEndTime()); + } - if (!firstNode) { + memberPITGroups.add(memberPITGroup); + + firstNode = false; + + if (pitGroupSet.getDepth() < 1) { + break; + } + + pitGroupSetId = pitGroupSet.getParentId(); + previousMemberPITGroup = memberPITGroup; + } - if (membershipPathNode.isComposite()) { - - //dont know what branch of the composite we are on... so - Group factor = membershipPathNode.getOtherFactor(); - membershipGuiContainer.setGuiGroupFactor(new GuiGroup(factor)); - switch(membershipPathNode.getCompositeType()) { - case UNION: + return true; + } + }); + + if (!proceed) { + return; + } + + // text should be rendered as the logged in user to ensure subject privacy + GrouperRequestContainer grouperRequestContainer = GrouperRequestContainer.retrieveFromRequestOrCreate(); + MembershipGuiContainer membershipGuiContainer = grouperRequestContainer.getMembershipGuiContainer(); + + StringBuilder result = new StringBuilder(); + + int pathLineNumber = 0; + membershipGuiContainer.setLineNumber(pathLineNumber); + + for (int i = 0; i < memberPITGroups.size(); i++) { + PITGroup memberPITGroup = memberPITGroups.get(i); + Timestamp endTime = endTimes.get(i); + + pitGroupsForTimelineStates.add(memberPITGroup); + + for (PITMember currPITMember : GrouperDAOFactory.getFactory().getPITMember().findPITMembersBySubjectIdSourceAndType(memberPITGroup.getSourceId(), "g:gsa", "group")) { + memberIdsForTimelineAuditQuery.add(currPITMember.getSourceId()); + } - result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupCompositeOfUnion")).append("\n"); - break; - case INTERSECTION: + if (i == 0) { + if (endTime == null) { + result.append(TextContainer.retrieveFromRequest().getText().get("pitMembershipTracePathFirstLineCurrentMembership")).append("\n"); + } else { + membershipGuiContainer.setGuiAuditDateCurrent(endTime); + result.append(TextContainer.retrieveFromRequest().getText().get("pitMembershipTracePathFirstLinePreviousMembership")).append("\n"); + } + } else { + if (endTime == null) { + result.append(TextContainer.retrieveFromRequest().getText().get("pitMembershipTraceGroupMemberOfCurrentMembership")).append("\n"); + } else { + membershipGuiContainer.setGuiAuditDateCurrent(endTime); + result.append(TextContainer.retrieveFromRequest().getText().get("pitMembershipTraceGroupMemberOfPreviousMembership")).append("\n"); + } + } + + pathLineNumber++; + membershipGuiContainer.setLineNumber(pathLineNumber); - result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupCompositeOfIntersection")).append("\n"); - break; - case COMPLEMENT: - - result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupCompositeOfMinus")).append("\n"); - break; - default: - throw new RuntimeException("Not expecting composite type: " + membershipPathNode.getCompositeType()); + membershipGuiContainer.setGuiPITGroupCurrent(new GuiPITGroup(memberPITGroup)); + + result.append(TextContainer.retrieveFromRequest().getText().get("pitMembershipTraceGroupLine")).append("\n"); + + pathLineNumber++; + membershipGuiContainer.setLineNumber(pathLineNumber); + } + + if (result.length() > 0) { + grouperRequestContainer.getMembershipGuiContainer().setTracePITMembershipString(result.toString()); + } + } + + private void traceMembershipsHelperTimeline(PITMember pitMember, PITField pitField, Set memberIdsForTimelineAuditQuery, Set pitGroupsForTimelineStates) { + + GrouperRequestContainer grouperRequestContainer = GrouperRequestContainer.retrieveFromRequestOrCreate(); + MembershipGuiContainer membershipGuiContainer = grouperRequestContainer.getMembershipGuiContainer(); + + GrouperSession loggedInGrouperSession = GrouperSession.staticGrouperSession(); + + AuditType addGroupMembershipAuditType = AuditTypeFinder.find("membership", "addGroupMembership", true); + AuditType updateGroupMembershipAuditType = AuditTypeFinder.find("membership", "updateGroupMembership", true); + AuditType deleteGroupMembershipAuditType = AuditTypeFinder.find("membership", "deleteGroupMembership", true); + + int initialStatesCount = pitGroupsForTimelineStates.size(); + int traceAdditionalStatesCount = GrouperUiConfig.retrieveConfig().propertyValueInt("uiV2.membership.traceAdditionalStatesCount", 10); + int maxStatesCount = initialStatesCount + traceAdditionalStatesCount; + + Set pitGroupsForTimelineStatesWithAdditional = new LinkedHashSet(pitGroupsForTimelineStates); + Set foundGroupIdsForAdditionalStates = new LinkedHashSet(); + + Map allProvisioningTargets = GrouperProvisioningSettings.getTargets(true); + + // refactor these into separate classes + List momentsOfInterest = new ArrayList(); + Map> eventsUserAudits = new LinkedHashMap>(); + Map> eventsPITAddMembershipGroup = new LinkedHashMap>(); + Map> eventsPITAddMembership = new LinkedHashMap>(); + Map> eventsPITDeleteMembershipGroup = new LinkedHashMap>(); + Map> eventsPITDeleteMembership = new LinkedHashMap>(); + Map> eventsProvisioningInTargetStart = new LinkedHashMap>(); + Map> eventsProvisioningInTargetEnd = new LinkedHashMap>(); + Map> states = new LinkedHashMap>(); + Map toDates = new LinkedHashMap(); + + GrouperSession.internal_callbackRootGrouperSession(new GrouperSessionHandler() { + + @Override + public Object callback(GrouperSession theGrouperSession) throws GrouperSessionException { + + + boolean isWheelOrRoot = PrivilegeHelper.isWheelOrRoot(loggedInGrouperSession.getSubject()); + + TreeSet preliminaryMomentsOfInterest = new TreeSet(); + + // moments of interest in the timeline are whenever the user was added or removed from any of these groups in the membership path + for (PITGroup pitGroup : pitGroupsForTimelineStates) { + Set currentPITMemberships = GrouperDAOFactory.getFactory().getPITMembershipView().findAllByPITOwnerAndPITMemberAndPITField(pitGroup.getId(), pitMember.getId(), pitField.getId(), null, null, null); + for (PITMembershipView currentPITMembership : currentPITMemberships) { + if (currentPITMembership.getEndTime() != null) { + if (currentPITMembership.getStartTime().getTime() > currentPITMembership.getEndTime().getTime()) { + // no overlap in membership and group set so ignoring as not useful + continue; } - } else { - result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupMemberOf")).append("\n"); - + long roundedEndTimeToSecond = ((currentPITMembership.getEndTime().getTime() + 500) / 1000) * 1000; + preliminaryMomentsOfInterest.add(roundedEndTimeToSecond); + } + + { + long roundedStartTimeToSecond = ((currentPITMembership.getStartTime().getTime() + 500) / 1000) * 1000; + preliminaryMomentsOfInterest.add(roundedStartTimeToSecond); } + } + } + + if (preliminaryMomentsOfInterest.size() == 0) { + return null; + } + + int traceEventsTimeRangeInSeconds = GrouperUiConfig.retrieveConfig().propertyValueInt("uiV2.membership.traceEventsTimeRangeInSeconds", 90); + List preliminaryMomentsOfInterestDescList = new ArrayList(preliminaryMomentsOfInterest.descendingSet()); - pathLineNumber++; - membershipGuiContainer.setLineNumber(pathLineNumber); + int count = 0; + for (int i = 0; i < preliminaryMomentsOfInterestDescList.size(); i++) { + if (count > 10) { + break; + } + + count++; + + long momentOfInterest = preliminaryMomentsOfInterestDescList.get(i); + long fromLong = momentOfInterest - (traceEventsTimeRangeInSeconds * 1000L); + long toLong = momentOfInterest + (traceEventsTimeRangeInSeconds * 1000L); + + while (true) { + if ((i+1) >= preliminaryMomentsOfInterestDescList.size()) { + break; + } + + long nextMomentOfInterest = preliminaryMomentsOfInterestDescList.get(i + 1); + long nextToLong = nextMomentOfInterest + (traceEventsTimeRangeInSeconds * 1000L); + if (nextToLong >= fromLong) { + // if there's overlap, then combine + fromLong = nextMomentOfInterest - (traceEventsTimeRangeInSeconds * 1000L); + i++; + } else { + break; + } } - membershipGuiContainer.setGuiGroupCurrent(new GuiGroup(ownerGroup)); + Timestamp momentOfInterestTimestamp = new Timestamp(momentOfInterest); + momentsOfInterest.add(momentOfInterestTimestamp); + eventsUserAudits.put(momentOfInterestTimestamp, new ArrayList()); + eventsPITAddMembership.put(momentOfInterestTimestamp, new ArrayList()); + eventsPITAddMembershipGroup.put(momentOfInterestTimestamp, new ArrayList()); + eventsPITDeleteMembership.put(momentOfInterestTimestamp, new ArrayList()); + eventsPITDeleteMembershipGroup.put(momentOfInterestTimestamp, new ArrayList()); + eventsProvisioningInTargetStart.put(momentOfInterestTimestamp, new ArrayList()); + eventsProvisioningInTargetEnd.put(momentOfInterestTimestamp, new ArrayList()); + states.put(momentOfInterestTimestamp, new LinkedHashMap()); + + Timestamp fromDate = new Timestamp(fromLong); + Timestamp toDate = new Timestamp(toLong); - Membership membership = MembershipFinder.findImmediateMembership(GrouperSession.staticGrouperSession(), ownerGroup, currentSubject, false); - membershipGuiContainer.setGuiMembershipCurrent(new GuiMembership(membership)); + toDates.put(momentOfInterestTimestamp, toDate); + + if (membershipGuiContainer.isTraceMembershipTimelineShowUserAudit()) { + UserAuditQuery userAuditQuery = new UserAuditQuery(); + userAuditQuery.setQueryOptions(new QueryOptions().sortAsc("lastUpdatedDb")); + userAuditQuery.setFromDate(fromDate); + userAuditQuery.setToDate(toDate); + + List memberIdCriterions = new ArrayList(); + + for (AuditType auditType : GrouperUtil.toList(addGroupMembershipAuditType, updateGroupMembershipAuditType, deleteGroupMembershipAuditType)) { + Criterion auditTypeCriterion = Restrictions.eq(AuditEntry.FIELD_AUDIT_TYPE_ID, auditType.getId()); + String auditEntryField = auditType.retrieveAuditEntryFieldForLabel("memberId"); + Criterion auditEntryFieldCriterion = Restrictions.in(auditEntryField, memberIdsForTimelineAuditQuery); + Criterion andCriterion = HibUtils.listCrit(auditTypeCriterion, auditEntryFieldCriterion); + memberIdCriterions.add(andCriterion); + } + + userAuditQuery.setExtraCriterion(HibUtils.listCritOr(memberIdCriterions)); + + List userAuditEntries = userAuditQuery.execute(); + for (AuditEntry userAudit : userAuditEntries) { + + GuiAuditEntry guiUserAudit = new GuiAuditEntry(userAudit); + guiUserAudit.internal_setupMember(); + guiUserAudit.internal_setupGroup(); + + if (guiUserAudit.getGuiGroup().getGroup() == null) { + continue; + } + + String userAuditGroupId = guiUserAudit.getGuiGroup().getGroup().getId(); + + if (!isWheelOrRoot && !guiUserAudit.getGuiGroup().getGroup().canHavePrivilege(loggedInGrouperSession.getSubject(), "read", false)) { + // no access so return + continue; + } + + eventsUserAudits.get(momentOfInterestTimestamp).add(guiUserAudit); + if (!foundGroupIdsForAdditionalStates.contains(userAuditGroupId) && pitGroupsForTimelineStatesWithAdditional.size() < maxStatesCount) { + foundGroupIdsForAdditionalStates.add(userAuditGroupId); + Set pitGroups = GrouperDAOFactory.getFactory().getPITGroup().findBySourceId(userAuditGroupId, false); + if (pitGroups.size() > 0) { + pitGroupsForTimelineStatesWithAdditional.add(pitGroups.iterator().next()); + } + } + } + } - result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupLine")).append("\n"); + if (membershipGuiContainer.isTraceMembershipTimelineShowPITAudit()) { + Set pitMembershipsStarted = GrouperDAOFactory.getFactory().getPITMembershipView().findAllByPITMemberAndPITFieldAndStartTimeRange(pitMember.getId(), pitField.getId(), fromDate, toDate); + for (PITMembershipView pitMembershipStarted : pitMembershipsStarted) { + + PITGroup currentPITGroup = GrouperDAOFactory.getFactory().getPITGroup().findById(pitMembershipStarted.getOwnerGroupId(), true); + + if (!isWheelOrRoot) { + Group currentGroup = GrouperDAOFactory.getFactory().getGroup().findByUuid(currentPITGroup.getSourceId(), false); + + if (currentGroup == null || !currentGroup.canHavePrivilege(loggedInGrouperSession.getSubject(), "read", false)) { + // no access so return + continue; + } + } + + eventsPITAddMembership.get(momentOfInterestTimestamp).add(pitMembershipStarted); + eventsPITAddMembershipGroup.get(momentOfInterestTimestamp).add(currentPITGroup); + + if (pitGroupsForTimelineStatesWithAdditional.size() < maxStatesCount) { + pitGroupsForTimelineStatesWithAdditional.add(currentPITGroup); + } + } + + Set pitMembershipsEnded = GrouperDAOFactory.getFactory().getPITMembershipView().findAllByPITMemberAndPITFieldAndEndTimeRange(pitMember.getId(), pitField.getId(), fromDate, toDate); + for (PITMembershipView pitMembershipEnded : pitMembershipsEnded) { + + PITGroup currentPITGroup = GrouperDAOFactory.getFactory().getPITGroup().findById(pitMembershipEnded.getOwnerGroupId(), true); + + if (!isWheelOrRoot) { + Group currentGroup = GrouperDAOFactory.getFactory().getGroup().findByUuid(currentPITGroup.getSourceId(), false); + + if (currentGroup == null || !currentGroup.canHavePrivilege(loggedInGrouperSession.getSubject(), "read", false)) { + // no access so return + continue; + } + } + + eventsPITDeleteMembership.get(momentOfInterestTimestamp).add(pitMembershipEnded); + eventsPITDeleteMembershipGroup.get(momentOfInterestTimestamp).add(currentPITGroup); + + if (pitGroupsForTimelineStatesWithAdditional.size() < maxStatesCount) { + pitGroupsForTimelineStatesWithAdditional.add(currentPITGroup); + } + } + } - firstNode = false; + if (membershipGuiContainer.isTraceMembershipTimelineShowProvisioningEvents()) { + List gcGrouperSyncMembershipsStarted = GrouperProvisioningService.retrieveGcGrouperSyncMembershipsByMemberIdAndInTargetStartTimeRange(pitMember.getSourceId(), fromDate, toDate); + + for (GcGrouperSyncMembership gcGrouperSyncMembership : gcGrouperSyncMembershipsStarted) { + String currentGroupId = gcGrouperSyncMembership.getGrouperSyncGroup().getGroupId(); + + if (!isWheelOrRoot) { + Group currentGroup = GrouperDAOFactory.getFactory().getGroup().findByUuid(currentGroupId, false); + GrouperProvisioningTarget currentGrouperProvisioningTarget = allProvisioningTargets.get(gcGrouperSyncMembership.getGrouperSync().getProvisionerName()); + if (currentGroup == null || currentGrouperProvisioningTarget == null || + !GrouperProvisioningService.isTargetViewable(currentGrouperProvisioningTarget, loggedInGrouperSession.getSubject(), currentGroup) || + !currentGroup.canHavePrivilege(loggedInGrouperSession.getSubject(), "read", false)) { + // no access so return + continue; + } + } + + eventsProvisioningInTargetStart.get(momentOfInterestTimestamp).add(gcGrouperSyncMembership); + if (!foundGroupIdsForAdditionalStates.contains(currentGroupId) && pitGroupsForTimelineStatesWithAdditional.size() < maxStatesCount) { + foundGroupIdsForAdditionalStates.add(currentGroupId); + Set pitGroups = GrouperDAOFactory.getFactory().getPITGroup().findBySourceId(currentGroupId, false); + if (pitGroups.size() > 0) { + pitGroupsForTimelineStatesWithAdditional.add(pitGroups.iterator().next()); + } + } + } + + List gcGrouperSyncMembershipsEnded = GrouperProvisioningService.retrieveGcGrouperSyncMembershipsByMemberIdAndInTargetEndTimeRange(pitMember.getSourceId(), fromDate, toDate); + + for (GcGrouperSyncMembership gcGrouperSyncMembership : gcGrouperSyncMembershipsEnded) { + String currentGroupId = gcGrouperSyncMembership.getGrouperSyncGroup().getGroupId(); + + if (!isWheelOrRoot) { + Group currentGroup = GrouperDAOFactory.getFactory().getGroup().findByUuid(currentGroupId, false); + GrouperProvisioningTarget currentGrouperProvisioningTarget = allProvisioningTargets.get(gcGrouperSyncMembership.getGrouperSync().getProvisionerName()); + if (currentGroup == null || currentGrouperProvisioningTarget == null || + !GrouperProvisioningService.isTargetViewable(currentGrouperProvisioningTarget, loggedInGrouperSession.getSubject(), currentGroup) || + !currentGroup.canHavePrivilege(loggedInGrouperSession.getSubject(), "read", false)) { + // no access so return + continue; + } + } + + eventsProvisioningInTargetEnd.get(momentOfInterestTimestamp).add(gcGrouperSyncMembership); + if (!foundGroupIdsForAdditionalStates.contains(currentGroupId) && pitGroupsForTimelineStatesWithAdditional.size() < maxStatesCount) { + foundGroupIdsForAdditionalStates.add(currentGroupId); + Set pitGroups = GrouperDAOFactory.getFactory().getPITGroup().findBySourceId(currentGroupId, false); + if (pitGroups.size() > 0) { + pitGroupsForTimelineStatesWithAdditional.add(pitGroups.iterator().next()); + } + } + } + } + } + + for (int i = 0; i < momentsOfInterest.size(); i++) { + Timestamp momentOfInterestTimestamp = momentsOfInterest.get(i); + Timestamp toDate = toDates.get(momentOfInterestTimestamp); + + for (PITGroup pitGroupForState : pitGroupsForTimelineStatesWithAdditional) { + + Set pitMembershipsForState = GrouperDAOFactory.getFactory().getPITMembershipView().findAllByPITOwnerAndPITMemberAndPITField(pitGroupForState.getId(), pitMember.getId(), pitField.getId(), toDate, toDate, null); + if (pitMembershipsForState.size() > 0) { + states.get(momentOfInterestTimestamp).put(pitGroupForState, true); + } else { + states.get(momentOfInterestTimestamp).put(pitGroupForState, false); + } + } + } + + return null; + } + }); + + if (momentsOfInterest.size() == 0) { + return; + } + + StringBuilder result = new StringBuilder(); + result.append("
    \n"); + + for (int i = 0; i < momentsOfInterest.size(); i++) { + + Timestamp momentOfInterestTimestamp = momentsOfInterest.get(i); + List currEventsUserAudits = eventsUserAudits.get(momentOfInterestTimestamp); + List currEventsPITAddMembership = eventsPITAddMembership.get(momentOfInterestTimestamp); + List currEventsPITAddMembershipGroup = eventsPITAddMembershipGroup.get(momentOfInterestTimestamp); + List currEventsPITDeleteMembership = eventsPITDeleteMembership.get(momentOfInterestTimestamp); + List currEventsPITDeleteMembershipGroup = eventsPITDeleteMembershipGroup.get(momentOfInterestTimestamp); + List currEventsProvisioningInTargetStart = eventsProvisioningInTargetStart.get(momentOfInterestTimestamp); + List currEventsProvisioningInTargetEnd = eventsProvisioningInTargetEnd.get(momentOfInterestTimestamp); + Map currStates = states.get(momentOfInterestTimestamp); + + membershipGuiContainer.setGuiAuditDateCurrent(momentOfInterestTimestamp); + result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceTimelineMomentOfInterest")).append("\n"); + + result.append("
    • " + TextContainer.retrieveFromRequest().getText().get("membershipTraceTimelineMomentOfInterestEventsLabel") + "
    • "); + result.append("
        "); + + Map> sortedEvents = new TreeMap>(); + + for (GuiAuditEntry guiUserAudit : currEventsUserAudits) { + boolean isAddMembership = false; + boolean isUpdateMembership = false; + boolean isDeleteMembership = false; + if (guiUserAudit.getAuditEntry().getAuditType().equals(addGroupMembershipAuditType)) { + isAddMembership = true; + } else if (guiUserAudit.getAuditEntry().getAuditType().equals(deleteGroupMembershipAuditType)) { + isDeleteMembership = true; + } else if (guiUserAudit.getAuditEntry().getAuditType().equals(updateGroupMembershipAuditType)) { + isUpdateMembership = true; + } else { + continue; + } + + membershipGuiContainer.setGuiAuditEntryCurrent(guiUserAudit); + long timestamp = guiUserAudit.getAuditEntry().getCreatedOn().getTime(); + + if (sortedEvents.get(timestamp) == null) { + sortedEvents.put(timestamp, new TreeSet()); + } + + if (isAddMembership) { + sortedEvents.get(timestamp).add(TextContainer.retrieveFromRequest().getText().get("membershipTraceTimelineUserAuditAddMembership")); + } else if (isUpdateMembership) { + sortedEvents.get(timestamp).add(TextContainer.retrieveFromRequest().getText().get("membershipTraceTimelineUserAuditUpdateMembership")); + } else if (isDeleteMembership) { + sortedEvents.get(timestamp).add(TextContainer.retrieveFromRequest().getText().get("membershipTraceTimelineUserAuditDeleteMembership")); + } + } + + for (int j = 0; j < currEventsPITAddMembership.size(); j++) { + PITMembershipView pitMembershipStarted = currEventsPITAddMembership.get(j); + PITGroup currentPITGroup = currEventsPITAddMembershipGroup.get(j); + + membershipGuiContainer.setGuiPITGroupCurrent(new GuiPITGroup(currentPITGroup)); + membershipGuiContainer.setGuiAuditDateCurrent(pitMembershipStarted.getStartTime()); + + long timestamp = pitMembershipStarted.getStartTime().getTime(); + + if (sortedEvents.get(timestamp) == null) { + sortedEvents.put(timestamp, new TreeSet()); + } + + sortedEvents.get(timestamp).add(TextContainer.retrieveFromRequest().getText().get("membershipTraceTimelinePITAuditAddMembership")); + } + + for (int j = 0; j < currEventsPITDeleteMembership.size(); j++) { + PITMembershipView pitMembershipEnded = currEventsPITDeleteMembership.get(j); + PITGroup currentPITGroup = currEventsPITDeleteMembershipGroup.get(j); + + membershipGuiContainer.setGuiPITGroupCurrent(new GuiPITGroup(currentPITGroup)); + membershipGuiContainer.setGuiAuditDateCurrent(pitMembershipEnded.getEndTime()); + + long timestamp = pitMembershipEnded.getEndTime().getTime(); + + if (sortedEvents.get(timestamp) == null) { + sortedEvents.put(timestamp, new TreeSet()); + } + + sortedEvents.get(timestamp).add(TextContainer.retrieveFromRequest().getText().get("membershipTraceTimelinePITAuditDeleteMembership")); + } + + for (GcGrouperSyncMembership gcGrouperSyncMembership : currEventsProvisioningInTargetStart) { + membershipGuiContainer.setGuiGcGrouperSyncMembershipCurrent(new GuiGcGrouperSyncMembership(gcGrouperSyncMembership)); + + long timestamp = gcGrouperSyncMembership.getInTargetStart().getTime(); + + if (sortedEvents.get(timestamp) == null) { + sortedEvents.put(timestamp, new TreeSet()); + } + + sortedEvents.get(timestamp).add(TextContainer.retrieveFromRequest().getText().get("membershipTraceTimelineProvisioningTargetStart")); + } + + for (GcGrouperSyncMembership gcGrouperSyncMembership : currEventsProvisioningInTargetEnd) { + membershipGuiContainer.setGuiGcGrouperSyncMembershipCurrent(new GuiGcGrouperSyncMembership(gcGrouperSyncMembership)); + + long timestamp = gcGrouperSyncMembership.getInTargetEnd().getTime(); + + if (sortedEvents.get(timestamp) == null) { + sortedEvents.put(timestamp, new TreeSet()); + } + + sortedEvents.get(timestamp).add(TextContainer.retrieveFromRequest().getText().get("membershipTraceTimelineProvisioningTargetEnd")); + } + + for (long timestamp : sortedEvents.keySet()) { + for (String event : sortedEvents.get(timestamp)) { + result.append(event + "\n"); + } + } + + result.append("
      "); + result.append("
    • " + TextContainer.retrieveFromRequest().getText().get("membershipTraceTimelineMomentOfInterestStateLabel") + "
    • "); + result.append("
        "); + + for (PITGroup currState : currStates.keySet()) { + membershipGuiContainer.setGuiPITGroupCurrent(new GuiPITGroup(currState)); + + if (currStates.get(currState)) { + result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceTimelineStateMembershipYes")).append("\n"); + } else { + result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceTimelineStateMembershipNo")).append("\n"); + } + } + + result.append("
      "); + + result.append("
    "); + } + + result.append("
\n"); + + grouperRequestContainer.getMembershipGuiContainer().setTraceMembershipTimelineString(result.toString()); + } + + private void traceMembershipHelperCurrent(MembershipPathGroup membershipPathGroup, Subject subject, Set memberIdsForTimelineAuditQuery, Set pitGroupsForTimelineStates) { + GrouperRequestContainer grouperRequestContainer = GrouperRequestContainer.retrieveFromRequestOrCreate(); + MembershipGuiContainer membershipGuiContainer = grouperRequestContainer.getMembershipGuiContainer(); + + Set membershipPaths = GrouperUtil.nonNull(membershipPathGroup.getMembershipPaths()); + + StringBuilder result = new StringBuilder(); + + //massage the paths to only consider the ones that are allowed + int membershipUnallowedCount = 0; + List membershipPathsAllowed = new ArrayList(); + + for (MembershipPath membershipPath : membershipPaths) { + if (membershipPath.isPathAllowed()) { + membershipPathsAllowed.add(membershipPath); + } else { + membershipUnallowedCount++; + } + } + + if (GrouperUtil.length(membershipPathsAllowed) == 0) { + + if (membershipUnallowedCount > 0) { + result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupNoPathsAllowed")).append("

\n"); + + } else { + result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupNoPaths")).append("

\n"); + } + } else if (membershipUnallowedCount > 0) { + membershipGuiContainer.setPathCountNotAllowed(membershipUnallowedCount); + result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupPathsNotAllowed")).append("

\n"); + } + + Set groupIdsForTimeline = new LinkedHashSet(); + + //

Danielle Knotts is an indirect member of

+ //

Root : Departments : Information Technology : Staff

+ //

which is a direct member of

+ //

Root : Applications : Wiki : Editors

Back to previous page + //
+ boolean firstPath = true; + // loop through each membership path + for (MembershipPath membershipPath : membershipPathsAllowed) { + + if (!firstPath) { + result.append("
\n"); + } + + int pathLineNumber = 0; + membershipGuiContainer.setLineNumber(pathLineNumber); + result.append(TextContainer.retrieveFromRequest().getText().get("membershipTracePathFirstLine")).append("\n"); + pathLineNumber++; + membershipGuiContainer.setLineNumber(pathLineNumber); + + boolean firstNode = true; + + Subject currentSubject = subject; + + //loop through each node in the path + for (MembershipPathNode membershipPathNode : membershipPath.getMembershipPathNodes()) { + + Group ownerGroup = membershipPathNode.getOwnerGroup(); + groupIdsForTimeline.add(ownerGroup.getId()); + + if (!firstNode) { + + if (membershipPathNode.isComposite()) { + + //dont know what branch of the composite we are on... so + Group factor = membershipPathNode.getOtherFactor(); + membershipGuiContainer.setGuiGroupFactor(new GuiGroup(factor)); + + if (factor != null) { + if (factor.canHavePrivilege(GrouperSession.staticGrouperSession().getSubject(), "read", false)) { + groupIdsForTimeline.add(factor.getId()); + } + } + + switch(membershipPathNode.getCompositeType()) { + case UNION: + + result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupCompositeOfUnion")).append("\n"); + break; + case INTERSECTION: + + result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupCompositeOfIntersection")).append("\n"); + break; + case COMPLEMENT: + + result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupCompositeOfMinus")).append("\n"); + break; + default: + throw new RuntimeException("Not expecting composite type: " + membershipPathNode.getCompositeType()); + } + + } else { + result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupMemberOf")).append("\n"); + + } + pathLineNumber++; membershipGuiContainer.setLineNumber(pathLineNumber); - - currentSubject = ownerGroup.toSubject(); + } - firstPath = false; + membershipGuiContainer.setGuiGroupCurrent(new GuiGroup(ownerGroup)); + + Membership membership = MembershipFinder.findImmediateMembership(GrouperSession.staticGrouperSession(), ownerGroup, currentSubject, false); + membershipGuiContainer.setGuiMembershipCurrent(new GuiMembership(membership)); + + result.append(TextContainer.retrieveFromRequest().getText().get("membershipTraceGroupLine")).append("\n"); + + firstNode = false; + pathLineNumber++; + membershipGuiContainer.setLineNumber(pathLineNumber); + + currentSubject = ownerGroup.toSubject(); } + firstPath = false; + } + + if (result.length() > 0) { grouperRequestContainer.getMembershipGuiContainer().setTraceMembershipsString(result.toString()); - - guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#grouperMainContentDivId", - "/WEB-INF/grouperUi2/membership/traceMembership.jsp")); - - } finally { - GrouperSession.stopQuietly(grouperSession); } + pitGroupsForTimelineStates.addAll(GrouperDAOFactory.getFactory().getPITGroup().findBySourceIdsActive(groupIdsForTimeline)); + + for (Member member : GrouperDAOFactory.getFactory().getMember().findBySubjectIds(groupIdsForTimeline, "g:gsa")) { + memberIdsForTimelineAuditQuery.add(member.getId()); + } } /** diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2ProvisionerConfiguration.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2ProvisionerConfiguration.java index b7cbb21f08e5..8738782d9a8e 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2ProvisionerConfiguration.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2ProvisionerConfiguration.java @@ -29,6 +29,8 @@ import edu.internet2.middleware.grouper.app.provisioning.ProvisioningConfiguration; import edu.internet2.middleware.grouper.audit.AuditEntry; import edu.internet2.middleware.grouper.audit.AuditTypeBuiltin; +import edu.internet2.middleware.grouper.cfg.dbConfig.ConfigItemFormElement; +import edu.internet2.middleware.grouper.cfg.dbConfig.OptionValueDriver; import edu.internet2.middleware.grouper.changeLog.esb.consumer.ProvisioningMessage; import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiPaging; import edu.internet2.middleware.grouper.grouperUi.beans.json.GuiResponseJs; @@ -810,8 +812,10 @@ public void addProvisionerConfiguration(final HttpServletRequest request, final String previousProvisionerStartWithClass = request.getParameter("previousProvisionerStartWithClass"); boolean skipStartWith = false; - if (StringUtils.isNotBlank(provisionerStartWithClass) && StringUtils.equals(provisionerStartWithClass, "blank")) { + if ( (StringUtils.isNotBlank(provisionerStartWithClass) && StringUtils.equals(provisionerStartWithClass, "blank")) || + (StringUtils.equals(previousProvisionerStartWithClass, "blank")) ) { skipStartWith = true; + provisionerConfigurationContainer.setBlankStartWithSelected(true); } if (!skipStartWith && StringUtils.isNotBlank(provisionerStartWithClass)) { @@ -851,17 +855,11 @@ public void addProvisionerConfiguration(final HttpServletRequest request, final configSuffixToValues.put(key, startWithValue); } - //Set newKeys = configSuffixToValues.keySet(); Set suffixesUserJustChanged = new HashSet<>(); Map oldSuffixToValue = provisionerStartWith.getCachedConfigKeyToValue(sessionId); if (oldSuffixToValue != null) { -// Set oldKeys = oldSuffixToValue.keySet(); -// newKeys.removeAll(oldKeys); - //now newKeys only have the keys that have been added since the last trip to the server - // compare old values with new values and build suffixesUserJustChanged - for (String key: startWithAttributes.keySet()) { String startWithNewValue = startWithAttributes.get(key).getValue(); String startWithOldValue = oldSuffixToValue.get(key); @@ -883,6 +881,7 @@ public void addProvisionerConfiguration(final HttpServletRequest request, final if (startWithAttributes.containsKey(key)) { startWithAttributes.get(key).setValue(GrouperUtil.stringValue(valueToSet)); + startWithAttributes.get(key).setShow(true); } } } @@ -890,11 +889,6 @@ public void addProvisionerConfiguration(final HttpServletRequest request, final } - - - - - } // once the start with submit is done @@ -1004,8 +998,30 @@ public void addProvisionerConfigurationSubmit(final HttpServletRequest request, provisionerConfiguration.setConfigId(provisionerConfigId); String provisionerStartWithClass = request.getParameter("provisionerStartWithClass"); + String previousProvisionerStartWithClass = request.getParameter("previousProvisionerStartWithClass"); + + List startWithConfigClasses = provisionerConfiguration.getStartWithConfigClasses(); - if (StringUtils.isNotBlank(provisionerStartWithClass)) { + if(startWithConfigClasses.size() > 0 && StringUtils.isBlank(previousProvisionerStartWithClass)) { + + GuiProvisionerConfiguration guiProvisioningConfiguration = GuiProvisionerConfiguration.convertFromProvisioningConfiguration(provisionerConfiguration); + provisionerConfigurationContainer.setGuiProvisionerConfiguration(guiProvisioningConfiguration); + + guiResponseJs.addAction(GuiScreenAction.newValidationMessage(GuiMessageType.error, + "#provisionerConfigStartWithId", + TextContainer.retrieveFromRequest().getText().get("provisionerConfigStartWithIdRequired"))); + + provisionerConfigurationContainer.setShowStartWithSection(true); + guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#grouperMainContentDivId", + "/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigAdd.jsp")); + + + return; + + } + + + if (StringUtils.isNotBlank(provisionerStartWithClass) && !StringUtils.equals("empty", provisionerStartWithClass)) { Class startWithKlass = (Class) GrouperUtil.forName(provisionerStartWithClass); ProvisionerStartWithBase provisionerStartWith = (ProvisionerStartWithBase) GrouperUtil.newInstance(startWithKlass); provisionerStartWith.setConfigId(provisionerConfigId); @@ -1049,7 +1065,6 @@ public void addProvisionerConfigurationSubmit(final HttpServletRequest request, } } - provisionerStartWith.populateProvisionerConfigurationValuesFromStartWith(configSuffixToValues, provisionerSuffixToValue); for (String key: provisionerSuffixToValue.keySet()) { @@ -1057,6 +1072,21 @@ public void addProvisionerConfigurationSubmit(final HttpServletRequest request, if (attributes.containsKey(key)) { attributes.get(key).setValue(GrouperUtil.stringValue(valueToSet)); + + } + } + + for (String key: provisionerSuffixToValue.keySet()) { + + if (attributes.containsKey(key)) { + + if (attributes.get(key).getFormElement() == ConfigItemFormElement.DROPDOWN) { + + attributes.get(key).getGrouperConfigModule() + .populateValuesLabelsFromOptionValueClass(attributes, attributes.get(key)); + + } + } } @@ -1069,6 +1099,8 @@ public void addProvisionerConfigurationSubmit(final HttpServletRequest request, guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#grouperMainContentDivId", "/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigAdd.jsp")); + guiResponseJs.addAction(GuiScreenAction.newScript("guiScrollTop()")); + return; } @@ -1114,7 +1146,6 @@ public void addProvisionerConfigurationSubmit(final HttpServletRequest request, } messageBuilder.append(TextContainer.retrieveFromRequest().getText().get("provisionerConfigAddEditSuccess")); guiResponseJs.addAction(GuiScreenAction.newMessageAppend(GuiMessageType.success, messageBuilder.toString())); - } finally { @@ -1181,6 +1212,8 @@ public void editProvisionerConfiguration(final HttpServletRequest request, final provisionerConfigurationContainer.setGuiProvisionerConfiguration(guiProvisioningConfiguration); } + provisionerConfiguration.correctFormFieldsForExpressionLanguageValues(); + guiResponseJs.addAction(GuiScreenAction.newInnerHtmlFromJsp("#grouperMainContentDivId", "/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigEdit.jsp")); diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Provisioning.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Provisioning.java index 255c4f24557d..eabe5a61deff 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Provisioning.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Provisioning.java @@ -91,18 +91,20 @@ public void viewProvisioningOnFolder(final HttpServletRequest request, final Htt grouperSession = GrouperSession.start(loggedInSubject); - stem = UiV2Stem.retrieveStemHelper(request, true).getStem(); + stem = UiV2Stem.retrieveStemHelper(request, false).getStem(); if (stem == null) { return; } + + if (!GrouperRequestContainer.retrieveFromRequestOrCreate().getStemContainer().isCanViewPrivileges()) { + return; + } + + final Stem STEM = stem; final GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs(); - - if (!PrivilegeHelper.isWheelOrRoot(loggedInSubject)) { - throw new RuntimeException("Cannot access provisioning."); - } final ProvisioningContainer provisioningContainer = GrouperRequestContainer.retrieveFromRequestOrCreate().getProvisioningContainer(); @@ -243,10 +245,6 @@ public void viewProvisioningConfigurationOnGroup(final HttpServletRequest reques return; } - if (!PrivilegeHelper.isWheelOrRoot(loggedInSubject)) { - throw new RuntimeException("Cannot access provisioning."); - } - final Group GROUP = group; final GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs(); @@ -267,7 +265,7 @@ public Object callback(GrouperSession theGrouperSession) throws GrouperSessionEx return null; } - setGrouperProvisioningAttributeValues(GROUP, targetName); + setGrouperProvisioningAttributeValues(GROUP, targetName, loggedInSubject); GuiGroup guiGroup = GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupContainer().getGuiGroup(); addProvisioningBreadcrumbs(guiGroup, targetName, "viewProvisioningOnGroup", "groupId", GROUP.getId()); @@ -308,10 +306,6 @@ public void viewProvisioningOnGroup(final HttpServletRequest request, final Http return; } - if (!PrivilegeHelper.isWheelOrRoot(loggedInSubject)) { - throw new RuntimeException("Cannot access provisioning."); - } - final Group GROUP = group; final GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs(); @@ -326,7 +320,7 @@ public Object callback(GrouperSession theGrouperSession) throws GrouperSessionEx return null; } - setGrouperProvisioningAttributeValues(GROUP, null); + setGrouperProvisioningAttributeValues(GROUP, null, loggedInSubject); GuiGroup guiGroup = GrouperRequestContainer.retrieveFromRequestOrCreate().getGroupContainer().getGuiGroup(); addProvisioningBreadcrumbs(guiGroup, null, null, null, null); @@ -359,10 +353,6 @@ public void viewProvisioningOnSubject(final HttpServletRequest request, final Ht try { - if (!PrivilegeHelper.isWheelOrRoot(loggedInSubject)) { - throw new RuntimeException("Cannot access provisioning."); - } - grouperSession = GrouperSession.start(loggedInSubject); subject = UiV2Subject.retrieveSubjectHelper(request, true); @@ -473,10 +463,6 @@ public void viewProvisioningTargetDetailsOnSubject(final HttpServletRequest requ return; } - if (!PrivilegeHelper.isWheelOrRoot(loggedInSubject)) { - throw new RuntimeException("Cannot access provisioning."); - } - final String targetName = request.getParameter("provisioningTargetName"); if (StringUtils.isBlank(targetName)) { @@ -577,10 +563,6 @@ public void viewProvisioningTargetDetailsOnGroupMembership(final HttpServletRequ return; } - if (!PrivilegeHelper.isWheelOrRoot(loggedInSubject)) { - throw new RuntimeException("Cannot access provisioning."); - } - final Group GROUP = group; final String targetName = request.getParameter("provisioningTargetName"); @@ -690,10 +672,6 @@ public void viewProvisioningOnGroupMembership(final HttpServletRequest request, return; } - if (!PrivilegeHelper.isWheelOrRoot(loggedInSubject)) { - throw new RuntimeException("Cannot access provisioning."); - } - final GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs(); final ProvisioningContainer provisioningContainer = GrouperRequestContainer.retrieveFromRequestOrCreate().getProvisioningContainer(); @@ -802,10 +780,6 @@ public void viewProvisioningTargetDetailsOnSubjectMembership(final HttpServletRe return; } - if (!PrivilegeHelper.isWheelOrRoot(loggedInSubject)) { - throw new RuntimeException("Cannot access provisioning."); - } - final String targetName = request.getParameter("provisioningTargetName"); if (StringUtils.isBlank(targetName)) { @@ -917,10 +891,6 @@ public void viewProvisioningOnSubjectMembership(final HttpServletRequest request return; } - if (!PrivilegeHelper.isWheelOrRoot(loggedInSubject)) { - throw new RuntimeException("Cannot access provisioning."); - } - final Group GROUP = group; final Subject SUBJECT = subject; @@ -1003,7 +973,7 @@ public Object callback(GrouperSession theGrouperSession) throws GrouperSessionEx } - private final void setGrouperProvisioningAttributeValues(Group group, String targetName) { + private final void setGrouperProvisioningAttributeValues(Group group, String targetName, Subject loggedInSubject) { List provisioningAttributeValues = new ArrayList(); @@ -1014,8 +984,23 @@ private final void setGrouperProvisioningAttributeValues(Group group, String tar provisioningAttributeValues.add(grouperProvisioningAttributeValue); } + + Map allTargets = GrouperProvisioningSettings.getTargets(true); + + List provisioningAttributeValuesViewable = new ArrayList(); + + for (GrouperProvisioningAttributeValue grouperProvisioningAttributeValue: provisioningAttributeValues) { + + String localTargetName = grouperProvisioningAttributeValue.getTargetName(); + GrouperProvisioningTarget grouperProvisioningTarget = allTargets.get(localTargetName); + if (grouperProvisioningTarget != null && GrouperProvisioningService.isTargetViewable(grouperProvisioningTarget, loggedInSubject, group)) { + provisioningAttributeValuesViewable.add(grouperProvisioningAttributeValue); + } + + } + // convert from raw to gui - List guiGrouperProvisioningAttributeValues = GuiGrouperProvisioningAttributeValue.convertFromGrouperProvisioningAttributeValues(provisioningAttributeValues); + List guiGrouperProvisioningAttributeValues = GuiGrouperProvisioningAttributeValue.convertFromGrouperProvisioningAttributeValues(provisioningAttributeValuesViewable); for (GuiGrouperProvisioningAttributeValue guiGrouperProvisioningAttributeValue: guiGrouperProvisioningAttributeValues) { String provisionerName = guiGrouperProvisioningAttributeValue.getGrouperProvisioningAttributeValue().getTargetName(); @@ -2679,14 +2664,14 @@ public void viewProvisioningTargetDetailsOnFolder(final HttpServletRequest reque grouperSession = GrouperSession.start(loggedInSubject); - stem = UiV2Stem.retrieveStemHelper(request, true).getStem(); + stem = UiV2Stem.retrieveStemHelper(request, false).getStem(); if (stem == null) { return; } - if (!PrivilegeHelper.isWheelOrRoot(loggedInSubject)) { - throw new RuntimeException("Cannot access provisioning."); + if (!GrouperRequestContainer.retrieveFromRequestOrCreate().getStemContainer().isCanViewPrivileges()) { + return; } final GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs(); @@ -2703,12 +2688,6 @@ public Object callback(GrouperSession theGrouperSession) throws GrouperSessionEx return false; } - if (!provisioningContainer.isCanWriteProvisioning()) { - guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.error, - TextContainer.retrieveFromRequest().getText().get("provisioningNotAllowedToWriteStem"))); - return false; - } - return true; } }); @@ -2863,16 +2842,12 @@ public void viewProvisioningTargetLogsOnGroup(final HttpServletRequest request, grouperSession = GrouperSession.start(loggedInSubject); - group = UiV2Group.retrieveGroupHelper(request, AccessPrivilege.UPDATE).getGroup(); + group = UiV2Group.retrieveGroupHelper(request, AccessPrivilege.VIEW).getGroup(); if (group == null) { return; } - if (!PrivilegeHelper.isWheelOrRoot(loggedInSubject)) { - throw new RuntimeException("Cannot access provisioning."); - } - final GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs(); final ProvisioningContainer provisioningContainer = GrouperRequestContainer.retrieveFromRequestOrCreate().getProvisioningContainer(); @@ -2887,12 +2862,6 @@ public Object callback(GrouperSession theGrouperSession) throws GrouperSessionEx return false; } - if (!provisioningContainer.isCanWriteProvisioning()) { - guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.error, - TextContainer.retrieveFromRequest().getText().get("provisioningNotAllowedToWriteGroup"))); - return false; - } - return true; } }); @@ -2924,7 +2893,7 @@ public Object callback(GrouperSession theGrouperSession) throws GrouperSessionEx List gcGrouperSyncLogs = GrouperProvisioningService.retrieveGcGrouperSyncLogs(targetName, GROUP.getUuid(), queryOptions); provisioningContainer.setGcGrouperSyncLogs(gcGrouperSyncLogs); - setGrouperProvisioningAttributeValues(GROUP, targetName); + setGrouperProvisioningAttributeValues(GROUP, targetName, loggedInSubject); guiPaging.setTotalRecordCount(queryOptions.getQueryPaging().getTotalRecordCount()); return null; @@ -2971,16 +2940,12 @@ public void viewProvisioningTargetDetailsOnGroup(final HttpServletRequest reques grouperSession = GrouperSession.start(loggedInSubject); - group = UiV2Group.retrieveGroupHelper(request, AccessPrivilege.UPDATE).getGroup(); + group = UiV2Group.retrieveGroupHelper(request, AccessPrivilege.VIEW).getGroup(); if (group == null) { return; } - if (!PrivilegeHelper.isWheelOrRoot(loggedInSubject)) { - throw new RuntimeException("Cannot access provisioning."); - } - final GuiResponseJs guiResponseJs = GuiResponseJs.retrieveGuiResponseJs(); final ProvisioningContainer provisioningContainer = GrouperRequestContainer.retrieveFromRequestOrCreate().getProvisioningContainer(); @@ -2995,12 +2960,6 @@ public Object callback(GrouperSession theGrouperSession) throws GrouperSessionEx return false; } - if (!provisioningContainer.isCanWriteProvisioning()) { - guiResponseJs.addAction(GuiScreenAction.newMessage(GuiMessageType.error, - TextContainer.retrieveFromRequest().getText().get("provisioningNotAllowedToWriteGroup"))); - return false; - } - return true; } }); @@ -3029,7 +2988,7 @@ public Object callback(GrouperSession theGrouperSession) throws GrouperSessionEx provisioningContainer.setUsersCount(usersCount); provisioningContainer.setGcGrouperSyncGroup(gcGrouperSyncGroup); - setGrouperProvisioningAttributeValues(GROUP, targetName); + setGrouperProvisioningAttributeValues(GROUP, targetName, loggedInSubject); return null; diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Stem.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Stem.java index 61545597a86a..560dfcf9de2c 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Stem.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Stem.java @@ -1433,6 +1433,7 @@ private void groupMembershipsInFolderFilterHelper(HttpServletRequest request, Ht String memberId = pitMembershipView.getPITMember().getSourceId(); Subject subject = memberIdToSubject.get(memberId); guiPITMembershipView.setGuiSubject(new GuiSubject(subject)); + guiPITMembershipView.setMemberId(memberId); guiPITMembershipViews.add(guiPITMembershipView); } diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Subject.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Subject.java index ebad9980fa28..7aee806390f0 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Subject.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/grouperUi/serviceLogic/UiV2Subject.java @@ -419,13 +419,24 @@ public void addToGroupFilter(HttpServletRequest request, HttpServletResponse res private static Subject retrieveSubjectHelper(HttpServletRequest request) { return retrieveSubjectHelper(request, true); } - + /** * get the subject from the request * @param request * @return the subject or null if not found */ public static Subject retrieveSubjectHelper(HttpServletRequest request, boolean displayErrorIfProblem) { + return retrieveSubjectHelper(request, displayErrorIfProblem, false); + } + + /** + * get the subject from the request + * @param request + * @param displayErrorIfProblem + * @param ignoreCachedSubjects + * @return the subject or null if not found + */ + public static Subject retrieveSubjectHelper(HttpServletRequest request, boolean displayErrorIfProblem, boolean ignoreCachedSubjects) { //initialize the bean GrouperRequestContainer grouperRequestContainer = GrouperRequestContainer.retrieveFromRequestOrCreate(); @@ -472,7 +483,8 @@ public static Subject retrieveSubjectHelper(HttpServletRequest request, boolean SubjectFinder subjectFinder = addedError ? null : new SubjectFinder().assignSourceId(sourceId) .assignSubjectId(subjectId).assignSubjectIdentifier(subjectIdentifier) .assignAllowUnresolvable(PrivilegeHelper.isWheelOrRootOrReadonlyRoot(GrouperSession.staticGrouperSession().getSubject())) - .assignSubjectIdOrIdentifier(subjectIdOrIdentifier).assignMemberId(memberId); + .assignSubjectIdOrIdentifier(subjectIdOrIdentifier).assignMemberId(memberId) + .assignIgnoreCachedSubjects(ignoreCachedSubjects); subject = subjectFinder == null ? null : subjectFinder.findSubject(); @@ -536,7 +548,7 @@ public void viewSubject(HttpServletRequest request, HttpServletResponse response grouperSession = GrouperSession.start(loggedInSubject); - subject = retrieveSubjectHelper(request); + subject = retrieveSubjectHelper(request, true, true); if (subject == null) { return; diff --git a/grouper-ui/java/src/edu/internet2/middleware/grouper/ui/tags/ConfigFormElement.java b/grouper-ui/java/src/edu/internet2/middleware/grouper/ui/tags/ConfigFormElement.java index 89abc8a0c2d5..daae127002a0 100644 --- a/grouper-ui/java/src/edu/internet2/middleware/grouper/ui/tags/ConfigFormElement.java +++ b/grouper-ui/java/src/edu/internet2/middleware/grouper/ui/tags/ConfigFormElement.java @@ -317,6 +317,27 @@ public void setAjaxCallback(String ajaxCallback) { this.ajaxCallback = ajaxCallback; } + /** + * number of levels to indent + */ + private Integer indent; + + /** + * number of levels to indent + * @return + */ + public Integer getIndent() { + return indent; + } + + /** + * number of levels to indent + * @param indent + */ + public void setIndent(Integer indent) { + this.indent = indent; + } + /** * html to render */ @@ -330,7 +351,11 @@ public void doTag() throws JspException, IOException { } field.append(""); - field.append(""); + field.append(""); field.append(""); diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/admin/adminDaemonJobAdd.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/admin/adminDaemonJobAdd.jsp index f582c9d8eaac..0deae0d036da 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/admin/adminDaemonJobAdd.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/admin/adminDaemonJobAdd.jsp @@ -135,6 +135,7 @@ ajaxCallback="ajax('../app/UiV2Admin.addDaemon?daemonConfigId=${guiGrouperDaemonConfiguration.grouperDaemonConfiguration.configId}&daemonConfigType=${guiGrouperDaemonConfiguration.grouperDaemonConfiguration['class'].name}', {formIds: 'addDaemonFormId'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/admin/adminDaemonJobEdit.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/admin/adminDaemonJobEdit.jsp index d39b2a14ef07..fcb882e79f39 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/admin/adminDaemonJobEdit.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/admin/adminDaemonJobEdit.jsp @@ -103,6 +103,7 @@ ajaxCallback="ajax('../app/UiV2Admin.editDaemon?daemonConfigId=${guiGrouperDaemonConfiguration.grouperDaemonConfiguration.configId}&daemonConfigType=${guiGrouperDaemonConfiguration.grouperDaemonConfiguration['class'].name}', {formIds: 'editDaemonFormId'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/admin/adminDaemonJobsViewLogs.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/admin/adminDaemonJobsViewLogs.jsp index bf9d43621bf0..f74b2a5f2a12 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/admin/adminDaemonJobsViewLogs.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/admin/adminDaemonJobsViewLogs.jsp @@ -8,7 +8,44 @@
  • ${textContainer.text['adminDaemonLogsBreadcrumb'] }
  • diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/editWsTrustedJwtConfigDetails.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/editWsTrustedJwtConfigDetails.jsp index 0e719672a25d..25986571b507 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/editWsTrustedJwtConfigDetails.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/editWsTrustedJwtConfigDetails.jsp @@ -72,6 +72,7 @@ ajaxCallback="ajax('../app/UiV2AuthenticationConfig.editWsTrustedJwtConfig?wsTrustedJwtConfigId=${grouperRequestContainer.authenticationContainer.guiWsTrustedJwtConfiguration.wsTrustedJwtConfiguration.configId}', {formIds: 'wsTrustedJwtConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/editWsTrustedOidcConfigDetails.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/editWsTrustedOidcConfigDetails.jsp index 1e8f39bdda09..c118ce750d7c 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/editWsTrustedOidcConfigDetails.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/editWsTrustedOidcConfigDetails.jsp @@ -73,6 +73,7 @@ ajaxCallback="ajax('../app/UiV2OidcConfig.editOidcConfig?oidcConfigId=${grouperRequestContainer.oidcConfigContainer.guiOidcConfiguration.oidcConfiguration.configId}', {formIds: 'wsTrustedJwtConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/wsTrustedJwtConfigAddHelper.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/wsTrustedJwtConfigAddHelper.jsp index 1d5e5343d552..ad0b905c3a77 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/wsTrustedJwtConfigAddHelper.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/wsTrustedJwtConfigAddHelper.jsp @@ -75,6 +75,7 @@ ajaxCallback="ajax('../app/UiV2AuthenticationConfig.addWsTrustedJwt', {formIds: 'wsTrustedJwtConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/wsTrustedOidcConfigAddHelper.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/wsTrustedOidcConfigAddHelper.jsp index 1cc558bbefcf..73406981df5b 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/wsTrustedOidcConfigAddHelper.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/authentication/wsTrustedOidcConfigAddHelper.jsp @@ -75,6 +75,7 @@ ajaxCallback="ajax('../app/UiV2OidcConfig.addOidcConfig', {formIds: 'wsTrustedOidcConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/customUi/customUiConfigAddHelper.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/customUi/customUiConfigAddHelper.jsp index a644eb98df63..8fe2a6ee2d84 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/customUi/customUiConfigAddHelper.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/customUi/customUiConfigAddHelper.jsp @@ -75,6 +75,7 @@ ajaxCallback="ajax('../app/UiV2CustomUiConfig.addCustomUiConfig', {formIds: 'customUiConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/customUi/editCustomUiConfigDetails.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/customUi/editCustomUiConfigDetails.jsp index d604364ce5cc..26f05229e533 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/customUi/editCustomUiConfigDetails.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/customUi/editCustomUiConfigDetails.jsp @@ -72,6 +72,7 @@ ajaxCallback="ajax('../app/UiV2CustomUiConfig.editCustomUiConfig?customUiConfigId=${grouperRequestContainer.customUiContainer.guiCustomUiConfiguration.customUiConfiguration.configId}', {formIds: 'customUiConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/externalSystems/editExternalSystemConfigDetails.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/externalSystems/editExternalSystemConfigDetails.jsp index add7a44b2752..61e60937e6e9 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/externalSystems/editExternalSystemConfigDetails.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/externalSystems/editExternalSystemConfigDetails.jsp @@ -76,6 +76,7 @@ ajaxCallback="ajax('../app/UiV2ExternalSystem.editExternalSystemConfigDetails?externalSystemConfigId=${grouperRequestContainer.externalSystemContainer.guiGrouperExternalSystem.grouperExternalSystem.configId}&externalSystemType=${grouperRequestContainer.externalSystemContainer.guiGrouperExternalSystem.grouperExternalSystem['class'].name}', {formIds: 'externalSystemConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/externalSystems/externalSystemConfigAddHelper.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/externalSystems/externalSystemConfigAddHelper.jsp index 3a5858a2df66..99480dd49dd2 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/externalSystems/externalSystemConfigAddHelper.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/externalSystems/externalSystemConfigAddHelper.jsp @@ -65,6 +65,7 @@ ajaxCallback="ajax('../app/UiV2ExternalSystem.addExternalSystem?externalSystemConfigId=${guiGrouperExternalSystem.grouperExternalSystem.configId}&externalSystemType=${guiGrouperExternalSystem.grouperExternalSystem['class'].name}', {formIds: 'externalSystemConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/globalAttributeResolver/editGlobalAttributeResolverConfigDetails.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/globalAttributeResolver/editGlobalAttributeResolverConfigDetails.jsp index 589913464c13..ff0b113c539e 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/globalAttributeResolver/editGlobalAttributeResolverConfigDetails.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/globalAttributeResolver/editGlobalAttributeResolverConfigDetails.jsp @@ -72,6 +72,7 @@ ajaxCallback="ajax('../app/UiV2GlobalAttributeResolverConfig.editGlobalAttributeResolverConfig?globalAttributeResolverConfigId=${grouperRequestContainer.globalAttributeResolverConfigContainer.guiGlobalAttributeResolverConfiguration.globalAttributeResolverConfiguration.configId}', {formIds: 'globalAttributeResolverConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/globalAttributeResolver/globalAttributeResolverConfigAddHelper.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/globalAttributeResolver/globalAttributeResolverConfigAddHelper.jsp index d0f8c2253d46..2c8a1fa09860 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/globalAttributeResolver/globalAttributeResolverConfigAddHelper.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/globalAttributeResolver/globalAttributeResolverConfigAddHelper.jsp @@ -75,6 +75,7 @@ ajaxCallback="ajax('../app/UiV2GlobalAttributeResolverConfig.addGlobalAttributeResolverConfig', {formIds: 'globalAttributeResolverConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/group/groupContents.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/group/groupContents.jsp index 252cd9e28f2d..fd2d692288eb 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/group/groupContents.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/group/groupContents.jsp @@ -4,7 +4,12 @@ - - + @@ -46,6 +51,14 @@ + @@ -83,6 +96,7 @@
  • ${textContainer.text['groupViewRevokeMembershipButton'] }
  • - -
  • ${textContainer.text['groupViewTraceMembershipButton'] }
  • -
    +
  • ${textContainer.text['groupViewTraceMembershipButton'] }
  • ${textContainer.text['groupViewViewGroupButton'] }
  • ${textContainer.text['groupViewMembershipAttributeAssignments'] }
  • - +
  • ${textContainer.text['provisioningMoreActionsMenuLabel'] }
  • diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/group/groupMoreActionsButtonContents.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/group/groupMoreActionsButtonContents.jsp index 590978dfd728..269fd1291ea2 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/group/groupMoreActionsButtonContents.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/group/groupMoreActionsButtonContents.jsp @@ -116,7 +116,7 @@ || grouperRequestContainer.deprovisioningContainer.canReadDeprovisioning || (grouperRequestContainer.groupContainer.canView && grouperRequestContainer.workflowContainer.canViewElectronicForm) || grouperRequestContainer.grouperLoaderContainer.canSeeLoader - || grouperRequestContainer.provisioningContainer.canReadProvisioning + || grouperRequestContainer.provisioningContainer.canReadProvisioningForGroup || grouperRequestContainer.objectTypeContainer.canReadObjectType || grouperRequestContainer.grouperReportContainer.reportingEnabled }"> @@ -151,7 +151,7 @@ >${textContainer.text['groupViewPermissionsButton'] }
    - +
  • ${textContainer.text['provisioningMoreActionsMenuLabel'] }
  • diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/group/groupNewTemplate.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/group/groupNewTemplate.jsp index 36c8b830edd6..9c4d0313c197 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/group/groupNewTemplate.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/group/groupNewTemplate.jsp @@ -52,6 +52,7 @@ hasExpressionLanguage="false" ajaxCallback="ajax('../app/UiV2Template.newTemplate?templateType=${grouperRequestContainer.groupStemTemplateContainer.templateType}', {formIds: 'newGroupTemplateFormId'}); return false;" valuesAndLabels="${guiGshTemplateInputConfig.gshTemplateInputConfig.dropdownKeysAndLabels}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/group/grouperLoaderGroupTab.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/group/grouperLoaderGroupTab.jsp index 613e84b1fb81..232ea27248f3 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/group/grouperLoaderGroupTab.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/group/grouperLoaderGroupTab.jsp @@ -386,14 +386,14 @@
    diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/gshTemplate/editGshTemplateConfigDetails.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/gshTemplate/editGshTemplateConfigDetails.jsp index 330ce6c92a99..276e9ef1f0c5 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/gshTemplate/editGshTemplateConfigDetails.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/gshTemplate/editGshTemplateConfigDetails.jsp @@ -72,6 +72,7 @@ ajaxCallback="ajax('../app/UiV2GshTemplateConfig.editGshTemplate?gshTemplateConfigId=${grouperRequestContainer.gshTemplateContainer.guiGshTemplateConfiguration.gshTemplateConfiguration.configId}', {formIds: 'gshTemplateConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/gshTemplate/gshTemplateConfigAddHelper.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/gshTemplate/gshTemplateConfigAddHelper.jsp index 4c8c13b00f88..eba213f10a5f 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/gshTemplate/gshTemplateConfigAddHelper.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/gshTemplate/gshTemplateConfigAddHelper.jsp @@ -75,6 +75,7 @@ ajaxCallback="ajax('../app/UiV2GshTemplateConfig.addGshTemplate', {formIds: 'gshTemplateConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/membership/traceMembership.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/membership/traceMembership.jsp index 79ef69db969c..c779f8297821 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/membership/traceMembership.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/membership/traceMembership.jsp @@ -3,6 +3,15 @@ <%-- for the new group or new stem button --%> +
    -

    ${textContainer.text['membershipTracePageLead'] }

    + +

    ${textContainer.text['membershipTracePageLead'] }

    - <%-- -

    Danielle Knotts is an indirect member of

    -

    Root : Departments : Information Technology : Staff

    -

    which is a direct member of

    -

    Root : Applications : Wiki : Editors

    Back to previous page -
    - --%> - <%-- note, this is generated in Java in UiV2Membership.traceMembership --%> - ${grouperRequestContainer.membershipGuiContainer.traceMembershipsString } + <%-- +

    Danielle Knotts is an indirect member of

    +

    Root : Departments : Information Technology : Staff

    +

    which is a direct member of

    +

    Root : Applications : Wiki : Editors

    Back to previous page +
    + --%> + <%-- note, this is generated in Java in UiV2Membership.traceMembership --%> + ${grouperRequestContainer.membershipGuiContainer.traceMembershipsString } +
    + +

    ${textContainer.text['pitMembershipTracePageLead'] }

    + + ${grouperRequestContainer.membershipGuiContainer.tracePITMembershipString } +
    + +

    ${textContainer.text['membershipTraceTimelinePageLead'] }

    + +
    + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +

    + +

    + + +

    ${textContainer.text['membershipTraceTimelineDescription'] }

    + + ${grouperRequestContainer.membershipGuiContainer.traceMembershipTimelineString} +
    + +
    diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigAdd.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigAdd.jsp index f1f1e3c64b7b..e8b65bf26ac7 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigAdd.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigAdd.jsp @@ -44,7 +44,6 @@
    - @@ -57,7 +56,16 @@ - + + + + + + + + + +
    + + + + + + ${textContainer.text['groupRemoveSelectedMembersButton'] } @@ -30,8 +35,8 @@ ${textContainer.text['groupViewDetailsHeaderMembership']}${textContainer.text['headerChooseAction']} ${textContainer.text['headerChooseAction']}
    ${guiPITMembershipView.getStartTimeLabel()} ${guiPITMembershipView.getEndTimeLabel()} + +
    ${textContainer.text['grouperLoaderRecentIncludeCurrent']} - + ${textContainer.text['grouperLoaderRecentIncludeCurrentTrue']} - + ${textContainer.text['grouperLoaderRecentIncludeCurrentFalse']} -
    ${textContainer.text['grouperLoaderIncludeInternalSourcesTrue']} +
    ${textContainer.text['grouperLoaderRecentIncludeCurrentDescription']}
    <%@ include file="provisionerConfigAddHelper.jsp" %> @@ -69,17 +77,32 @@ - diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigAddHelper.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigAddHelper.jsp index b84cbd8b0763..79af14ec5cf0 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigAddHelper.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigAddHelper.jsp @@ -61,7 +61,7 @@ + >${textContainer.text['provisionerStartWithOption_' += startWithConfigClass['class'].name]} @@ -164,6 +165,7 @@ ajaxCallback="ajax('../app/UiV2ProvisionerConfiguration.addProvisionerConfiguration?focusOnElementName=config_${attribute.configSuffix}&provisionerConfigId=${guiProvisionerConfiguration.provisionerConfiguration.configId}&provisionerConfigType=${guiProvisionerConfiguration.provisionerConfiguration['class'].name}', {formIds: 'provisionerConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigEdit.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigEdit.jsp index ea9bbd462b26..216eb63ed238 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigEdit.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisionerConfigEdit.jsp @@ -93,6 +93,7 @@ ajaxCallback="ajax('../app/UiV2ProvisionerConfiguration.editProvisionerConfiguration?focusOnElementName=config_${attribute.configSuffix}&provisionerConfigId=${grouperRequestContainer.provisionerConfigurationContainer.guiProvisionerConfiguration.provisionerConfiguration.configId}&provisionerConfigType=${grouperRequestContainer.provisionerConfigurationContainer.guiProvisionerConfiguration.provisionerConfiguration['class'].name}', {formIds: 'provisionerConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisioningConfigActivityGroup.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisioningConfigActivityGroup.jsp index 8ab41c80d999..5a81eebb1874 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisioningConfigActivityGroup.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisioningConfigActivityGroup.jsp @@ -24,10 +24,10 @@ - - - - + + + + @@ -123,19 +123,19 @@ - - - - + + + + @@ -128,19 +128,19 @@ - - diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/provisioning/provisioningGroupTargetDetailsHelper.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/provisioning/provisioningGroupTargetDetailsHelper.jsp index 85ecc413f1e4..9a94aef5d5e5 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/provisioning/provisioningGroupTargetDetailsHelper.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/provisioning/provisioningGroupTargetDetailsHelper.jsp @@ -162,38 +162,38 @@ - + - + - + - + diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/provisioning/provisioningSubjectMembershipMoreActionsButtonContents.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/provisioning/provisioningSubjectMembershipMoreActionsButtonContents.jsp index c95dbc7d14af..c126ea8b8b28 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/provisioning/provisioningSubjectMembershipMoreActionsButtonContents.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/provisioning/provisioningSubjectMembershipMoreActionsButtonContents.jsp @@ -8,7 +8,7 @@ - + - + - + - + diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/sqlSync/editSqlSyncConfigDetails.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/sqlSync/editSqlSyncConfigDetails.jsp index bf106ac11009..ed83e9a76c7b 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/sqlSync/editSqlSyncConfigDetails.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/sqlSync/editSqlSyncConfigDetails.jsp @@ -64,6 +64,7 @@ ajaxCallback="ajax('../app/UiV2SqlSyncConfiguration.editSqlSyncConfig?sqlSyncConfigId=${grouperRequestContainer.sqlSyncConfigurationContainer.guiSqlSyncConfiguration.sqlSyncConfiguration.configId}', {formIds: 'sqlSyncConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/sqlSync/sqlSyncConfigAddHelper.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/sqlSync/sqlSyncConfigAddHelper.jsp index d8e8fbe79036..8102284cf8eb 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/sqlSync/sqlSyncConfigAddHelper.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/sqlSync/sqlSyncConfigAddHelper.jsp @@ -75,6 +75,7 @@ ajaxCallback="ajax('../app/UiV2SqlSyncConfiguration.addSqlSyncConfiguration', {formIds: 'sqlSyncConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/stem/groupMembershipsInFolderContents.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/stem/groupMembershipsInFolderContents.jsp index 2491504996c7..e4cf47021bf8 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/stem/groupMembershipsInFolderContents.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/stem/groupMembershipsInFolderContents.jsp @@ -104,9 +104,7 @@
  • ${textContainer.text['groupViewRevokeMembershipButton'] }
  • - -
  • ${textContainer.text['groupViewTraceMembershipButton'] }
  • -
    +
  • ${textContainer.text['groupViewTraceMembershipButton'] }
  • ${textContainer.text['groupViewViewGroupButton'] }
  • diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/stem/stemMoreActionsButtonContents2.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/stem/stemMoreActionsButtonContents2.jsp index 5a8999d6c33d..08bf5c04e13e 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/stem/stemMoreActionsButtonContents2.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/stem/stemMoreActionsButtonContents2.jsp @@ -41,12 +41,14 @@ - + -
  • ${textContainer.text['stemViewCopyStemButton'] }
  • + +
  • ${textContainer.text['stemViewCopyStemButton'] }
  • +
  • -
  • ${textContainer.text['stemViewEditStemButton'] }
  • - -
  • ${textContainer.text['stemViewMoveStemButton'] }
  • + +
  • ${textContainer.text['stemViewEditStemButton'] }
  • + +
  • ${textContainer.text['stemViewMoveStemButton'] }
  • +
    - +
  • ${textContainer.text['attestationButton'] }
  • @@ -108,10 +112,10 @@
  • ${textContainer.text['deprovisioningMoreActionsMenuLabel'] }
  • - + +
  • ${textContainer.text['provisioningMoreActionsMenuLabel'] }
  • -
  • diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/subject/subjectContents.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/subject/subjectContents.jsp index 6899109a4135..091a981f94ab 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/subject/subjectContents.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/subject/subjectContents.jsp @@ -46,6 +46,7 @@ || (guiMembershipContainer.membershipContainer.membershipAssignType.immediate && guiMembershipSubjectContainer.guiGroup.canUpdate) || guiMembershipContainer.membershipContainer.membershipAssignType.nonImmediate + || guiMembershipSubjectContainer.canReadProvisioningForMembership || guiMembershipSubjectContainer.guiSubject.group}">
  • ${textContainer.text['subjectViewRevokeMembershipButton'] }
  • - -
  • ${textContainer.text['groupViewTraceMembershipButton'] }
  • -
    +
  • ${textContainer.text['groupViewTraceMembershipButton'] }
  • ${textContainer.text['groupViewViewGroupButton'] }
  • ${textContainer.text['membershipAttributeAssignmentsButton'] }
  • -
  • ${textContainer.text['subjectViewProvisioningButton'] }
  • + + +
  • ${textContainer.text['subjectViewProvisioningButton'] }
  • +
    @@ -83,4 +85,4 @@
    -
    \ No newline at end of file + diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/subject/subjectMoreActionsButtonContents.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/subject/subjectMoreActionsButtonContents.jsp index 8996222c6600..b5471e4c3733 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/subject/subjectMoreActionsButtonContents.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/subject/subjectMoreActionsButtonContents.jsp @@ -86,7 +86,7 @@
  • ${textContainer.text['visualization.title'] }
  • - +
  • ${textContainer.text['subjectViewProvisioningButton'] }
  • diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/subjectSource/subjectSourceConfigAddHelper.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/subjectSource/subjectSourceConfigAddHelper.jsp index b123f92e717a..2e2dba5a4287 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/subjectSource/subjectSourceConfigAddHelper.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/subjectSource/subjectSourceConfigAddHelper.jsp @@ -86,6 +86,7 @@ ajaxCallback="ajax('../app/UiV2SubjectSource.addSubjectSource?focusOnElementName=config_${attribute.configSuffix}&sourceConfigId=${guiSubjectSourceConfiguration.subjectSourceConfiguration.configId}&sourceConfigType=${guiSubjectSourceConfiguration.subjectSourceConfiguration['class'].name}', {formIds: 'sourceConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/subjectSource/subjectSourceEdit.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/subjectSource/subjectSourceEdit.jsp index 175d88cd18cd..3b95ee17b1cc 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/subjectSource/subjectSourceEdit.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/subjectSource/subjectSourceEdit.jsp @@ -80,6 +80,7 @@ ajaxCallback="ajax('../app/UiV2SubjectSource.editSubjectSource?focusOnElementName=config_${attribute.configSuffix}&subjectSourceId=${grouperRequestContainer.subjectSourceContainer.subjectSourceId}', {formIds: 'sourceConfigDetails'}); return false;" valuesAndLabels="${attribute.dropdownValuesAndLabels }" checkboxAttributes="${attribute.checkboxAttributes}" + indent="${attribute.configItemMetadata.indent}" /> diff --git a/grouper-ui/webapp/WEB-INF/tld/grouper-el.tld b/grouper-ui/webapp/WEB-INF/tld/grouper-el.tld index 61afa355d2e9..1d4f63a676bd 100644 --- a/grouper-ui/webapp/WEB-INF/tld/grouper-el.tld +++ b/grouper-ui/webapp/WEB-INF/tld/grouper-el.tld @@ -223,6 +223,15 @@ true + + + Number of levels to indent + + indent + false + true + + Is the field read only diff --git a/grouper-ui/webapp/WEB-INF/web.xml b/grouper-ui/webapp/WEB-INF/web.xml index 7217655f3ecc..8062bbf8f042 100644 --- a/grouper-ui/webapp/WEB-INF/web.xml +++ b/grouper-ui/webapp/WEB-INF/web.xml @@ -1,7 +1,7 @@ + version="3.0"> diff --git a/grouper-ui/webapp/grouperExternal/public/assets/js/grouperUi.js b/grouper-ui/webapp/grouperExternal/public/assets/js/grouperUi.js index f29d0535f401..351004796308 100644 --- a/grouper-ui/webapp/grouperExternal/public/assets/js/grouperUi.js +++ b/grouper-ui/webapp/grouperExternal/public/assets/js/grouperUi.js @@ -590,17 +590,22 @@ function dojoInitMenu(autoSelectNode) { return "children" in object; }, getChildren: function(object, onComplete, onError){ - // retrieve the full copy of the object - this.get(object.id).then(function(fullObject){ - // copy to the original object so it has the children array as well. - object.children = fullObject.children; - // now that full object, we should have an array of children - onComplete(fullObject.children); - }, function(error){ - // an error occurred, log it, and indicate no children - console.error(error); - onComplete([]); - }); + if (object.root && Array.isArray(object.children)) { + // already have children + onComplete(object.children); + } else { + // retrieve the full copy of the object + this.get(object.id).then(function(fullObject){ + // copy to the original object so it has the children array as well. + object.children = fullObject.children; + // now that full object, we should have an array of children + onComplete(fullObject.children); + }, function(error){ + // an error occurred, log it, and indicate no children + console.error(error); + onComplete([]); + }); + } }, getRoot: function(onItem, onError){ // get the root object, we will do a get() and callback the result @@ -2677,4 +2682,4 @@ function showLinkToRefreshProvisioningConfig(focusOnElementName, provisionerConf // sometimes window is blocked on back button $(window).unload(function() { $.unblockUI(); -}); \ No newline at end of file +}); diff --git a/grouper-webapp/pom.xml b/grouper-webapp/pom.xml index 5f6895df8d0b..dee275079178 100644 --- a/grouper-webapp/pom.xml +++ b/grouper-webapp/pom.xml @@ -24,7 +24,7 @@ edu.internet2.middleware.grouper grouper-parent - 2.5.0-SNAPSHOT + 2.6.0-SNAPSHOT ../grouper-parent diff --git a/grouper-webapp/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/grouper-webapp/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer index 9d5b5f1df302..22a3ba2ce086 100644 --- a/grouper-webapp/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer +++ b/grouper-webapp/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer @@ -1,2 +1 @@ -edu.internet2.middleware.grouper.authentication.Pac4jServletContainerInitializer -edu.internet2.middleware.grouper.j2ee.CommonServletContainerInitializer +edu.internet2.middleware.grouper.j2ee.CommonServletContainerInitializer \ No newline at end of file diff --git a/grouper-ws/grouper-ws/src/grouper-ws/edu/internet2/middleware/grouper/ws/rest/GrouperServiceRest.java b/grouper-ws/grouper-ws/src/grouper-ws/edu/internet2/middleware/grouper/ws/rest/GrouperServiceRest.java index 014bdb6887fe..364ae51bc82c 100644 --- a/grouper-ws/grouper-ws/src/grouper-ws/edu/internet2/middleware/grouper/ws/rest/GrouperServiceRest.java +++ b/grouper-ws/grouper-ws/src/grouper-ws/edu/internet2/middleware/grouper/ws/rest/GrouperServiceRest.java @@ -1441,7 +1441,7 @@ public static WsGetMembershipsResults getMemberships(GrouperVersion clientVersio wsRestGetMembershipsRequest.getServiceLookup(), wsRestGetMembershipsRequest.getPageSize(), wsRestGetMembershipsRequest.getPageNumber(), wsRestGetMembershipsRequest.getSortString(), wsRestGetMembershipsRequest.getAscending(), - wsRestGetMembershipsRequest.getPageNumberForMember(), + wsRestGetMembershipsRequest.getPageSizeForMember(), wsRestGetMembershipsRequest.getPageNumberForMember(), wsRestGetMembershipsRequest.getSortStringForMember(), wsRestGetMembershipsRequest.getAscendingForMember(), wsRestGetMembershipsRequest.getPageIsCursor(), diff --git a/grouper-ws/grouper-ws/src/grouper-ws/edu/internet2/middleware/grouper/ws/security/WsGrouperKerberosAuthentication.java b/grouper-ws/grouper-ws/src/grouper-ws/edu/internet2/middleware/grouper/ws/security/WsGrouperKerberosAuthentication.java index 5404265fdddc..37a5cf316bd1 100644 --- a/grouper-ws/grouper-ws/src/grouper-ws/edu/internet2/middleware/grouper/ws/security/WsGrouperKerberosAuthentication.java +++ b/grouper-ws/grouper-ws/src/grouper-ws/edu/internet2/middleware/grouper/ws/security/WsGrouperKerberosAuthentication.java @@ -35,6 +35,7 @@ import org.apache.commons.logging.LogFactory; import edu.internet2.middleware.grouper.cache.GrouperCache; +import edu.internet2.middleware.grouper.j2ee.Authentication; import edu.internet2.middleware.grouper.util.GrouperUtil; import edu.internet2.middleware.grouper.ws.GrouperWsConfig; import edu.internet2.middleware.grouper.ws.util.GrouperServiceUtils; @@ -82,15 +83,6 @@ public static void main(String[] args) throws Exception { /** logger */ private static final Log LOG = LogFactory.getLog(WsGrouperKerberosAuthentication.class); - /** - * this should be something like: Basic QWxhZGRabcdefGVuIHNlc2FtZQ== - * ^\\s*Basic\\s+([^\\s]+)$ - * "^\\s* Start of string and optional whitespace - * Basic\\s+ Must be basic auth, and have some whitespace after this - * ([^\\s]+)$ Capture the next non-whitespace string, then end of input - */ - private static Pattern regexPattern = Pattern.compile("^\\s*Basic\\s+([^\\s]+)$"); - /** * cache the logins in a hash cache */ @@ -122,28 +114,8 @@ public String retrieveLoggedInSubjectId(HttpServletRequest httpServletRequest) } LOG.debug("Login not in cache"); - Matcher matcher = regexPattern.matcher(authHeader); - String authHeaderBase64Part = null; - if (matcher.matches()) { - authHeaderBase64Part = matcher.group(1); - } - - //either not basic or something else wrong - if (StringUtils.isBlank(authHeaderBase64Part)) { - //dont log password - LOG.error("Cant find base64 part in auth header"); - return null; - } - - //unencrypt this - byte[] base64Bytes = authHeaderBase64Part.getBytes(); - byte[] unencodedBytes = Base64.decodeBase64(base64Bytes); - - String unencodedString = new String(unencodedBytes); - - //split based on user/pass - String user = GrouperUtil.prefixOrSuffix(unencodedString, ":", true); - String pass = GrouperUtil.prefixOrSuffix(unencodedString, ":", false); + String user = Authentication.retrieveUsername(authHeader); + String pass = Authentication.retrievePassword(authHeader); if (authenticateKerberos(user, pass)) { diff --git a/grouper-ws/grouper-ws/src/grouper-ws/edu/internet2/middleware/grouper/ws/security/WsGrouperLdapAuthentication.java b/grouper-ws/grouper-ws/src/grouper-ws/edu/internet2/middleware/grouper/ws/security/WsGrouperLdapAuthentication.java index e2d01fd4603a..5d01fe79a8b7 100644 --- a/grouper-ws/grouper-ws/src/grouper-ws/edu/internet2/middleware/grouper/ws/security/WsGrouperLdapAuthentication.java +++ b/grouper-ws/grouper-ws/src/grouper-ws/edu/internet2/middleware/grouper/ws/security/WsGrouperLdapAuthentication.java @@ -23,12 +23,9 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; -import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.commons.logging.Log; @@ -36,6 +33,7 @@ import org.ldaptive.SearchFilter; import edu.internet2.middleware.grouper.cache.GrouperCache; +import edu.internet2.middleware.grouper.j2ee.Authentication; import edu.internet2.middleware.grouper.ldap.LdapEntry; import edu.internet2.middleware.grouper.ldap.LdapSearchScope; import edu.internet2.middleware.grouper.ldap.LdapSessionUtils; @@ -69,15 +67,6 @@ public static void main(String[] args) throws Exception { /** logger */ private static final Log LOG = LogFactory.getLog(WsGrouperLdapAuthentication.class); - /** - * this should be something like: Basic QWxhZGRabcdefGVuIHNlc2FtZQ== - * ^\\s*Basic\\s+([^\\s]+)$ - * "^\\s* Start of string and optional whitespace - * Basic\\s+ Must be basic auth, and have some whitespace after this - * ([^\\s]+)$ Capture the next non-whitespace string, then end of input - */ - private static Pattern regexPattern = Pattern.compile("^\\s*Basic\\s+([^\\s]+)$"); - /** * cache the logins in a hash cache */ @@ -132,36 +121,13 @@ public String retrieveLoggedInSubjectId(HttpServletRequest httpServletRequest) } } - Matcher matcher = regexPattern.matcher(authHeader); - String authHeaderBase64Part = null; - if (matcher.matches()) { - authHeaderBase64Part = matcher.group(1); - } - - //either not basic or something else wrong - if (StringUtils.isBlank(authHeaderBase64Part)) { - //dont log password - if (LOG.isDebugEnabled()) { - debugMap.put("Cant find base64 part in auth header", true); - } - LOG.error("Cant find base64 part in auth header"); - return null; - } - - //unencrypt this - byte[] base64Bytes = authHeaderBase64Part.getBytes(); - byte[] unencodedBytes = Base64.decodeBase64(base64Bytes); - - String unencodedString = new String(unencodedBytes); - //split based on user/pass - String user = GrouperUtil.prefixOrSuffix(unencodedString, ":", true); - String pass = GrouperUtil.prefixOrSuffix(unencodedString, ":", false); + String user = Authentication.retrieveUsername(authHeader); + String pass = Authentication.retrievePassword(authHeader); if (LOG.isDebugEnabled()) { debugMap.put("user", user); } - if (authenticateLdap(user, pass)) { diff --git a/grouper/bin/gsh.sh b/grouper/bin/gsh.sh index e940f432ff53..a9028002e143 100755 --- a/grouper/bin/gsh.sh +++ b/grouper/bin/gsh.sh @@ -213,7 +213,7 @@ fi GSH=edu.internet2.middleware.grouper.app.gsh.GrouperShellWrapper -"${JAVA}" -Xms$MEM_START -Xmx$MEM_MAX -Dgrouper.home="$GROUPER_HOME/" -Dfile.encoding=utf-8 $GSH_JVMARGS -classpath "${GROUPER_CP}" $GSH "$@" +"${JAVA}" -Xms$MEM_START -Xmx$MEM_MAX -Dgrouper.home="$GROUPER_HOME/" -Dfile.encoding=utf-8 $GSH_JVMARGS $GROUPER_GSH_JVMARGS -classpath "${GROUPER_CP}" $GSH "$@" retVal=$? # handle return from either execution or bash source diff --git a/grouper/conf/grouper-loader.base.properties b/grouper/conf/grouper-loader.base.properties index 70dc8be9e296..511b868241db 100644 --- a/grouper/conf/grouper-loader.base.properties +++ b/grouper/conf/grouper-loader.base.properties @@ -1326,6 +1326,18 @@ otherJob.timeDaemon.class = edu.internet2.middleware.grouper.app.serviceLifecycl # {valueType: "cron", required: true} otherJob.timeDaemon.quartzCron = 45 * * * * ? +# Delete old sync logs +# {valueType: "class", readOnly: true, mustImplementInterface: "org.quartz.Job"} +otherJob.deleteOldSyncLogs.class = edu.internet2.middleware.grouper.app.provisioning.DeleteOldSyncLogsDaemon + +# Run the delete old sync logs daemon every minute +# {valueType: "cron", required: true} +otherJob.deleteOldSyncLogs.quartzCron = 39 41 23 * * ? + +# Keep entries for this many seconds. Default to 1 week (604800 seconds). Set to -1 to keep all (not recommended) +# {valueType: "integer", defaultValue: "604800"} +otherJob.deleteOldSyncLogs.keepEntriesForSeconds = + # Find and fix scheduler issues class # {valueType: "class", readOnly: true, mustExtendClass: "edu.internet2.middleware.grouper.app.loader.OtherJobBase", mustImplementInterface: "org.quartz.Job"} otherJob.schedulerCheckDaemon.class = edu.internet2.middleware.grouper.app.loader.GrouperDaemonSchedulerCheck @@ -1453,7 +1465,7 @@ otherJob.grouperLoaderJexlScriptFullSync.quartzCron = 31 19 * * * ? ## tableSync jobs should use class: edu.internet2.middleware.grouper.app.tableSync.TableSyncOtherJob ## and include a setting to point to the grouperClient config, if not same: otherJob..grouperClientTableSyncConfigKey = key ## this is the subtype of job to run: otherJob..syncType = fullSyncFull -## (can be: fullSyncFull, fullSyncGroupings, fullSyncChangeFlag, incrementalAllColumns, incrementalPrimaryKey) +## (can be: fullSyncFull, fullSyncGroups, fullSyncChangeFlag, incrementalAllColumns, incrementalPrimaryKey) ################################ # Object Type Job class @@ -1468,8 +1480,8 @@ otherJob.grouperLoaderJexlScriptFullSync.quartzCron = 31 19 * * * ? # {valueType: "string", required: true, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.sqlSync.SqlSyncConfiguration"} # otherJob.membershipSync.grouperClientTableSyncConfigKey = -# fullSyncFull, fullSyncGroupings, fullSyncChangeFlag, incrementalAllColumns, incrementalPrimaryKey -# {valueType: "string", required: true, formElement: "dropdown", optionValues: ["fullSyncFull", "fullSyncGroupings", "fullSyncChangeFlag", "incrementalAllColumns", "incrementalPrimaryKey"]} +# fullSyncFull, fullSyncGroups, fullSyncChangeFlag, incrementalAllColumns, incrementalPrimaryKey +# {valueType: "string", required: true, formElement: "dropdown", optionValues: ["fullSyncFull", "fullSyncGroups", "fullSyncChangeFlag", "incrementalAllColumns", "incrementalPrimaryKey"]} # otherJob.membershipSync.syncType = @@ -1486,7 +1498,7 @@ otherJob.recentMembershipsConfFull.quartzCron = 0 0 * * * ? # {valueType: "string"} otherJob.recentMembershipsConfFull.grouperClientTableSyncConfigKey = recentMembershipsConf -# fullSyncFull, fullSyncGroupings, fullSyncChangeFlag, incrementalAllColumns, incrementalPrimaryKey +# fullSyncFull, fullSyncGroups, fullSyncChangeFlag, incrementalAllColumns, incrementalPrimaryKey # {valueType: "string"} otherJob.recentMembershipsConfFull.syncType = fullSyncFull @@ -2264,6 +2276,9 @@ provisionerDefault.membershipsConvertToGroupSyncThreshold = # {valueType: "integer", defaultValue: "10000"} provisionerDefault.scoreConvertToFullSyncThreshold = +# Remove sync log rows after a certain number of days +# {valueType: "integer"} +grouper.provisioning.removeSyncLogRowsAfterDays = 7 ####################################### @@ -2283,55 +2298,55 @@ provisionerDefault.scoreConvertToFullSyncThreshold = # provisioner.genericProvisioner.entityResolver.resolveAttributesWithSQL = # Use global SQL resolver -# {valueType: "boolean", order: 406, defaultValue: "false", subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL}"} +# {valueType: "boolean", order: 406, indent: 1, defaultValue: "false", subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL}"} # provisioner.genericProvisioner.entityResolver.useGlobalSQLResolver = # Global SQL resolver -# {valueType: "string", order: 408, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && entityResolver.useGlobalSQLResolver}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.attr.resolver.SqlGlobalAttributeResolverOptionValueDriver"} +# {valueType: "string", order: 408, indent: 2, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && entityResolver.useGlobalSQLResolver}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.attr.resolver.SqlGlobalAttributeResolverOptionValueDriver"} # provisioner.genericProvisioner.entityResolver.globalSQLResolver = # SQL config id -# {valueType: "string", order: 410, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.loader.db.DatabaseGrouperExternalSystem"} +# {valueType: "string", order: 410, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.loader.db.DatabaseGrouperExternalSystem"} # provisioner.genericProvisioner.entityResolver.sqlConfigId = # Table or view name -# {valueType: "string", order: 412, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}"} +# {valueType: "string", order: 412, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}"} # provisioner.genericProvisioner.entityResolver.tableOrViewName = # Comma separated column names from the entity attributes table that need to be added as attributes in the target system -# {valueType: "string", order: 413, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}"} +# {valueType: "string", order: 413, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}"} # provisioner.genericProvisioner.entityResolver.columnNames = # Subject source id column -# {valueType: "string", order: 414, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.subject.provider.SourceManagerOptionValueDriver"} +# {valueType: "string", order: 414, indent: 1, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.subject.provider.SourceManagerOptionValueDriver"} # provisioner.genericProvisioner.entityResolver.subjectSourceIdColumn = # Subject search / matching column -# {valueType: "string", order: 416, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}"} +# {valueType: "string", order: 416, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}"} # provisioner.genericProvisioner.entityResolver.subjectSearchMatchingColumn = # SQL mapping type -# {valueType: "string", order: 418, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}", formElement: "dropdown", optionValues: ["entityAttribute", "translation"]} +# {valueType: "string", order: 418, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}", formElement: "dropdown", optionValues: ["entityAttribute", "translation"]} # provisioner.genericProvisioner.entityResolver.sqlMappingType = # SQL mapping entity attribute -# {valueType: "string", order: 420, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver && sqlMappingType == 'entityAttribute' }", formElement: "dropdown", optionValues: ['subjectId', 'subjectIdentifer0']} +# {valueType: "string", order: 420, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver && sqlMappingType == 'entityAttribute' }", formElement: "dropdown", optionValues: ['subjectId', 'subjectIdentifer0']} # provisioner.genericProvisioner.entityResolver.sqlMappingEntityAttribute = # SQL mapping expression -# {valueType: "string", order: 422, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver && sqlMappingType == 'translation' }"} +# {valueType: "string", order: 422, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver && sqlMappingType == 'translation' }"} # provisioner.genericProvisioner.entityResolver.sqlMappingExpression = # Last updated column -# {valueType: "string", order: 424, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}"} +# {valueType: "string", order: 424, indent: 1, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}"} # provisioner.genericProvisioner.entityResolver.lastUpdatedColumn = # Last updated type -# {valueType: "string", order: 426, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}", formElement: "dropdown", optionValues: ["timestamp", "millisSince1970"]} +# {valueType: "string", order: 426, indent: 1, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL && !entityResolver.useGlobalSQLResolver}", formElement: "dropdown", optionValues: ["timestamp", "millisSince1970"]} # provisioner.genericProvisioner.entityResolver.lastUpdatedType = # Select all SQL on full -# {valueType: "boolean", order: 428, defaultValue: "true", subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL}"} +# {valueType: "boolean", order: 428, indent: 1, defaultValue: "true", subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithSQL}"} # provisioner.genericProvisioner.entityResolver.selectAllSQLOnFull = # Resolve attributes with LDAP @@ -2339,67 +2354,67 @@ provisionerDefault.scoreConvertToFullSyncThreshold = # provisioner.genericProvisioner.entityResolver.resolveAttributesWithLDAP = # Use global LDAP resolver -# {valueType: "boolean", order: 432, defaultValue: "false", subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP}"} +# {valueType: "boolean", order: 432, indent: 1, defaultValue: "false", subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP}"} # provisioner.genericProvisioner.entityResolver.useGlobalLDAPResolver = # Global LDAP resolver -# {valueType: "string", order: 434, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && entityResolver.useGlobalLDAPResolver}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.attr.resolver.LdapGlobalAttributeResolverOptionValueDriver"} +# {valueType: "string", order: 434, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && entityResolver.useGlobalLDAPResolver}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.attr.resolver.LdapGlobalAttributeResolverOptionValueDriver"} # provisioner.genericProvisioner.entityResolver.globalLDAPResolver = # LDAP config id -# {valueType: "string", order: 436, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.externalSystem.LdapGrouperExternalSystem"} +# {valueType: "string", order: 436, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.externalSystem.LdapGrouperExternalSystem"} # provisioner.genericProvisioner.entityResolver.ldapConfigId = # Base DN -# {valueType: "string", order: 438, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}"} +# {valueType: "string", order: 438, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}"} # provisioner.genericProvisioner.entityResolver.baseDN = # Subject source id of subjects -# {valueType: "string", order: 439, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.subject.provider.SourceManagerOptionValueDriver"} +# {valueType: "string", order: 439, indent: 1, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.subject.provider.SourceManagerOptionValueDriver"} # provisioner.genericProvisioner.entityResolver.subjectSourceId = # Search scope -# {valueType: "string", order: 440, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}", formElement: "dropdown", optionValues: ['ONELEVEL_SCOPE', ' SUBTREE_SCOPE']} +# {valueType: "string", order: 440, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}", formElement: "dropdown", optionValues: ['ONELEVEL_SCOPE', 'SUBTREE_SCOPE']} # provisioner.genericProvisioner.entityResolver.searchScope = # Filter part -# {valueType: "string", order: 442, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}"} +# {valueType: "string", order: 442, indent: 1, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}"} # provisioner.genericProvisioner.entityResolver.filterPart = # Attributes -# {valueType: "string", order: 444, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}"} +# {valueType: "string", order: 444, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}"} # provisioner.genericProvisioner.entityResolver.attributes = # Attributes -# {valueType: "string", order: 444, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}"} +# {valueType: "string", order: 444, indent: 1, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}"} # provisioner.genericProvisioner.entityResolverr.multiValuedLdapAttributes = # LDAP matching / search attribute -# {valueType: "string", order: 446, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}"} +# {valueType: "string", order: 446, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}"} # provisioner.genericProvisioner.entityResolver.ldapMatchingSearchAttribute = # LDAP mapping type -# {valueType: "string", order: 448, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}", formElement: "dropdown", optionValues: ["entityAttribute", "translation"]} +# {valueType: "string", order: 448, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}", formElement: "dropdown", optionValues: ["entityAttribute", "translation"]} # provisioner.genericProvisione.entityResolverr.ldapMappingType = # LDAP mapping entity attribute -# {valueType: "string", order: 450, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver && entityResolver.ldapMappingType == 'entityAttribute'}", formElement: "dropdown", optionValues: ['subjectId', 'subjectIdentifier0']} +# {valueType: "string", order: 450, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver && entityResolver.ldapMappingType == 'entityAttribute'}", formElement: "dropdown", optionValues: ['subjectId', 'subjectIdentifier0']} # provisioner.genericProvisioner.entityResolver.ldapMappingEntityAttribute = # LDAP matching expression -# {valueType: "string", order: 452, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver && entityResolver.ldapMappingType == 'translation'}"} +# {valueType: "string", order: 452, indent: 1, required: true, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver && entityResolver.ldapMappingType == 'translation'}"} # provisioner.genericProvisioner.entityResolver.ldapMatchingExpression = # Filter all LDAP on full -# {valueType: "boolean", order: 454, defaultValue: "true", subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP}"} +# {valueType: "boolean", order: 454, indent: 1, defaultValue: "true", subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP}"} # provisioner.genericProvisioner.entityResolver.filterAllLDAPOnFull = # Last updated attribute -# {valueType: "string", order: 456, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}"} +# {valueType: "string", order: 456, indent: 1, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}"} # provisioner.genericProvisioner.entityResolver.lastUpdatedAttribute = # LDAP last updated format -# {valueType: "string", order: 458, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}", formElement: "dropdown", optionValues: ["default", "activeDirectory"]} +# {valueType: "string", order: 458, indent: 1, subSection: "entityAttributes", showEl: "${entityResolver.entityAttributesNotInSubjectSource && entityResolver.resolveAttributesWithLDAP && !entityResolver.useGlobalLDAPResolver}", formElement: "dropdown", optionValues: ["default", "activeDirectory"]} # provisioner.genericProvisioner.entityResolver.lastUpdatedFormat = @@ -2417,59 +2432,52 @@ provisionerDefault.scoreConvertToFullSyncThreshold = # provisioner.genericProvisioner.customizeMembershipCrud = # Select memberships -# {valueType: "boolean", order: 1500, defaultValue: "true", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud}"} +# {valueType: "boolean", order: 1500, indent: 1, defaultValue: "true", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud}"} # provisioner.genericProvisioner.selectMemberships = # Insert memberships -# {valueType: "boolean", order: 2500, defaultValue: "true", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud}"} +# {valueType: "boolean", order: 2500, indent: 1, defaultValue: "true", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud}"} # provisioner.genericProvisioner.insertMemberships = # Delete memberships -# {valueType: "boolean", order: 3500, defaultValue: "true", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud}"} +# {valueType: "boolean", order: 3500, indent: 1, defaultValue: "true", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud}"} # provisioner.genericProvisioner.deleteMemberships = # Delete memberships if not exist in grouper -# {valueType: "boolean", order: 4500, defaultValue: "false", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud && deleteMemberships}"} +# {valueType: "boolean", order: 4500, indent: 2, defaultValue: "false", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud && deleteMemberships}"} # provisioner.genericProvisioner.deleteMembershipsIfNotExistInGrouper = # Delete memberships if deleted in grouper -# {valueType: "boolean", order: 5500, defaultValue: "false", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud && deleteMemberships && !deleteMembershipsIfNotExistInGrouper}"} +# {valueType: "boolean", order: 5500, indent: 2, defaultValue: "false", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud && deleteMemberships && !deleteMembershipsIfNotExistInGrouper}"} # provisioner.genericProvisioner.deleteMembershipsIfGrouperDeleted = # Delete memberships if deleted in grouper -# {valueType: "boolean", order: 5600, defaultValue: "true", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud && deleteMemberships && !deleteMembershipsIfNotExistInGrouper && !deleteMembershipsIfGrouperDeleted}"} +# {valueType: "boolean", order: 5600, indent: 2, defaultValue: "true", subSection: "membership", showEl: "${operateOnGrouperMemberships && customizeMembershipCrud && deleteMemberships && !deleteMembershipsIfNotExistInGrouper && !deleteMembershipsIfGrouperDeleted}"} # provisioner.genericProvisioner.deleteMembershipsIfGrouperCreated = +# Advanced options, note, there might not be any +# {valueType: "boolean", order: 5625, defaultValue: "false", subSection: "membership", showEl: "${operateOnGrouperMemberships}"} +# provisioner.genericProvisioner.membershipAdvancedOptions = + # number of attributes for memberships -# {valueType: "integer", order: 5650, subSection: "membership", defaultValue: "0", showEl:"${operateOnGrouperMemberships && provisioningType == 'membershipObjects'}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } +# {valueType: "integer", order: 5700, subSection: "membership", defaultValue: "0", showEl:"${operateOnGrouperMemberships && provisioningType == 'membershipObjects'}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } # provisioner.genericProvisioner.numberOfMembershipAttributes = # Name of the attribute # {valueType: "string", order: 5710, required: true, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.name = - # Translate type -# {valueType: "string", order: 5720, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$}", formElement: "dropdown", optionValues: ["grouperProvisioningGroupField", "groupSyncField", "grouperProvisioningEntityField", "memberSyncField", "staticValues", "translationScript"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "string", order: 5720, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$}", formElement: "dropdown", optionValues: ["grouperProvisioningGroupField", "grouperProvisioningEntityField", "staticValues", "translationScript"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.translateExpressionType = - -# During the translation, use this sync field. If not using a built-in (e.g. subjectId), you can map an entity field to a gcGrouperSyncMember field -# {valueType: "string", required: true, order: 5724, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.translateExpressionType == 'memberSyncField'}", formElement: "dropdown", optionValues: ["memberId", "subjectId", "subjectIdentifier", "memberFromId2", "memberFromId3", "memberToId2", "memberToId3"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetMembershipAttribute.$i$.translateFromMemberSyncField = - -# During the translation, use this sync field. If not using a built-in (e.g. subjectId), you can map an entity field to a gcGrouperSyncMember field -# {valueType: "string", required: true, order: 5728, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.translateExpressionType == 'groupSyncField'}", formElement: "dropdown", optionValues: ["groupId", "groupIdIndex", "groupExtension", "groupName", "groupFromId2", "groupFromId3", "groupToId2", "groupToId3"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetMembershipAttribute.$i$.translateFromGroupSyncField = - - # Translate from field -# {valueType: "string", order: 5734, required: true, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.translateExpressionType == 'grouperProvisioningGroupField'}", formElement: "dropdown", optionValues: ["id", "idIndex", "idIndexString", "displayExtension", "displayName", "extension", "name", "description"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "string", order: 5734, required: true, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.translateExpressionType == 'grouperProvisioningGroupField'}", formElement: "dropdown", optionValues: ["id", "idIndex", "idIndexString", "displayExtension", "displayName", "extension", "groupAttributeValueCache0", "groupAttributeValueCache1", "groupAttributeValueCache2", "groupAttributeValueCache3", "name", "description"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.translateFromGrouperProvisioningGroupField = # Translate from field -# {valueType: "string", order: 5738, required: true, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.translateExpressionType == 'grouperProvisioningEntityField'}", formElement: "dropdown", optionValues: ["id", "email", "loginid", "name", "subjectId", "subjectSourceId", "description", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "string", order: 5738, required: true, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.translateExpressionType == 'grouperProvisioningEntityField'}", formElement: "dropdown", optionValues: ["description", "email", "entityAttributeValueCache0", "entityAttributeValueCache1", "entityAttributeValueCache2", "entityAttributeValueCache3", "id", "memberId", "name", "subjectId", "subjectSourceId", "subjectIdentifier", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.translateFromGrouperProvisioningEntityField = # Translate from static values @@ -2483,82 +2491,74 @@ provisionerDefault.scoreConvertToFullSyncThreshold = # Advanced options # {valueType: "boolean", order: 5770, defaultValue: "false", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetMembershipAttribute.$i$.showAdvancedMembershipAttribute = +# provisioner.genericProvisioner.targetMembershipAttribute.$i$.showAdvancedAttribute = # Show membership attribute crud -# {valueType: "boolean", order: 5820, defaultValue: "false", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "boolean", order: 5820, indent: 1, defaultValue: "false", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedAttribute}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.showAttributeCrud = # Select attribute? -# {valueType: "boolean", order: 5880, defaultValue: "true", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && (selectMemberships == null || selectMemberships) && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute && targetMembershipAttribute.$i$.showAttributeCrud}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "boolean", order: 5880, indent: 2, defaultValue: "true", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && (selectMemberships == null || selectMemberships) && targetMembershipAttribute.$i$.showAdvancedAttribute && targetMembershipAttribute.$i$.showAttributeCrud}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.select = # Insert attribute? -# {valueType: "boolean", order: 5900, defaultValue: "true", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && (insertMemberships == null || insertMemberships) && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute && targetMembershipAttribute.$i$.showAttributeCrud}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "boolean", order: 5900, indent: 2, defaultValue: "true", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && (insertMemberships == null || insertMemberships) && targetMembershipAttribute.$i$.showAdvancedAttribute && targetMembershipAttribute.$i$.showAttributeCrud}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.insert = # Show membership attribute validation -# {valueType: "boolean", order: 5925, defaultValue: "false", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "boolean", order: 5925, indent: 1, defaultValue: "false", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedAttribute}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.showAttributeValueSettings = # Value type -# {valueType: "string", order: 5950, defaultValue: "string", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute && targetMembershipAttribute.$i$.showAttributeValueSettings}", formElement: "dropdown", optionValues: ["string", "long", "int"], repeatGroup: "targetMembershipAttribute", repeatCount: 20 } +# {valueType: "string", order: 5950, indent: 2, defaultValue: "string", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedAttribute && targetMembershipAttribute.$i$.showAttributeValueSettings}", formElement: "dropdown", optionValues: ["string", "long", "int"], repeatGroup: "targetMembershipAttribute", repeatCount: 20 } # provisioner.genericProvisioner.targetMembershipAttribute.$i$.valueType = # Ignore this group if this attribute matches any of these values (comma separated) -# {valueType: "string", order: 6050, multiple: true, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute && targetMembershipAttribute.$i$.showAttributeValueSettings}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "string", order: 6050, indent: 2, multiple: true, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedAttribute && targetMembershipAttribute.$i$.showAttributeValueSettings}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.ignoreIfMatchesValue = # Default value if there is not a value -# {valueType: "string", order: 6075, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute && targetMembershipAttribute.$i$.showAttributeValueSettings}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "string", order: 6075, indent: 2, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedAttribute && targetMembershipAttribute.$i$.showAttributeValueSettings}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.defaultValue = # Show membership attribute validation -# {valueType: "boolean", order: 6080, defaultValue: "false", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "boolean", order: 6080, indent: 1, defaultValue: "false", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedAttribute}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.showAttributeValidation = # If a value is required to provision this group -# {valueType: "boolean", order: 6100, defaultValue: "false", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute && targetMembershipAttribute.$i$.showAttributeValidation}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "boolean", order: 6100, indent: 2, defaultValue: "false", showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedAttribute && targetMembershipAttribute.$i$.showAttributeValidation}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.required = # Maximum length of this attribute to be valid for provisioning -# {valueType: "integer", order: 6125, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute && targetMembershipAttribute.$i$.showAttributeValidation}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "integer", order: 6125, indent: 2, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedAttribute && targetMembershipAttribute.$i$.showAttributeValidation}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.maxlength = # Validate value with jexl to see if valid for provisioning, the variable 'value' represents the current value. return true if valid and false if invalid -# {valueType: "string", order: 6150, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute && targetMembershipAttribute.$i$.showAttributeValidation}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "string", order: 6150, indent: 2, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.showAdvancedAttribute && targetMembershipAttribute.$i$.showAttributeValidation}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.validExpression = # Translate expression create only type -# {valueType: "string", order: 6175, required: false, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.insert && targetMembershipAttribute.$i$.update && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute}", formElement: "dropdown", optionValues: ["grouperProvisioningGroupField", "groupSyncField", "grouperProvisioningEntityField", "memberSyncField", "staticValues", "translationScript"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "string", order: 6175, indent: 1, required: false, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && (!customizeMembershipCrud || targetMembershipAttribute.$i$.insert) && targetMembershipAttribute.$i$.showAdvancedAttribute}", formElement: "dropdown", optionValues: ["grouperProvisioningGroupField", "grouperProvisioningEntityField", "staticValues", "translationScript"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.translateExpressionTypeCreateOnly = -# During the translation, use this sync field. If not using a built-in (e.g. subjectId), you can map an entity field to a gcGrouperSyncMember field -# {valueType: "string", required: true, order: 6180, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.translateExpressionTypeCreateOnly == 'memberSyncField' && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute}", formElement: "dropdown", optionValues: ["memberId", "subjectId", "subjectIdentifier", "memberFromId2", "memberFromId3", "memberToId2", "memberToId3"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetMembershipAttribute.$i$.translateFromMemberSyncFieldCreateOnly = - -# During the translation, use this sync field. If not using a built-in (e.g. subjectId), you can map an entity field to a gcGrouperSyncMember field -# {valueType: "string", required: true, order: 6185, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.translateExpressionTypeCreateOnly == 'groupSyncField' && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute}", formElement: "dropdown", optionValues: ["groupId", "groupIdIndex", "groupExtension", "groupName", "groupFromId2", "groupFromId3", "groupToId2", "groupToId3"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetMembershipAttribute.$i$.translateFromGroupSyncFieldCreateOnly = - # Translate from field create only -# {valueType: "string", order: 6200, required: true, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.translateExpressionTypeCreateOnly == 'grouperProvisioningGroupField' && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute}", formElement: "dropdown", optionValues: ["id", "idIndex", "idIndexString", "displayExtension", "displayName", "extension", "name", "description"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "string", order: 6200, indent: 1, required: true, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && (!customizeMembershipCrud || targetMembershipAttribute.$i$.insert) && targetMembershipAttribute.$i$.translateExpressionTypeCreateOnly == 'grouperProvisioningGroupField' && targetMembershipAttribute.$i$.showAdvancedAttribute}", formElement: "dropdown", optionValues: ["description", "displayExtension", "displayName", "extension", "groupAttributeValueCache0", "groupAttributeValueCache1", "groupAttributeValueCache2", "groupAttributeValueCache3", "id", "idIndex", "idIndexString", "name"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.translateFromGrouperProvisioningGroupFieldCreateOnly = # Translate from field create only -# {valueType: "string", order: 6250, required: true, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.translateExpressionTypeCreateOnly == 'grouperProvisioningEntityField' && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute}", formElement: "dropdown", optionValues: ["id", "email", "loginid", "name", "subjectId", "subjectSourceId", "description", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "string", order: 6250, indent: 1, required: true, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && (!customizeMembershipCrud || targetMembershipAttribute.$i$.insert) && targetMembershipAttribute.$i$.translateExpressionTypeCreateOnly == 'grouperProvisioningEntityField' && targetMembershipAttribute.$i$.showAdvancedAttribute}", formElement: "dropdown", optionValues: ["description", "email", "entityAttributeValueCache0", "entityAttributeValueCache1", "entityAttributeValueCache2", "entityAttributeValueCache3", "id", "memberId", "name", "subjectId", "subjectSourceId", "subjectIdentifier", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"], repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.translateFromGrouperProvisioningEntityFieldCreateOnly = # Translate from static values create only -# {valueType: "string", order: 6275, required: true, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.translateExpressionTypeCreateOnly == 'staticValues' && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "string", order: 6275, indent: 1, required: true, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && (!customizeMembershipCrud || targetMembershipAttribute.$i$.insert) && targetMembershipAttribute.$i$.translateExpressionTypeCreateOnly == 'staticValues' && targetMembershipAttribute.$i$.showAdvancedAttribute}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.translateFromStaticValuesCreateOnly = # Translate expression create only -# {valueType: "string", order: 6300, required: false, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && targetMembershipAttribute.$i$.insert && targetMembershipAttribute.$i$.update && targetMembershipAttribute.$i$.translateExpressionTypeCreateOnly == 'translationScript' && targetMembershipAttribute.$i$.showAdvancedMembershipAttribute}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} +# {valueType: "string", order: 6300, indent: 1, required: false, showEl: "${operateOnGrouperMemberships && numberOfMembershipAttributes > $i$ && (!customizeMembershipCrud || targetMembershipAttribute.$i$.insert) && targetMembershipAttribute.$i$.translateExpressionTypeCreateOnly == 'translationScript' && targetMembershipAttribute.$i$.showAdvancedAttribute}", repeatGroup: "targetMembershipAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetMembershipAttribute.$i$.translateExpressionCreateOnly = # Operate on grouper groups @@ -2570,31 +2570,31 @@ provisionerDefault.scoreConvertToFullSyncThreshold = # provisioner.genericProvisioner.customizeGroupCrud = # Select groups -# {valueType: "boolean", order: 8500, defaultValue: "true", subSection: "group", showEl: "${operateOnGrouperGroups && customizeGroupCrud}"} +# {valueType: "boolean", order: 8500, indent: 1, defaultValue: "true", subSection: "group", showEl: "${operateOnGrouperGroups && customizeGroupCrud}"} # provisioner.genericProvisioner.selectGroups = # Insert groups -# {valueType: "boolean", order: 9000, subSection: "group", defaultValue: "true", showEl: "${operateOnGrouperGroups && customizeGroupCrud}"} +# {valueType: "boolean", order: 9000, indent: 1, subSection: "group", defaultValue: "true", showEl: "${operateOnGrouperGroups && customizeGroupCrud}"} # provisioner.genericProvisioner.insertGroups = # Delete groups -# {valueType: "boolean", order: 9500, defaultValue: "true", subSection: "group", showEl: "${operateOnGrouperGroups && customizeGroupCrud}"} +# {valueType: "boolean", order: 9500, indent: 1, defaultValue: "true", subSection: "group", showEl: "${operateOnGrouperGroups && customizeGroupCrud}"} # provisioner.genericProvisioner.deleteGroups = # Delete groups if not exist in grouper -# {valueType: "boolean", order: 10000, defaultValue: "false", subSection: "group", showEl: "${operateOnGrouperGroups && customizeGroupCrud && deleteGroups}"} +# {valueType: "boolean", order: 10000, indent: 2, defaultValue: "false", subSection: "group", showEl: "${operateOnGrouperGroups && customizeGroupCrud && deleteGroups}"} # provisioner.genericProvisioner.deleteGroupsIfNotExistInGrouper = # Delete groups if deleted in grouper -# {valueType: "boolean", order: 10500, defaultValue: "false", subSection: "group", showEl: "${operateOnGrouperGroups && customizeGroupCrud && deleteGroups && deleteGroupsIfNotExistInGrouper == false}"} +# {valueType: "boolean", order: 10500, indent: 2, defaultValue: "false", subSection: "group", showEl: "${operateOnGrouperGroups && customizeGroupCrud && deleteGroups && deleteGroupsIfNotExistInGrouper == false}"} # provisioner.genericProvisioner.deleteGroupsIfGrouperDeleted = # Delete groups if not exist in grouper -# {valueType: "boolean", order: 10600, defaultValue: "true", subSection: "group", showEl: "${operateOnGrouperGroups && customizeGroupCrud && deleteGroups && deleteGroupsIfNotExistInGrouper == false && deleteGroupsIfGrouperDeleted == false}"} +# {valueType: "boolean", order: 10600, indent: 2, defaultValue: "true", subSection: "group", showEl: "${operateOnGrouperGroups && customizeGroupCrud && deleteGroups && deleteGroupsIfNotExistInGrouper == false && deleteGroupsIfGrouperDeleted == false}"} # provisioner.genericProvisioner.deleteGroupsIfGrouperCreated = # Update groups -# {valueType: "boolean", order: 11500, defaultValue: "false", subSection: "group", showEl: "${operateOnGrouperGroups && customizeGroupCrud}"} +# {valueType: "boolean", order: 11500, indent: 1, defaultValue: "true", subSection: "group", showEl: "${operateOnGrouperGroups && customizeGroupCrud}"} # provisioner.genericProvisioner.updateGroups = # if the groups need to be resolved in target @@ -2609,115 +2609,94 @@ provisionerDefault.scoreConvertToFullSyncThreshold = # {valueType: "string", order: 21000, required: true, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.name = -# Membership attribute? -# {valueType: "boolean", order: 22200, defaultValue: "false", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && provisioningType == 'groupAttributes' && targetGroupAttribute.$i$.multiValued}", repeatGroup: "targetGroupAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetGroupAttribute.$i$.membershipAttribute = +# Translate type +# {valueType: "string", order: 21200, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$}", formElement: "dropdown", optionValues: ["grouperProvisioningGroupField", "staticValues", "translationScript"], repeatGroup: "targetGroupAttribute", repeatCount: 20} +# provisioner.genericProvisioner.targetGroupAttribute.$i$.translateExpressionType = -# During the translation, use this sync field. If not using a built-in (e.g. subjectId), you can map an entity field to a gcGrouperSyncMember field -# {valueType: "string", required: true, order: 22300, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.membershipAttribute && provisioningType == 'groupAttributes' && targetGroupAttribute.$i$.multiValued}", formElement: "dropdown", optionValues: ["memberId", "subjectId", "subjectIdentifier", "memberFromId2", "memberFromId3", "memberToId2", "memberToId3"], repeatGroup: "targetGroupAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetGroupAttribute.$i$.translateFromMemberSyncField = +# Translate from field +# {valueType: "string", order: 21400, required: true, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.translateExpressionType == 'grouperProvisioningGroupField'}", formElement: "dropdown", optionValues: ["id", "idIndex", "idIndexString", "displayExtension", "displayName", "extension", "name", "description"], repeatGroup: "targetGroupAttribute", repeatCount: 20} +# provisioner.genericProvisioner.targetGroupAttribute.$i$.translateFromGrouperProvisioningGroupField = + +# Translate from static values +# {valueType: "string", order: 21600, required: true, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.translateExpressionType == 'staticValues'}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# provisioner.genericProvisioner.targetGroupAttribute.$i$.translateFromStaticValues = + +# Translate expression +# {valueType: "string", order: 21800, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.translateExpressionType == 'translationScript'}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# provisioner.genericProvisioner.targetGroupAttribute.$i$.translateExpression = + +# Advanced options +# {valueType: "boolean", order: 22200, defaultValue: "false", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# provisioner.genericProvisioner.targetGroupAttribute.$i$.showAdvancedAttribute = # Show group attribute crud -# {valueType: "boolean", order: 22400, defaultValue: "false", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "boolean", order: 22400, indent: 1, defaultValue: "false", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.showAttributeCrud = # Select attribute? -# {valueType: "boolean", order: 22500, defaultValue: "true", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && (selectGroups == null || selectGroups) && targetGroupAttribute.$i$.showAttributeCrud}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "boolean", order: 22500, indent: 2, defaultValue: "true", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && (selectGroups == null || selectGroups) && targetGroupAttribute.$i$.showAttributeCrud}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.select = # Insert attribute? -# {valueType: "boolean", order: 23000, defaultValue: "true", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && (insertGroups == null || insertGroups) && targetGroupAttribute.$i$.showAttributeCrud}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "boolean", order: 23000, indent: 2, defaultValue: "true", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && (insertGroups == null || insertGroups) && targetGroupAttribute.$i$.showAttributeCrud}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.insert = # Update attribute? -# {valueType: "boolean", order: 24000, defaultValue: "true", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && (updateGroups == null || updateGroups) && targetGroupAttribute.$i$.showAttributeCrud}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "boolean", order: 24000, indent: 2, defaultValue: "true", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && (updateGroups == null || updateGroups) && targetGroupAttribute.$i$.showAttributeCrud}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.update = -# Matching id attribute? -# {valueType: "boolean", order: 24010, defaultValue: "false", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$}", repeatGroup: "targetGroupAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetGroupAttribute.$i$.matchingId = - -# Show membership attribute validation -# {valueType: "boolean", order: 25000, defaultValue: "false", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# Show group attribute validation +# {valueType: "boolean", order: 25000, indent: 1, defaultValue: "false", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.showAttributeValueSettings = # Value type -# {valueType: "string", order: 25100, defaultValue: "string", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAttributeValueSettings}", formElement: "dropdown", optionValues: ["string", "long", "int"], repeatGroup: "targetGroupAttribute", repeatCount: 20 } +# {valueType: "string", order: 25100, indent: 2, defaultValue: "string", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && targetGroupAttribute.$i$.showAttributeValueSettings}", formElement: "dropdown", optionValues: ["string", "long", "int"], repeatGroup: "targetGroupAttribute", repeatCount: 20 } # provisioner.genericProvisioner.targetGroupAttribute.$i$.valueType = # Multi-valued attribute? -# {valueType: "boolean", order: 25200, defaultValue: "false", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAttributeValueSettings}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "boolean", order: 25200, indent: 2, defaultValue: "false", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && targetGroupAttribute.$i$.showAttributeValueSettings}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.multiValued = # Default value if there is not a value -# {valueType: "string", order: 25500, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAttributeValueSettings}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "string", order: 25500, indent: 2, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && targetGroupAttribute.$i$.showAttributeValueSettings}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.defaultValue = # Ignore this group if this attribute matches any of these values (comma separated) -# {valueType: "string", order: 26000, multiple: true, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAttributeValueSettings}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "string", order: 26000, indent: 2, multiple: true, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && targetGroupAttribute.$i$.showAttributeValueSettings}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.ignoreIfMatchesValue = # Show group attribute validation -# {valueType: "boolean", order: 29200, defaultValue: "false", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "boolean", order: 29200, indent: 1, defaultValue: "false", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.showAttributeValidation = # If a value is required to provision this group -# {valueType: "boolean", order: 29250, defaultValue: "false", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAttributeValidation}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "boolean", order: 29250, indent: 2, defaultValue: "false", showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && targetGroupAttribute.$i$.showAttributeValidation}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.required = # Maximum length of this field to be valid for provisioning -# {valueType: "integer", order: 29500, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAttributeValidation}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "integer", order: 29500, indent: 2, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && targetGroupAttribute.$i$.showAttributeValidation}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.maxlength = # Validate value with jexl to see if valid for provisioning, the variable 'value' represents the current value. return true if valid and false if invalid -# {valueType: "string", order: 29750, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAttributeValidation}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "string", order: 29750, indent: 2, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && targetGroupAttribute.$i$.showAttributeValidation}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.validExpression = -# Search attribute? -# {valueType: "boolean", order: 31000, defaultValue: "false", showEl: "${operateOnGrouperGroups && selectGroups && numberOfGroupAttributes > $i$ && !targetGroupAttribute.$i$.multiValued && targetGroupAttribute.$i$.select}", repeatGroup: "targetGroupAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetGroupAttribute.$i$.searchAttribute = - # Translate expression create only type -# {valueType: "string", order: 31300, required: false, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.membershipAttribute == false && targetGroupAttribute.$i$.insert && targetGroupAttribute.$i$.update}", formElement: "dropdown", optionValues: ["grouperProvisioningGroupField", "staticValues", "translationScript"], repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "string", order: 31300, indent: 1, required: false, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && (!customizeGroupCrud || targetGroupAttribute.$i$.insert)}", formElement: "dropdown", optionValues: ["grouperProvisioningGroupField", "staticValues", "translationScript"], repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.translateExpressionTypeCreateOnly = # Translate from field create only -# {valueType: "string", order: 31600, required: true, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && !targetGroupAttribute.$i$.membershipAttribute && targetGroupAttribute.$i$.translateExpressionTypeCreateOnly == 'grouperProvisioningGroupField'}", formElement: "dropdown", optionValues: ["id", "idIndex", "idIndexString", "displayExtension", "displayName", "extension", "name", "description"], repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "string", order: 31600, indent: 1, required: true, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && (!customizeGroupCrud || targetGroupAttribute.$i$.insert) && targetGroupAttribute.$i$.translateExpressionTypeCreateOnly == 'grouperProvisioningGroupField'}", formElement: "dropdown", optionValues: ["id", "idIndex", "idIndexString", "displayExtension", "displayName", "extension", "name", "description"], repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.translateFromGrouperProvisioningGroupFieldCreateOnly = # Translate from static values create only -# {valueType: "string", order: 31800, required: true, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && !targetGroupAttribute.$i$.membershipAttribute && targetGroupAttribute.$i$.translateExpressionTypeCreateOnly == 'staticValues'}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "string", order: 31800, indent: 1, required: true, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && (!customizeGroupCrud || targetGroupAttribute.$i$.insert) && targetGroupAttribute.$i$.translateExpressionTypeCreateOnly == 'staticValues'}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.translateFromStaticValuesCreateOnly = # Translate expression create only -# {valueType: "string", order: 32000, required: false, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.membershipAttribute == false && targetGroupAttribute.$i$.insert && targetGroupAttribute.$i$.update && targetGroupAttribute.$i$.translateExpressionTypeCreateOnly == 'translationScript'}", repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "string", order: 32000, indent: 1, required: false, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.showAdvancedAttribute && (!customizeGroupCrud || targetGroupAttribute.$i$.insert) && targetGroupAttribute.$i$.translateExpressionTypeCreateOnly == 'translationScript'}", repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetGroupAttribute.$i$.translateExpressionCreateOnly = -# Translate type -# {valueType: "string", order: 32300, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.membershipAttribute == false}", formElement: "dropdown", optionValues: ["grouperProvisioningGroupField", "staticValues", "translationScript"], repeatGroup: "targetGroupAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetGroupAttribute.$i$.translateExpressionType = - -# Translate from field -# {valueType: "string", order: 32600, required: true, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && !targetGroupAttribute.$i$.membershipAttribute && targetGroupAttribute.$i$.translateExpressionType == 'grouperProvisioningGroupField'}", formElement: "dropdown", optionValues: ["id", "idIndex", "idIndexString", "displayExtension", "displayName", "extension", "name", "description"], repeatGroup: "targetGroupAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetGroupAttribute.$i$.translateFromGrouperProvisioningGroupField = - -# Translate from static values -# {valueType: "string", order: 32800, required: true, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && !targetGroupAttribute.$i$.membershipAttribute && targetGroupAttribute.$i$.translateExpressionType == 'staticValues'}", repeatGroup: "targetGroupAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetGroupAttribute.$i$.translateFromStaticValues = - -# Translate expression -# {valueType: "string", order: 33000, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && targetGroupAttribute.$i$.membershipAttribute == false && targetGroupAttribute.$i$.translateExpressionType == 'translationScript'}", repeatGroup: "targetGroupAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetGroupAttribute.$i$.translateExpression = - -# During 'group link' copy this value from the target into the sync field -# {valueType: "string", order: 35500, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && !targetGroupAttribute.$i$.membershipAttribute && hasTargetGroupLink}", formElement: "dropdown", optionValues: ["groupFromId2", "groupFromId3", "groupToId2", "groupToId3"], repeatGroup: "targetGroupAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetGroupAttribute.$i$.translateToGroupSyncField = - -# After calculating the Grouper value store that in a sync field -# {valueType: "string", order: 35700, showEl: "${operateOnGrouperGroups && numberOfGroupAttributes > $i$ && !targetGroupAttribute.$i$.membershipAttribute}", formElement: "dropdown", optionValues: ["groupFromId2", "groupFromId3", "groupToId2", "groupToId3"], repeatGroup: "targetGroupAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetGroupAttribute.$i$.translateGrouperToGroupSyncField = - - # Operate on grouper entities # {valueType: "boolean", order: 37000, defaultValue: "false", subSection: "entity"} # provisioner.genericProvisioner.operateOnGrouperEntities = @@ -2731,184 +2710,478 @@ provisionerDefault.scoreConvertToFullSyncThreshold = # provisioner.genericProvisioner.customizeEntityCrud = # Select entities -# {valueType: "boolean", order: 37500, defaultValue: "true", subSection: "entity", showEl: "${operateOnGrouperEntities && customizeEntityCrud}"} +# {valueType: "boolean", order: 37500, indent: 1, defaultValue: "true", subSection: "entity", showEl: "${operateOnGrouperEntities && customizeEntityCrud}"} # provisioner.genericProvisioner.selectEntities = # Insert entities -# {valueType: "boolean", order: 38000, subSection: "entity", defaultValue: "true", showEl: "${operateOnGrouperEntities && customizeEntityCrud && makeChangesToEntities}"} +# {valueType: "boolean", order: 38000, indent: 1, subSection: "entity", defaultValue: "true", showEl: "${operateOnGrouperEntities && customizeEntityCrud && makeChangesToEntities}"} # provisioner.genericProvisioner.insertEntities = # Delete entities -# {valueType: "boolean", order: 39000, subSection: "entity", defaultValue: "true", showEl: "${operateOnGrouperEntities && customizeEntityCrud && makeChangesToEntities}"} +# {valueType: "boolean", order: 39000, indent: 1, subSection: "entity", defaultValue: "true", showEl: "${operateOnGrouperEntities && customizeEntityCrud && makeChangesToEntities}"} # provisioner.genericProvisioner.deleteEntities = # Delete entities if not exist in grouper -# {valueType: "boolean", order: 39500, defaultValue: "false", subSection: "entity", showEl: "${operateOnGrouperEntities && customizeEntityCrud && makeChangesToEntities && deleteEntities}"} +# {valueType: "boolean", order: 39500, indent: 2, defaultValue: "false", subSection: "entity", showEl: "${operateOnGrouperEntities && customizeEntityCrud && makeChangesToEntities && deleteEntities}"} # provisioner.genericProvisioner.deleteEntitiesIfNotExistInGrouper = # Delete entities if deleted in grouper -# {valueType: "boolean", order: 40000, defaultValue: "false", subSection: "entity", showEl: "${operateOnGrouperEntities && customizeEntityCrud && makeChangesToEntities && deleteEntities && !deleteEntitiesIfNotExistInGrouper}"} +# {valueType: "boolean", order: 40000, indent: 2, defaultValue: "false", subSection: "entity", showEl: "${operateOnGrouperEntities && customizeEntityCrud && makeChangesToEntities && deleteEntities && !deleteEntitiesIfNotExistInGrouper}"} # provisioner.genericProvisioner.deleteEntitiesIfGrouperDeleted = # Delete entities if not exist in grouper -# {valueType: "boolean", order: 40100, defaultValue: "true", subSection: "entity", showEl: "${operateOnGrouperEntities && customizeEntityCrud && makeChangesToEntities && deleteEntities && !deleteEntitiesIfNotExistInGrouper && !deleteEntitiesIfGrouperDeleted}"} +# {valueType: "boolean", order: 40100, indent: 2, defaultValue: "true", subSection: "entity", showEl: "${operateOnGrouperEntities && customizeEntityCrud && makeChangesToEntities && deleteEntities && !deleteEntitiesIfNotExistInGrouper && !deleteEntitiesIfGrouperDeleted}"} # provisioner.genericProvisioner.deleteEntitiesIfGrouperCreated = # Update entities -# {valueType: "boolean", order: 41000, defaultValue: "true", subSection: "entity", showEl: "${operateOnGrouperEntities && customizeEntityCrud && makeChangesToEntities}"} +# {valueType: "boolean", order: 41000, indent: 1, defaultValue: "true", subSection: "entity", showEl: "${operateOnGrouperEntities && customizeEntityCrud && makeChangesToEntities}"} # provisioner.genericProvisioner.updateEntities = # Select all entities # {valueType: "boolean", order: 42000, required: "true", subSection: "entity", showEl: "${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities)}"} # provisioner.genericProvisioner.selectAllEntities = -# If the subject api is needed before provisioning to ldap -# {valueType: "boolean", defaultValue: "false", order: 46000, subSection: "entity", showEl: "${operateOnGrouperEntities}"} -# provisioner.genericProvisioner.hasSubjectLink = - # if the entities need to be resolved in target # {valueType: "boolean", defaultValue: "false", showEl:"${operateOnGrouperEntities && selectEntities}", order: 53000, subSection: "entity"} # provisioner.genericProvisioner.hasTargetEntityLink = # number of attributes for target entities -# {valueType: "integer", order: 59000, subSection: "entity", defaultValue: "0", showEl:"${operateOnGrouperEntities}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } +# {valueType: "integer", order: 59000, subSection: "entity", defaultValue: "0", showEl:"${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities)}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } # provisioner.genericProvisioner.numberOfEntityAttributes = # Name of the attribute # {valueType: "string", order: 61000, required: true, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$}", repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.name = -# Value type -# {valueType: "string", order: 62000, defaultValue: "string", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$}", formElement: "dropdown", optionValues: ["string", "long", "int"], repeatGroup: "targetEntityAttribute", repeatCount: 20 } -# provisioner.genericProvisioner.targetEntityAttribute.$i$.valueType = +# Translate type +# {valueType: "string", order: 61100, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$}", formElement: "dropdown", optionValues: ["grouperProvisioningEntityField", "staticValues", "translationScript"], repeatGroup: "targetEntityAttribute", repeatCount: 20} +# provisioner.genericProvisioner.targetEntityAttribute.$i$.translateExpressionType = -# Multi-valued attribute? -# {valueType: "boolean", order: 62200, defaultValue: "false", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$}", repeatGroup: "targetEntityAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetEntityAttribute.$i$.multiValued = +# Translate from field +# {valueType: "string", order: 61200, required: true, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.translateExpressionType == 'grouperProvisioningEntityField'}", formElement: "dropdown", optionValues: ["description", "email", "id", "memberId", "name", "subjectId", "subjectSourceId", "subjectIdentifier", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"], repeatGroup: "targetEntityAttribute", repeatCount: 20} +# provisioner.genericProvisioner.targetEntityAttribute.$i$.translateFromGrouperProvisioningEntityField = -# Membership attribute? -# {valueType: "boolean", order: 62400, defaultValue: "false", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && provisioningType == 'entityAttributes' && targetEntityAttribute.$i$.multiValued}", repeatGroup: "targetEntityAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetEntityAttribute.$i$.membershipAttribute = +# Translate from static values +# {valueType: "string", order: 61300, required: true, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.translateExpressionType == 'staticValues'}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# provisioner.genericProvisioner.targetEntityAttribute.$i$.translateFromStaticValues = -# During the translation, use this sync field -# {valueType: "string", order: 62600, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && provisioningType == 'entityAttributes' && targetEntityAttribute.$i$.membershipAttribute}", formElement: "dropdown", optionValues: ["groupId", "groupIdIndex", "groupExtension", "groupName", "groupFromId2", "groupFromId3", "groupToId2", "groupToId3"], repeatGroup: "targetEntityAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetEntityAttribute.$i$.translateFromGroupSyncField = +# Translate expression +# {valueType: "string", order: 61400, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.translateExpressionType == 'translationScript'}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# provisioner.genericProvisioner.targetEntityAttribute.$i$.translateExpression = + +# Advanced options +# {valueType: "boolean", order: 61500, defaultValue: "false", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# provisioner.genericProvisioner.targetEntityAttribute.$i$.showAdvancedAttribute = # Show entity attribute crud -# {valueType: "boolean", order: 62800, defaultValue: "false", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# {valueType: "boolean", order: 62000, indent: 1, defaultValue: "false", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute}", repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.showAttributeCrud = # Select attribute? -# {valueType: "boolean", order: 63000, defaultValue: "true", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && (selectEntities == null || selectEntities) && targetEntityAttribute.$i$.showAttributeCrud}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# {valueType: "boolean", order: 63000, indent: 2, defaultValue: "true", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && (selectEntities == null || selectEntities) && targetEntityAttribute.$i$.showAttributeCrud}", repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.select = # Insert attribute? -# {valueType: "boolean", order: 64000, defaultValue: "true", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && makeChangesToEntities && (insertEntities == null || insertEntities) && targetEntityAttribute.$i$.showAttributeCrud}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# {valueType: "boolean", order: 64000, indent: 2, defaultValue: "true", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && makeChangesToEntities && (insertEntities == null || insertEntities) && targetEntityAttribute.$i$.showAttributeCrud}", repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.insert = # Update attribute? -# {valueType: "boolean", order: 65000, defaultValue: "true", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && makeChangesToEntities && (updateEntities == null || updateEntities) && targetEntityAttribute.$i$.showAttributeCrud}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# {valueType: "boolean", order: 65000, indent: 2, defaultValue: "true", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && makeChangesToEntities && (updateEntities == null || updateEntities) && targetEntityAttribute.$i$.showAttributeCrud}", repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.update = -# Ignore entity if this attribute matches any of these values (comma separated) -# {valueType: "string", order: 66000, multiple: true, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$}", repeatGroup: "targetEntityAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetEntityAttribute.$i$.ignoreIfMatchesValue = +# Show entity attribute validation +# {valueType: "boolean", order: 67100, indent: 1, defaultValue: "false", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# provisioner.genericProvisioner.targetEntityAttribute.$i$.showAttributeValueSettings = + +# Value type +# {valueType: "string", order: 67200, indent: 2, defaultValue: "string", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && targetEntityAttribute.$i$.showAttributeValueSettings}", formElement: "dropdown", optionValues: ["string", "long", "int"], repeatGroup: "targetEntityAttribute", repeatCount: 20 } +# provisioner.genericProvisioner.targetEntityAttribute.$i$.valueType = -# Matching id attribute? -# {valueType: "boolean", order: 67000, defaultValue: "false", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$}", repeatGroup: "targetEntityAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetEntityAttribute.$i$.matchingId = +# Multi-valued attribute? +# {valueType: "boolean", order: 67300, indent: 2, defaultValue: "false", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && targetEntityAttribute.$i$.showAttributeValueSettings}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# provisioner.genericProvisioner.targetEntityAttribute.$i$.multiValued = # Default value if there is not a value -# {valueType: "string", order: 69000, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# {valueType: "string", order: 67400, indent: 2, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && targetEntityAttribute.$i$.showAttributeValueSettings}", repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.defaultValue = +# Ignore entity if this attribute matches any of these values (comma separated) +# {valueType: "string", order: 67500, indent: 2, multiple: true, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && targetEntityAttribute.$i$.showAttributeValueSettings}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# provisioner.genericProvisioner.targetEntityAttribute.$i$.ignoreIfMatchesValue = + # Show entity attribute validation -# {valueType: "boolean", order: 69125, defaultValue: "false", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# {valueType: "boolean", order: 69125, indent: 1, defaultValue: "false", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute}", repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.showAttributeValidation = + # If a value is required to provision this entity -# {valueType: "boolean", order: 69250, defaultValue: "false", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAttributeValidation}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# {valueType: "boolean", order: 69250, indent: 2, defaultValue: "false", showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && targetEntityAttribute.$i$.showAttributeValidation}", repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.required = # Maximum length of this field to be valid for provisioning -# {valueType: "string", order: 69500, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAttributeValidation}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# {valueType: "string", order: 69500, indent: 2, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && targetEntityAttribute.$i$.showAttributeValidation}", repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.maxlength = # Validate value with jexl to see if valid for provisioning -# {valueType: "string", order: 69750, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAttributeValidation}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# {valueType: "string", order: 69750, indent: 2, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && targetEntityAttribute.$i$.showAttributeValidation}", repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.validExpression = -# Search attribute? -# {valueType: "boolean", order: 70500, defaultValue: "false", showEl: "${operateOnGrouperEntities && selectEntities && numberOfEntityAttributes > $i$ && !targetEntityAttribute.$i$.multiValued && targetEntityAttribute.$i$.select}", repeatGroup: "targetEntityAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetEntityAttribute.$i$.searchAttribute = - # Translate expression create only type -# {valueType: "string", order: 70650, required: false, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.membershipAttribute == false && targetEntityAttribute.$i$.insert && targetEntityAttribute.$i$.update}", formElement: "dropdown", optionValues: ["grouperProvisioningEntityField", "staticValues", "translationScript"], repeatGroup: "targetEntityAttribute", repeatCount: 20} +# {valueType: "string", order: 70650, indent: 1, required: false, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && makeChangesToEntities && (!customizeEntityCrud || targetEntityAttribute.$i$.insert)}", formElement: "dropdown", optionValues: ["grouperProvisioningEntityField", "staticValues", "translationScript"], repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.translateExpressionTypeCreateOnly = # Translate from field create only -# {valueType: "string", order: 70750, required: true, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && !targetEntityAttribute.$i$.membershipAttribute && targetEntityAttribute.$i$.translateExpressionTypeCreateOnly == 'grouperProvisioningEntityField'}", formElement: "dropdown", optionValues: ["id", "email", "loginid", "name", "subjectId", "subjectSourceId", "description", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"], repeatGroup: "targetGroupAttribute", repeatCount: 20} +# {valueType: "string", order: 70750, indent: 1, required: true, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && makeChangesToEntities && (!customizeEntityCrud || targetEntityAttribute.$i$.insert) && targetEntityAttribute.$i$.translateExpressionTypeCreateOnly == 'grouperProvisioningEntityField'}", formElement: "dropdown", optionValues: ["description", "email", "id", "memberId", "name", "subjectId", "subjectSourceId", "subjectIdentifier", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"], repeatGroup: "targetGroupAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.translateFromGrouperProvisioningEntityFieldCreateOnly = # Translate from static values create only -# {valueType: "string", order: 70850, required: true, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && !targetEntityAttribute.$i$.membershipAttribute && targetEntityAttribute.$i$.translateExpressionTypeCreateOnly == 'staticValues'}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# {valueType: "string", order: 70850, indent: 1, required: true, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && makeChangesToEntities && (!customizeEntityCrud || targetEntityAttribute.$i$.insert) && targetEntityAttribute.$i$.translateExpressionTypeCreateOnly == 'staticValues'}", repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.translateFromStaticValuesCreateOnly = # Translate expression create only -# {valueType: "string", order: 72000, required: false, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.membershipAttribute == false && targetEntityAttribute.$i$.insert && targetEntityAttribute.$i$.translateExpressionTypeCreateOnly == 'translationScript'}", repeatGroup: "targetEntityAttribute", repeatCount: 20} +# {valueType: "string", order: 72000, indent: 1, required: false, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.showAdvancedAttribute && makeChangesToEntities && (!customizeEntityCrud || targetEntityAttribute.$i$.insert) && targetEntityAttribute.$i$.translateExpressionTypeCreateOnly == 'translationScript'}", repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.genericProvisioner.targetEntityAttribute.$i$.translateExpressionCreateOnly = -# Translate type -# {valueType: "string", order: 72300, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.membershipAttribute == false}", formElement: "dropdown", optionValues: ["grouperProvisioningEntityField", "staticValues", "translationScript"], repeatGroup: "targetEntityAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetEntityAttribute.$i$.translateExpressionType = +# subject sources to provision +# {valueType: "string", required: true, order: 76000, multiple: true, formElement: "checkbox", checkboxValuesFromClass: "edu.internet2.middleware.grouper.SubjectFinder", subSection: "general2", showEl: "${operateOnGrouperEntities || operateOnGrouperMemberships}"} +# provisioner.genericProvisioner.subjectSourcesToProvision = -# Translate from field -# {valueType: "string", order: 72600, required: true, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && !targetEntityAttribute.$i$.membershipAttribute && targetEntityAttribute.$i$.translateExpressionType == 'grouperProvisioningEntityField'}", formElement: "dropdown", optionValues: ["id", "email", "loginid", "name", "subjectId", "subjectSourceId", "description", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"], repeatGroup: "targetEntityAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetEntityAttribute.$i$.translateFromGrouperProvisioningEntityField = +# Advanced options, note, there might not be any +# {valueType: "boolean", order: 76500, defaultValue: "false", subSection: "membership2", showEl: "${operateOnGrouperMemberships}"} +# provisioner.genericProvisioner.membership2AdvancedOptions = -# Translate from static values -# {valueType: "string", order: 72800, required: true, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && !targetEntityAttribute.$i$.membershipAttribute && targetEntityAttribute.$i$.translateExpressionType == 'staticValues'}", repeatGroup: "targetEntityAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetEntityAttribute.$i$.translateFromStaticValues = +# Matching ID expression +# {valueType: "string", order: 76510, subSection: "membership2", showEl: "${operateOnGrouperMemberships && membership2AdvancedOptions && provisioningType == 'membershipObjects'}"} +# provisioner.genericProvisioner.membershipMatchingIdExpression = -# Translate expression -# {valueType: "string", order: 73000, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.membershipAttribute == false && targetEntityAttribute.$i$.translateExpressionType == 'translationScript'}", repeatGroup: "targetEntityAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetEntityAttribute.$i$.translateExpression = +# if provisioning normal memberships or privileges +# {valueType: "string", order: 76520, formElement: "dropdown", subSection: "membership2", showEl: "${operateOnGrouperMemberships && membership2AdvancedOptions}", defaultValue: "members", optionValues: ["members", "read, admin", "update, admin", "admin"]} +# provisioner.genericProvisioner.membershipFields = -# During the entity link, copy this attribute to the sync field -# {valueType: "string", order: 76000, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && targetEntityAttribute.$i$.membershipAttribute == false && hasTargetEntityLink}", formElement: "dropdown", optionValues: ["memberFromId2", "memberFromId3", "memberToId2", "memberToId3"], repeatGroup: "targetEntityAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetEntityAttribute.$i$.translateToMemberSyncField = +# membership attribute name for groups +# {valueType: "string", required: true, order: 77000, subSection: "group2", showEl: "${operateOnGrouperGroups && provisioningType == 'groupAttributes'}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions"} +# provisioner.genericProvisioner.groupMembershipAttributeName = -# After calculating the Grouper value store that in a sync field -# {valueType: "string", order: 76200, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$ && !targetEntityAttribute.$i$.membershipAttribute}", formElement: "dropdown", optionValues: ["memberFromId2", "memberFromId3", "memberToId2", "memberToId3"], repeatGroup: "targetEntityAttribute", repeatCount: 20} -# provisioner.genericProvisioner.targetEntityAttribute.$i$.translateGrouperToMemberSyncField = +# membership attribute value for groups +# {valueType: "string", required: true, order: 77010, subSection: "group2", showEl: "${operateOnGrouperGroups && provisioningType == 'groupAttributes'}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeWithCacheDropdownOptions"} +# provisioner.genericProvisioner.groupMembershipAttributeValue = -# subject sources to provision -# {valueType: "string", required: true, order: 76400, multiple: true, formElement: "checkbox", checkboxValuesFromClass: "edu.internet2.middleware.grouper.SubjectFinder", subSection: "general2", showEl: "${operateOnGrouperEntities || operateOnGrouperMemberships}"} -# provisioner.genericProvisioner.subjectSourcesToProvision = +# generally the matching attribute(s) are the same as the search attributes, but they can be different +# {valueType: "boolean", defaultValue: "true", order: 77220, subSection: "group2", showEl: "${operateOnGrouperGroups && (!customizeGroupCrud || selectGroups || insertGroups || updateGroups || deleteGroups)}"} +# provisioner.genericProvisioner.groupMatchingAttributeSameAsSearchAttribute = + +# how many group matching attributes +# {valueType: "integer", required: true, order: 77222, subSection: "group2", showEl: "${operateOnGrouperGroups && (!customizeGroupCrud || selectGroups || insertGroups || updateGroups || deleteGroups)}", formElement: "dropdown", optionValues: ["1", "2", "3"] } +# provisioner.genericProvisioner.groupMatchingAttributeCount = + +# group matching attribute 1 +# {valueType: "string", required: true, order: 77226, subSection: "group2", showEl: "${operateOnGrouperGroups && (!customizeGroupCrud || selectGroups || insertGroups || updateGroups || deleteGroups) && groupMatchingAttributeCount >= 1}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions" } +# provisioner.genericProvisioner.groupMatchingAttribute0name = + +# group matching attribute 2 +# {valueType: "string", required: true, order: 77230, subSection: "group2", showEl: "${operateOnGrouperGroups && (!customizeGroupCrud || selectGroups || insertGroups || updateGroups || deleteGroups) && groupMatchingAttributeCount >= 2}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions" } +# provisioner.genericProvisioner.groupMatchingAttribute1name = + +# group matching attribute 3 +# {valueType: "string", required: true, order: 77234, subSection: "group2", showEl: "${operateOnGrouperGroups && (!customizeGroupCrud || selectGroups || insertGroups || updateGroups || deleteGroups) && groupMatchingAttributeCount >= 3}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions" } +# provisioner.genericProvisioner.groupMatchingAttribute2name = + +# how many group search attributes +# {valueType: "integer", required: true, order: 77250, subSection: "group2", showEl: "${operateOnGrouperGroups && (!customizeGroupCrud || selectGroups || insertGroups || updateGroups || deleteGroups) && !groupMatchingAttributeSameAsSearchAttribute}", formElement: "dropdown", optionValues: ["1", "2", "3"] } +# provisioner.genericProvisioner.groupSearchAttributeCount = + +# group search attribute 1 +# {valueType: "string", required: true, order: 77254, subSection: "group2", showEl: "${operateOnGrouperGroups && (!customizeGroupCrud || selectGroups || insertGroups || updateGroups || deleteGroups) && !groupMatchingAttributeSameAsSearchAttribute && groupSearchAttributeCount >= 1}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions" } +# provisioner.genericProvisioner.groupSearchAttribute0name = + +# group search attribute 2 +# {valueType: "string", required: true, order: 77258, subSection: "group2", showEl: "${operateOnGrouperGroups && (!customizeGroupCrud || selectGroups || insertGroups || updateGroups || deleteGroups) && !groupMatchingAttributeSameAsSearchAttribute && groupSearchAttributeCount >= 2}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions" } +# provisioner.genericProvisioner.groupSearchAttribute1name = + +# group search attribute 3 +# {valueType: "string", required: true, order: 77262, subSection: "group2", showEl: "${operateOnGrouperGroups && (!customizeGroupCrud || selectGroups || insertGroups || updateGroups || deleteGroups) && !groupMatchingAttributeSameAsSearchAttribute && groupSearchAttributeCount >= 3}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions" } +# provisioner.genericProvisioner.groupSearchAttribute2name = + +# Target group link - has groupAttributeValueCache? +# {valueType: "boolean", defaultValue: "false", subSection: "group2", showEl: "${operateOnGrouperGroups}", order: 78001} +# provisioner.genericProvisioner.groupAttributeValueCacheHas = + +# Target group link - has groupAttributeValueCache0? +# {valueType: "boolean", indent: 1, defaultValue: "false", subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas}", order: 78001} +# provisioner.genericProvisioner.groupAttributeValueCache0has = + +# Target group link - groupAttributeValueCache0 source +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache0has}", order: 78002, formElement: "dropdown", optionValues: ["grouper", "target"]} +# provisioner.genericProvisioner.groupAttributeValueCache0source = + +# Target group link - groupAttributeValueCache0 type +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache0has}", order: 78004, formElement: "dropdown", optionValues: ["groupAttribute", "groupObject", "translationScript"]} +# provisioner.genericProvisioner.groupAttributeValueCache0type = + +# Target group link - groupAttributeValueCache0 groupAttribute +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache0has && groupAttributeValueCache0type == 'groupAttribute'}", order: 78006, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions"} +# provisioner.genericProvisioner.groupAttributeValueCache0groupAttribute = + +# Target group link - groupAttributeValueCache0 translationScript +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache0has && groupAttributeValueCache0type == 'translationScript'}", order: 78008} +# provisioner.genericProvisioner.groupAttributeValueCache0translationScript = + +# Target group link - has groupAttributeValueCache1? +# {valueType: "boolean", indent: 1, defaultValue: "false", subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas}", order: 78101} +# provisioner.genericProvisioner.groupAttributeValueCache1has = + +# Target group link - groupAttributeValueCache1 source +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache1has}", order: 78102, formElement: "dropdown", optionValues: ["grouper", "target"]} +# provisioner.genericProvisioner.groupAttributeValueCache1source = + +# Target group link - groupAttributeValueCache1 type +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache1has}", order: 78104, formElement: "dropdown", optionValues: ["groupAttribute", "groupObject", "translationScript"]} +# provisioner.genericProvisioner.groupAttributeValueCache1type = + +# Target group link - groupAttributeValueCache1 groupAttribute +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache1has && groupAttributeValueCache1type == 'groupAttribute'}", order: 78106, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions"} +# provisioner.genericProvisioner.groupAttributeValueCache1groupAttribute = + +# Target group link - groupAttributeValueCache1 translationScript +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache1has && groupAttributeValueCache1type == 'translationScript'}", order: 78108} +# provisioner.genericProvisioner.groupAttributeValueCache1translationScript = + + +# Target group link - has groupAttributeValueCache2? +# {valueType: "boolean", indent: 1, defaultValue: "false", subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas}", order: 78201} +# provisioner.genericProvisioner.groupAttributeValueCache2has = + +# Target group link - groupAttributeValueCache2 source +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache2has}", order: 78202, formElement: "dropdown", optionValues: ["grouper", "target"]} +# provisioner.genericProvisioner.groupAttributeValueCache2source = + +# Target group link - groupAttributeValueCache2 type +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache2has}", order: 78204, formElement: "dropdown", optionValues: ["groupAttribute", "groupObject", "translationScript"]} +# provisioner.genericProvisioner.groupAttributeValueCache2type = + +# Target group link - groupAttributeValueCache2 groupAttribute +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache2has && groupAttributeValueCache2type == 'groupAttribute'}", order: 78206, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions"} +# provisioner.genericProvisioner.groupAttributeValueCache2groupAttribute = + +# Target group link - groupAttributeValueCache2 translationScript +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache2has && groupAttributeValueCache2type == 'translationScript'}", order: 78208} +# provisioner.genericProvisioner.groupAttributeValueCache2translationScript = + + +# Target group link - has groupAttributeValueCache3? +# {valueType: "boolean", indent: 1, defaultValue: "false", subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas}", order: 78301} +# provisioner.genericProvisioner.groupAttributeValueCache3has = + +# Target group link - groupAttributeValueCache3 source +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache3has}", order: 78302, formElement: "dropdown", optionValues: ["grouper", "target"]} +# provisioner.genericProvisioner.groupAttributeValueCache3source = + +# Target group link - groupAttributeValueCache3 type +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache3has}", order: 78304, formElement: "dropdown", optionValues: ["groupAttribute", "groupObject", "translationScript"]} +# provisioner.genericProvisioner.groupAttributeValueCache3type = + +# Target group link - groupAttributeValueCache3 groupAttribute +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache3has && groupAttributeValueCache3type == 'groupAttribute'}", order: 78306, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions"} +# provisioner.genericProvisioner.groupAttributeValueCache3groupAttribute = + +# Target group link - groupAttributeValueCache3 translationScript +# {valueType: "string", indent: 2, required: true, subSection: "group2", showEl: "${operateOnGrouperGroups && groupAttributeValueCacheHas && groupAttributeValueCache3has && groupAttributeValueCache3type == 'translationScript'}", order: 78308} +# provisioner.genericProvisioner.groupAttributeValueCache3translationScript = + + +# group section 2 advanced options +# {valueType: "boolean", defaultValue: "false", order: 79800, subSection: "group2", showEl: "${operateOnGrouperGroups}"} +# provisioner.genericProvisioner.group2advanced = + +# groups require members +# {valueType: "boolean", indent: 1, defaultValue: "false", order: 79800, subSection: "group2", showEl: "${operateOnGrouperGroups && group2advanced}"} +# provisioner.genericProvisioner.groupsRequireMembers = + +# membership attribute name for entities +# {valueType: "string", required: true, order: 80100, subSection: "entity2", showEl: "${operateOnGrouperEntities && provisioningType == 'entityAttributes'}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeDropdownOptions"} +# provisioner.genericProvisioner.entityMembershipAttributeName = + +# membership attribute value for entities +# {valueType: "string", required: true, order: 80101, subSection: "entity2", showEl: "${operateOnGrouperEntities && provisioningType == 'entityAttributes'}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeWithCacheDropdownOptions"} +# provisioner.genericProvisioner.entityMembershipAttributeValue = + +# generally the matching attribute(s) are the same as the search attributes, but they can be different +# {valueType: "boolean", defaultValue: "true", order: 80220, subSection: "entity2", showEl: "${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities || (makeChangesToEntities && (insertEntities || updateEntities || deleteEntities)))}"} +# provisioner.genericProvisioner.entityMatchingAttributeSameAsSearchAttribute = + +# how many entity matching attributes +# {valueType: "integer", required: true, order: 80222, subSection: "entity2", showEl: "${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities || (makeChangesToEntities && (insertEntities || updateEntities || deleteEntities)))}", formElement: "dropdown", optionValues: ["1", "2", "3"] } +# provisioner.genericProvisioner.entityMatchingAttributeCount = + +# entity matching attribute 1 +# {valueType: "string", required: true, order: 80226, subSection: "entity2", showEl: "${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities || (makeChangesToEntities && (insertEntities || updateEntities || deleteEntities))) && entityMatchingAttributeCount >= 1}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeDropdownOptions" } +# provisioner.genericProvisioner.entityMatchingAttribute0name = + +# entity matching attribute 2 +# {valueType: "string", required: true, order: 80230, subSection: "entity2", showEl: "${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities || (makeChangesToEntities && (insertEntities || updateEntities || deleteEntities))) && entityMatchingAttributeCount >= 2}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeDropdownOptions" } +# provisioner.genericProvisioner.entityMatchingAttribute1name = + +# entity matching attribute 3 +# {valueType: "string", required: true, order: 80234, subSection: "entity2", showEl: "${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities || (makeChangesToEntities && (insertEntities || updateEntities || deleteEntities))) && entityMatchingAttributeCount >= 3}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeDropdownOptions" } +# provisioner.genericProvisioner.entityMatchingAttribute2name = + +# how many entity search attributes +# {valueType: "integer", required: true, order: 80250, subSection: "entity2", showEl: "${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities || (makeChangesToEntities && (insertEntities || updateEntities || deleteEntities))) && !entityMatchingAttributeSameAsSearchAttribute}", formElement: "dropdown", optionValues: ["1", "2", "3"] } +# provisioner.genericProvisioner.entitySearchAttributeCount = + +# entity search attribute 1 +# {valueType: "string", required: true, order: 80254, subSection: "entity2", showEl: "${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities || (makeChangesToEntities && (insertEntities || updateEntities || deleteEntities))) && !entityMatchingAttributeSameAsSearchAttribute && entitySearchAttributeCount >= 1}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeDropdownOptions" } +# provisioner.genericProvisioner.entitySearchAttribute0name = + +# entity search attribute 2 +# {valueType: "string", required: true, order: 80258, subSection: "entity2", showEl: "${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities || (makeChangesToEntities && (insertEntities || updateEntities || deleteEntities))) && !entityMatchingAttributeSameAsSearchAttribute && entitySearchAttributeCount >= 2}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeDropdownOptions" } +# provisioner.genericProvisioner.entitySearchAttribute1name = + +# entity search attribute 3 +# {valueType: "string", required: true, order: 80262, subSection: "entity2", showEl: "${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities || (makeChangesToEntities && (insertEntities || updateEntities || deleteEntities))) && !entityMatchingAttributeSameAsSearchAttribute && entitySearchAttributeCount >= 3}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeDropdownOptions" } +# provisioner.genericProvisioner.entitySearchAttribute2name = + + +# Target entity link - has entityAttributeValueCache? +# {valueType: "boolean", defaultValue: "false", subSection: "entity2", showEl: "${operateOnGrouperEntities}", order: 80301} +# provisioner.genericProvisioner.entityAttributeValueCacheHas = + +# Target entity link - has entityAttributeValueCache0? +# {valueType: "boolean", indent: 1, defaultValue: "false", subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas}", order: 80301} +# provisioner.genericProvisioner.entityAttributeValueCache0has = + +# Target entity link - entityAttributeValueCache0 source +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache0has}", order: 80302, formElement: "dropdown", optionValues: ["grouper", "target"]} +# provisioner.genericProvisioner.entityAttributeValueCache0source = + +# Target entity link - entityAttributeValueCache0 type +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache0has}", order: 80304, formElement: "dropdown", optionValues: ["entityAttribute", "entityObject", "subjectTranslationScript", "translationScript"]} +# provisioner.genericProvisioner.entityAttributeValueCache0type = + +# Target entity link - entityAttributeValueCache0 entityAttribute +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache0has && entityAttributeValueCache0type == 'entityAttribute'}", order: 80306, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeDropdownOptions"} +# provisioner.genericProvisioner.entityAttributeValueCache0entityAttribute = + +# Target entity link - entityAttributeValueCache0 translationScript +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache0has && (entityAttributeValueCache0type == 'translationScript' || entityAttributeValueCache0type == 'subjectTranslationScript')}", order: 80308} +# provisioner.genericProvisioner.entityAttributeValueCache0translationScript = + +# Target entity link - Entity attribute value cache 0 auto-USDU. This should generally be left as the default (true), USDU should update the value of this cache item from the subject source. +# {valueType: "boolean", indent: 2, defaultValue: "true", subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache0has}", order: 80309} +# provisioner.genericProvisioner.entityAttributeValueCache0auto = + + + +# Target entity link - has entityAttributeValueCache1? +# {valueType: "boolean", indent: 1, defaultValue: "false", subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas}", order: 80401} +# provisioner.genericProvisioner.entityAttributeValueCache1has = + +# Target entity link - entityAttributeValueCache1 source +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache1has}", order: 80402, formElement: "dropdown", optionValues: ["grouper", "target"]} +# provisioner.genericProvisioner.entityAttributeValueCache1source = + +# Target entity link - entityAttributeValueCache1 type +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache1has}", order: 80404, formElement: "dropdown", optionValues: ["entityAttribute", "entityObject", "subjectTranslationScript", "translationScript"]} +# provisioner.genericProvisioner.entityAttributeValueCache1type = + +# Target entity link - entityAttributeValueCache1 entityAttribute +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache1has && entityAttributeValueCache1type == 'entityAttribute'}", order: 80406, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeDropdownOptions"} +# provisioner.genericProvisioner.entityAttributeValueCache1entityAttribute = + +# Target entity link - entityAttributeValueCache1 translationScript +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache1has && (entityAttributeValueCache1type == 'translationScript' || entityAttributeValueCache1type == 'subjectTranslationScript')}", order: 80408} +# provisioner.genericProvisioner.entityAttributeValueCache1translationScript = + +# Target entity link - Entity attribute value cache 1 auto-USDU. This should generally be left as the default (true), USDU should update the value of this cache item from the subject source. +# {valueType: "boolean", indent: 2, defaultValue: "true", subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache1has}", order: 80409} +# provisioner.genericProvisioner.entityAttributeValueCache1auto = + + +# Target entity link - has entityAttributeValueCache2? +# {valueType: "boolean", indent: 1, defaultValue: "false", subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas}", order: 80501} +# provisioner.genericProvisioner.entityAttributeValueCache2has = + +# Target entity link - entityAttributeValueCache2 source +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache2has}", order: 80502, formElement: "dropdown", optionValues: ["grouper", "target"]} +# provisioner.genericProvisioner.entityAttributeValueCache2source = + +# Target entity link - entityAttributeValueCache2 type +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache2has}", order: 80504, formElement: "dropdown", optionValues: ["entityAttribute", "entityObject", "subjectTranslationScript", "translationScript"]} +# provisioner.genericProvisioner.entityAttributeValueCache2type = + +# Target entity link - entityAttributeValueCache2 entityAttribute +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache2has && entityAttributeValueCache2type == 'entityAttribute'}", order: 80506, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeDropdownOptions"} +# provisioner.genericProvisioner.entityAttributeValueCache2entityAttribute = + +# Target entity link - entityAttributeValueCache2 translationScript +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache2has && (entityAttributeValueCache2type == 'translationScript' || entityAttributeValueCache2type == 'subjectTranslationScript')}", order: 80508} +# provisioner.genericProvisioner.entityAttributeValueCache2translationScript = + +# Target entity link - Entity attribute value cache 2 auto-USDU. This should generally be left as the default (true), USDU should update the value of this cache item from the subject source. +# {valueType: "boolean", indent: 2, defaultValue: "true", subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache1has}", order: 80509} +# provisioner.genericProvisioner.entityAttributeValueCache2auto = + + +# Target entity link - has entityAttributeValueCache3? +# {valueType: "boolean", indent: 1, defaultValue: "false", subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas}", order: 80601} +# provisioner.genericProvisioner.entityAttributeValueCache3has = + +# Target entity link - entityAttributeValueCache3 source +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache3has}", order: 80602, formElement: "dropdown", optionValues: ["grouper", "target"]} +# provisioner.genericProvisioner.entityAttributeValueCache3source = + +# Target entity link - entityAttributeValueCache3 type +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache3has}", order: 80604, formElement: "dropdown", optionValues: ["entityAttribute", "entityObject", "subjectTranslationScript", "translationScript"]} +# provisioner.genericProvisioner.entityAttributeValueCache3type = + +# Target entity link - entityAttributeValueCache3 entityAttribute +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache3has && entityAttributeValueCache3type == 'entityAttribute'}", order: 80606, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeDropdownOptions"} +# provisioner.genericProvisioner.entityAttributeValueCache3entityAttribute = + +# Target entity link - entityAttributeValueCache3 translationScript +# {valueType: "string", indent: 2, required: true, subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache3has && (entityAttributeValueCache3type == 'translationScript' || entityAttributeValueCache3type == 'subjectTranslationScript')}", order: 80608} +# provisioner.genericProvisioner.entityAttributeValueCache3translationScript = + +# Target entity link - Entity attribute value cache 3 auto-USDU. This should generally be left as the default (true), USDU should update the value of this cache item from the subject source. +# {valueType: "boolean", indent: 2, defaultValue: "true", subSection: "entity2", showEl: "${operateOnGrouperEntities && entityAttributeValueCacheHas && entityAttributeValueCache3has}", order: 80509} +# provisioner.genericProvisioner.entityAttributeValueCache3auto = + + +# entity section 2 advanced options +# {valueType: "boolean", defaultValue: "false", order: 81000, subSection: "entity2", showEl: "${operateOnGrouperEntities}"} +# provisioner.genericProvisioner.entity2advanced = + +# overall group of entities to provision. If not specified, then provision entities with any memberships optional +# {valueType: "string", order: 81010, showEl: "${operateOnGrouperEntities && entity2advanced}", subSection: "entity2"} +# provisioner.genericProvisioner.groupIdOfUsersToProvision = + +# optional override for subject identifier to sync to member sync table +# {valueType: "string", order: 81020, showEl: "${operateOnGrouperEntities && entity2advanced}", formElement: "dropdown", optionValues: ["subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"], subSection: "entity2"} +# provisioner.genericProvisioner.subjectIdentifierForMemberSyncTable = # Show provisioning diagnostics -# {valueType: "boolean", order: 77000, defaultValue: "false", subSection: "provisioningDiagnostics"} +# {valueType: "boolean", order: 82000, defaultValue: "false", subSection: "provisioningDiagnostics"} # provisioner.genericProvisioner.showProvisioningDiagnostics = # Select all groups during diagnostics -# {valueType: "boolean", order: 78000, defaultValue: "false", subSection: "provisioningDiagnostics", showEl: "${showProvisioningDiagnostics}"} +# {valueType: "boolean", order: 82100, defaultValue: "false", subSection: "provisioningDiagnostics", showEl: "${showProvisioningDiagnostics}"} # provisioner.genericProvisioner.selectAllGroupsDuringDiagnostics = # Select all entities during diagnostics -# {valueType: "boolean", order: 79000, defaultValue: "false", subSection: "provisioningDiagnostics", showEl: "${showProvisioningDiagnostics}"} +# {valueType: "boolean", order: 82200, defaultValue: "false", subSection: "provisioningDiagnostics", showEl: "${showProvisioningDiagnostics}"} # provisioner.genericProvisioner.selectAllEntitiesDuringDiagnostics = # Select all memberships during diagnostics -# {valueType: "boolean", order: 80000, defaultValue: "false", subSection: "provisioningDiagnostics", showEl: "${showProvisioningDiagnostics}"} +# {valueType: "boolean", order: 82300, defaultValue: "false", subSection: "provisioningDiagnostics", showEl: "${showProvisioningDiagnostics}"} # provisioner.genericProvisioner.selectAllMembershipsDuringDiagnostics = # Test group name -# {valueType: "string", order: 81000, subSection: "provisioningDiagnostics", showEl: "${showProvisioningDiagnostics}"} +# {valueType: "string", order: 82400, subSection: "provisioningDiagnostics", showEl: "${showProvisioningDiagnostics}"} # provisioner.genericProvisioner.testGroupName = # create group during diagnostics -# {valueType: "boolean", order: 82000, defaultValue: "false", subSection: "provisioningDiagnostics", showEl: "${showProvisioningDiagnostics}"} +# {valueType: "boolean", order: 82500, defaultValue: "false", subSection: "provisioningDiagnostics", showEl: "${showProvisioningDiagnostics}"} # provisioner.genericProvisioner.createGroupDuringDiagnostics = # delete group during diagnostics @@ -2935,6 +3208,10 @@ provisionerDefault.scoreConvertToFullSyncThreshold = # {valueType: "string", subSection: "assigningProvisioning", order: 86550, showEl: "${showAssigningProvisioning}"} # provisioner.genericProvisioner.groupAllowedToAssign = +# Group allowed to view +# {valueType: "string", subSection: "assigningProvisioning", order: 86560, showEl: "${showAssigningProvisioning}"} +# provisioner.genericProvisioner.groupAllowedToView = + # Allow assignment only on one stem # {valueType: "boolean", subSection: "assigningProvisioning", defaultValue: "false", order: 86600, showEl: "${showAssigningProvisioning}"} # provisioner.genericProvisioner.allowAssignmentsOnlyOnOneStem = @@ -3094,9 +3371,13 @@ provisionerDefault.scoreConvertToFullSyncThreshold = # provisioner.genericProvisioner.logCommandsAlways = # keep a log of all commands, and if there is an error and if so then log to the log file -# {valueType: "boolean", subSection: "advanced", defaultValue: "false", order: 139160, showEl: "${showAdvanced && !logCommandsAlways}"} +# {valueType: "boolean", indent: 1, subSection: "advanced", defaultValue: "false", order: 139160, showEl: "${showAdvanced && !logCommandsAlways}"} # provisioner.genericProvisioner.logCommandsOnError = +# when there is an error, log max this many of each time (to avoid filling up the logs with redundant entries) +# {valueType: "integer", subSection: "advanced", defaultValue: "10", order: 139180, showEl: "${showAdvanced}"} +# provisioner.genericProvisioner.logMaxErrorsPerType = + # if the target should be checked before sending actions. e.g. if an addMember is made to a provisionable # group, then check the target to see if the entity is already a member first. # default to provisionerDefault.membershipsConvertToGroupSyncThreshold = 500 @@ -3120,78 +3401,25 @@ provisionerDefault.scoreConvertToFullSyncThreshold = # {valueType: "integer", defaultValue: 20, subSection: "advanced", showEl: "${operateOnGrouperGroups && hasTargetGroupLink && showAdvanced}", order: 139500} # provisioner.genericProvisioner.refreshGroupLinkIfLessThanAmount = -# Target group link - groupFromId2 -# {valueType: "string", subSection: "advanced", showEl: "${operateOnGrouperGroups && hasTargetGroupLink && showAdvanced}", order: 139600} -# provisioner.genericProvisioner.common.groupLink.groupFromId2 = - -# Target group link - groupFromId3 -# {valueType: "string", subSection: "advanced", showEl: "${operateOnGrouperGroups && hasTargetGroupLink && showAdvanced}", order: 139700} -# provisioner.genericProvisioner.common.groupLink.groupFromId3 = - -# Target group link - groupToId2 -# {valueType: "string", subSection: "advanced", showEl: "${operateOnGrouperGroups && hasTargetGroupLink && showAdvanced}", order: 139800} -# provisioner.genericProvisioner.common.groupLink.groupToId2 = - -# Target group link - groupToId3 -# {valueType: "string", subSection: "advanced", showEl: "${operateOnGrouperGroups && hasTargetGroupLink && showAdvanced}", order: 139900} -# provisioner.genericProvisioner.common.groupLink.groupToId3 = - # refresh subject link if less than this amount -# {valueType: "integer", defaultValue: 20, showEl: "${hasSubjectLink && operateOnGrouperEntities && showAdvanced}", order: 140000, subSection: "advanced"} +# {valueType: "integer", defaultValue: 20, showEl: "${operateOnGrouperEntities && showAdvanced}", order: 140000, subSection: "advanced"} # provisioner.genericProvisioner.refreshSubjectLinkIfLessThanAmount = -# Subject link - memberFromId2 -# {valueType: "string", showEl: "${hasSubjectLink && operateOnGrouperEntities && showAdvanced}", order: 141000, subSection: "advanced"} -# provisioner.genericProvisioner.common.subjectLink.memberFromId2 = - -# Subject link - memberFromId3 -# {valueType: "string", showEl: "${hasSubjectLink && operateOnGrouperEntities && showAdvanced}", order: 142000, subSection: "advanced"} -# provisioner.genericProvisioner.common.subjectLink.memberFromId3 = - -# Subject link - memberToId2 -# {valueType: "string", showEl: "${hasSubjectLink && operateOnGrouperEntities && showAdvanced}", order: 143000, subSection: "advanced"} -# provisioner.genericProvisioner.common.subjectLink.memberToId2 = - -# Subject link - memberToId3 -# {valueType: "string", showEl: "${hasSubjectLink && operateOnGrouperEntities && showAdvanced}", order: 144000, subSection: "advanced"} -# provisioner.genericProvisioner.common.subjectLink.memberToId3 = - # refresh target user link if less than this amount # {valueType: "integer", defaultValue: 20, showEl: "${hasTargetEntityLink && operateOnGrouperEntities && showAdvanced}", order: 145000, subSection: "advanced"} # provisioner.genericProvisioner.refreshEntityLinkIfLessThanAmount = -# Target user link - memberFromId2 -# {valueType: "string", showEl: "${hasTargetEntityLink && operateOnGrouperEntities && showAdvanced}", order: 146000, subSection: "advanced"} -# provisioner.genericProvisioner.common.entityLink.memberFromId2 = - -# Target user link - memberFromId3 -# {valueType: "string", showEl: "${hasTargetEntityLink && operateOnGrouperEntities && showAdvanced}", order: 147000, subSection: "advanced"} -# provisioner.genericProvisioner.common.entityLink.memberFromId3 = - -# Target user link - memberToId2 -# {valueType: "string", showEl: "${hasTargetEntityLink && operateOnGrouperEntities && showAdvanced}", order: 148000, subSection: "advanced"} -# provisioner.genericProvisioner.common.entityLink.memberToId2 = - -# Target user link - memberToId3 -# {valueType: "string", showEl: "${hasTargetEntityLink && operateOnGrouperEntities && showAdvanced}", order: 149000, subSection: "advanced"} -# provisioner.genericProvisioner.common.entityLink.memberToId3 = - -# if provisioning normal memberships or privileges -# {valueType: "string", order: 150000, formElement: "dropdown", subSection: "advanced", showEl: "${operateOnGrouperMemberships && showAdvanced}", defaultValue: "members", optionValues: ["members", "read, admin", "update, admin", "admin"]} -# provisioner.genericProvisioner.membershipFields = - -# overall group of entities to provision. If not specified, then provision entities with any memberships optional -# {valueType: "string", order: 150000, showEl: "${operateOnGrouperEntities && showAdvanced}", subSection: "advanced"} -# provisioner.genericProvisioner.groupIdOfUsersToProvision = - -# optional override for subject identifier to sync to member sync table -# {valueType: "string", order: 150000, showEl: "${showAdvanced}", formElement: "dropdown", optionValues: ["subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"], subSection: "advanced"} -# provisioner.genericProvisioner.subjectIdentifierForMemberSyncTable = - # Allow blank matching IDs # {valueType: "boolean", subSection: "advanced", defaultValue: "false", order: 153000, showEl: "${showAdvanced}"} # provisioner.genericProvisioner.allowBlankMatchingIds = +# Add disabled full sync daemon? +# {valueType: "boolean", subSection: "advanced", defaultValue: "false", order: 154000, showEl: "${showAdvanced}"} +# provisioner.genericProvisioner.addDisabledFullSyncDaemon = + +# Add disabled incremental sync daemon? +# {valueType: "boolean", subSection: "advanced", defaultValue: "false", order: 155000, showEl: "${showAdvanced}"} +# provisioner.genericProvisioner.addDisabledIncrementalSyncDaemon = ######################################## ## box provisioner @@ -3207,7 +3435,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.keySuffixes = debugLog,logAl # Subsections to ignore for box provisioner # {valueType: "string"} -provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user +# provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner class # {valueType: "class", required: true, readOnly: true, order: 10} @@ -3226,7 +3454,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner.myBoxProvisioner.memberViewabilityLevel = # number of attributes for memberships -# {valueType: "integer", order: 5601, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } +# {valueType: "integer", order: 5701, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } # provisioner.myBoxProvisioner.numberOfMembershipAttributes = ######################################## @@ -3247,7 +3475,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner.myLdapProvisioner.provisioningType = # number of attributes for memberships -# {valueType: "integer", order: 5601, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } +# {valueType: "integer", order: 5701, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } # provisioner.myLdapProvisioner.numberOfMembershipAttributes = # where users are @@ -3281,9 +3509,13 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner.myLdapProvisioner.allowLdapGroupDnOverride = # when doing flat or bushy provisioning, this is the ldap "group" rdn, defaults to "cn" -# {valueType: "string", subSection: "group", order: 18740, defaultValue: "cn", showEl: "${ operateOnGrouperGroups && provisioningType == 'groupAttributes'}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions"} +# {valueType: "string", subSection: "group2", order: 77100, defaultValue: "cn", showEl: "${ operateOnGrouperGroups && provisioningType == 'groupAttributes'}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions"} # provisioner.myLdapProvisioner.groupRdnAttribute = +# when adding users, this is the rdn of the dn (e.g. uid if dn is uid=123,ou=users,ou...) +# {valueType: "string", subSection: "entity2", order: 80150, showEl: "${ operateOnGrouperEntities && makeChangesToEntities && (!customizeEntityCrud || insertEntities)}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeDropdownOptions"} +# provisioner.myLdapProvisioner.userRdnAttribute = + # bushy makes an ou for each folder and cn is extension. flat is cn is group name # {valueType: "string", subSection: "group", order: 18750, required: true, formElement: "dropdown", optionValues: ["bushy", "flat"], showEl: "${ operateOnGrouperGroups && provisioningType == 'groupAttributes'}"} # provisioner.myLdapProvisioner.groupDnType = @@ -3309,37 +3541,31 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner.someSqlProvisioner.dbExternalSystemConfigId = # users table to query to lookup users required if hasTargetEntityLink -# {valueType: "string", order: 49010, subSection: "entity", showEl: "${ operateOnGrouperEntities }"} +# {valueType: "string", order: 49010, subSection: "entity", showEl: "${ operateOnGrouperEntities && (!customizeEntityCrud || selectEntities) }"} # provisioner.someSqlProvisioner.userTableName = # users table primary key column of user table -# {valueType: "string", order: 49020, subSection: "entity", showEl: "${operateOnGrouperEntities}"} +# {valueType: "string", order: 80995, subSection: "entity2", showEl: "${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities) }", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeDropdownOptions"} # provisioner.someSqlProvisioner.userPrimaryKey = # if this is more complicated than just a simple select, put the query here optional, select * from users where ... -# {valueType: "string", order: 49040, subSection: "entity", showEl: "${operateOnGrouperEntities }"} +# {valueType: "string", order: 81007, subSection: "entity2", showEl: "${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities) && entity2Advanced}"} # provisioner.someSqlProvisioner.userSearchQuery = # memberships table where memberships go. include schema name if necessary # {valueType: "string", required: true, order: 5605, subSection: "membership", showEl: "${operateOnGrouperMemberships && provisioningType == 'membershipObjects' }"} # provisioner.someSqlProvisioner.membershipTableName = -# memberships table primary key column(s) of membership table -# {valueType: "string", order: 5606, subSection: "membership", showEl: "${operateOnGrouperMemberships && provisioningType == 'membershipObjects'}"} -# provisioner.someSqlProvisioner.membershipPrimaryKey = - -# column from group table which is the foreign key in membership table. Include schema name if necessary. -# {valueType: "string", required: false, order: 5610, subSection: "membership", showEl: "${operateOnGrouperMemberships && provisioningType == 'membershipObjects' }"} +# column from membership table which is the foreign key to the group table +# {valueType: "string", required: false, order: 78050, subSection: "membership2", showEl: "${operateOnGrouperMemberships && provisioningType == 'membershipObjects' && operateOnGrouperGroups && (!customizeGroupCrud || selectGroups) }", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningMembershipAttributeDropdownOptions"} # provisioner.someSqlProvisioner.membershipGroupForeignKeyColumn = - -# column from entity/user table which is the foreign key in membership table. Include schema name if necessary. -# {valueType: "string", required: false, order: 5620, subSection: "membership", showEl: "${operateOnGrouperMemberships && provisioningType == 'membershipObjects' }"} +# column from membership table which is the foreign key to the entity table +# {valueType: "string", required: false, order: 78051, subSection: "membership2", showEl: "${operateOnGrouperMemberships && provisioningType == 'membershipObjects' && operateOnGrouperEntities && (!customizeEntityCrud || selectEntities) }", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningMembershipAttributeDropdownOptions"} # provisioner.someSqlProvisioner.membershipEntityForeignKeyColumn = - # if this is more complicated than just a simple select, put the query here optional, select * from memberships where ... -# {valueType: "string", order: 5630, subSection: "membership", showEl: "${operateOnGrouperMemberships && provisioningType == 'membershipObjects'}"} +# {valueType: "string", order: 5630, subSection: "membership", showEl: "${operateOnGrouperMemberships && provisioningType == 'membershipObjects' && membershipAdvancedOptions}"} # provisioner.someSqlProvisioner.membershipSearchQuery = # groups table to query to lookup users required if hasTargetEntityLink @@ -3347,39 +3573,39 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner.someSqlProvisioner.groupTableName = # groups table primary key column of group table -# {valueType: "string", subSection: "group", order: 15020, showEl: "${operateOnGrouperGroups }"} +# {valueType: "string", subSection: "group2", order: 79400, showEl: "${operateOnGrouperGroups }", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupAttributeDropdownOptions"} # provisioner.someSqlProvisioner.groupTableIdColumn = -# if this is more complicated than just a simple select, put the query here optional, select * from groups where ... -# {valueType: "string", subSection: "group", order: 15040, showEl: "${operateOnGrouperGroups }"} -# provisioner.someSqlProvisioner.groupSearchQuery = - # Use separate table for group attributes # {valueType: "boolean", order: 15041, defaultValue: "false", subSection: "group", showEl: "${operateOnGrouperGroups}"} # provisioner.someSqlProvisioner.useSeparateTableForGroupAttributes = # table to store group attributes -# {valueType: "string", subSection: "group", order: 15042, showEl: "${operateOnGrouperGroups && useSeparateTableForGroupAttributes}"} +# {valueType: "string", indent: 1, subSection: "group", order: 15042, showEl: "${operateOnGrouperGroups && useSeparateTableForGroupAttributes}"} # provisioner.someSqlProvisioner.groupAttributesTableName = # column from group table which is the foreign key in the group attribute table. Include schema name if necessary. -# {valueType: "string", subSection: "group", order: 15043, showEl: "${operateOnGrouperGroups && useSeparateTableForGroupAttributes}"} +# {valueType: "string", indent: 1, subSection: "group", order: 15043, showEl: "${operateOnGrouperGroups && useSeparateTableForGroupAttributes}"} # provisioner.someSqlProvisioner.groupAttributesGroupForeignKeyColumn = # name of the column in group attribute table that will store attribute names. Include schema name if necessary. -# {valueType: "string", subSection: "group", defaultValue: "attribute_name", order: 15044, showEl: "${operateOnGrouperGroups && useSeparateTableForGroupAttributes}"} +# {valueType: "string", indent: 1, subSection: "group", defaultValue: "attribute_name", order: 15044, showEl: "${operateOnGrouperGroups && useSeparateTableForGroupAttributes}"} # provisioner.someSqlProvisioner.groupAttributesAttributeNameColumn = # name of the column in group attribute table that will store attribute values. Include schema name if necessary. -# {valueType: "string", subSection: "group", order: 15045, defaultValue: "attribute_value", showEl: "${operateOnGrouperGroups && useSeparateTableForGroupAttributes}"} +# {valueType: "string", indent: 1, subSection: "group", order: 15045, defaultValue: "attribute_value", showEl: "${operateOnGrouperGroups && useSeparateTableForGroupAttributes}"} # provisioner.someSqlProvisioner.groupAttributesAttributeValueColumn = +# if this is more complicated than just a simple select, put the query here optional, select * from groups where ... +# {valueType: "string", indent: 1, subSection: "group2", order: 79912, showEl: "${operateOnGrouperGroups && group2advanced }"} +# provisioner.someSqlProvisioner.groupSearchQuery = + # name of the column in group attribute table that will store last modified timestamp. Include schema name if necessary. -# {valueType: "string", subSection: "group", order: 15046, showEl: "${operateOnGrouperGroups && useSeparateTableForGroupAttributes}"} +# {valueType: "string", indent: 1, subSection: "group2", order: 79913, showEl: "${operateOnGrouperGroups && useSeparateTableForGroupAttributes && group2advanced}"} # provisioner.someSqlProvisioner.groupAttributesLastModifiedColumn = # type of the last modified column. Include schema name if necessary. -# {valueType: "string", subSection: "group", order: 15047, defaultValue: "long", showEl: "${operateOnGrouperGroups && useSeparateTableForGroupAttributes}", formElement: "dropdown", optionValues: ["long", "timestamp"]} +# {valueType: "string", indent: 1, subSection: "group2", order: 79914, defaultValue: "long", showEl: "${operateOnGrouperGroups && useSeparateTableForGroupAttributes && group2advanced}", formElement: "dropdown", optionValues: ["long", "timestamp"]} # provisioner.someSqlProvisioner.groupAttributesLastModifiedColumnType = # Storage type @@ -3388,31 +3614,31 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # Use separate table for entity attributes -# {valueType: "boolean", order: 49011, defaultValue: "false", subSection: "entity", showEl: "${operateOnGrouperEntities}"} +# {valueType: "boolean", order: 49011, defaultValue: "false", subSection: "entity", showEl: "${operateOnGrouperEntities && (!customizeEntityCrud || selectEntities) }"} # provisioner.someSqlProvisioner.useSeparateTableForEntityAttributes = # table to store entity attributes -# {valueType: "string", subSection: "entity", order: 49012, showEl: "${operateOnGrouperEntities && useSeparateTableForEntityAttributes}"} +# {valueType: "string", indent: 1, subSection: "entity", order: 49012, showEl: "${operateOnGrouperEntities && useSeparateTableForEntityAttributes}"} # provisioner.someSqlProvisioner.entityAttributesTableName = # column from entity table which is the foreign key in the entity attribute table. Include schema name if necessary. -# {valueType: "string", subSection: "entity", order: 49013, showEl: "${operateOnGrouperEntities && useSeparateTableForEntityAttributes}"} +# {valueType: "string", indent: 1, subSection: "entity", order: 49013, showEl: "${operateOnGrouperEntities && useSeparateTableForEntityAttributes}"} # provisioner.someSqlProvisioner.entityAttributesEntityForeignKeyColumn = # name of the column in entity attribute table that will store attribute names. Include schema name if necessary. -# {valueType: "string", subSection: "entity", defaultValue: "attribute_name", order: 49044, showEl: "${operateOnGrouperEntities && useSeparateTableForEntityAttributes}"} +# {valueType: "string", indent: 1, subSection: "entity", defaultValue: "attribute_name", order: 49014, showEl: "${operateOnGrouperEntities && useSeparateTableForEntityAttributes}"} # provisioner.someSqlProvisioner.entityAttributesAttributeNameColumn = # name of the column in entity attribute table that will store attribute values. Include schema name if necessary. -# {valueType: "string", subSection: "entity", order: 49045, defaultValue: "attribute_value", showEl: "${operateOnGrouperEntities && useSeparateTableForEntityAttributes}"} +# {valueType: "string", indent: 1, subSection: "entity", order: 49015, defaultValue: "attribute_value", showEl: "${operateOnGrouperEntities && useSeparateTableForEntityAttributes}"} # provisioner.someSqlProvisioner.entityAttributesAttributeValueColumn = # name of the column in entity attribute table that will store last modified timestamp. Include schema name if necessary. -# {valueType: "string", subSection: "entity", order: 49046, showEl: "${operateOnGrouperEntities && useSeparateTableForEntityAttributes}"} +# {valueType: "string", indent: 1, subSection: "entity2", order: 81011, showEl: "${operateOnGrouperEntities && useSeparateTableForEntityAttributes && entity2advanced}"} # provisioner.someSqlProvisioner.entityAttributesLastModifiedColumn = # type of the last modified column. Include schema name if necessary. -# {valueType: "string", subSection: "entity", order: 49047, defaultValue: "long", showEl: "${operateOnGrouperEntities && useSeparateTableForEntityAttributes}", formElement: "dropdown", optionValues: ["long", "timestamp"]} +# {valueType: "string", indent: 1, subSection: "entity2", order: 81012, defaultValue: "long", showEl: "${operateOnGrouperEntities && useSeparateTableForEntityAttributes && entity2advanced}", formElement: "dropdown", optionValues: ["long", "timestamp"]} # provisioner.someSqlProvisioner.entityAttributesLastModifiedColumnType = # Storage type @@ -3455,7 +3681,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner.myScimProvisioner.updateGroups = false # number of attributes for memberships -# {valueType: "integer", order: 5601, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } +# {valueType: "integer", order: 5701, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } # provisioner.myScimProvisioner.numberOfMembershipAttributes = # Name of the attribute @@ -3793,7 +4019,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner.myAzureProvisioner.provisioningType = # number of attributes for memberships -# {valueType: "integer", order: 5601, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } +# {valueType: "integer", order: 5701, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } # provisioner.myAzureProvisioner.numberOfMembershipAttributes = # Name of the attribute @@ -3842,7 +4068,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner.myDuoProvisioner.duoExternalSystemConfigId = # number of attributes for memberships -# {valueType: "integer", order: 5601, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } +# {valueType: "integer", order: 5701, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } # provisioner.myDuoProvisioner.numberOfMembershipAttributes = # Name of the attribute @@ -3870,7 +4096,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner.myDuoRoleProvisioner.duoExternalSystemConfigId = # number of attributes for memberships -# {valueType: "integer", order: 5601, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } +# {valueType: "integer", order: 5701, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } # provisioner.myDuoRoleProvisioner.numberOfMembershipAttributes = # Insert groups @@ -3890,7 +4116,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner.myDuoRoleProvisioner.targetGroupAttribute.$i$.name = # Name of the attribute -# {valueType: "string", order: 61000, required: true, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$}", formElement: "dropdown", optionValues: ["id", "name", "email"], repeatGroup: "targetEntityAttribute", repeatCount: 20} +# {valueType: "string", order: 61000, required: true, showEl: "${operateOnGrouperEntities && numberOfEntityAttributes > $i$}", formElement: "dropdown", optionValues: ["id", "name", "email", "role"], repeatGroup: "targetEntityAttribute", repeatCount: 20} # provisioner.myDuoRoleProvisioner.targetEntityAttribute.$i$.name = @@ -3955,7 +4181,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner.myMessagingProvisioner.deleteMembershipsIfNotExistInGrouper = # number of attributes for memberships -# {valueType: "integer", order: 5601, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } +# {valueType: "integer", order: 5701, subSection: "membership", defaultValue: "0", showEl:"${false}", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } # provisioner.myMessagingProvisioner.numberOfMembershipAttributes = # Select groups @@ -3982,10 +4208,6 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # {valueType: "boolean", order: 39500, defaultValue: "false", subSection: "entity", showEl: "${false}"} # provisioner.myMessagingProvisioner.deleteEntitiesIfNotExistInGrouper = -# If the subject api is needed before provisioning to ldap -# {valueType: "boolean", defaultValue: "false", order: 46000, subSection: "entity", showEl: "${false}"} -# provisioner.myMessagingProvisioner.hasSubjectLink = - # if the entities need to be resolved in target # {valueType: "boolean", defaultValue: "false", showEl:"${false}", order: 53000, subSection: "entity"} # provisioner.myMessagingProvisioner.hasTargetEntityLink = @@ -4023,7 +4245,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner.myGoogleProvisioner.class = edu.internet2.middleware.grouper.app.google.GrouperGoogleProvisioner # this is the google external system config id -# {valueType: "string", required: true, order: 20, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.changelogconsumer.googleapps.GoogleGrouperExternalSystem"} +# {valueType: "string", required: true, order: 20, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.google.GoogleGrouperExternalSystem"} # provisioner.myGoogleProvisioner.googleExternalSystemConfigId = # Name of the attribute @@ -4067,61 +4289,173 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisioner.myGoogleProvisioner.allowWebPosting = -####################################### -## provisioner startWiths - sql group table -####################################### - -# this is the sql external system config id -# {valueType: "string", order: 25, readOnly: true} -# provisionerStartWith.sqlGroupTable.startWith = sqlGroupTable +############################################### +## provisioner startWiths - sql common +############################################### # this is the sql external system config id # {order: 50, valueType: "string", required: true, order: 20, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.loader.db.DatabaseGrouperExternalSystem"} -# provisionerStartWith.sqlGroupTable.dbExternalSystemConfigId = - -# group table name -# {order: 100, valueType: "string", required: true} -# provisionerStartWith.sqlGroupTable.groupTableName = - -# group table id column -# {order: 150, valueType: "string", required: true} -# provisionerStartWith.sqlGroupTable.groupTableIdColumn = - -# column names -# {valueType: "string", order: 200, required: true} -# provisionerStartWith.sqlGroupTable.columnNames = - -# user primary key -# {order: 250, valueType: "string", required: true} -# provisionerStartWith.sqlGroupTable.userPrimaryKey = +# provisionerStartWith.sqlCommon.dbExternalSystemConfigId = -####################################### -## provisioner startWiths - sql entity table -####################################### - # this is the sql external system config id # {valueType: "string", order: 25, readOnly: true} -# provisionerStartWith.sqlEntityTable.startWith = sqlEntityTable - -# this is the sql external system config id -# {order: 50, valueType: "string", required: true, order: 20, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.loader.db.DatabaseGrouperExternalSystem"} -# provisionerStartWith.sqlEntityTable.dbExternalSystemConfigId = - +# provisionerStartWith.sqlCommon.startWith = sqlCommon + +# Sql pattern +# {valueType: "string", order: 50, required: true, formElement: "dropdown", showEl: "${dbExternalSystemConfigId != null}", optionValues: ["entityTable", "entityTableWithAttributeTable", "entityTableWithAttributeTableAndMemberships", "entityTableMembershipTable", "groupTable", "groupTableWithAttributeTable", "groupTableWithAttributeTableAndMemberships", "groupTableMembershipTable", "groupTableEntityTableMembershipTable", "membershipTable", "other"]} +# provisionerStartWith.sqlCommon.sqlPattern = + +# User attributes type +# {valueType: "string", order: 100, required: true, formElement: "dropdown", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null}", optionValues: ["core", "entityResolver", "subjectSource", "subjectSourceAndEntityResolver"]} +# provisionerStartWith.sqlCommon.userAttributesType = + +# Membership structure +# {valueType: "string", order: 200, defaultValue: "membershipObjects", formElement: "dropdown", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null}", optionValues: ["entityAttributes", "groupAttributes", "membershipObjects", "notApplicable"]} +# provisionerStartWith.sqlCommon.membershipStructure = + +# subject source entity resolver attributes +# {valueType: "string", order: 300, required: true, showEl: "${userAttributesType == 'subjectSource' || userAttributesType == 'subjectSourceAndEntityResolver'}"} +# provisionerStartWith.sqlCommon.subjectSourceEntityResolverAttributes = + +# has group table +# {valueType: "boolean", order: 400, defaultValue: "false", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null}"} +# provisionerStartWith.sqlCommon.hasGroupTable = + # group table name -# {order: 100, valueType: "string", required: true} -# provisionerStartWith.sqlEntityTable.entityTableName = - -# group table id column -# {order: 150, valueType: "string", required: true} -# provisionerStartWith.sqlEntityTable.entityTableIdColumn = +# {valueType: "string", order: 500, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasGroupTable}"} +# provisionerStartWith.sqlCommon.groupTableName = + +# group table primary column +# {valueType: "string", order: 600, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasGroupTable}"} +# provisionerStartWith.sqlCommon.groupTableIdColumn = + +# group table primary key value +# {valueType: "string", order: 650, required: true, formElement: "dropdown", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasGroupTable}", optionValues: ["groupExtension", "groupIdIndex", "groupName", "groupUuid", "other", "script"]} +# provisionerStartWith.sqlCommon.groupTablePrimaryKeyValue = + +# group table column names +# {valueType: "string", order: 700, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasGroupTable}"} +# provisionerStartWith.sqlCommon.groupTableColumnNames = + +# need group link? +# {valueType: "boolean", order: 800, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasGroupTable}"} +# provisionerStartWith.sqlCommon.hasTargetGroupLink = + +# has group attribute table? +# {valueType: "boolean", order: 900, defaultValue: "false", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasGroupTable}"} +# provisionerStartWith.sqlCommon.hasGroupAttributeTable = + +# group attribute table name +# {valueType: "string", order: 1000, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasGroupTable && hasGroupAttributeTable}"} +# provisionerStartWith.sqlCommon.groupAttributesTableName = + +# column name which is foreign key to group table +# {valueType: "string", order: 1100, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasGroupTable && hasGroupAttributeTable}"} +# provisionerStartWith.sqlCommon.groupAttributesGroupForeignKeyColumn = + +# column name which is the attribute name +# {valueType: "string", order: 1200, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasGroupTable && hasGroupAttributeTable}"} +# provisionerStartWith.sqlCommon.groupAttributesAttributeNameColumn = + +# column name which is the attribute value +# {valueType: "string", order: 1300, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasGroupTable && hasGroupAttributeTable}"} +# provisionerStartWith.sqlCommon.groupAttributesAttributeValueColumn = + +# membership attribute name +# {valueType: "string", order: 1400, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasGroupTable && hasGroupAttributeTable && membershipStructure == 'groupAttributes'}"} +# provisionerStartWith.sqlCommon.groupMembershipAttributeName = + +# membership attribute value +# {valueType: "string", order: 1500, required: true, formElement: "dropdown", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasGroupTable && hasGroupAttributeTable && membershipStructure == 'groupAttributes'}", optionValues: ["entityPrimaryKey", "other", "script", "subjectId", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"]} +# provisionerStartWith.sqlCommon.groupMembershipAttributeValue = + +# other attribute names in attribute table +# {valueType: "string", order: 1600, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasGroupTable && hasGroupAttributeTable}"} +# provisionerStartWith.sqlCommon.groupOtherAttributeNames = + +# has entity table +# {valueType: "boolean", order: 1700, defaultValue: "false", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null}"} +# provisionerStartWith.sqlCommon.hasEntityTable = + +# entity table name +# {valueType: "string", order: 1800, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasEntityTable}"} +# provisionerStartWith.sqlCommon.entityTableName = + +# entity table primary column +# {valueType: "string", order: 1900, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasEntityTable}"} +# provisionerStartWith.sqlCommon.entityTableIdColumn = + +# entity table primary key value +# {valueType: "string", order: 2000, required: true, formElement: "dropdown", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasEntityTable}", optionValues: ["email", "entityUuid", "entityDescription", "entityName", "other", "script", "subjectId", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"]} +# provisionerStartWith.sqlCommon.entityTablePrimaryKeyValue = + +# other entity table column names +# {valueType: "string", order: 2100, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasEntityTable}"} +# provisionerStartWith.sqlCommon.entityTableColumnNames = + +# need entity link? +# {valueType: "boolean", order: 2200, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasEntityTable}"} +# provisionerStartWith.sqlCommon.hasTargetEntityLink = + +# has entity attribute table? +# {valueType: "boolean", order: 2300, defaultValue: "false", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasEntityTable}"} +# provisionerStartWith.sqlCommon.hasEntityAttributeTable = + +# entity attribute table name +# {valueType: "string", order: 2400, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasEntityTable && hasEntityAttributeTable}"} +# provisionerStartWith.sqlCommon.entityAttributesTableName = + +# column name which is foreign key to entity table +# {valueType: "string", order: 2500, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasEntityTable && hasEntityAttributeTable}"} +# provisionerStartWith.sqlCommon.entityAttributesEntityForeignKeyColumn = + +# column name which is the attribute name +# {valueType: "string", order: 2600, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasEntityTable && hasEntityAttributeTable}"} +# provisionerStartWith.sqlCommon.entityAttributesAttributeNameColumn = + +# column name which is the attribute value +# {valueType: "string", order: 2700, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasEntityTable && hasEntityAttributeTable}"} +# provisionerStartWith.sqlCommon.entityAttributesAttributeValueColumn = + +# membership attribute name +# {valueType: "string", order: 2800, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasEntityTable && hasEntityAttributeTable && membershipStructure == 'entityAttributes'}"} +# provisionerStartWith.sqlCommon.entityMembershipAttributeName = + +# membership attribute value +# {valueType: "string", order: 2900, required: true, formElement: "dropdown", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasEntityTable && hasEntityAttributeTable && membershipStructure == 'entityAttributes'}", optionValues: ["groupExtension", "groupIdIndex", "groupName", "groupPrimaryKey", "groupUuid", "other", "script"]} +# provisionerStartWith.sqlCommon.entityMembershipAttributeValue = + +# other attribute names in attribute table +# {valueType: "string", order: 3000, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && hasEntityTable && hasEntityAttributeTable}"} +# provisionerStartWith.sqlCommon.entityOtherAttributeNames = -# column names -# {valueType: "string", order: 200, required: true} -# provisionerStartWith.sqlEntityTable.columnNames = +# membership table name +# {valueType: "string", order: 3150, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && membershipStructure == 'membershipObjects'}"} +# provisionerStartWith.sqlCommon.membershipTableName = -# user primary key -# {order: 250, valueType: "string", required: true} -# provisionerStartWith.sqlEntityTable.userPrimaryKey = +# group column +# {valueType: "string", order: 3200, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && membershipStructure == 'membershipObjects'}"} +# provisionerStartWith.sqlCommon.membershipTableGroupColumn = + +# group value +# {valueType: "string", order: 3300, required: true, formElement: "dropdown", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && membershipStructure == 'membershipObjects'}", optionValues: ["groupExtension", "groupIdIndex", "groupName", "groupPrimaryKey", "groupUuid", "other", "script"]} +# provisionerStartWith.sqlCommon.membershipTableGroupValue = + +# entity column +# {valueType: "string", order: 3400, required: true, showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && membershipStructure == 'membershipObjects'}"} +# provisionerStartWith.sqlCommon.membershipTableEntityColumn = + +# entity value +# {valueType: "string", order: 3500, required: true, formElement: "dropdown", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null && membershipStructure == 'membershipObjects'}", optionValues: ["entityPrimaryKey", "other", "script", "subjectId", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"]} +# provisionerStartWith.sqlCommon.membershipTableEntityValue = + +# add disabled full sync daemon? +# {valueType: "boolean", order: 3600, defaultValue: "false", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null}"} +# provisionerStartWith.sqlCommon.addDisabledFullSyncDaemon = + +# add disabled incremental sync daemon? +# {valueType: "boolean", order: 3700, defaultValue: "false", showEl: "${dbExternalSystemConfigId != null && sqlPattern != null && userAttributesType != null}"} +# provisionerStartWith.sqlCommon.addDisabledIncrementalSyncDaemon = ################################################ ## provisioner startWith - ldap memberships @@ -4140,7 +4474,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisionerStartWith.ldapMemberships.ldapPattern = # Membership structure -# {valueType: "string", order: 300, required: true, formElement: "dropdown", showEl: "${ldapPattern != null}", optionValues: ["groupAttributes", "entityAttributes"]} +# {valueType: "string", order: 300, required: true, formElement: "dropdown", showEl: "${ldapPattern != null}", optionValues: ["entityAttributes", "groupAttributes"]} # provisionerStartWith.ldapMemberships.membershipStructure = # membershipValue is DN? @@ -4149,10 +4483,10 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # Group organization: bushy or flat # {valueType: "string", order: 500, required: true, formElement: "dropdown", showEl: "${membershipValueDn != null && membershipStructure == 'groupAttributes'}", optionValues: ["bushy", "flat"]} -# provisionerStartWith.ldapMemberships.groupOrganization = +# provisionerStartWith.ldapMemberships.groupDnType = # User attributes type -# {valueType: "string", order: 550, required: true, formElement: "dropdown", showEl: "${groupOrganization != null}", optionValues: ["core", "subjectSource", "entityResolver", "subjectSourceAndEntityResolver"]} +# {valueType: "string", order: 550, required: true, formElement: "dropdown", showEl: "${groupDnType != null}", optionValues: ["core", "entityResolver", "subjectSource", "subjectSourceAndEntityResolver"]} # provisionerStartWith.ldapMemberships.userAttributesType = # subject source entity resolver attributes @@ -4165,14 +4499,14 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # group base OU # {valueType: "string", order: 800, required: true, showEl: "${groupLinkForAnotherReason || membershipStructure == 'groupAttributes' || membershipValueDn}"} -# provisionerStartWith.ldapMemberships.groupBaseOu = +# provisionerStartWith.ldapMemberships.groupSearchBaseDn = # what attribute is RDN for groups? # {valueType: "string", order: 900, required: true, showEl: "${groupLinkForAnotherReason || membershipStructure == 'groupAttributes' || membershipValueDn}"} -# provisionerStartWith.ldapMemberships.rdnGroupsAttribute = +# provisionerStartWith.ldapMemberships.groupRdnAttribute = # what is RDN value for groups? -# {valueType: "string", order: 1000, required: true, formElement: "dropdown", showEl: "${groupLinkForAnotherReason || membershipStructure == 'groupAttributes' || membershipValueDn}", optionValues: ["extension", "extensionUnderscoreIdIndex", "idIndex", "name", "nameBackwardsUnderscoreMax64", "other", "script", "uuid", "flat"]} +# {valueType: "string", order: 1000, required: true, formElement: "dropdown", showEl: "${groupLinkForAnotherReason || membershipStructure == 'groupAttributes' || membershipValueDn}", optionValues: ["extension", "extensionUnderscoreIdIndex", "id", "idIndex", "idIndexString", "name", "nameBackwardsUnderscoreMax64", "other", "script"]} # provisionerStartWith.ldapMemberships.rdnValueForGroups = # Membership attribute name for groups @@ -4180,8 +4514,8 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisionerStartWith.ldapMemberships.membershipAttributeNameForGroups = # Membership value for groups -# {valueType: "string", order: 1200, required: true, formElement: "dropdown", showEl: "${ (groupLinkForAnotherReason || membershipStructure == 'groupAttributes' || membershipValueDn) && (!membershipValueDn)}", optionValues: ["other", "script", "subjectId", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"]} -# provisionerStartWith.ldapMemberships.membershipValueForGroups = +# {valueType: "string", order: 1200, required: true, formElement: "dropdown", showEl: "${ (groupLinkForAnotherReason || membershipStructure == 'groupAttributes' || membershipValueDn) && (!membershipValueDn)}", optionValuesFromClass: "edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityAttributeWithCacheDropdownOptions"} +# provisionerStartWith.ldapMemberships.groupMembershipAttributeValue = # IdIndex attribute # {valueType: "string", order: 1300, showEl: "${groupLinkForAnotherReason || membershipStructure == 'groupAttributes' || membershipValueDn}"} @@ -4196,7 +4530,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisionerStartWith.ldapMemberships.matchingSearchAttributeNameForGroups = # matching search attribute value for groups -# {valueType: "string", order: 1600, required: true, formElement: "dropdown", showEl: "${ (groupLinkForAnotherReason || membershipStructure == 'groupAttributes' || membershipValueDn) && (matchingSearchAttributeDifferentThanRdnorIdIndex)}", optionValues: ["extension", "idIndex", "name", "other", "script", "uuid"]} +# {valueType: "string", order: 1600, required: true, formElement: "dropdown", showEl: "${ (groupLinkForAnotherReason || membershipStructure == 'groupAttributes' || membershipValueDn) && (matchingSearchAttributeDifferentThanRdnorIdIndex)}", optionValues: ["extension", "id", "idIndex", "name", "other", "script"]} # provisionerStartWith.ldapMemberships.matchingSearchAttributeValueForGroups = # object classes for groups @@ -4209,7 +4543,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # if allow group DN override # {valueType: "boolean", order: 1900, defaultValue: "false", showEl: "${groupLinkForAnotherReason || membershipStructure == 'groupAttributes' || membershipValueDn}"} -# provisionerStartWith.ldapMemberships.allowGroupDnOverride = +# provisionerStartWith.ldapMemberships.allowLdapGroupDnOverride = # if need entity link for another reason # {valueType: "boolean", order: 2000, defaultValue: "false", showEl: "${membershipStructure != null && membershipStructure != 'entityAttributes' && !membershipValueDn}"} @@ -4217,7 +4551,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # Entity base OU # {valueType: "string", order: 2100, required: true, showEl: "${entityLinkForAnotherReason || membershipStructure == 'entityAttributes' || membershipValueDn}"} -# provisionerStartWith.ldapMemberships.entityBaseOu = +# provisionerStartWith.ldapMemberships.userSearchBaseDn = # change entities in LDAP (besides entity attribute if doing entity attributes)? # {valueType: "boolean", order: 2200, defaultValue: "false", showEl: "${entityLinkForAnotherReason || membershipStructure == 'entityAttributes' || membershipValueDn}"} @@ -4225,7 +4559,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # RDN attribute for entities # {valueType: "string", order: 2300, required: true, showEl: "${ (entityLinkForAnotherReason || membershipStructure == 'entityAttributes' || membershipValueDn) && (changeEntitiesInLdap)}"} -# provisionerStartWith.ldapMemberships.rdnEntitiesAttribute = +# provisionerStartWith.ldapMemberships.userRdnAttribute = # what is RDN value for entities # {valueType: "string", order: 2400, required: true, formElement: "dropdown", showEl: "${ (entityLinkForAnotherReason || membershipStructure == 'entityAttributes' || membershipValueDn) && (changeEntitiesInLdap)}", optionValues: ["other", "script", "subjectId", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"]} @@ -4259,16 +4593,12 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # {valueType: "string", order: 3100, showEl: "${entityLinkForAnotherReason || membershipStructure == 'entityAttributes' || membershipValueDn}"} # provisionerStartWith.ldapMemberships.otherEntityLdapAttributes = -# allow membership value override? -# {valueType: "boolean", order: 3200, defaultValue: "false", showEl: "${entityLinkForAnotherReason || membershipStructure == 'entityAttributes' || membershipValueDn}"} -# provisionerStartWith.ldapMemberships.allowMembershipValueOverride = - # add disabled full sync daemon? -# {valueType: "boolean", order: 3300, defaultValue: "true", showEl: "${membershipValueDn != null}"} +# {valueType: "boolean", order: 3300, defaultValue: "true", showEl: "${membershipStructure != null}"} # provisionerStartWith.ldapMemberships.addDisabledFullSyncDaemon = # add disabled incremental sync daemon? -# {valueType: "boolean", order: 3400, defaultValue: "true", showEl: "${membershipValueDn != null}"} +# {valueType: "boolean", order: 3400, defaultValue: "true", showEl: "${membershipStructure != null}"} # provisionerStartWith.ldapMemberships.addDisabledIncrementalSyncDaemon = ################################################ @@ -4288,7 +4618,7 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisionerStartWith.azureCommon.azurePattern = # User attributes type -# {valueType: "string", order: 100, required: true, formElement: "dropdown", showEl: "${azurePattern != null}", optionValues: ["core", "subjectSource", "entityResolver", "subjectSourceAndEntityResolver"]} +# {valueType: "string", order: 100, required: true, formElement: "dropdown", showEl: "${azurePattern != null}", optionValues: ["core", "entityResolver", "subjectSource", "subjectSourceAndEntityResolver"]} # provisionerStartWith.azureCommon.userAttributesType = # subject source entity resolver attributes @@ -4360,3 +4690,68 @@ provisionerPropertiesToIgnore.GrouperBoxProvisioner.subsections = group,user # provisionerStartWith.azureCommon.addDisabledIncrementalSyncDaemon = +################################################ +## provisioner startWith - Duo +################################################ + +# azure common +# {valueType: "string", order: 25, readOnly: true} +# provisionerStartWith.duoCommon.startWith = duoCommon + +# this is the duo external system config id +# {valueType: "string", required: true, order: 20, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouperDuo.DuoGrouperExternalSystem"} +# provisionerStartWith.duoCommon.duoExternalSystemConfigId = + +# Duo pattern +# {valueType: "string", order: 50, required: true, formElement: "dropdown", showEl: "${duoExternalSystemConfigId != null}", optionValues: ["manageGroupsManageEntities", "manageGroupsReadonlyEntities", "manageEntities", "other"]} +# provisionerStartWith.duoCommon.duoPattern = + +# User attributes type +# {valueType: "string", order: 100, required: true, formElement: "dropdown", showEl: "${duoPattern != null}", optionValues: ["core", "entityResolver", "subjectSource", "subjectSourceAndEntityResolver"]} +# provisionerStartWith.duoCommon.userAttributesType = + +# subject source entity resolver attributes +# {valueType: "string", order: 200, required: true, showEl: "${userAttributesType == 'subjectSource' || userAttributesType == 'subjectSourceAndEntityResolver'}"} +# provisionerStartWith.duoCommon.subjectSourceEntityResolverAttributes = + +# manage groups +# {valueType: "boolean", order: 250, defaultValue: "false", showEl: "${duoPattern != null}"} +# provisionerStartWith.duoCommon.manageGroups = + +# group name attribute value +# {valueType: "string", order: 300, required: true, formElement: "dropdown", showEl: "${manageGroups == true}", optionValues: ["extension", "idIndex", "name", "other", "script", "uuid"]} +# provisionerStartWith.duoCommon.groupNameAttributeValue = + +# use group description +# {valueType: "boolean", order: 400, defaultValue: "true", showEl: "${manageGroups == true}"} +# provisionerStartWith.duoCommon.useGroupDescription = + +# manage entities +# {valueType: "boolean", order: 500, defaultValue: "false", showEl: "${duoPattern != null}"} +# provisionerStartWith.duoCommon.manageEntities = + +# Entity user name +# {valueType: "string", order: 600, required: true, formElement: "dropdown", showEl: "${manageEntities == true}", optionValues: ["other", "script", "subjectId", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2"]} +# provisionerStartWith.duoCommon.entityUserName = + +# Entity name subject attribute +# {valueType: "string", order: 700, showEl: "${manageEntities == true}"} +# provisionerStartWith.duoCommon.entityNameSubjectAttribute = + +# Entity first name subject attribute +# {valueType: "string", order: 800, showEl: "${manageEntities == true}"} +# provisionerStartWith.duoCommon.entityFirstNameSubjectAttribute = + +# Entity email subject attribute +# {valueType: "string", order: 900, showEl: "${manageEntities == true}"} +# provisionerStartWith.duoCommon.entityEmailSubjectAttribute = + +# add disabled full sync daemon? +# {valueType: "boolean", order: 1700, defaultValue: "true", showEl: "${duoPattern != null}"} +# provisionerStartWith.duoCommon.addDisabledFullSyncDaemon = + +# add disabled incremental sync daemon? +# {valueType: "boolean", order: 1800, defaultValue: "true", showEl: "${duoPattern != null}"} +# provisionerStartWith.duoCommon.addDisabledIncrementalSyncDaemon = + + diff --git a/grouper/conf/grouper-ui-ng.base.properties b/grouper/conf/grouper-ui-ng.base.properties index 41ad093145b2..80fecad253ba 100644 --- a/grouper/conf/grouper-ui-ng.base.properties +++ b/grouper/conf/grouper-ui-ng.base.properties @@ -476,6 +476,10 @@ audit.query.default-since=7 # {valueType: "string", required: false} uiV2.audit.dateFormat = yyyy/MM/dd h:mm aa +# Format string for audit dates with seconds used in membership timeline +# {valueType: "string", required: false} +uiV2.audit.dateFormatWithSeconds = yyyy/MM/dd h:mm:ss aa + ##################################################### ## Misc @@ -1224,6 +1228,18 @@ uiV2.attributeDefNamesComboboxResultSize = 200 # {valueType: "integer", required: true} uiV2.permissionActionsComboboxResultSize = 200 +################################### +## V2 UI membership settings +################################### + +# On the trace membership page, for each moment of interest, events are shown that are plus or minus the number of seconds configured here +# {valueType: "integer", required: true} +uiV2.membership.traceEventsTimeRangeInSeconds = 90 + +# On the trace membership page, additional number of states to show based on groups in events. States for groups in the membership path are shown regardless. +# {valueType: "integer", required: true} +uiV2.membership.traceAdditionalStatesCount = 10 + ################################### ## V2 UI privilege inheritance settings ################################### diff --git a/grouper/conf/grouper.base.properties b/grouper/conf/grouper.base.properties index 379fb1a718d5..b1b40ebb4e63 100644 --- a/grouper/conf/grouper.base.properties +++ b/grouper/conf/grouper.base.properties @@ -1119,7 +1119,7 @@ grouper.stemName.maxSize = #smtp server is a domain name or dns name. set to "testing" if you want to log instead of send. eg: whatever.school.edu # {valueType: "string"} -mail.smtp.server = localhost +mail.smtp.server = #leave blank if unauthenticated # {valueType: "string"} @@ -4114,6 +4114,28 @@ grouper.felix.cache.rootdir = /opt/grouper/grouperWebapp/WEB-INF/grouperFelixCac # {valueType: "string", required: true, order: 13000, showEl: "${numberOfImplementations > $i$}", repeatGroup: "osgiImplementation", repeatCount: 10} # grouperOsgiPlugin.testConfigId.osgiImplementation.$i$.implementsInterface = +############################################ +## External Authentication plugin +############################################ +# Enable external authorization security filters +# {valueType: "boolean", defaultValue: "false"} +#grouper.is.extAuth.enabled=true + +# Name of the jar containing the external authorization plugin +# {valueType: "string", required: true} +#grouper.extAuth.jarname=grouper-authentication-plugin-0.0.1-SNAPSHOT.jar + +# Callback filter implementation classname +# ex: edu.internet2.middleware.grouper.plugins.testImplementation.SamplePluginProviderServiceImpl +# ${valueType: "class", required: true} +#grouper.extAuth.filter.callback.implmentation.className=edu.internet2.middleware.grouper.authentication.plugin.filter.CallbackFilterDecorator + +# Security filter implementation classname +# ex: edu.internet2.middleware.grouper.plugins.testImplementation.SamplePluginProviderServiceImpl +# ${valueType: "class", required: true} +#grouper.extAuth.filter.security.implmentation.className=edu.internet2.middleware.grouper.authentication.plugin.filter.SecurityFilterDecorator + + ############################################ ## logging loggers (levels and appenders) @@ -4140,6 +4162,4 @@ grouper.felix.cache.rootdir = /opt/grouper/grouperWebapp/WEB-INF/grouperFelixCac # which appender to send logs to (optional), default to the appender for the class logs to, or default to: grouper_error # e.g. CATALINA, stderr, grouper_error, grouper_daemon, grouper_pspng, grouper_provisioning, grouper_ws, grouper_ws_longRunning # {valueType: "string", regex: "^grouper\\.logger\\.[^.]+\\.appender$"} -# grouper.logger..appender = - - +# grouper.logger..appender = \ No newline at end of file diff --git a/grouper/conf/grouperText/grouper.textNg.en.us.base.properties b/grouper/conf/grouperText/grouper.textNg.en.us.base.properties index 413a75c0c67c..31311d3f0032 100644 --- a/grouper/conf/grouperText/grouper.textNg.en.us.base.properties +++ b/grouper/conf/grouperText/grouper.textNg.en.us.base.properties @@ -3943,6 +3943,34 @@ membershipTraceBreadcrumb = Trace membership # lead at the top of the page that explains trace membership membershipTracePageLead = ${grouperRequestContainer.subjectContainer.guiSubject.ScreenLabelShort2noLink} is a member of the ${grouperUtil.xmlEscape(grouperRequestContainer.groupContainer.guiGroup.group.displayExtension)} group by the following paths: +# pit membership trace +pitMembershipTracePageLead = ${grouperRequestContainer.subjectContainer.guiSubject.ScreenLabelShort2noLink} was a member of the ${grouperUtil.xmlEscape(grouperRequestContainer.groupContainer.guiGroup.group.displayExtension)} group by the following path: +pitMembershipTracePathFirstLineCurrentMembership =

    ${grouperRequestContainer.subjectContainer.guiSubject.shortLink} is a direct member of

    +pitMembershipTracePathFirstLinePreviousMembership =

    ${grouperRequestContainer.subjectContainer.guiSubject.shortLink} is NOT a direct member of (ended ${grouperRequestContainer.membershipGuiContainer.getGuiAuditDateLabelCurrent()})

    +pitMembershipTraceGroupLine =

    ${grouperRequestContainer.membershipGuiContainer.guiPITGroupCurrent.linkOrName}

    +pitMembershipTraceGroupMemberOfCurrentMembership =

    which is a direct member of

    +pitMembershipTraceGroupMemberOfPreviousMembership =

    which is NOT a direct member of (ended ${grouperRequestContainer.membershipGuiContainer.getGuiAuditDateLabelCurrent()})

    + +# membership trace timeline +membershipTraceTimelinePageLead = Membership timeline: +membershipTraceTimelineButton = Show timeline +membershipTraceTimelineShowUserAudit = Show user audit +membershipTraceTimelineShowPITAudit = Show point in time audit +membershipTraceTimelineShowProvisioningEvents = Show provisioning events +membershipTraceTimelineDescription = The following are times when the subject was added or removed from any of the groups in the membership path above. The events include all membership adds and removes for the subject around the time. And the state includes whether the subject was a member of each of the groups in the membership path at that time. +membershipTraceTimelineMomentOfInterestEventsLabel = Event(s) +membershipTraceTimelineMomentOfInterestStateLabel = State +membershipTraceTimelineMomentOfInterest =
  • ${grouperRequestContainer.membershipGuiContainer.getGuiAuditDateLabelCurrent()}
  • +membershipTraceTimelineUserAuditAddMembership =
  •  ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGuiDateWithSeconds()} - [user audit] ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGuiSubjectPerformedAction().shortLink} added ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGuiMember().shortLink} to ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGuiGroup().link} group using ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGrouperEngineLabel()}
  • +membershipTraceTimelineUserAuditUpdateMembership =
  •  ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGuiDateWithSeconds()} - [user audit] ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGuiSubjectPerformedAction().shortLink} updated ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGuiMember().shortLink} in ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGuiGroup().link} group using ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGrouperEngineLabel()}
  • +membershipTraceTimelineUserAuditDeleteMembership =
  •  ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGuiDateWithSeconds()} - [user audit] ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGuiSubjectPerformedAction().shortLink} removed ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGuiMember().shortLink} from ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGuiGroup().link} group using ${grouperRequestContainer.membershipGuiContainer.getGuiAuditEntryCurrent().getGrouperEngineLabel()}
  • +membershipTraceTimelinePITAuditAddMembership =
  •  ${grouperRequestContainer.membershipGuiContainer.getGuiAuditDateLabelCurrent()} - [point in time audit] added ${grouperRequestContainer.subjectContainer.guiSubject.shortLink} to ${grouperRequestContainer.membershipGuiContainer.guiPITGroupCurrent.linkOrName} group
  • +membershipTraceTimelinePITAuditDeleteMembership =
  •  ${grouperRequestContainer.membershipGuiContainer.getGuiAuditDateLabelCurrent()} - [point in time audit] removed ${grouperRequestContainer.subjectContainer.guiSubject.shortLink} from ${grouperRequestContainer.membershipGuiContainer.guiPITGroupCurrent.linkOrName} group
  • +membershipTraceTimelineProvisioningTargetStart =
  •  ${grouperRequestContainer.membershipGuiContainer.getGuiGcGrouperSyncMembershipCurrent().getInTargetStartLabel()} - [provisioning] added ${grouperRequestContainer.subjectContainer.guiSubject.shortLink} to ${grouperRequestContainer.membershipGuiContainer.getGuiGcGrouperSyncMembershipCurrent().groupLinkOrName} group in target ${grouperRequestContainer.membershipGuiContainer.getGuiGcGrouperSyncMembershipCurrent().provisionerName}
  • +membershipTraceTimelineProvisioningTargetEnd =
  •  ${grouperRequestContainer.membershipGuiContainer.getGuiGcGrouperSyncMembershipCurrent().getInTargetEndLabel()} - [provisioning] removed ${grouperRequestContainer.subjectContainer.guiSubject.shortLink} from ${grouperRequestContainer.membershipGuiContainer.getGuiGcGrouperSyncMembershipCurrent().groupLinkOrName} group in target ${grouperRequestContainer.membershipGuiContainer.getGuiGcGrouperSyncMembershipCurrent().provisionerName}
  • +membershipTraceTimelineStateMembershipYes =
  •  ${grouperRequestContainer.membershipGuiContainer.guiPITGroupCurrent.linkOrName}
  • +membershipTraceTimelineStateMembershipNo =
  •  ${grouperRequestContainer.membershipGuiContainer.guiPITGroupCurrent.linkOrName}
  • + # no memberships found on trace memberships screen membershipTraceNoMembershipFound = No memberships found @@ -3982,13 +4010,13 @@ membershipTraceBackToMembershipButton = Back to membership membershipTraceBackToAttributeDefButton = Back to attribute # if there are no paths -membershipTraceGroupNoPaths = There are no indirect paths for this entity and group +membershipTraceGroupNoPaths = There are no current indirect paths for this entity and group. # if there are no paths allowed by user -membershipTraceGroupNoPathsAllowed = There are no indirect paths for this entity and group that you are allowed to read +membershipTraceGroupNoPathsAllowed = There are no current indirect paths for this entity and group that you are allowed to read. # if there are some paths cannot see -membershipTraceGroupPathsNotAllowed = Note: there are ${grouperRequestContainer.membershipGuiContainer.pathCountNotAllowed} paths for this entity and group that you are not allowed to see since you cannot READ a group in the path +membershipTraceGroupPathsNotAllowed = Note: there are ${grouperRequestContainer.membershipGuiContainer.pathCountNotAllowed} current paths for this entity and group that you are not allowed to see since you cannot READ a group in the path. ######################################## ## Edit memberships @@ -8935,14 +8963,14 @@ privsioningConfigDetailsLastGroupMetadataSync = Last metadata sync time privsioningConfigDetailsLastGroupMetadataSyncStart = Last metadata sync start time privsioningConfigDetailsLastGroupMetadataSyncDescription = Last time when this group's name and description and metadata was synced (not including memberships) privsioningConfigDetailsLastGroupMetadataSyncStartDescription = Last time when this group's name and description and metadata was started to be synced (not including memberships) -privsioningConfigDetailsGroupFromId2 = Group from id2 -privsioningConfigDetailsGroupFromId2Description = Group from id2 -privsioningConfigDetailsGroupFromId3 = Group from id3 -privsioningConfigDetailsGroupFromId3Description = Group from id3 -privsioningConfigDetailsGroupToId2 = Group to id2 -privsioningConfigDetailsGroupToId2Description = Group to id2 -privsioningConfigDetailsGroupToId3 = Group to id3 -privsioningConfigDetailsGroupToId3Description = Group to id3 +privsioningConfigDetailsGroupAttributeValueCache0 = Group from id2 +privsioningConfigDetailsGroupAttributeValueCache0Description = Group from id2 +privsioningConfigDetailsGroupAttributeValueCache1 = Group from id3 +privsioningConfigDetailsGroupAttributeValueCache1Description = Group from id3 +privsioningConfigDetailsGroupAttributeValueCache2 = Group to id2 +privsioningConfigDetailsGroupAttributeValueCache2Description = Group to id2 +privsioningConfigDetailsGroupAttributeValueCache3 = Group to id3 +privsioningConfigDetailsGroupAttributeValueCache3Description = Group to id3 privsioningConfigDetailsMetadataUpdated = Sync link last updated privsioningConfigDetailsMetadataUpdatedDescription = If this object has a link data cached, this is the last time it was updated from the target privsioningConfigDetailsErrorMessage = Error message @@ -8995,14 +9023,14 @@ privsioningConfigDetailsMembershipId2 = Membership id2 privsioningConfigDetailsMembershipId2Description = Membership id2 privsioningConfigDetailsProvisionable = Provisionable -privsioningConfigDetailsMemberFromId2 = Member from id2 -privsioningConfigDetailsMemberFromId2Description = Member from id2 -privsioningConfigDetailsMemberFromId3 = Member from id3 -privsioningConfigDetailsMemberFromId3Description = Member from id3 -privsioningConfigDetailsMemberToId2 = Member to id2 -privsioningConfigDetailsMemberToId2Description = Member to id2 -privsioningConfigDetailsMemberToId3 = Member to id3 -privsioningConfigDetailsMemberToId3Description = Member to id3 +privsioningConfigDetailsEntityAttributeValueCache0 = Member from id2 +privsioningConfigDetailsEntityAttributeValueCache0Description = Member from id2 +privsioningConfigDetailsEntityAttributeValueCache1 = Member from id3 +privsioningConfigDetailsEntityAttributeValueCache1Description = Member from id3 +privsioningConfigDetailsEntityAttributeValueCache2 = Member to id2 +privsioningConfigDetailsEntityAttributeValueCache2Description = Member to id2 +privsioningConfigDetailsEntityAttributeValueCache3 = Member to id3 +privsioningConfigDetailsEntityAttributeValueCache3Description = Member to id3 provisioningGroupSyncSuccess = Provisioner group sync message was sent successfully @@ -9022,10 +9050,10 @@ provisioningSubjectProvsionableEndLabel = Provisionable end provisioningSubjectLastUpdatedLabel = Last updated provisioningSubjectLastUserSyncLabel = Last user sync provisioningSubjectLastUserMetadataSyncLabel = Last user metadata sync -provisioningSubjectMemberFromId2Label = Member from id2 -provisioningSubjectMemberFromId3Label = Member from id3 -provisioningSubjectMemberToId2Label = Member to id2 -provisioningSubjectMemberToId3Label = Member to id3 +provisioningSubjectEntityAttributeValueCache0Label = Member from id2 +provisioningSubjectEntityAttributeValueCache1Label = Member from id3 +provisioningSubjectEntityAttributeValueCache2Label = Member to id2 +provisioningSubjectEntityAttributeValueCache3Label = Member to id3 provisioningSubjectMembershipIdLabel = Membership id provisioningSubjectMembershipId2Label = Membership id2 @@ -11574,10 +11602,10 @@ provisionerActivityTableHeaderLastGroupSyncStart = Last group sync start time provisionerActivityTableHeaderLastGroupSync = Last group sync time provisionerActivityTableHeaderLastGroupMetadataSyncStart = Last group metadata sync start time provisionerActivityTableHeaderLastGroupMetadataSync = Last group metadata sync time -provisionerActivityTableHeaderGroupFromId2 = Group from id2 -provisionerActivityTableHeaderGroupFromId3 = Group from id3 -provisionerActivityTableHeaderGroupToId2 = Group to id2 -provisionerActivityTableHeaderGroupToId3 = Group to id3 +provisionerActivityTableHeaderGroupAttributeValueCache0 = Group from id2 +provisionerActivityTableHeaderGroupAttributeValueCache1 = Group from id3 +provisionerActivityTableHeaderGroupAttributeValueCache2 = Group to id2 +provisionerActivityTableHeaderGroupAttributeValueCache3 = Group to id3 provisionerActivityTableHeaderMetadataUpdated = Metdata updated time provisionerActivityTableHeaderErrorMessage = Error message time provisionerActivityTableHeaderErrorTimestamp = Error time @@ -11592,10 +11620,10 @@ provisionerActivityTableHeaderLastUserSyncStart = Last user sync start time provisionerActivityTableHeaderLastUserSync = Last user sync time provisionerActivityTableHeaderLastUserMetadataSyncStart = Last metadata sync start time provisionerActivityTableHeaderLastUserMetadataSync = Last metadata sync time -provisionerActivityTableHeaderMemberFromId2 = Member from id2 -provisionerActivityTableHeaderMemberFromId3 = Member from id3 -provisionerActivityTableHeaderMemberToId2 = Member to id2 -provisionerActivityTableHeaderMemberToId3 = Member to id3 +provisionerActivityTableHeaderEntityAttributeValueCache0 = Member from id2 +provisionerActivityTableHeaderEntityAttributeValueCache1 = Member from id3 +provisionerActivityTableHeaderEntityAttributeValueCache2 = Member to id2 +provisionerActivityTableHeaderEntityAttributeValueCache3 = Member to id3 provisionerActivityTableHeaderMembershipId = Membership id provisionerActivityTableHeaderMembershipId2 = Membership id2 @@ -11769,6 +11797,8 @@ provisionerConfigConfirmDeleteConfig = Are you sure you want to delete this prov # error that provisioner config id is required provisionerConfigCreateErrorConfigIdRequired = Error: Configuration id is required +provisionerConfigStartWithIdRequired = Error: Start with is required + # Add provisioner config breadcrumb on misc. page miscellaneousProvisionerConfigAddBreadcrumb = Add provisioner configuration miscellaneousProvisionerConfigEditBreadcrumb = Edit provisioner configuration @@ -11776,6 +11806,8 @@ miscellaneousProvisionerConfigEditBreadcrumb = Edit provisioner configuration # provisioner config add form submit button label provisionerConfigAddFormSubmitButton = Submit +provisionerConfigAddFormContinueButton = Continue + # provisioner config edit form submit button label provisionerConfigEditFormSubmitButton = Submit @@ -11802,6 +11834,11 @@ provisionerTypeHint = Type of provisioner that will be connected to, for example provisionerStartWithLabel = Start with provisionerStartWithHint = Start with +provisionerStartWithOption_edu.internet2.middleware.grouper.app.sqlProvisioning.SqlProvisioningStartWith = SQL 'start with' +provisionerStartWithOption_edu.internet2.middleware.grouper.app.azure.AzureProvisioningStartWith = Azure 'start with' +provisionerStartWithOption_edu.internet2.middleware.grouper.app.duo.DuoProvisioningStartWith = Duo 'start with' +provisionerStartWithOption_edu.internet2.middleware.grouper.app.ldapProvisioning.LdapProvisioningMembershipStartWith = LDAP 'start with' + # provisioner config was saved successfully provisionerConfigAddEditSuccess = Provisioner configuration was saved successfully. @@ -12685,13 +12722,17 @@ grouperConfigurationValidationConfigIdInvalid = Error: the '$$configIdLabel$$' m grouperConfigurationValidationTestSqlQueryRequired = Error: '${configFieldLabel}' is required when test expected value is provided grouperConfigurationTestExpectedNotMatchingResult = Error: expected '$$expectedValue$$' but received '$$receivedValue$$' -grouperStartWithGroupTableConfigurationValidationGroupTableNotFound = Error: '$$groupTableName$$' not found +grouperStartWithGroupTableConfigurationValidationGroupTableNotFound = Error: '$$tableName$$' not found grouperStartWithEntityTableConfigurationValidationUserTableNotFound = Error: '$$userTableName$$' not found -grouperStartWithGroupTableConfigurationValidationGroupIdColumnNotFound = Error: '$$groupTableIdColumn$$' not found +grouperStartWithGroupTableConfigurationValidationGroupIdColumnNotFound = Error: '$$column$$' not found grouperStartWithEntityTableConfigurationValidationUserIdColumnNotFound = Error: '$$userTableIdColumn$$' not found grouperStartWithGroupTableConfigurationValidationGroupColumnsNotFound = Error: '$$groupTableColumns$$' columns not found grouperStartWithEntityTableConfigurationValidationEntityColumnsNotFound = Error: '$$userTableColumns$$' columns not found +grouperStartWithInvalidMembershipStructureHasMembershipTable = If membership structure is not notApplicable then has membership table must be true + +subjectSourceEntityResolverAttributesMoreThanThreeAttributes = There cannot be more than three attributes + grouperStartWithLdapConfigurationValidationExternalSystemNotActiveDirectory = Error: External system with id '$$externalSystemId$$' is not of type active directory. grouperStartWithLdapConfigurationValidationSubjectAttributesNotValid = Error: '$$subjectAttributes$$' not valid @@ -13135,11 +13176,11 @@ startWithBlankConfiguration = Blank configuration config.SqlProvisioningGroupTableStartWith.startWithDescription = This is the description for group table start with config.SqlProvisioningGroupTableStartWith.startWithDocumentation = This is the documentation for group table start with -config.SqlProvisionerConfiguration.description = This is the description for Sql provisioner -config.SqlProvisionerConfiguration.documentation = This is the documentation for Sql provisioner +config.SqlProvisionerConfiguration.description = The Grouper SQL provisioner will provision group / entity / membership information to a SQL database. +config.SqlProvisionerConfiguration.documentation = The database can be of any type and must be defined as an external system. The table structure can consist of: a group table, a group attribute table, an entity table, and entity attribute table, and a membership table. -config.LdapGrouperExternalSystem.description = This is the description for Ldap external system -config.LdapGrouperExternalSystem.documentation = This is the documentation for Ldap external system +config.LdapGrouperExternalSystem.description = The Grouper LDAP provisioner will provision group / entity / membership information to an LDAP or AD. +config.LdapGrouperExternalSystem.documentation = The LDAP or AD must be defined as an external system. The memberships can be represented as attribute values of a group (groupAttributes), or attribute values of an LDAP user (entityAttributes). config.AzureProvisionerConfiguration.title = Azure config.AzureProvisionerConfiguration.description = This is the description for Azure provisioner @@ -13241,31 +13282,113 @@ grouperProvisioningMetadataDuoEmailDescription = Add an email address config.GenericConfiguration.subSection.entityAttributes.title = External entity attributes configuration config.GenericConfiguration.subSection.entityAttributes.description = If you are provisioning data items about users which need to be retrieved from a SQL or LDAP call. -config.GenericConfiguration.subSection.entityAttributes.documentation = This is the test documentation +config.GenericConfiguration.subSection.entityAttributes.documentation = When provisioning user (entity) data, the data might be built-in to Grouper (e.g. subject id, name, description, subject identifier), or need a subject link (retrieve arbitrary subject API attributes), or use this, make a SQL or LDAP call to get attributes about a user. Generally this is 'false' and will be removed in a future Grouper release as we transition to user data fields. config.GenericConfiguration.subSection.group.title = Group configuration config.GenericConfiguration.subSection.group.description = Configuration dealing with groups in the target +config.GenericConfiguration.subSection.group.documentation = A group consists of attributes and a collection of entities. Grouper provisions groups in the format that the target uses to represent them. config.GenericConfiguration.subSection.entity.title = Entity configuration config.GenericConfiguration.subSection.entity.description = Configuration dealing with entities in the target +config.GenericConfiguration.subSection.entity.documentation = An entity is a subject or a user. Entities can be in groups as memberships. Grouper provisions entities in the format that the target uses to represent them. By default Grouper assumes another provisioning system is provisioning entities and uses them readonly, but Grouper can insert/update/delete entities if needed. config.GenericConfiguration.subSection.membership.title = Membership configuration config.GenericConfiguration.subSection.membership.description = Configuration dealing with memberships in the target +config.GenericConfiguration.subSection.membership.documentation = Group provisions the effective relationship of an entity in a group in the form of memberships. Grouper will provision memberships is the format that the target uses to represent memberships. config.GenericConfiguration.subSection.assigningProvisioning.title = Assigning provisioning config.GenericConfiguration.subSection.assigningProvisioning.description = Settings regarding how objects are marked provisionable +config.GenericConfiguration.subSection.assigningProvisioning.documentation = You can configure how users assign objects to be provisionable in grouper, who can assign, view, etc. config.GenericConfiguration.subSection.provisioningDiagnostics.title = Provisioning diagnostics -config.GenericConfiguration.subSection.provisioningDiagnostics.description = Provisioning diagnostics +config.GenericConfiguration.subSection.provisioningDiagnostics.description = Check to see if your provisioner is configured correctly +config.GenericConfiguration.subSection.provisioningDiagnostics.documentation = Run the diagnostics for insights into how the translations and target operations are functioning to make sure the provisioner is working how you want it to work. config.GenericConfiguration.subSection.advanced.title = Advanced -config.GenericConfiguration.subSection.advanced.description = Advanced +config.GenericConfiguration.subSection.advanced.description = Less common settings +config.GenericConfiguration.subSection.advanced.documentation = Configure logging and other settings config.GenericConfiguration.subSection.general2.title = General configuration section 2 -config.GenericConfiguration.subSection.general2.description = Provisioning configuration after memberships / groups / entities +config.GenericConfiguration.subSection.general2.description = Provisioning configuration after attributes configured for memberships / groups / entities +config.GenericConfiguration.subSection.general2.documentation = Some settings rely on configurations in the memberships / groups / entities sections so this second second section is below those + +config.GenericConfiguration.subSection.group2.title = Group configuration section 2 +config.GenericConfiguration.subSection.group2.description = Group configuration after attributes configured for memberships / groups / entities +config.GenericConfiguration.subSection.group2.documentation = Some settings rely on configurations in the memberships / groups / entities sections so this second second section is below those + + +config.GenericConfiguration.attribute.groupMatchingAttributeSameAsSearchAttribute.label = Matching attribute(s) same as search attribute(s) +config.GenericConfiguration.attribute.groupMatchingAttributeSameAsSearchAttribute.description = Generally the attribute(s) used to match target groups with grouper groups are the same as search attribute(s). If you want to match on different attribute(s) than being searched for then set to false. + +config.GenericConfiguration.attribute.groupMatchingAttributeCount.label = Matching attribute count +config.GenericConfiguration.attribute.groupMatchingAttributeCount.description = Generally you will have one matching attribute though if you wanted a fallback if the primary attribute does not match you can configure multiple attributes. + +config.GenericConfiguration.attribute.groupMatchingAttribute0name.label = Matching attribute 1 +config.GenericConfiguration.attribute.groupMatchingAttribute0name.description = The first matching attribute used to match target groups with Grouper groups + +config.GenericConfiguration.attribute.groupMatchingAttribute1name.label = Matching attribute 2 +config.GenericConfiguration.attribute.groupMatchingAttribute1name.description = The second matching attribute used to match target groups with Grouper groups + +config.GenericConfiguration.attribute.groupMatchingAttribute2name.label = Matching attribute 3 +config.GenericConfiguration.attribute.groupMatchingAttribute2name.description = The third matching attribute used to match target groups with Grouper groups + +config.GenericConfiguration.attribute.groupSearchAttributeCount.label = Search attribute count +config.GenericConfiguration.attribute.groupSearchAttributeCount.description = Generally you will have one search attribute though if you wanted a fallback if the primary attribute does not find the group in the target you can configure multiple attributes. + +config.GenericConfiguration.attribute.groupSearchAttribute0name.label = Search attribute 1 +config.GenericConfiguration.attribute.groupSearchAttribute0name.description = The first search attribute used to find target groups based on data in Grouper. + +config.GenericConfiguration.attribute.groupSearchAttribute1name.label = Search attribute 2 +config.GenericConfiguration.attribute.groupSearchAttribute1name.description = The second search attribute used to find target groups based on data in Grouper. If the group is not found with the first attribute, this one will be used + +config.GenericConfiguration.attribute.groupSearchAttribute2name.label = Search attribute 3 +config.GenericConfiguration.attribute.groupSearchAttribute2name.description = The third search attribute used to find target groups based on data in Grouper. If the group is not found with the first or second attribute, this one will be used + + +config.GenericConfiguration.attribute.group2advanced.label = Advanced options +config.GenericConfiguration.attribute.group2advanced.description = Advanced options for group section 2 + +config.GenericConfiguration.attribute.entity2advanced.label = Advanced options +config.GenericConfiguration.attribute.entity2advanced.description = Advanced options for entity section 2 + +config.GenericConfiguration.subSection.membership2.title = Membership configuration section 2 +config.GenericConfiguration.subSection.membership2.description = Membership configuration after attributes configured for memberships / groups / entities +config.GenericConfiguration.subSection.membership2.documentation = Some settings rely on configurations in the memberships / groups / entities sections so this second second section is below those + +config.GenericConfiguration.subSection.entity2.title = Entity configuration section 2 +config.GenericConfiguration.subSection.entity2.description = Entity configuration after attributes configured for memberships / groups / entities +config.GenericConfiguration.subSection.entity2.documentation = Some settings rely on configurations in the memberships / groups / entities sections so this second second section is below those + +config.GenericConfiguration.attribute.entityMatchingAttributeSameAsSearchAttribute.label = Matching attribute(s) same as search attribute(s) +config.GenericConfiguration.attribute.entityMatchingAttributeSameAsSearchAttribute.description = Generally the attribute(s) used to match target entities with grouper entities are the same as search attribute(s). If you want to match on different attribute(s) than being searched for then set to false. + +config.GenericConfiguration.attribute.entityMatchingAttributeCount.label = Matching attribute count +config.GenericConfiguration.attribute.entityMatchingAttributeCount.description = Generally you will have one matching attribute though if you wanted a fallback if the primary attribute does not match you can configure multiple attributes. + +config.GenericConfiguration.attribute.entityMatchingAttribute0name.label = Matching attribute 1 +config.GenericConfiguration.attribute.entityMatchingAttribute0name.description = The first matching attribute used to match target entities with Grouper entities + +config.GenericConfiguration.attribute.entityMatchingAttribute1name.label = Matching attribute 2 +config.GenericConfiguration.attribute.entityMatchingAttribute1name.description = The second matching attribute used to match target entities with Grouper entities + +config.GenericConfiguration.attribute.entityMatchingAttribute2name.label = Matching attribute 3 +config.GenericConfiguration.attribute.entityMatchingAttribute2name.description = The third matching attribute used to match target entities with Grouper entities + +config.GenericConfiguration.attribute.entitySearchAttributeCount.label = Search attribute count +config.GenericConfiguration.attribute.entitySearchAttributeCount.description = Generally you will have one search attribute though if you wanted a fallback if the primary attribute does not find the entity in the target you can configure multiple attributes. + +config.GenericConfiguration.attribute.entitySearchAttribute0name.label = Search attribute 1 +config.GenericConfiguration.attribute.entitySearchAttribute0name.description = The first search attribute used to find target entities based on data in Grouper. + +config.GenericConfiguration.attribute.entitySearchAttribute1name.label = Search attribute 2 +config.GenericConfiguration.attribute.entitySearchAttribute1name.description = The second search attribute used to find target entities based on data in Grouper. If the entity is not found with the first attribute, this one will be used + +config.GenericConfiguration.attribute.entitySearchAttribute2name.label = Search attribute 3 +config.GenericConfiguration.attribute.entitySearchAttribute2name.description = The third search attribute used to find target entities based on data in Grouper. If the entity is not found with the first or second attribute, this one will be used + config.GenericConfiguration.subSection.targetGroupAttribute.i.title = Target __i+1__ -config.GenericConfiguration.subSection.targetGroupAttribute.i.description = Configuration for the group field / attribute +config.GenericConfiguration.subSection.targetGroupAttribute.i.description = Configuration for the group attribute config.GenericConfiguration.subSection.targetEntityAttribute.i.title = Target __i+1__ -config.GenericConfiguration.subSection.targetEntityAttribute.i.description = Configuration for the entity field / attribute +config.GenericConfiguration.subSection.targetEntityAttribute.i.description = Configuration for the entity attribute config.GenericConfiguration.subSection.targetMembershipAttribute.i.title = Target __i+1__ -config.GenericConfiguration.subSection.targetMembershipAttribute.i.description = Configuration for the membership field / attribute +config.GenericConfiguration.subSection.targetMembershipAttribute.i.description = Configuration for the membership attribute config.GenericConfiguration.attribute.class.label = Class config.GenericConfiguration.attribute.quartzCron.label = Quartz cron @@ -13290,6 +13413,15 @@ config.GenericConfiguration.attribute.deleteMembershipsIfGrouperCreated.descript config.GenericConfiguration.attribute.operateOnGrouperGroups.label = Operate on groups config.GenericConfiguration.attribute.operateOnGrouperGroups.description = If the provisioner involves group objects. This might not be true if you are provisioning memberships or entityAttributes without a target group link. +config.GenericConfiguration.attribute.membershipAdvancedOptions.label = Advanced options +config.GenericConfiguration.attribute.membershipAdvancedOptions.description = Advanced membership options, note, there might not be any + +config.GenericConfiguration.attribute.membership2AdvancedOptions.label = Advanced options +config.GenericConfiguration.attribute.membership2AdvancedOptions.description = Advanced membership2 options, note, there might not be any + +config.GenericConfiguration.attribute.membershipMatchingIdExpression.label = Membership matching ID expression +config.GenericConfiguration.attribute.membershipMatchingIdExpression.description = This is an advanced option for edge cases. Put in a JEXL expression that will create a matching ID for memberships (e.g. SQL, though SQL should be able to do this automatically). e.g.
    ${new('edu.internet2.middleware.grouperClient.collections.MultiKey', targetMembership.retrieveAttributeValueString('group_col'), targetMembership.retrieveAttributeValueString('entity_col'))} + config.GenericConfiguration.attribute.customizeGroupCrud.label = Customize group CRUD config.GenericConfiguration.attribute.customizeGroupCrud.description = Customize Create/Read/Update/Delete characteristics of groups. By default groups will SELECT / INSERT / UPDATE / DELETE_IF_GROUPER_CREATED_THEN_DELETED @@ -13314,7 +13446,7 @@ config.GenericConfiguration.attribute.deleteGroupsIfGrouperDeleted.description = config.GenericConfiguration.attribute.deleteGroupsIfGrouperCreated.label = Delete groups if created by Grouper config.GenericConfiguration.attribute.deleteGroupsIfGrouperCreated.description = Delete groups if Grouper provisioned the group at some point in the past and the group was removed in Grouper. This is the default behavior. config.GenericConfiguration.attribute.updateGroups.label = Update groups -config.GenericConfiguration.attribute.updateGroups.description = If group fields and attributes which differ from the target should cause the target data to be updated. This does not include the membership attribute if the membership provisioning type is groupAttributes. +config.GenericConfiguration.attribute.updateGroups.description = If group attributes which differ from the target should cause the target data to be updated. This does not include the membership attribute if the membership provisioning type is groupAttributes. config.GenericConfiguration.attribute.groupRequireMembers.label = Require members config.GenericConfiguration.attribute.groupRequireMembers.description = If the group has no members, then consider it not provisionable (e.g. it is eligible to be removed from target) @@ -13343,13 +13475,18 @@ config.GenericConfiguration.attribute.logCommandsAlways.label = Log target comma config.GenericConfiguration.attribute.logCommandsAlways.description = Log the low level commands to the target for all commands (successes and failures). This should only be enabled while troubleshooting. config.GenericConfiguration.attribute.logCommandsOnError.label = Log target commands on error config.GenericConfiguration.attribute.logCommandsOnError.description = Log the low level commands to the target for errors. This should only be enabled while troubleshooting. This has performance implications even for non error transactions. + +config.GenericConfiguration.attribute.logMaxErrorsPerType.label = Log max errors per type +config.GenericConfiguration.attribute.logMaxErrorsPerType.description = Each DAO operation has an error type, e.g. "entityUpdate". If there is an error only log it if this many errors of that type has not already been logged. Turn off this logging by setting to 0. + config.GenericConfiguration.attribute.groupAllowedToAssign.label = Group allowed to assign +config.GenericConfiguration.attribute.groupAllowedToView.label = Group allowed to view config.GenericConfiguration.attribute.allowAssignmentsOnlyOnOneStem.label = Allow assignments only on one stem config.GenericConfiguration.attribute.readOnly.label = Read only config.GenericConfiguration.attribute.readOnly.description = Run this provisioner in read only mode meaning no changes will be made to the target. The "log all objects verbose" will show what the provisioner would have done. config.GenericConfiguration.attribute.numberOfGroupAttributes.label = Number of group attributes config.GenericConfiguration.attribute.numberOfMembershipAttributes.label = Number of membership attributes -config.GenericConfiguration.attribute.numberOfGroupAttributes.description = In the object that represents a target group, this is the number of fields and attributes +config.GenericConfiguration.attribute.numberOfGroupAttributes.description = In the object that represents a target group, this is the number of attributes config.GenericConfiguration.attribute.numberOfMembershipAttributes.description = In the object that represents a target membership, this is the number of attributes config.GenericConfiguration.attribute.recalculateAllOperations.label = Recalculate all real time events config.GenericConfiguration.attribute.provisioningType.label = Provisioning type @@ -13518,6 +13655,123 @@ config.LdapProvisioningMembershipStartWith.attribute.ldapExternalSystemConfigId. config.GenericConfiguration.attribute.startWith.label = Start with id config.GenericConfiguration.attribute.startWith.description = Start with id +config.SqlProvisioningStartWith.attribute.dbExternalSystemConfigId.label = Db external system config id +config.SqlProvisioningStartWith.attribute.dbExternalSystemConfigId.description = Sql database external system config id. If you do not see your database configuration add it in Miscellaneous -> External systems. You can also provision across database link. + +config.SqlProvisioningStartWith.attribute.sqlPattern.label = Sql pattern +config.SqlProvisioningStartWith.attribute.sqlPattern.description = entityTable - provision a table of entities
    entityTableWithAttributeTable - provision entities into a table but allow some attributes to be columns of the entity table and some attributes to be in a separate table for entity attributes
    entityTableWithAttributeTableAndMemberships - provision entities into a table but allow some attributes to be columns of the entity table and some attributes to be in a separate table for entity attributes. Memberships will be provisioned like LDAP where they are a multi-valued attribute of the entity, in the entity attributes table
    entityTableMembershipTable - provision a table of entities and a table for memberships. One column of the membership table is a foreign key to the entity table, and the other column is something related to the group (e.g. groupName)
    groupTable - provision a table of groups
    groupTableWithAttributeTable - provision groups into a table but allow some attributes to be columns of the group table and some attributes to be in a separate table for group attributes
    groupTableWithAttributeTableAndMemberships - provision groups into a table but allow some attributes to be columns of the group table and some attributes to be in a separate table for group attributes. Memberships will be provisioned like LDAP where they are a multi-valued attribute of the group, in the group attributes table
    groupTableMembershipTable - provision a table of groups and a table for memberships. One column of the membership table is a foreign key to the group table, and the other column is something related to the entity (e.g. subjectId)
    groupTableEntityTableMembershipTable - provision a table for groups, a table for entities, and a table for memberships. The memberships table has two columns, one for the foreign key to groups, and one for the foreign key to memberships
    membershipTable - provision a table with memberships with two columns, something related to the group (e.g. groupName), and something related to the entity (e.g. subjectId)
    other - no pattern, just fill out this form + +config.SqlProvisioningStartWith.attribute.userAttributesType.label = User attributes type +config.SqlProvisioningStartWith.attribute.userAttributesType.description = User attributes type + +config.SqlProvisioningStartWith.attribute.membershipStructure.label = Membership structure +config.SqlProvisioningStartWith.attribute.membershipStructure.description = Membership structure + +config.SqlProvisioningStartWith.attribute.subjectSourceEntityResolverAttributes.label = Subject source entity resolver attributes +config.SqlProvisioningStartWith.attribute.subjectSourceEntityResolverAttributes.description = Subject source entity resolver attributes + +config.SqlProvisioningStartWith.attribute.hasGroupTable.label = Has group table +config.SqlProvisioningStartWith.attribute.hasGroupTable.description = Has group table + +config.SqlProvisioningStartWith.attribute.groupTableName.label = Group table name +config.SqlProvisioningStartWith.attribute.groupTableName.description = Group table name, e.g. from_grouper_group + +config.SqlProvisioningStartWith.attribute.groupTableIdColumn.label = Group table primary key +config.SqlProvisioningStartWith.attribute.groupTableIdColumn.description = Group table primary key column, e.g. group_id_index + +config.SqlProvisioningStartWith.attribute.groupTablePrimaryKeyValue.label = Group table primary key value +config.SqlProvisioningStartWith.attribute.groupTablePrimaryKeyValue.description = Group table primary key value, e.g. groupIdIndex + +config.SqlProvisioningStartWith.attribute.groupTableColumnNames.label = Group table column names +config.SqlProvisioningStartWith.attribute.groupTableColumnNames.description = Group table column names + +config.SqlProvisioningStartWith.attribute.hasTargetGroupLink.label = Need group link? +config.SqlProvisioningStartWith.attribute.hasTargetGroupLink.description = Need group link? + +config.SqlProvisioningStartWith.attribute.hasGroupAttributeTable.label = Has group attribute table? +config.SqlProvisioningStartWith.attribute.hasGroupAttributeTable.description = Has group attribute table? + +config.SqlProvisioningStartWith.attribute.groupAttributesTableName.label = Group attribute table name +config.SqlProvisioningStartWith.attribute.groupAttributesTableName.description = Group attribute table name + +config.SqlProvisioningStartWith.attribute.groupAttributesGroupForeignKeyColumn.label = Column foreign key to group +config.SqlProvisioningStartWith.attribute.groupAttributesGroupForeignKeyColumn.description = Column name which is foreign key to group table, e.g. group_uuid + +config.SqlProvisioningStartWith.attribute.groupAttributesAttributeNameColumn.label = Attribute name column +config.SqlProvisioningStartWith.attribute.groupAttributesAttributeNameColumn.description = Column name which is the attribute name, e.g. attribute_name + +config.SqlProvisioningStartWith.attribute.groupAttributesAttributeValueColumn.label = Attribute value column +config.SqlProvisioningStartWith.attribute.groupAttributesAttributeValueColumn.description = Column name which is the attribute value, e.g. attribute_value + +config.SqlProvisioningStartWith.attribute.groupMembershipAttributeName.label = Group membership attribute name +config.SqlProvisioningStartWith.attribute.groupMembershipAttributeName.description = Group membership attribute name + +config.SqlProvisioningStartWith.attribute.groupMembershipAttributeValue.label = Group membership attribute value +config.SqlProvisioningStartWith.attribute.groupMembershipAttributeValue.description = Group membership attribute value + +config.SqlProvisioningStartWith.attribute.groupOtherAttributeNames.label = Group other attribute names +config.SqlProvisioningStartWith.attribute.groupOtherAttributeNames.description = Group other attribute names + +config.SqlProvisioningStartWith.attribute.hasEntityTable.label = Has entity table +config.SqlProvisioningStartWith.attribute.hasEntityTable.description = Has entity table + +config.SqlProvisioningStartWith.attribute.entityTableName.label = Entity table name +config.SqlProvisioningStartWith.attribute.entityTableName.description = Entity table name + +config.SqlProvisioningStartWith.attribute.entityTableIdColumn.label = Entity table primary key +config.SqlProvisioningStartWith.attribute.entityTableIdColumn.description = Entity table primary key column, e.g. entity_uuid + +config.SqlProvisioningStartWith.attribute.entityTablePrimaryKeyValue.label = Entity table primary key value +config.SqlProvisioningStartWith.attribute.entityTablePrimaryKeyValue.description = Entity table primary key value, e.g. entity_uuid + +config.SqlProvisioningStartWith.attribute.entityTableColumnNames.label = Entity table column names +config.SqlProvisioningStartWith.attribute.entityTableColumnNames.description = Entity table column names + +config.SqlProvisioningStartWith.attribute.hasTargetEntityLink.label = Need entity link? +config.SqlProvisioningStartWith.attribute.hasTargetEntityLink.description = Need entity link? + +config.SqlProvisioningStartWith.attribute.hasEntityAttributeTable.label = Has entity attribute table? +config.SqlProvisioningStartWith.attribute.hasEntityAttributeTable.description = Has entity attribute table? + +config.SqlProvisioningStartWith.attribute.entityAttributeTableName.label = Entity attribute table name +config.SqlProvisioningStartWith.attribute.entityAttributeTableName.description = Entity attribute table name + +config.SqlProvisioningStartWith.attribute.entityAttributesEntityForeignKeyColumn.label = Column foreign key to entity +config.SqlProvisioningStartWith.attribute.entityAttributesEntityForeignKeyColumn.description = Column name which is foreign key to entity table, e.g. entity_uuid + +config.SqlProvisioningStartWith.attribute.entityAttributesAttributeNameColumn.label = Attribute name column +config.SqlProvisioningStartWith.attribute.entityAttributesAttributeNameColumn.description = Column name which is the attribute name, e.g. attribute_name + +config.SqlProvisioningStartWith.attribute.entityAttributesAttributeValueColumn.label = Attribute value column +config.SqlProvisioningStartWith.attribute.entityAttributesAttributeValueColumn.description = Column name which is the attribute value, e.g. attribute_value + +config.SqlProvisioningStartWith.attribute.entityMembershipAttributeName.label = Entity membership attribute name +config.SqlProvisioningStartWith.attribute.entityMembershipAttributeName.description = Entity membership attribute name + +config.SqlProvisioningStartWith.attribute.entityMembershipAttributeValue.label = Entity membership attribute value +config.SqlProvisioningStartWith.attribute.entityMembershipAttributeValue.description = Entity membership attribute value + +config.SqlProvisioningStartWith.attribute.entityOtherAttributeNames.label = Entity other attribute names +config.SqlProvisioningStartWith.attribute.entityOtherAttributeNames.description = Entity other attribute names + +config.SqlProvisioningStartWith.attribute.hasMembershipTable.label = Has membership table? +config.SqlProvisioningStartWith.attribute.hasMembershipTable.description = Has membership table? + +config.SqlProvisioningStartWith.attribute.membershipTableName.label = Membership table name +config.SqlProvisioningStartWith.attribute.membershipTableName.description = Membership table name + +config.SqlProvisioningStartWith.attribute.membershipTableGroupColumn.label = Membership table group column +config.SqlProvisioningStartWith.attribute.membershipTableGroupColumn.description = Membership table group column + +config.SqlProvisioningStartWith.attribute.membershipTableGroupValue.label = Membership table group value +config.SqlProvisioningStartWith.attribute.membershipTableGroupValue.description = Membership table group value + +config.SqlProvisioningStartWith.attribute.membershipTableEntityColumn.label = Membership table entity column +config.SqlProvisioningStartWith.attribute.membershipTableEntityColumn.description = Membership table entity column + +config.SqlProvisioningStartWith.attribute.membershipTableEntityValue.label = Membership table entity value +config.SqlProvisioningStartWith.attribute.membershipTableEntityValue.description = Membership table entity value + config.LdapProvisioningMembershipStartWith.attribute.ldapPattern.label = Ldap pattern config.LdapProvisioningMembershipStartWith.attribute.ldapPattern.description = Ldap pattern @@ -13527,8 +13781,8 @@ config.LdapProvisioningMembershipStartWith.attribute.membershipStructure.descrip config.LdapProvisioningMembershipStartWith.attribute.membershipValueDn.label = Membership value dn config.LdapProvisioningMembershipStartWith.attribute.membershipValueDn.description = Membership value dn -config.LdapProvisioningMembershipStartWith.attribute.groupOrganization.label = Group organization -config.LdapProvisioningMembershipStartWith.attribute.groupOrganization.description = Group organization +config.LdapProvisioningMembershipStartWith.attribute.groupDnType.label = Group DN type +config.LdapProvisioningMembershipStartWith.attribute.groupDnType.description = Group DN type config.LdapProvisioningMembershipStartWith.attribute.userAttributesType.label = User attributes type config.LdapProvisioningMembershipStartWith.attribute.userAttributesType.description = User attributes type @@ -13539,11 +13793,11 @@ config.LdapProvisioningMembershipStartWith.attribute.subjectSourceEntityResolver config.LdapProvisioningMembershipStartWith.attribute.groupLinkForAnotherReason.label = Group link for another reason config.LdapProvisioningMembershipStartWith.attribute.groupLinkForAnotherReason.description = Group link for another reason -config.LdapProvisioningMembershipStartWith.attribute.groupBaseOu.label = Group base OU -config.LdapProvisioningMembershipStartWith.attribute.groupBaseOu.description = Group base OU +config.LdapProvisioningMembershipStartWith.attribute.groupSearchBaseDn.label = Group search base DN +config.LdapProvisioningMembershipStartWith.attribute.groupSearchBaseDn.description = Group search base DN -config.LdapProvisioningMembershipStartWith.attribute.rdnGroupsAttribute.label = RDN groups attribute -config.LdapProvisioningMembershipStartWith.attribute.rdnGroupsAttribute.description = RDN groups attribute +config.LdapProvisioningMembershipStartWith.attribute.groupRdnAttribute.label = RDN groups attribute +config.LdapProvisioningMembershipStartWith.attribute.groupRdnAttribute.description = RDN groups attribute config.LdapProvisioningMembershipStartWith.attribute.rdnValueForGroups.label = RDN value for groups config.LdapProvisioningMembershipStartWith.attribute.rdnValueForGroups.description = RDN value for groups @@ -13551,8 +13805,8 @@ config.LdapProvisioningMembershipStartWith.attribute.rdnValueForGroups.descripti config.LdapProvisioningMembershipStartWith.attribute.membershipAttributeNameForGroups.label = Membership attribute name for groups config.LdapProvisioningMembershipStartWith.attribute.membershipAttributeNameForGroups.description = Membership attribute name for groups -config.LdapProvisioningMembershipStartWith.attribute.membershipValueForGroups.label = Membership value for groups -config.LdapProvisioningMembershipStartWith.attribute.membershipValueForGroups.description = Membership value for groups +config.LdapProvisioningMembershipStartWith.attribute.groupMembershipAttributeValue.label = Membership value for groups +config.LdapProvisioningMembershipStartWith.attribute.groupMembershipAttributeValue.description = Membership value for groups config.LdapProvisioningMembershipStartWith.attribute.idIndexAttribute.label = Id index attribute config.LdapProvisioningMembershipStartWith.attribute.idIndexAttribute.description = Id index attribute @@ -13572,8 +13826,8 @@ config.LdapProvisioningMembershipStartWith.attribute.objectClassesForGroups.desc config.LdapProvisioningMembershipStartWith.attribute.otherGroupLdapAttributes.label = Other group ldap attributes config.LdapProvisioningMembershipStartWith.attribute.otherGroupLdapAttributes.description = Other group ldap attributes -config.LdapProvisioningMembershipStartWith.attribute.allowGroupDnOverride.label = Allow group dn override -config.LdapProvisioningMembershipStartWith.attribute.allowGroupDnOverride.description = Allow group dn override +config.LdapProvisioningMembershipStartWith.attribute.allowLdapGroupDnOverride.label = Allow group dn override +config.LdapProvisioningMembershipStartWith.attribute.allowLdapGroupDnOverride.description = Allow group dn override config.LdapProvisioningMembershipStartWith.attribute.entityLinkForAnotherReason.label = Entity link for another reason config.LdapProvisioningMembershipStartWith.attribute.entityLinkForAnotherReason.description = Entity link for another reason @@ -13581,14 +13835,14 @@ config.LdapProvisioningMembershipStartWith.attribute.entityLinkForAnotherReason. config.LdapProvisioningMembershipStartWith.attribute.entityLinkForAnotherReason.label = Entity link for another reason config.LdapProvisioningMembershipStartWith.attribute.entityLinkForAnotherReason.description = Entity link for another reason -config.LdapProvisioningMembershipStartWith.attribute.entityBaseOu.label = Entity base OU -config.LdapProvisioningMembershipStartWith.attribute.entityBaseOu.description = Entity base OU +config.LdapProvisioningMembershipStartWith.attribute.userSearchBaseDn.label = Entity search base DN +config.LdapProvisioningMembershipStartWith.attribute.userSearchBaseDn.description = Entity search base DN config.LdapProvisioningMembershipStartWith.attribute.changeEntitiesInLdap.label = Change entities in ldap config.LdapProvisioningMembershipStartWith.attribute.changeEntitiesInLdap.description = Change entities in ldap -config.LdapProvisioningMembershipStartWith.attribute.rdnEntitiesAttribute.label = RDN entities attribute -config.LdapProvisioningMembershipStartWith.attribute.rdnEntitiesAttribute.description = RDN entities attribute +config.LdapProvisioningMembershipStartWith.attribute.userRdnAttribute.label = RDN entities attribute +config.LdapProvisioningMembershipStartWith.attribute.userRdnAttribute.description = RDN entities attribute config.LdapProvisioningMembershipStartWith.attribute.rdnValueForEntities.label = RDN value for entities config.LdapProvisioningMembershipStartWith.attribute.rdnValueForEntities.description = RDN value for entities @@ -13678,32 +13932,158 @@ config.AzureProvisioningStartWith.attribute.manageEntitiesInAzure.description = config.AzureProvisioningStartWith.attribute.entityDisplayName.label = Entity display name config.AzureProvisioningStartWith.attribute.entityDisplayName.description = Entity display name +config.DuoProvisioningStartWith.attribute.duoExternalSystemConfigId.label = Duo external system +config.DuoProvisioningStartWith.attribute.duoExternalSystemConfigId.description = Duo external system + +config.DuoProvisioningStartWith.attribute.duoPattern.label = Duo pattern +config.DuoProvisioningStartWith.attribute.duoPattern.description = Duo pattern +config.DuoProvisioningStartWith.attribute.userAttributesType.label = User attributes type +config.DuoProvisioningStartWith.attribute.userAttributesType.description = User attributes type + +config.DuoProvisioningStartWith.attribute.subjectSourceEntityResolverAttributes.label = Subject source entity resolver attributes +config.DuoProvisioningStartWith.attribute.subjectSourceEntityResolverAttributes.description = Subject source entity resolver attributes + +config.DuoProvisioningStartWith.attribute.manageGroups.label = Manage groups +config.DuoProvisioningStartWith.attribute.manageGroups.description = Manage groups + +config.DuoProvisioningStartWith.attribute.groupNameAttributeValue.label = Group name attribute value +config.DuoProvisioningStartWith.attribute.groupNameAttributeValue.description = Group name attribute value + +config.DuoProvisioningStartWith.attribute.useGroupDescription.label = Use group description +config.DuoProvisioningStartWith.attribute.useGroupDescription.description = Use group description + +config.DuoProvisioningStartWith.attribute.manageEntities.label = Manage entities +config.DuoProvisioningStartWith.attribute.manageEntities.description = Manage entities + +config.DuoProvisioningStartWith.attribute.entityUserName.label = User name +config.DuoProvisioningStartWith.attribute.entityUserName.description = Entity user name + +config.DuoProvisioningStartWith.attribute.entityNameSubjectAttribute.label = Name subject attribute or entity resolver name +config.DuoProvisioningStartWith.attribute.entityNameSubjectAttribute.description = Name subject attribute or entity resolver name + +config.DuoProvisioningStartWith.attribute.entityFirstNameSubjectAttribute.label = First name subject attribute or entity resolver name +config.DuoProvisioningStartWith.attribute.entityFirstNameSubjectAttribute.description = First name subject attribute or entity resolver name + +config.DuoProvisioningStartWith.attribute.entityEmailSubjectAttribute.label = Email subject attribute or entity resolver name +config.DuoProvisioningStartWith.attribute.entityEmailSubjectAttribute.description = Email subject attribute or entity resolver name + +config.GenericConfiguration.attribute.groupsRequireMembers.label = Groups require members +config.GenericConfiguration.attribute.groupsRequireMembers.description = If this is set to true, then a group without members will be considered not provisionable and eligible for deletion (depending on delete configuration) config.GenericConfiguration.attribute.refreshSubjectLinkIfLessThanAmount.label = Refresh subject link config.GenericConfiguration.attribute.refreshEntityLinkIfLessThanAmount.label = Refresh target entity link config.GenericConfiguration.attribute.refreshGroupLinkIfLessThanAmount.label = Refresh target group link config.GenericConfiguration.attribute.refreshGroupLinkIfLessThanAmount.description = Target group links will be refreshed when they can be (full sync retrieve all groups), or when they must be (group link data is not cached in Grouper). Otherwise if there are groups to operate on, if there are only a few (less than this amount), then refresh the group link, otherwise for expediency just use the cached data. Generally you do not need to edit this value. This is an integer. -config.GenericConfiguration.attribute.common.subjectLink.memberFromId2.label = Subject link - memberFromId2 -config.GenericConfiguration.attribute.common.subjectLink.memberFromId3.label = Subject link - memberFromId3 -config.GenericConfiguration.attribute.common.subjectLink.memberToId2.label = Subject link - memberToId2 -config.GenericConfiguration.attribute.common.subjectLink.memberToId3.label = Subject link - memberToId3 -config.GenericConfiguration.attribute.common.entityLink.memberFromId2.label = Target entity link - memberFromId2 -config.GenericConfiguration.attribute.common.entityLink.memberFromId3.label = Target entity link - memberFromId3 -config.GenericConfiguration.attribute.common.entityLink.memberToId2.label = Target entity link - memberToId2 -config.GenericConfiguration.attribute.common.entityLink.memberToId3.label = Target entity link - memberToId3 -config.GenericConfiguration.attribute.common.groupLink.groupFromId2.label = Target group link - groupFromId2 -config.GenericConfiguration.attribute.common.groupLink.groupFromId2.description = Generally you do not need to edit this, and you will set this in an attribute configuration. This is one of four sync buckets. Enter a JEXL using the variable "targetGroup" (type ProvisioningGroup.java). Depending on the data returned by the provisioner's DAO, you can refer to fields ${targetGroup.name} or attributes ${targetGroup.retrieveAttributeValue('someAttrName')} -config.GenericConfiguration.attribute.common.groupLink.groupFromId3.label = Target group link - groupFromId3 -config.GenericConfiguration.attribute.common.groupLink.groupFromId3.description = Generally you do not need to edit this, and you will set this in an attribute configuration. This is one of four sync buckets. Enter a JEXL using the variable "targetGroup" (type ProvisioningGroup.java). Depending on the data returned by the provisioner's DAO, you can refer to fields ${targetGroup.name} or attributes ${targetGroup.retrieveAttributeValue('someAttrName')} -config.GenericConfiguration.attribute.common.groupLink.groupToId2.label = Target group link - groupToId2 -config.GenericConfiguration.attribute.common.groupLink.groupToId2.description = Generally you do not need to edit this, and you will set this in an attribute configuration. This is one of four sync buckets. Enter a JEXL using the variable "targetGroup" (type ProvisioningGroup.java). Depending on the data returned by the provisioner's DAO, you can refer to fields ${targetGroup.name} or attributes ${targetGroup.retrieveAttributeValue('someAttrName')} -config.GenericConfiguration.attribute.common.groupLink.groupToId3.label = Target group link - groupToId3 -config.GenericConfiguration.attribute.common.groupLink.groupToId3.description = Generally you do not need to edit this, and you will set this in an attribute configuration. This is one of four sync buckets. Enter a JEXL using the variable "targetGroup" (type ProvisioningGroup.java). Depending on the data returned by the provisioner's DAO, you can refer to fields ${targetGroup.name} or attributes ${targetGroup.retrieveAttributeValue('someAttrName')} +config.GenericConfiguration.attribute.groupAttributeValueCacheHas.label = Use group attribute value cache +config.GenericConfiguration.attribute.groupAttributeValueCacheHas.description = If you need to cache something in the database from the target or from grouper. There are four buckets to store data in + +config.GenericConfiguration.attribute.groupAttributeValueCache0has.label = Use group attribute value cache 0 +config.GenericConfiguration.attribute.groupAttributeValueCache0has.description = If you need to cache something in the database (grouper_sync_group.group_from_id2 column) from the target or from grouper. +config.GenericConfiguration.attribute.groupAttributeValueCache1has.label = Use group attribute value cache 1 +config.GenericConfiguration.attribute.groupAttributeValueCache1has.description = If you need to cache something in the database (grouper_sync_group.group_from_id3 column) from the target or from grouper. +config.GenericConfiguration.attribute.groupAttributeValueCache2has.label = Use group attribute value cache 2 +config.GenericConfiguration.attribute.groupAttributeValueCache2has.description = If you need to cache something in the database (grouper_sync_group.group_to_id2 column) from the target or from grouper. +config.GenericConfiguration.attribute.groupAttributeValueCache3has.label = Use group attribute value cache 3 +config.GenericConfiguration.attribute.groupAttributeValueCache3has.description = If you need to cache something in the database (grouper_sync_group.group_to_id3 column) from the target or from grouper. + +config.GenericConfiguration.attribute.groupAttributeValueCache0source.label = Group attribute value cache 0 source +config.GenericConfiguration.attribute.groupAttributeValueCache0source.description = Cache the data from Grouper or from target. You would pick Grouper if there is something in Grouper that might be needed during a delete that might not be available when the data is not in Grouper anymore (e.g. the search attribute). You would pick target when there is something in the target that is needed and maybe to help with performance (e.g. the UUID or DN). +config.GenericConfiguration.attribute.groupAttributeValueCache1source.label = Group attribute value cache 1 source +config.GenericConfiguration.attribute.groupAttributeValueCache1source.description = $$config.GenericConfiguration.attribute.groupAttributeValueCache0source.description$$ +config.GenericConfiguration.attribute.groupAttributeValueCache2source.label = Group attribute value cache 2 source +config.GenericConfiguration.attribute.groupAttributeValueCache2source.description = $$config.GenericConfiguration.attribute.groupAttributeValueCache0source.description$$ +config.GenericConfiguration.attribute.groupAttributeValueCache3source.label = Group attribute value cache 3 source +config.GenericConfiguration.attribute.groupAttributeValueCache3source.description = $$config.GenericConfiguration.attribute.groupAttributeValueCache0source.description$$ + +config.GenericConfiguration.attribute.groupAttributeValueCache0type.label = Group attribute value cache 0 type +config.GenericConfiguration.attribute.groupAttributeValueCache0type.description = groupAttribute: Pick an attribute from the object model to cache
    groupObject: Store the entire representation of the group (target format). Skip the membership attribute if applicable, and truncate large attributes (if space not available).
    translationScript: Translate data from the Grouper side to store in the database cache +config.GenericConfiguration.attribute.groupAttributeValueCache1type.label = Group attribute value cache 1 type +config.GenericConfiguration.attribute.groupAttributeValueCache1type.description = $$config.GenericConfiguration.attribute.groupAttributeValueCache0type.description$$ +config.GenericConfiguration.attribute.groupAttributeValueCache2type.label = Group attribute value cache 2 type +config.GenericConfiguration.attribute.groupAttributeValueCache2type.description = $$config.GenericConfiguration.attribute.groupAttributeValueCache0type.description$$ +config.GenericConfiguration.attribute.groupAttributeValueCache3type.label = Group attribute value cache 3 type +config.GenericConfiguration.attribute.groupAttributeValueCache3type.description = $$config.GenericConfiguration.attribute.groupAttributeValueCache0type.description$$ + +config.GenericConfiguration.attribute.groupAttributeValueCache0groupAttribute.label = Group attribute value cache 0 group attribute +config.GenericConfiguration.attribute.groupAttributeValueCache0groupAttribute.description = Pick an attribute from the provisioningGroup object (Grouper or target depending on the source) to store in the database cache +config.GenericConfiguration.attribute.groupAttributeValueCache1groupAttribute.label = Group attribute value cache 1 attribute +config.GenericConfiguration.attribute.groupAttributeValueCache1groupAttribute.description = $$config.GenericConfiguration.attribute.groupAttributeValueCache0groupAttribute.description$$ +config.GenericConfiguration.attribute.groupAttributeValueCache2groupAttribute.label = Group attribute value cache 2 attribute +config.GenericConfiguration.attribute.groupAttributeValueCache2groupAttribute.description = $$config.GenericConfiguration.attribute.groupAttributeValueCache0groupAttribute.description$$ +config.GenericConfiguration.attribute.groupAttributeValueCache3groupAttribute.label = Group attribute value cache 3 attribute +config.GenericConfiguration.attribute.groupAttributeValueCache3groupAttribute.description = $$config.GenericConfiguration.attribute.groupAttributeValueCache0groupAttribute.description$$ + +config.GenericConfiguration.attribute.groupAttributeValueCache0translationScript.label = Group attribute value cache 0 script +config.GenericConfiguration.attribute.groupAttributeValueCache0translationScript.description = If your source is 'Grouper' you can refer to grouper fields ${grouperProvisioningGroup.name} or attributes ${grouperProvisioningGroup.retrieveAttributeValue('someAttrName')}
    If your source is 'target', you can refer to target fields ${targetGroup.name} or attributes ${targetGroup.retrieveAttributeValue('someAttrName')} +config.GenericConfiguration.attribute.groupAttributeValueCache1translationScript.label = Group attribute value cache 1 script +config.GenericConfiguration.attribute.groupAttributeValueCache1translationScript.description = $$config.GenericConfiguration.attribute.groupAttributeValueCache0translationScript.description$$ +config.GenericConfiguration.attribute.groupAttributeValueCache2translationScript.label = Group attribute value cache 2 script +config.GenericConfiguration.attribute.groupAttributeValueCache2translationScript.description = $$config.GenericConfiguration.attribute.groupAttributeValueCache0translationScript.description$$ +config.GenericConfiguration.attribute.groupAttributeValueCache3translationScript.label = Group attribute value cache 3 script +config.GenericConfiguration.attribute.groupAttributeValueCache3translationScript.description = $$config.GenericConfiguration.attribute.groupAttributeValueCache0translationScript.description$$ + +config.GenericConfiguration.attribute.entityAttributeValueCacheHas.label = Use entity attribute value cache +config.GenericConfiguration.attribute.entityAttributeValueCacheHas.description = If you need to cache something in the database from the target or from grouper. There are four buckets to store data in + +config.GenericConfiguration.attribute.entityAttributeValueCache0auto.label = Entity attribute value cache 0 auto-USDU +config.GenericConfiguration.attribute.entityAttributeValueCache0auto.description = This should generally be left as the default (true), USDU should update the value of this cache item from the subject source. +config.GenericConfiguration.attribute.entityAttributeValueCache1auto.label = Entity attribute value cache 1 auto-USDU +config.GenericConfiguration.attribute.entityAttributeValueCache1auto.description = This should generally be left as the default (true), USDU should update the value of this cache item from the subject source. +config.GenericConfiguration.attribute.entityAttributeValueCache2auto.label = Entity attribute value cache 2 auto-USDU +config.GenericConfiguration.attribute.entityAttributeValueCache2auto.description = This should generally be left as the default (true), USDU should update the value of this cache item from the subject source. +config.GenericConfiguration.attribute.entityAttributeValueCache3auto.label = Entity attribute value cache 3 auto-USDU +config.GenericConfiguration.attribute.entityAttributeValueCache3auto.description = This should generally be left as the default (true), USDU should update the value of this cache item from the subject source. + +config.GenericConfiguration.attribute.entityAttributeValueCache0has.label = Use entity attribute value cache 0 +config.GenericConfiguration.attribute.entityAttributeValueCache0has.description = If you need to cache something in the database (grouper_sync_member.member_from_id2 column) from the target or from grouper. +config.GenericConfiguration.attribute.entityAttributeValueCache1has.label = Use entity attribute value cache 1 +config.GenericConfiguration.attribute.entityAttributeValueCache1has.description = If you need to cache something in the database (grouper_sync_member.member_from_id3 column) from the target or from grouper. +config.GenericConfiguration.attribute.entityAttributeValueCache2has.label = Use entity attribute value cache 2 +config.GenericConfiguration.attribute.entityAttributeValueCache2has.description = If you need to cache something in the database (grouper_sync_member.member_to_id2 column) from the target or from grouper. +config.GenericConfiguration.attribute.entityAttributeValueCache3has.label = Use entity attribute value cache 3 +config.GenericConfiguration.attribute.entityAttributeValueCache3has.description = If you need to cache something in the database (grouper_sync_member.member_to_id3 column) from the target or from grouper. + +config.GenericConfiguration.attribute.entityAttributeValueCache0source.label = Entity attribute value cache 0 source +config.GenericConfiguration.attribute.entityAttributeValueCache0source.description = Cache the data from Grouper or from target. You would pick Grouper if there is something in Grouper that might be needed during a delete that might not be available when the data is not in Grouper anymore (e.g. the search attribute). You would pick target when there is something in the target that is needed and maybe to help with performance (e.g. the UUID or DN). +config.GenericConfiguration.attribute.entityAttributeValueCache1source.label = Entity attribute value cache 1 source +config.GenericConfiguration.attribute.entityAttributeValueCache1source.description = $$config.GenericConfiguration.attribute.entityAttributeValueCache0source.description$$ +config.GenericConfiguration.attribute.entityAttributeValueCache2source.label = Entity attribute value cache 2 source +config.GenericConfiguration.attribute.entityAttributeValueCache2source.description = $$config.GenericConfiguration.attribute.entityAttributeValueCache0source.description$$ +config.GenericConfiguration.attribute.entityAttributeValueCache3source.label = Entity attribute value cache 3 source +config.GenericConfiguration.attribute.entityAttributeValueCache3source.description = $$config.GenericConfiguration.attribute.entityAttributeValueCache0source.description$$ + +config.GenericConfiguration.attribute.entityAttributeValueCache0type.label = Entity attribute value cache 0 type +config.GenericConfiguration.attribute.entityAttributeValueCache0type.description = entityAttribute: Pick an attribute from the object model to cache
    entityObject: Store the entire representation of the entity (target format). Skip the membership attribute if applicable, and truncate large attributes (if space not available).
    subjectTranslationScript: Translate data from the Subject API for the entity being provisioned. e.g. ${subject.getAttributeValue('email')} Note, if you are using 'built-in' fields you don't need this... e.g. email, subjectId, subjectIdentifier0, subjectIdentifier1, subjectIdentifier2, you can just translate from a grouper entity attribute
    translationScript: Translate data from the Grouper side to store in the database cache +config.GenericConfiguration.attribute.entityAttributeValueCache1type.label = Entity attribute value cache 1 type +config.GenericConfiguration.attribute.entityAttributeValueCache1type.description = $$config.GenericConfiguration.attribute.entityAttributeValueCache0type.description$$ +config.GenericConfiguration.attribute.entityAttributeValueCache2type.label = Entity attribute value cache 2 type +config.GenericConfiguration.attribute.entityAttributeValueCache2type.description = $$config.GenericConfiguration.attribute.entityAttributeValueCache0type.description$$ +config.GenericConfiguration.attribute.entityAttributeValueCache3type.label = Entity attribute value cache 3 type +config.GenericConfiguration.attribute.entityAttributeValueCache3type.description = $$config.GenericConfiguration.attribute.entityAttributeValueCache0type.description$$ + +config.GenericConfiguration.attribute.entityAttributeValueCache0entityAttribute.label = Entity attribute value cache 0 entity attribute +config.GenericConfiguration.attribute.entityAttributeValueCache0entityAttribute.description = Pick an attribute from the provisioningEntity object (Grouper or target depending on the source) to store in the database cache +config.GenericConfiguration.attribute.entityAttributeValueCache1entityAttribute.label = Entity attribute value cache 1 attribute +config.GenericConfiguration.attribute.entityAttributeValueCache1entityAttribute.description = $$config.GenericConfiguration.attribute.entityAttributeValueCache0entityAttribute.description$$ +config.GenericConfiguration.attribute.entityAttributeValueCache2entityAttribute.label = Entity attribute value cache 2 attribute +config.GenericConfiguration.attribute.entityAttributeValueCache2entityAttribute.description = $$config.GenericConfiguration.attribute.entityAttributeValueCache0entityAttribute.description$$ +config.GenericConfiguration.attribute.entityAttributeValueCache3entityAttribute.label = Entity attribute value cache 3 attribute +config.GenericConfiguration.attribute.entityAttributeValueCache3entityAttribute.description = $$config.GenericConfiguration.attribute.entityAttributeValueCache0entityAttribute.description$$ + +config.GenericConfiguration.attribute.entityAttributeValueCache0translationScript.label = Entity attribute value cache 0 script +config.GenericConfiguration.attribute.entityAttributeValueCache0translationScript.description = If your source is 'Grouper' and type is 'translationScript' you can refer to grouper fields ${grouperProvisioningEntity.name} or attributes ${grouperProvisioningEntity.retrieveAttributeValue('someAttrName')}
    If your source is 'Grouper' and the type is 'subjectTranslationScript', you can use fields or attributes from the Subject API subject, e.g. ${subject.name} or ${subject.getAttributeValue('email')}
    If your source is 'target', you can refer to target fields ${targetEntity.name} or attributes ${targetEntity.retrieveAttributeValue('someAttrName')} +config.GenericConfiguration.attribute.entityAttributeValueCache1translationScript.label = Entity attribute value cache 1 script +config.GenericConfiguration.attribute.entityAttributeValueCache1translationScript.description = $$config.GenericConfiguration.attribute.entityAttributeValueCache0translationScript.description$$ +config.GenericConfiguration.attribute.entityAttributeValueCache2translationScript.label = Entity attribute value cache 2 script +config.GenericConfiguration.attribute.entityAttributeValueCache2translationScript.description = $$config.GenericConfiguration.attribute.entityAttributeValueCache0translationScript.description$$ +config.GenericConfiguration.attribute.entityAttributeValueCache3translationScript.label = Entity attribute value cache 3 script +config.GenericConfiguration.attribute.entityAttributeValueCache3translationScript.description = $$config.GenericConfiguration.attribute.entityAttributeValueCache0translationScript.description$$ config.GenericConfiguration.attribute.targetGroupAttribute.i.name.label = __i+1__ - name config.GenericConfiguration.attribute.targetGroupAttribute.i.name.description = Attribute name is the key in the key/value pairs for this group +config.SqlProvisionerConfiguration.attribute.targetGroupAttribute.i.name.description = Column name for this column, or attribute name if the attribute is in a separate attributes table config.GenericConfiguration.attribute.option.targetGroupAttribute.i.groupAttributePrefix = Group config.GenericConfiguration.attribute.option.targetMembershipAttribute.i.membershipAttributePrefix = Membership config.GenericConfiguration.attribute.option.targetEntityAttribute.i.entityAttributePrefix = Entity @@ -13712,8 +14092,14 @@ config.GenericConfiguration.attribute.option.targetGroupAttribute.i.attributePre config.GenericConfiguration.attribute.targetMembershipAttribute.i.name.label = __i+1__ - name config.GenericConfiguration.attribute.targetMembershipAttribute.i.name.description = Attribute name is the key in the key/value pairs for this group -config.GenericConfiguration.attribute.targetMembershipAttribute.i.showAdvancedMembershipAttribute.label = __i+1__ - advanced options -config.GenericConfiguration.attribute.targetMembershipAttribute.i.showAdvancedMembershipAttribute.description = Show less common options like value type, CRUD control, validation, etc +config.GenericConfiguration.attribute.targetMembershipAttribute.i.showAdvancedAttribute.label = __i+1__ - advanced options +config.GenericConfiguration.attribute.targetMembershipAttribute.i.showAdvancedAttribute.description = Show less common options like value type, CRUD control, validation, etc + +config.GenericConfiguration.attribute.targetGroupAttribute.i.showAdvancedAttribute.label = __i+1__ - advanced options +config.GenericConfiguration.attribute.targetGroupAttribute.i.showAdvancedAttribute.description = Show less common options like value type, CRUD control, validation, etc + +config.GenericConfiguration.attribute.targetEntityAttribute.i.showAdvancedAttribute.label = __i+1__ - advanced options +config.GenericConfiguration.attribute.targetEntityAttribute.i.showAdvancedAttribute.description = Show less common options like value type, CRUD control, validation, etc config.GenericConfiguration.attribute.targetMembershipAttribute.i.showAttributeCrud.label = __i+1__ - customize CRUD config.GenericConfiguration.attribute.targetMembershipAttribute.i.showAttributeCrud.description = By default this attribute will follow the same Create/Read/Update/Delete settings as the enclosing object. If the provisioner cannot perform the configured action it will not (e.g. a UUID for a web service which is readonly). Customize the configuration here. @@ -13742,9 +14128,6 @@ config.GenericConfiguration.attribute.targetGroupAttribute.i.showAttributeValida config.GenericConfiguration.attribute.targetEntityAttribute.i.showAttributeValidation.label = __i+1__ - show validation settings config.GenericConfiguration.attribute.targetEntityAttribute.i.showAttributeValidation.description = If there is validation on this attribute (which is not built in), then customize there -config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateFromGroupSyncField.label = __i+1__ - Group sync from field -config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateFromGroupSyncField.description = If this is a membership attribute for entityAttributes provisioning, then the values can be copied from the group sync object from this field. - config.GenericConfiguration.attribute.targetMembershipAttribute.i.valueType.label = __i+1__ - value type config.GenericConfiguration.attribute.targetMembershipAttribute.i.valueType.description = Generally this is going to be a string (text). int means 4 byte signed integer (-2 billion to 2 billion). long is for large integers config.GenericConfiguration.attribute.targetMembershipAttribute.i.select.label = __i+1__ - select @@ -13755,14 +14138,8 @@ config.GenericConfiguration.attribute.targetMembershipAttribute.i.update.label = config.GenericConfiguration.attribute.targetMembershipAttribute.i.update.description = Should this attribute be changed when the group is updated. config.GenericConfiguration.attribute.targetMembershipAttribute.i.ignoreIfMatchesValue.label = __i+1__ - ignore if matches value config.GenericConfiguration.attribute.targetMembershipAttribute.i.ignoreIfMatchesValue.description = If the group field or attribute value matches any of these values then ignore it (do not delete or update). Comma separated values, escaped comma is U+002C -config.GenericConfiguration.attribute.targetMembershipAttribute.i.matchingId.label = __i+1__ - matching id -config.GenericConfiguration.attribute.targetMembershipAttribute.i.matchingId.description = The "matching id" is the attribute that is used to match up target objects with Grouper objects. If the matching ID is something opaque like the idIndex or uuid then objects can be more reliably renamed. config.GenericConfiguration.attribute.targetMembershipAttribute.i.multiValued.label = __i+1__ - multi-valued attribute config.GenericConfiguration.attribute.targetMembershipAttribute.i.multiValued.description = If this attribute is multi-valued in the target. Generally attributes are single-valued. The membership attribute must be multi-valued if provisioning groupAttributes. -config.GenericConfiguration.attribute.targetMembershipAttribute.i.searchAttribute.label = __i+1__ - search attribute -config.GenericConfiguration.attribute.targetMembershipAttribute.i.searchAttribute.description = If this attribute is used to find groups in the target. The search in the target for this group might just need this attribute name and value or there might be a search filter, and this is the value of the bind variable. -config.GenericConfiguration.attribute.targetMembershipAttribute.i.membershipAttribute.label = __i+1__ - membership attribute -config.GenericConfiguration.attribute.targetMembershipAttribute.i.membershipAttribute.description = If this is groupAttribute provisioning and this attribute is multi-valued and holds entries that represents entities/memberships config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateExpressionCreateOnly.label = __i+1__ - translation expression insert only config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateExpressionCreateOnly.description = If you have a different translation from Grouper to Target for updates as opposed to inserts, put the insert translation here. Available variables:
    • $$provisioning.helper.variable.grouperProvisioningGroup$$
    • $$provisioning.helper.variable.gcGrouperSyncGroup$$
    • $$provisioning.helper.variable.provisioningGroupWrapper$$
    • $$provisioning.helper.variable.grouperTargetGroup$$
    • provisioning.helper.variable.grouperProvisioningEntity
    • provisioning.helper.variable.gcGrouperSyncMember
    • provisioning.helper.variable.provisioningEntityWrapper
    • provisioning.helper.variable.grouperTargetEntity
    @@ -13786,8 +14163,6 @@ config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateFromS config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateExpression.label = __i+1__ - translation expression config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateExpression.description = This is the translation for this attribute from Grouper to Target format during Group updates and inserts (if not overridden by "insert only" translation). Available variables:
    • $$provisioning.helper.variable.grouperProvisioningGroup$$
    • $$provisioning.helper.variable.gcGrouperSyncGroup$$
    • $$provisioning.helper.variable.provisioningGroupWrapper$$
    • $$provisioning.helper.variable.grouperTargetGroup$$
    • provisioning.helper.variable.grouperProvisioningEntity
    • provisioning.helper.variable.gcGrouperSyncMember
    • provisioning.helper.variable.provisioningEntityWrapper
    • provisioning.helper.variable.grouperTargetEntity
    -config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateExpressionFromMembership.label = __i+1__ - translation expression from membership -config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateExpressionFromMembership.description = Generally you will leave this blank and use a "membership sync from field". If you need to do a translation, you can use any membership object variable config.GenericConfiguration.attribute.targetMembershipAttribute.i.defaultValue.label = __i+1__ - default value config.GenericConfiguration.attribute.targetMembershipAttribute.i.defaultValue.description = If there should always be a value in the target, then list the value here to assign to the field/attribute if it is blank. Use <emptyString> if the default value should be an empty string. config.GenericConfiguration.attribute.targetMembershipAttribute.i.required.label = __i+1__ - required @@ -13796,12 +14171,6 @@ config.GenericConfiguration.attribute.targetMembershipAttribute.i.maxlength.labe config.GenericConfiguration.attribute.targetMembershipAttribute.i.maxlength.description = If there is a maximum length requirement for this field in the target, assign the integer of maximum number of characters. If this field value size is greater than the max length, then the Group is invalid and will not be provisioned config.GenericConfiguration.attribute.targetMembershipAttribute.i.validExpression.label = __i+1__ - validation expression config.GenericConfiguration.attribute.targetMembershipAttribute.i.validExpression.description = If there is a complex validation by JEXL script enter that here. The available variables are "value" (each individual value), and "valueMultiple" (the set of multiple values if this attribute supports multiple values. Return true for valid or false for invalid. Example to see if numeric value is positive: ${value>0} -config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateFromMemberSyncField.label = __i+1__ - membership sync from field -config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateFromMemberSyncField.description = If this is a membership attribute for groupAttributes provisioning, then the values can be copied from the member sync object from this field. -config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateToGroupSyncField.label = __i+1__ - target group link field -config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateToGroupSyncField.description = If this is a group link field/attribute, then copy the target value to this group sync field, and retrieve from the group sync field as a cache during translation for incremental provisioning or during deletes. -config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateGrouperToGroupSyncField.label = __i+1__ - Grouper group link field -config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateGrouperToGroupSyncField.description = Copy the Grouper value to this group sync field, and retrieve from the group sync field during provisioning. config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateFromGrouperProvisioningEntityField.label = __i+1__ - translate from grouperProvisioningEntity field config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateFromGrouperProvisioningEntityField.description = Select the field from grouperProvisioningEntity to copy data from. id: is the UUID of the entity, email: email address of the user, loginid: netId to log in to systems, name: first and last name, subjectId: should be an opaque unchanging identifier, subjectSourceId: sourceId of the user, description: description that is configured in the subject source, subjectIdentifier0: the first identifier of the subject (might be a netId) @@ -13809,10 +14178,10 @@ config.GenericConfiguration.attribute.targetMembershipAttribute.i.translateFromG -provisioning.helper.variable.grouperProvisioningGroup = grouperProvisioningGroup (ProvisioningGroup.java): this is the Grouper representation of the group. Fields include: id, idIndex, name, displayName. Attributes include: description -provisioning.helper.variable.gcGrouperSyncGroup = gcGrouperSyncGroup (GcGrouperSyncGroup.java): this is the "sync" group object. Fields include: groupFromId2, groupFromId3, groupToId2, groupToId3 +provisioning.helper.variable.grouperProvisioningGroup = grouperProvisioningGroup (ProvisioningGroup.java): this is the Grouper representation of the group. Fields include: id, idIndex, name, displayName. Attributes include: description. Here is an example of a regex replace all non alphanumeric ids: ${grouperProvisioningGroup.name.replaceAll('[^a-zA-Z0-9]', '_')} +provisioning.helper.variable.gcGrouperSyncGroup = gcGrouperSyncGroup (GcGrouperSyncGroup.java): this is the "sync" group object. Fields include: groupAttributeValueCache0, groupAttributeValueCache1, groupAttributeValueCache2, groupAttributeValueCache3 provisioning.helper.variable.provisioningGroupWrapper = provisioningGroupWrapper (ProvisioningGroupWrapper.java): holds references to all group data. Fields include: create, delete, recalc, gcGrouperSyncGroup, grouperProvisioningGroup, grouperTargetGroup, targetProvisioningGroup, targetNativeGroup -provisioning.helper.variable.grouperTargetGroup = grouperTargetGroup (ProvisioningGroup.java): generally this is not needed since it is being built by the translation process. Fields and attributes depend on the provisioner. +provisioning.helper.variable.grouperTargetGroup = grouperTargetGroup (ProvisioningGroup.java): generally this is not needed since it is being built by the translation process. Attributes depend on the provisioner. config.GenericConfiguration.attribute.targetGroupAttribute.i.valueType.label = __i+1__ - value type config.GenericConfiguration.attribute.targetGroupAttribute.i.valueType.description = Generally this is going to be a string (text). int means 4 byte signed integer (-2 billion to 2 billion). long is for large integers @@ -13824,14 +14193,8 @@ config.GenericConfiguration.attribute.targetGroupAttribute.i.update.label = __i+ config.GenericConfiguration.attribute.targetGroupAttribute.i.update.description = Should this attribute be changed when the group is updated. This defaults to if the group object is selected. Note, if this is the memberships attribute in the provisioning type 'groupAttributes' then the CRUD controls on memberships will take effect instead of this attribute's CRUD. config.GenericConfiguration.attribute.targetGroupAttribute.i.ignoreIfMatchesValue.label = __i+1__ - ignore if matches value config.GenericConfiguration.attribute.targetGroupAttribute.i.ignoreIfMatchesValue.description = If the group field or attribute value matches any of these values then ignore it (do not delete or update). Comma separated values, escaped comma is U+002C -config.GenericConfiguration.attribute.targetGroupAttribute.i.matchingId.label = __i+1__ - matching id -config.GenericConfiguration.attribute.targetGroupAttribute.i.matchingId.description = The "matching id" is the attribute that is used to match up target objects with Grouper objects. If the matching ID is something opaque like the idIndex or uuid then objects can be more reliably renamed. config.GenericConfiguration.attribute.targetGroupAttribute.i.multiValued.label = __i+1__ - multi-valued attribute config.GenericConfiguration.attribute.targetGroupAttribute.i.multiValued.description = If this attribute is multi-valued in the target. Generally attributes are single-valued. The membership attribute must be multi-valued if provisioning groupAttributes. -config.GenericConfiguration.attribute.targetGroupAttribute.i.searchAttribute.label = __i+1__ - search attribute -config.GenericConfiguration.attribute.targetGroupAttribute.i.searchAttribute.description = If this attribute is used to find groups in the target. The search in the target for this group might just need this attribute name and value or there might be a search filter, and this is the value of the bind variable. -config.GenericConfiguration.attribute.targetGroupAttribute.i.membershipAttribute.label = __i+1__ - membership attribute -config.GenericConfiguration.attribute.targetGroupAttribute.i.membershipAttribute.description = If this is groupAttribute provisioning and this attribute is multi-valued and holds entries that represents entities/memberships config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpressionCreateOnly.label = __i+1__ - translation expression insert only config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpressionCreateOnly.description = If you have a different translation from Grouper to Target for updates as opposed to inserts, put the insert translation here. Available variables:
    • $$provisioning.helper.variable.grouperProvisioningGroup$$
    • $$provisioning.helper.variable.gcGrouperSyncGroup$$
    • $$provisioning.helper.variable.provisioningGroupWrapper$$
    • $$provisioning.helper.variable.grouperTargetGroup$$
    @@ -13855,8 +14218,6 @@ config.GenericConfiguration.attribute.targetGroupAttribute.i.translateFromStatic config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpression.label = __i+1__ - translation expression config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpression.description = This is the translation for this attribute from Grouper to Target format during Group updates and inserts (if not overridden by "insert only" translation). Available variables:
    • $$provisioning.helper.variable.grouperProvisioningGroup$$
    • $$provisioning.helper.variable.gcGrouperSyncGroup$$
    • $$provisioning.helper.variable.provisioningGroupWrapper$$
    • $$provisioning.helper.variable.grouperTargetGroup$$
    -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpressionFromMembership.label = __i+1__ - translation expression from membership -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpressionFromMembership.description = Generally you will leave this blank and use a "membership sync from field". If you need to do a translation, you can use any membership object variable config.GenericConfiguration.attribute.targetGroupAttribute.i.defaultValue.label = __i+1__ - default value config.GenericConfiguration.attribute.targetGroupAttribute.i.defaultValue.description = If there should always be a value in the target, then list the value here to assign to the field/attribute if it is blank. Use <emptyString> if the default value should be an empty string. config.GenericConfiguration.attribute.targetGroupAttribute.i.required.label = __i+1__ - required @@ -13865,12 +14226,6 @@ config.GenericConfiguration.attribute.targetGroupAttribute.i.maxlength.label = _ config.GenericConfiguration.attribute.targetGroupAttribute.i.maxlength.description = If there is a maximum length requirement for this field in the target, assign the integer of maximum number of characters. If this field value size is greater than the max length, then the Group is invalid and will not be provisioned config.GenericConfiguration.attribute.targetGroupAttribute.i.validExpression.label = __i+1__ - validation expression config.GenericConfiguration.attribute.targetGroupAttribute.i.validExpression.description = If there is a complex validation by JEXL script enter that here. The available variables are "value" (each individual value), and "valueMultiple" (the set of multiple values if this attribute supports multiple values. Return true for valid or false for invalid. Example to see if numeric value is positive: ${value>0} -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateFromMemberSyncField.label = __i+1__ - membership sync from field -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateFromMemberSyncField.description = If this is a membership attribute for groupAttributes provisioning, then the values can be copied from the member sync object from this field. -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateToGroupSyncField.label = __i+1__ - target group link field -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateToGroupSyncField.description = If this is a group link field/attribute, then copy the target value to this group sync field, and retrieve from the group sync field as a cache during translation for incremental provisioning or during deletes. -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateGrouperToGroupSyncField.label = __i+1__ - Grouper group link field -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateGrouperToGroupSyncField.description = Copy the Grouper value to this group sync field, and retrieve from the group sync field during provisioning. config.SqlProvisionerConfiguration.attribute.targetGroupAttribute.i.storageType.label = __i+1__ - Storage type config.SqlProvisionerConfiguration.attribute.targetGroupAttribute.i.storageType.description = Storage type @@ -13878,6 +14233,10 @@ config.SqlProvisionerConfiguration.attribute.targetGroupAttribute.i.storageType. config.SqlProvisionerConfiguration.attribute.targetEntityAttribute.i.storageType.label = __i+1__ - Storage type config.SqlProvisionerConfiguration.attribute.targetEntityAttribute.i.storageType.description = Storage type +config.SqlProvisionerConfiguration.attribute.option.targetGroupAttribute.i.attributePrefix = col / attr +config.SqlProvisionerConfiguration.attribute.option.targetEntityAttribute.i.attributePrefix = col / attr + + config.GenericConfiguration.attribute.operateOnGrouperEntities.label = Operate on entities config.GenericConfiguration.attribute.operateOnGrouperEntities.description = If the provisioner involves entity objects. This might not be true if you are provisioning memberships or groupAttributes without a target entity link. @@ -13887,12 +14246,24 @@ config.GenericConfiguration.attribute.selectAllEntities.description = If you hav config.GenericConfiguration.attribute.loadEntitiesToGrouperTable.label = Load entities into grouper table config.GenericConfiguration.attribute.loadEntitiesToGrouperTable.description = Load entities into grouper table for reporting and diagnostics. +config.GenericConfiguration.attribute.groupMembershipAttributeName.label = Group attribute name for memberships +config.GenericConfiguration.attribute.groupMembershipAttributeName.description = The group attribute that stores values that represent memberships for the group + +config.GenericConfiguration.attribute.groupMembershipAttributeValue.label = Entity attribute name for memberships +config.GenericConfiguration.attribute.groupMembershipAttributeValue.description = The entity attribute that has values that represent memberships for the group, will be stored in the group attribute name for memberships + +config.GenericConfiguration.attribute.entityMembershipAttributeName.label = Entity attribute name for memberships +config.GenericConfiguration.attribute.entityMembershipAttributeName.description = The entity attribute that stores values that represent memberships for the entity + +config.GenericConfiguration.attribute.entityMembershipAttributeValue.label = Group attribute name for memberships +config.GenericConfiguration.attribute.entityMembershipAttributeValue.description = The group attribute that has values that represent memberships for the entity, will be stored in the entity attribute name for memberships + config.GenericConfiguration.attribute.selectEntities.label = Select entities config.GenericConfiguration.attribute.selectEntities.description = If entities should be read from the target. Generally this will be 'true' except:
    1. Messages are sent to the target without knowing the state of the target
    2. Provisioning groupAttributes with no entity link
    3. Provisioning membership objects with no entity link
    config.GenericConfiguration.attribute.insertEntities.label = Insert entities config.GenericConfiguration.attribute.insertEntities.description = If provisionable entities in Grouper which do not exist in the target should be created in the target. This will not be true if all the needed entities exist in the target or if the target manages entities it another process. config.GenericConfiguration.attribute.updateEntities.label = Update entities -config.GenericConfiguration.attribute.updateEntities.description = If entity fields and attributes which differ from the target should cause the target data to be updated. This does not include the membership attribute if the membership provisioning type is entityAttributes. +config.GenericConfiguration.attribute.updateEntities.description = If entity attributes which differ from the target should cause the target data to be updated. This does not include the membership attribute if the membership provisioning type is entityAttributes. config.GenericConfiguration.attribute.deleteEntities.label = Delete entities config.GenericConfiguration.attribute.deleteEntities.description = If you want to delete entities in the target (default yes delete if Grouper created and then deleted the entity). Note, there are a few types of "deletes" you can choose from if you select "true", you must pick which delete option below. config.GenericConfiguration.attribute.deleteEntitiesIfNotExistInGrouper.label = Delete entities if not exist in Grouper @@ -13905,23 +14276,24 @@ config.GenericConfiguration.attribute.deleteEntitiesIfGrouperCreated.description config.GenericConfiguration.attribute.subjectSourcesToProvision.label = Subject sources to provision config.GenericConfiguration.attribute.subjectSourcesToProvision.description = Generally you will only select your "people" source(s). If a subject is not in any of the selected sources, they are not considered provisionable. -grouperProvisioningSubjectSourcesToProvisionRequiresEntitiesInvalid = Error with '$$config.GenericConfiguration.attribute.subjectSourcesToProvision.label$$', if you configure sources then you need to '$$config.GenericConfiguration.attribute.operateOnGrouperEntities.label$$' +grouperProvisioningSubjectSourcesToProvisionRequiresEntitiesInvalid = Error with '$$config.GenericConfiguration.attribute.subjectSourcesToProvision.label$$', if you configure sources then you need to '$$config.GenericConfiguration.attribute.operateOnGrouperEntities.label$$' or '$$config.GenericConfiguration.attribute.operateOnGrouperMemberships.label$$' -config.GenericConfiguration.attribute.hasSubjectLink.label = Has subject link -config.GenericConfiguration.attribute.hasSubjectLink.description = If the subjectId or the primary subjectIdentifier is needed to perform provisioning, then you do not need a subject link. If you need more subject attributes, then you do need a subject link to lookup subject attribute from the subject API. config.GenericConfiguration.attribute.hasTargetEntityLink.label = Has target entity link config.GenericConfiguration.attribute.hasTargetEntityLink.description = "Entity link" is when memberships refer to some data that does not exist in Grouper or the Subject API and needs to be retrieved from the target Entity object. This data is cached in the "member sync" database table. Here are some examples:
    1. Provisioning membership objects where the entity reference is a target DN or UUID.
    2. Provisioning groupAttributes where the entity value is a target DN or UUID
    config.GenericConfiguration.attribute.numberOfEntityAttributes.label = Number of entity attributes +config.GenericConfiguration.attribute.numberOfEntityAttributes.description = In the object that represents a target entity, this is the number of attributes config.GenericConfiguration.attribute.targetEntityAttribute.i.name.label = __i+1__ - name config.GenericConfiguration.attribute.targetEntityAttribute.i.name.description = Attribute name is the key in the key/value pairs for this entity +config.SqlProvisionerConfiguration.attribute.targetEntityAttribute.i.name.description = Column name for this column, or attribute name if the attribute is in a separate attributes table + config.GenericConfiguration.attribute.option.targetEntityAttribute.i.attributePrefix = attr provisioning.helper.variable.grouperProvisioningEntity = grouperProvisioningEntity (ProvisioningEntity.java): this is the Grouper representation of the entity. Fields include: email (needs configuration), id, loginId (needs configuration), name, subjectId. Attributes include: subjectSourceId, description, subjectIdentifier0 -provisioning.helper.variable.gcGrouperSyncMember = gcGrouperSyncMember (GcGrouperSyncMember.java): this is the "sync" entity object. Fields include: memberFromId2, memberFromId3, memberToId2, memberToId3 +provisioning.helper.variable.gcGrouperSyncMember = gcGrouperSyncMember (GcGrouperSyncMember.java): this is the "sync" entity object. Fields include: entityAttributeValueCache0, entityAttributeValueCache1, entityAttributeValueCache2, entityAttributeValueCache3 provisioning.helper.variable.provisioningEntityWrapper = provisioningEntityWrapper (ProvisioningGroupWrapper.java): holds references to all entity data. Fields include: create, delete, recalc, gcGrouperSyncMember, grouperProvisioningEntity, grouperTargetEntity, targetProvisioningEntity, targetNativeEntity -provisioning.helper.variable.grouperTargetEntity = grouperTargetEntity (ProvisioningEntity.java): generally this is not needed since it is being built by the translation process. Fields and attributes depend on the provisioner. +provisioning.helper.variable.grouperTargetEntity = grouperTargetEntity (ProvisioningEntity.java): generally this is not needed since it is being built by the translation process. Attributes depend on the provisioner. config.GenericConfiguration.attribute.targetEntityAttribute.i.valueType.label = __i+1__ - value type config.GenericConfiguration.attribute.targetEntityAttribute.i.valueType.description = Generally this is going to be a string (text). int means 4 byte signed integer (-2 billion to 2 billion). long is for large integers @@ -13933,14 +14305,8 @@ config.GenericConfiguration.attribute.targetEntityAttribute.i.update.label = __i config.GenericConfiguration.attribute.targetEntityAttribute.i.update.description = Should this attribute be changed when the group is updated. This defaults to if the entity object is updated. Note, if this is the memberships attribute in the provisioning type 'entityAttributes' then the CRUD controls on memberships will take effect instead of this attribute's CRUD. config.GenericConfiguration.attribute.targetEntityAttribute.i.ignoreIfMatchesValue.label = __i+1__ - ignore if matches value config.GenericConfiguration.attribute.targetEntityAttribute.i.ignoreIfMatchesValue.description = If the entity field or attribute value matches any of these values then ignore it (do not delete or update). Comma separated values, escaped comma is U+002C -config.GenericConfiguration.attribute.targetEntityAttribute.i.matchingId.label = __i+1__ - matching id -config.GenericConfiguration.attribute.targetEntityAttribute.i.matchingId.description = The "matching id" is the attribute that is used to match up target objects with Grouper objects. If the matching ID is something opaque like the subjectId then objects can be more reliably renamed. config.GenericConfiguration.attribute.targetEntityAttribute.i.multiValued.label = __i+1__ - multi-valued attribute config.GenericConfiguration.attribute.targetEntityAttribute.i.multiValued.description = If this attribute is multi-valued in the target. Generally attributes are single-valued. The membership attribute must be multi-valued if provisioning entityAttributes. -config.GenericConfiguration.attribute.targetEntityAttribute.i.membershipAttribute.label = __i+1__ - membership attribute -config.GenericConfiguration.attribute.targetEntityAttribute.i.membershipAttribute.description = If this is entityAttribute provisioning and this attribute is multi-valued and holds entries that represents groups/memberships -config.GenericConfiguration.attribute.targetEntityAttribute.i.searchAttribute.label = __i+1__ - search attribute -config.GenericConfiguration.attribute.targetEntityAttribute.i.searchAttribute.description = If this attribute is used to find entities in the target. The search in the target for this entity might just need this attribute name and value or there might be a search filter, and this is the value of the bind variable. config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpressionCreateOnly.label = __i+1__ - translation expression during inserts config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpressionCreateOnly.description = If you have a different translation from Grouper to Target for updates as opposed to inserts, put the insert translation here. Available variables:
    • $$provisioning.helper.variable.grouperProvisioningEntity$$
    • $$provisioning.helper.variable.gcGrouperSyncEntity$$
    • $$provisioning.helper.variable.provisioningEntityWrapper$$
    • $$provisioning.helper.variable.grouperTargetEntity$$
    config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpression.label = __i+1__ - translation expression @@ -13964,8 +14330,6 @@ config.GenericConfiguration.attribute.targetEntityAttribute.i.translateFromGroup config.GenericConfiguration.attribute.targetEntityAttribute.i.translateFromStaticValues.label = __i+1__ - translate from static values config.GenericConfiguration.attribute.targetEntityAttribute.i.translateFromStaticValues.description = Specify static value. Value should be comma-separated if this is a multi-valued attribute. -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpressionFromMembership.label = __i+1__ - translation expression from membership -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpressionFromMembership.description = Generally you will leave this blank and use a "membership sync from field". If you need to do a translation, you can use any membership object variable config.GenericConfiguration.attribute.targetEntityAttribute.i.defaultValue.label = __i+1__ - default value config.GenericConfiguration.attribute.targetEntityAttribute.i.defaultValue.description = If there should always be a value in the target, then list the value here to assign to the field/attribute if it is blank. Use <emptyString> if the default value should be an empty string. config.GenericConfiguration.attribute.targetEntityAttribute.i.required.label = __i+1__ - required @@ -13974,12 +14338,6 @@ config.GenericConfiguration.attribute.targetEntityAttribute.i.maxlength.label = config.GenericConfiguration.attribute.targetEntityAttribute.i.maxlength.description = If there is a maximum length requirement for this field in the target, assign the integer of maximum number of characters. If this field value size is greater than the max length, then the Entity is invalid and will not be provisioned config.GenericConfiguration.attribute.targetEntityAttribute.i.validExpression.label = __i+1__ - validation expression config.GenericConfiguration.attribute.targetEntityAttribute.i.validExpression.description = If there is a complex validation by JEXL script enter that here. The available variables are "value" (each individual value), and "valueMultiple" (the set of multiple values if this attribute supports multiple values. Return true for valid or false for invalid. Example to see if numeric value is positive: ${value>0} -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateFromGroupSyncField.label = __i+1__ - Group sync from field -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateFromGroupSyncField.description = If this is a membership attribute for entityAttributes provisioning, then the values can be copied from the group sync object from this field. -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateToMemberSyncField.label = __i+1__ - Member sync to field -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateToMemberSyncField.description = If this is an entity link field/attribute, then copy the target value to this member sync field, and retrieve from the member sync field as a cache during translation for incremental provisioning or during deletes. -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateGrouperToMemberSyncField.label = __i+1__ - Grouper member link field -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateGrouperToMemberSyncField.description = Copy the grouper value to this member sync field, and retrieve from the member sync field during provisioning. config.GenericConfiguration.subSection.metadata.title = Metadata config.GenericConfiguration.subSection.metadata.description = Metadata is extra information attached to folders, groups, entities, or memberships used in provisioning configuration @@ -14078,6 +14436,10 @@ config.LdapProvisionerConfiguration.attribute.allowLdapGroupDnOverride.descripti config.LdapProvisionerConfiguration.attribute.groupDnType.label = Group DN type config.LdapProvisionerConfiguration.attribute.groupRdnAttribute.label = RDN attribute for groups config.LdapProvisionerConfiguration.attribute.groupRdnAttribute.description = The RDN attribute for group objects in LDAP. This dropdown is populated from group attributes. Fill them out and then select the RDN. click here to refresh + +config.LdapProvisionerConfiguration.attribute.userRdnAttribute.label = RDN attribute for entities +config.LdapProvisionerConfiguration.attribute.userRdnAttribute.description = The RDN attribute for user objects in LDAP. This dropdown is populated from entity attributes. Fill them out and then select the RDN. click here to refresh + config.LdapProvisionerConfiguration.attribute.folderRdnAttribute.label = RDN attribute for folders config.LdapProvisionerConfiguration.attribute.folderRdnAttribute.description = The RDN attribute for folder objects in LDAP. e.g. If the RDN attribute for folders is "ou" and the RDN attribute for groups is "cn", then the DN for the Grouper group app:foo:service:policy:foo_user would be cn=foo_user,ou=policy,ou=service,ou=foo,ou=app,<group base DN>. config.LdapProvisionerConfiguration.attribute.folderObjectClasses.label = Object classes for folders @@ -14088,6 +14450,9 @@ config.SqlProvisionerConfiguration.attribute.provisioningType.label = Sql provis config.SqlProvisionerConfiguration.attribute.dbExternalSystemConfigId.label = Db external system config id config.SqlProvisionerConfiguration.attribute.dbExternalSystemConfigId.description = Sql database external system config id. If you do not see your database configuration add it in Miscellaneous -> External systems. You can also provision across database link. +config.SqlProvisionerConfiguration.attribute.provisioningType.label = SQL provisioning type +config.SqlProvisionerConfiguration.attribute.provisioningType.description = membershipObjects: memberships table holds memberships (most common)
    groupAttributes: group attribute table to hold memberships (similar to LDAP)
    entityAttributes: entity attribute table to hold memberships (similar to LDAP) + config.SqlProvisionerConfiguration.attribute.membershipTableName.label = Membership table name config.SqlProvisionerConfiguration.attribute.membershipSearchQuery.label = Membership search query @@ -14096,23 +14461,39 @@ config.SqlProvisionerConfiguration.attribute.userPrimaryKey.label = Entity prima config.SqlProvisionerConfiguration.attribute.userSearchQuery.label = Entity search query config.SqlProvisionerConfiguration.attribute.insertEntities.label = Insert entities -config.SqlProvisionerConfiguration.attribute.membershipPrimaryKey.label = Membership primary key +config.SqlProvisionerConfiguration.attribute.numberOfGroupAttributes.label = Number of group columns or attributes +config.SqlProvisionerConfiguration.attribute.numberOfGroupAttributes.description = In the object that represents a target group, this is the number of columns in the group table (and if you have a group attributes table then also the attributes in that table). +config.SqlProvisionerConfiguration.attribute.numberOfMembershipAttributes.label = Number of membership columns +config.SqlProvisionerConfiguration.attribute.numberOfMembershipAttributes.description = In the object that represents a target membership, this is the number of attributes +config.SqlProvisionerConfiguration.attribute.numberOfEntityAttributes.label = Number of entity columns or attributes +config.SqlProvisionerConfiguration.attribute.numberOfEntityAttributes.description = In the object that represents a target entity, this is the number of columns in the entity table (and if you have an entity attributes table then also the attributes in that table). + config.SqlProvisionerConfiguration.attribute.membershipGroupForeignKeyColumn.label = Membership group foreign key +config.SqlProvisionerConfiguration.attribute.membershipGroupForeignKeyColumn.description = Column from membership table which is the foreign key to the group table config.SqlProvisionerConfiguration.attribute.membershipEntityForeignKeyColumn.label = Membership entity foreign key +config.SqlProvisionerConfiguration.attribute.membershipEntityForeignKeyColumn.description = Column from membership table which is the foreign key to the entity table config.SqlProvisionerConfiguration.attribute.groupTableName.label = Group table name -config.SqlProvisionerConfiguration.attribute.groupPrimaryKey.label = Group primary key +config.SqlProvisionerConfiguration.attribute.groupTableName.description = Table name of the group table, could have a schema qualifier config.SqlProvisionerConfiguration.attribute.groupSearchQuery.label = Group search query +config.SqlProvisionerConfiguration.attribute.groupSearchQuery.description = Group search query, generally Grouper will generate this automatically config.SqlProvisionerConfiguration.attribute.groupTableIdColumn.label = Group table ID column +config.SqlProvisionerConfiguration.attribute.groupTableIdColumn.description = Primary key column of the group table config.SqlProvisionerConfiguration.attribute.useSeparateTableForGroupAttributes.label = Separate table for group attributes config.SqlProvisionerConfiguration.attribute.groupAttributesTableName.label = Group attributes table name +config.SqlProvisionerConfiguration.attribute.groupAttributesTableName.description = Table to store group attributes with a column which is a foreign key to the group table, and an attribute name column, and an attribute value column config.SqlProvisionerConfiguration.attribute.groupAttributesGroupForeignKeyColumn.label = Group attributes group foreign key column +config.SqlProvisionerConfiguration.attribute.groupAttributesGroupForeignKeyColumn.description = Column name in the group attribute table which is a foreign key to the group table config.SqlProvisionerConfiguration.attribute.groupAttributesAttributeNameColumn.label = Group attributes attribute name column +config.SqlProvisionerConfiguration.attribute.groupAttributesAttributeNameColumn.description = Column name in the group attribute table which is the name of the attribute config.SqlProvisionerConfiguration.attribute.groupAttributesAttributeValueColumn.label = Group attributes attribute value column +config.SqlProvisionerConfiguration.attribute.groupAttributesAttributeValueColumn.description = Column name in the group attribute table which is the value of the attribute config.SqlProvisionerConfiguration.attribute.groupAttributesLastModifiedColumn.label = Group attributes attribute last modified column +config.SqlProvisionerConfiguration.attribute.groupAttributesLastModifiedColumn.description = Column name in the gruop attribute table which is the last modified column config.SqlProvisionerConfiguration.attribute.groupAttributesLastModifiedColumnType.label = Group attributes last modified column type +config.SqlProvisionerConfiguration.attribute.groupAttributesLastModifiedColumnType.description = Type of the last modified column config.SqlProvisionerConfiguration.attribute.useSeparateTableForEntityAttributes.label = Separate table for entity attributes config.SqlProvisionerConfiguration.attribute.entityAttributesTableName.label = Entity attributes table name @@ -14126,28 +14507,28 @@ provisioning.configuration.validation.mustHaveEntityMembershipAttribute = Error: provisioning.configuration.validation.mustHaveGroupMembershipAttribute = Error: you are provisioning groupMemberships but you do you not have a group field or attribute marked for memberships. Identify a group field or attribute for memberships provisioning.configuration.validation.mustHaveEntityMatchingId = Error: you are provisioning entityAttributes but you do you not have an entity field or attribute marked as matchingId. Identify an entity field or attribute as matchingId provisioning.configuration.validation.mustHaveGroupMatchingId = Error: you are provisioning groupMemberships but you do you not have a group field or attribute marked as matchingId. Identify a group field or attribute as matchingId -provisioning.configuration.validation.mustInsertDnIfInsertingEntities = Error: if you are inserting entities, you must insert the DN (name field) -provisioning.configuration.validation.mustInsertDnIfInsertingGroups = Error: if you are inserting groups, you must insert the DN (name field) +provisioning.configuration.validation.mustInsertDnIfInsertingEntities = Error: if you are inserting entities, you must insert the DN (ldap_dn field) +provisioning.configuration.validation.mustInsertDnIfInsertingGroups = Error: if you are inserting groups, you must insert the DN (ldap_dn field) provisioning.configuration.validation.mustSelectOrInsertMemberships = Error: if you are operating on memberships, then you must select or insert provisioning.configuration.validation.mustSelectOrInsertEntities = Error: if you are operating on entities, then you must select or insert provisioning.configuration.validation.mustSelectOrInsertGroups = Error: if you are operating on groups, then you must select or insert -provisioning.configuration.validation.mustHaveGroupDn = Error: you need to have a group field named "name" which represents the DN -provisioning.configuration.validation.mustHaveEntityDn = Error: you need to have a entity field named "name" which represents the DN -provisioning.configuration.validation.mustSelectDn = Error: you need to select the DN (name field) +provisioning.configuration.validation.mustHaveGroupDn = Error: you need to have a group field named "ldap_dn" which represents the DN +provisioning.configuration.validation.mustHaveEntityDn = Error: you need to have a entity field named "ldap_dn" which represents the DN +provisioning.configuration.validation.mustSelectDn = Error: you need to select the DN (ldap_dn field) provisioning.configuration.validation.doSomething = Error: you need to operate on groups, entities, or memberships provisioning.configuration.validation.oneGroupDeleteType = Error: if you are deleting groups, you need to pick one and only one delete type provisioning.configuration.validation.oneMembershipDeleteType = Error: if you are deleting memberships, you need to pick one and only one delete type provisioning.configuration.validation.oneEntityDeleteType = Error: if you are deleting entities, you need to pick one and only one delete type provisioning.configuration.validation.targetGroupLinkNeedsConfig = Error: if you are using 'group link' you must translate a group attribute to a sync field (recommended) or have a group link script (less likely) provisioning.configuration.validation.targetEntityLinkNeedsConfig = Error: if you are using 'entity link' you must translate an entity attribute to a sync field (recommended) or have an entity link script (less likely) -provisioning.configuration.validation.targetGroupLinkMultipleToSameBucket = Error: you cannot have multiple mappings or jexl's to the same group link field -provisioning.configuration.validation.targetEntityLinkMultipleToSameBucket = Error: you cannot have multiple mappings or jexl's to the same entity link field +provisioning.configuration.validation.targetGroupLinkMultipleFromSameAttribute = Error: you cannot have multiple mappings or jexl's to multiple group link fields from the same attribute +provisioning.configuration.validation.targetEntityLinkMultipleFromSameAttribute = Error: you cannot have multiple mappings or jexl's to multiple entity link fields from the same attribute provisioning.configuration.validation.extraneousConfigs = Error: there are extraneous configs for this provisioner: ${extraneousConfig}. Remove them from the grouper-loader.properties config file. provisioning.configuration.validation.invalidClass = Error: invalid provisioner class provisioning.configuration.validation.multipleAttributesSameName = Error: two ${type} ${fieldType}s have the same name '${attributeName}' provisioning.configuration.validation.attributeNameRequired = Error: ${type} attribute name is required -provisioning.configuration.validation.dnRequired = Error: ${type} attribute 'name' is required. It represents the LDAP DN -provisioning.configuration.validation.dnString = Error: ${type} attribute 'name' must be value type 'string'. It represents the LDAP DN +provisioning.configuration.validation.dnRequired = Error: ${type} attribute 'ldap_dn' is required. It represents the LDAP DN +provisioning.configuration.validation.dnString = Error: ${type} attribute 'ldap_dn' must be value type 'string'. It represents the LDAP DN provisioning.configuration.validation.groupIdOfUsersToProvisionNotExist = Error: Group does not exist from UUID of users to provision provisionerConfigurationSaveErrorMetadataNotValidFormat = Metadata name must start with md_ and can only contain alpha-numeric and underscore characters. provisionerConfigurationSaveErrorMetadataDefaultValueNotCorrectType = Default value '$$defaultValue$$' must be of the selected type '$$selectedType$$'. @@ -14978,6 +15359,8 @@ grouperLoaderFailsafeApprove = Failsafe approve adminDaemonJobsMoreActionsFailsafeApprove = Failsafe approve failsafeApproved = Success: failsafe approved +daemonJobDisabledSuccess = Success: Daemon job disabled +daemonJobEnabledSuccess = Success: Daemon job enabled # cancel the grouper loader edit grouperLoaderEditButtonCancel = Cancel diff --git a/grouper/conf/grouperText/grouper.textNg.fr.fr.base.properties b/grouper/conf/grouperText/grouper.textNg.fr.fr.base.properties index 7de4ea2c79a6..09c3357550aa 100644 --- a/grouper/conf/grouperText/grouper.textNg.fr.fr.base.properties +++ b/grouper/conf/grouperText/grouper.textNg.fr.fr.base.properties @@ -13,7 +13,7 @@ # comma separated config files that override each other (files on the right override the left) # each should start with file: or classpath: # e.g. classpath:grouperText/grouper.text.en.us.base.properties, file:c:/temp/grouperText/grouper.text.en.us.properties -text.config.hierarchy=classpath:grouperText/grouper.textNg.fr.fr.base.properties, classpath:grouperText/grouper.text.fr.fr.properties, database:grouper +text.config.hierarchy=classpath:grouperText/grouper.textNg.en.us.base.properties, classpath:grouperText/grouper.textNg.fr.fr.base.properties, classpath:grouperText/grouper.text.fr.fr.properties, database:grouper # seconds between checking to see if the config files are updated text.config.secondsBetweenUpdateChecks=600 @@ -650,11 +650,14 @@ priv.action.assigned=Privileges affectés priv.action.assigned-failed=Privileges non affectés priv.action.revocation-failure=Le(s) privilège (s) suivant n'a (ont) pas pu être révoqué(s). Cela est dû au fait que le(s) privilège(s) n'a (ont) pas été attribué(s) directement à cette entité, mais à un groupe dont l'entité est membre: priv.create=Créer +priv.stemView=View +priv.stemViewUpper=VIEW priv.stem=Administrer priv.stemAdmin=Administrer priv.createUpper=CRÉER priv.stemAdminUpper=ADMINISTRER priv.creatorsUpper=CRÉER +priv.stemViewersUpper=VIEW priv.stemAdminsUpper=ADMINISTRER priv.member=Membre priv.member-list-field=membre de la liste {0} @@ -2695,7 +2698,28 @@ localEntityExpiresAtDateHint=Format - yyyy/mm/dd localEntityAllowedFromCidrsHint=Si plusieurs, les séparer par une virgule. Ex : 1.2.3.4/24, 1.2.3.5/36 - laisser vide si autoriser depuis n'importe quels réseaux -localEntityWsJwtRecentSourceAddressesLabel=Dernières adresses sources +localEntityWsJwtRecentSourceAddressesLabel=Adresses sources récentes + +localEntityWsJwtFailedSourceAddressesLabel = Adresses sources en erreurs + +localEntityWsJwtSampleAuthorizationHeaderLabel = Exemple d'en-tête d'autorisation + +localEntityWsJwtKeyMoreActionsButton = Actions sur les clés JWT WS + +ariaLabelGuiMoreLocalEntityWsJwtKeyActions = Affiche les actions sur les clés JWT WS + +localEntityWsJwtKeyMoreActionsEditSettings = Modifier les paramètres + +localEntityWsJwtKeyMoreActionsDeleteKey = Supprimer la clé et ses paramètres +localEntityWsJwtKeyConfirmDeleteKey = Êtes-vous sur de vouloir supprimer cette clé et ses paramètres ? + +localEntityWsJwtKeyMoreActionsDeleteKeyAndCreateNew = Remplacer la clé +localEntityWsJwtKeyConfirmDeleteAndCreateNewKey = Êtes-vous sur de vouloir remplacer cette clé ? + +localEntityViewWsJwtKeySaveButton = Valider +localEntityViewWsJwtKeyCancelButton = Annuler + +localEntityWsJwtKeyExpiresAtInvalidFormat = Le format de la date d'expiration est incorrect (yyyy/mm/dd) ######################### ## role hierarchies @@ -3413,11 +3437,11 @@ guiBreadcrumbsProvisioningLabel=Provisionnement guiBreadcrumbsAriaLabel=Fil d'ariane: Vous êtes ici: -# if there is more to show, this is the more button -guiMore=Plus +# if there is more details to show, this is the details button +guiMore=Afficher les détails # if there is less to show, this is the less button -guiLess=Moins +guiLess=Cacher les détails # aria Label properties for Stems, Attribute Defs, Groups and Subjects ariaLabelGuiMoreGroupDetails=Afficher plus de détails pour ce groupe @@ -3616,7 +3640,7 @@ myGroupsTabGroupsCanJoin=Groupes que je peux rejoindre myGroupsDescription=Le tableau suivant liste tous les groupes dont vous pouvez gérer les appartenances. # my groups filter for label -myGroupsFilterFor=Filtrer par: +myGroupsFilterFor=Filtrer par : # my groups name placeholder myGroupsSearchNamePlaceholder=Nom du groupe ou du dossier @@ -3696,7 +3720,7 @@ myStemsTitle=Mes dossiers myStemsDescription=Le tableau suivant liste les dossiers où vous avez des privilèges # my stems filter for label -myStemsFilterFor=Filtrer par: +myStemsFilterFor=Filtrer par : # my stems name placeholder myStemsSearchNamePlaceholder=Nom du dossier @@ -3761,7 +3785,7 @@ myServicesTitle=Mes services myServicesDescription=Le tableau suivant liste tous les services correspondant au filtre de recherche # my services filter for label -myServicesFilterFor=Filtrer par: +myServicesFilterFor=Filtrer par : # my services name placeholder myServicesSearchNamePlaceholder=Nom du service @@ -4634,10 +4658,10 @@ groupLabelThisGroupNotCompositeFactor=Ce groupe n'est pas une opérande d'un gro # composite strings for the various types of composites groupLabelCompositeUnion=${grouperRequestContainer.groupContainer.compositeOwnerGuiGroup.shortLinkWithIcon} is a composite union of ${grouperRequestContainer.groupContainer.compositeLeftFactorGuiGroup.shortLinkWithIcon} and ${grouperRequestContainer.groupContainer.compositeRightFactorGuiGroup.shortLinkWithIcon} groupLabelCompositeIntersection=${grouperRequestContainer.groupContainer.compositeOwnerGuiGroup.shortLinkWithIcon} est un groupe algébrique de type intersection entre ${grouperRequestContainer.groupContainer.compositeLeftFactorGuiGroup.shortLinkWithIcon} et ${grouperRequestContainer.groupContainer.compositeRightFactorGuiGroup.shortLinkWithIcon} -groupLabelCompositeMinus=${grouperRequestContainer.groupContainer.compositeOwnerGuiGroup.shortLinkWithIcon} est un groupe algébrique composé de ${grouperRequestContainer.groupContainer.compositeLeftFactorGuiGroup.shortLinkWithIcon} moins ${grouperRequestContainer.groupContainer.compositeRightFactorGuiGroup.shortLinkWithIcon} +groupLabelCompositeMinus=${grouperRequestContainer.groupContainer.compositeOwnerGuiGroup.shortLinkWithIcon} est un groupe composé de ${grouperRequestContainer.groupContainer.compositeLeftFactorGuiGroup.shortLinkWithIcon} moins ${grouperRequestContainer.groupContainer.compositeRightFactorGuiGroup.shortLinkWithIcon} # in the main panel this will show composites -groupLabelCompositeOwnerMainPanel=Note: ce groupe ne peut comporter de membres direct car c'est un groupe compositle: +groupLabelCompositeOwnerMainPanel=Note : ce groupe ne peut comporter de membres directs car c'est un groupe composite - groupLabelCompositeFactorMainPanel=Note: ce groupe est un groupe algébrique: # if you dont not have privileges to view the composite group information @@ -4879,11 +4903,13 @@ groupPrivilegesAssignStemAdminPrivilege=Attribuer le privilège $$priv.stemAdmin groupPrivilegesAssignCreatePrivilege=Attribuer le privilège $$priv.createUpper$$ groupPrivilegesAssignStemAttributeReadPrivilege=Attribuer le privilège $$priv.stemAttrReadUpper$$ groupPrivilegesAssignStemAttributeUpdatePrivilege=Attribuer le privilège $$priv.stemAttrUpdateUpper$$ +groupPrivilegesAssignStemViewPrivilege = Attribuer le privilège $$priv.stemViewUpper$$ groupPrivilegesAssignAllStemPrivilege=Attribuer TOUS les privilèges groupPrivilegesRevokeStemAdminPrivilege=Supprimer le privilège $$priv.stemAdminUpper$$ groupPrivilegesRevokeCreatePrivilege=Supprimer le privilège $$priv.createUpper$$ groupPrivilegesRevokeStemAttributeReadPrivilege=Supprimer le privilège $$priv.stemAttrReadUpper$$ groupPrivilegesRevokeStemAttributeUpdatePrivilege=Supprimer le privilège $$priv.stemAttrUpdateUpper$$ +groupPrivilegesRevokeStemViewPrivilege = Supprimer le privilège $$priv.stemViewUpper$$ groupPrivilegesRevokeAllStemPrivilege=Supprimer TOUS les privilèges groupPrivilegesAssignAttrAdminPrivilege=Attribuer le privilège $$priv.adminUpper$$ @@ -5024,6 +5050,27 @@ groupMembershipsRemoveNoSubjectSelects=Erreur: selectionnez au moins un membre # assign these privileges label on view group groupViewAssignThesePrivileges=Attribuer les privilèges suivants : +# start date on view group +groupViewStartDate = Start date: + +# end date on view group +groupViewEndDate = End date: + +# start date subtext on view group +groupViewStartDateSubtext = The optional date on which this entity's membership begins. Expected timezone is ${grouperUtil.getFriendlyTimezoneStringForInputDescription()}. + +# end date subtext on view group +groupViewEndDateSubtext = The optional date on which this entity's membership expires. Expected timezone is ${grouperUtil.getFriendlyTimezoneStringForInputDescription()}. + +# group view, start date invalid +groupViewFromDateInvalid = 'Start date' is invalid. Enter: yyyy/mm/dd hh:mi am/pm (12-hour clock) + +# group view, end date invalid +groupViewToDateInvalid = 'End date' is invalid. Enter: yyyy/mm/dd hh:mi am/pm (12-hour clock) + +# group view, start/end date used with privilege +groupAddMemberPrivStartEndDateError = Start date and end date can only be set for the default member privilege + # Add link in text of group view screen groupViewAddMemberLink=Ajouter @@ -5066,6 +5113,8 @@ groupViewEditGroupButton=Modifier le groupe # edit group button text localEntityViewEditLocalEntityButton=Modifier l'entité locale +localEntityWsJwtKeyLocalEntityButton = Clé JWT WS + # edit role inheritance button text roleViewEditInheritanceButton=Modifier l'héritage @@ -5106,7 +5155,10 @@ groupViewViewGroupButton=Voir le groupe groupViewActionsButton=Actions # more action buttons on group screen -groupViewMoreActionsButton=Plus d'actions +groupViewMoreActionsButton=Actions sur le groupe + +# more action buttons on subject screen +subjectViewMoreActionsButton=Actions sur l'entité #text on the "more" tab groupMoreTab=Plus d'infos @@ -5275,7 +5327,7 @@ groupImportAddAnotherGroupButton=Ajouter un autre groupe groupImportValidateButton=Valider # if no entity ids or identifiers were specified -groupImportNoEntitiesSpecified=Enter entity ids or identifiers +groupImportNoEntitiesSpecified=Merci de renseigner des ids ou identifiants d'entités # too many entities to validate from textarea groupImportTooManyEntitiesToValidate=Impossible d'effectuer l'import, trop d'entité à valider... Veuillez utiliser l'option d'import par fichier. @@ -5319,6 +5371,24 @@ groupImportSearchForMembersToAdd=Par recherche # group import, copy list of member ids groupImportCopyListOfIds=Par saisie d'une liste d'identifiants +# group import, start date invalid +groupImportFromDateInvalid = 'Date de debut' invalide. Format correct : yyyy/mm/dd hh:mi am/pm (sur 12 heures) + +# group import, end date invalid +groupImportToDateInvalid = 'Date de fin' invalide. Format correct : yyyy/mm/dd hh:mi am/pm (sur 12 heures) + +# group import, start date +groupImportStartDate = Date de début : + +# group import, start date sub text +groupImportStartDateSubtext = Date facultative de début de participation au groupe. Le fuseau horaire à utiliser est ${grouperUtil.getFriendlyTimezoneStringForInputDescription()}. + +# group import, end date +groupImportEndDate = Date de fin : + +# group import, end date sub text +groupImportEndDateSubtext = Date facultative de fin de participation au groupe. Le fuseau horaire à utiliser est ${grouperUtil.getFriendlyTimezoneStringForInputDescription()}. + # group import, select a file groupImportSelectFileToImport=Sélectionnez un fichier à importer : @@ -5525,7 +5595,28 @@ groupAttributeMembershipAssignmentsButton=Assignation d'attributs d'appartenance # electronic forms groupWorkflowElectronicForms=Formulaires en ligne - + +# quick links +groupViewMoreActionsQuickLinks = Accès rapide + +# templates +groupViewMoreActionsTemplates = Modèles + +# manage +groupViewMoreActionsManage = Gestion + +# auditing +groupViewMoreActionsAuditing = Audit + +# administration +groupViewMoreActionsAdministration = Administration + +# delete +groupViewMoreActionsDelete = Suppression + + + + ######################################## ## View this group's memberships ######################################## @@ -6852,6 +6943,8 @@ stemPrivilegesDecription=Le tableau suivant liste toutes les entités avec des p # dropdown for privileges filter, everyone stemPrivilegesFilterEveryone=Tous les privilèges +# dropdown for privileges filter, people with create group +stemPrivilegesFilterStemViewers = Entités avec $$priv.stemViewUpper$$ # dropdown for privileges filter, people with create group stemPrivilegesFilterCreators=Entités avec $$priv.createUpper$$ @@ -6996,6 +7089,25 @@ stemViewMoreActionsAddToMyFavorites=Ajouter à mes favoris # actions button stemViewActionsButton=Actions +# quick links +stemViewMoreActionsQuickLinks = Accès rapide + +# templates +stemViewMoreActionsTemplates = Modèles + +# manage +stemViewMoreActionsManage = Gestion + +# auditing +stemViewMoreActionsAuditing = Audit + +# administration +stemViewMoreActionsAdministration = Administration + +# delete +stemViewMoreActionsDelete = Delete + + ######################################## # Stem group memberships @@ -7759,8 +7871,8 @@ grouperAttestationAuthorizedGroupDescription=Le nom du groupe autorisé à attes grouperAttestationEmailAddressesRequired=Les courriels sont obligatoire # error message to add email grop if not emailing a group -grouperAttestationEmailGroupRequired = Email group is required -grouperAttestationEmailGroupCantRead = You need to be able READ the email group (Grouper privilege) +grouperAttestationEmailGroupRequired = Merci d'indiquer un groupe destinataire des notifications +grouperAttestationEmailGroupCantRead = Vous devez avoir au minimum le droit de LIRE le groupe indiqué comme destinataire des notifications # error message to add report if using report grouperAttestationReportNameRequired=Le nom du rapport est requis @@ -7801,7 +7913,9 @@ attestationReportEmailManagersLabel=Envoyer un e-mail aux membres autorisés du grouperAttestationDontEmailManagersLabel=Non, envoyer un courriel à une liste personnalisée d'adresses grouperAttestationReportEmailManagersLabel=Oui, envoyez un e-mail aux membres autorisés du groupe +grouperAttestationEmailCustomListLabel = Envoie un courriel à une liste personnalisée d'adresses grouperAttestationEmailManagersLabel=Oui, envoyer un courriel aux administrateurs et gestionnaires du groupe +grouperAttestationEmailGroupLabel = Envoyer un email aux membres d'un groupe (recommandé) # description of email group managers field grouperAttestationEmailManagersDescription=Si les gestionnaires du groupe (avec les droits ADMIN ou (READ et UPDATE)) doivent recevoir un courriel lorsqu'une attestation est due @@ -7809,6 +7923,7 @@ grouperAttestationReportEmailManagersDescription=Si les membres autorisés du gr # description of email addresses field grouperAttestationEmailAddressesDescription=Entrez une liste d'adresse de messageries séparée par des virgules +grouperAttestationEmailGroupDescription = Envoie les courriels aux membres du groupe indiqué. Seuls les membres avec les droits MODIFIER/ADMINISTRER sur ce groupe (avec attestation) seront notifiés. grouperAttestationReportEmailAddressesDescription=Entrez des adresses e-mail séparées par des virgules si vous n'envoyez pas d'e-mail aux membres autorisés du groupe # remove direct attestation configuration @@ -7845,6 +7960,12 @@ attestationEmailAddressesLabel=Liste d'adresses personnalisée # description help for the email addresses textfield attestationEmailAddressesDescription=Liste séparée par virgule des courriels pour les rappels. Si non spécifié, les ADMINS et UPDATERS seront utilisés. +# label for the email addresses textfield +attestationEmailGroupLabel = Notifier un groupe + +# description help for the email addresses textfield +attestationEmailGroupDescription = Groupe dont les membres seront destinataires des courriels liés à l'attestation + #default certify label attestationDefaultCertifyLabel=Utiliser le nbre de jours par défaut avant recertification @@ -8591,7 +8712,7 @@ ariaLabelGuiMoreProvisioningActions=Afficher les actions de provisionnement provisioningMoreActionsButton=Actions de provisionnement # more actions menu view more actions -provisioningMoreActionsViewSettings=Afficher les provisioners +provisioningMoreActionsViewSettings=Afficher les provisionnements # more actions menu edit more actions provisioningMoreActionsEditSettings=Modifier les paramètres de provisionnement @@ -8651,7 +8772,8 @@ provisioningStemScopeHint=Est-ce que les paramètres de provisionnement affecten # validation that metadata item is required provisioningMetadataItemRequired=$$metadataLabel$$ est requis - +# validation that metadata item is not unique +provisioningMetadataItemNotUnique = $$metadataLabel$$ n'est pas unique # value is not of correct type provisioningMetadataValueNotCorrectTypeRequired=$$value$$ n'est pas du type $$type$$ @@ -8771,14 +8893,14 @@ privsioningConfigDetailsLastGroupMetadataSync=Date de dernière synchro des mét privsioningConfigDetailsLastGroupMetadataSyncStart=Dernière date de début de synchro des métadonnées privsioningConfigDetailsLastGroupMetadataSyncDescription=Date à laquelle le nom, la description et les métadonnées du groupe ont été synchronisés pour la dernières fois (sans inclure l'appartenance) privsioningConfigDetailsLastGroupMetadataSyncStartDescription=Date à laquelle la dernière synchronisation du nom, de la description et des metadonnées du groupe a commencé (sans inclure l'appartenance) -privsioningConfigDetailsGroupFromId2=Groupe provenant d'id2 -privsioningConfigDetailsGroupFromId2Description=Groupe provenant d'id2 -privsioningConfigDetailsGroupFromId3=Groupe provenant d'id3 -privsioningConfigDetailsGroupFromId3Description=Groupe provenant d'id3 -privsioningConfigDetailsGroupToId2=Grouper vers id2 -privsioningConfigDetailsGroupToId2Description=Grouper vers id2 -privsioningConfigDetailsGroupToId3=Grouper vers id3 -privsioningConfigDetailsGroupToId3Description=Grouper vers id3 +privsioningConfigDetailsGroupAttributeValueCache0=Groupe provenant d'id2 +privsioningConfigDetailsGroupAttributeValueCache0Description=Groupe provenant d'id2 +privsioningConfigDetailsGroupAttributeValueCache1=Groupe provenant d'id3 +privsioningConfigDetailsGroupAttributeValueCache1Description=Groupe provenant d'id3 +privsioningConfigDetailsGroupAttributeValueCache2=Grouper vers id2 +privsioningConfigDetailsGroupAttributeValueCache2Description=Grouper vers id2 +privsioningConfigDetailsGroupAttributeValueCache3=Grouper vers id3 +privsioningConfigDetailsGroupAttributeValueCache3Description=Grouper vers id3 privsioningConfigDetailsMetadataUpdated=Dernière mise à jour du lien (link) privsioningConfigDetailsMetadataUpdatedDescription=Si cet objet à des données de lien (link data) en cache, c'est la dernière fois qu'il a été mis à jour à partir de la cible privsioningConfigDetailsErrorMessage=Message d'erreur @@ -8831,14 +8953,14 @@ privsioningConfigDetailsMembershipId2=id2 d'appartenance privsioningConfigDetailsMembershipId2Description=id2 d'appartenance privsioningConfigDetailsProvisionable=Provisionnable -privsioningConfigDetailsMemberFromId2=Membre de id2 -privsioningConfigDetailsMemberFromId2Description=Membre de id2 -privsioningConfigDetailsMemberFromId3=Membre de id3 -privsioningConfigDetailsMemberFromId3Description=Membre de id3 -privsioningConfigDetailsMemberToId2=Membre vers id2 -privsioningConfigDetailsMemberToId2Description=Membre vers id2 -privsioningConfigDetailsMemberToId3=Member vers id3 -privsioningConfigDetailsMemberToId3Description=Membre vers id3 +privsioningConfigDetailsEntityAttributeValueCache0=Membre de id2 +privsioningConfigDetailsEntityAttributeValueCache0Description=Membre de id2 +privsioningConfigDetailsEntityAttributeValueCache1=Membre de id3 +privsioningConfigDetailsEntityAttributeValueCache1Description=Membre de id3 +privsioningConfigDetailsEntityAttributeValueCache2=Membre vers id2 +privsioningConfigDetailsEntityAttributeValueCache2Description=Membre vers id2 +privsioningConfigDetailsEntityAttributeValueCache3=Member vers id3 +privsioningConfigDetailsEntityAttributeValueCache3Description=Membre vers id3 provisioningGroupSyncSuccess=Le message de synchro pour le provisionnement de groupe a été envoyé avec succès @@ -8858,10 +8980,10 @@ provisioningSubjectProvsionableEndLabel=Fin provisionnable provisioningSubjectLastUpdatedLabel=Dernière mise à jour provisioningSubjectLastUserSyncLabel=Dernière synchro utilisateur provisioningSubjectLastUserMetadataSyncLabel=Dernière synchronisation des métadonnées de l'utilisateur -provisioningSubjectMemberFromId2Label=Membre de id2 -provisioningSubjectMemberFromId3Label=Membre de id3 -provisioningSubjectMemberToId2Label=Membre vers id2 -provisioningSubjectMemberToId3Label=Membre vers id3 +provisioningSubjectEntityAttributeValueCache0Label=Membre de id2 +provisioningSubjectEntityAttributeValueCache1Label=Membre de id3 +provisioningSubjectEntityAttributeValueCache2Label=Membre vers id2 +provisioningSubjectEntityAttributeValueCache3Label=Membre vers id3 provisioningSubjectMembershipIdLabel=Id d'appartenance provisioningSubjectMembershipId2Label=id2 d'appartenance @@ -9718,6 +9840,7 @@ config.GshTemplateConfiguration.attribute.option.input.i.type.string.label=Chaî config.GshTemplateConfiguration.attribute.option.input.i.formElementType.text.label=Champ de texte config.GshTemplateConfiguration.attribute.option.input.i.formElementType.textarea.label=Zone de texte config.GshTemplateConfiguration.attribute.option.input.i.formElementType.dropdown.label=Menu déroulant +config.GshTemplateConfiguration.attribute.option.input.i.formElementType.password.label = Mot de passe config.GshTemplateConfiguration.attribute.option.input.i.dropdownValueFormat.sql.label=SQL config.GshTemplateConfiguration.attribute.option.input.i.dropdownValueFormat.csv.label=CSV @@ -9767,6 +9890,21 @@ config.GshTemplateConfiguration.attribute.folderUuidToShow.description=Sur quel config.GshTemplateConfiguration.attribute.folderShowOnDescendants.label=Condition d'affichage sur les descendants config.GshTemplateConfiguration.attribute.folderShowOnDescendants.description=certainFolder : uniquement sur un dossier oneChildLevel : uniquement sur les dossiers à la racine. certainFolderAndOneChildLevel : uniquement sur un dossier et les dossiers à la racine. Descendants : sur l'ensemble des sous-dossiers contenus dans le dossier. certainFolderAndDescendants : sur un dossier et sur l'ensemble des sous-dossiers. +config.GshTemplateConfiguration.attribute.showOnGroups.label=Afficher sur les groupes +config.GshTemplateConfiguration.attribute.showOnGroups.description=si cette option de modèle est disponible sur les groupes + +config.GshTemplateConfiguration.attribute.groupShowType.label=Condition d'affichage +config.GshTemplateConfiguration.attribute.groupShowType.description=Doit-il s'afficher pour un groupe, des groupes dans un certain dossier ou tous les groupes + +config.GshTemplateConfiguration.attribute.groupUuidsToShow.label = UUID des groupes +config.GshTemplateConfiguration.attribute.groupUuidsToShow.description = UUID des groupes, séparés par une virgule, où ce template sera disponible + +config.GshTemplateConfiguration.attribute.folderUuidForGroupsInFolder.label = UUID du dossier parent +config.GshTemplateConfiguration.attribute.folderUuidForGroupsInFolder.description = UUID du dossier dans lequel les groupes auront ce template de disponible + +config.GshTemplateConfiguration.attribute.groupShowOnDescendants.label=Condition d'affichage sur les descendants +config.GshTemplateConfiguration.attribute.groupShowOnDescendants.description=OneChildLevel : uniquement sur les groupes à la racine du dossier. Descendants : sur l'ensemble des groupes contenus dans le dossier + config.GshTemplateConfiguration.attribute.securityRunType.label=Sécurité liée à l'execution config.GshTemplateConfiguration.attribute.securityRunType.description=Qui peut exécuter ce modèle. Seulement GrouperSystem, le groupe d'admins ou un groupe spécifique @@ -9923,6 +10061,8 @@ config.GshTemplateConfiguration.attribute.numberOfTests.description=Nombre de te config.GenericConfiguration.subSection.test.title=Paramètres de test config.GenericConfiguration.subSection.test.description=Paramètres de test +provisioning.documentationLink = Documentation + config.GenericConfiguration.subSection.test.i.title=Test __i+1__ : paramètres config.GenericConfiguration.subSection.test.i.description=Paramètres de test @@ -9974,82 +10114,82 @@ gshTemplate.error.input.invalidDropdownValue.message='$$inputName$$' n'est pas v ## Sql Sync ######################################## -sqlSyncMainLink = Sql sync +sqlSyncMainLink = Synchro SQL -miscellaneousSqlSyncOverallBreadcrumb = Sql sync +miscellaneousSqlSyncOverallBreadcrumb = Synchro SQL -miscellaneousSqlSyncMainDescription = Sql sync +miscellaneousSqlSyncMainDescription = Synchro SQL sqlSyncMoreActionsButton = Actions -sqlSyncConfigIdLabel = Config id +sqlSyncConfigIdLabel = ID Config -sqlSyncMoreActionsAddButton = Add sql sync +sqlSyncMoreActionsAddButton = Ajouter une synchro SQL -sqlSyncMoreActionsViewButton = View Sql sync configs +sqlSyncMoreActionsViewButton = Afficher les configurations -ariaLabelGuiMoreSqlSyncActions = Show Sql sync actions +ariaLabelGuiMoreSqlSyncActions = Affiche les actions liés à la synchronisation SQL -sqlSyncNoConfiguredSqlSyncs = There are no sql syncs configured. +sqlSyncNoConfiguredSqlSyncs = Aucune synchro SQL de configurée -miscellaneousSqlSyncAddBreadcrumb = Add sql sync -miscellaneousSqlSyncEditBreadcrumb = Edit sql sync +miscellaneousSqlSyncAddBreadcrumb = Ajouter synchro SQL +miscellaneousSqlSyncEditBreadcrumb = Modifier synchro SQL -sqlSyncConfigAddFormSubmitButton = Submit +sqlSyncConfigAddFormSubmitButton = Valider -sqlSyncConfigAddFormCancelButton = Cancel +sqlSyncConfigAddFormCancelButton = Annuler -sqlSyncConfigIdHint = The Config id is an alphanumeric key for the sql sync that will be referred to from places that use the sql sync. It is also used in the configuration keys. +sqlSyncConfigIdHint = L'ID de configuration est une clé alphanumérique. Elle sera utilisé pour identifier de manière unique cette configuration de synchronisation SQL. -sqlSyncTypeLabel = Sql sync configuration +sqlSyncTypeLabel = Configuration synchro SQL -sqlSyncTypeHint = Sql sync configuration +sqlSyncTypeHint = Configuration synchro SQL -sqlSyncCreateErrorConfigIdRequired = Error: Config id is required +sqlSyncCreateErrorConfigIdRequired = Erreur : l'ID Config est obligatoire -sqlSyncConfigAddEditSuccess = Sql sync config was saved successfully. -sqlSyncConfigDeleteSuccess = Sql sync config was deleted successfully. -sqlSyncConfigChangeStatusSuccess = Sql sync config's status was changed successfully. +sqlSyncConfigAddEditSuccess = La configuration de la synchro SQL a été sauvegardée avec succès. +sqlSyncConfigDeleteSuccess = La configuration de cette synchro SQL a été supprimée avec succès. +sqlSyncConfigChangeStatusSuccess = La configuration de cette synchro SQL a été mis à jour avec succès. -sqlSyncConfigsTableHeaderConfigId = Config id +sqlSyncConfigsTableHeaderConfigId = ID Config -sqlSyncConfigsTableHeaderEnabled = Enabled +sqlSyncConfigsTableHeaderEnabled = Statut sqlSyncConfigsTableHeaderActions = Actions -sqlSyncConfigsTableEnabledTrueValue = Enabled +sqlSyncConfigsTableEnabledTrueValue = Activé -sqlSyncConfigsTableEnabledFalseValue = Disabled +sqlSyncConfigsTableEnabledFalseValue = Désactivé sqlSyncConfigsRowActionsButton = Actions -sqlSyncConfigsTableViewDetailsActionOption = View details +sqlSyncConfigsTableViewDetailsActionOption = Afficher les détails -sqlSyncConfigsTableEditDetailsActionOption = Edit details +sqlSyncConfigsTableEditDetailsActionOption = Modifier -sqlSyncConfigsTableRunActionOption = Run +sqlSyncConfigsTableRunActionOption = Exécuter -sqlSyncConfigsTableDeleteDetailsActionOption = Delete sql sync config +sqlSyncConfigsTableDeleteDetailsActionOption = Supprimer la conf de la synchro SQL -sqlSyncConfigsTableDisableActionOption = Disable +sqlSyncConfigsTableDisableActionOption = Désactiver -sqlSyncConfigsTableEnableActionOption = Enable +sqlSyncConfigsTableEnableActionOption = Activer -sqlSyncConfigsConfirmDeleteConfig = Are you sure you want to delete this sql sync config? +sqlSyncConfigsConfirmDeleteConfig = Êtes-vous sûr de vouloir supprimer cette synchro SQL ? -config.SqlSyncConfiguration.attribute.databaseFrom.label = Database from +config.SqlSyncConfiguration.attribute.databaseFrom.label = BDD d'origine -config.SqlSyncConfiguration.attribute.tableFrom.label = Table from +config.SqlSyncConfiguration.attribute.tableFrom.label = Table d'origine -config.SqlSyncConfiguration.attribute.databaseTo.label = Database to +config.SqlSyncConfiguration.attribute.databaseTo.label = BDD de destination -config.SqlSyncConfiguration.attribute.databaseToReadonly.label = Database to readonly +config.SqlSyncConfiguration.attribute.databaseToReadonly.label = BDD en lecture seule -config.SqlSyncConfiguration.attribute.tableTo.label = Table to +config.SqlSyncConfiguration.attribute.tableTo.label = Table de destination -config.SqlSyncConfiguration.attribute.columns.label = Columns +config.SqlSyncConfiguration.attribute.columns.label = Colonnes -config.SqlSyncConfiguration.attribute.primaryKeyColumns.label = Primary key columns +config.SqlSyncConfiguration.attribute.primaryKeyColumns.label = Clés primaires des colonnes config.SqlSyncConfiguration.attribute.changeFlagColumn.label = Change flag column @@ -10057,9 +10197,9 @@ config.SqlSyncConfiguration.attribute.groupingColumn.label = Grouping column config.SqlSyncConfiguration.attribute.groupingSize.label = Grouping size -config.SqlSyncConfiguration.attribute.batchSize.label = Batch size +config.SqlSyncConfiguration.attribute.batchSize.label = Taille des lots -config.SqlSyncConfiguration.attribute.maxBindVarsInSelect.label = Max bind variables in select +config.SqlSyncConfiguration.attribute.maxBindVarsInSelect.label = Nbre max de bind variables dans un select config.SqlSyncConfiguration.attribute.switchFromIncrementalToFullIfOverRecords.label = Incremental to full if over records @@ -10075,10 +10215,10 @@ config.SqlSyncConfiguration.attribute.incrementalProgressColumn.label = Incremen config.SqlSyncConfiguration.attribute.incrementalAllColumnsColumn.label = Incremental all columns column -config.SqlSyncConfiguration.attribute.statusDatabase.label = Status database +config.SqlSyncConfiguration.attribute.statusDatabase.label = Statut de la BDD -sqlSyncConfigSaveErrorTableFromContainsIllegalCharacters = Table from value can only contain alphanumeric characters, underscores, and dots -sqlSyncConfigSaveErrorTableToContainsIllegalCharacters = Table to value can only contain alphanumeric characters, underscores, and dots +sqlSyncConfigSaveErrorTableFromContainsIllegalCharacters = Le champ "Table d'origine" ne peut contenir que des caractères alphanumeriques , tirets bas (soulignés) et points +sqlSyncConfigSaveErrorTableToContainsIllegalCharacters = Le champ "Table destinataire" ne peut contenir que des caractères alphanumeriques , tirets bas (soulignés) et points ######################################## ## Subject Resolution / USDU @@ -10288,7 +10428,7 @@ subjectResolutionViewSubjectTableSubjectLastResolvedDate=Date de la dernière r subjectResolutionViewSubjectTableSubjectLastCheckedDate=Date de la dernière vérification du sujet # subject resolution view subject - days subject has been unresolved -subjectResolutionViewSubjectTableSubjectDaysUnresolved = Days subject has been unresolved +subjectResolutionViewSubjectTableSubjectDaysUnresolved = Nbre de jours depuis que le sujet est non résolu # subject resolution view subject - subject deleted? subjectResolutionViewSubjectTableSubjectIsDeleted=Est supprimé @@ -10585,42 +10725,42 @@ localEntityCreateDescriptionLabel=Description: localEntityCreateDescriptionDescription=La description contient des informations sur l'entité locale, par exemple : ce que l'entité représente, pourquoi elle a été créée... # label for the enabled date field -groupCreateEnabledDateLabel=Date d'activation: +groupCreateEnabledDateLabel=Date d'activation : # description for the enabled date field -groupCreateEnabledDateDescription = When this group will be enabled if the time is in the future +groupCreateEnabledDateDescription = A quelle date le groupe sera activé # label for the disabled date field groupCreateDisabledDateLabel=Date de désactivation : # description for the disabled date field -groupCreateDisabledDateDescription = When this group will be disabled if the time is in the future +groupCreateDisabledDateDescription = A quelle date le groupe sera désactivé # placeholder in the date field groupCreateDatePlaceholder = yyyy/mm/dd hh24:mi:ss # invalid dates on edit group -groupCreateErrorEnabledDateInvalid = 'Enabled date' is invalid. Enter: yyyy/mm/dd hh24:mi:ss -groupCreateErrorDisabledDateInvalid = 'Disabled date' is invalid. Enter: yyyy/mm/dd hh24:mi:ss +groupCreateErrorEnabledDateInvalid = 'Date d'activation' est invalide. Le format correct est : yyyy/mm/dd hh24:mi:ss +groupCreateErrorDisabledDateInvalid = 'Date de désactivation' est invalide. Le format correct est : yyyy/mm/dd hh24:mi:ss # label for the enabled date field -localEntityCreateEnabledDateLabel=Date d'activation: +localEntityCreateEnabledDateLabel=Date d'activation : # description for the enabled date field -localEntityCreateEnabledDateDescription = When this local entity will be enabled if the time is in the future +localEntityCreateEnabledDateDescription = A quelle date cette entité locale sera activée # label for the disabled date field localEntityCreateDisabledDateLabel=Date de désactivation : # description for the disabled date field -localEntityCreateDisabledDateDescription = When this local entity will be disabled if the time is in the future +localEntityCreateDisabledDateDescription = A quelle date cette entité locale sera désactivée # placeholder in the date field localEntityCreateDatePlaceholder = yyyy/mm/dd hh24:mi:ss # invalid dates on edit group -localEntityCreateErrorEnabledDateInvalid = 'Enabled date' is invalid. Enter: yyyy/mm/dd hh24:mi:ss -localEntityCreateErrorDisabledDateInvalid = 'Disabled date' is invalid. Enter: yyyy/mm/dd hh24:mi:ss +localEntityCreateErrorEnabledDateInvalid = 'Date d'activation' est invalide. Le format correct est : yyyy/mm/dd hh24:mi:ss +localEntityCreateErrorDisabledDateInvalid = 'Date de désactivation' est invalide. Le format correct est : yyyy/mm/dd hh24:mi:ss # show advanced properties button groupCreateAdvanced=Voir les options avancées @@ -11063,6 +11203,8 @@ grouperReportConfigInvalidSendEmailToGroupNameIdError=L'identifiant du groupe au grouperReportConfigQueryBlankError=La requête est un champ obligatoire +grouperReportConfigScriptBlankError = Script GSH est un champ obligatoire + grouperReportConfigQuartzCronBlankError=La planification est un champ obligatoire grouperReportConfigQuartzCronInvalidError=La planification n'est pas valide @@ -11181,7 +11323,7 @@ stemCopyIntoFolder=Copier dans ce dossier: stemCopyIntoFolderDescription=Saisissez un nom ou rechercher un dossier.
    Saisissez '$$stem.root.display-name$$' pour le dossier racine # stem copy cant find parent stem -stemCopyCantFindParentStemId=Erreur: Impossible de trouver le dossier parent. Veuillez sélectionner un dossier proveneant des résultats. +stemCopyCantFindParentStemId=Erreur: Impossible de trouver le dossier parent. Veuillez sélectionner un dossier provenant des résultats. # stem copy no privileges on parent stem stemCopyCantStemParent=Erreur: Vous n'avez les privilèges suffisant afin de créer un nouveau dossier dans le dossier parent @@ -11229,7 +11371,10 @@ stemCopyGroupsAsMembers=Copier aussi l'appartenance des groupes, de ce dossier, stemCopyGroupsAsMembersHelp=Si vous sélectionnez cette option et que des groupes de ce dossier sont aussi membres d'autres groupes, les nouveaux groupes créés lors de la copie seront aussi ajoutés en tant que membres de ces groupes. Si vous n'avez les privilèges suffisants, vous obtiendrez une erreur. # stem copy groups have privileges elsewhere checkbox -stemCopyGroupsAsPrivilegees=Si vous sélectionnez cette option et que des groupes de ce dossier ont aussi des privilèges sur d'autres groupes, les nouveaux groupes créés lors de la copie auront les mêmes privilèges. Si vous n'avez les privilèges suffisants, vous obtiendrez une erreur. +stemCopyGroupsAsPrivilegees=Si le dossier d'origine a des privilèges sur d'autres groupes ou dossiers, en sélectionnant cette option ses privilèges seront dupliqués. + +# stem copy groups have privileges elsewhere checkbox help +stemCopyGroupsAsPrivilegeesHelp = Si vous sélectionnez cette option et que des groupes de ce dossier ont aussi des privilèges sur d'autres groupes ou dossiers, les nouveaux groupes créés lors de la copie auront les mêmes privilèges. Si vous n'avez les privilèges suffisants, vous obtiendrez une erreur. # stem copy folder privileges checkbox stemCopyFolderPrivileges=Copier les privilèges du dossier? @@ -11304,16 +11449,16 @@ adminProvisionerConfigurationsLink=Provisionnement provisionerConfigsMoreActionsButton=Actions # aria label provisioner configs actions dropdown button text -ariaLabelGuiMoreProvisionerConfigsActions = Show provisioner configuration actions +ariaLabelGuiMoreProvisionerConfigsActions = Affiche les actions liés à la configuration des provisionnements # more action add form option -provisionerConfigMoreActionsAddButton=Ajouter un provisioner +provisionerConfigMoreActionsAddButton=Ajouter un provisionnement # more action view provisioner configs option -provisionerConfigMoreActionsViewButton=Afficher les provisioners +provisionerConfigMoreActionsViewButton=Afficher les provisionnements # message when no provisioner configurations are in the system -provisionerConfigNoConfiguredProvisionerConfigsFound=Aucun provisioner n'est configuré. +provisionerConfigNoConfiguredProvisionerConfigsFound=Aucun provisionnement configuré. provisionerConfigNoRecentActivityFound=Il n'y a aucune activité récente @@ -11359,7 +11504,7 @@ provisionerLogsTableHeaderOwner=Propriétaire provisionerLogsTableHeaderStatus=Status provisionerLogsTableHeaderRecordsProcessed=Enregistrements traités provisionerLogsTableHeaderRecordsChanged=Enregistrements modifiés -provisionerLogsTableHeaderJobTookMillis = Millis job took +provisionerLogsTableHeaderJobTookMillis = Durée en millis provisionerLogsTableHeaderServer=Serveur provisionerLogsTableHeaderDescription=Description @@ -11379,10 +11524,10 @@ provisionerActivityTableHeaderLastGroupSyncStart=Heure de début de la dernière provisionerActivityTableHeaderLastGroupSync=Heure de la dernière synchronisation du groupe provisionerActivityTableHeaderLastGroupMetadataSyncStart=Heure de début de la dernière synchronisation des métadonnées du groupe provisionerActivityTableHeaderLastGroupMetadataSync=Heure de la dernière synchronisation des métadonnées du groupe -provisionerActivityTableHeaderGroupFromId2=Groupe provenant d'id2 -provisionerActivityTableHeaderGroupFromId3=Groupe provenant d'id3 -provisionerActivityTableHeaderGroupToId2=Grouper vers id2 -provisionerActivityTableHeaderGroupToId3=Grouper vers id3 +provisionerActivityTableHeaderGroupAttributeValueCache0=Groupe provenant d'id2 +provisionerActivityTableHeaderGroupAttributeValueCache1=Groupe provenant d'id3 +provisionerActivityTableHeaderGroupAttributeValueCache2=Grouper vers id2 +provisionerActivityTableHeaderGroupAttributeValueCache3=Grouper vers id3 provisionerActivityTableHeaderMetadataUpdated=Heure de mise à jour des métadonnées provisionerActivityTableHeaderErrorMessage=Heure du message d'erreur provisionerActivityTableHeaderErrorTimestamp=Date de l'erreur @@ -11397,10 +11542,10 @@ provisionerActivityTableHeaderLastUserSyncStart=Date de début de la dernière s provisionerActivityTableHeaderLastUserSync=Heure de la dernière synchronisation de l'utilisateur provisionerActivityTableHeaderLastUserMetadataSyncStart=Heure de début de la dernière synchronisation des métadonnées provisionerActivityTableHeaderLastUserMetadataSync=Heure de la dernière synchronisation des métadonnées -provisionerActivityTableHeaderMemberFromId2=Membre de id2 -provisionerActivityTableHeaderMemberFromId3=Membre de id3 -provisionerActivityTableHeaderMemberToId2=Membre vers id2 -provisionerActivityTableHeaderMemberToId3=Membre vers id3 +provisionerActivityTableHeaderEntityAttributeValueCache0=Membre de id2 +provisionerActivityTableHeaderEntityAttributeValueCache1=Membre de id3 +provisionerActivityTableHeaderEntityAttributeValueCache2=Membre vers id2 +provisionerActivityTableHeaderEntityAttributeValueCache3=Membre vers id3 provisionerActivityTableHeaderMembershipId=Id d'appartenance provisionerActivityTableHeaderMembershipId2=id2 d'appartenance @@ -11504,7 +11649,7 @@ provisionerConfigsTableViewLogsActionOption=Voir les logs provisionerConfigsTableViewActivityActionOption=Afficher l'activité # view provisioner config jobs option in dropdown in table -provisionerConfigsTableViewJobsActionOption=Afficher les travaux +provisionerConfigsTableViewJobsActionOption=Afficher les tâches # edit provisioner config details option in dropdown in table provisionerConfigsTableEditDetailsActionOption=Modifier le provisionnement @@ -11574,9 +11719,11 @@ provisionerConfigConfirmDeleteConfig=Voulez-vous vraiment supprimer cette config # error that provisioner config id is required provisionerConfigCreateErrorConfigIdRequired=Erreur : l'identifiant de configuration est requis +provisionerConfigStartWithIdRequired = Erreur : le champ "Commencer avec" est obligatoire + # Add provisioner config breadcrumb on misc. page -miscellaneousProvisionerConfigAddBreadcrumb=Ajouter une configuration de provisionnement -miscellaneousProvisionerConfigEditBreadcrumb=Modifier une configuration de provisionnement +miscellaneousProvisionerConfigAddBreadcrumb=Ajouter un provisionnement +miscellaneousProvisionerConfigEditBreadcrumb=Modifier un provisionnement # provisioner config add form submit button label provisionerConfigAddFormSubmitButton=Soumettre @@ -11595,13 +11742,17 @@ provisionerConfigEditFormCancelButton=Annuler provisionerConfigIdLabel=Identifiant de configuration # provisioner config id hint -provisionerConfigIdHint=L'ID de configuration est une clé alphanumérique pour la configuration de ce provisionnement. Il est également utilisé dans les clés de configuration. Exemple : myLdapProvisioner +provisionerConfigIdHint=L'ID de configuration est une clé alphanumérique correspondant à la configuration de ce provisionnement. Il est aussi utilisé pour composer les noms des différents paramètres. Exemple : myLdapProvisioner # provisioner type label provisionerTypeLabel=Type de provisionnement + # provisioner type hint -provisionerTypeHint=Type de provisionnement auquel se connecter, par exemple LDAP ou Duo +provisionerTypeHint=Type de provisionnement, par exemple LDAP ou Duo + +provisionerStartWithLabel = Commencer avec +provisionerStartWithHint = Commencer avec # provisioner config was saved successfully provisionerConfigAddEditSuccess=La configuration du provisionnement a été enregistrée avec succès. @@ -11626,22 +11777,18 @@ grouperProvisioningDiagnosticsBack=Retour à la liste des provisionnements grouperProvisioningDiagnosticsLargeOperationsLabel=Opérations étendues -grouperProvisioningDiagnosticsSelectAllGroupsError=Le comportement de ce provisionnement n'est pas de sélectionner tous les groupes ! grouperProvisioningDiagnosticsSelectAllGroupsLabel=Sélectionnez tous les groupes grouperProvisioningDiagnosticsSelectAllGroupsDescription=Pour les provisionnements conséquents, les diagnostics peuvent prendre plus de temps. Le mieux serait peut-être de les exécuter en dehors de l'interface utilisateur -grouperProvisioningDiagnosticsSelectAllEntitiesError=Le comportement de ce provisionnement n'est pas de sélectionner toutes les entités ! grouperProvisioningDiagnosticsSelectAllEntitiesLabel=Sélectionnez toutes les entités grouperProvisioningDiagnosticsSelectAllEntitiesDescription=Pour les provisionnements conséquents, les diagnostics peuvent prendre plus de temps. Le mieux serait peut-être de les exécuter en dehors de l'interface utilisateur -grouperProvisioningDiagnosticsSelectAllMembershipsError=Le comportement de ce provisionnement n'est pas de sélectionner toutes les appartenances de membres ! grouperProvisioningDiagnosticsSelectAllMembershipsLabel=Sélectionnez toutes les appartenances de membres grouperProvisioningDiagnosticsSelectAllMembershipsDescription=Pour les provisionnements conséquents, les diagnostics peuvent prendre plus de temps. Le mieux serait peut-être de les exécuter en dehors de l'interface utilisateur grouperProvisioningDiagnosticsGroupNameLabel=Nom du groupe de tests grouperProvisioningDiagnosticsGroupNameDescription=Nom d'un groupe pouvant être sélectionné, inséré, mis à jour, supprimé dans la cible. Ce groupe doit être provisionnable pour la cible -grouperProvisioningDiagnosticsGroupInsertError=Le comportement de ce provisionnement n'est pas de sélectionner tous les groupes ! grouperProvisioningDiagnosticsGroupInsertLabel=Insérer un groupe dans la cible grouperProvisioningDiagnosticsGroupInsertDescription=Si le groupe de test n'est pas dans la cible ou s'il peut être supprimé, créez le groupe dans la cible. grouperProvisioningDiagnosticsGroupInsertLabelTrue=Vrai @@ -11736,7 +11883,7 @@ customUiConfigAddFormSubmitButton=Envoyer customUiConfigAddFormCancelButton=Annuler -customUiConfigIdHint=L'ID de configuration est une clé alphanumérique pour l'interface utilisateur personnalisée qui sera référencée à partir d'endroits qui utilisent l'interface utilisateur personnalisée. Il est également utilisé dans les clés de configuration. +customUiConfigIdHint=L'ID de configuration est une clé alphanumérique correspondant à cette interface personnalisée. Il est aussi utilisé pour composer les noms des différents paramètres. customUiTypeLabel=Configuration de l'interface utilisateur personnalisée @@ -11999,12 +12146,12 @@ grouperExternalSystemTableEnableActionOption=Activé grouperConfigIsElLabel=EL? # for each of the attributes, el label -grouperConfigIsElTooltip=Si coché, cela permettra un langage d'expression similaire à celui de la configuration EL +grouperConfigIsElTooltip=Si coché, autorise l'utilisation d'une expression language (EL) # ldap external system title config.LdapGrouperExternalSystem.title=Ldap -# azure external system title +# external system titles config.AzureGrouperExternalSystem.title=Azure config.GoogleGrouperExternalSystem.title=Google config.Office365GrouperExternalSystem.title=Office 365 @@ -12064,9 +12211,9 @@ grouperExternalSystemCreateErrorConfigIdRequired=Erreur : ID Config est obligato # error that external system config id grouper cannot be used for database type grouperExternalSystemCreateErrorConfigIdGrouperCanNotBeUsed=Erreur : l'ID config "grouper" ne peut pas être utilisé pour un type base de données -config.defaultTrueLabel=Vrai -config.defaultFalseLabel=Faux -config.defaultValueLabel=Valeur par défaut +config.defaultTrueLabel=Oui +config.defaultFalseLabel=Non +config.defaultValueLabel=Par défaut # labels for attributes config.LdapGrouperExternalSystem.attribute.url.label=URL @@ -12126,6 +12273,15 @@ config.DuoGrouperExternalSystem.attribute.adminIntegrationKey.label = Integratio config.DuoGrouperExternalSystem.attribute.adminSecretKey.label = Secret key config.DuoGrouperExternalSystem.attribute.useSsl.label = Use ssl +config.GoogleGrouperExternalSystem.attribute.domain.label = Domain name +config.GoogleGrouperExternalSystem.attribute.serviceAccountEmail.label = Service account email +config.GoogleGrouperExternalSystem.attribute.serviceAccountPKCS12FilePath.label = Service account PKCS12 file path +config.GoogleGrouperExternalSystem.attribute.serviceAccountPrivateKeyPEM.label = Service account private key +config.GoogleGrouperExternalSystem.attribute.serviceImpersonationUser.label = Service impersonation user +config.GoogleGrouperExternalSystem.attribute.tokenUrl.label = Token api url +config.GoogleGrouperExternalSystem.attribute.directoryApiBaseUrl.label = Directory api base url +config.GoogleGrouperExternalSystem.attribute.groupSettingsApiBaseUrl.label = Group settings api base url + config.SftpGrouperExternalSystem.attribute.host.label=Hôte config.SftpGrouperExternalSystem.attribute.user.label=Nom d'utilisateur config.SftpGrouperExternalSystem.attribute.secret.privateKey_0.label=Clé privée @@ -12136,6 +12292,13 @@ config.SftpGrouperExternalSystem.attribute.deleteTempFilesAfterSession.label=Sup config.SftpGrouperExternalSystem.attribute.timeoutMillis.label=Timeout en milliseconde config.SftpGrouperExternalSystem.attribute.enabled.label=Activé +config.SftpGrouperExternalSystem.attribute.proxyHost.label = Hôte proxy +config.SftpGrouperExternalSystem.attribute.proxyHost.description = Hôte du proxy pour ce connecteur externe SFTP, si vide la valeur par défaut est reprise du grouper.properties : grouperSftp.proxyHost +config.SftpGrouperExternalSystem.attribute.proxyPort.label = Port proxy +config.SftpGrouperExternalSystem.attribute.proxyPort.description = Port du proxy pour ce connecteur externe SFTP, si vide la valeur par défaut est reprise du grouper.properties : grouperSftp.proxyPort +config.SftpGrouperExternalSystem.attribute.proxyType.label = Type proxy +config.SftpGrouperExternalSystem.attribute.proxyType.description = Type de proxy pour ce connecteur externe SFTP : PROXY_HTTP, PROXY_SOCKS5, PROXY_STREAM, si vide la valeur par défaut est reprise du grouper.properties : grouperSftp.proxyType + config.SmtpGrouperExternalSystem.attribute.server.label=Serveur config.SmtpGrouperExternalSystem.attribute.user.label=Nom d'utilisateur config.SmtpGrouperExternalSystem.attribute.pass.label=Mot de passe @@ -12235,6 +12398,19 @@ grouperConfigurationValidationConfigIdInvalid=Erreur : '$$configIdLabel$$' doit grouperConfigurationValidationTestSqlQueryRequired=Erreur : '${configFieldLabel}' est obligatoire quand le test sur la valeur retournée est renseigné grouperConfigurationTestExpectedNotMatchingResult=Erreur : valeur attendue '$$expectedValue$$' mais obtenue '$$receivedValue$$' +grouperStartWithGroupTableConfigurationValidationGroupTableNotFound = Erreur : '$$tableName$$' introuvable +grouperStartWithEntityTableConfigurationValidationUserTableNotFound = Erreur : '$$userTableName$$' introuvable +grouperStartWithGroupTableConfigurationValidationGroupIdColumnNotFound = Erreur : '$$column$$' introuvable +grouperStartWithEntityTableConfigurationValidationUserIdColumnNotFound = Erreur : '$$userTableIdColumn$$' introuvable +grouperStartWithGroupTableConfigurationValidationGroupColumnsNotFound = Erreur : '$$groupTableColumns$$' colonnes introuvable +grouperStartWithEntityTableConfigurationValidationEntityColumnsNotFound = Erreur : '$$userTableColumns$$' colonnes introuvable + +grouperStartWithLdapConfigurationValidationExternalSystemNotActiveDirectory = Erreur : Le connecteur externe avec l'id '$$externalSystemId$$' n'est pas de type active directory. +grouperStartWithLdapConfigurationValidationSubjectAttributesNotValid = Erreur : '$$subjectAttributes$$' n'est pas valide + +grouperStartWithAzureConfigurationValidationEntityFieldNotSelected = Error: Select at least one of user principal name, on prem immutable id, mail nickname + +grouperConfigurationValidationGoogleFilePathOrPrivateKeyRequired = Error: Supply PKCS12 file path or private key grouperConfigurationValidationInvalidBoolean=Erreur : '${configFieldLabel}' n'est pas un booléen valide. Il devrait être à 'true' ou 'false' grouperConfigurationValidationInvalidClass=Erreur : '${configFieldLabel}' n'est pas une classe Java valide. Le champ devrait contenir le nom d'une classe présente dans la classpath (.jar dans /opt/grouper/grouperWebapp/WEB-INF/lib ou .class dans /opt/grouper/grouperWebapp/WEB-INF/classes) @@ -12249,13 +12425,13 @@ grouperConfigurationValidationInvalidGroup=Erreur : '${configFieldLabel}' n'est grouperConfigurationValidationDoesNotExtendClass=Erreur : '${configFieldLabel}' n’étend pas $$mustExtendClass$$ grouperConfigurationValidationDoesNotImplementInterface=Erreur : '${configFieldLabel}' n’implémente pas $$mustImplementInterface$$ -miscellaneousGrouperExternalSystemsAddBreadcrumb=Ajouter config brique externe +miscellaneousGrouperExternalSystemsAddBreadcrumb=Ajouter config connecteur externe -miscellaneousGrouperExternalSystemsEditBreadcrumb=Modifier config brique externe +miscellaneousGrouperExternalSystemsEditBreadcrumb=Modifier config connecteur externe miscellaneousGrouperExternalSystemsViewDetailsBreadcrumb=Voir les détails -grouperConfigDefaultValueHintPrefix=La valeur par défaut est +grouperConfigDefaultValueHintPrefix=Par défaut config.GrouperDaemonReportConfiguration.attribute.quartz.cron.label=Quartz cron config.GrouperDaemonReportConfiguration.attribute.emailTo.label=Destinataire @@ -12645,18 +12821,138 @@ config.BoxProvisionerConfiguration.attribute.boxExternalSystemConfigId.label=Id config.BoxProvisionerConfiguration.attribute.invitabilityLevel.label=Invitability level config.BoxProvisionerConfiguration.attribute.memberViewabilityLevel.label=Member viewability level -config.AzureProvisionerConfiguration.title=Azure provisioner - -config.GenericConfiguration.subSection.group.title=Configuration de groupe -config.GenericConfiguration.subSection.group.description=Configuration concernant les groupes de la cible +config.DuoProvisionerConfiguration.title = Duo users +config.DuoProvisionerConfiguration.attribute.duoExternalSystemConfigId.label = Duo external system +config.DuoProvisionerConfiguration.attribute.duoExternalSystemConfigId.description = Duo external system + +config.DuoRoleProvisionerConfiguration.title = Duo administrators + +startWithBlankConfiguration = Configuration vide +config.SqlProvisioningGroupTableStartWith.startWithDescription = This is the description for group table start with +config.SqlProvisioningGroupTableStartWith.startWithDocumentation = This is the documentation for group table start with + +config.SqlProvisionerConfiguration.description = Le provisionneur Grouper SQL permet de provisionner les groupes / entitées / membres vers une BDD SQL. +config.SqlProvisionerConfiguration.documentation = La base données peut-être de n'importe quelle type et doit avoir été configurée comme connecteur externe. La structure des tables doit-être composé de : d'une table pour les groupes, d'une table pour les attributs de groupe, d'une table pour les entités, d'une table pour les attributs d'entités et d'une table pour les appartenances. + +config.LdapGrouperExternalSystem.description = Le provisionneur Grouper LDAP permet de provisionner les groupes / entitées / membres vers un LDAP ou un AD. +config.LdapGrouperExternalSystem.documentation = Le LDAP ou l'AD doit avoir été configuré en tant que connecteur externe. Les appartenances peuvent être représentés en tant que valeurs d'attributs d'un groupe (groupAttributes), ou en tant que valeurs d'attributs d'un utilisateur LDAP (entityAttributes). + +config.AzureProvisionerConfiguration.title=Azure +config.AzureProvisionerConfiguration.description = This is the description for Azure provisioner +config.AzureProvisionerConfiguration.documentation = This is the documentation for Azure provisioner +config.AzureProvisionerConfiguration.attribute.azureExternalSystemConfigId.label = External system config id + +config.AzureProvisionerConfiguration.attribute.allowOnlyMembersToPost.label = Show metadata for 'allow only members to post' +config.AzureProvisionerConfiguration.attribute.allowOnlyMembersToPost.description = When marking a group as provisionable, allow users to choose if only members can post +grouperProvisioningMetadataAllowOnlyMembersToPostLabel = Allow only members to post +grouperProvisioningMetadataAllowOnlyMembersToPostDescription = Change the default settings on a group that allows only members to post + +grouperProvisioningMetadataAzureGroupTypeDescription = Azure group type +grouperProvisioningMetadataAzureGroupTypeLabel = Azure group type + +config.azureGroupTypeMailEnabled = Mail enabled +config.azureGroupTypeMailEnabledSecurity = Mail enabled security +config.azureGroupTypeSecurity = Security +config.azureGroupTypeUnifiedSecurityEnabled = Unified security enabled +config.azureGroupTypeUnifiedNotSecurityEnabled = Unified security not enabled + +config.AzureProvisionerConfiguration.attribute.hideGroupInOutlook.label = Show metadata for 'hide group in outlook' +config.AzureProvisionerConfiguration.attribute.hideGroupInOutlook.description = When marking a group as provisionable, allow users to choose if group can be hidden in outlook +grouperProvisioningMetadataHideGroupInOutlookLabel = Hide group in outlook +grouperProvisioningMetadataHideGroupInOutlookDescription = Change the default settings on a group that allows to hide group in outlook + +config.AzureProvisionerConfiguration.attribute.subscribeNewGroupMembers.label = Show metadata for 'subscribe new group members' +config.AzureProvisionerConfiguration.attribute.subscribeNewGroupMembers.description = When marking a group as provisionable, allow users to choose if new group members can subscribe +grouperProvisioningMetadataSubscribeNewGroupMembersLabel = Subscribe new group members +grouperProvisioningMetadataSubscribeNewGroupMembersDescription = Change the default settings on a group that allows new group members to subscribe + +config.AzureProvisionerConfiguration.attribute.welcomeEmailDisabled.label = Show metadata for 'welcome email disabled' +config.AzureProvisionerConfiguration.attribute.welcomeEmailDisabled.description = When marking a group as provisionable, allow users to choose if welcome email can be disabled +grouperProvisioningMetadataWelcomeEmailDisabledLabel = Welcome email disabled +grouperProvisioningMetadataWelcomeEmailDisabledDescription = Change the default settings on a group that disables welcome email + +config.AzureProvisionerConfiguration.attribute.resourceProvisioningOptionsTeams.label = Show metadata for 'teams' +config.AzureProvisionerConfiguration.attribute.resourceProvisioningOptionsTeams.description = When marking a group as provisionable, allow users to choose if resource provisioning options can be set as Teams +grouperProvisioningMetadataResourceProvisioningOptionsTeamsLabel = Teams +grouperProvisioningMetadataResourceProvisioningOptionsTeamsDescription = Change the default settings on a group that sets resource provisioning options to Teams + +config.GoogleProvisionerConfiguration.title = Google + +config.GoogleProvisionerConfiguration.attribute.googleExternalSystemConfigId.label = External system config id + +config.GoogleProvisionerConfiguration.attribute.whoCanAdd.label = Show metadata for 'who can add' +config.GoogleProvisionerConfiguration.attribute.whoCanAdd.description = When marking a group as provisionable, allow users to choose who can add + +config.GoogleProvisionerConfiguration.attribute.whoCanJoin.label = Show metadata for 'who can join' +config.GoogleProvisionerConfiguration.attribute.whoCanJoin.description = When marking a group as provisionable, allow users to choose who can join + +config.GoogleProvisionerConfiguration.attribute.whoCanViewMembership.label = Show metadata for 'who can view membership' +config.GoogleProvisionerConfiguration.attribute.whoCanViewMembership.description = When marking a group as provisionable, allow users to choose who can view membership + +config.GoogleProvisionerConfiguration.attribute.whoCanViewGroup.label = Show metadata for 'who can view group' +config.GoogleProvisionerConfiguration.attribute.whoCanViewGroup.description = When marking a group as provisionable, allow users to choose who can view group + +config.GoogleProvisionerConfiguration.attribute.whoCanInvite.label = Show metadata for 'who can invite' +config.GoogleProvisionerConfiguration.attribute.whoCanInvite.description = When marking a group as provisionable, allow users to choose who can invite + +config.GoogleProvisionerConfiguration.attribute.allowExternalMembers.label = Show metadata for 'allow external members' +config.GoogleProvisionerConfiguration.attribute.allowExternalMembers.description = When marking a group as provisionable, allow users to choose if external members are allowed + +config.GoogleProvisionerConfiguration.attribute.whoCanPostMessage.label = Show metadata for 'who can post message' +config.GoogleProvisionerConfiguration.attribute.whoCanPostMessage.description = When marking a group as provisionable, allow users to choose who can post message + +config.GoogleProvisionerConfiguration.attribute.allowWebPosting.label = Show metadata for 'allow web posting' +config.GoogleProvisionerConfiguration.attribute.allowWebPosting.description = When marking a group as provisionable, allow users to choose if web posting is allowed + +grouperProvisioningMetadataWhoCanAddLabel = Who can add +grouperProvisioningMetadataWhoCanAddDescription = Change the default settings on a group to modify who can add +grouperProvisioningMetadataWhoCanJoinLabel = Who can join +grouperProvisioningMetadataWhoCanJoinDescription = Change the default settings on a group to modify who can join +grouperProvisioningMetadataWhoCanViewMembershipLabel = Who can view membership +grouperProvisioningMetadataWhoCanViewMembershipDescription = Change the default settings on a group to modify who can view membership +grouperProvisioningMetadataWhoCanInviteLabel = Who can invite +grouperProvisioningMetadataWhoCanInviteDescription = Change the default settings on a group to modify who can invite +grouperProvisioningMetadataWhoCanViewGroupLabel = Who can view +grouperProvisioningMetadataWhoCanViewGroupDescription = Change the default settings on a group to modify who can view group +grouperProvisioningMetadataWhoCanPostMessageLabel = Who can post +grouperProvisioningMetadataWhoCanPostMessageDescription = Change the default settings on a group to modify who can post +grouperProvisioningMetadataAllowExternalMembersLabel = Allow external members +grouperProvisioningMetadataAllowExternalMembersDescription = Change the default settings on a group that allows external members +grouperProvisioningMetadataAllowWebPostingLabel = Allow web posting +grouperProvisioningMetadataAllowWebPostingDescription = Change the default settings on a group that allows web posting + +grouperProvisioningMetadataDuoRolesLabel = Duo role +grouperProvisioningMetadataDuoRolesDescription = Pick a role +config.duoRoleOwner = Owner +config.duoRoleAdministrator = Administrator +config.duoRoleApplicationManager = Application manager +config.duoRoleUserManager = User manager +config.duoRoleHelpDesk = Help desk +config.duoRoleBilling = Billing +config.duoPhishingManager = Phishing Manager +config.duoRoleReadOnly = Read only + +grouperProvisioningMetadataDuoEmailLabel = Email address +grouperProvisioningMetadataDuoEmailDescription = Add an email address + +config.GenericConfiguration.subSection.entityAttributes.title=Configuration des attributs d'entité +config.GenericConfiguration.subSection.entityAttributes.description=Configuration concernant les attributs d'entité de la source +config.GenericConfiguration.subSection.entityAttributes.documentation = When provisioning user (entity) data, the data might be built-in to Grouper (e.g. subject id, name, description, subject identifier), or need a subject link (retrieve arbitrary subject API attributes), or use this, make a SQL or LDAP call to get attributes about a user. Generally this is 'false' and will be removed in a future Grouper release as we transition to user data fields. +config.GenericConfiguration.subSection.group.title=Configuration des groupes +config.GenericConfiguration.subSection.group.description=Configuration du provisionnement des groupes vers la cible +config.GenericConfiguration.subSection.group.documentation = A group consists of attributes and a collection of entities. Grouper provisions groups in the format that the target uses to represent them. config.GenericConfiguration.subSection.entity.title=Configuration de l'entité config.GenericConfiguration.subSection.entity.description=Configuration concernant les entités de la cible -config.GenericConfiguration.subSection.membership.title=Configuration des membres -config.GenericConfiguration.subSection.membership.description=Configuration concernant les membres de la cible +config.GenericConfiguration.subSection.entity.documentation = Une entité est un sujet ou un utilisateur. Les entités peuvent être dans des groupes en tant que membre (appartenance). Grouper provisionne les entités dans le format utilisé par la cible. Par défaut, Grouper assume qu'une autre système provisionne les entités et les utilises dont qu'en lecture seule, mais Grouper peut aussi insérer/mettre à jour/supprimer des entités si besoin. +config.GenericConfiguration.subSection.membership.title=Configuration des appartenances +config.GenericConfiguration.subSection.membership.description=Configuration du provisionnement des appartenances vers la cible +config.GenericConfiguration.subSection.membership.documentation = Grouper provisionne la relation effective entre une entité et un groupe sous la forme d'une appartenance. Grouper la provisionnera dans le format utilisé par la cible poour representer les appartenances. config.GenericConfiguration.subSection.assigningProvisioning.title=Affectation du provisionnement config.GenericConfiguration.subSection.assigningProvisioning.description=Paramètres liés à la façon dont les objets sont marqués comme provisionnable +config.GenericConfiguration.subSection.assigningProvisioning.documentation = Vous pouvez configurer comment les utilisateurs peuvent assigner des objets à un provisionnement, qui peut assigner, voir... config.GenericConfiguration.subSection.provisioningDiagnostics.title=Diagnostic de provisionnement config.GenericConfiguration.subSection.provisioningDiagnostics.description=Diagnostic de provisionnement +config.GenericConfiguration.subSection.provisioningDiagnostics.documentation = Execute un diagnostic pour avoir une vue des transformations et opérations effectuées sur la cible. Permet de s'assurer que le provisionnement s'effectue bien comme attendu. config.GenericConfiguration.subSection.advanced.title=Avancé config.GenericConfiguration.subSection.advanced.description=Avancé @@ -12666,51 +12962,78 @@ config.GenericConfiguration.subSection.targetGroupAttribute.i.description=Config config.GenericConfiguration.subSection.targetEntityAttribute.i.title=Cible __i+1__ config.GenericConfiguration.subSection.targetEntityAttribute.i.description=Configuration pour le champ / l'attribut de l'entité -config.GenericConfiguration.attribute.class.label=Classe +config.GenericConfiguration.subSection.targetMembershipAttribute.i.title = Target __i+1__ +config.GenericConfiguration.subSection.targetMembershipAttribute.i.description = Configuration for the membership attribute + +config.GenericConfiguration.attribute.class.label=Classe JAVA utilisée config.GenericConfiguration.attribute.quartzCron.label=Quartz cron -config.GenericConfiguration.attribute.quartzCron.description = Job quartz cron (not exact cron syntax) e.g. 38 17 4 * * ? means daily at 4:17:38am +config.GenericConfiguration.attribute.quartzCron.description = Quartz cron (diffère de la syntaxte cron habituelle, ex : 38 17 4 * * ? signifie tous les jours à 4:17:38am) config.GenericConfiguration.attribute.provisionerConfigId.label=Identifiant de configuration du provisionnement -config.GenericConfiguration.attribute.operateOnGrouperMemberships.label=Opère sur l'appartenance -config.GenericConfiguration.attribute.operateOnGrouperMemberships.description=Si vous provisionnez les membres. Généralement, ce sera « vrai ». +config.GenericConfiguration.attribute.operateOnGrouperMemberships.label=Provisionner les appartenances +config.GenericConfiguration.attribute.operateOnGrouperMemberships.description=Si vous provisionnez les appartenances. Dans la plupart des cas, oui. config.GenericConfiguration.attribute.membershipFields.label=Champs d'appartenance config.GenericConfiguration.attribute.membershipFields.description=Si vous provisionnez des appartenances ou des privilèges. En général, il suffit de laisser cela à la valeur par défaut (membres, ce qui signifie appartenance) à moins que vous ne vouliez que la cible ait des informations sur les personnes autorisées à effectuer certaines opérations dans Grouper (p. ex., droit de LECTURE sur l'appartenance d’un groupe). -config.GenericConfiguration.attribute.insertMemberships.label=Ajouter des membres -config.GenericConfiguration.attribute.insertMemberships.description=Si des membres doivent être ajoutées à la cible, ce sera généralement « vrai ». -config.GenericConfiguration.attribute.selectMemberships.label=Sélectionner des membres -config.GenericConfiguration.attribute.selectMemberships.description=Si les membres doivent être lues à partir de la cible. Généralement, ce sera 'vrai', sauf dans les cas où des messages sont envoyés à la cible sans connaître l’état de la cible. -config.GenericConfiguration.attribute.deleteMemberships.label=Supprimer des membres -config.GenericConfiguration.attribute.deleteMemberships.description=Si vous voulez supprimer des membres dans la cible, vous pouvez sélectionner le type de « suppressions » par défaut il est à la valeur « vrai ». -config.GenericConfiguration.attribute.deleteMembershipsIfGrouperDeleted.label=Supprimer les membres si supprimées par Grouper -config.GenericConfiguration.attribute.deleteMembershipsIfGrouperDeleted.description=Il s’agit du paramétrage « classique ». Supprimer les membres des groupes provisionnables dans la cible que si le membre vient d’être supprimée dans Grouper. Cela signifie que les membres présents avant l’existence du provisonnement, ou les membres qui ont été ajoutées uniquement dans la cible (pas dans Grouper), ne seront pas supprimées. -config.GenericConfiguration.attribute.deleteMembershipsIfGrouperCreated.label=Supprimer les membres si créées par Grouper -config.GenericConfiguration.attribute.deleteMembershipsIfGrouperCreated.description=Supprimer les membres si Grouper a provisionné le membre à un moment donné dans le passé et le membre a été supprimée dans Grouper. -config.GenericConfiguration.attribute.operateOnGrouperGroups.label=Opérer sur des groupes -config.GenericConfiguration.attribute.operateOnGrouperGroups.description=Si ce provisionnement implique des objets de groupe. Cela peut ne pas être vrai si vous mettez en service des appartenances ou des entityAttributes sans lien sur le groupe cible. -config.GenericConfiguration.attribute.selectGroups.label=Sélectionnez des groupes -config.GenericConfiguration.attribute.selectGroups.description = If groups should be read from the target. Generally this will be 'true' except:
    1. Messages are sent to the target without knowing the state of the target
    2. Provisioning userAttributes with no group link
    3. Provisioning membership objects with no group link
    -config.GenericConfiguration.attribute.insertGroups.label=Insérer des groupes -config.GenericConfiguration.attribute.insertGroups.description = If provisionable groups in Grouper which do not exist in the target should be created in the target. Generally this will be 'true'. +config.GenericConfiguration.attribute.insertMemberships.label=Insertion des appartenances +config.GenericConfiguration.attribute.insertMemberships.description=Si les appartenances doivent être provisionnées dans la cible, généralement oui. +config.GenericConfiguration.attribute.customizeMembershipCrud.label = Personnaliser le CRUD des appartenances +config.GenericConfiguration.attribute.customizeMembershipCrud.description = Personnalise les caractéristiques des opération de insertion/lecture/mis à jour/suppression (Create/Read/Update/Delete) pour les appartenances. Par défaut, les opérations sur les appartenances seronts les suivantes : SELECT / INSERT / DELETE_IF_GROUPER_CREATED_THEN_DELETED +config.GenericConfiguration.attribute.selectMemberships.label=Sélection des appartenances +config.GenericConfiguration.attribute.selectMemberships.description=Si les appartenances doivent être récupérés depuis la cible. Généralement oui, sauf dans les cas où l’état de la cible importe peu. +config.GenericConfiguration.attribute.deleteMemberships.label=Supprimer les appartenances +config.GenericConfiguration.attribute.deleteMemberships.description=Si vous voulez supprimer les appartenances provisionnées dans la cible, généralement oui. Plusieurs type de suppressions vous seront proposé. +config.GenericConfiguration.attribute.deleteMembershipsIfGrouperDeleted.label=Supprimer les appartenances lorsqu'ils le sont côté Grouper +config.GenericConfiguration.attribute.deleteMembershipsIfGrouperDeleted.description=Option intermediaire. Supprimer les appartenances dans la cible uniquement si elles sont supprimées dans Grouper. Cela implique que les appartenances présentes avant la mise en place du provisionnement, ou présentes uniquement dans la cible (et non dans Grouper), ne seront pas supprimées. +config.GenericConfiguration.attribute.deleteMembershipsIfGrouperCreated.label=Supprimer l'appartenance si créées par Grouper +config.GenericConfiguration.attribute.deleteMembershipsIfGrouperCreated.description=Supprime les appartenances lorsque Grouper les a provisionnée à un moment donné et que cette appartenance a été supprimée dans Grouper. +config.GenericConfiguration.attribute.operateOnGrouperGroups.label=Provisionner les groupes +config.GenericConfiguration.attribute.operateOnGrouperGroups.description=Si le provisionnement implique des groupes. Ce n'est pas toujours le cas, notamment si vous provisionnez des appartenances ou des attributs d'entités (entityAttributes) sans lien avec un groupe cible. + +config.GenericConfiguration.attribute.membershipAdvancedOptions.label = Options avancées +config.GenericConfiguration.attribute.membershipAdvancedOptions.description = Advanced membership options, note, there might not be any + +config.GenericConfiguration.attribute.membership2AdvancedOptions.label = Options avancées +config.GenericConfiguration.attribute.membership2AdvancedOptions.description = Advanced membership2 options, note, there might not be any + +config.GenericConfiguration.attribute.customizeGroupCrud.label = Personnaliser le CRUD des groupes +config.GenericConfiguration.attribute.customizeGroupCrud.description = Personnalise les caractéristiques des opération de insertion/lecture/mis à jour/suppression (Create/Read/Update/Delete) pour les groupes. Par défaut, les opérations sur les groupes seronts les suivantes : SELECT / INSERT / UPDATE / DELETE_IF_GROUPER_CREATED_THEN_DELETED + +config.GenericConfiguration.attribute.makeChangesToEntities.label = Opérer sur les entités +config.GenericConfiguration.attribute.makeChangesToEntities.description = Si des opérations d'insertion, de mise à jours ou de suppression doivent être effectuées sur les entités de la cible. Par défaut, Grouper fait uniquement de la selection sur les entités de la cible. + +config.GenericConfiguration.attribute.customizeEntityCrud.label = Personnaliser le CRUD des entités +config.GenericConfiguration.attribute.customizeEntityCrud.description = Personnalise les caractéristiques des opération de insertion/lecture/mis à jour/suppression (Create/Read/Update/Delete) pour les entités. Par défaut, les opérations seront limités au SELECT ou SELECT / INSERT / UPDATE / DELETE_IF_GROUPER_CREATED_THEN_DELETED si le choix a été fait d'opérer sur les entités de la cibles. + +config.GenericConfiguration.attribute.selectGroups.label=Sélection des groupes +config.GenericConfiguration.attribute.selectGroups.description = Si les groupes doivent être récupérés depuis la cible. Généralement oui, sauf dans les cas où :
    1. l'état de la cible importe peu
    2. Le provisionnement d'attributs d'utilisateur (userAttribute) sans aucun lien avec un groupe de la cible
    3. Le provisionnement d'appartenance sans aucun lien avec un groupe de la cible
    +config.GenericConfiguration.attribute.insertGroups.label=Insertion des groupes +config.GenericConfiguration.attribute.insertGroups.description = Si les groupes provisionnables, inexistants dans la cible, doivent être créés. Généralement oui. config.GenericConfiguration.attribute.deleteGroups.label=Supprimer les groupes -config.GenericConfiguration.attribute.deleteGroups.description=Si vous souhaitez supprimer des groupes dans la cible. Vous pouvez sélectionner la valeur "vrai" pour choisir parmi les types de "suppressions" dans les options de suppression ci-dessous. -config.GenericConfiguration.attribute.deleteMembershipsIfNotExistInGrouper.label=Supprimer les appartenances de membres si elles n'existent pas dans Grouper -config.GenericConfiguration.attribute.deleteMembershipsIfNotExistInGrouper.description=En général, c'est l'option que vous souhaitez. Supprimez toutes les appartenances des groupes provisionnables dans la cible qui ne trouvent pas dans Grouper. Cela signifie que Grouper fait autorité sur les appartenances. +config.GenericConfiguration.attribute.deleteGroups.description=Si vous voulez supprimer les groupes provisionnés dans la cible. Plusieurs type de suppressions vous seront proposé. +config.GenericConfiguration.attribute.deleteMembershipsIfNotExistInGrouper.label=Supprimer les appartenances si elles n'existent pas dans Grouper +config.GenericConfiguration.attribute.deleteMembershipsIfNotExistInGrouper.description=En général, c'est l'option à utiliser. Supprime toutes les appartenances, ne se trouvant pas dans Grouper, de la cible. Signifie que Grouper fait autorité sur les appartenances de la cible. config.GenericConfiguration.attribute.deleteGroupsIfNotExistInGrouper.label=Supprimer les groupes s'ils n'existent pas dans Grouper -config.GenericConfiguration.attribute.deleteGroupsIfNotExistInGrouper.description=Supprimez tous les groupes de la cible sélectionnés à partir de l'opération « sélectionner tous les groupes » qui ne sont pas dans Grouper. Cela signifie que Grouper fait autorité sur les groupes. -config.GenericConfiguration.attribute.deleteGroupsIfGrouperDeleted.label=Supprimer les groupes s'ils sont supprimés dans Grouper -config.GenericConfiguration.attribute.deleteGroupsIfGrouperDeleted.description = This is the "medium" knob. Only delete a group if the group was provisionable and was just deleted in Grouper. This means that groups that existed before the provisioner existed, or groups that were added only in the target (not in Grouper), will not be removed. -config.GenericConfiguration.attribute.deleteGroupsIfGrouperCreated.label=Supprimer les groupes s'ils sont créés par Grouper -config.GenericConfiguration.attribute.deleteGroupsIfGrouperCreated.description=Supprimez les groupes si Grouper a provisionné le groupe à un moment donné dans le passé et que le groupe a été supprimé dans Grouper. -config.GenericConfiguration.attribute.updateGroups.label=Mettre à jour les groupes -config.GenericConfiguration.attribute.updateGroups.description = If group fields and attributes which differ from the target should cause the target data to be updated. This does not include the membership attribute if the membership provisioning type if groupAttributes. +config.GenericConfiguration.attribute.deleteGroupsIfNotExistInGrouper.description=Supprimer les groupes de la cible n'existant plus dans Grouper et à condition de faire partie de la requête de sélection des tous les groupes (select all groupes). Signifie que Grouper fait autorité sur les groupes de la cible. +config.GenericConfiguration.attribute.deleteGroupsIfGrouperDeleted.label=Supprimer les groupes lorsqu'ils le sont côté Grouper +config.GenericConfiguration.attribute.deleteGroupsIfGrouperDeleted.description = Option intermediaire. Supprimer les groupes dans la cible uniquement si elles sont supprimées dans Grouper. Cela implique que les groupes présents avant la mise en place du provisionnement, ou présents uniquement dans la cible (et non dans Grouper), ne seront pas supprimées. +config.GenericConfiguration.attribute.deleteGroupsIfGrouperCreated.label=Supprimer les groupes si créés par Grouper +config.GenericConfiguration.attribute.deleteGroupsIfGrouperCreated.description=Supprime les groupes si Grouper a provisionné le groupe à un moment donné et que le groupe a été supprimé dans Grouper. +config.GenericConfiguration.attribute.updateGroups.label=Mise à jour des groupes +config.GenericConfiguration.attribute.updateGroups.description = Si les champs et attributs des groupes qui diffèrent de la cible doivent être mis à jour. Cela ne concerne pas les attributs d'appartenances si le type de provisionnement est groupAttributes. + +config.GenericConfiguration.attribute.groupRequireMembers.label = Membres obligatoires +config.GenericConfiguration.attribute.groupRequireMembers.description = Si le groupe n'a pas de membres, alors considérer qu'il n'est pas provisionnable (avec possibilité de suppression dans la cible) + + +grouper.provisioning.attribute = Attribut config.GenericConfiguration.attribute.showProvisioningDiagnostics.label=Afficher les diagnostics d'approvisionnement config.GenericConfiguration.attribute.showAdvanced.label=Afficher les paramètres avancés config.GenericConfiguration.attribute.canFullSync.label=Peut synchroniser complètement config.GenericConfiguration.attribute.selectAllGroupsDuringDiagnostics.label=Sélectionnez tous les groupes pendant le diagnostic -config.GenericConfiguration.attribute.selectAllGroupsDuringDiagnostics.description = For large provisioners this could take some time. Will select all groups and show some info on them +config.GenericConfiguration.attribute.selectAllGroupsDuringDiagnostics.description = Selectionne tous les groupes et affiche certaines informations. En cas de large provisionnement, peut allonger le délai de traitement. config.GenericConfiguration.attribute.selectAllEntitiesDuringDiagnostics.label=Sélectionner toutes les entités lors du diagnostic -config.GenericConfiguration.attribute.selectAllEntitiesDuringDiagnostics.description = For large provisioners this could take some time. Will select all entities and show some info on them -config.GenericConfiguration.attribute.selectAllMembershipsDuringDiagnostics.label = Select all memberships during diagnostics -config.GenericConfiguration.attribute.selectAllMembershipsDuringDiagnostics.description = For large provisioners this could take some time. Will select all memberships and show some info on them +config.GenericConfiguration.attribute.selectAllEntitiesDuringDiagnostics.description = Selectionne toutes les entités et affiche certaines informations. En cas de large provisionnement, peut allonger le délai de traitement. +config.GenericConfiguration.attribute.selectAllMembershipsDuringDiagnostics.label = toutes les appartenances lors du diagnostic +config.GenericConfiguration.attribute.selectAllMembershipsDuringDiagnostics.description = Selectionne toutes les appartenances et affiche certaines informations. En cas de large provisionnement, peut allonger le délai de traitement. config.GenericConfiguration.attribute.createGroupDuringDiagnostics.label=Créer un groupe pendant le diagnostic config.GenericConfiguration.attribute.createEntityDuringDiagnostics.label=Créer une entité pendant le diagnostic config.GenericConfiguration.attribute.deleteGroupDuringDiagnostics.label=Supprimer le groupe pendant le diagnostic @@ -12718,60 +13041,137 @@ config.GenericConfiguration.attribute.deleteEntityDuringDiagnostics.label=Suppri config.GenericConfiguration.attribute.testGroupName.label=Nom du groupe de tests config.GenericConfiguration.attribute.testGroupName.description=Mettez un nom complet de groupe ici qui est marqué comme provisionnable, par ex. test:testGroup config.GenericConfiguration.attribute.testSubjectIdOrIdentifier.label=Test de l'id du sujet ou de l'identifiant -config.GenericConfiguration.attribute.debugLog.label=Journal de débogage -config.GenericConfiguration.attribute.logAllObjectsVerbose.label=Déboguer tous les objets détaillés -config.GenericConfiguration.attribute.groupAllowedToAssign.label=Groupe autorisé à attribuer +config.GenericConfiguration.attribute.debugLog.label=Journal de debug +config.GenericConfiguration.attribute.logAllObjectsVerbose.label=Afficher les logs détaillés de tous les objets +config.GenericConfiguration.attribute.logCommandsAlways.label = Log toutes les commandes effectuées sur la cible +config.GenericConfiguration.attribute.logCommandsAlways.description = Log toutes les commandes bas niveau effectuées sur la cible (succès et echec). A activer uniquement en cas de dépannage. +config.GenericConfiguration.attribute.logCommandsOnError.label = Log les commandes en erreur effectuées sur la cible +config.GenericConfiguration.attribute.logCommandsOnError.description = Log les commandes bas niveau, en erreur, sur la cible. A activer uniquement en cas de dépannage. Influence les performances même pour les transactions sans erreurs. +config.GenericConfiguration.attribute.groupAllowedToAssign.label=Groupe autorisé à assigner +config.GenericConfiguration.attribute.groupAllowedToView.label = Group autorisé à voir config.GenericConfiguration.attribute.allowAssignmentsOnlyOnOneStem.label=Autoriser les affectations uniquement sur une racine config.GenericConfiguration.attribute.readOnly.label=Lecture seulement -config.GenericConfiguration.attribute.numberOfGroupAttributes.label=Nombre d'attributs de groupe -config.GenericConfiguration.attribute.numberOfGroupAttributes.description = In the object that represents a target group, this is the number of fields and attributes +config.GenericConfiguration.attribute.readOnly.description = Execute le provisionnement en lecture seule, cela signifie qu'aucun changement ne sera fait sur la cible. L'option "Afficher les logs détaillés de tous les objets" permet d'afficher les opérations qu'auraient fait le provisionnement. +config.GenericConfiguration.attribute.numberOfGroupAttributes.label=Nombre d'attribut de groupe +config.GenericConfiguration.attribute.numberOfMembershipAttributes.label = Nombre d'attribut d'appartenance +config.GenericConfiguration.attribute.numberOfGroupAttributes.description = Dans l'objet representant un groupe dans la cible, c'est le nombre de champs et d'attributs +config.GenericConfiguration.attribute.numberOfMembershipAttributes.description = Dans l'objet representant une appartenance dans la cible, c'est le nombre d'attributs config.GenericConfiguration.attribute.recalculateAllOperations.label=Recalculer tous les événements en temps réel config.GenericConfiguration.attribute.provisioningType.label=Type d'approvisionnement config.GenericConfiguration.attribute.groupIdOfUsersToProvision.label=ID de groupe d'entités à provisionner -config.GenericConfiguration.attribute.groupIdOfUsersToProvision.Description = Provide a group name of users to provision to the target. If a user is not in the group then they are not provisionable anymore. +config.GenericConfiguration.attribute.groupIdOfUsersToProvision.Description = Founit un groupe d'utilisateurs à provisionner dans la cible. Si l'utilisateur n'en fait pas partie, il n'est plus provisionnable. +config.GenericConfiguration.attribute.subjectIdentifierForMemberSyncTable.label = Synchro de membre -identifiant de sujet +config.GenericConfiguration.attribute.subjectIdentifierForMemberSyncTable.description = Les membres peuvent avoir jusqu'à 3 identifiants de sujets configurés dans Grouper. Selectionner celui qui sera stocké, dans la table de synchro de membre, pour le provisionnement. Surcharge le comportement par défaut déterminé par la manière dont le provisionnement est configuré. config.GenericConfiguration.attribute.membershipsConvertToGroupSyncThreshold.label = Memberships convert to group sync threshold config.GenericConfiguration.attribute.scoreConvertToFullSyncThreshold.label = Score convert to full sync threshold -config.GenericConfiguration.attribute.hasTargetGroupLink.label=A un lien avec le groupe cible -config.GenericConfiguration.attribute.hasTargetGroupLink.description = "Group link" is when memberships refer to some data that does not exist in Grouper and needs to be retrieved from the target Group object. This data is cached in the "group sync" database table. Here are some examples:
    1. Provisioning membership objects where the group reference is a target DN or UUID.
    2. Provisioning entityAttributes where the group value is a target DN or UUID
    +config.GenericConfiguration.attribute.hasTargetGroupLink.label=A un lien avec des groupes dans la cible +config.GenericConfiguration.attribute.hasTargetGroupLink.description = Un lien de groupe (group link) doit s'opérer lorsque le provisionnement nécessite des données non-présentes dans Grouper mais récupérable dans l'objet du groupe cible. Ces données sont mis en cache dans la table "group sync" de la base de données. Quelques exemples de cas où cela est nécessaire :
    1. Provisionner les appartenances à un groupe à partir de son DN ou de son UUID.
    2. Provisionner des entityAttributes où la valeur de groupe est un DN ou un UUID
    +config.AzureProvisioningStartWith.attribute.azureExternalSystemConfigId.label = External system config id +config.AzureProvisioningStartWith.attribute.azureExternalSystemConfigId.description = Pick the Azure extenal system to connect to for this provisioner. If the azure external system is not in the list, first go and configure that in the Grouper external system UI screen. + +config.AzureProvisioningStartWith.attribute.azurePattern.label = Azure pattern +config.AzureProvisioningStartWith.attribute.azurePattern.description = Azure pattern + +config.AzureProvisioningStartWith.attribute.userAttributesType.label = User attributes type +config.AzureProvisioningStartWith.attribute.userAttributesType.description = User attributes type + +config.AzureProvisioningStartWith.attribute.subjectSourceEntityResolverAttributes.label = Subject source entity resolver attributes +config.AzureProvisioningStartWith.attribute.subjectSourceEntityResolverAttributes.description = Subject source entity resolver attributes + +config.AzureProvisioningStartWith.attribute.groupDisplayNameAttributeValue.label = Group display name attribute value +config.AzureProvisioningStartWith.attribute.groupDisplayNameAttributeValue.description = Group display name attribute value + +config.AzureProvisioningStartWith.attribute.useGroupDescription.label = Use group description +config.AzureProvisioningStartWith.attribute.useGroupDescription.description = Use group description + +config.AzureProvisioningStartWith.attribute.mailNicknameAttributeValue.label = Mail nickname attribute value +config.AzureProvisioningStartWith.attribute.mailNicknameAttributeValue.description = Mail nickname attribute value + +config.AzureProvisioningStartWith.attribute.hasMetadataForGroupType.label = Has metadata for group type +config.AzureProvisioningStartWith.attribute.hasMetadataForGroupType.description = Has metadata for group type + +config.AzureProvisioningStartWith.attribute.hasMetadataForAllowOnlyMembersToPost.label = Has metadata for allow only members to post +config.AzureProvisioningStartWith.attribute.hasMetadataForAllowOnlyMembersToPost.description = Has metadata for allow only members to post + +config.AzureProvisioningStartWith.attribute.hasMetadataForHideGroupInOutlook.label = Has metadata for hide group in outlook +config.AzureProvisioningStartWith.attribute.hasMetadataForHideGroupInOutlook.description = Has metadata for hide group in outlook + +config.AzureProvisioningStartWith.attribute.hasMetadataForSubscribeNewGroupMembers.label = Has metadata for subscribe new group members +config.AzureProvisioningStartWith.attribute.hasMetadataForSubscribeNewGroupMembers.description = Has metadata for subscribe new group members + +config.AzureProvisioningStartWith.attribute.hasMetadataForWelcomeEmailDisabled.label = Has metadata for welcome email disabled +config.AzureProvisioningStartWith.attribute.hasMetadataForWelcomeEmailDisabled.description = Has metadata for welcome email disabled + +config.AzureProvisioningStartWith.attribute.hasMetadataForResourceProvisioningOptionsTeams.label = Has metadata for resource provisioning options teams +config.AzureProvisioningStartWith.attribute.hasMetadataForResourceProvisioningOptionsTeams.description = Has metadata for resource provisioning options teams + +config.AzureProvisioningStartWith.attribute.entityUserPrincipalName.label = Entity user principal name +config.AzureProvisioningStartWith.attribute.entityUserPrincipalName.description = Entity user principal name + +config.AzureProvisioningStartWith.attribute.entityMailNickname.label = Entity mail nickname +config.AzureProvisioningStartWith.attribute.entityMailNickname.description = Entity mail nickname + +config.AzureProvisioningStartWith.attribute.entityOnPremisesImmutableId.label = Entity on premises immutable id +config.AzureProvisioningStartWith.attribute.entityOnPremisesImmutableId.description = Entity on premises immutable id + +config.AzureProvisioningStartWith.attribute.manageEntitiesInAzure.label = Manage entities in azure +config.AzureProvisioningStartWith.attribute.manageEntitiesInAzure.description = Manage entities in azure + +config.AzureProvisioningStartWith.attribute.entityDisplayName.label = Entity display name +config.AzureProvisioningStartWith.attribute.entityDisplayName.description = Entity display name + +config.DuoProvisioningStartWith.attribute.duoExternalSystemConfigId.label = Duo external system +config.DuoProvisioningStartWith.attribute.duoExternalSystemConfigId.description = Duo external system + +config.DuoProvisioningStartWith.attribute.duoPattern.label = Duo pattern +config.DuoProvisioningStartWith.attribute.duoPattern.description = Duo pattern + +config.DuoProvisioningStartWith.attribute.userAttributesType.label = User attributes type +config.DuoProvisioningStartWith.attribute.userAttributesType.description = User attributes type + +config.DuoProvisioningStartWith.attribute.subjectSourceEntityResolverAttributes.label = Subject source entity resolver attributes +config.DuoProvisioningStartWith.attribute.subjectSourceEntityResolverAttributes.description = Subject source entity resolver attributes + +config.DuoProvisioningStartWith.attribute.manageGroups.label = Manage groups +config.DuoProvisioningStartWith.attribute.manageGroups.description = Manage groups + +config.DuoProvisioningStartWith.attribute.groupNameAttributeValue.label = Group name attribute value +config.DuoProvisioningStartWith.attribute.groupNameAttributeValue.description = Group name attribute value + +config.DuoProvisioningStartWith.attribute.useGroupDescription.label = Use group description +config.DuoProvisioningStartWith.attribute.useGroupDescription.description = Use group description + +config.DuoProvisioningStartWith.attribute.manageEntities.label = Manage entities +config.DuoProvisioningStartWith.attribute.manageEntities.description = Manage entities + +config.DuoProvisioningStartWith.attribute.entityUserName.label = User name +config.DuoProvisioningStartWith.attribute.entityUserName.description = Entity user name + +config.DuoProvisioningStartWith.attribute.entityNameSubjectAttribute.label = Name subject attribute or entity resolver name +config.DuoProvisioningStartWith.attribute.entityNameSubjectAttribute.description = Name subject attribute or entity resolver name + +config.DuoProvisioningStartWith.attribute.entityFirstNameSubjectAttribute.label = First name subject attribute or entity resolver name +config.DuoProvisioningStartWith.attribute.entityFirstNameSubjectAttribute.description = First name subject attribute or entity resolver name + +config.DuoProvisioningStartWith.attribute.entityEmailSubjectAttribute.label = Email subject attribute or entity resolver name +config.DuoProvisioningStartWith.attribute.entityEmailSubjectAttribute.description = Email subject attribute or entity resolver name config.GenericConfiguration.attribute.refreshSubjectLinkIfLessThanAmount.label=Actualiser le lien du sujet config.GenericConfiguration.attribute.refreshEntityLinkIfLessThanAmount.label=Actualiser le lien de l'entité cible config.GenericConfiguration.attribute.refreshGroupLinkIfLessThanAmount.label=Actualiser le lien du groupe cible -config.GenericConfiguration.attribute.refreshGroupLinkIfLessThanAmount.description = Target group links will be refreshed when they can be (full sync retrieve all groups), or when they must be (group link data is not cached in Grouper). Otherwise if there are groups to operate on, if there are only a few (less than this amount), then refresh the group link, otherwise for expediency just use the cached data. Generally you do not need to edit this value. This is an integer. - -config.GenericConfiguration.attribute.common.subjectLink.memberFromId2.label=Lien du sujet - memberFromId2 -config.GenericConfiguration.attribute.common.subjectLink.memberFromId3.label=Lien du sujet - memberFromId3 -config.GenericConfiguration.attribute.common.subjectLink.memberToId2.label=Lien du sujet - memberToId2 -config.GenericConfiguration.attribute.common.subjectLink.memberToId3.label=Lien du sujet - memberToId3 -config.GenericConfiguration.attribute.common.entityLink.memberFromId2.label=Lien d'entité cible - memberFromId2 -config.GenericConfiguration.attribute.common.entityLink.memberFromId3.label=Lien d'entité cible - memberFromId3 -config.GenericConfiguration.attribute.common.entityLink.memberToId2.label=Lien d'entité cible - memberToId2 -config.GenericConfiguration.attribute.common.entityLink.memberToId3.label=Lien d'entité cible - memberToId3 -config.GenericConfiguration.attribute.common.groupLink.groupFromId2.label=Lien du groupe cible - groupFromId2 -config.GenericConfiguration.attribute.common.groupLink.groupFromId2.description=En général, vous n’avez pas besoin de modifier cela, et vous le configurerez dans une configuration d’attributs. Il s’agit de l’un des quatre buckets de synchronisation. Entrez un JEXL en utilisant la variable "targetGroup" (type ProvisioningGroup.java). En fonction des données retournées par le DAO du provisionneur, vous pouvez vous référer aux champs ${targetGroup.name} ou aux attributs ${targetGroup.retrieveAttributeValue('someAttrName')} -config.GenericConfiguration.attribute.common.groupLink.groupFromId3.label=Lien du groupe cible - groupFromId3 -config.GenericConfiguration.attribute.common.groupLink.groupFromId3.description=En général, vous n’avez pas besoin de modifier cela, et vous le configurerez dans une configuration d’attributs. Il s’agit de l’un des quatre buckets de synchronisation. Entrez un JEXL en utilisant la variable "targetGroup" (type ProvisioningGroup.java). En fonction des données retournées par le DAO du provisionneur, vous pouvez vous référer aux champs ${targetGroup.name} ou aux attributs ${targetGroup.retrieveAttributeValue('someAttrName')} -config.GenericConfiguration.attribute.common.groupLink.groupToId2.label=Lien du groupe cible - groupToId2 -config.GenericConfiguration.attribute.common.groupLink.groupToId2.description=En général, vous n’avez pas besoin de modifier cela, et vous le configurerez dans une configuration d’attributs. Il s’agit de l’un des quatre buckets de synchronisation. Entrez un JEXL en utilisant la variable "targetGroup" (type ProvisioningGroup.java). En fonction des données retournées par le DAO du provisionneur, vous pouvez vous référer aux champs ${targetGroup.name} ou aux attributs ${targetGroup.retrieveAttributeValue('someAttrName')} -config.GenericConfiguration.attribute.common.groupLink.groupToId3.label=Lien du groupe cible - groupToId3 -config.GenericConfiguration.attribute.common.groupLink.groupToId3.description=En général, vous n’avez pas besoin de modifier cela, et vous le configurerez dans une configuration d’attributs. Il s’agit de l’un des quatre buckets de synchronisation. Entrez un JEXL en utilisant la variable "targetGroup" (type ProvisioningGroup.java). En fonction des données retournées par le DAO du provisionneur, vous pouvez vous référer aux champs ${targetGroup.name} ou aux attributs ${targetGroup.retrieveAttributeValue('someAttrName')} +config.GenericConfiguration.attribute.refreshGroupLinkIfLessThanAmount.description = Les liens de groupes cibles seront rafraichis quand ils peuvent l'être (récupération de tous les groupes lors d'une synchro complète), ou quand ils doivent l'être (les données de lien du groupe ne sont pas en cache dans Grouper). Autrement lors d'opérations sur des groupes et lorsqu'il y en a moins que ce nombre le lien de groupe sera actualisé et si il y en a plus, les données mises en cache seront utilisées. La valeur doit-être un entier. + config.GenericConfiguration.attribute.targetGroupAttribute.i.name.label=__i+1__ - nom config.GenericConfiguration.attribute.targetGroupAttribute.i.name.description=Le nom de l'attribut est la clé dans les paires clé/valeur pour ce groupe -config.GenericConfiguration.attribute.targetGroupAttribute.i.isFieldElseAttribute.label=__i+1__ - champ ou attribut -config.GenericConfiguration.attribute.option.targetGroupAttribute.i.isFieldElseAttribute.trueLabel=Champ -config.GenericConfiguration.attribute.option.targetGroupAttribute.i.isFieldElseAttribute.falseLabel=Attribut config.GenericConfiguration.attribute.option.targetGroupAttribute.i.groupAttributePrefix=Groupe config.GenericConfiguration.attribute.option.targetEntityAttribute.i.entityAttributePrefix=Entité config.GenericConfiguration.attribute.option.targetGroupAttribute.i.attributePrefix=attr -config.GenericConfiguration.attribute.option.targetGroupAttribute.i.fieldPrefix=Champ -config.GenericConfiguration.attribute.targetGroupAttribute.i.isFieldElseAttribute.description=Il existe des champs de groupe intégrés : id, idIndex, name, displayName. Les attributs peuvent avoir des noms libres. Consultez la documentation sur le type de fournisseur pour connaitre les champs ou attributs pris en charge. -config.GenericConfiguration.attribute.targetGroupAttribute.i.fieldName.label=__i+1__ - nom -config.GenericConfiguration.attribute.targetGroupAttribute.i.fieldName.description = ProvisioningGroup.java field name. + provisioning.helper.variable.grouperProvisioningGroup=grouperProvisioningGroup (ProvisioningGroup.java) : il s’agit de la représentation Grouper du groupe. Les champs incluent : id, idIndex, name, displayName. Les attributs comprennent : description -provisioning.helper.variable.gcGrouperSyncGroup=gcGrouperSyncGroup (GcGrouperSyncGroup.java) : il s’agit de l’objet de groupe "sync". Les champs comprennent : groupFromId2, groupFromId3, groupToId2, groupToId3 +provisioning.helper.variable.gcGrouperSyncGroup=gcGrouperSyncGroup (GcGrouperSyncGroup.java) : il s’agit de l’objet de groupe "sync". Les champs comprennent : groupAttributeValueCache0, groupAttributeValueCache1, groupAttributeValueCache2, groupAttributeValueCache3 provisioning.helper.variable.provisioningGroupWrapper=provisioningGroupWrapper (ProvisioningGroupWrapper.java) : contient des références à toutes les données du groupe. Les champs incluent : create, delete, recalc, gcGrouperSyncGroup, grouperProvisioningGroup, grouperTargetGroup, targetProvisioningGroup, targetNativeGroup provisioning.helper.variable.grouperTargetGroup=grouperTargetGroup (ProvisioningGroup.java) : généralement ce n’est pas nécessaire car il est construit par le processus de traduction. Les champs et attributs dépendent du provisionneur. @@ -12785,16 +13185,9 @@ config.GenericConfiguration.attribute.targetGroupAttribute.i.update.label=__i+1_ config.GenericConfiguration.attribute.targetGroupAttribute.i.update.description=Cet attribut devrait être modifié lors de la mise à jour du groupe. config.GenericConfiguration.attribute.targetGroupAttribute.i.ignoreIfMatchesValue.label=__i+1__ - ignorer si cela correspond à la valeur config.GenericConfiguration.attribute.targetGroupAttribute.i.ignoreIfMatchesValue.description=Si le champ de groupe ou la valeur d'attribut correspond à l'une de ces valeurs, ignorez-le (ne pas supprimer ni mettre à jour). Valeurs séparées par des virgules, la virgule échappée est U+002C -config.GenericConfiguration.attribute.targetGroupAttribute.i.matchingId.label=__i+1__ - identifiant correspondant -config.GenericConfiguration.attribute.targetGroupAttribute.i.matchingId.description=Le "matching id" est l'attribut qui est utilisé pour faire correspondre les objets cibles avec les objets Grouper. Si l'ID correspondant est quelque chose d'opaque comme idIndex ou uuid, les objets peuvent être renommés de manière plus fiable. config.GenericConfiguration.attribute.targetGroupAttribute.i.multiValued.label=__i+1__ - attribut à plusieurs valeurs config.GenericConfiguration.attribute.targetGroupAttribute.i.multiValued.description=Si cet attribut est multi-évalué dans la cible. En général, les attributs ont une valeur unique. L'attribut d'appartenance doit avoir plusieurs valeurs si vous approvisionnez groupAttributes. -config.GenericConfiguration.attribute.targetGroupAttribute.i.searchAttribute.label=__i+1__ - attribut de recherche -config.GenericConfiguration.attribute.targetGroupAttribute.i.searchAttribute.description=Si cet attribut est utilisé pour rechercher des groupes dans la cible. La recherche dans la cible pour ce groupe peut simplement avoir besoin de ce nom et de cette valeur d'attribut ou il peut y avoir un filtre de recherche, et c'est la valeur de la variable de liaison. -config.GenericConfiguration.attribute.targetGroupAttribute.i.membershipAttribute.label=__i+1__ - attribut d'appartenance -config.GenericConfiguration.attribute.targetGroupAttribute.i.membershipAttribute.description=S'il s'agit d'un approvisionnement de type groupAttribute et que cet attribut est multi-évalué et contient des entrées qui représentent des entités/appartenances config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpressionCreateOnly.label=__i+1__ - insertion d'expression de traduction uniquement -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpressionCreateOnly.description = If you have a different translation from Grouper to Target for updates as opposed to inserts, put the insert translation here. Available variables:
    • $$provisioning.helper.variable.grouperProvisioningGroup$$
    • $$provisioning.helper.variable.gcGrouperSyncGroup$$
    • $$provisioning.helper.variable.provisioningGroupWrapper$$
    • $$provisioning.helper.variable.grouperTargetGroup$$
    config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpressionTypeCreateOnly.label=__i+1__ - insertion de type de traduction uniquement config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpressionTypeCreateOnly.description=Si c’est une simple (insérer seulement) traduction directement à partir du champ, puis sélectionnez GrouperProvisioningGroupField puisque vous n’avez pas à vous soucier d’une faute de script et la performance est meilleure. Sinon, configurez un script de traduction. @@ -12803,15 +13196,9 @@ config.GenericConfiguration.attribute.targetGroupAttribute.i.translateFromGroupe config.GenericConfiguration.attribute.targetGroupAttribute.i.translateFromGrouperProvisioningGroupFieldCreateOnly.description=Sélectionnez le champ (pour insérer uniquement) dans grouperProvisioningGroup à partir duquel copier les données. id : est l’UUID du groupe, idIndex : identifiant numérique, displayExtension : dernière partie du nom e.g. pour affichage dans l’interface utilisateur, displayName : chemin complet du nom d’affichage e.g. pour affichage dans l’interface utilisateur, extension : dernière partie du nom du système, nom : chemin complet du nom du système, description : description du groupe config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpressionType.label=__i+1__ - type de traduction -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpressionType.description = If this is a simple translation straight from field, then select GrouperProvisioningGroupField since you do not have to worry about a script typo and the performance is better. Otherwise configure a translation script. -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateFromGrouperProvisioningGroupField.label = __i+1__ - translate from grouperProvisioningGroup field -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateFromGrouperProvisioningGroupField.description = Select the field from grouperProvisioningGroup to copy data from. id: is the UUID of the group, idIndex: numeric indentifier, displayExtension: last part of the name e.g. for display in the UI, displayName: full path of of the display name e.g. for display in the UI, extension: last part of the system name, name: full path of the system name, description: group description config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpression.label=__i+1__ - expression de traduction -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpression.description = This is the translation for this attribute from Grouper to Target format during Group updates and inserts (if not overridden by "insert only" translation). Available variables:
    • $$provisioning.helper.variable.grouperProvisioningGroup$$
    • $$provisioning.helper.variable.gcGrouperSyncGroup$$
    • $$provisioning.helper.variable.provisioningGroupWrapper$$
    • $$provisioning.helper.variable.grouperTargetGroup$$
    -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpressionFromMembership.label=__i+1__ - expression de traduction de l'appartenance -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateExpressionFromMembership.description=En règle générale, vous laisserez ce champ vide et utiliserez une "synchronisation des membres à partir du champ". Si vous devez effectuer une traduction, vous pouvez utiliser n'importe quelle variable d'objet d'appartenance config.GenericConfiguration.attribute.targetGroupAttribute.i.defaultValue.label=__i+1__ - valeur par défaut config.GenericConfiguration.attribute.targetGroupAttribute.i.defaultValue.description=Si la valeur ne doit pas être vide dans la cible, répertoriez ici la valeur à affecter au champ/attribut s'il est vide. config.GenericConfiguration.attribute.targetGroupAttribute.i.required.label=__i+1__ - obligatoire @@ -12820,57 +13207,28 @@ config.GenericConfiguration.attribute.targetGroupAttribute.i.maxlength.label=__i config.GenericConfiguration.attribute.targetGroupAttribute.i.maxlength.description=S’il y a une longueur maximale requise pour ce champ dans la cible, assignez le nombre entier de caractères maximum. Si cette taille de champ est supérieure à la longueur maximale, alors le groupe n’est pas valide et ne sera pas approvisionné config.GenericConfiguration.attribute.targetGroupAttribute.i.validExpression.label=__i+1__ - expression de validation config.GenericConfiguration.attribute.targetGroupAttribute.i.validExpression.description=S’il y a une validation complexe par le script JEXL, saisissez-la ici. Les variables disponibles sont "value" (valeur unique), et "valueMultiple" (valeurs multiples supportées. Renvoie true pour valide ou false pour invalide. Exemple pour voir si la valeur numérique est positive : ${value>0} -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateFromMemberSyncField.label=__i+1__ - synchronisation des membres depuis le champ -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateFromMemberSyncField.description=S'il s'agit d'un attribut d'appartenance pour l'approvisionnement groupAttributes, les valeurs peuvent être copiées à partir de l'objet de synchronisation de membre contenu dans ce champ. -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateToGroupSyncField.label=__i+1__ - champ de lien du groupe cible -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateToGroupSyncField.description = If this is a group link field/attribute, then copy the target value to this group sync field, and retrieve from the group sync field as a cache during translation for incremental provisioning or during deletes. -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateGrouperToGroupSyncField.label = __i+1__ - Grouper group link field -config.GenericConfiguration.attribute.targetGroupAttribute.i.translateGrouperToGroupSyncField.description=Copiez la valeur de Grouper dans ce champ de synchronisation de groupe, et récupérez le pendant le approvisionnement. -config.GenericConfiguration.attribute.operateOnGrouperEntities.label = Operate on entities -config.GenericConfiguration.attribute.operateOnGrouperEntities.description = If the provisioner involves entity objects. This might not be true if you are provisioning memberships or groupAttributes without a target entity link. -config.GenericConfiguration.attribute.selectAllEntities.label = Select all entities -config.GenericConfiguration.attribute.selectAllEntities.description = Select false if the target does not allow selecting all entities e.g AWS. config.GenericConfiguration.attribute.selectEntities.label=Sélectionner des entités -config.GenericConfiguration.attribute.selectEntities.description = If entities should be read from the target. Generally this will be 'true' except:
    1. Messages are sent to the target without knowing the state of the target
    2. Provisioning groupAttributes with no entity link
    3. Provisioning membership objects with no entity link
    config.GenericConfiguration.attribute.insertEntities.label=Insérer les entités -config.GenericConfiguration.attribute.insertEntities.description = If provisionable entities in Grouper which do not exist in the target should be created in the target. This will not be true if all the needed entities exist in the target or if the target manages entities it another process. config.GenericConfiguration.attribute.updateEntities.label=Mettre à jour les entités -config.GenericConfiguration.attribute.updateEntities.description = If entity fields and attributes which differ from the target should cause the target data to be updated. This does not include the membership attribute if the membership provisioning type if entityAttributes. config.GenericConfiguration.attribute.deleteEntities.label=Supprimer les entités -config.GenericConfiguration.attribute.deleteEntities.description = If you want to delete entities in the target. Note, there are a few types of "deletes" you can choose from if you select "true", you must pick which delete option below. config.GenericConfiguration.attribute.deleteEntitiesIfNotExistInGrouper.label=Supprimer les entités si elles n'existent pas dans Grouper config.GenericConfiguration.attribute.deleteEntitiesIfNotExistInGrouper.description=Supprimer toutes les entités de la cible qui sont sélectionnées dans l’opération "Sélectionner toutes les entités" qui ne sont pas approvisionné par Grouper dans la cible. Cela signifie que Grouper fait autorité sur les entités. config.GenericConfiguration.attribute.deleteEntitiesIfGrouperDeleted.label=Supprimer les entités si supprimées dans Grouper -config.GenericConfiguration.attribute.deleteEntitiesIfGrouperDeleted.description = This is the "medium" knob. Only delete an entity if the entity was provisionable now is not. This means that entities that existed before the provisioner existed, or entities that were added only in the target (not in Grouper), will not be removed. config.GenericConfiguration.attribute.deleteEntitiesIfGrouperCreated.label=Supprimer les entités s'ils ont été créé par Grouper -config.GenericConfiguration.attribute.deleteEntitiesIfGrouperCreated.description = Delete entities if Grouper provisioned the entity at some point in the past and the entity was removed as provisionable in Grouper. -config.GenericConfiguration.attribute.subjectSourcesToProvision.label=Sources des sujets à approvisionner +config.GenericConfiguration.attribute.subjectSourcesToProvision.label=Sources des sujets à utiliser config.GenericConfiguration.attribute.subjectSourcesToProvision.description=Généralement, vous ne sélectionnerez que vos sources « personnes ». Si un sujet ne figure dans aucune des sources sélectionnées, il n'est pas considéré comme provisionnable. -config.GenericConfiguration.attribute.hasSubjectLink.label=A un lien de sujet -config.GenericConfiguration.attribute.hasSubjectLink.description=Si le subjectId ou le subjectIdentifier principal est nécessaire pour effectuer l'approvisionnement, vous n'avez pas besoin de lien d'objet. Si vous avez besoin de plus d'attributs de sujet, alors vous avez besoin d'un lien de sujet pour rechercher l'attribut de sujet à partir de l'API de sujet. config.GenericConfiguration.attribute.hasTargetEntityLink.label=A un lien d'entité cible -config.GenericConfiguration.attribute.hasTargetEntityLink.description = "Entity link" is when memberships refer to some data that does not exist in Grouper or the Subject API and needs to be retrieved from the target Entity object. This data is cached in the "member sync" database table. Here are some examples:
    1. Provisioning membership objects where the entity reference is a target DN or UUID.
    2. Provisioning groupAttributes where the entity value is a target DN or UUID
    config.GenericConfiguration.attribute.numberOfEntityAttributes.label=Nombre d'attributs d'entité -config.GenericConfiguration.attribute.targetEntityAttribute.i.name.label=__i+1__ - nom -config.GenericConfiguration.attribute.targetEntityAttribute.i.name.description = Attribute name is the key in the key/value pairs for this entity -config.GenericConfiguration.attribute.targetEntityAttribute.i.isFieldElseAttribute.label=__i+1__ - champ ou attribut -config.GenericConfiguration.attribute.option.targetEntityAttribute.i.isFieldElseAttribute.trueLabel=Champ -config.GenericConfiguration.attribute.option.targetEntityAttribute.i.isFieldElseAttribute.falseLabel=Attribut -config.GenericConfiguration.attribute.option.targetEntityAttribute.i.attributePrefix=attr -config.GenericConfiguration.attribute.option.targetEntityAttribute.i.fieldPrefix=Champ -config.GenericConfiguration.attribute.targetEntityAttribute.i.isFieldElseAttribute.description=Il existe des champs d'entité par défaut : id, loginId, subjectId, name, email. Les attributs peuvent avoir des noms libres. Consultez la documentation du type de fournisseur pour voir quels champs ou attributs sont pris en charge. -config.GenericConfiguration.attribute.targetEntityAttribute.i.fieldName.label=__i+1__ - nom -config.GenericConfiguration.attribute.targetEntityAttribute.i.fieldName.description = ProvisioningEntity.java field name. +config.GenericConfiguration.attribute.option.targetEntityAttribute.i.attributePrefix=attr -provisioning.helper.variable.grouperProvisioningEntity = grouperProvisioningEntity (ProvisioningEntity.java): this is the Grouper representation of the entity. Fields include: email (needs configuration), id, loginId (needs configuration), name, subjectId. Attributes include: subjectSourceId, description, subjectIdentifier0 -provisioning.helper.variable.gcGrouperSyncMember=gcGrouperSyncMember (GcGrouperSyncMember.java) : c'est l'objet entité "sync". Les champs incluent : memberFromId2, memberFromId3, memberToId2, memberToId3 +provisioning.helper.variable.gcGrouperSyncMember=gcGrouperSyncMember (GcGrouperSyncMember.java) : c'est l'objet entité "sync". Les champs incluent : entityAttributeValueCache0, entityAttributeValueCache1, entityAttributeValueCache2, entityAttributeValueCache3 provisioning.helper.variable.provisioningEntityWrapper=provisioningEntityWrapper (ProvisioningGroupWrapper.java) : contient des références à toutes les données d'entité. Les champs incluent : créer, supprimer, recalc, gcGrouperSyncMember, grouperProvisioningEntity, grouperTargetEntity, targetProvisioningEntity, targetNativeEntity provisioning.helper.variable.grouperTargetEntity=grouperTargetEntity (ProvisioningEntity.java) : en général, il n'est pas nécessaire car il est construit par le processus de traduction. Les champs et les attributs dépendent du fournisseur. @@ -12884,47 +13242,23 @@ config.GenericConfiguration.attribute.targetEntityAttribute.i.update.label=__i+1 config.GenericConfiguration.attribute.targetEntityAttribute.i.update.description=Cet attribut devrait être modifié lors de la mise à jour du groupe. config.GenericConfiguration.attribute.targetEntityAttribute.i.ignoreIfMatchesValue.label=__i+1__ - ignorer si cela correspond à la valeur config.GenericConfiguration.attribute.targetEntityAttribute.i.ignoreIfMatchesValue.description=Si le champ d'entité ou la valeur d'attribut correspond à l'une de ces valeurs, ignorez-la (ne pas supprimer ni mettre à jour). Valeurs séparées par des virgules, la virgule échappée est U+002C -config.GenericConfiguration.attribute.targetEntityAttribute.i.matchingId.label=__i+1__ - identifiant correspondant -config.GenericConfiguration.attribute.targetEntityAttribute.i.matchingId.description = The "matching id" is the attribute that is used to match up target objects with Grouper objects. If the matching ID is something opaque like the subjectId then objects can be more reliably renamed. config.GenericConfiguration.attribute.targetEntityAttribute.i.multiValued.label=__i+1__ - attribut à plusieurs valeurs -config.GenericConfiguration.attribute.targetEntityAttribute.i.multiValued.description = If this attribute is multi-valued in the target. Generally attributes are single-valued. The membership attribute must be multi-valued if provisioning entityAttributes. -config.GenericConfiguration.attribute.targetEntityAttribute.i.membershipAttribute.label=__i+1__ - attribut d'appartenance -config.GenericConfiguration.attribute.targetEntityAttribute.i.membershipAttribute.description = If this is entityAttribute provisioning and this attribute is multi-valued and holds entries that represents groups/memberships -config.GenericConfiguration.attribute.targetEntityAttribute.i.searchAttribute.label=__i+1__ - attribut de recherche -config.GenericConfiguration.attribute.targetEntityAttribute.i.searchAttribute.description = If this attribute is used to find entities in the target. The search in the target for this entity might just need this attribute name and value or there might be a search filter, and this is the value of the bind variable. config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpressionCreateOnly.label = __i+1__ - translation expression during inserts -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpressionCreateOnly.description = If you have a different translation from Grouper to Target for updates as opposed to inserts, put the insert translation here. Available variables:
    • $$provisioning.helper.variable.grouperProvisioningEntity$$
    • $$provisioning.helper.variable.gcGrouperSyncEntity$$
    • $$provisioning.helper.variable.provisioningEntityWrapper$$
    • $$provisioning.helper.variable.grouperTargetEntity$$
    config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpression.label=__i+1__ - expression de traduction -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpression.description = This is the translation for this attribute from Grouper to Target format during Entity updates and inserts (if not overridden by "insert only" translation). Available variables:
    • $$provisioning.helper.variable.grouperProvisioningEntity$$
    • $$provisioning.helper.variable.gcGrouperSyncEntity$$
    • $$provisioning.helper.variable.provisioningEntityWrapper$$
    • $$provisioning.helper.variable.grouperTargetEntity$$
    config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpressionTypeCreateOnly.label=__i+1__ - insertion de type de traduction uniquement -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpressionTypeCreateOnly.description = If this is a simple translation straight from field, then select GrouperProvisioningEntityField since you do not have to worry about a script typo and the performance is better. Otherwise configure a translation script. -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateFromGrouperProvisioningEntityFieldCreateOnly.label = __i+1__ - translate from grouperProvisioningEntity field insert only -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateFromGrouperProvisioningEntityFieldCreateOnly.description = Select the field from grouperProvisioningEntity to copy data from. id: is the UUID of the entity, email: email address of the user, loginid: netId to log in to systems, name: first and last name, subjectId: should be an opaque unchanging identifier, subjectSourceId: sourceId of the user, description: description that is configured in the subject source, subjectIdentifier0: the first identifier of the subject (might be a netId) config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpressionType.label=__i+1__ - type de traduction -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpressionType.description = If this is a simple translation straight from field, then select GrouperProvisioningEntityField since you do not have to worry about a script typo and the performance is better. Otherwise configure a translation script. -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateFromGrouperProvisioningEntityField.label = __i+1__ - translate from grouperProvisioningEntity field -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateFromGrouperProvisioningEntityField.description = Select the field from grouperProvisioningEntity to copy data from. id: is the UUID of the entity, email: email address of the user, loginid: netId to log in to systems, name: first and last name, subjectId: should be an opaque unchanging identifier, subjectSourceId: sourceId of the user, description: description that is configured in the subject source, subjectIdentifier0: the first identifier of the subject (might be a netId) -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpressionFromMembership.label=__i+1__ - expression de traduction de l'appartenance -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateExpressionFromMembership.description=En règle générale, vous laisserez ce champ vide et utiliserez une "synchronisation des membres à partir du champ". Si vous devez effectuer une traduction, vous pouvez utiliser n'importe quelle variable d'objet d'appartenance config.GenericConfiguration.attribute.targetEntityAttribute.i.defaultValue.label=__i+1__ - valeur par défaut config.GenericConfiguration.attribute.targetEntityAttribute.i.defaultValue.description=Si la valeur ne doit pas être vide dans la cible, répertoriez ici la valeur à affecter au champ/attribut s'il est vide. config.GenericConfiguration.attribute.targetEntityAttribute.i.required.label=__i+1__ - obligatoire -config.GenericConfiguration.attribute.targetEntityAttribute.i.required.description = If this field is required, then the Entity is invalid and will not be provisioned if the value is missing config.GenericConfiguration.attribute.targetEntityAttribute.i.maxlength.label=__i+1__ - longueur maximale config.GenericConfiguration.attribute.targetEntityAttribute.i.maxlength.description=Nombre de caractères maximum pour ce champ. Si ce nombre est dépassé alors l'entité sera invalide et ne sera pas provisionnée config.GenericConfiguration.attribute.targetEntityAttribute.i.validExpression.label=__i+1__ - expression de validation config.GenericConfiguration.attribute.targetEntityAttribute.i.validExpression.description=S’il y a une validation complexe par le script JEXL, saisissez-la ici. Les variables disponibles sont "value" (valeur unique), et "valueMultiple" (valeurs multiples supportées. Renvoie true pour valide ou false pour invalide. Exemple pour voir si la valeur numérique est positive : ${value>0} -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateFromGroupSyncField.label = __i+1__ - Group sync from field -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateFromGroupSyncField.description = If this is a membership attribute for entityAttributes provisioning, then the values can be copied from the group sync object from this field. -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateToMemberSyncField.label = __i+1__ - Member sync to field -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateToMemberSyncField.description = If this is an entity link field/attribute, then copy the target value to this member sync field, and retrieve from the member sync field as a cache during translation for incremental provisioning or during deletes. -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateGrouperToMemberSyncField.label = __i+1__ - Grouper member link field -config.GenericConfiguration.attribute.targetEntityAttribute.i.translateGrouperToMemberSyncField.description = Copy the grouper value to this member sync field, and retrieve from the member sync field during provisioning. config.GenericConfiguration.subSection.metadata.title=Métadonnées config.GenericConfiguration.subSection.metadata.description=Les métadonnées sont des informations supplémentaires attachées aux dossiers, groupes, entités ou appartenances utilisées dans la configuration de l'approvisionnement @@ -12940,7 +13274,6 @@ config.GenericConfiguration.subSection.metadata.i.description=Configurer l'attri config.GenericConfiguration.attribute.metadata.i.name.label=Métadonnées __i+1__ : nom -config.GenericConfiguration.attribute.metadata.i.name.description = name of metadata item. This will be the name in the json attribute and can be assigned to a group, entity, or membership attribute. This must be unique across metadata for this provisioner. Must start with md_
    The label on the screen will be the externalized text key md_metadataName_provisionerConfigId_label
    The description on the screen will be the externalized text key md_metadataName_provisionerConfigId_description config.GenericConfiguration.attribute.metadata.i.showForFolder.label=Métadonnées __i+1__ : afficher pour le dossier config.GenericConfiguration.attribute.metadata.i.showForFolder.description=Cet élément de métadonnées doit s'afficher quand il est marqué sur un dossier comme provisionnable @@ -13001,38 +13334,36 @@ grouperProvisioningObjectMetadataProvisionableRegexLabel=Regex de provision grouperProvisioningObjectMetadataProvisionableRegexDescription=Si vous souhaitez filtrer les groupes dans les dossiers provisionnés par une expression régulière sur leurs noms.
    Valeur par défaut : '${grouperRequestContainer.provisioningContainer.currentGuiGrouperProvisioningAttributeValue.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getProvisionableRegex()}'.
    Si le groupe concorde avec la regex alors il sera provisionné. Si vous utilisez "not matches" alors il sera filtré. Ex :
    folderExtension matches ^.*_someExtension$
    folderName not matches ^.*_someExtension$
    groupExtension matches ^.*_someExtension$
    groupName not matches ^.*_someExtension$ grouperProvisioningObjectMetadataProvisionableRegexError=Erreur : regex invalide. Elle doit être de la forme : folderExtension matches ^.*_someExtension$   folderName not matches ^.*_someExtension   groupExtension matches ^.*_someExtension$   groupName not matches ^.*_someExtension$ -config.LdapProvisionerConfiguration.title=Provisionnement LDAP +config.LdapProvisionerConfiguration.title=LDAP config.LdapProvisionerConfiguration.attribute.ldapExternalSystemConfigId.label=Id config brique externe config.LdapProvisionerConfiguration.attribute.ldapExternalSystemConfigId.description=Sélectionner le LDAP à utiliser pour ce provisionnement. Si le LDAP n'est pas dans la liste, vous pouvez en configurer un nouveau depuis l'interface de configuration d'une brique externe. -config.LdapProvisionerConfiguration.attribute.provisioningType.label=Type de provisonnement LDAP -config.LdapProvisionerConfiguration.attribute.provisioningType.description=groupAttributes : groupe ldap possédant des attributs contenant les membres
    entityAttributes : utilisateur ldap possédant des attributs contenant les membres
    Habituellement, avec un provisionnement LDAP, le type utilisé est groupAttributes. - -config.LdapProvisionerConfiguration.attribute.targetGroupAttribute.i.isFieldElseAttribute.description=$$config.GenericConfiguration.attribute.targetGroupAttribute.i.isFieldElseAttribute.description$$ Le processus de provisionnement du LDAP utilise le champ 'nom' du groupe pour renseigner le DN du groupe. Toutes les autres données des groupes LDAP sont représentées par des attributs. -config.LdapProvisionerConfiguration.attribute.targetGroupAttribute.i.fieldName.description=$$config.GenericConfiguration.attribute.targetGroupAttribute.i.fieldName.description$$ Le champ "nom" est le DN du groupe LDAP. - -config.LdapProvisionerConfiguration.attribute.targetEntityAttribute.i.isFieldElseAttribute.description=$$config.GenericConfiguration.attribute.targetEntityAttribute.i.isFieldElseAttribute.description$$ Le processus de provisionnement du LDAP utilise le champ 'nom' de l'entité pour renseigner le DN de l'entité au sein du LDAP. Toutes les autres données des groupes LDAP sont représentées par des attributs. -config.LdapProvisionerConfiguration.attribute.targetEntityAttribute.i.fieldName.description=$$config.GenericConfiguration.attribute.targetGroupAttribute.i.fieldName.description$$ Le champ "nom" est le DN de l'entité LDAP. +config.LdapProvisionerConfiguration.attribute.provisioningType.label=Type de provisionnement LDAP +config.LdapProvisionerConfiguration.attribute.provisioningType.description=groupAttributes : groupe ldap avec des attributs contenant les appartenances
    entityAttributes : utilisateur ldap avec des attributs contenant les appartenances
    Habituellement, avec un provisionnement LDAP, le type utilisé est groupAttributes. config.LdapProvisionerConfiguration.attribute.userSearchBaseDn.label=Base DN pour la recherche d'entité config.LdapProvisionerConfiguration.attribute.userSearchFilter.label=Filtre de recherche d'entité config.LdapProvisionerConfiguration.attribute.userSearchAllFilter.label=Filtre de recherche de toutes les entités config.LdapProvisionerConfiguration.attribute.groupSearchBaseDn.label=Base DN pour la recherche de groupe config.LdapProvisionerConfiguration.attribute.groupSearchFilter.label=Filtre de recherche de groupe -config.LdapProvisionerConfiguration.attribute.groupSearchFilter.description=Recherche retournant un seul groupe. Vous pouvez utiliser la variable 'targetGroup'. Ex : (&(gidNumber=${targetGroup.retrieveAttributeValue('gidNumber')})(objectClass=groupOfNames)). Remarque : si le filtre de recherche est simplement l'attribut de recherche, vous pouvez laisser ce champ à vide +config.LdapProvisionerConfiguration.attribute.groupSearchFilter.description=Recherche retournant un seul groupe. Vous pouvez utiliser la variable 'targetGroup'. Ex : (&(gidNumber=${targetGroup.retrieveAttributeValue('gidNumber')})(objectClass=groupOfNames)). Remarque : si le filtre de recherche est simplement l'attribut configuré comme attribut de recherche, vous pouvez laisser ce champ à vide config.LdapProvisionerConfiguration.attribute.groupSearchAllFilter.label=Filtre de recherche de tous les groupes +config.LdapProvisionerConfiguration.attribute.groupSearchAllFilter.description=Filtre retournant l'ensemble des groupes. Si vide, par défaut, la recherche utilisera l'attribut configuré comme attribut de recherche et les objectclass, si configuré. Ex : (&(gidNumber=*)(objectClass=posixGroup)(objectClass=top)) + config.LdapProvisionerConfiguration.attribute.allowLdapGroupDnOverride.label=Autoriser la surchage du DN config.LdapProvisionerConfiguration.attribute.allowLdapGroupDnOverride.description=Lorsque un groupe est marqué comme provisionnable, autoriser une valeur différente que celle par défaut pour le DN (afin de provisionner un groupe dans une branche spécifique) config.LdapProvisionerConfiguration.attribute.groupDnType.label=Type de DN de groupe -config.LdapProvisionerConfiguration.attribute.groupRdnAttribute.label=Attribut RDN pour les groupes -config.LdapProvisionerConfiguration.attribute.groupRdnAttribute.description=L'attribut RDN pour les groupes LDAP. Ce menu déroulant est alimenté depuis les attributs de groupe. Renseignez-les puis sélectionner le RDN. Actualiser +config.LdapProvisionerConfiguration.attribute.groupRdnAttribute.label=Attribut RDN des groupes +config.LdapProvisionerConfiguration.attribute.groupRdnAttribute.description=L'attribut RDN pour les groupes LDAP. Ce menu déroulant est alimenté à partir des attributs de groupe (à configurer un peu plus bas). Renseignez-les puis sélectionner le RDN. Actualiser config.LdapProvisionerConfiguration.attribute.folderRdnAttribute.label=Attribut RDN pour les dossiers config.LdapProvisionerConfiguration.attribute.folderRdnAttribute.description=L'attribut RDN à utiliser pour provisionner les dossiers dans le LDAP. Ex : si l'attribut "ou" pour les dossiers et "cn" pour les groupes sont utilisés comme attribut RDN, alors un groupe app:foo:service:policy:foo_user sera provisionné dans le LDAP avec le DN suivant : cn=foo_user,ou=policy,ou=service,ou=foo,ou=app. config.LdapProvisionerConfiguration.attribute.folderObjectClasses.label=Object classes des dossiers config.LdapProvisionerConfiguration.attribute.folderObjectClasses.description=Les objectClass (séparés par une virgule) à ajouter lorsqu'un dossier est provisionné dans le LDAP. -config.SqlProvisionerConfiguration.title=Provisionnement SQL +config.SqlProvisionerConfiguration.title=SQL config.SqlProvisionerConfiguration.attribute.provisioningType.label=Type de provisionnement SQL config.SqlProvisionerConfiguration.attribute.dbExternalSystemConfigId.label=ID config de base de données externe +config.SqlProvisionerConfiguration.attribute.provisioningType.label=Type de provisionnement SQL + config.SqlProvisionerConfiguration.attribute.membershipTableName.label=Nom de la table des appartenances config.SqlProvisionerConfiguration.attribute.membershipSearchQuery.label=Requête utilisée pour rechercher les appartenances @@ -13042,7 +13373,6 @@ config.SqlProvisionerConfiguration.attribute.userSearchQuery.label=Requête de r config.SqlProvisionerConfiguration.attribute.insertEntities.label=Insérer les entités config.SqlProvisionerConfiguration.attribute.groupTableName.label=Nom de la table de groupe -config.SqlProvisionerConfiguration.attribute.groupPrimaryKey.label=Clé primaire de groupe config.SqlProvisionerConfiguration.attribute.groupSearchQuery.label=Requête de recherche de groupe provisioning.configuration.validation.mustHaveEntityMembershipAttribute=Erreur : ce provisionnement alimente des entityAttributes mais vous n'avez pas de champ d'entité ni d'attribut utilisé pour l'appartenance. Merci d'indiquer un champ d'entité ou d'attribut @@ -13075,29 +13405,9 @@ provisioning.configuration.validation.groupIdOfUsersToProvisionNotExist=Erreur : provisionerConfigurationSaveErrorMetadataNotValidFormat=Le nom d'une métadonnée doit commencer par md_ et ne peut contenir que des caractères alphanumériques et des tirets-bas. provisionerConfigurationSaveErrorMetadataDefaultValueNotCorrectType=La valeur par défaut doit être du type sélectionné '$$selectedType$$'. -provisioning.configuration.validation.idRequired = Error: group field 'id' is required. It represents the group id -provisioning.configuration.validation.groupNameString = Error: group field 'name' must be value type 'string'. It represents the group name -provisioning.configuration.validation.idString = Error: group field 'id' must be value type 'string'. It represents the group id -provisioning.configuration.validation.entityLoginIdRequired = Error: entity field 'loginId' is required. It represents the username -provisioning.configuration.validation.entityLoginIdString = Error: entity field 'loginId' must be value type 'string'. It represents the username - -provisioning.configuration.validation.groupFieldRequired = Error: group field '$$fieldName$$' is required. It represents the group $$fieldName$$ -provisioning.configuration.validation.entityFieldRequired = Error: entity field '$$fieldName$$' is required. It represents the entity $$fieldName$$ -provisioning.configuration.validation.groupFieldString = Error: group field '$$fieldName$$' must be value type 'string'. It represents the group $$fieldName$$ -provisioning.configuration.validation.entityFieldString = Error: entity field '$$fieldName$$' must be value type 'string'. It represents the entity $$fieldName$$ -provisioning.configuration.validation.groupAttributeString = Error: group attribute '$$attributeName$$' must be value type 'string'. It represents the group $$attributeName$$ -provisioning.configuration.validation.entityAttributeString = Error: entity attribute '$$attributeName$$' must be value type 'string'. It represents the entity $$attributeName$$ -provisioning.configuration.validation.groupMoreThanTwoFields = Error: groups cannot have more than two fields configured. -provisioning.configuration.validation.entityMoreThanFourFields = Error: entities cannot have more than four fields configured. -provisioning.configuration.validation.entityMoreThanOneField = Error: entities cannot have more than one field configured. -provisioning.configuration.validation.entityMoreThanTwelveAttributes = Error: entities cannot have more than 12 attributes configured for this provisioner type. -provisioning.configuration.validation.incorrectGroupAttributeConfigured = Error: only one group attribute can be configured and that must be 'description' -provisioning.configuration.validation.incorrectDuoEntityAttributeConfigured = Error: only two entity attributes can be configured and they must be 'firstname' and 'lastname' -provisioning.configuration.validation.incorrectAWSEntityAttributeConfigured = Error: only 12 entity attributes can be configured. -provisioning.configuration.validation.incorrectEntityFieldsConfigured = Error: only four entity fields can be configured and they must be 'id', 'loginId', 'name' and 'email' - -config.GrouperScim2Configuration.title=Provisionnement SCIM 2 -config.GrouperScim2Configuration.attribute.bearerTokenExternalSystemConfigId.label=id brique externe du bearer token + +config.GrouperScim2Configuration.title=SCIM2 +config.GrouperScim2Configuration.attribute.bearerTokenExternalSystemConfigId.label=id connecteur externe du bearer token config.GrouperScim2Configuration.attribute.scimType.label = SCIM type config.GrouperScim2Configuration.attribute.scimType.description = SCIM type @@ -13109,7 +13419,6 @@ config.GenericConfiguration.attribute.replaceMemberships.description=Si les memb -config.AzureProvisionerConfiguration.attribute.targetGroupAttribute.i.fieldName.description=Plusieurs champs embarqués qui correspondent à des attributs Azure @@ -13163,12 +13472,13 @@ config.GenericConfiguration.attribute.param.netId.value.description=Sélectionne config.GenericConfiguration.attribute.enabled.label=Activé config.GenericConfiguration.attribute.enabled.description=Activé -config.GenericConfiguration.attribute.id.label=ID source de sujet -config.GenericConfiguration.attribute.id.description=L'ID source de sujet est l'identifiant utilisé au sein du code, de l'API, des tâche...Il doit être à la fois alphanumérique, court et compréhensible. Ex : pennperson -config.GenericConfiguration.attribute.name.label=Nom de la source de sujet -config.GenericConfiguration.attribute.name.description=Le nom de la source de sujet est le nom utilisé pour l'affichage (ex : menu déroulant dans l'UI). Il peut contenir des espaces, des accents... -config.GenericConfiguration.attribute.types.label=Types -config.GenericConfiguration.attribute.types.description=Les types ne sont pas utilisés actuellement. Choisissez "person" si votre source contient en majorité des personnes ou 'application' si elle contient plutôt des comptes applicatifs + +config.LdapSubjectSourceConfiguration.attribute.id.label=ID source de sujet +config.LdapSubjectSourceConfiguration.attribute.id.description=L'ID source de sujet est l'identifiant utilisé au sein du code, de l'API, des tâche...Il doit être à la fois alphanumérique, court et compréhensible. Ex : pennperson +config.LdapSubjectSourceConfiguration.attribute.name.label=Nom de la source de sujet +config.LdapSubjectSourceConfiguration.attribute.name.description=Le nom de la source de sujet est le nom utilisé pour l'affichage (ex : menu déroulant dans l'UI). Il peut contenir des espaces, des accents... +config.LdapSubjectSourceConfiguration.attribute.types.label=Types +config.LdapSubjectSourceConfiguration.attribute.types.description=Les types ne sont pas utilisés actuellement. Choisissez "person" si votre source contient en majorité des personnes ou 'application' si elle contient plutôt des comptes applicatifs config.GenericConfiguration.attribute.param.maxResults.value.label=Taille max des resultats config.GenericConfiguration.attribute.param.maxResults.value.description=Taille max des resultats @@ -13344,7 +13654,7 @@ adminDaemonJobsHomeBreadcrumb=Accueil adminDaemonJobsBreadcrumb=Toutes les tâches # breadcrumb on the daemon logs screen -adminDaemonLogsBreadcrumb=Tâches périodiques +adminDaemonLogsBreadcrumb=Tâches planifiées # title of daemon jobs adminDaemonJobsTitle=Toutes les tâches @@ -13425,9 +13735,9 @@ adminDaemonJobsColumnTooltipMoreActions=Actions proposées pour cette tâche adminDaemonJobsCronDescriptionError=Erreur : impossible de charger la chaîne du cron Quartz # various states -adminDaemonJobsStateRunning=RUNNING -adminDaemonJobsStateEnabled=ENABLED -adminDaemonJobsStateDisabled=DISABLED +adminDaemonJobsStateRunning=EN COURS +adminDaemonJobsStateEnabled=ACTIVÉ +adminDaemonJobsStateDisabled=DÉSACTIVÉ # more actions ariaLabelGuiMoreDaemonJobActions=Montrer plus d'actions pour cette tâche @@ -13435,7 +13745,8 @@ adminDaemonJobsMoreActionsDefaultText=Actions de la tâche adminDaemonJobsMoreActionsRunNow=Exécuter la tâche maintenant adminDaemonJobsMoreActionsDisable=Désactiver la tâche adminDaemonJobsMoreActionsEnable=Activer la tâche -adminDaemonJobsMoreActionsLogs=Visualiser les journaux des tâches périodiques +adminDaemonJobsMoreActionsLogs=Visualiser les journaux des tâches planifiées +adminDaemonJobsMoreActionsDelete = Supprimer # daemon jobs change log pending in queue daemonJobsChangeLogPendingInQueue=Tâches en attente : @@ -13464,6 +13775,9 @@ daemonJobsResetButton=Réinitialiser # if no results found daemonJobsNoResultsFound=Aucun résultat +# if no results found +daemonJobConfigNotFound = Erreur : configuration introuvable pour la tâche ${grouperRequestContainer.adminContainer.daemonJobName} + # next refresh daemonJobsNextRefresh=Prochain rafraichissement : @@ -13471,11 +13785,27 @@ daemonJobsNextRefresh=Prochain rafraichissement : daemonJobsMaxRefreshesReached=Nombre max de rafraichissement atteint # description at the top of log screen -daemonJobsViewLogsTitle=Logs des tâches périodiques - +daemonJobsViewLogsTitle=Logs des tâches planifiées # if there are logs daemonJobsViewLogsDescription=Journaux ${grouperUtil.length(grouperRequestContainer.adminContainer.guiHib3GrouperLoaderLogs)} trouvés pour tâche : ${grouperRequestContainer.adminContainer.guiDaemonJobs.get(0).jobName} +# aria label accessibility for more actions for daemon +daemonJobsMoreActionsAria = Voir les actions liés aux tâches + +# more actions button +daemonJobsViewMoreActionsButton = Actions sur la tâche + +# all daemon jobs button +daemonJobsButtonAllDaemonJobs = Toutes les tâches + +# add daemon +daemonJobsAddDaemon = Ajouter une tâche + +# edit daemon +daemonJobsEditDaemon = Modifier une tâche + +daemonNameLabel = Tâche + grouperDaemonConfigEnableLabel=Activé # error that config id is required @@ -13488,8 +13818,7 @@ grouperDaemonConfigCreateErrorConfigIdRequired=Erreur : ID Config est obligatoir # Last updated tooltip label adminJobHistoryTooltipLastUpdated=Dernière mise à jour -# Elapsed tooltip label -adminJobHistoryTooltipElapsed = Elapsed + ######################################## ## Admin menu subject API diagnostics @@ -13690,15 +14019,17 @@ grouperLoaderGroupManagedByLoaderSummary=Résumé : {0} grouperLoaderIsNotGrouperLoader=Aucune tâche de synchronisation configuré pour ce groupe. Cliquez sur [Plus] pour en configurer une. # description at top of group loader -grouperLoaderEditConfiguration=Modifier la configuration +grouperLoaderEditConfiguration=Modifier # LDAP or SQL grouperLoaderSourceType=Type de source grouperLoaderLdap=LDAP grouperLoaderSql=SQL grouperLoaderRecentMemberships=Appartenances récentes +grouperLoaderJexlScript = JEXL script grouperLoaderSourceType__SQL=extrait les membres depuis une base de données SQL. grouperLoaderSourceType__LDAP=extrait les membres depuis un annuaire LDAP. +grouperLoaderSourceType__JEXL_SCRIPT = Récupère les membres depuis un script JEXL. grouperLoaderSourceType__RECENT_MEMBERSHIPS=Récupère les membres à partir des appartenances récentes d'un groupe grouperLoaderSourceType__=extrait les membres depuis une base de données SQL, d'un annuaire LDAP ou depuis les dernières appartenances d'un groupe @@ -13964,7 +14295,7 @@ grouperLoaderStatus_CONFIG_ERROR=Erreur de configuration grouperLoaderStatus_SUBJECT_PROBLEMS=Problèmes de sujet # drop down for view loader settings -grouperLoaderMoreActionsViewLoader=Afficher la configuration +grouperLoaderMoreActionsViewLoader=Afficher # drop down for view loader logs grouperLoaderMoreActionsViewLoaderLogs=Afficher les journaux @@ -14052,7 +14383,7 @@ grouperLoaderLogsShowSubjobs=Sous-tâche : grouperLoaderLogsShowSubjobsLabel=Voir les sous-tâches grouperLoaderLogsShowSubjobsTooltip=Une tâche qui synchronise plusieurs groupes a une ligne de sous-tâche pour chacun de ces groupes. Cocher cette case permet d'afficher aussi ces lignes. grouperLoaderLogsShowStatus=Status: -grouperLoaderLogsNumberOfRows=Nombre de lignes: +grouperLoaderLogsNumberOfRows=Nombre de lignes : grouperLoaderLogsCannotParseDate=Impossible de traiter la date : grouperLoaderLogsCannotParseNumberOfRows=Impossible de traiter le nombre de lignes : grouperLoaderLogsNumberOfRowsOverMax=Le nombre maximum de ligne est : @@ -14273,7 +14604,7 @@ attributeDefAttributeAssignmentsTitle=Assignation d'attributs attributeDefAttributeAssignmentsDescription=Assignation d'attributs # more actions on attribute def more actions panel -attributeDefViewMoreActionsButton=Plus d'actions +attributeDefViewMoreActionsButton=Actions sur l'attribut # save button on attribute def assignment screen attributeDefAssignSaveButton=Sauvegarder @@ -14379,6 +14710,9 @@ membershipAssignAttributeAttributeDefDescription=La définition d'un attribut re # attribute name label membershipAssignAttributeAttributeDefNameLabel=Nom d'attribut : +# group label +membershipAssignAttributeGroupLabel = Groupe : + # attribute name description membershipAssignAttributeAttributeDefNameDescription=L'attribut est la partie qui est assigné à l'objet. Généralement plusieurs attributs sont liés à une définition d'attribut. @@ -14492,7 +14826,10 @@ miscellaneousConfigureBreadcrumb=Configuration miscellaneousConfigurationFilesBreadcrumb=Fichiers de configuration # breadcrumb for grouper external systems -miscellaneousGrouperExternalSystemsBreadcrumb=Briques externes +miscellaneousGrouperExternalSystemsBreadcrumb=Connecteurs externes + +# breadcrumb for provisioner configs +miscellaneousProvisionerConfigurationsBreadcrumb=Provisionnement # breadcrumb for provisioner config run full sync miscellaneousProvisionerConfigRunFullSyncBreadcrumb=Exécuter la synchronisation complète @@ -14513,7 +14850,7 @@ miscellaneousConfigurationMainDescription=Fichiers de configuration miscellaneousConfigurationHistoryMainDescription=Historique des modifications # header for grouper external systems -miscellaneousGrouperExternalSystemsMainDescription=Briques externes à Grouper +miscellaneousGrouperExternalSystemsMainDescription=Connecteurs externes à Grouper # configuration description below the h1 miscellaneousConfigurationMainSubtitle = Paramétrage de Grouper. Les changements prennent quelques minutes à s'appliquer sur l'ensemble des JVM connecté à cette base de données. @@ -14612,7 +14949,7 @@ configurationMustExtendClass=, doit hériter de la classe Java : configurationMustImplementInterface=, doit implémenter l'interface Java : # if base value is different put here -configurationBaseValueIfDifferent=Valeur par défaut : +configurationBaseValueIfDifferent=Par défaut : # if unprocessed value is different configurationUnprocessedValueIfDifferentLabel=Valeur non traitée : diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/Group.java b/grouper/src/grouper/edu/internet2/middleware/grouper/Group.java index a222aadd4db1..97865a64ccf2 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/Group.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/Group.java @@ -47,6 +47,7 @@ import static edu.internet2.middleware.grouper.hooks.examples.GroupTypeTupleIncludeExcludeHook.systemOfRecordExtensionSuffix; import java.sql.Timestamp; +import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -1436,7 +1437,37 @@ public Object callback(GrouperTransaction grouperTransaction) } //if a date didnt match up, then save the membership if (hasChange) { - GrouperDAOFactory.getFactory().getMembership().update(membership); + HibernateSession.callbackHibernateSession( + GrouperTransactionType.READ_WRITE_OR_USE_EXISTING, AuditControl.WILL_AUDIT, + new HibernateHandler() { + + public Object callback(HibernateHandlerBean hibernateHandlerBean) + throws GrouperDAOException { + GrouperDAOFactory.getFactory().getMembership().update(membership); + + if (!hibernateHandlerBean.isCallerWillCreateAudit()) { + + SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd h:mm a"); + String enabledTimeString = membership.getEnabledTime() == null ? null : sdf.format(membership.getEnabledTime()); + String disabledTimeString = membership.getDisabledTime() == null ? null : sdf.format(membership.getDisabledTime()); + + AuditEntry auditEntry = new AuditEntry(AuditTypeBuiltin.MEMBERSHIP_GROUP_UPDATE, "id", + membership.getUuid(), "fieldId", field.getUuid(), + "fieldName", field.getName(), "memberId", membership.getMemberUuid(), + "membershipType", membership.getType(), + "groupId", Group.this.getUuid(), "groupName", Group.this.getName()); + + auditEntry.setDescription("Updated membership: group: " + Group.this.getName() + + ", subject: " + subject.getSource().getId() + "." + subject.getId() + ", field: " + + field.getName() + + ", enabledTime: " + enabledTimeString + + ", disabledTime: " + disabledTimeString); + auditEntry.saveOrUpdate(true); + } + + return null; + } + }); } return hasChange; } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/GroupFinder.java b/grouper/src/grouper/edu/internet2/middleware/grouper/GroupFinder.java index 2a1c94fb2f7a..205af528edee 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/GroupFinder.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/GroupFinder.java @@ -1303,7 +1303,7 @@ public Set findGroups() { this.subjectNotInGroup, this.groupIds, this.groupNames, this.compositeOwner, this.attributeDefNameId, this.attributeValue, this.attributeValuesOnAssignment, this.attributeCheckReadOnAttributeDef, this.attributeDefNameId2, this.attributeValue2, - this.attributeValuesOnAssignment2, this.attributeNotAssigned); + this.attributeValuesOnAssignment2, this.attributeNotAssigned, this.excludeAlternateNames); } @@ -1427,6 +1427,11 @@ public GroupFinder assignStemScope(Scope theStemScope) { */ private Set attributeValuesOnAssignment2; + /** + * whether to exclude alternate names from name/scope search + */ + private boolean excludeAlternateNames = false; + /** * if we are looking up a group, only look by uuid or name * @param theFindByUuidOrName @@ -1509,5 +1514,15 @@ public GroupFinder assignAttributeValuesOnAssignment2(Set theValues) { return this; } + /** + * whether to exclude alternate names from name/scope search + * @param excludeAlternateNames + * @return + */ + public GroupFinder assignExcludeAlternateNames(boolean excludeAlternateNames) { + this.excludeAlternateNames = excludeAlternateNames; + return this; + } + } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/GroupSave.java b/grouper/src/grouper/edu/internet2/middleware/grouper/GroupSave.java index c9553edb159d..7da1fbff01c4 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/GroupSave.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/GroupSave.java @@ -592,6 +592,10 @@ public Group save() this.groupNameToEdit = this.name; } + if (StringUtils.isBlank(this.name)) { + this.name = this.groupNameToEdit; + } + //validate //get the stem name if (!StringUtils.contains(GroupSave.this.name, ":")) { diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/StemFinder.java b/grouper/src/grouper/edu/internet2/middleware/grouper/StemFinder.java index e2eec41bcfe9..a4ab2767bc8b 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/StemFinder.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/StemFinder.java @@ -747,12 +747,17 @@ public StemFinder assignFindByUuidOrName(boolean theFindByUuidOrName) { * find groups with this value */ private Object attributeValue2; - + /** * find stems that don't have a certain type assigned */ private boolean attributeNotAssigned = false; - + + /** + * whether to exclude alternate names from name/scope search + */ + private boolean excludeAlternateNames = false; + /** * find stems that don't have a certain type assigned * @param attributeNotAssigned @@ -763,6 +768,16 @@ public StemFinder assignAttributeNotAssigned(boolean attributeNotAssigned) { return this; } + /** + * whether to exclude alternate names from name/scope search + * @param excludeAlternateNames + * @return + */ + public StemFinder assignExcludeAlternateNames(boolean excludeAlternateNames) { + this.excludeAlternateNames = excludeAlternateNames; + return this; + } + /** * config key for caching */ @@ -903,7 +918,7 @@ public Set findStems() { this.attributeDefNameId, this.attributeValue, this.attributeCheckReadOnAttributeDef, this.attributeValuesOnAssignment, this.attributeDefNameId2, this.attributeValue2, this.attributeValuesOnAssignment2, - this.attributeNotAssigned); + this.attributeNotAssigned, this.excludeAlternateNames); for (Stem stem : GrouperUtil.nonNull(stems)) { stemFlashCacheAddIfSupposedTo(stem); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/SubjectFinder.java b/grouper/src/grouper/edu/internet2/middleware/grouper/SubjectFinder.java index f3f6a6da4aaa..1075a75ae77c 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/SubjectFinder.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/SubjectFinder.java @@ -173,6 +173,21 @@ public SubjectFinder assignAllowUnresolvable(boolean theAllowUnresolvable) { return this; } + /** + * whether to ignore cached subjects + */ + private boolean ignoreCachedSubjects = false; + + /** + * whether to ignore cached subjects, false by default + * @param ignoreCachedSubjects + * @return self for chaining + */ + public SubjectFinder assignIgnoreCachedSubjects(boolean ignoreCachedSubjects) { + this.ignoreCachedSubjects = ignoreCachedSubjects; + return this; + } + /** * assign subject id or identifier to search for * @param theSubjectIdOrIdentifier @@ -267,23 +282,23 @@ public Subject findSubject() { private Subject findSubjectHelper() { if (!StringUtils.isBlank(this.subjectId)) { if (!StringUtils.isBlank(this.sourceId)) { - return SubjectFinder.findByIdAndSource(this.subjectId, this.sourceId, false); + return SubjectFinder.findByIdAndSource(this.subjectId, this.sourceId, this.ignoreCachedSubjects, false); } - return SubjectFinder.findById(this.subjectId, false); + return SubjectFinder.findById(this.subjectId, this.ignoreCachedSubjects, false); } if (!StringUtils.isBlank(this.subjectIdentifier)) { if (!StringUtils.isBlank(this.sourceId)) { - return SubjectFinder.findByIdentifierAndSource(this.subjectIdentifier, this.sourceId, false); + return SubjectFinder.findByIdentifierAndSource(this.subjectIdentifier, this.sourceId, this.ignoreCachedSubjects, false); } - return SubjectFinder.findByIdentifier(this.subjectId, false); + return SubjectFinder.findByIdentifier(this.subjectId, this.ignoreCachedSubjects, false); } if (!StringUtils.isBlank(this.subjectIdOrIdentifier)) { if (!StringUtils.isBlank(this.sourceId)) { - return SubjectFinder.findByIdOrIdentifierAndSource(this.subjectIdOrIdentifier, this.sourceId, false); + return SubjectFinder.findByIdOrIdentifierAndSource(this.subjectIdOrIdentifier, this.sourceId, this.ignoreCachedSubjects, false); } - return SubjectFinder.findByIdOrIdentifier(this.subjectIdOrIdentifier, false); + return SubjectFinder.findByIdOrIdentifier(this.subjectIdOrIdentifier, this.ignoreCachedSubjects, false); } if (!StringUtils.isBlank(this.memberId)) { @@ -376,8 +391,22 @@ public static boolean isUseThreadsBasedOnThreadLocal() { */ public static Subject findByIdOrIdentifier(String idOrIdentifier, boolean exceptionIfNull) throws SubjectNotFoundException, SubjectNotUniqueException { + return findByIdOrIdentifier(idOrIdentifier, false, exceptionIfNull); + } + + /** + * find by id or identifier + * @param idOrIdentifier + * @param ignoreCachedSubjects + * @param exceptionIfNull if SubjectNotFoundException or null + * @return the subject + * @throws SubjectNotFoundException + * @throws SubjectNotUniqueException + */ + public static Subject findByIdOrIdentifier(String idOrIdentifier, boolean ignoreCachedSubjects, boolean exceptionIfNull) + throws SubjectNotFoundException, SubjectNotUniqueException { try { - return getResolver().findByIdOrIdentifier(idOrIdentifier); + return getResolver().findByIdOrIdentifier(idOrIdentifier, ignoreCachedSubjects); } catch (SubjectNotFoundException snfe) { if (exceptionIfNull) { throw snfe; @@ -434,8 +463,23 @@ public static Subject findByOptionalArgs(String sourceId, String subjectId, Stri */ public static Subject findByIdOrIdentifierAndSource(String idOrIdentifier, String source, boolean exceptionIfNull) throws SubjectNotFoundException, SubjectNotUniqueException { + return findByIdOrIdentifierAndSource(idOrIdentifier, source, false, exceptionIfNull); + } + + /** + * find by id or identifier + * @param idOrIdentifier + * @param source + * @param ignoreCachedSubjects + * @param exceptionIfNull if SubjectNotFoundException or null + * @return the subject + * @throws SubjectNotFoundException + * @throws SubjectNotUniqueException + */ + public static Subject findByIdOrIdentifierAndSource(String idOrIdentifier, String source, boolean ignoreCachedSubjects, boolean exceptionIfNull) + throws SubjectNotFoundException, SubjectNotUniqueException { try { - return getResolver().findByIdOrIdentifier(idOrIdentifier, source); + return getResolver().findByIdOrIdentifier(idOrIdentifier, source, ignoreCachedSubjects); } catch (SubjectNotFoundException snfe) { if (exceptionIfNull) { throw snfe; @@ -528,10 +572,36 @@ public static Subject findById(String id) * @throws SubjectNotUniqueException */ public static Subject findById(String id, boolean exceptionIfNull) + throws SubjectNotFoundException, + SubjectNotUniqueException { + return findById(id, false, exceptionIfNull); + } + + /** + * Search within all configured sources for subject with identified by id. + *
    +   * try {
    +   *   Subject subj = SubjectFinder.findById(subjectID);
    +   * }
    +   * catch (SubjectNotFoundException eSNF)  {
    +   *   // Subject not found
    +   * }
    +   * catch (SubjectNotUniqueException eSNU) {
    +   *   // Subject not unique
    +   * }
    +   *  
    + * @param id Subject ID + * @param ignoreCachedSubjects + * @param exceptionIfNull + * @return A {@link Subject} object + * @throws SubjectNotFoundException + * @throws SubjectNotUniqueException + */ + public static Subject findById(String id, boolean ignoreCachedSubjects, boolean exceptionIfNull) throws SubjectNotFoundException, SubjectNotUniqueException { try { - return getResolver().find(id); + return getResolver().find(id, ignoreCachedSubjects); } catch (SubjectNotFoundException snfe) { if (exceptionIfNull) { throw snfe; @@ -561,11 +631,38 @@ public static Subject findById(String id, boolean exceptionIfNull) * @throws SubjectNotUniqueException */ public static Subject findByIdAndSource(String id, String source, boolean exceptionIfNull) + throws SubjectNotFoundException, + SubjectNotUniqueException { + return findByIdAndSource(id, source, false, exceptionIfNull); + } + + /** + * Search within all configured sources for subject with identified by id. + *
    +   * try {
    +   *   Subject subj = SubjectFinder.findByIdAndSource(subjectID, source, true);
    +   * }
    +   * catch (SubjectNotFoundException eSNF)  {
    +   *   // Subject not found
    +   * }
    +   * catch (SubjectNotUniqueException eSNU) {
    +   *   // Subject not unique
    +   * }
    +   *  
    + * @param id Subject ID + * @param source is the source to check in + * @param ignoreCachedSubjects + * @param exceptionIfNull + * @return A {@link Subject} object + * @throws SubjectNotFoundException + * @throws SubjectNotUniqueException + */ + public static Subject findByIdAndSource(String id, String source, boolean ignoreCachedSubjects, boolean exceptionIfNull) throws SubjectNotFoundException, SubjectNotUniqueException { try { - return getResolver().find(id, source); + return getResolver().find(id, source, ignoreCachedSubjects); } catch (SubjectNotFoundException snfe) { if (exceptionIfNull) { throw snfe; @@ -1364,9 +1461,36 @@ public static Subject findById(String id, String type, String source, boolean ex public static Subject findByIdentifier(String id, boolean exceptionIfNotFound) throws SubjectNotFoundException, SubjectNotUniqueException + { + return findByIdentifier(id, false, exceptionIfNotFound); + } + + /** + * Get a subject by a well-known identifier. + *
    +   * try {
    +   *   Subject subj = SubjectFinder.findByIdentifier(identifier);
    +   * }
    +   * catch (SubjectNotFoundException eSNF)  {
    +   *   // Subject not found
    +   * }
    +   * catch (SubjectNotUniqueException eSNU) {
    +   *   // Subject not unique
    +   * }
    +   *  
    + * @param id Subject identifier. + * @param ignoreCachedSubjects + * @param exceptionIfNotFound + * @return A {@link Subject} object + * @throws SubjectNotFoundException + * @throws SubjectNotUniqueException + */ + public static Subject findByIdentifier(String id, boolean ignoreCachedSubjects, boolean exceptionIfNotFound) + throws SubjectNotFoundException, + SubjectNotUniqueException { try { - return getResolver().findByIdentifier(id); + return getResolver().findByIdentifier(id, ignoreCachedSubjects); } catch (SubjectNotFoundException snfe) { if (exceptionIfNotFound) { throw snfe; @@ -1492,11 +1616,40 @@ public static Set findBySubjectsInGroup(GrouperSession grouperSession, * @throws SubjectNotUniqueException */ public static Subject findByIdentifierAndSource(String identifier, String source, boolean exceptionIfNull) + throws SourceUnavailableException, + SubjectNotFoundException, + SubjectNotUniqueException { + return findByIdentifierAndSource(identifier, source, false, exceptionIfNull); + } + + /** + * Get a subject by a well-known identifier, and source. + *

    + * NOTE: This method does not perform any caching. + *

    + *
    +   * try {
    +   *   Subject subj = SubjectFinder.findByIdentifierAndSource(id, source, true);
    +   * }
    +   * catch (SubjectNotFoundException e) {
    +   *   // Subject not found
    +   * }
    +   *  
    + * @param identifier Well-known identifier. + * @param source {@link Source} adapter to search. + * @param ignoreCachedSubjects + * @param exceptionIfNull + * @return A {@link Subject} object + * @throws SourceUnavailableException + * @throws SubjectNotFoundException + * @throws SubjectNotUniqueException + */ + public static Subject findByIdentifierAndSource(String identifier, String source, boolean ignoreCachedSubjects, boolean exceptionIfNull) throws SourceUnavailableException, SubjectNotFoundException, SubjectNotUniqueException { try { - return getResolver().findByIdentifier(identifier, source); + return getResolver().findByIdentifier(identifier, source, ignoreCachedSubjects); } catch (SubjectNotFoundException snfe) { if (exceptionIfNull) { throw snfe; @@ -1873,9 +2026,22 @@ public static Map findByIds(Collection ids, String sour * not be in the result */ public static Map findByIds(Collection ids, String source, boolean resolveAsLazySubjects) { + return findByIds(ids, source, resolveAsLazySubjects, false); + } + + /** + * find subjects by ids + * @param ids + * @param source + * @param resolveAsLazySubjects + * @param ignoreCachedSubjects + * @return the map of id to subject. If a subject is not found, it will + * not be in the result + */ + public static Map findByIds(Collection ids, String source, boolean resolveAsLazySubjects, boolean ignoreCachedSubjects) { if (!resolveAsLazySubjects) { - return getResolver().findByIds(ids, source); + return getResolver().findByIds(ids, source, ignoreCachedSubjects); } // Fetch members directly from the database @@ -1900,14 +2066,13 @@ public static Map findByIds(Collection ids, String sour } } - Map subjectsFromResolver = getResolver().findByIds(subjectIdsNotFoundInMembersTable, source); + Map subjectsFromResolver = getResolver().findByIds(subjectIdsNotFoundInMembersTable, source, ignoreCachedSubjects); result.putAll(subjectsFromResolver); return result; } - /** * find subjects by ids * @param ids @@ -1917,6 +2082,19 @@ public static Map findByIds(Collection ids, String sour * not be in the result */ public static Map findBySourceIdsAndSubjectIds(Collection sourceIdsSubjectIds, boolean resolveAsLazySubjects) { + return findBySourceIdsAndSubjectIds(sourceIdsSubjectIds, resolveAsLazySubjects, false); + } + + /** + * find subjects by ids + * @param ids + * @param source + * @param resolveAsLazySubjects + * @parma ignoreCachedSubjects + * @return the map of id to subject. If a subject is not found, it will + * not be in the result + */ + public static Map findBySourceIdsAndSubjectIds(Collection sourceIdsSubjectIds, boolean resolveAsLazySubjects, boolean ignoreCachedSubjects) { Map sourceIdSubjectIdToSubject = new HashMap(); @@ -1942,7 +2120,7 @@ public static Map findBySourceIdsAndSubjectIds(Collection subjectIds = sourceIdToSubjectIds.get(sourceId); - Map subjectIdToSubject = findByIds(subjectIds, sourceId, resolveAsLazySubjects); + Map subjectIdToSubject = findByIds(subjectIds, sourceId, resolveAsLazySubjects, ignoreCachedSubjects); for (Subject subject : GrouperUtil.nonNull(subjectIdToSubject).values()) { sourceIdSubjectIdToSubject.put(new MultiKey(sourceId, subject.getId()), subject); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/azure/AzureProvisioningStartWith.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/azure/AzureProvisioningStartWith.java index 0daf9a2114bc..b4fa42062cf2 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/azure/AzureProvisioningStartWith.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/azure/AzureProvisioningStartWith.java @@ -11,6 +11,7 @@ import edu.internet2.middleware.grouper.app.config.GrouperConfigurationModuleAttribute; import edu.internet2.middleware.grouper.app.provisioning.ProvisionerStartWithBase; import edu.internet2.middleware.grouper.cfg.text.GrouperTextContainer; +import edu.internet2.middleware.grouper.util.GrouperUtil; import edu.internet2.middleware.grouperClientExt.org.apache.commons.lang3.StringUtils; /** @@ -27,7 +28,93 @@ public String getPropertyValueThatIdentifiesThisConfig() { public void populateProvisionerConfigurationValuesFromStartWith( Map startWithSuffixToValue, Map provisionerSuffixToValue) { - // TODO Auto-generated method stub + + provisionerSuffixToValue.put("azureExternalSystemConfigId", startWithSuffixToValue.get("azureExternalSystemConfigId")); + + if ( StringUtils.isNotBlank(startWithSuffixToValue.get("userAttributesType")) && !StringUtils.equals(startWithSuffixToValue.get("userAttributesType"), "core")) { + provisionerSuffixToValue.put("entityResolver.entityAttributesNotInSubjectSource", "true"); + } + + { + int numberOfGroupAttributes = 0; + + provisionerSuffixToValue.put("operateOnGrouperGroups", "true"); + provisionerSuffixToValue.put("targetGroupAttribute."+numberOfGroupAttributes+".name", startWithSuffixToValue.get("groupDisplayNameAttributeValue")); + numberOfGroupAttributes++; + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("useGroupDescription"), true)) { + provisionerSuffixToValue.put("targetGroupAttribute."+numberOfGroupAttributes+".name", "description"); + numberOfGroupAttributes++; + } + + provisionerSuffixToValue.put("targetGroupAttribute."+numberOfGroupAttributes+".name", startWithSuffixToValue.get("mailNicknameAttributeValue")); + numberOfGroupAttributes++; + + provisionerSuffixToValue.put("numberOfGroupAttributes", numberOfGroupAttributes); + } + + { + int numberOfMetadataItems = 0; + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("hasMetadataForGroupType"), true)) { + numberOfMetadataItems++; + provisionerSuffixToValue.put("metadata.0.name", "md_groupType"); + provisionerSuffixToValue.put("metadata.0.showForGroup", "true"); + } + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("hasMetadataForAllowOnlyMembersToPost"), true)) { + numberOfMetadataItems++; + provisionerSuffixToValue.put("metadata.1.name", "md_allowOnlyMembersToPost"); + provisionerSuffixToValue.put("metadata.1.showForGroup", "true"); + } + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("hasMetadataForHideGroupInOutlook"), true)) { + numberOfMetadataItems++; + provisionerSuffixToValue.put("metadata.2.name", "md_hideGroupInOutlook"); + provisionerSuffixToValue.put("metadata.2.showForGroup", "true"); + } + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("hasMetadataForSubscribeNewGroupMembers"), true)) { + numberOfMetadataItems++; + provisionerSuffixToValue.put("metadata.3.name", "md_subscribeNewGroupMembers"); + provisionerSuffixToValue.put("metadata.3.showForGroup", "true"); + } + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("hasMetadataForWelcomeEmailDisabled"), true)) { + numberOfMetadataItems++; + provisionerSuffixToValue.put("metadata.4.name", "md_welcomeEmailDisabled"); + provisionerSuffixToValue.put("metadata.4.showForGroup", "true"); + } + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("hasMetadataForResourceProvisioningOptionsTeams"), true)) { + numberOfMetadataItems++; + provisionerSuffixToValue.put("metadata.5.name", "md_resourceProvisioningOptionsTeams"); + provisionerSuffixToValue.put("metadata.5.showForGroup", "true"); + } + + if (numberOfMetadataItems > 0) { + provisionerSuffixToValue.put("configureMetadata", "true"); + } + } + + { + int numberOfEntityAttributes = 0; + + provisionerSuffixToValue.put("operateOnGrouperEntities", "true"); + provisionerSuffixToValue.put("targetEntityAttribute."+numberOfEntityAttributes+".name", startWithSuffixToValue.get("entityUserPrincipalName")); + numberOfEntityAttributes++; + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("useGroupDescription"), true)) { + provisionerSuffixToValue.put("targetGroupAttribute."+numberOfEntityAttributes+".name", "description"); + numberOfEntityAttributes++; + } + + provisionerSuffixToValue.put("targetGroupAttribute."+numberOfEntityAttributes+".name", startWithSuffixToValue.get("mailNicknameAttributeValue")); + numberOfEntityAttributes++; + + provisionerSuffixToValue.put("numberOfGroupAttributes", numberOfEntityAttributes); + } + } @@ -45,6 +132,8 @@ public Map screenRedraw(Map suffixToValue, result.put("manageEntitiesInAzure", "true"); } else if (StringUtils.equals(valueUserEnteredOnScreen, "manageGroupsReadonlyEntities")) { result.put("manageEntitiesInAzure", "false"); + } else if (StringUtils.equals(valueUserEnteredOnScreen, "other")) { + result.clear(); } } } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/config/GrouperConfigurationModuleAttribute.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/config/GrouperConfigurationModuleAttribute.java index 00b580d5cac6..3bcbe48c7e52 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/config/GrouperConfigurationModuleAttribute.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/config/GrouperConfigurationModuleAttribute.java @@ -406,12 +406,22 @@ public Object getObjectValueAllowInvalid() { } + private boolean show; + + + public void setShow(boolean show) { + this.show = show; + } + /** * * @return if show */ public boolean isShow() { - + + if (this.show) { + return true; + } { Boolean showOverride = this.grouperConfigModule.showAttributeOverride(this.configSuffix); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/config/GrouperConfigurationModuleBase.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/config/GrouperConfigurationModuleBase.java index f3780d5d7fda..dea36c3c722c 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/config/GrouperConfigurationModuleBase.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/config/GrouperConfigurationModuleBase.java @@ -26,6 +26,7 @@ import org.apache.commons.logging.Log; import edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioner; import edu.internet2.middleware.grouper.cfg.dbConfig.CheckboxValueDriver; import edu.internet2.middleware.grouper.cfg.dbConfig.ConfigFileMetadata; import edu.internet2.middleware.grouper.cfg.dbConfig.ConfigFileName; @@ -1169,7 +1170,7 @@ private GrouperConfigurationModuleAttribute buildConfigurationModuleAttribute( return grouperConfigModuleAttribute; } - protected void populateValuesLabelsFromOptionValueClass( + public void populateValuesLabelsFromOptionValueClass( Map attributesSoFar, GrouperConfigurationModuleAttribute grouperConfigModuleAttribute) { @@ -1519,7 +1520,7 @@ public String getDocumentation() { if (StringUtils.isNotBlank(documentation)) { String id = GrouperUtil.uniqueId(); String documentationLink = GrouperTextContainer.textOrNull("provisioning.documentationLink"); - return "
    "+documentationLink+"
    "; + return "
    "+documentationLink+"
    "; } return ""; @@ -1548,7 +1549,7 @@ public String getStartWithDocumentation() { if (StringUtils.isNotBlank(documentation)) { String id = GrouperUtil.uniqueId(); String documentationLink = GrouperTextContainer.textOrNull("provisioning.documentationLink"); - return "
    "+documentationLink+"
    "; + return "
    "+documentationLink+"
    "; } return ""; @@ -1630,21 +1631,21 @@ public boolean isMultiple() { public String getCacheAttributePrefix() { if (this.cacheAttributePrefix == null) { - this.cacheAttributePrefix = GrouperTextContainer.textOrNull("config.GenericConfiguration.attribute.option.targetGroupAttribute.i.attributePrefix"); + this.cacheAttributePrefix = this.retrieveText("attribute.option.targetGroupAttribute.i.attributePrefix"); } return cacheAttributePrefix; } public String getCacheEntityAttributePrefix() { if (this.cacheEntityAttributePrefix == null) { - this.cacheEntityAttributePrefix = GrouperTextContainer.textOrNull("config.GenericConfiguration.attribute.option.targetEntityAttribute.i.entityAttributePrefix"); + this.cacheEntityAttributePrefix = this.retrieveText("attribute.option.targetEntityAttribute.i.entityAttributePrefix"); } return cacheEntityAttributePrefix; } public String getCacheMembershipAttributePrefix() { if (this.cacheMembershipAttributePrefix == null) { - this.cacheMembershipAttributePrefix = GrouperTextContainer.textOrNull("config.GenericConfiguration.attribute.option.targetMembershipAttribute.i.membershipAttributePrefix"); + this.cacheMembershipAttributePrefix = this.retrieveText("attribute.option.targetMembershipAttribute.i.membershipAttributePrefix"); } return cacheMembershipAttributePrefix; } @@ -1652,10 +1653,18 @@ public String getCacheMembershipAttributePrefix() { public String getCacheGroupAttributePrefix() { if (this.cacheGroupAttributePrefix == null) { - this.cacheGroupAttributePrefix = GrouperTextContainer.textOrNull("config.GenericConfiguration.attribute.option.targetGroupAttribute.i.groupAttributePrefix"); + this.cacheGroupAttributePrefix = this.retrieveText("attribute.option.targetGroupAttribute.i.groupAttributePrefix"); } return cacheGroupAttributePrefix; } + public String retrieveText(String suffix) { + String label = GrouperTextContainer.textOrNull("config." + this.getClass().getSimpleName() + "." + suffix); + + if (StringUtils.isBlank(label)) { + label = GrouperTextContainer.textOrNull("config.GenericConfiguration." + suffix); + } + return label; + } } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/config/GrouperConfigurationModuleSubSection.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/config/GrouperConfigurationModuleSubSection.java index b4e6049bea48..2808343b717c 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/config/GrouperConfigurationModuleSubSection.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/config/GrouperConfigurationModuleSubSection.java @@ -118,7 +118,7 @@ public String getDocumentation() { if (StringUtils.isNotBlank(documentation)) { String id = GrouperUtil.uniqueId(); String documentationLink = GrouperTextContainer.textOrNull("provisioning.documentationLink"); - return ""+documentationLink+" "; + return ""+documentationLink+" "; } return documentation; diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/daemon/GrouperDaemonOtherJobTableSyncConfiguration.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/daemon/GrouperDaemonOtherJobTableSyncConfiguration.java index 0a2d9f1bb7a1..1c030fb970c1 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/daemon/GrouperDaemonOtherJobTableSyncConfiguration.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/daemon/GrouperDaemonOtherJobTableSyncConfiguration.java @@ -19,7 +19,7 @@ public ConfigFileName getConfigFileName() { // ## tableSync jobs should use class: edu.internet2.middleware.grouper.app.tableSync.TableSyncOtherJob // ## and include a setting to point to the grouperClient config, if not same: otherJob..grouperClientTableSyncConfigKey = key // ## this is the subtype of job to run: otherJob..syncType = fullSyncFull - // ## (can be: fullSyncFull, fullSyncGroupings, fullSyncChangeFlag, incrementalAllColumns, incrementalPrimaryKey) + // ## (can be: fullSyncFull, fullSyncGroups, fullSyncChangeFlag, incrementalAllColumns, incrementalPrimaryKey) // ################################ // // # Object Type Job class @@ -34,7 +34,7 @@ public ConfigFileName getConfigFileName() { // # {valueType: "string"} // # otherJob.membershipSync.grouperClientTableSyncConfigKey = memberships // - // # fullSyncFull, fullSyncGroupings, fullSyncChangeFlag, incrementalAllColumns, incrementalPrimaryKey + // # fullSyncFull, fullSyncGroups, fullSyncChangeFlag, incrementalAllColumns, incrementalPrimaryKey // # {valueType: "string"} // # otherJob.membershipSync.syncType = fullSyncFull diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/DuoMockServiceHandler.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/DuoMockServiceHandler.java index 11f8ed9f9c3d..496565fd8905 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/DuoMockServiceHandler.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/DuoMockServiceHandler.java @@ -257,9 +257,19 @@ public void checkAuthorization(MockServiceRequest mockServiceRequest) { GrouperUtil.assertion(colonIndex != -1, "Need to pass in integrationKey and password in Authorization header"); String integrationKey = credentials.substring(0, colonIndex).trim(); - String configId = GrouperConfig.retrieveConfig().propertyValueStringRequired("grouperTest.duo.mock.configId"); - String expectedIntegrationKey = GrouperConfig.retrieveConfig().propertyValueStringRequired("grouper.duoConnector."+configId+".adminIntegrationKey"); - String adminDomainName = GrouperConfig.retrieveConfig().propertyValueStringRequired("grouper.duoConnector."+configId+".adminDomainName"); + String configId = GrouperConfig.retrieveConfig().propertyValueString("grouperTest.duo.mock.configId"); + if (StringUtils.isBlank(configId)) { + configId = "duo1"; + } + String expectedIntegrationKey = GrouperConfig.retrieveConfig().propertyValueString("grouper.duoConnector."+configId+".adminIntegrationKey"); + if (StringUtils.isBlank(expectedIntegrationKey)) { + expectedIntegrationKey = "DI3GFYRTLYKA0J3E3U1H"; + } + + String adminDomainName = GrouperConfig.retrieveConfig().propertyValueString("grouper.duoConnector."+configId+".adminDomainName"); + if (StringUtils.isBlank(adminDomainName)) { + adminDomainName = "localhost:8080/grouper/mockServices/duo"; + } if (!StringUtils.equals(expectedIntegrationKey, integrationKey)) { throw new RuntimeException("Integration key does not match with what is in grouper config"); } @@ -295,7 +305,10 @@ public void checkAuthorization(MockServiceRequest mockServiceRequest) { String hmacSource = date + "\n" + method + "\n" + adminDomainName + "\n" + path + "\n" + paramsLine; - String adminSecretKey = GrouperConfig.retrieveConfig().propertyValueStringRequired("grouper.duoConnector."+configId+".adminSecretKey"); + String adminSecretKey = GrouperConfig.retrieveConfig().propertyValueString("grouper.duoConnector."+configId+".adminSecretKey"); + if (StringUtils.isBlank(adminSecretKey)) { + adminSecretKey = "PxtwEr5XxxpGHYxj39vQnmjtPKEq1G1rurdwH7N5"; + } String hmac = new HmacUtils(HmacAlgorithms.HMAC_SHA_1, adminSecretKey).hmacHex(hmacSource); if (!StringUtils.equals(hmac, password)) { @@ -332,6 +345,7 @@ public void getUsers(MockServiceRequest mockServiceRequest, MockServiceResponse try { checkAuthorization(mockServiceRequest); } catch (Exception e) { + e.printStackTrace(); mockServiceResponse.setResponseCode(401); return; } @@ -395,6 +409,7 @@ public void getUser(MockServiceRequest mockServiceRequest, MockServiceResponse m try { checkAuthorization(mockServiceRequest); } catch (Exception e) { + e.printStackTrace(); mockServiceResponse.setResponseCode(401); return; } @@ -433,6 +448,7 @@ public void getGroupsByUser(MockServiceRequest mockServiceRequest, MockServiceRe try { checkAuthorization(mockServiceRequest); } catch (Exception e) { + e.printStackTrace(); mockServiceResponse.setResponseCode(401); return; } @@ -502,6 +518,7 @@ public void disassociateGroupFromUser(MockServiceRequest mockServiceRequest, Moc try { checkAuthorization(mockServiceRequest); } catch (Exception e) { + e.printStackTrace(); mockServiceResponse.setResponseCode(401); return; } @@ -623,6 +640,7 @@ public void postUsers(MockServiceRequest mockServiceRequest, MockServiceResponse checkAuthorization(mockServiceRequest); checkRequestContentTypeAndDateHeader(mockServiceRequest); } catch (Exception e) { + e.printStackTrace(); mockServiceResponse.setResponseCode(401); return; } @@ -680,6 +698,7 @@ public void updateUser(MockServiceRequest mockServiceRequest, MockServiceRespons checkAuthorization(mockServiceRequest); checkRequestContentTypeAndDateHeader(mockServiceRequest); } catch (Exception e) { + e.printStackTrace(); mockServiceResponse.setResponseCode(401); return; } @@ -759,6 +778,7 @@ public void postGroups(MockServiceRequest mockServiceRequest, MockServiceRespons checkAuthorization(mockServiceRequest); checkRequestContentTypeAndDateHeader(mockServiceRequest); } catch (Exception e) { + e.printStackTrace(); mockServiceResponse.setResponseCode(401); return; } @@ -800,6 +820,7 @@ public void getGroups(MockServiceRequest mockServiceRequest, MockServiceResponse try { checkAuthorization(mockServiceRequest); } catch (Exception e) { + e.printStackTrace(); mockServiceResponse.setResponseCode(401); return; } @@ -860,6 +881,7 @@ public void getUsersByGroup(MockServiceRequest mockServiceRequest, MockServiceRe try { checkAuthorization(mockServiceRequest); } catch (Exception e) { + e.printStackTrace(); mockServiceResponse.setResponseCode(401); return; } @@ -930,6 +952,7 @@ public void getGroup(MockServiceRequest mockServiceRequest, MockServiceResponse try { checkAuthorization(mockServiceRequest); } catch (Exception e) { + e.printStackTrace(); mockServiceResponse.setResponseCode(401); return; } @@ -969,6 +992,7 @@ public void updateGroup(MockServiceRequest mockServiceRequest, MockServiceRespon checkAuthorization(mockServiceRequest); checkRequestContentTypeAndDateHeader(mockServiceRequest); } catch (Exception e) { + e.printStackTrace(); mockServiceResponse.setResponseCode(401); return; } @@ -1115,6 +1139,7 @@ public void deleteGroups(MockServiceRequest mockServiceRequest, MockServiceRespo try { checkAuthorization(mockServiceRequest); } catch (Exception e) { + e.printStackTrace(); mockServiceResponse.setResponseCode(401); return; } @@ -1148,6 +1173,7 @@ public void deleteUsers(MockServiceRequest mockServiceRequest, MockServiceRespon try { checkAuthorization(mockServiceRequest); } catch (Exception e) { + e.printStackTrace(); mockServiceResponse.setResponseCode(401); return; } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/DuoProvisionerConfiguration.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/DuoProvisionerConfiguration.java index 10c38c412399..adac0a0d8a6f 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/DuoProvisionerConfiguration.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/DuoProvisionerConfiguration.java @@ -1,14 +1,44 @@ package edu.internet2.middleware.grouper.app.duo; +import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.commons.lang3.StringUtils; +import edu.internet2.middleware.grouper.app.provisioning.ProvisionerStartWithBase; import edu.internet2.middleware.grouper.app.provisioning.ProvisioningConfiguration; import edu.internet2.middleware.grouper.cfg.dbConfig.ConfigFileName; +import edu.internet2.middleware.grouper.util.GrouperUtil; public class DuoProvisionerConfiguration extends ProvisioningConfiguration { + + public final static Set startWithConfigClassNames = new LinkedHashSet(); + + static { + startWithConfigClassNames.add(DuoProvisioningStartWith.class.getName()); + } + + @Override + public List getStartWithConfigClasses() { + + List result = new ArrayList(); + + for (String className: startWithConfigClassNames) { + try { + Class configClass = (Class) GrouperUtil.forName(className); + ProvisionerStartWithBase config = GrouperUtil.newInstance(configClass); + result.add(config); + } catch (Exception e) { + //TODO + } + } + + return result; + + } @Override public ConfigFileName getConfigFileName() { diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/DuoProvisioningStartWith.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/DuoProvisioningStartWith.java new file mode 100644 index 000000000000..ca4070ceb59f --- /dev/null +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/DuoProvisioningStartWith.java @@ -0,0 +1,114 @@ +package edu.internet2.middleware.grouper.app.duo; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import edu.internet2.middleware.grouper.app.provisioning.ProvisionerStartWithBase; +import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClientExt.org.apache.commons.lang3.StringUtils; + +public class DuoProvisioningStartWith extends ProvisionerStartWithBase { + + @Override + public String getPropertyValueThatIdentifiesThisConfig() { + return "duoCommon"; + } + + @Override + public void populateProvisionerConfigurationValuesFromStartWith( + Map startWithSuffixToValue, + Map provisionerSuffixToValue) { + + provisionerSuffixToValue.put("duoExternalSystemConfigId", startWithSuffixToValue.get("duoExternalSystemConfigId")); + + if ( StringUtils.isNotBlank(startWithSuffixToValue.get("userAttributesType")) && !StringUtils.equals(startWithSuffixToValue.get("userAttributesType"), "core")) { + provisionerSuffixToValue.put("entityResolver.entityAttributesNotInSubjectSource", "true"); + } + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("manageGroups"), false)) { + + provisionerSuffixToValue.put("operateOnGrouperGroups", "true"); + provisionerSuffixToValue.put("numberOfGroupAttributes", 1); + + provisionerSuffixToValue.put("targetGroupAttribute.0.name", startWithSuffixToValue.get("groupNameAttributeValue")); + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("useGroupDescription"), true)) { + provisionerSuffixToValue.put("numberOfGroupAttributes", 2); + provisionerSuffixToValue.put("targetGroupAttribute.1.name", "description"); + } + + } + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("manageEntities"), false)) { + + provisionerSuffixToValue.put("operateOnGrouperEntities", "true"); + int numberOfEntityAttributes = 1; + + provisionerSuffixToValue.put("targetEntityAttribute.0.name", startWithSuffixToValue.get("entityUserName")); + + if (StringUtils.isNotBlank(startWithSuffixToValue.get("entityNameSubjectAttribute"))) { + numberOfEntityAttributes++; + provisionerSuffixToValue.put("targetEntityAttribute.1.name", startWithSuffixToValue.get("entityNameSubjectAttribute")); + } + + if (StringUtils.isNotBlank(startWithSuffixToValue.get("entityFirstNameSubjectAttribute"))) { + numberOfEntityAttributes++; + provisionerSuffixToValue.put("targetEntityAttribute.2.name", startWithSuffixToValue.get("entityFirstNameSubjectAttribute")); + } + + if (StringUtils.isNotBlank(startWithSuffixToValue.get("entityEmailSubjectAttribute"))) { + numberOfEntityAttributes++; + provisionerSuffixToValue.put("targetEntityAttribute.3.name", startWithSuffixToValue.get("entityEmailSubjectAttribute")); + } + + provisionerSuffixToValue.put("numberOfEntityAttributes", numberOfEntityAttributes); + + } + + + + } + + @Override + public Map screenRedraw(Map suffixToValue, + Set suffixesUserJustChanged) { + + Map result = new HashMap<>(); + + for (String suffixUserJustChanged: suffixesUserJustChanged) { + + if (StringUtils.equals(suffixUserJustChanged, "duoPattern")) { + String valueUserEnteredOnScreen = suffixToValue.get(suffixUserJustChanged); + if (StringUtils.equals(valueUserEnteredOnScreen, "manageGroupsManageEntities")) { + result.put("manageGroups", "true"); + result.put("manageEntities", "true"); + } else if (StringUtils.equals(valueUserEnteredOnScreen, "manageGroupsReadonlyEntities")) { + result.put("manageGroups", "true"); + result.put("manageEntities", "false"); + } else if (StringUtils.equals(valueUserEnteredOnScreen, "manageEntities")) { + result.put("manageGroups", "false"); + result.put("manageEntities", "true"); + } + else if (StringUtils.equals(valueUserEnteredOnScreen, "other")) { + result.clear(); + } + } + } + + return result; + } + + @Override + public void validatePreSave(boolean isInsert, List errorsToDisplay, Map validationErrorsToDisplay) { + + super.validatePreSave(isInsert, errorsToDisplay, validationErrorsToDisplay); + + if (errorsToDisplay.size() > 0 || validationErrorsToDisplay.size() > 0) { + return; + } + + } + +} diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/role/DuoRoleMockServiceHandler.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/role/DuoRoleMockServiceHandler.java index 1a9814fba0ac..b8e30bb5a287 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/role/DuoRoleMockServiceHandler.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/role/DuoRoleMockServiceHandler.java @@ -628,7 +628,7 @@ private static ObjectNode toUserJson(GrouperDuoRoleUser grouperDuoRoleUser) { GrouperUtil.jsonJacksonAssignString(result, "email", grouperDuoRoleUser.getEmail()); GrouperUtil.jsonJacksonAssignString(result, "name", grouperDuoRoleUser.getName()); - GrouperUtil.jsonJacksonAssignString(result, "role", grouperDuoRoleUser.getName()); + GrouperUtil.jsonJacksonAssignString(result, "role", grouperDuoRoleUser.getRole()); GrouperUtil.jsonJacksonAssignString(result, "admin_id", grouperDuoRoleUser.getId()); return result; diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/role/DuoRoleProvisoningConfigurationValidation.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/role/DuoRoleProvisoningConfigurationValidation.java index 57ac5eabfc66..91e413cccdc0 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/role/DuoRoleProvisoningConfigurationValidation.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/role/DuoRoleProvisoningConfigurationValidation.java @@ -11,17 +11,10 @@ * */ public class DuoRoleProvisoningConfigurationValidation extends GrouperProvisioningConfigurationValidation { - - @Override - public Collection validateGroupAttributeNamesAllowed() { - return GrouperUtil.toSet("description"); - - } @Override public Collection validateGroupAttributeNamesRequired() { - return GrouperUtil.toSet("name", "id"); - + return GrouperUtil.toSet("role"); } @Override @@ -29,14 +22,9 @@ public boolean validateGroupAttributesRequireString() { return true; } - @Override - public Collection validateEntityAttributeNamesAllowed() { - return GrouperUtil.toSet("name", "email", "firstname", "lastname"); - } - @Override public Collection validateEntityAttributeNamesRequired() { - return GrouperUtil.toSet("id", "loginId"); + return GrouperUtil.toSet("email", "id", "name", "role"); } @Override diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/role/GrouperDuoRoleUser.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/role/GrouperDuoRoleUser.java index 016a5bdc9cf7..9f35e3fbd460 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/role/GrouperDuoRoleUser.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/duo/role/GrouperDuoRoleUser.java @@ -50,7 +50,7 @@ public static GrouperDuoRoleUser fromProvisioningEntity(ProvisioningEntity targe if (GrouperUtil.length(roles) > 1) { throw new RuntimeException("Only one role is allowed: "+targetEntity); } - grouperDuoUser.setRole(targetEntity.retrieveAttributeValueString("role")); + grouperDuoUser.setRole(GrouperUtil.length(roles) == 1? (String)roles.iterator().next(): null); } return grouperDuoUser; @@ -60,7 +60,7 @@ public static GrouperDuoRoleUser fromProvisioningEntity(ProvisioningEntity targe public ProvisioningEntity toProvisioningEntity() { ProvisioningEntity targetEntity = new ProvisioningEntity(); - targetEntity.assignAttributeValue("role", this.role); + targetEntity.addAttributeValue("role", this.role); targetEntity.setId(this.id); targetEntity.setEmail(this.email); targetEntity.setName(this.name); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/externalSystem/GrouperExternalSystem.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/externalSystem/GrouperExternalSystem.java index e6b428b41b1f..291af820e3ae 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/externalSystem/GrouperExternalSystem.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/externalSystem/GrouperExternalSystem.java @@ -71,23 +71,23 @@ public String propertiesApiProperyValue(String attributeName) { public final static Set externalTypeClassNames = new LinkedHashSet(); static { + externalTypeClassNames.add("edu.internet2.middleware.grouperMessagingActiveMQ.ActiveMqGrouperExternalSystem"); externalTypeClassNames.add(AzureGrouperExternalSystem.class.getName()); - externalTypeClassNames.add(LdapGrouperExternalSystem.class.getName()); - externalTypeClassNames.add(GoogleGrouperExternalSystem.class.getName()); - externalTypeClassNames.add("edu.internet2.middleware.grouper.o365.Office365GrouperExternalSystem"); externalTypeClassNames.add("edu.internet2.middleware.grouperBox.BoxGrouperExternalSystem"); + externalTypeClassNames.add("edu.internet2.middleware.grouper.app.loader.db.DatabaseGrouperExternalSystem"); externalTypeClassNames.add("edu.internet2.middleware.grouperDuo.DuoGrouperExternalSystem"); - externalTypeClassNames.add("edu.internet2.middleware.grouperMessagingActiveMQ.ActiveMqGrouperExternalSystem"); - externalTypeClassNames.add("edu.internet2.middleware.grouperMessagingRabbitmq.RabbitMqGrouperExternalSystem"); - externalTypeClassNames.add("edu.internet2.middleware.grouperMessagingAWS.SqsGrouperExternalSystem"); - externalTypeClassNames.add("edu.internet2.middleware.grouper.app.file.SftpGrouperExternalSystem"); - externalTypeClassNames.add(SmtpGrouperExternalSystem.class.getName()); + externalTypeClassNames.add(GoogleGrouperExternalSystem.class.getName()); externalTypeClassNames.add(GrouperInternalMessagingExternalSystem.class.getName()); - externalTypeClassNames.add("edu.internet2.middleware.grouper.app.loader.db.DatabaseGrouperExternalSystem"); + externalTypeClassNames.add(LdapGrouperExternalSystem.class.getName()); + externalTypeClassNames.add("edu.internet2.middleware.grouper.o365.Office365GrouperExternalSystem"); + externalTypeClassNames.add(OidcGrouperExternalSystem.class.getName()); + externalTypeClassNames.add("edu.internet2.middleware.grouperMessagingRabbitmq.RabbitMqGrouperExternalSystem"); externalTypeClassNames.add("edu.internet2.middleware.grouper.app.remedy.RemedyGrouperExternalSystem"); externalTypeClassNames.add("edu.internet2.middleware.grouper.app.remedy.RemedyDigitalMarketplaceGrouperExternalSystem"); + externalTypeClassNames.add("edu.internet2.middleware.grouper.app.file.SftpGrouperExternalSystem"); + externalTypeClassNames.add(SmtpGrouperExternalSystem.class.getName()); + externalTypeClassNames.add("edu.internet2.middleware.grouperMessagingAWS.SqsGrouperExternalSystem"); externalTypeClassNames.add(WsBearerTokenExternalSystem.class.getName()); - externalTypeClassNames.add(OidcGrouperExternalSystem.class.getName()); } /** diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisioningMembershipStartWith.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisioningMembershipStartWith.java index cc995b4e113a..df248a6aabac 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisioningMembershipStartWith.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisioningMembershipStartWith.java @@ -13,9 +13,7 @@ import edu.internet2.middleware.grouper.app.provisioning.ProvisionerStartWithBase; import edu.internet2.middleware.grouper.cfg.text.GrouperTextContainer; import edu.internet2.middleware.grouper.util.GrouperUtil; -import edu.internet2.middleware.grouperClientExt.org.apache.commons.lang3.StringUtils; -import edu.internet2.middleware.subject.Source; -import edu.internet2.middleware.subject.provider.SourceManager; +import org.apache.commons.lang3.StringUtils; /** */ @@ -29,7 +27,314 @@ public String getPropertyValueThatIdentifiesThisConfig() { @Override public void populateProvisionerConfigurationValuesFromStartWith(Map startWithSuffixToValue, Map provisionerSuffixToValue) { - // TODO Auto-generated method stub + + + if (StringUtils.equals(startWithSuffixToValue.get("userAttributesType"), "entityResolver") || StringUtils.equals(startWithSuffixToValue.get("userAttributesType"), "subjectSourceAndEntityResolver")) { + provisionerSuffixToValue.put("entityResolver.entityAttributesNotInSubjectSource", "true"); + } + + if (StringUtils.equals(startWithSuffixToValue.get("userAttributesType"), "subjectSource") + || StringUtils.equals(startWithSuffixToValue.get("userAttributesType"), "subjectSourceAndEntityResolver")) { + provisionerSuffixToValue.put("operateOnGrouperEntities", "true"); + + String attributesCommaSeparated = startWithSuffixToValue.get("subjectSourceEntityResolverAttributes"); + if (StringUtils.isNotBlank(attributesCommaSeparated)) { + provisionerSuffixToValue.put("entityAttributeValueCacheHas", "true"); + String[] attributes = GrouperUtil.splitTrim(attributesCommaSeparated, ","); + // by this time the validation is already done that there are no more than 3 attributes + for (int i=0; i otherLdapAttributes = GrouperUtil.splitTrimToSet(otherGroupLdapAttributes, ","); + + for (String otherLdapAttribute: otherLdapAttributes) { + provisionerSuffixToValue.put("targetGroupAttribute."+groupAttributes+".name", otherLdapAttribute); + + if (StringUtils.equals("description", otherLdapAttribute)) { + provisionerSuffixToValue.put("targetGroupAttribute."+groupAttributes+".translateExpressionType", "grouperProvisioningGroupField"); + provisionerSuffixToValue.put("targetGroupAttribute."+groupAttributes+".translateFromGrouperProvisioningGroupField", "description"); + } + + groupAttributes++; + } + + } + + provisionerSuffixToValue.put("numberOfGroupAttributes", groupAttributes); + + } + + if (StringUtils.equals(startWithSuffixToValue.get("membershipStructure"), "entityAttributes") || + GrouperUtil.booleanValue(startWithSuffixToValue.get("membershipValueDn"), false) || + GrouperUtil.booleanValue(startWithSuffixToValue.get("entityLinkForAnotherReason"), false)) { + + provisionerSuffixToValue.put("operateOnGrouperEntities", "true"); + + provisionerSuffixToValue.put("hasTargetEntityLink", "true"); + + provisionerSuffixToValue.put("operateOnGrouperEntities", "true"); + + provisionerSuffixToValue.put("entityAttributeValueCacheHas", "true"); + provisionerSuffixToValue.put("entityAttributeValueCache0has", "true"); + provisionerSuffixToValue.put("entityAttributeValueCache0source", "target"); + provisionerSuffixToValue.put("entityAttributeValueCache0type", "entityAttribute"); + + provisionerSuffixToValue.put("entityAttributeValueCache0entityAttribute", "ldap_dn"); + + + boolean changeEntitiesInLdap = GrouperUtil.booleanValue(startWithSuffixToValue.get("changeEntitiesInLdap"), false); + + int entityAttributes = 0; + + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".name", "ldap_dn"); + + entityAttributes++; + + if (changeEntitiesInLdap) { + String userRdnAttribute = startWithSuffixToValue.get("userRdnAttribute"); + String rdnValueForEntities = startWithSuffixToValue.get("rdnValueForEntities"); + + + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".name", userRdnAttribute); + + if (StringUtils.equalsAny(rdnValueForEntities, "subjectId", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2")) { + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".translateFromGrouperProvisioningEntityField", rdnValueForEntities); + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".translateExpressionType", "grouperProvisioningEntityField"); + + } else if (StringUtils.equalsAny(rdnValueForEntities, "script")) { + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".translateExpressionType", "translationScript"); + } + + entityAttributes++; + + } + + if (StringUtils.equals(startWithSuffixToValue.get("membershipStructure"), "entityAttributes")) { + + String membershipAttributeNameForEntities = startWithSuffixToValue.get("membershipAttributeNameForEntities"); + + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".name", membershipAttributeNameForEntities); + provisionerSuffixToValue.put("entityMembershipAttributeName", membershipAttributeNameForEntities); + + if (!GrouperUtil.booleanValue(startWithSuffixToValue.get("membershipValueDn"), false)) { + + String membershipValueForEntities = startWithSuffixToValue.get("membershipValueForEntities"); + + } + + entityAttributes++; + + } + + boolean matchingSearchAttributeDifferentThanRDN = false; + if (changeEntitiesInLdap) { + matchingSearchAttributeDifferentThanRDN = GrouperUtil.booleanValue(startWithSuffixToValue.get("matchingSearchAttributeDifferentThanRDN"), false); + } + + provisionerSuffixToValue.put("entityMatchingAttributeCount", "1"); + + if (!changeEntitiesInLdap || matchingSearchAttributeDifferentThanRDN) { + + String matchingSearchAttributeNameForEntities = startWithSuffixToValue.get("matchingSearchAttributeNameForEntities"); + String matchingSearchAttributeValueForEntities = startWithSuffixToValue.get("matchingSearchAttributeValueForEntities"); + + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".name", matchingSearchAttributeNameForEntities); + + if (StringUtils.equalsAny(matchingSearchAttributeValueForEntities, "subjectId", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2")) { + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".translateExpressionType", "grouperProvisioningEntityField"); + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".translateFromGrouperProvisioningEntityField", matchingSearchAttributeValueForEntities); + } else if (StringUtils.equalsAny(matchingSearchAttributeValueForEntities, "script")){ + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".translateExpressionType", "translationScript"); + } + + entityAttributes++; + + provisionerSuffixToValue.put("entityMatchingAttribute0name", matchingSearchAttributeNameForEntities); + + } + + + String objectClassesForEntities = startWithSuffixToValue.get("objectClassesForEntities"); + if (StringUtils.isNotBlank(objectClassesForEntities)) { + + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".name", "objectClass"); + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".translateExpressionType", "staticValues"); + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".translateFromStaticValues", objectClassesForEntities); + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".showAdvancedAttribute", "true"); + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".showAttributeValueSettings", "true"); + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".multiValued", "true"); + entityAttributes++; + } + + String otherEntityLdapAttributes = startWithSuffixToValue.get("otherEntityLdapAttributes"); + if (StringUtils.isNotBlank(otherEntityLdapAttributes)) { + + Set otherLdapAttributes = GrouperUtil.splitTrimToSet(otherEntityLdapAttributes, ","); + + for (String otherLdapAttribute: otherLdapAttributes) { + provisionerSuffixToValue.put("targetEntityAttribute."+entityAttributes+".name", otherLdapAttribute); + entityAttributes++; + } + + } + + + provisionerSuffixToValue.put("numberOfEntityAttributes", entityAttributes); + +// if (StringUtils.equals(startWithSuffixToValue.get("membershipStructure"), "entityAttributes") && +// !GrouperUtil.booleanValue(startWithSuffixToValue.get("membershipValueDn"), false)) { +// +// boolean allowMembershipValueOverride = GrouperUtil.booleanValue(startWithSuffixToValue.get("allowMembershipValueOverride"), false); +// +// } + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("addDisabledFullSyncDaemon"), false) || GrouperUtil.booleanValue(startWithSuffixToValue.get("addDisabledIncrementalSyncDaemon"), false)) { + provisionerSuffixToValue.put("showAdvanced", "true"); + } + + + } + } @@ -61,6 +366,16 @@ public void validatePreSave(boolean isInsert, List errorsToDisplay, Map< } + GrouperConfigurationModuleAttribute subjectSourceEntityResoverModuleAttribute = this.retrieveAttributes().get("subjectSourceEntityResolverAttributes"); + if (subjectSourceEntityResoverModuleAttribute != null && StringUtils.isNotBlank(subjectSourceEntityResoverModuleAttribute.getValue())) { + String commaSeparatedResolverAttributes = subjectSourceEntityResoverModuleAttribute.getValue(); + List list = GrouperUtil.splitTrimToList(commaSeparatedResolverAttributes, ","); + if (list.size() > 3) { + String errorMessage = GrouperTextContainer.textOrNull("subjectSourceEntityResolverAttributesMoreThanThreeAttributes"); + validationErrorsToDisplay.put(subjectSourceEntityResoverModuleAttribute.getHtmlForElementIdHandle(), errorMessage); + } + } + //TODO wait until all source attributes are exposed // list those attributes and validate against subject source (textfield, comma separated attributes, required) // GrouperConfigurationModuleAttribute entityResolverAttributes = this.retrieveAttributes().get("subjectSourceEntityResolverAttributes"); @@ -99,27 +414,27 @@ public Map screenRedraw(Map suffixToValue, Set screenRedraw(Map suffixToValue, Set exceptions = new ArrayList(); + String dn = targetGroup.retrieveAttributeValueString(ldap_dn); + if (targetGroup.getProvisioningGroupWrapper() != null && targetGroup.getProvisioningGroupWrapper().getTargetProvisioningGroup() != null + && !GrouperUtil.isBlank(targetGroup.getProvisioningGroupWrapper().getTargetProvisioningGroup().retrieveAttributeValueString(ldap_dn))) { + dn = targetGroup.getProvisioningGroupWrapper().getTargetProvisioningGroup().retrieveAttributeValueString(ldap_dn); + } + + boolean movedDn = false; for (ProvisioningObjectChange provisionObjectChange : provisionObjectChanges) { String attributeName = provisionObjectChange.getAttributeName(); @@ -365,7 +372,7 @@ public TargetDaoUpdateGroupResponse updateGroup(TargetDaoUpdateGroupRequest targ oldValue = GrouperUtil.stringValue(oldValue); } - if (attributeName == null && LdapProvisioningTargetDao.ldap_dn.equals(attributeName) && action == ProvisioningObjectChangeAction.update) { + if (attributeName != null && LdapProvisioningTargetDao.ldap_dn.equals(attributeName) && action == ProvisioningObjectChangeAction.update) { // this is a rename try { checkParentFolderCaseChanges(ldapSyncConfiguration, (String)oldValue, (String)newValue); @@ -382,7 +389,9 @@ public TargetDaoUpdateGroupResponse updateGroup(TargetDaoUpdateGroupRequest targ throw e; } } - + + movedDn = true; + dn = (String)newValue; deleteEmptyParentFolders(ldapSyncConfiguration, ldapSyncDaoForLdap, (String)oldValue); provisionObjectChange.setProvisioned(true); @@ -409,6 +418,12 @@ public TargetDaoUpdateGroupResponse updateGroup(TargetDaoUpdateGroupRequest targ ldapModificationItems.put(item, provisionObjectChange); } } else if (action == ProvisioningObjectChangeAction.update) { + + // the rdn was already changed + if (movedDn && dn.startsWith(attributeName+"=")) { + continue; + } + if (oldValue != null) { LdapModificationItem item = new LdapModificationItem(LdapModificationType.REMOVE_ATTRIBUTE, new LdapAttribute(attributeName, oldValue)); ldapModificationItems.put(item, provisionObjectChange); @@ -435,7 +450,7 @@ public TargetDaoUpdateGroupResponse updateGroup(TargetDaoUpdateGroupRequest targ } LdapSyncDaoForLdap ldapSyncDaoForLdap = new LdapSyncDaoForLdap(); - LdapModificationResult result = ldapSyncDaoForLdap.modify(ldapConfigId, targetGroup.retrieveAttributeValueString(ldap_dn), new ArrayList(ldapModificationItems.keySet())); + LdapModificationResult result = ldapSyncDaoForLdap.modify(ldapConfigId, dn, new ArrayList(ldapModificationItems.keySet())); if (!hasRenameFailure) { targetGroup.setProvisioned(true); // assume true to start with @@ -511,7 +526,7 @@ public ProvisioningGroup retrieveGroupByDn(String dn, boolean includeAllMembersh groupAttributesMultivalued.add("objectClass"); - String groupAttributeNameForMemberships = ldapSyncConfiguration.getGroupAttributeNameForMemberships(); + String groupAttributeNameForMemberships = ldapSyncConfiguration.getGroupMembershipAttributeName(); if (!StringUtils.isBlank(groupAttributeNameForMemberships)) { if (includeAllMemberships) { groupSearchAttributeNames.add(groupAttributeNameForMemberships); @@ -596,7 +611,7 @@ public TargetDaoRetrieveGroupsResponse retrieveGroups(TargetDaoRetrieveGroupsReq //groupSearchAttributeNames.add("objectClass"); groupAttributesMultivalued.add("objectClass"); - String groupAttributeNameForMemberships = ldapSyncConfiguration.getGroupAttributeNameForMemberships(); + String groupAttributeNameForMemberships = ldapSyncConfiguration.getGroupMembershipAttributeName(); if (!StringUtils.isBlank(groupAttributeNameForMemberships)) { if (includeAllMembershipsIfApplicable) { groupSearchAttributeNames.add(groupAttributeNameForMemberships); @@ -712,7 +727,7 @@ public TargetDaoRetrieveAllEntitiesResponse retrieveAllEntities(TargetDaoRetriev //entitySearchAttributeNames.add("objectClass"); userAttributesMultivalued.add("objectClass"); - String userAttributeNameForMemberships = ldapSyncConfiguration.getEntityAttributeNameForMemberships(); + String userAttributeNameForMemberships = ldapSyncConfiguration.getEntityMembershipAttributeName(); if (!StringUtils.isBlank(userAttributeNameForMemberships)) { if (includeAllMembershipsIfApplicable) { entitySearchAttributeNames.add(userAttributeNameForMemberships); @@ -775,7 +790,7 @@ public TargetDaoRetrieveEntitiesResponse retrieveEntities(TargetDaoRetrieveEntit //entitySelectAttributeNames.add("objectClass"); userAttributesMultivalued.add("objectClass"); - String userAttributeNameForMemberships = ldapSyncConfiguration.getEntityAttributeNameForMemberships(); + String userAttributeNameForMemberships = ldapSyncConfiguration.getEntityMembershipAttributeName(); if (!StringUtils.isBlank(userAttributeNameForMemberships)) { if (includeAllMembershipsIfApplicable) { entitySelectAttributeNames.add(userAttributeNameForMemberships); @@ -812,7 +827,7 @@ public TargetDaoRetrieveEntitiesResponse retrieveEntities(TargetDaoRetrieveEntit searchFilter = "(" + grouperProvisioningConfigurationAttribute.getName() + "=" + GrouperUtil.ldapFilterEscape(value) + ")"; } else { - throw new RuntimeException("Why is groupSearchFilter empty?"); + throw new RuntimeException("Why is entitySearchFilter empty?"); } } @@ -962,10 +977,10 @@ public TargetDaoRetrieveMembershipResponse retrieveMembership(TargetDaoRetrieveM String dn; if (this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.groupAttributes) { - membershipAttributeName = ldapSyncConfiguration.getGroupAttributeNameForMemberships(); + membershipAttributeName = ldapSyncConfiguration.getGroupMembershipAttributeName(); dn = ((ProvisioningGroup)targetDaoRetrieveMembershipRequest.getTargetMembership()).retrieveAttributeValueString(ldap_dn); } else if (this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.entityAttributes) { - membershipAttributeName = ldapSyncConfiguration.getEntityAttributeNameForMemberships(); + membershipAttributeName = ldapSyncConfiguration.getEntityMembershipAttributeName(); dn = ((ProvisioningEntity)targetDaoRetrieveMembershipRequest.getTargetMembership()).retrieveAttributeValueString(ldap_dn); } else { throw new RuntimeException("Unexpected grouperProvisioningBehaviorMembershipType: " + this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType()); @@ -1055,6 +1070,13 @@ public TargetDaoUpdateEntityResponse updateEntity(TargetDaoUpdateEntityRequest t boolean hasRenameFailure = false; List exceptions = new ArrayList(); + String dn = targetEntity.retrieveAttributeValueString(ldap_dn); + if (targetEntity.getProvisioningEntityWrapper() != null && targetEntity.getProvisioningEntityWrapper().getTargetProvisioningEntity() != null + && !GrouperUtil.isBlank(targetEntity.getProvisioningEntityWrapper().getTargetProvisioningEntity().retrieveAttributeValueString(ldap_dn))) { + dn = targetEntity.getProvisioningEntityWrapper().getTargetProvisioningEntity().retrieveAttributeValueString(ldap_dn); + } + + boolean movedDn = false; for (ProvisioningObjectChange provisionObjectChange : provisionObjectChanges) { String attributeName = provisionObjectChange.getAttributeName(); @@ -1074,7 +1096,11 @@ public TargetDaoUpdateEntityResponse updateEntity(TargetDaoUpdateEntityRequest t // this is a rename try { LdapSyncDaoForLdap ldapSyncDaoForLdap = new LdapSyncDaoForLdap(); + newValue = GrouperUtil.stringValue(newValue); + oldValue = GrouperUtil.stringValue(oldValue); ldapSyncDaoForLdap.move(ldapConfigId, (String)oldValue, (String)newValue); + movedDn = true; + dn = (String)newValue; provisionObjectChange.setProvisioned(true); } catch (Exception e) { provisionObjectChange.setProvisioned(false); @@ -1099,6 +1125,11 @@ public TargetDaoUpdateEntityResponse updateEntity(TargetDaoUpdateEntityRequest t ldapModificationItems.put(item, provisionObjectChange); } } else if (action == ProvisioningObjectChangeAction.update) { + // the rdn was already changed + if (movedDn && dn.startsWith(attributeName+"=")) { + continue; + } + if (oldValue != null) { LdapModificationItem item = new LdapModificationItem(LdapModificationType.REMOVE_ATTRIBUTE, new LdapAttribute(attributeName, oldValue)); ldapModificationItems.put(item, provisionObjectChange); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisioningTranslator.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisioningTranslator.java index df8cdefc53e7..72d5ec4c07ce 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisioningTranslator.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisioningTranslator.java @@ -1,5 +1,8 @@ package edu.internet2.middleware.grouper.app.ldapProvisioning; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; @@ -7,6 +10,7 @@ import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningConfigurationAttribute; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningConfigurationAttributeType; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningTranslator; +import edu.internet2.middleware.grouper.app.provisioning.ProvisioningAttribute; import edu.internet2.middleware.grouper.app.provisioning.ProvisioningEntityWrapper; import edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroup; import edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroupWrapper; @@ -17,6 +21,50 @@ */ public class LdapProvisioningTranslator extends GrouperProvisioningTranslator { + /** + * we need the rdn to be evaled before the dn + */ + @Override + public Collection entityTargetAttributesInTranslationOrder() { + + Collection defaultAttributes = super.entityTargetAttributesInTranslationOrder(); + + List result = new ArrayList(); + + GrouperProvisioningConfigurationAttribute dnAttribute = null; + for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : defaultAttributes) { + if (LdapProvisioningTargetDao.ldap_dn.equals(grouperProvisioningConfigurationAttribute.getName())) { + dnAttribute = grouperProvisioningConfigurationAttribute; + } else { + result.add(grouperProvisioningConfigurationAttribute); + } + } + if (dnAttribute != null) { + result.add(dnAttribute); + } + return result; + } + + @Override + public Collection groupAttributesInTranslationOrder() { + + Collection defaultAttributes = super.groupAttributesInTranslationOrder(); + + List result = new ArrayList(); + GrouperProvisioningConfigurationAttribute dnAttribute = null; + for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : defaultAttributes) { + if (LdapProvisioningTargetDao.ldap_dn.equals(grouperProvisioningConfigurationAttribute.getName())) { + dnAttribute = grouperProvisioningConfigurationAttribute; + } else { + result.add(grouperProvisioningConfigurationAttribute); + } + } + if (dnAttribute != null) { + result.add(dnAttribute); + } + return result; + } + @Override public Object attributeTranslation(Object currentValue, Map elVariableMap, boolean forCreate, @@ -28,10 +76,43 @@ public Object attributeTranslation(Object currentValue, Map elVa grouperProvisioningConfigurationAttribute, provisioningGroupWrapper, provisioningEntityWrapper); + String expressionToUse = grouperProvisioningConfigurationAttribute == null ? null : getTargetExpressionToUse(forCreate, grouperProvisioningConfigurationAttribute); + String translateFromGrouperProvisioningEntityField = grouperProvisioningConfigurationAttribute == null ? null : getTranslateFromGrouperProvisioningEntityField(forCreate, grouperProvisioningConfigurationAttribute); + String translateFromGrouperProvisioningGroupField = grouperProvisioningConfigurationAttribute == null ? null : getTranslateFromGrouperProvisioningGroupField(forCreate, grouperProvisioningConfigurationAttribute); + if (grouperProvisioningConfigurationAttribute != null + && !StringUtils.isBlank(translateFromGrouperProvisioningEntityField) + && grouperProvisioningConfigurationAttribute.getGrouperProvisioningConfigurationAttributeType() + == GrouperProvisioningConfigurationAttributeType.entity + && StringUtils.isBlank(expressionToUse) + && LdapProvisioningTargetDao.ldap_dn.equals(grouperProvisioningConfigurationAttribute.getName())) { + + LdapSyncConfiguration ldapSyncConfiguration = (LdapSyncConfiguration) this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration(); + + String userRdnAttributeName = ldapSyncConfiguration.getUserRdnAttribute(); + + if (!StringUtils.isBlank(userRdnAttributeName)) { + String fieldValueString = GrouperUtil.stringValue(attributeValue); + + if (StringUtils.isBlank(fieldValueString)) { + //throw new RuntimeException("Not expecting null DN part! " + provisioningEntityWrapper.getGrouperProvisioningEntity()); + // allow this so a validation can happen not exception + attributeValue = null; + } else { + + String dn = GrouperUtil.ldapEscapeRdn(userRdnAttributeName + "=" + fieldValueString) + "," + ldapSyncConfiguration.getUserSearchBaseDn(); + + attributeValue = dn; + } + } + } + + + if (grouperProvisioningConfigurationAttribute != null + && !StringUtils.isBlank(translateFromGrouperProvisioningGroupField) && grouperProvisioningConfigurationAttribute.getGrouperProvisioningConfigurationAttributeType() == GrouperProvisioningConfigurationAttributeType.group - && !StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningGroupField()) + && StringUtils.isBlank(expressionToUse) && LdapProvisioningTargetDao.ldap_dn.equals(grouperProvisioningConfigurationAttribute.getName())) { String fieldValueString = GrouperUtil.stringValue(attributeValue); @@ -49,11 +130,12 @@ public Object attributeTranslation(Object currentValue, Map elVa dn = provisioningGroupWrapper.getGrouperProvisioningGroup().retrieveAttributeValueString("md_grouper_ldapGroupDnOverride"); } - if (StringUtils.isEmpty(dn)) { + if (StringUtils.isEmpty(dn)) { if (ldapSyncConfiguration.getGroupDnType() == LdapSyncGroupDnType.bushy) { String groupRdnAttributeValue = null; - if (((ProvisioningGroup)elVariableMap.get("grouperTargetGroup")).getAttributes().get(groupRdnAttributeName) != null) { + if (((ProvisioningGroup)elVariableMap.get("grouperTargetGroup")).getAttributes() != null + && ((ProvisioningGroup)elVariableMap.get("grouperTargetGroup")).getAttributes().get(groupRdnAttributeName) != null) { groupRdnAttributeValue = (String)((ProvisioningGroup)elVariableMap.get("grouperTargetGroup")).getAttributes().get(groupRdnAttributeName).getValue(); } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapSyncConfiguration.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapSyncConfiguration.java index 55ec52ffa5dc..fcd31fee38e8 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapSyncConfiguration.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapSyncConfiguration.java @@ -10,6 +10,7 @@ import edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningConfiguration; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningConfigurationAttribute; import edu.internet2.middleware.grouper.util.GrouperUtil; /** @@ -25,7 +26,16 @@ public class LdapSyncConfiguration extends GrouperProvisioningConfiguration { private String folderRdnAttribute; private String groupRdnAttribute; private Set folderObjectClasses; + private String userRdnAttribute; + public String getUserRdnAttribute() { + return userRdnAttribute; + } + + public void setUserRdnAttribute(String userRdnAttribute) { + this.userRdnAttribute = userRdnAttribute; + } + @Override public void configureSpecificSettings() { @@ -37,6 +47,7 @@ public void configureSpecificSettings() { this.userSearchBaseDn = this.retrieveConfigString("userSearchBaseDn", false); this.groupSearchBaseDn = this.retrieveConfigString("groupSearchBaseDn", false); this.groupRdnAttribute = GrouperUtil.defaultIfNull(this.retrieveConfigString("groupRdnAttribute", false), "cn"); + this.userRdnAttribute = this.retrieveConfigString("userRdnAttribute", false); { String groupDnTypeString = this.retrieveConfigString("groupDnType", false); @@ -55,6 +66,70 @@ public void configureSpecificSettings() { } } this.allowLdapGroupDnOverride = GrouperUtil.booleanValue(this.retrieveConfigString("allowLdapGroupDnOverride", false), false); + + { + GrouperProvisioningConfigurationAttribute groupDnAttributeConfig = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().get(LdapProvisioningTargetDao.ldap_dn); + GrouperProvisioningConfigurationAttribute groupRdnAttributeConfig = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().get(this.groupRdnAttribute); + if (groupRdnAttributeConfig != null && groupDnAttributeConfig != null + && StringUtils.isBlank(groupDnAttributeConfig.getTranslateFromStaticValues()) + && StringUtils.isBlank(groupDnAttributeConfig.getTranslateFromStaticValuesCreateOnly()) + && StringUtils.isBlank(groupDnAttributeConfig.getTranslateExpression()) + && StringUtils.isBlank(groupDnAttributeConfig.getTranslateExpressionCreateOnly()) + && StringUtils.isBlank(groupDnAttributeConfig.getTranslateFromGrouperProvisioningGroupField()) + && StringUtils.isBlank(groupDnAttributeConfig.getTranslateFromGrouperProvisioningGroupFieldCreateOnly())) { + for (boolean createOnly : new boolean[] {false, true}) { + String groupAttribute = null; + String rdnTranslateFromGrouperProvisioningGroupField = createOnly ? groupRdnAttributeConfig.getTranslateFromGrouperProvisioningGroupFieldCreateOnly() + : groupRdnAttributeConfig.getTranslateFromGrouperProvisioningGroupField(); + if (StringUtils.isBlank(rdnTranslateFromGrouperProvisioningGroupField)) { + continue; + } + if (StringUtils.equals("name", rdnTranslateFromGrouperProvisioningGroupField)) { + groupAttribute = "name"; + } + if (this.getGroupDnType() == LdapSyncGroupDnType.bushy && StringUtils.equals("extension", rdnTranslateFromGrouperProvisioningGroupField)) { + groupAttribute = "name"; + } + if (this.getGroupDnType() == LdapSyncGroupDnType.flat && StringUtils.equals("extension", rdnTranslateFromGrouperProvisioningGroupField)) { + groupAttribute = "extension"; + } + + if (!StringUtils.isBlank(groupAttribute)) { + if (createOnly) { + groupDnAttributeConfig.setTranslateFromGrouperProvisioningGroupFieldCreateOnly(groupAttribute); + } else { + groupDnAttributeConfig.setTranslateFromGrouperProvisioningGroupField(groupAttribute); + } + } + } + } + } + + if (!StringUtils.isBlank(this.userRdnAttribute)) { + GrouperProvisioningConfigurationAttribute userDnAttributeConfig = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().get(LdapProvisioningTargetDao.ldap_dn); + GrouperProvisioningConfigurationAttribute userRdnAttributeConfig = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().get(this.userRdnAttribute); + if (userRdnAttributeConfig != null && userDnAttributeConfig != null + && StringUtils.isBlank(userDnAttributeConfig.getTranslateFromStaticValues()) + && StringUtils.isBlank(userDnAttributeConfig.getTranslateFromStaticValuesCreateOnly()) + && StringUtils.isBlank(userDnAttributeConfig.getTranslateExpression()) + && StringUtils.isBlank(userDnAttributeConfig.getTranslateExpressionCreateOnly()) + && StringUtils.isBlank(userDnAttributeConfig.getTranslateFromGrouperProvisioningEntityField()) + && StringUtils.isBlank(userDnAttributeConfig.getTranslateFromGrouperProvisioningEntityFieldCreateOnly())) { + for (boolean createOnly : new boolean[] {false, true}) { String userAttribute = null; + String rdnTranslateFromGrouperProvisioningEntityField = createOnly ? userRdnAttributeConfig.getTranslateFromGrouperProvisioningEntityFieldCreateOnly() + : userRdnAttributeConfig.getTranslateFromGrouperProvisioningEntityField(); + if (StringUtils.isBlank(rdnTranslateFromGrouperProvisioningEntityField)) { + continue; + } + if (createOnly) { + userDnAttributeConfig.setTranslateFromGrouperProvisioningEntityFieldCreateOnly(rdnTranslateFromGrouperProvisioningEntityField); + } else { + userDnAttributeConfig.setTranslateFromGrouperProvisioningEntityField(rdnTranslateFromGrouperProvisioningEntityField); + } + } + } + } + } /** diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapSyncConfigurationValidation.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapSyncConfigurationValidation.java index 6fe05eafaf91..d521efd40bae 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapSyncConfigurationValidation.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapSyncConfigurationValidation.java @@ -3,8 +3,11 @@ import org.apache.commons.lang.StringUtils; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioner; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningBehavior; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningConfiguration; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningConfigurationAttribute; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningConfigurationAttributeType; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningConfigurationAttributeValueType; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningConfigurationValidation; import edu.internet2.middleware.grouper.app.provisioning.ProvisioningValidationIssue; import edu.internet2.middleware.grouper.cfg.text.GrouperTextContainer; @@ -47,32 +50,29 @@ public void validateDnSelect() { GrouperProvisioner grouperProvisioner = this.getGrouperProvisioner(); GrouperProvisioningConfiguration grouperProvisioningConfiguration = grouperProvisioner.retrieveGrouperProvisioningConfiguration(); + GrouperProvisioningBehavior grouperProvisioningBehavior = grouperProvisioner.retrieveGrouperProvisioningBehavior(); - if (grouperProvisioningConfiguration.isOperateOnGrouperGroups()) { - if (grouperProvisioningConfiguration.isSelectGroups() || grouperProvisioningConfiguration.isUpdateGroups() || grouperProvisioningConfiguration.isDeleteGroups() || grouperProvisioningConfiguration.isInsertGroups()) { - GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = grouperProvisioningConfiguration.getTargetGroupAttributeNameToConfig().get(LdapProvisioningTargetDao.ldap_dn); - if (grouperProvisioningConfigurationAttribute == null) { - this.addErrorMessage(new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.mustHaveGroupDn"))); - } - if (grouperProvisioningConfiguration.isSelectGroups() && grouperProvisioningConfigurationAttribute != null && !grouperProvisioningConfigurationAttribute.isSelect()) { - this.addErrorMessage(new ProvisioningValidationIssue() - .assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.mustSelectDn")) - .assignJqueryHandle(grouperProvisioningConfigurationAttribute.configKey("select"))); - } + if (grouperProvisioningBehavior.isSelectGroups() || grouperProvisioningBehavior.isUpdateGroups() || grouperProvisioningBehavior.isDeleteGroups() || grouperProvisioningBehavior.isInsertGroups()) { + GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = grouperProvisioningConfiguration.getTargetGroupAttributeNameToConfig().get(LdapProvisioningTargetDao.ldap_dn); + if (grouperProvisioningConfigurationAttribute == null) { + this.addErrorMessage(new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.mustHaveGroupDn"))); + } + if (grouperProvisioningConfiguration.isSelectGroups() && grouperProvisioningConfigurationAttribute != null && !grouperProvisioningConfigurationAttribute.isSelect()) { + this.addErrorMessage(new ProvisioningValidationIssue() + .assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.mustSelectDn")) + .assignJqueryHandle(grouperProvisioningConfigurationAttribute.configKey("select"))); } } - if (grouperProvisioningConfiguration.isOperateOnGrouperEntities()) { - if (grouperProvisioningConfiguration.isSelectEntities() || grouperProvisioningConfiguration.isUpdateEntities() || grouperProvisioningConfiguration.isDeleteEntities() || grouperProvisioningConfiguration.isInsertEntities()) { - GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = grouperProvisioningConfiguration.getTargetEntityAttributeNameToConfig().get(LdapProvisioningTargetDao.ldap_dn); - if (grouperProvisioningConfigurationAttribute == null) { - this.addErrorMessage(new ProvisioningValidationIssue() - .assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.mustHaveEntityDn"))); - } - if (grouperProvisioningConfiguration.isSelectEntities() && grouperProvisioningConfigurationAttribute != null && !grouperProvisioningConfigurationAttribute.isSelect()) { - this.addErrorMessage(new ProvisioningValidationIssue() - .assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.mustSelectDn")) - .assignJqueryHandle(grouperProvisioningConfigurationAttribute.configKey("select"))); - } + if (grouperProvisioningBehavior.isSelectEntities() || grouperProvisioningBehavior.isUpdateEntities() || grouperProvisioningBehavior.isDeleteEntities() || grouperProvisioningBehavior.isInsertEntities()) { + GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = grouperProvisioningConfiguration.getTargetEntityAttributeNameToConfig().get(LdapProvisioningTargetDao.ldap_dn); + if (grouperProvisioningConfigurationAttribute == null) { + this.addErrorMessage(new ProvisioningValidationIssue() + .assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.mustHaveEntityDn"))); + } + if (grouperProvisioningConfiguration.isSelectEntities() && grouperProvisioningConfigurationAttribute != null && !grouperProvisioningConfigurationAttribute.isSelect()) { + this.addErrorMessage(new ProvisioningValidationIssue() + .assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.mustSelectDn")) + .assignJqueryHandle(grouperProvisioningConfigurationAttribute.configKey("select"))); } } @@ -89,8 +89,9 @@ public void validateDnInsertIfInsertObject() { GrouperProvisioner grouperProvisioner = this.getGrouperProvisioner(); GrouperProvisioningConfiguration grouperProvisioningConfiguration = grouperProvisioner.retrieveGrouperProvisioningConfiguration(); + GrouperProvisioningBehavior grouperProvisioningBehavior = grouperProvisioner.retrieveGrouperProvisioningBehavior(); - if (grouperProvisioningConfiguration.isOperateOnGrouperGroups() && grouperProvisioningConfiguration.isInsertGroups()) { + if (grouperProvisioningBehavior.isInsertGroups()) { GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = grouperProvisioningConfiguration.getTargetGroupAttributeNameToConfig().get(LdapProvisioningTargetDao.ldap_dn); if (grouperProvisioningConfigurationAttribute != null && !grouperProvisioningConfigurationAttribute.isInsert()) { this.addErrorMessage(new ProvisioningValidationIssue() @@ -98,7 +99,8 @@ public void validateDnInsertIfInsertObject() { .assignJqueryHandle(grouperProvisioningConfigurationAttribute.configKey("insert"))); } } - if (grouperProvisioningConfiguration.isOperateOnGrouperEntities() && grouperProvisioningConfiguration.isInsertEntities()) { + + if (grouperProvisioningBehavior.isInsertEntities()) { GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = grouperProvisioningConfiguration.getTargetEntityAttributeNameToConfig().get(LdapProvisioningTargetDao.ldap_dn); if (grouperProvisioningConfigurationAttribute != null && !grouperProvisioningConfigurationAttribute.isInsert()) { this.addErrorMessage(new ProvisioningValidationIssue() @@ -111,51 +113,46 @@ public void validateDnInsertIfInsertObject() { /** * make sure attribute names arent re-used - * @param suffixToConfigValue - * @return */ public void validateDnExistsAndString() { - OBJECT_TYPE: for (String objectType: new String[] {"targetGroupAttribute", "targetEntityAttribute"}) { - - String objectTypeLabel = null; - - if (StringUtils.equals(objectType, "targetGroupAttribute") && !GrouperUtil.booleanValue(this.getSuffixToConfigValue().get("selectGroups"), false)) { - continue; - } - if (StringUtils.equals(objectType, "targetEntityAttribute") && !GrouperUtil.booleanValue(this.getSuffixToConfigValue().get("selectEntities"), false)) { - continue; - } - - if (StringUtils.equals("targetGroupAttribute", objectType)) { - objectTypeLabel = GrouperTextContainer.textOrNull("auditsGroup"); - } else if (StringUtils.equals("targetEntityAttribute", objectType)) { - objectTypeLabel = GrouperTextContainer.textOrNull("auditsEntity"); + GrouperProvisioningBehavior grouperProvisioningBehavior = this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior(); + GrouperProvisioningConfiguration grouperProvisioningConfiguration = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration(); + + String objectTypeLabel = null; + + if (grouperProvisioningBehavior.isSelectGroups()) { + objectTypeLabel = GrouperTextContainer.textOrNull("auditsGroup"); + GrouperTextContainer.assignThreadLocalVariable("type", objectTypeLabel); + + GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = grouperProvisioningConfiguration.getTargetGroupAttributeNameToConfig() + .get(LdapProvisioningTargetDao.ldap_dn); + if (grouperProvisioningConfigurationAttribute == null) { + this.addErrorMessage(new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnRequired"))); } else { - throw new RuntimeException("Cant find object type: " + objectType); + if (grouperProvisioningConfigurationAttribute.getValueType() != GrouperProvisioningConfigurationAttributeValueType.STRING) { + this.addErrorMessage(new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnString")) + .assignJqueryHandle(grouperProvisioningConfigurationAttribute.configKey("name"))); + } } + } + + if (grouperProvisioningBehavior.isSelectEntities()) { + objectTypeLabel = GrouperTextContainer.textOrNull("auditsEntity"); GrouperTextContainer.assignThreadLocalVariable("type", objectTypeLabel); - for (int i=0; i< 20; i++) { - // TODO validate DN - // if (i>0) { - // this.addErrorMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnRequired")); - // } - // continue OBJECT_TYPE; - -// String name = this.getSuffixToConfigValue().get(nameConfigKey); -// String type = this.getSuffixToConfigValue().get(objectType + "."+i+".valueType"); -// -// // all good, field with name LdapProvisioningTargetDao.ldap_dn and type string -// if (StringUtils.equals(name, LdapProvisioningTargetDao.ldap_dn)) { -// if (!StringUtils.isBlank(type) && !StringUtils.equalsIgnoreCase(type, "string")) { -// this.addErrorMessageAndJqueryHandle(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnString"), nameConfigKey); -// } -// continue OBJECT_TYPE; -// } - - } + GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = grouperProvisioningConfiguration.getTargetEntityAttributeNameToConfig() + .get(LdapProvisioningTargetDao.ldap_dn); + if (grouperProvisioningConfigurationAttribute == null) { + this.addErrorMessage(new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnRequired"))); + } else { + if (grouperProvisioningConfigurationAttribute.getValueType() != GrouperProvisioningConfigurationAttributeValueType.STRING) { + this.addErrorMessage(new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnString")) + .assignJqueryHandle(grouperProvisioningConfigurationAttribute.configKey("name"))); + } + } } + GrouperTextContainer.resetThreadLocalVariableMap(); } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/loader/GrouperLoaderIncrementalJob.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/loader/GrouperLoaderIncrementalJob.java index 5f6c19d2c337..a2a585f09a7f 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/loader/GrouperLoaderIncrementalJob.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/loader/GrouperLoaderIncrementalJob.java @@ -43,8 +43,6 @@ import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; -import org.quartz.Trigger.TriggerState; -import org.quartz.TriggerKey; import edu.internet2.middleware.grouper.Group; import edu.internet2.middleware.grouper.GroupFinder; @@ -648,15 +646,16 @@ private synchronized static void scheduleJobNow(Group loaderGroup, String groupe Scheduler scheduler = GrouperLoader.schedulerFactory().getScheduler(); List currentTriggers = scheduler.getTriggersOfJob(new JobKey(jobName)); boolean alreadyScheduled = false; - for (Trigger currentTrigger : currentTriggers) { - TriggerKey currentTriggerKey = currentTrigger.getKey(); - if (TriggerState.BLOCKED == scheduler.getTriggerState(currentTriggerKey)) { + for (Trigger currentTrigger : currentTriggers) { + // currentTrigger.getNextFireTime() seems to be null if currently executing + // so this should mean that there's already a trigger that should fire at any time now + if (currentTrigger.getNextFireTime() != null && currentTrigger.getNextFireTime().getTime() <= System.currentTimeMillis()) { alreadyScheduled = true; break; } } - // what if it doesn't get moved to the blocked state quick enough. there really shouldn't be more than 3 triggers. look at this again later. + // there really shouldn't be more than 3 triggers. if (currentTriggers.size() > 2) { alreadyScheduled = true; } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/DeleteOldSyncLogsDaemon.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/DeleteOldSyncLogsDaemon.java new file mode 100644 index 000000000000..98935bb195ee --- /dev/null +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/DeleteOldSyncLogsDaemon.java @@ -0,0 +1,58 @@ +package edu.internet2.middleware.grouper.app.provisioning; + +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig; +import edu.internet2.middleware.grouper.app.loader.OtherJobBase; +import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClient.jdbc.GcDbAccess; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncLogDao; +import edu.internet2.middleware.grouperClient.util.GrouperClientUtils; + +public class DeleteOldSyncLogsDaemon extends OtherJobBase { + + @Override + public OtherJobOutput run(OtherJobInput otherJobInput) { + + Map debugMap = new LinkedHashMap(); + + try { + String jobName = otherJobInput.getJobName(); + // jobName = OTHER_JOB_deleteOldSyncLogs + jobName = GrouperClientUtils.stripPrefix(jobName, "OTHER_JOB_"); + + int keepEntriesForSeconds = GrouperLoaderConfig.retrieveConfig().propertyValueInt("otherJob." + jobName + ".keepEntriesForSeconds", 604800); + + debugMap.put("keepEntriesForSeconds", keepEntriesForSeconds); + + if (keepEntriesForSeconds < 0) { + return null; + } + long millisSince1970beforeWhichDelete = System.currentTimeMillis() - (keepEntriesForSeconds * 1000); + + List idsToDelete = new GcDbAccess().sql("select id from grouper_sync_log where last_updated < ?").addBindVar(new Timestamp(millisSince1970beforeWhichDelete)).selectList(String.class); + + debugMap.put("idsToDeleteSize", GrouperUtil.length(idsToDelete)); + + if (GrouperUtil.length(idsToDelete) > 0) { + int deleted = GcGrouperSyncLogDao.internal_logDeleteByIds(idsToDelete); + debugMap.put("deleted", deleted); + otherJobInput.getHib3GrouperLoaderLog().setDeleteCount(deleted); + } + + } catch (RuntimeException e) { + debugMap.put("exception", GrouperUtil.getFullStackTrace(e)); + throw e; + } finally { + otherJobInput.getHib3GrouperLoaderLog().setJobDescription(GrouperUtil.mapToString(debugMap)); + } + return null; + } + +} diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioner.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioner.java index 7b6765163b06..c06c5fbedfbb 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioner.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioner.java @@ -426,6 +426,31 @@ public GrouperProvisioningValidation retrieveGrouperProvisioningValidation() { private GrouperProvisioningLogicIncremental grouperProvisioningLogicIncremental = null; + /** + * return the instance of the provisioning log + * @return the logic + */ + public GrouperProvisioningLog retrieveGrouperProvisioningLog() { + if (this.grouperProvisioningLog == null) { + Class grouperProvisioningLogClass = this.grouperProvisioningLogClass(); + this.grouperProvisioningLog = GrouperUtil.newInstance(grouperProvisioningLogClass); + this.grouperProvisioningLog.setGrouperProvisioner(this); + } + return this.grouperProvisioningLog; + + } + + + private GrouperProvisioningLog grouperProvisioningLog = null; + + /** + * return the class of the provisioning logic + */ + protected Class grouperProvisioningLogClass() { + return GrouperProvisioningLog.class; + } + + private GrouperProvisioningLogic grouperProvisioningLogic = null; /** diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningBehavior.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningBehavior.java index 3f812c92ecdb..080798729fa3 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningBehavior.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningBehavior.java @@ -2,6 +2,7 @@ import java.lang.reflect.Array; import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -130,27 +131,6 @@ public boolean isAllowProvisionableRegexOverride() { // # provisioner.genericProvisioner. = - /** - * set to true if blank (empty) valued attributes on target should be treated differently than attribute not being assigned on target - */ - private boolean deleteBlankAttributesFromTarget = false; - - /** - * set to true if blank (empty) valued attributes on target should be treated differently than attribute not being assigned on target - * @return - */ - public boolean isDeleteBlankAttributesFromTarget() { - return deleteBlankAttributesFromTarget; - } - - /** - * set to true if blank (empty) valued attributes on target should be treated differently than attribute not being assigned on target - * @param deleteBlankAttributesFromTarget1 - */ - public void setDeleteBlankAttributesFromTarget(boolean deleteBlankAttributesFromTarget1) { - this.deleteBlankAttributesFromTarget = deleteBlankAttributesFromTarget1; - } - /** * If the subject API is needed to resolve attribute on subject required, drives requirements of other configurations. defaults to false. */ @@ -173,7 +153,7 @@ public boolean canInsertGroupAttribute(String name) { return true; } if (this.getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.groupAttributes - && StringUtils.equals(name, this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupAttributeNameForMemberships())) { + && StringUtils.equals(name, this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupMembershipAttributeName())) { return this.isInsertMemberships(); } return false; @@ -186,7 +166,7 @@ public boolean canUpdateGroupAttribute(String name) { return true; } if (this.getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.groupAttributes - && StringUtils.equals(name, this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupAttributeNameForMemberships())) { + && StringUtils.equals(name, this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupMembershipAttributeName())) { return this.isUpdateMemberships(); } return false; @@ -201,7 +181,7 @@ public boolean canInsertEntityAttribute(String name) { } if (this.getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.entityAttributes - && StringUtils.equals(name, this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityAttributeNameForMemberships())) { + && StringUtils.equals(name, this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityMembershipAttributeName())) { return this.isInsertMemberships(); } return false; @@ -214,7 +194,7 @@ public boolean canUpdateEntityAttribute(String name) { return true; } if (this.getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.entityAttributes - && StringUtils.equals(name, this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityAttributeNameForMemberships())) { + && StringUtils.equals(name, this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityMembershipAttributeName())) { return this.isUpdateMemberships(); } return false; @@ -239,15 +219,11 @@ public boolean isHasTargetEntityLink() { if (this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().isHasTargetEntityLink()) { return true; } - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values()) { - if (!StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { - return true; + for (GrouperProvisioningConfigurationAttributeDbCache entityAttributeCache : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()) { + if (entityAttributeCache == null) { + continue; } - } - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values()) { - if (!StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { + if (entityAttributeCache.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target) { return true; } } @@ -265,291 +241,42 @@ public void setHasTargetEntityLink(Boolean hasTargetEntityLink) { public boolean isHasSubjectLink() { - if (hasSubjectLink != null) { - return hasSubjectLink; - } - return this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().isHasSubjectLink(); - } - - - - public void setHasSubjectLink(Boolean hasSubjectLink) { - this.hasSubjectLink = hasSubjectLink; - } - - /** - * - * @return true if has script or an attribute mapped - */ - public boolean isHasGroupLinkGroupFromId2() { - - if (StringUtils.isNotBlank(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupLinkGroupFromId2())) { - return true; - } - - if (null != getGroupLinkGroupFromId2Attribute()) { - return true; - } - - return false; - - } - - public GrouperProvisioningConfigurationAttribute getEntityLinkMemberToId2Attribute() { - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values()) { - if (StringUtils.equals("memberToId2", grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values()) { - if (StringUtils.equals("memberToId2", grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - return null; - } - - public GrouperProvisioningConfigurationAttribute getEntityLinkMemberFromId2Attribute() { - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values()) { - if (StringUtils.equals("memberFromId2", grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values()) { - if (StringUtils.equals("memberFromId2", grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - return null; - } - - public GrouperProvisioningConfigurationAttribute getEntityLinkMemberFromId3Attribute() { - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values()) { - if (StringUtils.equals("memberFromId3", grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values()) { - if (StringUtils.equals("memberFromId3", grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - return null; - } - - public GrouperProvisioningConfigurationAttribute getEntityLinkMemberToId3Attribute() { - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values()) { - if (StringUtils.equals("memberToId3", grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values()) { - if (StringUtils.equals("memberToId3", grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - return null; - } - - public GrouperProvisioningConfigurationAttribute getGroupLinkGroupToId2Attribute() { - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values()) { - if (StringUtils.equals("groupToId2", grouperProvisioningConfigurationAttribute.getTranslateToGroupSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values()) { - if (StringUtils.equals("groupToId2", grouperProvisioningConfigurationAttribute.getTranslateToGroupSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - return null; - } - - public GrouperProvisioningConfigurationAttribute getGroupLinkGroupToId3Attribute() { - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values()) { - if (StringUtils.equals("groupToId3", grouperProvisioningConfigurationAttribute.getTranslateToGroupSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values()) { - if (StringUtils.equals("groupToId3", grouperProvisioningConfigurationAttribute.getTranslateToGroupSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - return null; - } - - public GrouperProvisioningConfigurationAttribute getGroupLinkGroupFromId2Attribute() { - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values()) { - if (StringUtils.equals("groupFromId2", grouperProvisioningConfigurationAttribute.getTranslateToGroupSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values()) { - if (StringUtils.equals("groupFromId2", grouperProvisioningConfigurationAttribute.getTranslateToGroupSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - return null; - } - - public GrouperProvisioningConfigurationAttribute getGroupLinkGroupFromId3Attribute() { - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values()) { - if (StringUtils.equals("groupFromId3", grouperProvisioningConfigurationAttribute.getTranslateToGroupSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values()) { - if (StringUtils.equals("groupFromId3", grouperProvisioningConfigurationAttribute.getTranslateToGroupSyncField())) { - return grouperProvisioningConfigurationAttribute; - } - } - return null; - } + if (hasSubjectLink == null) { + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache0 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[0]; + boolean hasSubjectLinkEntityAttributeValueCache0 = grouperProvisioningConfigurationAttributeDbCache0 != null + && grouperProvisioningConfigurationAttributeDbCache0.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache0.getTranslationScript()); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache1 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[1]; + boolean hasSubjectLinkEntityAttributeValueCache1 = grouperProvisioningConfigurationAttributeDbCache1 != null + && grouperProvisioningConfigurationAttributeDbCache1.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache1.getTranslationScript()); - /** - * - * @return true if has script or an attribute mapped - */ - public boolean isHasGroupLinkGroupFromId3() { - - if (StringUtils.isNotBlank(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupLinkGroupFromId3())) { - return true; - } + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache2 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[2]; + boolean hasSubjectLinkEntityAttributeValueCache2 = grouperProvisioningConfigurationAttributeDbCache2 != null + && grouperProvisioningConfigurationAttributeDbCache2.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache2.getTranslationScript()); - if (null != getGroupLinkGroupFromId3Attribute()) { - return true; + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache3 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[3]; + boolean hasSubjectLinkEntityAttributeValueCache3 = grouperProvisioningConfigurationAttributeDbCache3 != null + && grouperProvisioningConfigurationAttributeDbCache3.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache3.getTranslationScript()); + this.hasSubjectLink = hasSubjectLinkEntityAttributeValueCache0 || hasSubjectLinkEntityAttributeValueCache1 + || hasSubjectLinkEntityAttributeValueCache2 || hasSubjectLinkEntityAttributeValueCache3; } - return false; + return hasSubjectLink; } - /** - * - * @return true if has script or an attribute mapped - */ - public boolean isHasGroupLinkGroupToId2() { - - if (StringUtils.isNotBlank(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupLinkGroupToId2())) { - return true; - } - if (null != getGroupLinkGroupToId2Attribute()) { - return true; - } - - return false; - - } - - /** - * - * @return true if has script or an attribute mapped - */ - public boolean isHasGroupLinkGroupToId3() { - - if (StringUtils.isNotBlank(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupLinkGroupToId3())) { - return true; - } - - if (null != getGroupLinkGroupToId3Attribute()) { - return true; - } - - return false; - - } - - - /** - * - * @return true if has script or an attribute mapped - */ - public boolean isHasEntityLinkMemberToId2() { - - if (StringUtils.isNotBlank(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityLinkMemberToId2())) { - return true; - } - - if (null != getEntityLinkMemberToId2Attribute()) { - return true; - } - - return false; - - } - - /** - * - * @return true if has script or an attribute mapped - */ - public boolean isHasEntityLinkMemberFromId2() { - - if (StringUtils.isNotBlank(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityLinkMemberFromId2())) { - return true; - } - - if (null != getEntityLinkMemberFromId2Attribute()) { - return true; - } - - return false; - - } - - /** - * - * @return true if has script or an attribute mapped - */ - public boolean isHasEntityLinkMemberFromId3() { - - if (StringUtils.isNotBlank(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityLinkMemberFromId3())) { - return true; - } - - if (null != getEntityLinkMemberFromId3Attribute()) { - return true; - } - - return false; - - } - - - /** - * - * @return true if has script or an attribute mapped - */ - public boolean isHasEntityLinkMemberToId3() { - - if (StringUtils.isNotBlank(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityLinkMemberToId3())) { - return true; - } - - if (null != getEntityLinkMemberToId3Attribute()) { - return true; - } - - return false; - + public void setHasSubjectLink(Boolean hasSubjectLink) { + this.hasSubjectLink = hasSubjectLink; } public boolean isHasTargetGroupLink() { @@ -559,15 +286,11 @@ public boolean isHasTargetGroupLink() { if (this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().isHasTargetGroupLink()) { return true; } - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values()) { - if (!StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateToGroupSyncField())) { - return true; + for (GrouperProvisioningConfigurationAttributeDbCache groupAttributeCache : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()) { + if (groupAttributeCache == null) { + continue; } - } - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values()) { - if (!StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateToGroupSyncField())) { + if (groupAttributeCache.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target) { return true; } } @@ -575,8 +298,51 @@ public boolean isHasTargetGroupLink() { return false; } + private Set groupAttributeNamesWithCache = null; + public boolean isGroupAttributeNameHasCache(String attributeName) { + + if (this.groupAttributeNamesWithCache == null) { + Set result = new HashSet(); + + for (GrouperProvisioningConfigurationAttributeDbCache groupAttributeCache : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()) { + if (groupAttributeCache == null) { + continue; + } + if (groupAttributeCache.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.attribute + && !StringUtils.isBlank(groupAttributeCache.getAttributeName())) { + result.add(groupAttributeCache.getAttributeName()); + } + } + + this.groupAttributeNamesWithCache = result; + } + return this.groupAttributeNamesWithCache.contains(attributeName); + } + + private Set entityAttributeNamesWithCache; + + public boolean isEntityAttributeNameHasCache(String attributeName) { + + if (this.entityAttributeNamesWithCache == null) { + Set result = new HashSet(); + + for (GrouperProvisioningConfigurationAttributeDbCache entityAttributeCache : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()) { + if (entityAttributeCache == null) { + continue; + } + if (entityAttributeCache.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.attribute + && !StringUtils.isBlank(entityAttributeCache.getAttributeName())) { + result.add(entityAttributeCache.getAttributeName()); + } + } + + this.entityAttributeNamesWithCache = result; + } + return this.entityAttributeNamesWithCache.contains(attributeName); + } + public void setHasTargetGroupLink(Boolean hasTargetGroupLink) { this.hasTargetGroupLink = hasTargetGroupLink; } @@ -682,6 +448,10 @@ public boolean isSelectEntities() { selectEntities = false; return selectEntities; } + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeEntityCrud()) { + selectEntities = true; + return selectEntities; + } this.selectEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isSelectEntities(); return this.selectEntities; @@ -717,7 +487,10 @@ public boolean isSelectMemberships() { selectMemberships = false; return selectMemberships; } - + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeMembershipCrud()) { + selectMemberships = true; + return selectMemberships; + } this.selectMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isSelectMemberships(); return this.selectMemberships; } @@ -807,6 +580,10 @@ public boolean isSelectGroups() { selectGroups = false; return selectGroups; } + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeGroupCrud()) { + selectGroups = true; + return selectGroups; + } this.selectGroups = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isSelectGroups(); return this.selectGroups; @@ -827,8 +604,6 @@ public void setSelectGroups(Boolean groupsRetrieve) { private Boolean insertGroups; - private Set insertGroupsAttributes; - private Boolean deleteGroupsIfNotExistInGrouper; private Boolean deleteGroupsIfGrouperDeleted; @@ -854,6 +629,16 @@ public boolean isDeleteEntitiesIfGrouperCreated() { return deleteEntitiesIfGrouperCreated; } + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isMakeChangesToEntities()) { + deleteEntitiesIfGrouperCreated = false; + return deleteEntitiesIfGrouperCreated; + } + + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeEntityCrud()) { + deleteEntitiesIfGrouperCreated = true; + return deleteEntitiesIfGrouperCreated; + } + // is it configured to? deleteEntitiesIfGrouperCreated = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isDeleteEntitiesIfGrouperCreated(); return deleteEntitiesIfGrouperCreated; @@ -879,6 +664,10 @@ public boolean isDeleteGroupsIfGrouperCreated() { deleteGroupsIfGrouperCreated = false; return deleteGroupsIfGrouperCreated; } + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeGroupCrud()) { + deleteGroupsIfGrouperCreated = true; + return deleteGroupsIfGrouperCreated; + } // is it configured to? deleteGroupsIfGrouperCreated = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isDeleteGroupsIfGrouperCreated(); @@ -904,6 +693,10 @@ public boolean isDeleteMembershipsIfGrouperCreated() { deleteMembershipsIfGrouperCreated = false; return deleteMembershipsIfGrouperCreated; } + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeMembershipCrud()) { + deleteMembershipsIfGrouperCreated = true; + return deleteMembershipsIfGrouperCreated; + } // is it configured to? this.deleteMembershipsIfGrouperCreated = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isDeleteMembershipsIfGrouperCreated(); @@ -957,7 +750,11 @@ public boolean isDeleteGroups() { deleteGroups = false; return deleteGroups; } - + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeGroupCrud()) { + deleteGroups = true; + return deleteGroups; + } + // is it configured to? deleteGroups = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isDeleteGroups(); return deleteGroups; @@ -999,6 +796,11 @@ public boolean isDeleteEntities() { return deleteEntities; } + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeEntityCrud()) { + deleteEntities = true; + return deleteEntities; + } + // is it configured to? deleteEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isDeleteEntities(); return deleteEntities; @@ -1097,6 +899,10 @@ public boolean isDeleteMemberships() { deleteMemberships = false; return deleteMemberships; } + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeMembershipCrud()) { + deleteMemberships = true; + return deleteMemberships; + } // is it configured to? this.deleteMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isDeleteMemberships(); @@ -1166,6 +972,10 @@ public boolean isUpdateGroups() { updateGroups = false; return updateGroups; } + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeGroupCrud()) { + updateGroups = true; + return updateGroups; + } // is it configured to? updateGroups = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isUpdateGroups(); @@ -1202,6 +1012,10 @@ public boolean isInsertGroups() { insertGroups = false; return insertGroups; } + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeGroupCrud()) { + insertGroups = true; + return insertGroups; + } // is it configured to? insertGroups = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isInsertGroups(); @@ -1214,14 +1028,6 @@ public void setInsertGroups(Boolean groupsInsert) { } - public Set getInsertGroupsAttributes() { - return insertGroupsAttributes; - } - - public void setInsertGroupsAttributes(Set groupsInsertAttributes) { - this.insertGroupsAttributes = groupsInsertAttributes; - } - public boolean isDeleteGroupsIfNotExistInGrouper() { if (this.deleteGroupsIfNotExistInGrouper != null) { @@ -1328,6 +1134,11 @@ public boolean isUpdateEntities() { return updateEntities; } + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeEntityCrud()) { + updateEntities = true; + return updateEntities; + } + // is it configured to? updateEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isUpdateEntities(); return updateEntities; @@ -1372,6 +1183,11 @@ public boolean isInsertEntities() { return insertEntities; } + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeEntityCrud()) { + insertEntities = true; + return insertEntities; + } + // is it configured to? insertEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isInsertEntities(); return insertEntities; @@ -1506,6 +1322,10 @@ public boolean isUpdateMemberships() { updateMemberships = false; return updateMemberships; } + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeMembershipCrud()) { + updateMemberships = true; + return updateMemberships; + } // is it configured to? theres not a lot of use cases for updating memberships, so lets sort of ignore this for now this.updateMemberships = this.isInsertMemberships(); @@ -1545,6 +1365,10 @@ public boolean isInsertMemberships() { insertMemberships = false; return insertMemberships; } + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isCustomizeMembershipCrud()) { + insertMemberships = true; + return insertMemberships; + } this.insertMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isInsertMemberships(); return this.insertMemberships; @@ -1623,11 +1447,13 @@ public String toString() { Set fieldNames = GrouperUtil.fieldNames(GrouperProvisioningBehavior.class, null, false); fieldNames = new TreeSet(fieldNames); + + fieldNames.remove("grouperProvisioner"); + fieldNames.remove("entityAttributeNamesWithCache"); + fieldNames.remove("groupAttributeNamesWithCache"); + boolean firstField = true; for (String fieldName : fieldNames) { - if ("grouperProvisioner".equals(fieldName)) { - continue; - } // call getter Object value = GrouperUtil.propertyValue(this, fieldName); if (!GrouperUtil.isBlank(value)) { @@ -1649,23 +1475,23 @@ public String toString() { result.append(fieldName).append(" = '").append(GrouperUtil.toStringForLog(value, false)).append("'"); } } - for (String propertyName : new String[] {"hasEntityLinkMemberFromId2", - "hasEntityLinkMemberFromId3", "hasEntityLinkMemberToId2", "hasEntityLinkMemberToId3", - "hasGroupLinkGroupFromId2", "hasGroupLinkGroupFromId3", "hasGroupLinkGroupToId2", "hasGroupLinkGroupToId3", - "groupLinkGroupFromId2Attribute", "groupLinkGroupFromId3Attribute", "groupLinkGroupToId2Attribute", - "groupLinkGroupToId3Attribute", "entityLinkMemberFromId2Attribute", "entityLinkMemberFromId3Attribute", - "entityLinkMemberToId2Attribute", "entityLinkMemberToId3Attribute"}) { - - Object value = GrouperUtil.propertyValue(this, propertyName); - if (value != null) { - if (!firstField) { - result.append(", "); - } - firstField = false; - result.append(propertyName).append(" = '").append(GrouperUtil.toStringForLog(value, false)).append("'"); - - } - } +// for (String propertyName : new String[] {"hasEntityLinkEntityAttributeValueCache0", +// "hasEntityLinkEntityAttributeValueCache1", "hasEntityLinkEntityAttributeValueCache2", "hasEntityLinkEntityAttributeValueCache3", +// "hasGroupLinkGroupAttributeValueCache0", "hasGroupLinkGroupAttributeValueCache1", "hasGroupLinkGroupAttributeValueCache2", "hasGroupLinkGroupAttributeValueCache3", +// "groupLinkGroupAttributeValueCache0Attribute", "groupLinkGroupAttributeValueCache1Attribute", "groupLinkGroupAttributeValueCache2Attribute", +// "groupLinkGroupAttributeValueCache3Attribute", "entityLinkEntityAttributeValueCache0Attribute", "entityLinkEntityAttributeValueCache1Attribute", +// "entityLinkEntityAttributeValueCache2Attribute", "entityLinkEntityAttributeValueCache3Attribute"}) { +// +// Object value = GrouperUtil.propertyValue(this, propertyName); +// if (value != null) { +// if (!firstField) { +// result.append(", "); +// } +// firstField = false; +// result.append(propertyName).append(" = '").append(GrouperUtil.toStringForLog(value, false)).append("'"); +// +// } +// } return result.toString(); } @@ -1703,12 +1529,12 @@ public String getSubjectIdentifierForMemberSyncTable() { return this.subjectIdentifierForMemberSyncTable; } - String currSubjectIdentifierForMemberSyncTable = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().retrieveConfigString("subjectIdentifierForMemberSyncTable", false); + String currSubjectIdentifierForMemberSyncTable = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getSubjectIdentifierForMemberSyncTable(); // no override, try to compute it if (StringUtils.isBlank(currSubjectIdentifierForMemberSyncTable)) { List searchAttributes = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntitySearchAttributes(); - for (GrouperProvisioningConfigurationAttribute searchAttribute : searchAttributes) { + for (GrouperProvisioningConfigurationAttribute searchAttribute : GrouperUtil.nonNull(searchAttributes)) { String value = searchAttribute.getTranslateFromGrouperProvisioningEntityField(); if (value != null && value.startsWith("subjectIdentifier")) { currSubjectIdentifierForMemberSyncTable = value; @@ -1717,13 +1543,14 @@ public String getSubjectIdentifierForMemberSyncTable() { } if (StringUtils.isBlank(currSubjectIdentifierForMemberSyncTable)) { - GrouperProvisioningConfigurationAttribute matchingAttribute = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().retrieveEntityAttributeMatching(); - if (matchingAttribute != null) { + List matchingAttributes = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityMatchingAttributes(); + for (GrouperProvisioningConfigurationAttribute matchingAttribute : GrouperUtil.nonNull(matchingAttributes)) { String value = matchingAttribute.getTranslateFromGrouperProvisioningEntityField(); if (value != null && value.startsWith("subjectIdentifier")) { - currSubjectIdentifierForMemberSyncTable = value.substring(11); + currSubjectIdentifierForMemberSyncTable = value; //value.substring(11); } } + } if (StringUtils.isBlank(currSubjectIdentifierForMemberSyncTable)) { diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningCompare.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningCompare.java index 08efd37755cf..c4ee3899f8d2 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningCompare.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningCompare.java @@ -13,6 +13,7 @@ import org.apache.commons.lang.StringUtils; import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncErrorCode; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncMembership; public class GrouperProvisioningCompare { @@ -273,7 +274,7 @@ public void compareAttributesForInsert(ProvisioningUpdatable provisioningUpdatab } - public void compareAttributeValues( + public void compareAttributesForUpdate( List provisioningUpdatablesToUpdate, Map grouperTargetAttributes, Map targetProvisioningAttributes, @@ -282,97 +283,114 @@ public void compareAttributeValues( if (grouperProvisioningUpdatable == null) { return; } + boolean recalc = grouperProvisioningUpdatable.isRecalc(); - String attributeForMemberships = null; - - if (!recalc) { - boolean provisionOneAttribute = false; - switch (this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType()) { - case membershipObjects: - // provision memberships - if (grouperProvisioningUpdatable instanceof ProvisioningMembership) { - break; - } - // otherwise ignore - return; - case entityAttributes: - - attributeForMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getAttributeNameForMemberships(); - provisionOneAttribute = true; - if (grouperProvisioningUpdatable instanceof ProvisioningEntity) { - break; - } - // otherwise ignore - return; - - case groupAttributes: + for (String attributeName: GrouperUtil.nonNull(grouperTargetAttributes).keySet()) { - attributeForMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getAttributeNameForMemberships(); - provisionOneAttribute = true; - if (grouperProvisioningUpdatable instanceof ProvisioningGroup) { - break; - } - // otherwise ignore - return; - - default: - throw new RuntimeException("Not expecting membership type"); + ProvisioningAttribute targetAttribute = GrouperUtil.nonNull(targetProvisioningAttributes).get(attributeName); + ProvisioningAttribute grouperAttribute = GrouperUtil.nonNull(grouperTargetAttributes).get(attributeName); + + Object grouperValue = grouperAttribute == null ? null : grouperAttribute.getValue(); + Object targetValue = targetAttribute == null ? null : targetAttribute.getValue(); + + ProvisioningUpdatable targetProvisioningUpdatable = null; + if (grouperProvisioningUpdatable instanceof ProvisioningGroup) { + ProvisioningGroupWrapper provisioningGroupWrapper = ((ProvisioningGroup)grouperProvisioningUpdatable).getProvisioningGroupWrapper(); + targetProvisioningUpdatable = provisioningGroupWrapper == null ? null : provisioningGroupWrapper.getTargetProvisioningGroup(); + } + if (grouperProvisioningUpdatable instanceof ProvisioningEntity) { + ProvisioningEntityWrapper provisioningEntityWrapper = ((ProvisioningEntity)grouperProvisioningUpdatable).getProvisioningEntityWrapper(); + targetProvisioningUpdatable = provisioningEntityWrapper == null ? null : provisioningEntityWrapper.getTargetProvisioningEntity(); } - if (provisionOneAttribute) { + compareAttributeForUpdateValue(grouperProvisioningUpdatable, grouperAttribute, targetProvisioningUpdatable, targetAttribute, attributeName, recalc); + compareAttributeForUpdateValueMembershipOnly(grouperProvisioningUpdatable, grouperAttribute, targetProvisioningUpdatable, targetAttribute, attributeName, recalc); + } + if (GrouperUtil.length(grouperProvisioningUpdatable.getInternal_objectChanges()) > 0) { + addProvisioningUpdatableToUpdateIfNotThere(provisioningUpdatablesToUpdate, + grouperProvisioningUpdatable); + } + } + + public void compareAttributeForUpdateValueMembershipOnly(ProvisioningUpdatable grouperProvisioningUpdatable, ProvisioningAttribute grouperAttribute, + ProvisioningUpdatable targetProvisioningUpdatable, ProvisioningAttribute targetAttribute, String attributeName, + boolean recalc) { + + if (grouperProvisioningUpdatable == null) { + return; + } + + String attributeForMemberships = null; + + switch (this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType()) { + case membershipObjects: + // we dont update any attribute for memberships, we just insert and delete them + return; + case entityAttributes: - if (StringUtils.isBlank(attributeForMemberships)) { - throw new RuntimeException("Attribute for memberships is blank!"); + attributeForMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getAttributeNameForMemberships(); + if (grouperProvisioningUpdatable instanceof ProvisioningEntity && StringUtils.equals(attributeForMemberships, attributeName)) { + break; } + // otherwise ignore + return; - ProvisioningAttribute grouperAttribute = grouperTargetAttributes.get(attributeForMemberships); + case groupAttributes: + + attributeForMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getAttributeNameForMemberships(); + if (grouperProvisioningUpdatable instanceof ProvisioningGroup && StringUtils.equals(attributeForMemberships, attributeName)) { + break; + } + // otherwise ignore + return; - if (grouperAttribute == null) { - return; + default: + throw new RuntimeException("Not expecting membership type"); + } + if (StringUtils.isBlank(attributeForMemberships)) { + throw new RuntimeException("Attribute for memberships is blank!"); + } + if (!recalc) { + + if (grouperAttribute == null) { + return; + } + for (Object value : GrouperUtil.nonNull(grouperAttribute.getValueToProvisioningMembershipWrapper()).keySet()) { + ProvisioningMembershipWrapper provisioningMembershipWrapper = grouperAttribute.getValueToProvisioningMembershipWrapper().get(value); + if (provisioningMembershipWrapper.isRecalc()) { + continue; } - for (Object value : GrouperUtil.nonNull(grouperAttribute.getValueToProvisioningMembershipWrapper()).keySet()) { - ProvisioningMembershipWrapper provisioningMembershipWrapper = grouperAttribute.getValueToProvisioningMembershipWrapper().get(value); - if (provisioningMembershipWrapper.isRecalc()) { - continue; + if (provisioningMembershipWrapper.getGrouperIncrementalDataAction() != null) { + switch (provisioningMembershipWrapper.getGrouperIncrementalDataAction()) { + case delete: + + if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isDeleteMembership(provisioningMembershipWrapper.getGcGrouperSyncMembership())) { + this.membershipDeleteCount++; + countDeleteMembershipObjectCount(provisioningMembershipWrapper.getGrouperProvisioningMembership()); + + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeForMemberships, + ProvisioningObjectChangeAction.delete, value, null) + ); + } + break; + case insert: + if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isInsertMemberships()) { + this.membershipAddCount++; + countAddMembershipObjectCount(provisioningMembershipWrapper.getGrouperProvisioningMembership()); + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeForMemberships, + ProvisioningObjectChangeAction.insert, null, value) + ); + } + break; + default: + throw new RuntimeException("Not expecting grouperIncrementalDataAction for " + grouperProvisioningUpdatable); } - if (provisioningMembershipWrapper.getGrouperIncrementalDataAction() != null) { - switch (provisioningMembershipWrapper.getGrouperIncrementalDataAction()) { - case delete: - - if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isDeleteMembership(provisioningMembershipWrapper.getGcGrouperSyncMembership())) { - this.membershipDeleteCount++; - countDeleteMembershipObjectCount(provisioningMembershipWrapper.getGrouperProvisioningMembership()); - - grouperProvisioningUpdatable.addInternal_objectChange( - new ProvisioningObjectChange(attributeForMemberships, - ProvisioningObjectChangeAction.delete, value, null) - ); - } - break; - case insert: - if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isInsertMemberships()) { - this.membershipAddCount++; - countAddMembershipObjectCount(provisioningMembershipWrapper.getGrouperProvisioningMembership()); - grouperProvisioningUpdatable.addInternal_objectChange( - new ProvisioningObjectChange(attributeForMemberships, - ProvisioningObjectChangeAction.insert, null, value) - ); - } - break; - default: - throw new RuntimeException("Not expecting grouperIncrementalDataAction for " + grouperProvisioningUpdatable); - } - } - } - if (GrouperUtil.length(grouperProvisioningUpdatable.getInternal_objectChanges()) > 0) { - addProvisioningUpdatableToUpdateIfNotThere(provisioningUpdatablesToUpdate, - grouperProvisioningUpdatable); - } - } else { - return; + } } - + return; } // if we're doing an update for an incremental and it's not a recalc, then skip this because we are only doing memberships above if (grouperProvisioningUpdatable instanceof ProvisioningGroup && ((ProvisioningGroup)grouperProvisioningUpdatable).getProvisioningGroupWrapper().getTargetProvisioningGroup() == null ) { @@ -382,186 +400,331 @@ public void compareAttributeValues( if (grouperProvisioningUpdatable instanceof ProvisioningEntity && ((ProvisioningEntity)grouperProvisioningUpdatable).getProvisioningEntityWrapper().getTargetProvisioningEntity() == null ) { return; } - - for (String attributeName: GrouperUtil.nonNull(grouperTargetAttributes).keySet()) { - -// if (!this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().canUpdateObjectAttribute(grouperProvisioningUpdatable, attributeName)) { -// continue; -// } + + Object grouperValue = grouperAttribute == null ? null : grouperAttribute.getValue(); + Object targetValue = targetAttribute == null ? null : targetAttribute.getValue(); - if (!recalc && !StringUtils.equals(attributeForMemberships, attributeName)) { - continue; - } - - - ProvisioningAttribute targetAttribute = GrouperUtil.nonNull(targetProvisioningAttributes).get(attributeName); - ProvisioningAttribute grouperAttribute = grouperTargetAttributes.get(attributeName); + if (targetAttribute == null) { - Object grouperValue = grouperAttribute == null ? null : grouperAttribute.getValue(); - Object targetValue = targetAttribute == null ? null : targetAttribute.getValue(); - - if (targetAttribute == null) { - - if (grouperProvisioningUpdatable.canInsertAttribute(attributeName)) { - if (GrouperUtil.isArrayOrCollection(grouperValue)) { - if (grouperValue instanceof Collection) { - for (Object value : (Collection)grouperValue) { - - value = filterDeletedMemberships(grouperAttribute, value); - - if (filterNonRecalcMemberships(grouperAttribute, value, recalc)) { - continue; - } - - grouperProvisioningUpdatable.addInternal_objectChange( - new ProvisioningObjectChange(attributeName, - ProvisioningObjectChangeAction.insert, null, value) - ); + if (grouperProvisioningUpdatable.canInsertAttribute(attributeName)) { + if (GrouperUtil.isArrayOrCollection(grouperValue)) { + if (grouperValue instanceof Collection) { + for (Object value : (Collection)grouperValue) { + + value = filterDeletedMemberships(grouperAttribute, value); + + if (filterNonRecalcMemberships(grouperAttribute, value, recalc)) { + continue; } - } else { - throw new RuntimeException("Arrays not supported"); + + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeName, + ProvisioningObjectChangeAction.insert, null, value) + ); } } else { - // just a scalar - grouperProvisioningUpdatable.addInternal_objectChange( - new ProvisioningObjectChange(attributeName, - ProvisioningObjectChangeAction.insert, null, grouperValue) - ); - + throw new RuntimeException("Arrays not supported"); } + } else { + // just a scalar + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeName, + ProvisioningObjectChangeAction.insert, null, grouperValue) + ); + } - } else { - - // update - Collection targetCollection = null; - if (targetValue != null) { - if (targetValue instanceof Collection) { - targetCollection = (Collection)targetValue; - } + } + } else { + + // update + Collection targetCollection = null; + if (targetValue != null) { + if (targetValue instanceof Collection) { + targetCollection = (Collection)targetValue; } - Collection grouperCollection = null; - if (grouperValue != null) { - if (grouperValue instanceof Collection) { - grouperCollection = new HashSet((Collection)grouperValue); - } + } + Collection grouperCollection = null; + if (grouperValue != null) { + if (grouperValue instanceof Collection) { + grouperCollection = new HashSet((Collection)grouperValue); } - - if (grouperCollection != null) { - Iterator iterator = grouperCollection.iterator(); - while (iterator.hasNext()) { - Object value = iterator.next(); - value = filterDeletedMemberships(grouperAttribute, value); - - if (filterNonRecalcMemberships(grouperAttribute, value, recalc)) { - continue; - } - - if (value == null) { - iterator.remove(); - } + } + + if (grouperCollection != null) { + Iterator iterator = grouperCollection.iterator(); + while (iterator.hasNext()) { + Object value = iterator.next(); + value = filterDeletedMemberships(grouperAttribute, value); + + if (filterNonRecalcMemberships(grouperAttribute, value, recalc)) { + continue; + } + + if (value == null) { + iterator.remove(); } } - - // scalar - if (grouperCollection == null && targetCollection == null) { - if (!attributeValueEquals(attributeName, grouperValue, targetValue, grouperProvisioningUpdatable)) { - if (grouperProvisioningUpdatable.canUpdateAttribute(attributeName)) { - grouperProvisioningUpdatable.addInternal_objectChange( - new ProvisioningObjectChange(attributeName, - ProvisioningObjectChangeAction.update, targetValue, grouperValue) - ); - } + } + + // scalar + if (grouperCollection == null && targetCollection == null) { + if (!attributeValueEquals(attributeName, grouperValue, targetValue, grouperProvisioningUpdatable)) { + if (grouperProvisioningUpdatable.canUpdateAttribute(attributeName)) { + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeName, + ProvisioningObjectChangeAction.update, targetValue, grouperValue) + ); } - continue; } + return; + } - if (grouperCollection == null) { - grouperCollection = new HashSet(); - if (grouperValue != null) { - grouperCollection.add(grouperValue); - } + if (grouperCollection == null) { + grouperCollection = new HashSet(); + if (grouperValue != null) { + grouperCollection.add(grouperValue); } - if (targetCollection == null) { - targetCollection = new HashSet(); - if (targetValue != null) { - targetCollection.add(targetValue); - } + } + if (targetCollection == null) { + targetCollection = new HashSet(); + if (targetValue != null) { + targetCollection.add(targetValue); + } + } + + Collection inserts = new HashSet(grouperCollection); + inserts.removeAll(targetCollection); + if (grouperProvisioningUpdatable.canInsertAttribute(attributeName)) { + for (Object insertValue : inserts) { + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeName, + ProvisioningObjectChangeAction.insert, null, insertValue) + ); + } + } + Collection deletes = new HashSet(targetCollection); + deletes.removeAll(grouperCollection); + if (grouperProvisioningUpdatable.canDeleteAttribute(attributeName)) { + for (Object deleteValue : deletes) { + + if (grouperProvisioningUpdatable.canDeleteAttributeValue(attributeName, deleteValue)) { - Collection inserts = new HashSet(grouperCollection); - inserts.removeAll(targetCollection); - if (grouperProvisioningUpdatable.canInsertAttribute(attributeName)) { - for (Object insertValue : inserts) { grouperProvisioningUpdatable.addInternal_objectChange( new ProvisioningObjectChange(attributeName, - ProvisioningObjectChangeAction.insert, null, insertValue) + ProvisioningObjectChangeAction.delete, deleteValue, null) ); - - } - } - Collection deletes = new HashSet(targetCollection); - deletes.removeAll(grouperCollection); - if (grouperProvisioningUpdatable.canDeleteAttribute(attributeName)) { - for (Object deleteValue : deletes) { - - if (grouperProvisioningUpdatable.canDeleteAttributeValue(attributeName, deleteValue)) { - - grouperProvisioningUpdatable.addInternal_objectChange( - new ProvisioningObjectChange(attributeName, - ProvisioningObjectChangeAction.delete, deleteValue, null) - ); - } - } + } } - } + } + } + + } + + + /** + * dont compare the membership attribute of group or entity. dont compare memberships at all + * @param grouperProvisioningUpdatable + * @param attributeName + * @param grouperAttribute + * @param targetProvisioningUpdatable + * @param targetAttribute + * @param recalc + */ + public void compareAttributeForUpdateValue( + ProvisioningUpdatable grouperProvisioningUpdatable, ProvisioningAttribute grouperAttribute, + ProvisioningUpdatable targetProvisioningUpdatable, ProvisioningAttribute targetAttribute, String attributeName, + boolean recalc) { + + // we dont update memberships right now + if (grouperProvisioningUpdatable instanceof ProvisioningMembership) { + return; } - for (String attributeName: GrouperUtil.nonNull(targetProvisioningAttributes).keySet()) { - if (grouperProvisioningUpdatable.canDeleteAttribute(attributeName)) { + String attributeForMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getAttributeNameForMemberships(); + switch (this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType()) { + case membershipObjects: + // this is ok + break; + case entityAttributes: + + // dont deal with entity membership attribute + if (grouperProvisioningUpdatable instanceof ProvisioningEntity && StringUtils.equals(attributeForMemberships, attributeName)) { + return; + } + break; + case groupAttributes: - ProvisioningAttribute grouperAttribute = grouperTargetAttributes.get(attributeName); - if (grouperAttribute == null) { - ProvisioningAttribute targetAttribute = targetProvisioningAttributes.get(attributeName); - Object targetValue = targetAttribute == null ? null : targetAttribute.getValue(); + // dont deal with group membership attribute + if (grouperProvisioningUpdatable instanceof ProvisioningGroup && StringUtils.equals(attributeForMemberships, attributeName)) { + return; + } + // otherwise ignore + break; + + default: + throw new RuntimeException("Not expecting membership type"); + } + + Object grouperValue = grouperAttribute == null ? null : grouperAttribute.getValue(); + Object targetValue = targetAttribute == null ? null : targetAttribute.getValue(); + + // update + Collection targetCollection = null; + if (targetValue != null) { + if (targetValue instanceof Collection) { + targetCollection = (Collection)targetValue; + } + } + Collection grouperCollection = null; + if (grouperValue != null) { + if (grouperValue instanceof Collection) { + grouperCollection = new HashSet((Collection)grouperValue); + } + } + + // remove null values from collection + if (grouperCollection != null) { + Iterator iterator = grouperCollection.iterator(); + while (iterator.hasNext()) { + Object value = iterator.next(); + + if (value == null) { + iterator.remove(); + } + } + } + + // if its not a recalc and collection + if (!recalc && grouperCollection != null) { + // update all updatable fields? weird that target value will be null, but thats ok + if (grouperProvisioningUpdatable.canUpdateAttribute(attributeName)) { + for (Object value : grouperCollection) { + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeName, + ProvisioningObjectChangeAction.update, null, value) + ); + } + } + return; + } + + // if its not a recalc and scalar + if (!recalc) { + // update all updatable fields? weird that target value will be null, but thats ok + if (grouperProvisioningUpdatable.canUpdateAttribute(attributeName)) { + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeName, + ProvisioningObjectChangeAction.update, null, grouperValue) + ); + } + return; + } + + // its a recalc, and collection insert + if (targetValue == null && grouperCollection != null) { + + if (grouperProvisioningUpdatable.canUpdateAttribute(attributeName)) { + for (Object value : grouperCollection) { - if (GrouperUtil.isArrayOrCollection(targetValue)) { - if (targetValue instanceof Collection) { - for (Object value : (Collection)targetValue) { - if (grouperProvisioningUpdatable.canDeleteAttributeValue(attributeName, value)) { - grouperProvisioningUpdatable.addInternal_objectChange( - new ProvisioningObjectChange(attributeName, - ProvisioningObjectChangeAction.delete, value, null) - ); - } - } - } else { - throw new RuntimeException("Arrays not supported"); - } - - // note for ldap I think we want this as false - if (this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().isDeleteBlankAttributesFromTarget()) { - // indicate the attribute itself is gone - grouperProvisioningUpdatable.addInternal_objectChange( - new ProvisioningObjectChange(attributeName, - ProvisioningObjectChangeAction.delete, null, null) + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeName, + ProvisioningObjectChangeAction.update, null, value) ); - } - } else { - // just a scalar - if (grouperProvisioningUpdatable.canDeleteAttributeValue(attributeName, targetValue)) { - grouperProvisioningUpdatable.addInternal_objectChange( - new ProvisioningObjectChange(attributeName, - ProvisioningObjectChangeAction.delete, targetValue, null) - ); - } - - } } - } + } + return; } - if (GrouperUtil.length(grouperProvisioningUpdatable.getInternal_objectChanges()) > 0) { - addProvisioningUpdatableToUpdateIfNotThere(provisioningUpdatablesToUpdate, - grouperProvisioningUpdatable); + + // its a recalc, and scalar insert + if (targetValue == null && grouperValue != null) { + + if (grouperProvisioningUpdatable.canUpdateAttribute(attributeName)) { + // just a scalar + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeName, + ProvisioningObjectChangeAction.update, null, grouperValue) + ); + } + return; + } + + // do collection deletes + if (grouperValue == null && targetCollection != null) { + for (Object value : targetCollection) { + if (grouperProvisioningUpdatable.canUpdateAttribute(attributeName)) { + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeName, + ProvisioningObjectChangeAction.update, value, null) + ); + } + } + return; + } + + // do scalar deletes + if (grouperValue == null && targetValue != null) { + + if (grouperProvisioningUpdatable.canUpdateAttribute(attributeName)) { + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeName, + ProvisioningObjectChangeAction.update, targetValue, null) + ); + } + return; + } + + // scalar update + if (grouperCollection == null && targetCollection == null) { + if (!attributeValueEquals(attributeName, grouperValue, targetValue, grouperProvisioningUpdatable)) { + if (grouperProvisioningUpdatable.canUpdateAttribute(attributeName)) { + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeName, + ProvisioningObjectChangeAction.update, targetValue, grouperValue) + ); + } + } + return; + } + + // convert both to collections + if (grouperCollection == null) { + grouperCollection = new HashSet(); + if (grouperValue != null) { + grouperCollection.add(grouperValue); + } + } + if (targetCollection == null) { + targetCollection = new HashSet(); + if (targetValue != null) { + targetCollection.add(targetValue); + } + } + + Collection inserts = new HashSet(grouperCollection); + inserts.removeAll(targetCollection); + if (grouperProvisioningUpdatable.canUpdateAttribute(attributeName)) { + for (Object insertValue : inserts) { + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeName, + ProvisioningObjectChangeAction.update, null, insertValue) + ); + + } + } + Collection deletes = new HashSet(targetCollection); + deletes.removeAll(grouperCollection); + if (grouperProvisioningUpdatable.canDeleteAttribute(attributeName)) { + for (Object deleteValue : deletes) { + + if (grouperProvisioningUpdatable.canUpdateAttribute(attributeName)) { + + grouperProvisioningUpdatable.addInternal_objectChange( + new ProvisioningObjectChange(attributeName, + ProvisioningObjectChangeAction.update, deleteValue, null) + ); + } + } } } @@ -792,7 +955,7 @@ public void compareTargetEntities(Collection provisio ProvisioningEntity grouperTargetEntity = provisioningEntityWrapper.getGrouperTargetEntity(); ProvisioningEntity targetProvisioningEntity = provisioningEntityWrapper.getTargetProvisioningEntity(); - compareAttributeValues(provisioningEntitiesToUpdate, grouperTargetEntity == null ? null : grouperTargetEntity.getAttributes(), + compareAttributesForUpdate(provisioningEntitiesToUpdate, grouperTargetEntity == null ? null : grouperTargetEntity.getAttributes(), targetProvisioningEntity == null ? null : targetProvisioningEntity.getAttributes(), grouperTargetEntity); } @@ -885,6 +1048,10 @@ public void compareTargetGroups(Collection provisionin } + } else if (provisioningGroupWrapper.getGcGrouperSyncGroup() != null && provisioningGroupWrapper.getGcGrouperSyncGroup().isInTarget() + && provisioningGroupWrapper.isDelete() && provisioningGroupWrapper.getErrorCode() == GcGrouperSyncErrorCode.MEM) { + provisioningGroupWrappersForDelete.add(provisioningGroupWrapper); + continue; } // updates @@ -899,6 +1066,12 @@ public void compareTargetGroups(Collection provisionin } else { + + if (!provisioningGroupWrapper.isUpdate()) { + // if there's no changelog that says it was updated then it might just be a membership change so skip the update + continue; + } + provisioningGroupWrappersForUpdate.add(provisioningGroupWrapper); } @@ -988,7 +1161,7 @@ public void compareTargetGroups(Collection provisionin ProvisioningGroup grouperTargetGroup = provisioningGroupWrapper.getGrouperTargetGroup(); ProvisioningGroup targetProvisioningGroup = provisioningGroupWrapper.getTargetProvisioningGroup(); - compareAttributeValues(provisioningGroupsToUpdate, grouperTargetGroup == null ? null : grouperTargetGroup.getAttributes(), + compareAttributesForUpdate(provisioningGroupsToUpdate, grouperTargetGroup == null ? null : grouperTargetGroup.getAttributes(), targetProvisioningGroup == null ? null : targetProvisioningGroup.getAttributes(), grouperTargetGroup); } @@ -1241,7 +1414,7 @@ public void compareTargetMemberships(Collection p ProvisioningMembership grouperTargetMembership = grouperMatchingIdToTargetMembership.get(matchingIdToUpdate); ProvisioningMembership targetProvisioningMembership = targetMatchingIdToTargetMembership.get(matchingIdToUpdate); - compareAttributeValues(provisioningMembershipsToUpdate, grouperTargetMembership == null ? null : grouperTargetMembership.getAttributes(), + compareAttributesForUpdate(provisioningMembershipsToUpdate, grouperTargetMembership == null ? null : grouperTargetMembership.getAttributes(), targetProvisioningMembership == null ? null : targetProvisioningMembership.getAttributes(), grouperTargetMembership); } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfiguration.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfiguration.java index 253b891cfa4c..3648dd30219c 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfiguration.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfiguration.java @@ -68,8 +68,14 @@ public boolean isCustomizeMembershipCrud() { + private String subjectIdentifierForMemberSyncTable; + + + public String getSubjectIdentifierForMemberSyncTable() { + return subjectIdentifierForMemberSyncTable; + } public void setCustomizeMembershipCrud(boolean customizeMembershipCrud) { this.customizeMembershipCrud = customizeMembershipCrud; @@ -615,36 +621,6 @@ public void setMetadataNameToMetadataItem( this.metadataNameToMetadataItem = metadataNameToMetadataItem; } - /** - * get the group matching attribute object (could be field or attribute) - * @return the attribute - */ - public GrouperProvisioningConfigurationAttribute retrieveGroupAttributeMatching() { - - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : this.getTargetGroupAttributeNameToConfig().values()) { - if (grouperProvisioningConfigurationAttribute.isMatchingId()) { - return grouperProvisioningConfigurationAttribute; - } - } - - return null; - } - - /** - * get the entity matching attribute object (could be field or attribute) - * @return the attribute - */ - public GrouperProvisioningConfigurationAttribute retrieveEntityAttributeMatching() { - - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : this.getTargetEntityAttributeNameToConfig().values()) { - if (grouperProvisioningConfigurationAttribute.isMatchingId()) { - return grouperProvisioningConfigurationAttribute; - } - } - - return null; - } - /** * * @return map @@ -653,95 +629,11 @@ public Map getTargetGroupAttr return targetGroupAttributeNameToConfig; } - /** - * use this attribute as a matching id - */ - private String entityMatchingIdAttribute; - - /** - * use this attribute as a matching id - * @return - */ - public String getEntityMatchingIdAttribute() { - return entityMatchingIdAttribute; - } - - /** - * use this attribute as a matching id - * @param entityMatchingIdAttribute - */ - public void setEntityMatchingIdAttribute(String entityMatchingIdAttribute) { - this.entityMatchingIdAttribute = entityMatchingIdAttribute; - } - - /** - * use this attribute as a matching id - */ - private String groupMatchingIdAttribute; - - - - /** - * use this attribute as a matching id - * @return - */ - public String getGroupMatchingIdAttribute() { - return groupMatchingIdAttribute; - } - - /** - * use this attribute as a matching id - * @param groupMatchingIdAttribute - */ - public void setGroupMatchingIdAttribute(String groupMatchingIdAttribute) { - this.groupMatchingIdAttribute = groupMatchingIdAttribute; - } - - /** - * - */ - private String membershipMatchingIdAttribute; - - - - public String getMembershipMatchingIdAttribute() { - return membershipMatchingIdAttribute; - } - - - public void setMembershipMatchingIdAttribute(String membershipMatchingIdAttribute) { - this.membershipMatchingIdAttribute = membershipMatchingIdAttribute; - } - - /** - * expression to get the group id from target group - */ - private String groupMatchingIdExpression; - /** * expression to get the membership id from the target group */ private String membershipMatchingIdExpression; - /** - * expression to get the entity id from the target entity - */ - private String entityMatchingIdExpression; - - - - public String getGroupMatchingIdExpression() { - return groupMatchingIdExpression; - } - - - - public void setGroupMatchingIdExpression(String groupMatchingIdExpression) { - this.groupMatchingIdExpression = groupMatchingIdExpression; - } - - - public String getMembershipMatchingIdExpression() { return membershipMatchingIdExpression; } @@ -754,16 +646,6 @@ public void setMembershipMatchingIdExpression(String membershipMatchingIdExpress - public String getEntityMatchingIdExpression() { - return entityMatchingIdExpression; - } - - - - public void setEntityMatchingIdExpression(String entityMatchingIdExpression) { - this.entityMatchingIdExpression = entityMatchingIdExpression; - } - private boolean logCommandsAlways = false; @@ -778,7 +660,16 @@ public void setLogCommandsAlways(boolean logCommandsAlways) { this.logCommandsAlways = logCommandsAlways; } + private int logMaxErrorsPerType; + public int getLogMaxErrorsPerType() { + return logMaxErrorsPerType; + } + + public void setLogMaxErrorsPerType(int logMaxErrorsPerType) { + this.logMaxErrorsPerType = logMaxErrorsPerType; + } + public boolean isLogCommandsOnError() { return logCommandsOnError; } @@ -1002,104 +893,37 @@ public void preConfigure() { } } - /** - * If the subject API is needed to resolve attribute on subject required, drives requirements of other configurations. defaults to false. - */ - private boolean hasSubjectLink = false; - /** * If groups need to be resolved in the target before provisioning */ private boolean hasTargetGroupLink = false; - + /** * If users need to be resolved in the target before provisioning */ private boolean hasTargetEntityLink = false; - + /** * subject sources to provision optional, defaults to all except g:gsa, grouperExternal, g:isa, localEntities. comma separated list. checkboxes. */ private Set subjectSourcesToProvision = null; - - - private String subjectLinkMemberFromId2; - - private String subjectLinkMemberFromId3; - - private String subjectLinkMemberToId2; - private String subjectLinkMemberToId3; - - - public String getSubjectLinkMemberFromId2() { - return subjectLinkMemberFromId2; - } - - - - public void setSubjectLinkMemberFromId2(String subjectLinkMemberFromId2) { - this.subjectLinkMemberFromId2 = subjectLinkMemberFromId2; - } - - - - - public String getSubjectLinkMemberFromId3() { - return subjectLinkMemberFromId3; - } - - - - - public void setSubjectLinkMemberFromId3(String subjectLinkMemberFromId3) { - this.subjectLinkMemberFromId3 = subjectLinkMemberFromId3; - } - - - - - public String getSubjectLinkMemberToId2() { - return subjectLinkMemberToId2; - } - - - - - public void setSubjectLinkMemberToId2(String subjectLinkMemberToId2) { - this.subjectLinkMemberToId2 = subjectLinkMemberToId2; - } - - - - - public String getSubjectLinkMemberToId3() { - return subjectLinkMemberToId3; - } - - - - - public void setSubjectLinkMemberToId3(String subjectLinkMemberToId3) { - this.subjectLinkMemberToId3 = subjectLinkMemberToId3; - } - /** - * attributes to use when searching, targetId is first if multiple + * attributes to use when searching */ private List entitySearchAttributes = null; - + /** - * attributes to use when searching, targetId is first if multiple + * attributes to use when searching */ private List groupSearchAttributes = null; - - /** + + /** * attributes to use when selecting from target */ private Set groupSelectAttributes = null; - + /** * attributes to use when selecting from target * @return @@ -1124,19 +948,37 @@ public Set getEntitySelectAttributes() { return entitySelectAttributes; } + /** + * attributes to use when selecting from target + * @param entitySelectAttributes + */ + public void setEntitySelectAttributes(Set entitySelectAttributes) { + this.entitySelectAttributes = entitySelectAttributes; + } + + /** + * attributes to use when selecting from target + */ + private Set entitySelectAttributes = null; + /** - * attributes to use when selecting from target - * @param entitySelectAttributes + * attributes to use when matching */ - public void setEntitySelectAttributes(Set entitySelectAttributes) { - this.entitySelectAttributes = entitySelectAttributes; + private List entityMatchingAttributes = null; + + public List getEntityMatchingAttributes() { + return entityMatchingAttributes; } /** - * attributes to use when selecting from target + * attributes to use when searching */ - private Set entitySelectAttributes = null; + private List groupMatchingAttributes = null; + public List getGroupMatchingAttributes() { + return groupMatchingAttributes; + } + /** * someAttr everything is assumed to be single valued except objectclass and the provisionedAttributeName optional */ @@ -1620,7 +1462,10 @@ public String toString() { fieldNames.remove("targetMembershipFieldNameToConfig"); fieldNames.remove("grouperProvisioningToTargetTranslation"); fieldNames.remove("metadataNameToMetadataItem"); - + fieldNames.remove("entityMatchingAttributes"); + fieldNames.remove("groupMatchingAttributes"); + fieldNames.remove("entitySearchAttributes"); + fieldNames.remove("groupSearchAttributes"); fieldNames = new TreeSet(fieldNames); boolean firstField = true; @@ -1645,6 +1490,50 @@ public String toString() { result.append(fieldName).append(" = '").append(GrouperUtil.toStringForLog(value, false)).append("'"); } } + if (GrouperUtil.length(this.groupMatchingAttributes) > 0) { + result.append(", groupMatchingAttributes: "); + boolean first = true; + for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : this.groupMatchingAttributes) { + if (!first) { + result.append(", "); + } + first = false; + result.append(grouperProvisioningConfigurationAttribute.getName()); + } + } + if (GrouperUtil.length(this.groupSearchAttributes) > 0) { + result.append(", groupSearchAttributes: "); + boolean first = true; + for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : this.groupSearchAttributes) { + if (!first) { + result.append(", "); + } + first = false; + result.append(grouperProvisioningConfigurationAttribute.getName()); + } + } + if (GrouperUtil.length(this.entityMatchingAttributes) > 0) { + result.append(", entityMatchingAttributes: "); + boolean first = true; + for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : this.entityMatchingAttributes) { + if (!first) { + result.append(", "); + } + first = false; + result.append(grouperProvisioningConfigurationAttribute.getName()); + } + } + if (GrouperUtil.length(this.entitySearchAttributes) > 0) { + result.append(", entitySearchAttributes: "); + boolean first = true; + for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : this.entitySearchAttributes) { + if (!first) { + result.append(", "); + } + first = false; + result.append(grouperProvisioningConfigurationAttribute.getName()); + } + } for (String key : new TreeSet(this.metadataNameToMetadataItem.keySet())) { if (result.charAt(result.length()-1) != '\n') { result.append("\n"); @@ -1818,58 +1707,43 @@ public void setAttributeNameForMemberships(String attributeNameForMemberships) { } /** - * attribute name in a group object that refers to memberships (if applicable) - */ - private String groupAttributeNameForMemberships; - - /** - * attribute name in a group object that refers to memberships (if applicable) - * @return + * */ - public String getGroupAttributeNameForMemberships() { - return groupAttributeNameForMemberships; - } + public abstract void configureSpecificSettings(); + + private GrouperProvisioningBehaviorMembershipType grouperProvisioningBehaviorMembershipType; /** - * attribute name in a group object that refers to memberships (if applicable) - * @param groupAttributeNameForMemberships + * number of metadata */ - public void setGroupAttributeNameForMemberships(String groupAttributeNameForMemberships) { - this.groupAttributeNameForMemberships = groupAttributeNameForMemberships; + private int numberOfMetadata; + + private String groupMembershipAttributeName; + + public String getGroupMembershipAttributeName() { + return groupMembershipAttributeName; } - - /** - * attribute name in a user object that refers to memberships (if applicable) - */ - private String entityAttributeNameForMemberships; - - /** - * attribute name in a user object that refers to memberships (if applicable) - * @return - */ - public String getEntityAttributeNameForMemberships() { - return entityAttributeNameForMemberships; + + public String getGroupMembershipAttributeValue() { + return groupMembershipAttributeValue; } + private String groupMembershipAttributeValue; + /** * attribute name in a user object that refers to memberships (if applicable) - * @param userAttributeNameForMemberships */ - public void setEntityAttributeNameForMemberships(String userAttributeNameForMemberships) { - this.entityAttributeNameForMemberships = userAttributeNameForMemberships; - } + private String entityMembershipAttributeName; - /** - * - */ - public abstract void configureSpecificSettings(); + public String getEntityMembershipAttributeName() { + return entityMembershipAttributeName; + } - private GrouperProvisioningBehaviorMembershipType grouperProvisioningBehaviorMembershipType; + public String getEntityMembershipAttributeValue() { + return entityMembershipAttributeValue; + } - /** - * number of metadata - */ - private int numberOfMetadata; + private String entityMembershipAttributeValue; /** @@ -2044,6 +1918,13 @@ public void configureGenericSettings() { } + this.groupMembershipAttributeName = this.retrieveConfigString("groupMembershipAttributeName", false); + this.groupMembershipAttributeValue = this.retrieveConfigString("groupMembershipAttributeValue", false); + + this.entityMembershipAttributeName = this.retrieveConfigString("entityMembershipAttributeName", false); + this.entityMembershipAttributeValue = this.retrieveConfigString("entityMembershipAttributeValue", false); + + for (String objectType: new String[] {"targetGroupAttribute", "targetEntityAttribute", "targetMembershipAttribute"}) { boolean foundMatchingId = false; @@ -2096,39 +1977,7 @@ public void configureGenericSettings() { } } - - { - boolean searchAttribute = GrouperUtil.booleanValue(this.retrieveConfigBoolean(objectType + "."+i+".searchAttribute" , false), false); - attributeConfig.setSearchAttribute(searchAttribute); - } - { - boolean membershipAttribute = GrouperUtil.booleanValue(this.retrieveConfigBoolean(objectType + "."+i+".membershipAttribute" , false), false); - String translateExpressionFromMembership = this.retrieveConfigString(objectType + "." + i + ".translateExpressionFromMembership", false); - if (membershipAttribute) { - if (foundMembershipAttribute) { - throw new RuntimeException("Can only have one " + objectType + " membershipAttribute attribute or field! " + name + ", " + foundMembershipAttributeName); - } - foundMembershipAttribute = true; - foundMembershipAttributeName = name; - - attributeConfig.setTranslateExpressionFromMembership(translateExpressionFromMembership); - } - attributeConfig.setMembershipAttribute(membershipAttribute); - } - - { - boolean matchingId = GrouperUtil.booleanValue(this.retrieveConfigBoolean(objectType + "."+i+".matchingId" , false), false); - if (matchingId) { - if (foundMatchingId) { - throw new RuntimeException("Can only have one " + objectType + " matchingId attribute or field! " + name + ", " + foundMatchingIdName); - } - foundMatchingId = true; - foundMatchingIdName = name; - } - attributeConfig.setMatchingId(matchingId); - } - { String translateExpression = this.retrieveConfigString(objectType + "."+i+".translateExpression" , false); attributeConfig.setTranslateExpression(translateExpression); @@ -2149,11 +1998,6 @@ public void configureGenericSettings() { attributeConfig.setTranslateFromStaticValuesCreateOnly(translateFromStaticValuesCreateOnly); } - { - String translateFromGroupSyncField = this.retrieveConfigString(objectType+"."+i+".translateFromGroupSyncField" , false); - attributeConfig.setTranslateFromGroupSyncField(translateFromGroupSyncField); - } - { String translateFromGrouperProvisioningGroupField = this.retrieveConfigString(objectType+"."+i+".translateFromGrouperProvisioningGroupField" , false); attributeConfig.setTranslateFromGrouperProvisioningGroupField(translateFromGrouperProvisioningGroupField); @@ -2174,30 +2018,6 @@ public void configureGenericSettings() { attributeConfig.setTranslateFromGrouperProvisioningEntityFieldCreateOnly(translateFromGrouperProvisioningEntityFieldCreateOnly); } - { - String translateFromMemberSyncField = this.retrieveConfigString(objectType+"."+i+".translateFromMemberSyncField" , false); - attributeConfig.setTranslateFromMemberSyncField(translateFromMemberSyncField); - } - - { - String translateToGroupSyncField = this.retrieveConfigString(objectType+"."+i+".translateToGroupSyncField" , false); - attributeConfig.setTranslateToGroupSyncField(translateToGroupSyncField); - } - - { - String translateToMemberSyncField = this.retrieveConfigString(objectType+"."+i+".translateToMemberSyncField" , false); - attributeConfig.setTranslateToMemberSyncField(translateToMemberSyncField); - } - - { - String translateGrouperToGroupSyncField = this.retrieveConfigString(objectType+"."+i+".translateGrouperToGroupSyncField" , false); - attributeConfig.setTranslateGrouperToGroupSyncField(translateGrouperToGroupSyncField); - } - - { - String translateGrouperToMemberSyncField = this.retrieveConfigString(objectType+"."+i+".translateGrouperToMemberSyncField" , false); - attributeConfig.setTranslateGrouperToMemberSyncField(translateGrouperToMemberSyncField); - } { boolean showAttributeCrud = GrouperUtil.booleanValue(this.retrieveConfigBoolean(objectType + "."+i+".showAttributeCrud" , false), false); if (showAttributeCrud) { @@ -2220,14 +2040,24 @@ public void configureGenericSettings() { { boolean showAttributeValueSettings = GrouperUtil.booleanValue(this.retrieveConfigBoolean(objectType + "."+i+".showAttributeValueSettings" , false), false); + Boolean multiValued = null; if (showAttributeValueSettings) { - - { - boolean multiValued = GrouperUtil.booleanValue(this.retrieveConfigBoolean(objectType + "."+i+".multiValued" , false), false); - attributeConfig.setMultiValued(multiValued); + multiValued = this.retrieveConfigBoolean(objectType + "."+i+".multiValued" , false); + } + // default multivalued to true for membership attribute if nothing set already + if (multiValued == null) { + if (StringUtils.equals(objectType, "targetGroupAttribute") && !StringUtils.isBlank(this.groupMembershipAttributeName) + && StringUtils.equals(this.groupMembershipAttributeName, name)) { + multiValued = true; } - - + if (StringUtils.equals(objectType, "targetEntityAttribute") && !StringUtils.isBlank(this.entityMembershipAttributeName) + && StringUtils.equals(this.entityMembershipAttributeName, name)) { + multiValued = true; + } + } + attributeConfig.setMultiValued(multiValued == null ? false: multiValued); + + if (showAttributeValueSettings) { { String defaultValue = this.retrieveConfigString(objectType + "."+i+".defaultValue" , false); attributeConfig.setDefaultValue(defaultValue); @@ -2285,11 +2115,6 @@ public void configureGenericSettings() { } } - this.hasSubjectLink = GrouperUtil.defaultIfNull(this.retrieveConfigBoolean("hasSubjectLink", false), false); - if (this.hasSubjectLink) { - this.debugMap.put("hasSubjectLink", this.hasSubjectLink); - } - this.hasTargetGroupLink = GrouperUtil.defaultIfNull(this.retrieveConfigBoolean("hasTargetGroupLink", false), false); if (this.hasTargetGroupLink) { this.debugMap.put("hasTargetGroupLink", this.hasTargetGroupLink); @@ -2299,22 +2124,23 @@ public void configureGenericSettings() { if (this.hasTargetEntityLink) { this.debugMap.put("hasTargetEntityLink", this.hasTargetEntityLink); } - + + if (GrouperUtil.defaultIfNull(this.retrieveConfigBoolean("group2advanced", false), false)) { + this.groupsRequireMembers = GrouperUtil.defaultIfNull(this.retrieveConfigBoolean("groupsRequireMembers", false), false); + } + this.groupSearchFilter = this.retrieveConfigString("groupSearchFilter", false); - this.entityMatchingIdExpression = this.retrieveConfigString("entityMatchingIdExpression", false); - this.groupMatchingIdExpression = this.retrieveConfigString("groupMatchingIdExpression", false); this.membershipMatchingIdExpression = this.retrieveConfigString("membershipMatchingIdExpression", false); - this.entityMatchingIdAttribute = this.retrieveConfigString("entityMatchingIdAttribute", false); - this.groupMatchingIdAttribute = this.retrieveConfigString("groupMatchingIdAttribute", false); - this.logAllObjectsVerbose = GrouperUtil.defaultIfNull(this.retrieveConfigBoolean("logAllObjectsVerbose", false), false); this.logCommandsAlways = GrouperUtil.defaultIfNull(this.retrieveConfigBoolean("logCommandsAlways", false), false); this.logCommandsOnError = GrouperUtil.defaultIfNull(this.retrieveConfigBoolean("logCommandsOnError", false), false); + this.logMaxErrorsPerType = GrouperUtil.intValue(this.retrieveConfigInt("logMaxErrorsPerType", false), 10); + this.debugLog = GrouperUtil.defaultIfNull(this.retrieveConfigBoolean("debugLog", false), false); this.operateOnGrouperEntities = GrouperUtil.booleanValue(this.retrieveConfigBoolean("operateOnGrouperEntities", false), false); @@ -2328,21 +2154,66 @@ public void configureGenericSettings() { } this.debugMap.put("subjectSourcesToProvision", GrouperUtil.join(this.subjectSourcesToProvision.iterator(), ',')); - this.subjectLinkMemberFromId2 = this.retrieveConfigString("common.subjectLink.memberFromId2", false); - this.subjectLinkMemberFromId3 = this.retrieveConfigString("common.subjectLink.memberFromId3", false); - this.subjectLinkMemberToId2 = this.retrieveConfigString("common.subjectLink.memberToId2", false); - this.subjectLinkMemberToId3 = this.retrieveConfigString("common.subjectLink.memberToId3", false); - - this.groupLinkGroupFromId2 = this.retrieveConfigString("common.groupLink.groupFromId2", false); - this.groupLinkGroupFromId3 = this.retrieveConfigString("common.groupLink.groupFromId3", false); - this.groupLinkGroupToId2 = this.retrieveConfigString("common.groupLink.groupToId2", false); - this.groupLinkGroupToId3 = this.retrieveConfigString("common.groupLink.groupToId3", false); + this.groupAttributeValueCacheHas = GrouperUtil.booleanValue(this.retrieveConfigBoolean("groupAttributeValueCacheHas", false), false); + if (this.groupAttributeValueCacheHas) { + this.groupAttributeDbCaches = new GrouperProvisioningConfigurationAttributeDbCache[4]; - this.entityLinkMemberFromId2 = this.retrieveConfigString("common.entityLink.memberFromId2", false); - this.entityLinkMemberFromId3 = this.retrieveConfigString("common.entityLink.memberFromId3", false); - this.entityLinkMemberToId2 = this.retrieveConfigString("common.entityLink.memberToId2", false); - this.entityLinkMemberToId3 = this.retrieveConfigString("common.entityLink.memberToId3", false); + for (int i=0;i<4;i++) { + boolean theGroupAttributeValueCacheHas = GrouperUtil.booleanValue(this.retrieveConfigBoolean("groupAttributeValueCache" + i + "has", false), false); + if (!theGroupAttributeValueCacheHas) { + continue; + } + this.groupAttributeDbCaches[i] = new GrouperProvisioningConfigurationAttributeDbCache(this.grouperProvisioner, i, "group"); + String theGroupAttributeValueCache0source = this.retrieveConfigString("groupAttributeValueCache" + i + "source", true); + this.groupAttributeDbCaches[i].setSource( + GrouperProvisioningConfigurationAttributeDbCacheSource.valueOfIgnoreCase(theGroupAttributeValueCache0source, true)); + + String theGroupAttributeValueCache0type = this.retrieveConfigString("groupAttributeValueCache" + i + "type", true); + this.groupAttributeDbCaches[i].setType( + GrouperProvisioningConfigurationAttributeDbCacheType.valueOfIgnoreCase(theGroupAttributeValueCache0type, true)); + + if (this.groupAttributeDbCaches[i].getType() == GrouperProvisioningConfigurationAttributeDbCacheType.attribute) { + this.groupAttributeDbCaches[i].setAttributeName(this.retrieveConfigString("groupAttributeValueCache" + i + "groupAttribute", true)); + } else if (this.groupAttributeDbCaches[i].getType() == GrouperProvisioningConfigurationAttributeDbCacheType.translationScript) { + this.groupAttributeDbCaches[i].setTranslationScript(this.retrieveConfigString("groupAttributeValueCache" + i + "translationScript", true)); + } else { + throw new RuntimeException("Invalid attribute cache type: " + "groupAttributeValueCache" + i + "type" + ", " + + this.groupAttributeDbCaches[i].getType()); + } + } + } + + this.entityAttributeValueCacheHas = GrouperUtil.booleanValue(this.retrieveConfigBoolean("entityAttributeValueCacheHas", false), false); + if (this.entityAttributeValueCacheHas) { + this.entityAttributeDbCaches = new GrouperProvisioningConfigurationAttributeDbCache[4]; + for (int i=0;i<4;i++) { + boolean theEntityAttributeValueCacheHas = GrouperUtil.booleanValue(this.retrieveConfigBoolean("entityAttributeValueCache" + i + "has", false), false); + if (!theEntityAttributeValueCacheHas) { + continue; + } + this.entityAttributeDbCaches[i] = new GrouperProvisioningConfigurationAttributeDbCache(this.grouperProvisioner, i, "entity"); + String theEntityAttributeValueCache0source = this.retrieveConfigString("entityAttributeValueCache" + i + "source", true); + this.entityAttributeDbCaches[i].setSource( + GrouperProvisioningConfigurationAttributeDbCacheSource.valueOfIgnoreCase(theEntityAttributeValueCache0source, true)); + + String theEntityAttributeValueCache0type = this.retrieveConfigString("entityAttributeValueCache" + i + "type", true); + this.entityAttributeDbCaches[i].setType( + GrouperProvisioningConfigurationAttributeDbCacheType.valueOfIgnoreCase(theEntityAttributeValueCache0type, true)); + + if (this.entityAttributeDbCaches[i].getType() == GrouperProvisioningConfigurationAttributeDbCacheType.attribute) { + this.entityAttributeDbCaches[i].setAttributeName(this.retrieveConfigString("entityAttributeValueCache" + i + "entityAttribute", true)); + } else if (this.entityAttributeDbCaches[i].getType() == GrouperProvisioningConfigurationAttributeDbCacheType.translationScript) { + this.entityAttributeDbCaches[i].setTranslationScript(this.retrieveConfigString("entityAttributeValueCache" + i + "translationScript", true)); + } else if (this.entityAttributeDbCaches[i].getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript) { + this.entityAttributeDbCaches[i].setTranslationScript(this.retrieveConfigString("entityAttributeValueCache" + i + "translationScript", true)); + } else { + throw new RuntimeException("Invalid attribute cache type: " + "entityAttributeValueCache" + i + "type" + ", " + + this.entityAttributeDbCaches[i].getType()); + } + } + } + this.refreshSubjectLinkIfLessThanAmount = GrouperUtil.intValue(this.retrieveConfigInt("refreshSubjectLinkIfLessThanAmount", false), 20); this.refreshGroupLinkIfLessThanAmount = GrouperUtil.intValue(this.retrieveConfigInt("refreshGroupLinkIfLessThanAmount", false), 20); this.refreshEntityLinkIfLessThanAmount = GrouperUtil.intValue(this.retrieveConfigInt("refreshEntityLinkIfLessThanAmount", false), 20); @@ -2426,7 +2297,6 @@ public void configureGenericSettings() { this.groupIdOfUsersToProvision = this.retrieveConfigString("groupIdOfUsersToProvision", false); - this.groupsRequireMembers = GrouperUtil.booleanValue(this.retrieveConfigBoolean("groupsRequireMembers", false), false); this.loadEntitiesToGrouperTable = GrouperUtil.booleanValue(this.retrieveConfigBoolean("loadEntitiesToGrouperTable", false), false); this.allowBlankMatchingIds = GrouperUtil.booleanValue(this.retrieveConfigBoolean("allowBlankMatchingIds", false), false); @@ -2478,7 +2348,6 @@ public void configureGenericSettings() { } this.groupSelectAttributes = new HashSet(); - this.groupSearchAttributes = new ArrayList(); for (String targetGroupAttributeName : this.targetGroupAttributeNameToConfig.keySet()) { GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = targetGroupAttributeNameToConfig.get(targetGroupAttributeName); @@ -2486,8 +2355,7 @@ public void configureGenericSettings() { this.groupSelectAttributes.add(targetGroupAttributeName); } - if (grouperProvisioningConfigurationAttribute.isMembershipAttribute()) { - this.groupAttributeNameForMemberships = targetGroupAttributeName; + if (!StringUtils.isBlank(this.groupMembershipAttributeName) && StringUtils.equals(this.groupMembershipAttributeName, grouperProvisioningConfigurationAttribute.getName())) { this.attributeNameForMemberships = targetGroupAttributeName; grouperProvisioningConfigurationAttribute.setSelect(this.isSelectMemberships()); grouperProvisioningConfigurationAttribute.setInsert(this.isInsertMemberships()); @@ -2496,26 +2364,78 @@ public void configureGenericSettings() { if (grouperProvisioningConfigurationAttribute.isMultiValued()) { this.groupAttributesMultivalued.add(targetGroupAttributeName); } - if (grouperProvisioningConfigurationAttribute.isSearchAttribute()) { - if (grouperProvisioningConfigurationAttribute.isMatchingId()) { - this.groupSearchAttributes.add(0, grouperProvisioningConfigurationAttribute); - } else { - this.groupSearchAttributes.add(grouperProvisioningConfigurationAttribute); + } + + boolean entityMatchingAttributeSameAsSearchAttribute = GrouperUtil.booleanValue(this.retrieveConfigBoolean("entityMatchingAttributeSameAsSearchAttribute", false), true); + int entityMatchingAttributeCount = GrouperUtil.intValue(this.retrieveConfigInt("entityMatchingAttributeCount", false), 0); + this.entityMatchingAttributes = new ArrayList(); + this.entitySearchAttributes = new ArrayList(); + for (int i=0;i(); + this.groupSearchAttributes = new ArrayList(); + for (int i=0;i(); - this.entitySearchAttributes = new ArrayList(); for (String targetEntityAttributeName : this.targetEntityAttributeNameToConfig.keySet()) { GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = targetEntityAttributeNameToConfig.get(targetEntityAttributeName); if (grouperProvisioningConfigurationAttribute.isSelect()) { this.entitySelectAttributes.add(targetEntityAttributeName); } - if (grouperProvisioningConfigurationAttribute.isMembershipAttribute()) { + if (!StringUtils.isBlank(this.entityMembershipAttributeName) + && StringUtils.equals(this.entityMembershipAttributeName, grouperProvisioningConfigurationAttribute.getName())) { this.attributeNameForMemberships = targetEntityAttributeName; - this.entityAttributeNameForMemberships = targetEntityAttributeName; grouperProvisioningConfigurationAttribute.setSelect(this.isSelectMemberships()); grouperProvisioningConfigurationAttribute.setInsert(this.isInsertMemberships()); } @@ -2524,25 +2444,6 @@ public void configureGenericSettings() { this.entityAttributesMultivalued.add(targetEntityAttributeName); } - if (grouperProvisioningConfigurationAttribute.isSearchAttribute()) { - if (grouperProvisioningConfigurationAttribute.isMatchingId()) { - this.entitySearchAttributes.add(0, grouperProvisioningConfigurationAttribute); - } else { - this.entitySearchAttributes.add(grouperProvisioningConfigurationAttribute); - } - } - } - - if (StringUtils.isEmpty(this.groupAttributeNameForMemberships)) { - this.groupAttributeNameForMemberships = this.retrieveConfigString("groupAttributeNameForMemberships", false); - } else if (!StringUtils.isEmpty(this.retrieveConfigString("groupAttributeNameForMemberships", false))) { - throw new RuntimeException("Should only specify membershipAttribute on one attribute or groupAttributeNameForMemberships"); - } - - if (StringUtils.isEmpty(this.entityAttributeNameForMemberships)) { - this.entityAttributeNameForMemberships = this.retrieveConfigString("userAttributeNameForMemberships", false); - } else if (!StringUtils.isEmpty(this.retrieveConfigString("userAttributeNameForMemberships", false))) { - throw new RuntimeException("Should only specify membershipAttribute on one attribute or userAttributeNameForMemberships"); } this.recalculateAllOperations = GrouperUtil.booleanValue(this.retrieveConfigBoolean("recalculateAllOperations", false), false); @@ -2582,6 +2483,8 @@ public void configureGenericSettings() { } + this.subjectIdentifierForMemberSyncTable = this.retrieveConfigString("subjectIdentifierForMemberSyncTable", false); + // diagnostics settings this.diagnosticsGroupsAllSelect = this.retrieveConfigBoolean("selectAllGroupsDuringDiagnostics", false); this.diagnosticsEntitiesAllSelect = this.retrieveConfigBoolean("selectAllEntitiesDuringDiagnostics", false); @@ -2609,11 +2512,31 @@ public boolean isGroupsRequireMembers() { return groupsRequireMembers; } + private boolean groupAttributeValueCacheHas; + + public boolean isGroupAttributeValueCacheHas() { + return groupAttributeValueCacheHas; + } + private Boolean entityAttributeValueCacheHas; + public boolean isEntityAttributeValueCacheHas() { + return entityAttributeValueCacheHas; + } + private GrouperProvisioningConfigurationAttributeDbCache[] groupAttributeDbCaches = new GrouperProvisioningConfigurationAttributeDbCache[4]; + + public GrouperProvisioningConfigurationAttributeDbCache[] getGroupAttributeDbCaches() { + return groupAttributeDbCaches; + } + private GrouperProvisioningConfigurationAttributeDbCache[] entityAttributeDbCaches = new GrouperProvisioningConfigurationAttributeDbCache[4]; + + public GrouperProvisioningConfigurationAttributeDbCache[] getEntityAttributeDbCaches() { + return entityAttributeDbCaches; + } + private void assignAutoTranslatedGroupsConfiguration() { if (this.getGrouperProvisioner().retrieveGrouperProvisioningTranslator().isTranslateGrouperToTargetAutomatically()) { @@ -2818,77 +2741,6 @@ public void setRecalculateAllOperations(boolean recalculateAllOperations) { */ private boolean configured = false; - private String entityLinkMemberFromId2; - - private String entityLinkMemberFromId3; - - private String entityLinkMemberToId2; - - private String entityLinkMemberToId3; - - - - public String getEntityLinkMemberFromId2() { - return entityLinkMemberFromId2; - } - - - - - public void setEntityLinkMemberFromId2(String entityLinkMemberFromId2) { - this.entityLinkMemberFromId2 = entityLinkMemberFromId2; - } - - - - - public String getEntityLinkMemberFromId3() { - return entityLinkMemberFromId3; - } - - - - - public void setEntityLinkMemberFromId3(String entityLinkMemberFromId3) { - this.entityLinkMemberFromId3 = entityLinkMemberFromId3; - } - - - - - public String getEntityLinkMemberToId2() { - return entityLinkMemberToId2; - } - - - - - public void setEntityLinkMemberToId2(String entityLinkMemberToId2) { - this.entityLinkMemberToId2 = entityLinkMemberToId2; - } - - - - - public String getEntityLinkMemberToId3() { - return entityLinkMemberToId3; - } - - - - - public void setEntityLinkMemberToId3(String entityLinkMemberToId3) { - this.entityLinkMemberToId3 = entityLinkMemberToId3; - } - - private String groupLinkGroupFromId2; - - private String groupLinkGroupFromId3; - - private String groupLinkGroupToId2; - - private String groupLinkGroupToId3; - /** * attribute name to config */ @@ -2909,60 +2761,6 @@ public Map getTargetEntityAtt } - public String getGroupLinkGroupFromId2() { - return groupLinkGroupFromId2; - } - - - - - public void setGroupLinkGroupFromId2(String groupLinkGroupFromId2) { - this.groupLinkGroupFromId2 = groupLinkGroupFromId2; - } - - - - - public String getGroupLinkGroupFromId3() { - return groupLinkGroupFromId3; - } - - - - - public void setGroupLinkGroupFromId3(String groupLinkGroupFromId3) { - this.groupLinkGroupFromId3 = groupLinkGroupFromId3; - } - - - - - public String getGroupLinkGroupToId2() { - return groupLinkGroupToId2; - } - - - - - public void setGroupLinkGroupToId2(String groupLinkGroupToId2) { - this.groupLinkGroupToId2 = groupLinkGroupToId2; - } - - - - - public String getGroupLinkGroupToId3() { - return groupLinkGroupToId3; - } - - - - - public void setGroupLinkGroupToId3(String groupLinkGroupToId3) { - this.groupLinkGroupToId3 = groupLinkGroupToId3; - } - - /** * configure the provisioner, call super if subclassing @@ -3013,15 +2811,6 @@ public void setDebugMap(Map debugMap) { } - public boolean isHasSubjectLink() { - return hasSubjectLink; - } - - - public void setHasSubjectLink(boolean hasSubjectLink) { - this.hasSubjectLink = hasSubjectLink; - } - public boolean isHasTargetGroupLink() { return hasTargetGroupLink; diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationAttribute.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationAttribute.java index e4081630aab9..9afc950dd9bf 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationAttribute.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationAttribute.java @@ -7,14 +7,109 @@ import java.util.Set; import java.util.TreeSet; +import org.apache.commons.lang3.StringUtils; + import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncMember; public class GrouperProvisioningConfigurationAttribute { private GrouperProvisioner grouperProvisioner; + private GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache; + + private boolean grouperProvisioningConfigurationAttributeDbCacheRetrieved = false; + /** + * + * @return if this is a member cache attribute + */ + public GrouperProvisioningConfigurationAttributeDbCache getSyncMemberCacheAttribute() { + + // this is only for entities + if (this.grouperProvisioningConfigurationAttributeType != GrouperProvisioningConfigurationAttributeType.entity) { + return null; + } + + // cache this + if (this.grouperProvisioningConfigurationAttributeDbCacheRetrieved) { + return this.grouperProvisioningConfigurationAttributeDbCache; + } + + this.grouperProvisioningConfigurationAttributeDbCacheRetrieved = true; + + for (GrouperProvisioningConfigurationAttributeDbCache theGrouperProvisioningConfigurationAttributeDbCache + : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()) { + + if (theGrouperProvisioningConfigurationAttributeDbCache != null + && StringUtils.equals(this.name, theGrouperProvisioningConfigurationAttributeDbCache.getAttributeName())) { + this.grouperProvisioningConfigurationAttributeDbCache = theGrouperProvisioningConfigurationAttributeDbCache; + break; + } + } + return this.grouperProvisioningConfigurationAttributeDbCache; + } + /** + * + * @return if this is a group cache attribute + */ + public GrouperProvisioningConfigurationAttributeDbCache getSyncGroupCacheAttribute() { + + // this is only for groups + if (this.grouperProvisioningConfigurationAttributeType != GrouperProvisioningConfigurationAttributeType.group) { + return null; + } + + // cache this + if (this.grouperProvisioningConfigurationAttributeDbCacheRetrieved) { + return this.grouperProvisioningConfigurationAttributeDbCache; + } + + this.grouperProvisioningConfigurationAttributeDbCacheRetrieved = true; + + for (GrouperProvisioningConfigurationAttributeDbCache theGrouperProvisioningConfigurationAttributeDbCache + : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()) { + + if (theGrouperProvisioningConfigurationAttributeDbCache != null + && StringUtils.equals(this.name, theGrouperProvisioningConfigurationAttributeDbCache.getAttributeName())) { + this.grouperProvisioningConfigurationAttributeDbCache = theGrouperProvisioningConfigurationAttributeDbCache; + break; + } + } + return this.grouperProvisioningConfigurationAttributeDbCache; + } + + /** + * + * @return if this is a translatable attribute from sync member + */ + public boolean isSyncMemberAttribute() { + return StringUtils.equals("memberId", this.translateFromGrouperProvisioningEntityField) + || StringUtils.equals("subjectId", this.translateFromGrouperProvisioningEntityField) + || StringUtils.equals("subjectIdentifier", this.translateFromGrouperProvisioningEntityField) + || StringUtils.equals("entityAttributeValueCache0", this.translateFromGrouperProvisioningEntityField) + || StringUtils.equals("entityAttributeValueCache1", this.translateFromGrouperProvisioningEntityField) + || StringUtils.equals("entityAttributeValueCache2", this.translateFromGrouperProvisioningEntityField) + || StringUtils.equals("entityAttributeValueCache3", this.translateFromGrouperProvisioningEntityField); + + } + + /** + * + * @return if this is a translatable attribute from sync group + */ + public boolean isSyncGroupAttribute() { + return StringUtils.equals("groupId", this.translateFromGrouperProvisioningGroupField) + || StringUtils.equals("groupIdIndex", this.translateFromGrouperProvisioningGroupField) + || StringUtils.equals("groupExtension", this.translateFromGrouperProvisioningGroupField) + || StringUtils.equals("groupName", this.translateFromGrouperProvisioningGroupField) + || StringUtils.equals("groupAttributeValueCache0", this.translateFromGrouperProvisioningGroupField) + || StringUtils.equals("groupAttributeValueCache1", this.translateFromGrouperProvisioningGroupField) + || StringUtils.equals("groupAttributeValueCache2", this.translateFromGrouperProvisioningGroupField) + || StringUtils.equals("groupAttributeValueCache3", this.translateFromGrouperProvisioningGroupField); + } + public GrouperProvisioner getGrouperProvisioner() { return grouperProvisioner; } @@ -78,51 +173,6 @@ public void setGrouperProvisioningConfigurationAttributeType( public GrouperProvisioningConfigurationAttribute() { } - /** - * After calculating the Grouper value store that in a sync field - */ - private String translateGrouperToMemberSyncField; - - /** - * After calculating the Grouper value store that in a sync field - * @return - */ - public String getTranslateGrouperToMemberSyncField() { - return translateGrouperToMemberSyncField; - } - - /** - * After calculating the Grouper value store that in a sync field - * @param translateGrouperToMemberSyncField - */ - public void setTranslateGrouperToMemberSyncField( - String translateGrouperToMemberSyncField) { - this.translateGrouperToMemberSyncField = translateGrouperToMemberSyncField; - } - - /** - * After calculating the Grouper value store that in a sync field - */ - private String translateGrouperToGroupSyncField; - - - - /** - * After calculating the Grouper value store that in a sync field - * @return - */ - public String getTranslateGrouperToGroupSyncField() { - return translateGrouperToGroupSyncField; - } - - /** - * After calculating the Grouper value store that in a sync field - * @param translateGrouperToGroupSyncField - */ - public void setTranslateGrouperToGroupSyncField(String translateGrouperToGroupSyncField) { - this.translateGrouperToGroupSyncField = translateGrouperToGroupSyncField; - } - @Override public String toString() { @@ -131,6 +181,8 @@ public String toString() { Set fieldNames = GrouperUtil.fieldNames(GrouperProvisioningConfigurationAttribute.class, null, false); fieldNames.remove("grouperProvisioner"); + fieldNames.remove("grouperProvisioningConfigurationAttributeDbCache"); + fieldNames.remove("grouperProvisioningConfigurationAttributeDbCacheRetrieved"); fieldNames = new TreeSet(fieldNames); boolean firstField = true; @@ -160,56 +212,6 @@ public String toString() { return result.toString(); } - /** - * - */ - private String translateFromMemberSyncField; - - /** - * take this value from target and copy into the sync field - */ - private String translateToGroupSyncField; - - - - /** - * take this value from target and copy into the sync field - * @return - */ - public String getTranslateToGroupSyncField() { - return translateToGroupSyncField; - } - - /** - * take this value from target and copy into the sync field - * @param translateToGroupSyncField - */ - public void setTranslateToGroupSyncField(String translateToGroupSyncField) { - this.translateToGroupSyncField = translateToGroupSyncField; - } - - /** - * take this value from target and copy into the sync field - */ - private String translateToMemberSyncField; - - - /** - * take this value from target and copy into the sync field - * @return - */ - public String getTranslateToMemberSyncField() { - return translateToMemberSyncField; - } - - /** - * take this value from target and copy into the sync field - * @param translateToEntitySyncField - */ - public void setTranslateToMemberSyncField(String translateToEntitySyncField) { - this.translateToMemberSyncField = translateToEntitySyncField; - } - /** * grouper provisioning entity field */ @@ -299,31 +301,6 @@ public void setTranslateFromGrouperProvisioningGroupField( this.translateFromGrouperProvisioningGroupField = translateFromGrouperProvisioningGroupField; } - /** - * - */ - private String translateFromGroupSyncField; - - - public String getTranslateFromMemberSyncField() { - return translateFromMemberSyncField; - } - - - public void setTranslateFromMemberSyncField(String translateFromMemberSyncField) { - this.translateFromMemberSyncField = translateFromMemberSyncField; - } - - - public String getTranslateFromGroupSyncField() { - return translateFromGroupSyncField; - } - - - public void setTranslateFromGroupSyncField(String translateFromGroupSyncField) { - this.translateFromGroupSyncField = translateFromGroupSyncField; - } - /** * attribute or field name */ @@ -458,43 +435,6 @@ public void setIgnoreIfMatchesValue(Set ignoreIfMatchesValues) { */ private String translateFromStaticValuesCreateOnly; - /** - * NOTE: CURRENTLY NOT USED - * expression when translating a group or entity membership attribute - */ - private String translateExpressionFromMembership; - - /** - * if this attribute is used as the matching id - */ - private boolean matchingId; - - /** - * if this attribute is the membership attribute - */ - private boolean membershipAttribute; - - /** - * if this is the attribute used to search for objects in the target - */ - private boolean searchAttribute; - - /** - * if this is the attribute used to search for objects in the target - * @return - */ - public boolean isSearchAttribute() { - return searchAttribute; - } - - /** - * if this is the attribute used to search for objects in the target - * @param searchAttribute - */ - public void setSearchAttribute(boolean searchAttribute) { - this.searchAttribute = searchAttribute; - } - /** * attribute or field name * @return @@ -577,12 +517,26 @@ public boolean isUpdateConsiderMemberships() { return true; } GrouperProvisioningBehavior grouperProvisioningBehavior = this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior(); - if ((grouperProvisioningBehavior.getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.groupAttributes - || grouperProvisioningBehavior.getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.entityAttributes) - && this.isMembershipAttribute() && (grouperProvisioningBehavior.isInsertMemberships() + + GrouperProvisioningConfiguration grouperProvisioningConfiguration = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration(); + + if (grouperProvisioningBehavior.getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.groupAttributes + && this.grouperProvisioningConfigurationAttributeType == GrouperProvisioningConfigurationAttributeType.group + && !StringUtils.isBlank(grouperProvisioningConfiguration.getGroupMembershipAttributeName()) + && StringUtils.equals(grouperProvisioningConfiguration.getGroupMembershipAttributeName(), this.name) + && (grouperProvisioningBehavior.isInsertMemberships() + || grouperProvisioningBehavior.isDeleteMemberships() || grouperProvisioningBehavior.isUpdateMemberships())) { + return true; + } + if (grouperProvisioningBehavior.getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.entityAttributes + && this.grouperProvisioningConfigurationAttributeType == GrouperProvisioningConfigurationAttributeType.entity + && !StringUtils.isBlank(grouperProvisioningConfiguration.getEntityMembershipAttributeName()) + && StringUtils.equals(grouperProvisioningConfiguration.getEntityMembershipAttributeName(), this.name) + && (grouperProvisioningBehavior.isInsertMemberships() || grouperProvisioningBehavior.isDeleteMemberships() || grouperProvisioningBehavior.isUpdateMemberships())) { return true; } + return false; } @@ -642,56 +596,6 @@ public void setTranslateExpressionCreateOnly(String translateExpressionCreateOnl this.translateExpressionCreateOnly = translateExpressionCreateOnly; } - /** - * if this attribute is used as the matching id - * @return - */ - public boolean isMatchingId() { - return matchingId; - } - - /** - * if this attribute is used as the matching id - * @param matchingId - */ - public void setMatchingId(boolean matchingId) { - this.matchingId = matchingId; - } - - /** - * if this attribute is the membership attribute - * @return - */ - public boolean isMembershipAttribute() { - return membershipAttribute; - } - - /** - * if this attribute is the membership attribute - * @param membershipAttribute - */ - public void setMembershipAttribute(boolean membershipAttribute) { - this.membershipAttribute = membershipAttribute; - } - - - /** - * NOTE: CURRENTLY NOT USED - * @return expression when translating a group or entity membership attribute - */ - public String getTranslateExpressionFromMembership() { - return translateExpressionFromMembership; - } - - /** - * expression when translating a group or entity membership attribute - * @param translateExpressionFromMembership - */ - public void setTranslateExpressionFromMembership( - String translateExpressionFromMembership) { - this.translateExpressionFromMembership = translateExpressionFromMembership; - } - /** * default value if there is not a value */ diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationAttributeDbCache.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationAttributeDbCache.java new file mode 100644 index 000000000000..f686b097963c --- /dev/null +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationAttributeDbCache.java @@ -0,0 +1,186 @@ +package edu.internet2.middleware.grouper.app.provisioning; + +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; + +import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncGroup; + +public class GrouperProvisioningConfigurationAttributeDbCache { + + /** + * get all the cached values for a group attribute. + * these are prioritized by most important. + * note, the current value will not be returned + * @param someTargetGroup + * @param attributeName + * @return the set of values + */ + public static Set cachedValuesForGroup(ProvisioningGroup someTargetGroup, String attributeName) { + Set cachedValues = new LinkedHashSet(); + if (someTargetGroup.getProvisioningGroupWrapper() == null + || someTargetGroup.getProvisioningGroupWrapper().getGcGrouperSyncGroup() == null) { + return cachedValues; + } + GcGrouperSyncGroup gcGrouperSyncGroup = someTargetGroup.getProvisioningGroupWrapper().getGcGrouperSyncGroup(); + Object currentValue = someTargetGroup.retrieveAttributeValue(attributeName); + GrouperProvisioner grouperProvisioner = someTargetGroup.getGrouperProvisioner(); + // look in target first + for (GrouperProvisioningConfigurationAttributeDbCacheSource source : + new GrouperProvisioningConfigurationAttributeDbCacheSource[] { + GrouperProvisioningConfigurationAttributeDbCacheSource.target, + GrouperProvisioningConfigurationAttributeDbCacheSource.grouper + }) { + + // see if there is an attribute cached + for (GrouperProvisioningConfigurationAttributeDbCache cache : + grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()) { + if (cache == null || cache.getSource() != source || !StringUtils.equals(attributeName, cache.getAttributeName())) { + continue; + } + Object value = gcGrouperSyncGroup.retrieveField("groupAttributeValueCache" + cache.getIndex()); + if (!GrouperUtil.isBlank(value) && !GrouperUtil.equals(value, currentValue) && !cachedValues.contains(value)) { + cachedValues.add(value); + } + } + + // TODO finish this for object cache +// // see if there is an object cached +// for (GrouperProvisioningConfigurationAttributeDbCache cache : +// grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()) { +// if (cache == null || cache.getSource() != source || cache.getType() != GrouperProvisioningConfigurationAttributeDbCacheType.object) { +// continue; +// } +// +// +// +// Object value = gcGrouperSyncGroup.retrieveField("groupAttributeValueCache" + cache.getIndex()); +// if (!GrouperUtil.isBlank(value) && !GrouperUtil.equals(value, currentValue) && !cachedValues.contains(value)) { +// cachedValues.add(value); +// } +// } + + + } + return cachedValues; + } + + public String toString() { + StringBuilder result = new StringBuilder(this.objectType).append("Cache("); + result.append("index: ").append(this.index); + result.append(", source: ").append(this.source); + result.append(", type: ").append(this.type); + if (!StringUtils.isBlank(this.attributeName)) { + result.append(", attributeName: ").append(this.attributeName); + } + if (!StringUtils.isBlank(this.translationScript)) { + result.append(", translationScript: ").append(this.translationScript); + } + + return result.append(")").toString(); + } + + private String cacheName = null; + + public String getCacheName() { + if (this.cacheName == null) { + this.cacheName = this.objectType + "AttributeValueCache" + this.index; + } + return this.cacheName; + } + + public GrouperProvisioningConfigurationAttributeDbCache(GrouperProvisioner grouperProvisioner1, int index1, String objectType1) { + this.grouperProvisioner = grouperProvisioner1; + this.index = index1; + this.objectType = objectType1; + } + + public GrouperProvisioningConfigurationAttribute retrieveAttribute() { + if (this.type != GrouperProvisioningConfigurationAttributeDbCacheType.attribute + || StringUtils.isBlank(this.attributeName)) { + return null; + } + + Map targetGroupAttributeNameToConfig = null; + + if (StringUtils.equals("group", this.objectType)) { + targetGroupAttributeNameToConfig = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig(); + } else if (StringUtils.equals("entity", this.objectType)) { + targetGroupAttributeNameToConfig = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig(); + } else { + throw new RuntimeException("Invalid object type '" + this.objectType + "'"); + } + + GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = targetGroupAttributeNameToConfig.get(this.attributeName); + + GrouperUtil.assertion(grouperProvisioningConfigurationAttribute != null, this.objectType + " attribute cache " + this.index + " attribute not found: '" + this.attributeName + "'"); + + return grouperProvisioningConfigurationAttribute; + } + + private GrouperProvisioner grouperProvisioner = null; + + /** + * group or entity + */ + private String objectType; + + /** + * group or entity + * @return the object type + */ + public String getObjectType() { + return objectType; + } + + private int index; + + + private GrouperProvisioningConfigurationAttributeDbCacheSource source; + + private GrouperProvisioningConfigurationAttributeDbCacheType type; + + private String attributeName; + + private String translationScript; + + public int getIndex() { + return index; + } + + public GrouperProvisioningConfigurationAttributeDbCacheSource getSource() { + return source; + } + + public void setSource(GrouperProvisioningConfigurationAttributeDbCacheSource source) { + this.source = source; + } + + public GrouperProvisioningConfigurationAttributeDbCacheType getType() { + return type; + } + + public void setType(GrouperProvisioningConfigurationAttributeDbCacheType type) { + this.type = type; + } + + public String getAttributeName() { + return attributeName; + } + + public void setAttributeName(String attributeName) { + this.attributeName = attributeName; + } + + public String getTranslationScript() { + return translationScript; + } + + public void setTranslationScript(String translationScript) { + this.translationScript = translationScript; + } + +} diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationAttributeDbCacheSource.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationAttributeDbCacheSource.java new file mode 100644 index 000000000000..48ea4c516091 --- /dev/null +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationAttributeDbCacheSource.java @@ -0,0 +1,21 @@ +package edu.internet2.middleware.grouper.app.provisioning; + +import edu.internet2.middleware.grouper.app.attestation.AttestationType; +import edu.internet2.middleware.grouper.util.GrouperUtil; + +public enum GrouperProvisioningConfigurationAttributeDbCacheSource { + grouper, target; + + /** + * do a case-insensitive matching + * + * @param string + * @param exceptionOnBlank will not allow null or blank entries + * @return the enum or null or exception if not found + */ + public static GrouperProvisioningConfigurationAttributeDbCacheSource valueOfIgnoreCase(String string, boolean exceptionOnBlank) { + return GrouperUtil.enumValueOfIgnoreCase(GrouperProvisioningConfigurationAttributeDbCacheSource.class, + string, exceptionOnBlank); + } + +} diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationAttributeDbCacheType.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationAttributeDbCacheType.java new file mode 100644 index 000000000000..55180b7c7bbf --- /dev/null +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationAttributeDbCacheType.java @@ -0,0 +1,33 @@ +package edu.internet2.middleware.grouper.app.provisioning; + +import org.apache.commons.lang3.StringUtils; + +import edu.internet2.middleware.grouper.util.GrouperUtil; + +/** + * + * @author mchyzer + * + */ +public enum GrouperProvisioningConfigurationAttributeDbCacheType { + + attribute, object, subjectTranslationScript, translationScript; + + /** + * do a case-insensitive matching + * + * @param string + * @param exceptionOnBlank will not allow null or blank entries + * @return the enum or null or exception if not found + */ + public static GrouperProvisioningConfigurationAttributeDbCacheType valueOfIgnoreCase(String string, boolean exceptionOnBlank) { + if (StringUtils.equalsIgnoreCase(string, "groupAttribute") || StringUtils.equalsIgnoreCase(string, "entityAttribute")) { + return GrouperProvisioningConfigurationAttributeDbCacheType.attribute; + } + if (StringUtils.equalsIgnoreCase(string, "groupObject") || StringUtils.equalsIgnoreCase(string, "entityObject")) { + return GrouperProvisioningConfigurationAttributeDbCacheType.object; + } + return GrouperUtil.enumValueOfIgnoreCase(GrouperProvisioningConfigurationAttributeDbCacheType.class, + string, exceptionOnBlank); + } +} diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationValidation.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationValidation.java index 3f629205cee5..204c572ef652 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationValidation.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningConfigurationValidation.java @@ -434,10 +434,11 @@ public void validateFromSuffixValueMap() { public void validateOperateOnEntitiesIfSubjectSourcesToProvision() { boolean operateOnGrouperEntities = GrouperUtil.booleanValue(this.suffixToConfigValue.get("operateOnGrouperEntities"), false); + boolean operateOnGrouperMemberships = GrouperUtil.booleanValue(this.suffixToConfigValue.get("operateOnGrouperMemberships"), false); String subjectSourcesToProvision = this.suffixToConfigValue.get("subjectSourcesToProvision"); - if (!StringUtils.isBlank(subjectSourcesToProvision) && !operateOnGrouperEntities) { + if (!StringUtils.isBlank(subjectSourcesToProvision) && !operateOnGrouperEntities && !operateOnGrouperMemberships) { this.addErrorMessage(new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("grouperProvisioningSubjectSourcesToProvisionRequiresEntitiesInvalid"))); } @@ -516,45 +517,30 @@ public void validateMatchingAttributes() { boolean hasGroupMembershipId = false; boolean hasMemberMembershipId = false; - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : grouperProvisioningConfigurationAttributes) { - //validate the matching attributes come from gcSync objects - - if (grouperProvisioningConfigurationAttribute.isMatchingId()) { - - if (grouperProvisioningConfigurationAttribute.getGrouperProvisioningConfigurationAttributeType() == GrouperProvisioningConfigurationAttributeType.entity) { - hasMemberMatchingId = true; - } - if (grouperProvisioningConfigurationAttribute.getGrouperProvisioningConfigurationAttributeType() == GrouperProvisioningConfigurationAttributeType.group) { - hasGroupMatchingId = true; - } - if (grouperProvisioningConfigurationAttribute.getGrouperProvisioningConfigurationAttributeType() == GrouperProvisioningConfigurationAttributeType.membership) { - hasMembershipMatchingId = true; - } - + for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : GrouperUtil.nonNull(grouperProvisioningConfiguration.getGroupMatchingAttributes())) { + if (grouperProvisioningConfigurationAttribute != null) { + hasGroupMatchingId = true; } - - - if (grouperProvisioningConfigurationAttribute.isMembershipAttribute()) { - - if (StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateFromGroupSyncField()) - && StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateFromMemberSyncField())) { - -// throw new RuntimeException(grouperProvisioningConfigurationAttribute.getGrouperProvisioningConfigurationAttributeType() -// + " " + (grouperProvisioningConfigurationAttribute.isAttribute() ? "attribute" : "field") + " '" + grouperProvisioningConfigurationAttribute.getName() -// + "' is a membership attribute but does not have a translation from a sync field. It must have a translation from a sync field! " + grouperProvisioningConfigurationAttribute); - } - - if (grouperProvisioningConfigurationAttribute.getGrouperProvisioningConfigurationAttributeType() == GrouperProvisioningConfigurationAttributeType.entity) { - hasMemberMembershipId = true; - } - if (grouperProvisioningConfigurationAttribute.getGrouperProvisioningConfigurationAttributeType() == GrouperProvisioningConfigurationAttributeType.group) { - hasGroupMembershipId = true; - } - + } + + for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : GrouperUtil.nonNull(grouperProvisioningConfiguration.getEntityMatchingAttributes())) { + if (grouperProvisioningConfigurationAttribute != null) { + hasMemberMatchingId = true; } - } - + + if (!StringUtils.isBlank(grouperProvisioningConfiguration.getGroupMembershipAttributeName())) { + if (grouperProvisioningConfiguration.getTargetGroupAttributeNameToConfig().get(grouperProvisioningConfiguration.getGroupMembershipAttributeName()) != null) { + hasGroupMembershipId = true; + } + } + + if (!StringUtils.isBlank(grouperProvisioningConfiguration.getEntityMembershipAttributeName())) { + if (grouperProvisioningConfiguration.getTargetEntityAttributeNameToConfig().get(grouperProvisioningConfiguration.getEntityMembershipAttributeName()) != null) { + hasMemberMembershipId = true; + } + } + if (grouperProvisioningConfiguration.getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.groupAttributes) { if (!hasGroupMatchingId) { this.addErrorMessage(new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.mustHaveGroupMatchingId"))); @@ -719,36 +705,28 @@ public void validateGroupLinkHasConfiguration() { if (hasTargetGroupLink) { // check attributes - for (int i=0; i< 20; i++) { - - String name = suffixToConfigValue.get("targetGroupAttribute."+i+".name"); - if (StringUtils.isBlank(name)) { - break; - } + for (GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()) { - // there is an attribute here - String translateToGroupSyncField = suffixToConfigValue.get("targetGroupAttribute."+i+".translateToGroupSyncField"); - - if (!StringUtils.isBlank(translateToGroupSyncField)) { + if (grouperProvisioningConfigurationAttributeDbCache != null) { return; } - + } // check scripts - if (!StringUtils.isBlank(suffixToConfigValue.get("common.groupLink.groupFromId2"))) { + if (!StringUtils.isBlank(suffixToConfigValue.get("common.groupLink.groupAttributeValueCache0"))) { return; } - if (!StringUtils.isBlank(suffixToConfigValue.get("common.groupLink.groupFromId3"))) { + if (!StringUtils.isBlank(suffixToConfigValue.get("common.groupLink.groupAttributeValueCache1"))) { return; } - if (!StringUtils.isBlank(suffixToConfigValue.get("common.groupLink.groupToId2"))) { + if (!StringUtils.isBlank(suffixToConfigValue.get("common.groupLink.groupAttributeValueCache2"))) { return; } - if (!StringUtils.isBlank(suffixToConfigValue.get("common.groupLink.groupToId3"))) { + if (!StringUtils.isBlank(suffixToConfigValue.get("common.groupLink.groupAttributeValueCache3"))) { return; } this.addErrorMessage(new ProvisioningValidationIssue() @@ -763,8 +741,6 @@ public void validateGroupLinkHasConfiguration() { /** * if there is a entity delete, then there must be one delete type - * @param suffixToConfigValue - * @return */ public void validateEntityLinkHasConfiguration() { @@ -772,36 +748,28 @@ public void validateEntityLinkHasConfiguration() { if (hasTargetEntityLink) { // check attributes - for (int i=0; i< 20; i++) { - - String name = suffixToConfigValue.get("targetEntityAttribute."+i+".name"); - if (StringUtils.isBlank(name)) { - break; - } - - // there is an attribute here - String translateToEntitySyncField = suffixToConfigValue.get("targetEntityAttribute."+i+".translateToMemberSyncField"); + for (GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()) { - if (!StringUtils.isBlank(translateToEntitySyncField)) { + if (grouperProvisioningConfigurationAttributeDbCache != null) { return; } - + } // check scripts - if (!StringUtils.isBlank(suffixToConfigValue.get("common.entityLink.memberFromId2"))) { + if (!StringUtils.isBlank(suffixToConfigValue.get("common.entityLink.entityAttributeValueCache0"))) { return; } - if (!StringUtils.isBlank(suffixToConfigValue.get("common.entityLink.memberFromId3"))) { + if (!StringUtils.isBlank(suffixToConfigValue.get("common.entityLink.entityAttributeValueCache1"))) { return; } - if (!StringUtils.isBlank(suffixToConfigValue.get("common.entityLink.memberToId2"))) { + if (!StringUtils.isBlank(suffixToConfigValue.get("common.entityLink.entityAttributeValueCache2"))) { return; } - if (!StringUtils.isBlank(suffixToConfigValue.get("common.entityLink.mmeberToId3"))) { + if (!StringUtils.isBlank(suffixToConfigValue.get("common.entityLink.entityAttributeValueCache3"))) { return; } this.addErrorMessage(new ProvisioningValidationIssue() @@ -823,41 +791,26 @@ public void validateGroupLinkOnePerBucket() { if (!hasTargetGroupLink) { return; } - - String errorMessage = GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetGroupLinkMultipleToSameBucket"); + + String errorMessage = GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetGroupLinkMultipleFromSameAttribute"); + + Set attributeNames = new HashSet(); - for (String bucket : new String[] {"groupFromId2", "groupFromId3", "groupToId2", "groupToId3"}) { + for (GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()) { - List currentErrors = new ArrayList(); - - // check attributes - for (int i=0; i< 20; i++) { - - String name = suffixToConfigValue.get("targetGroupAttribute."+i+".name"); - if (StringUtils.isBlank(name)) { - break; - } - - // there is an attribute here - String suffix = "targetGroupAttribute."+i+".translateToGroupSyncField"; - String translateToGroupSyncField = suffixToConfigValue.get(suffix); - - if (StringUtils.equals(bucket, translateToGroupSyncField)) { - currentErrors.add(new ProvisioningValidationIssue().assignMessage(errorMessage).assignJqueryHandle(suffix)); - } - - } - - String suffix = "common.groupLink." + bucket; - if (!StringUtils.isBlank(suffixToConfigValue.get(suffix))) { - currentErrors.add(new ProvisioningValidationIssue().assignMessage(errorMessage).assignJqueryHandle(suffix)); + if (grouperProvisioningConfigurationAttributeDbCache == null || StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache.getAttributeName())) { + continue; } - if (currentErrors.size() > 1) { - this.addErrorMessages(currentErrors); + if (attributeNames.contains(grouperProvisioningConfigurationAttributeDbCache.getAttributeName())) { + String suffix = "groupAttributeValueCache" + grouperProvisioningConfigurationAttributeDbCache.getIndex() + "groupAttribute"; + this.addErrorMessage(new ProvisioningValidationIssue().assignMessage(errorMessage).assignJqueryHandle(suffix)); } + + attributeNames.add(grouperProvisioningConfigurationAttributeDbCache.getAttributeName()); + } - + } /** @@ -942,40 +895,24 @@ public void validateEntityLinkOnePerBucket() { return; } - String errorMessage = GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkMultipleToSameBucket"); + String errorMessage = GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkMultipleFromSameAttribute"); + + Set attributeNames = new HashSet(); - for (String bucket : new String[] {"memberFromId2", "memberFromId3", "memberToId2", "memberToId3"}) { + for (GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()) { - List currentErrors = new ArrayList(); - - // check attributes - for (int i=0; i< 20; i++) { - - String name = suffixToConfigValue.get("targetEntityAttribute."+i+".name"); - if (StringUtils.isBlank(name)) { - break; - } - - // there is an attribute here - String suffix = "targetEntityAttribute."+i+".translateToMemberSyncField"; - String translateToGroupSyncField = suffixToConfigValue.get(suffix); - - if (StringUtils.equals(bucket, translateToGroupSyncField)) { - currentErrors.add(new ProvisioningValidationIssue().assignMessage(errorMessage).assignJqueryHandle(suffix)); - } - - } - - String suffix = "common.entityLink." + bucket; - if (!StringUtils.isBlank(suffixToConfigValue.get(suffix))) { - currentErrors.add(new ProvisioningValidationIssue().assignMessage(errorMessage).assignJqueryHandle(suffix)); + if (grouperProvisioningConfigurationAttributeDbCache == null || StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache.getAttributeName())) { + continue; } - if (currentErrors.size() > 1) { - this.addErrorMessages(currentErrors); + if (attributeNames.contains(grouperProvisioningConfigurationAttributeDbCache.getAttributeName())) { + String suffix = "entityAttributeValueCache" + grouperProvisioningConfigurationAttributeDbCache.getIndex() + "entityAttribute"; + this.addErrorMessage(new ProvisioningValidationIssue().assignMessage(errorMessage).assignJqueryHandle(suffix)); } + + attributeNames.add(grouperProvisioningConfigurationAttributeDbCache.getAttributeName()); + } - } /** diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningDiagnosticsContainer.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningDiagnosticsContainer.java index 074a30430ade..34e22d589a8e 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningDiagnosticsContainer.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningDiagnosticsContainer.java @@ -317,7 +317,12 @@ private void appendSelectGroupFromGrouper() { if (GrouperUtil.isBlank(grouperTargetGroup.getMatchingId())) { - GrouperProvisioningConfigurationAttribute matchingAttribute = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().retrieveGroupAttributeMatching(); + // TODO handle multiple matching IDs + GrouperProvisioningConfigurationAttribute matchingAttribute = null; + if (GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupMatchingAttributes()) > 0) { + matchingAttribute = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupMatchingAttributes().get(0); + } + if (matchingAttribute == null) { if (this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().isInsertGroups() || this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().isUpdateGroups() || this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().isDeleteGroups()) { @@ -437,7 +442,12 @@ private void appendSelectEntityFromGrouper() { if (GrouperUtil.isBlank(grouperTargetEntity.getMatchingId())) { - GrouperProvisioningConfigurationAttribute matchingAttribute = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().retrieveEntityAttributeMatching(); + // TODO handle multiple matching IDs + GrouperProvisioningConfigurationAttribute matchingAttribute = null; + if (GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityMatchingAttributes()) > 0) { + matchingAttribute = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityMatchingAttributes().get(0); + } + if (matchingAttribute == null) { if (this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().isInsertEntities() || this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().isUpdateEntities() || this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().isDeleteEntities()) { this.report.append("Error: Cannot find the entity matching attribute/field\n"); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningFullSyncJob.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningFullSyncJob.java index 27e5981e0098..1f4770e20a86 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningFullSyncJob.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningFullSyncJob.java @@ -55,6 +55,7 @@ public void run() { grouperProvisioner.setJobName(hib3GrouperLoaderLog.getJobName()); GrouperProvisioningOutput grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); + grouperProvisioningOutput.setHib3GrouperLoaderLog(hib3GrouperLoaderLog); grouperProvisioningOutput.copyToHib3LoaderLog(); hib3GrouperLoaderLog.store(); } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningGrouperDao.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningGrouperDao.java index d5c3060bf05f..b10716423464 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningGrouperDao.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningGrouperDao.java @@ -248,10 +248,11 @@ public List retrieveMembers(boolean retrieveAll, Collection< for (int j = 0; j < (GrouperUtil.length(subjectSources) + GrouperUtil.length(fieldIds)); j++) { typesInitial.add(StringType.INSTANCE); } - - sqlInitial.append(" and gm.subject_source in ("); - sqlInitial.append(HibUtils.convertToInClauseForSqlStatic(subjectSources)); - sqlInitial.append(") "); + if (GrouperUtil.length(subjectSources) > 0) { + sqlInitial.append(" and gm.subject_source in ("); + sqlInitial.append(HibUtils.convertToInClauseForSqlStatic(subjectSources)); + sqlInitial.append(") "); + } sqlInitial.append(" and gs.field_id in ("); sqlInitial.append(HibUtils.convertToInClauseForSqlStatic(fieldIds)); @@ -470,9 +471,11 @@ public List retrieveMemberships(boolean retrieveAll, Col typesInitial.add(StringType.INSTANCE); } - sqlInitial.append(" and gm.subject_source in ("); - sqlInitial.append(HibUtils.convertToInClauseForSqlStatic(subjectSources)); - sqlInitial.append(") "); + if (GrouperUtil.length(subjectSources) > 0) { + sqlInitial.append(" and gm.subject_source in ("); + sqlInitial.append(HibUtils.convertToInClauseForSqlStatic(subjectSources)); + sqlInitial.append(") "); + } sqlInitial.append(" and gs.field_id in ("); sqlInitial.append(HibUtils.convertToInClauseForSqlStatic(fieldIds)); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningGrouperSyncDao.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningGrouperSyncDao.java index 77864086b3e3..3243bd373460 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningGrouperSyncDao.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningGrouperSyncDao.java @@ -472,24 +472,36 @@ public void updateSubjectLink( } // If using subject attributes and those are not in the member sync object, then resolve the subject, and put in the member sync object - String subjectLinkMemberFromId2 = this.grouperProvisioner - .retrieveGrouperProvisioningConfiguration().getSubjectLinkMemberFromId2(); - boolean hasSubjectLinkMemberFromId2 = !StringUtils.isBlank(subjectLinkMemberFromId2); - - String subjectLinkMemberFromId3 = this.grouperProvisioner - .retrieveGrouperProvisioningConfiguration().getSubjectLinkMemberFromId3(); - boolean hasSubjectLinkMemberFromId3 = !StringUtils.isBlank(subjectLinkMemberFromId3); - - String subjectLinkMemberToId2 = this.grouperProvisioner - .retrieveGrouperProvisioningConfiguration().getSubjectLinkMemberToId2(); - boolean hasSubjectLinkMemberToId2 = !StringUtils.isBlank(subjectLinkMemberToId2); - - String subjectLinkMemberToId3 = this.grouperProvisioner - .retrieveGrouperProvisioningConfiguration().getSubjectLinkMemberToId3(); - boolean hasSubjectLinkMemberToId3 = !StringUtils.isBlank(subjectLinkMemberToId3); - - if (!hasSubjectLinkMemberFromId2 && !hasSubjectLinkMemberFromId3 - && !hasSubjectLinkMemberToId2 && !hasSubjectLinkMemberToId3) { + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache0 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[0]; + boolean hasSubjectLinkAttributeValueCache0 = grouperProvisioningConfigurationAttributeDbCache0 != null + && grouperProvisioningConfigurationAttributeDbCache0.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.grouper + && grouperProvisioningConfigurationAttributeDbCache0.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache0.getTranslationScript()); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache1 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[1]; + boolean hasSubjectLinkAttributeValueCache1 = grouperProvisioningConfigurationAttributeDbCache1 != null + && grouperProvisioningConfigurationAttributeDbCache1.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.grouper + && grouperProvisioningConfigurationAttributeDbCache1.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache1.getTranslationScript()); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache2 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[2]; + boolean hasSubjectLinkAttributeValueCache2 = grouperProvisioningConfigurationAttributeDbCache2 != null + && grouperProvisioningConfigurationAttributeDbCache2.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.grouper + && grouperProvisioningConfigurationAttributeDbCache2.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache2.getTranslationScript()); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache3 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[3]; + boolean hasSubjectLinkAttributeValueCache3 = grouperProvisioningConfigurationAttributeDbCache3 != null + && grouperProvisioningConfigurationAttributeDbCache3.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.grouper + && grouperProvisioningConfigurationAttributeDbCache3.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache3.getTranslationScript()); + + if (!hasSubjectLinkAttributeValueCache0 && !hasSubjectLinkAttributeValueCache1 + && !hasSubjectLinkAttributeValueCache2 && !hasSubjectLinkAttributeValueCache3) { return; } @@ -506,7 +518,7 @@ public void updateSubjectLink( } Map sourceIdSubjectIdToSubject = SubjectFinder - .findBySourceIdsAndSubjectIds(sourceIdSubjectIds, false); + .findBySourceIdsAndSubjectIds(sourceIdSubjectIds, false, true); for (GcGrouperSyncMember gcGrouperSyncMember : gcGrouperSyncMembersToRefreshSubjectLink) { @@ -523,28 +535,28 @@ public void updateSubjectLink( Map variableMap = new HashMap(); variableMap.put("subject", subject); - if (hasSubjectLinkMemberFromId2) { - String memberFromId2Value = GrouperUtil - .substituteExpressionLanguage(subjectLinkMemberFromId2, variableMap); - gcGrouperSyncMember.setMemberFromId2(memberFromId2Value); + if (hasSubjectLinkAttributeValueCache0) { + String entityAttributeValueCache0Value = GrouperUtil + .substituteExpressionLanguage(grouperProvisioningConfigurationAttributeDbCache0.getTranslationScript(), variableMap); + gcGrouperSyncMember.setEntityAttributeValueCache0(entityAttributeValueCache0Value); } - if (hasSubjectLinkMemberFromId3) { - String memberFromId3Value = GrouperUtil - .substituteExpressionLanguage(subjectLinkMemberFromId3, variableMap); - gcGrouperSyncMember.setMemberFromId3(memberFromId3Value); + if (hasSubjectLinkAttributeValueCache1) { + String entityAttributeValueCache1Value = GrouperUtil + .substituteExpressionLanguage(grouperProvisioningConfigurationAttributeDbCache1.getTranslationScript(), variableMap); + gcGrouperSyncMember.setEntityAttributeValueCache1(entityAttributeValueCache1Value); } - if (hasSubjectLinkMemberToId2) { - String memberToId2Value = GrouperUtil - .substituteExpressionLanguage(subjectLinkMemberToId2, variableMap); - gcGrouperSyncMember.setMemberToId2(memberToId2Value); + if (hasSubjectLinkAttributeValueCache2) { + String entityAttributeValueCache2Value = GrouperUtil + .substituteExpressionLanguage(grouperProvisioningConfigurationAttributeDbCache2.getTranslationScript(), variableMap); + gcGrouperSyncMember.setEntityAttributeValueCache2(entityAttributeValueCache2Value); } - if (hasSubjectLinkMemberFromId3) { - String memberToId3Value = GrouperUtil - .substituteExpressionLanguage(subjectLinkMemberToId3, variableMap); - gcGrouperSyncMember.setMemberToId3(memberToId3Value); + if (hasSubjectLinkAttributeValueCache1) { + String entityAttributeValueCache3Value = GrouperUtil + .substituteExpressionLanguage(grouperProvisioningConfigurationAttributeDbCache3.getTranslationScript(), variableMap); + gcGrouperSyncMember.setEntityAttributeValueCache3(entityAttributeValueCache3Value); } } @@ -1372,18 +1384,18 @@ public void processResultsSelectMembershipsFull( { String groupAttributeNameForMemberships = this.grouperProvisioner .retrieveGrouperProvisioningConfiguration() - .getGroupAttributeNameForMemberships(); + .getGroupMembershipAttributeName(); // get the attribute that holds members GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = this.grouperProvisioner .retrieveGrouperProvisioningConfiguration() .getTargetGroupAttributeNameToConfig().get(groupAttributeNameForMemberships); - String translateFromMemberSyncField = grouperProvisioningConfigurationAttribute == null + String translateFromMemberAttribute = grouperProvisioningConfigurationAttribute == null ? null - : grouperProvisioningConfigurationAttribute.getTranslateFromMemberSyncField(); + : grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningEntityField(); - if (StringUtils.isBlank(translateFromMemberSyncField)) { + if (StringUtils.isBlank(translateFromMemberAttribute)) { this.grouperProvisioner.getDebugMap() .put("processResultsSelectMembershipsFullCantUnresolveMemberships", true); @@ -1400,8 +1412,8 @@ public void processResultsSelectMembershipsFull( .getGcGrouperSyncMember(); if (gcGrouperSyncMember != null) { Object provisioningAttribute = this.getGrouperProvisioner() - .retrieveGrouperProvisioningTranslator().translateFromMemberSyncField( - gcGrouperSyncMember, translateFromMemberSyncField); + .retrieveGrouperProvisioningTranslator().translateFromGrouperProvisioningEntityField( + provisioningEntityWrapper, translateFromMemberAttribute); String provisioningAttributeString = GrouperUtil .stringValue(provisioningAttribute); provisioningAttributeToMember.put(provisioningAttributeString, @@ -1497,18 +1509,18 @@ public void processResultsSelectMembershipsFull( case entityAttributes: { String entityAttributeNameForMemberships = this.grouperProvisioner .retrieveGrouperProvisioningConfiguration() - .getEntityAttributeNameForMemberships(); + .getEntityMembershipAttributeName(); // get the attribute that holds members GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = this.grouperProvisioner .retrieveGrouperProvisioningConfiguration() .getTargetGroupAttributeNameToConfig().get(entityAttributeNameForMemberships); - String translateFromGroupSyncField = grouperProvisioningConfigurationAttribute == null + String translateFromGroupAttribute = grouperProvisioningConfigurationAttribute == null ? null - : grouperProvisioningConfigurationAttribute.getTranslateFromGroupSyncField(); + : grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningGroupField(); - if (StringUtils.isBlank(translateFromGroupSyncField)) { + if (StringUtils.isBlank(translateFromGroupAttribute)) { this.grouperProvisioner.getDebugMap() .put("processResultsSelectMembershipsFullCantUnresolveMemberships", true); @@ -1526,10 +1538,9 @@ public void processResultsSelectMembershipsFull( if (gcGrouperSyncGroup != null) { Object provisioningAttribute = this.getGrouperProvisioner() - .retrieveGrouperProvisioningTranslator().translateFromGroupSyncField( - gcGrouperSyncGroup, translateFromGroupSyncField); - String provisioningAttributeString = GrouperUtil - .stringValue(provisioningAttribute); + .retrieveGrouperProvisioningTranslator() + .translateFromGrouperProvisioningGroupField(provisioningGroupWrapper, translateFromGroupAttribute); + String provisioningAttributeString = GrouperUtil.stringValue(provisioningAttribute); provisioningAttributeToGroup.put(provisioningAttributeString, gcGrouperSyncGroup); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLinkLogic.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLinkLogic.java index 6d5f752b241f..37dd22dc5736 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLinkLogic.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLinkLogic.java @@ -52,16 +52,31 @@ public boolean groupLinkMissing(GcGrouperSyncGroup gcGrouperSyncGroup) { } // If using subject attributes and those are not in the member sync object, then resolve the subject, and put in the member sync object - boolean hasGroupLinkGroupFromId2 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasGroupLinkGroupFromId2(); - boolean hasGroupLinkGroupFromId3 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasGroupLinkGroupFromId3(); - boolean hasGroupLinkGroupToId2 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasGroupLinkGroupToId2(); - boolean hasGroupLinkGroupToId3 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasGroupLinkGroupToId3(); - + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache0 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[0]; + boolean hasGroupLinkAttributeValueCache0 = grouperProvisioningConfigurationAttributeDbCache0 != null + && grouperProvisioningConfigurationAttributeDbCache0.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache1 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[1]; + boolean hasGroupLinkAttributeValueCache1 = grouperProvisioningConfigurationAttributeDbCache1 != null + && grouperProvisioningConfigurationAttributeDbCache1.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache2 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[2]; + boolean hasGroupLinkAttributeValueCache2 = grouperProvisioningConfigurationAttributeDbCache2 != null + && grouperProvisioningConfigurationAttributeDbCache2.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache3 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[3]; + boolean hasGroupLinkAttributeValueCache3 = grouperProvisioningConfigurationAttributeDbCache3 != null + && grouperProvisioningConfigurationAttributeDbCache3.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + boolean needsRefresh = false; - needsRefresh = needsRefresh || (hasGroupLinkGroupFromId2 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupFromId2())); - needsRefresh = needsRefresh || (hasGroupLinkGroupFromId3 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupFromId3())); - needsRefresh = needsRefresh || (hasGroupLinkGroupToId2 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupToId2())); - needsRefresh = needsRefresh || (hasGroupLinkGroupToId3 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupToId3())); + needsRefresh = needsRefresh || (hasGroupLinkAttributeValueCache0 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupAttributeValueCache0())); + needsRefresh = needsRefresh || (hasGroupLinkAttributeValueCache1 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupAttributeValueCache1())); + needsRefresh = needsRefresh || (hasGroupLinkAttributeValueCache2 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupAttributeValueCache2())); + needsRefresh = needsRefresh || (hasGroupLinkAttributeValueCache3 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupAttributeValueCache3())); return needsRefresh; } @@ -77,17 +92,31 @@ public boolean entityLinkMissing(GcGrouperSyncMember gcGrouperSyncMember) { return false; } - // If using subject attributes and those are not in the member sync object, then resolve the subject, and put in the member sync object - boolean hasEntityLinkMemberFromId2 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasEntityLinkMemberFromId2(); - boolean hasEntityLinkMemberFromId3 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasEntityLinkMemberFromId3(); - boolean hasEntityLinkMemberToId2 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasEntityLinkMemberToId2(); - boolean hasEntityLinkMemberToId3 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasEntityLinkMemberToId3(); - + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache0 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[0]; + boolean hasEntityLinkAttributeValueCache0 = grouperProvisioningConfigurationAttributeDbCache0 != null + && grouperProvisioningConfigurationAttributeDbCache0.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache1 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[1]; + boolean hasEntityLinkAttributeValueCache1 = grouperProvisioningConfigurationAttributeDbCache1 != null + && grouperProvisioningConfigurationAttributeDbCache1.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache2 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[2]; + boolean hasEntityLinkAttributeValueCache2 = grouperProvisioningConfigurationAttributeDbCache2 != null + && grouperProvisioningConfigurationAttributeDbCache2.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache3 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[3]; + boolean hasEntityLinkAttributeValueCache3 = grouperProvisioningConfigurationAttributeDbCache3 != null + && grouperProvisioningConfigurationAttributeDbCache3.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + boolean needsRefresh = false; - needsRefresh = needsRefresh || (hasEntityLinkMemberFromId2 && StringUtils.isBlank(gcGrouperSyncMember.getMemberFromId2())); - needsRefresh = needsRefresh || (hasEntityLinkMemberFromId3 && StringUtils.isBlank(gcGrouperSyncMember.getMemberFromId3())); - needsRefresh = needsRefresh || (hasEntityLinkMemberToId2 && StringUtils.isBlank(gcGrouperSyncMember.getMemberToId2())); - needsRefresh = needsRefresh || (hasEntityLinkMemberToId3 && StringUtils.isBlank(gcGrouperSyncMember.getMemberToId3())); + needsRefresh = needsRefresh || (hasEntityLinkAttributeValueCache0 && StringUtils.isBlank(gcGrouperSyncMember.getEntityAttributeValueCache0())); + needsRefresh = needsRefresh || (hasEntityLinkAttributeValueCache1 && StringUtils.isBlank(gcGrouperSyncMember.getEntityAttributeValueCache1())); + needsRefresh = needsRefresh || (hasEntityLinkAttributeValueCache2 && StringUtils.isBlank(gcGrouperSyncMember.getEntityAttributeValueCache2())); + needsRefresh = needsRefresh || (hasEntityLinkAttributeValueCache3 && StringUtils.isBlank(gcGrouperSyncMember.getEntityAttributeValueCache3())); return needsRefresh; } @@ -105,21 +134,35 @@ public void retrieveSubjectLink() { if (GrouperUtil.length(gcGrouperSyncMembers) == 0) { return; } - + if (!this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().isEntityAttributeValueCacheHas()) { + return; + } // If using subject attributes and those are not in the member sync object, then resolve the subject, and put in the member sync object - String subjectLinkMemberFromId2 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getSubjectLinkMemberFromId2(); - boolean hasSubjectLinkMemberFromId2 = !StringUtils.isBlank(subjectLinkMemberFromId2); - - String subjectLinkMemberFromId3 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getSubjectLinkMemberFromId3(); - boolean hasSubjectLinkMemberFromId3 = !StringUtils.isBlank(subjectLinkMemberFromId3); - - String subjectLinkMemberToId2 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getSubjectLinkMemberToId2(); - boolean hasSubjectLinkMemberToId2 = !StringUtils.isBlank(subjectLinkMemberToId2); - - String subjectLinkMemberToId3 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getSubjectLinkMemberToId3(); - boolean hasSubjectLinkMemberToId3 = !StringUtils.isBlank(subjectLinkMemberToId3); - - if (!hasSubjectLinkMemberFromId2 && !hasSubjectLinkMemberFromId3 && !hasSubjectLinkMemberToId2 && !hasSubjectLinkMemberToId3) { + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache0 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[0]; + boolean hasSubjectLinkEntityAttributeValueCache0 = grouperProvisioningConfigurationAttributeDbCache0 != null + && grouperProvisioningConfigurationAttributeDbCache0.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache0.getTranslationScript()); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache1 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[1]; + boolean hasSubjectLinkEntityAttributeValueCache1 = grouperProvisioningConfigurationAttributeDbCache1 != null + && grouperProvisioningConfigurationAttributeDbCache1.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache1.getTranslationScript()); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache2 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[2]; + boolean hasSubjectLinkEntityAttributeValueCache2 = grouperProvisioningConfigurationAttributeDbCache2 != null + && grouperProvisioningConfigurationAttributeDbCache2.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache2.getTranslationScript()); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache3 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[3]; + boolean hasSubjectLinkEntityAttributeValueCache3 = grouperProvisioningConfigurationAttributeDbCache3 != null + && grouperProvisioningConfigurationAttributeDbCache3.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache3.getTranslationScript()); + + if (!hasSubjectLinkEntityAttributeValueCache0 && !hasSubjectLinkEntityAttributeValueCache1 && !hasSubjectLinkEntityAttributeValueCache2 && !hasSubjectLinkEntityAttributeValueCache3) { return; } @@ -131,10 +174,10 @@ public void retrieveSubjectLink() { } else { for (GcGrouperSyncMember gcGrouperSyncMember : gcGrouperSyncMembers) { boolean needsRefresh = false; - needsRefresh = needsRefresh || (hasSubjectLinkMemberFromId2 && StringUtils.isBlank(gcGrouperSyncMember.getMemberFromId2())); - needsRefresh = needsRefresh || (hasSubjectLinkMemberFromId3 && StringUtils.isBlank(gcGrouperSyncMember.getMemberFromId3())); - needsRefresh = needsRefresh || (hasSubjectLinkMemberToId2 && StringUtils.isBlank(gcGrouperSyncMember.getMemberToId2())); - needsRefresh = needsRefresh || (hasSubjectLinkMemberToId3 && StringUtils.isBlank(gcGrouperSyncMember.getMemberToId3())); + needsRefresh = needsRefresh || (hasSubjectLinkEntityAttributeValueCache0 && StringUtils.isBlank(gcGrouperSyncMember.getEntityAttributeValueCache0())); + needsRefresh = needsRefresh || (hasSubjectLinkEntityAttributeValueCache1 && StringUtils.isBlank(gcGrouperSyncMember.getEntityAttributeValueCache1())); + needsRefresh = needsRefresh || (hasSubjectLinkEntityAttributeValueCache2 && StringUtils.isBlank(gcGrouperSyncMember.getEntityAttributeValueCache2())); + needsRefresh = needsRefresh || (hasSubjectLinkEntityAttributeValueCache3 && StringUtils.isBlank(gcGrouperSyncMember.getEntityAttributeValueCache3())); if (needsRefresh) { gcGrouperSyncMembersToRefreshSubjectLink.add(gcGrouperSyncMember); } @@ -150,7 +193,7 @@ public void retrieveSubjectLink() { /** * update group link for these groups - * @param gcGrouperSyncGroupsToRefreshGroupLink + * @param provisioningGroupWrappers */ public void updateGroupLink(Collection provisioningGroupWrappers) { @@ -159,26 +202,40 @@ public void updateGroupLink(Collection provisioningGro } // If using subject attributes and those are not in the member sync object, then resolve the subject, and put in the member sync object - String groupLinkGroupFromId2 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupLinkGroupFromId2(); - GrouperProvisioningConfigurationAttribute groupLinkGroupFromId2Attribute = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGroupLinkGroupFromId2Attribute(); - boolean hasGroupLinkGroupFromId2 = !StringUtils.isBlank(groupLinkGroupFromId2) || groupLinkGroupFromId2Attribute != null; - String groupLinkGroupFromId3 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupLinkGroupFromId3(); - GrouperProvisioningConfigurationAttribute groupLinkGroupFromId3Attribute = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGroupLinkGroupFromId3Attribute(); - boolean hasGroupLinkGroupFromId3 = !StringUtils.isBlank(groupLinkGroupFromId3) || groupLinkGroupFromId3Attribute != null; - - String groupLinkGroupToId2 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupLinkGroupToId2(); - GrouperProvisioningConfigurationAttribute groupLinkGroupToId2Attribute = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGroupLinkGroupToId2Attribute(); - boolean hasGroupLinkGroupToId2 = !StringUtils.isBlank(groupLinkGroupToId2) || groupLinkGroupToId2Attribute != null; - - String groupLinkGroupToId3 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupLinkGroupToId3(); - GrouperProvisioningConfigurationAttribute groupLinkGroupToId3Attribute = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGroupLinkGroupToId3Attribute(); - boolean hasGroupLinkGroupToId3 = !StringUtils.isBlank(groupLinkGroupToId3) || groupLinkGroupToId3Attribute != null; - - if (!hasGroupLinkGroupFromId2 && !hasGroupLinkGroupFromId3 && !hasGroupLinkGroupToId2 && !hasGroupLinkGroupToId3) { + if (!this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().isGroupAttributeValueCacheHas()) { return; } - + // If using subject attributes and those are not in the member sync object, then resolve the subject, and put in the member sync object + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache0 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[0]; + boolean hasGroupLinkAttributeValueCache0 = grouperProvisioningConfigurationAttributeDbCache0 != null + && grouperProvisioningConfigurationAttributeDbCache0.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + GrouperProvisioningConfigurationAttribute groupLinkGroupAttributeValueCache0Attribute = + grouperProvisioningConfigurationAttributeDbCache0 == null ? null : grouperProvisioningConfigurationAttributeDbCache0.retrieveAttribute(); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache1 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[1]; + boolean hasGroupLinkAttributeValueCache1 = grouperProvisioningConfigurationAttributeDbCache1 != null; + GrouperProvisioningConfigurationAttribute groupLinkGroupAttributeValueCache1Attribute = + grouperProvisioningConfigurationAttributeDbCache1 == null ? null : grouperProvisioningConfigurationAttributeDbCache1.retrieveAttribute(); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache2 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[2]; + boolean hasGroupLinkAttributeValueCache2 = grouperProvisioningConfigurationAttributeDbCache2 != null; + GrouperProvisioningConfigurationAttribute groupLinkGroupAttributeValueCache2Attribute = + grouperProvisioningConfigurationAttributeDbCache2 == null ? null : grouperProvisioningConfigurationAttributeDbCache2.retrieveAttribute(); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache3 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[3]; + boolean hasGroupLinkAttributeValueCache3 = grouperProvisioningConfigurationAttributeDbCache3 != null; + GrouperProvisioningConfigurationAttribute groupLinkGroupAttributeValueCache3Attribute = + grouperProvisioningConfigurationAttributeDbCache3 == null ? null : grouperProvisioningConfigurationAttributeDbCache3.retrieveAttribute(); + + if (!hasGroupLinkAttributeValueCache0 && !hasGroupLinkAttributeValueCache1 && !hasGroupLinkAttributeValueCache2 && !hasGroupLinkAttributeValueCache3) { + return; + } + int groupsCannotFindLinkData = 0; int groupsCannotFindSyncGroup = 0; @@ -211,54 +268,54 @@ public void updateGroupLink(Collection provisioningGro Map variableMap = new HashMap(); variableMap.put("targetGroup", targetGroup); - if (hasGroupLinkGroupFromId2) { - String groupFromId2Value = null; - if (groupLinkGroupFromId2Attribute != null) { - groupFromId2Value = targetGroup.retrieveAttributeValueString(groupLinkGroupFromId2Attribute); + if (hasGroupLinkAttributeValueCache0) { + String groupAttributeValueCache0Value = null; + if (groupLinkGroupAttributeValueCache0Attribute != null) { + groupAttributeValueCache0Value = targetGroup.retrieveAttributeValueString(groupLinkGroupAttributeValueCache0Attribute); } else { - groupFromId2Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(groupLinkGroupFromId2, variableMap, true, false, true)); + groupAttributeValueCache0Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(grouperProvisioningConfigurationAttributeDbCache0.getTranslationScript(), variableMap, true, false, true)); } - if (!StringUtils.equals(groupFromId2Value, gcGrouperSyncGroup.getGroupFromId2())) { - gcGrouperSyncGroup.setGroupFromId2(groupFromId2Value); + if (!StringUtils.equals(groupAttributeValueCache0Value, gcGrouperSyncGroup.getGroupAttributeValueCache0())) { + gcGrouperSyncGroup.setGroupAttributeValueCache0(groupAttributeValueCache0Value); hasChange = true; } } - if (hasGroupLinkGroupFromId3) { - String groupFromId3Value = null; - if (groupLinkGroupFromId3Attribute != null) { - groupFromId3Value = targetGroup.retrieveAttributeValueString(groupLinkGroupFromId3Attribute); + if (hasGroupLinkAttributeValueCache1) { + String groupAttributeValueCache1Value = null; + if (groupLinkGroupAttributeValueCache1Attribute != null) { + groupAttributeValueCache1Value = targetGroup.retrieveAttributeValueString(groupLinkGroupAttributeValueCache1Attribute); } else { - groupFromId3Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(groupLinkGroupFromId3, variableMap, true, false, true)); + groupAttributeValueCache1Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(grouperProvisioningConfigurationAttributeDbCache1.getTranslationScript(), variableMap, true, false, true)); } - if (!StringUtils.equals(groupFromId3Value, gcGrouperSyncGroup.getGroupFromId3())) { - gcGrouperSyncGroup.setGroupFromId3(groupFromId3Value); + if (!StringUtils.equals(groupAttributeValueCache1Value, gcGrouperSyncGroup.getGroupAttributeValueCache1())) { + gcGrouperSyncGroup.setGroupAttributeValueCache1(groupAttributeValueCache1Value); hasChange = true; } } - if (hasGroupLinkGroupToId2) { - String groupToId2Value = null; - if (groupLinkGroupToId2Attribute != null) { - groupToId2Value = targetGroup.retrieveAttributeValueString(groupLinkGroupToId2Attribute); + if (hasGroupLinkAttributeValueCache2) { + String groupAttributeValueCache2Value = null; + if (groupLinkGroupAttributeValueCache2Attribute != null) { + groupAttributeValueCache2Value = targetGroup.retrieveAttributeValueString(groupLinkGroupAttributeValueCache2Attribute); } else { - groupToId2Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(groupLinkGroupToId2, variableMap, true, false, true)); + groupAttributeValueCache2Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(grouperProvisioningConfigurationAttributeDbCache2.getTranslationScript(), variableMap, true, false, true)); } - if (!StringUtils.equals(groupToId2Value, gcGrouperSyncGroup.getGroupToId2())) { - gcGrouperSyncGroup.setGroupToId2(groupToId2Value); + if (!StringUtils.equals(groupAttributeValueCache2Value, gcGrouperSyncGroup.getGroupAttributeValueCache2())) { + gcGrouperSyncGroup.setGroupAttributeValueCache2(groupAttributeValueCache2Value); hasChange = true; } } - if (hasGroupLinkGroupFromId3) { - String groupToId3Value = null; - if (groupLinkGroupToId3Attribute != null) { - groupToId3Value = targetGroup.retrieveAttributeValueString(groupLinkGroupToId3Attribute); + if (hasGroupLinkAttributeValueCache3) { + String groupAttributeValueCache3Value = null; + if (groupLinkGroupAttributeValueCache3Attribute != null) { + groupAttributeValueCache3Value = targetGroup.retrieveAttributeValueString(groupLinkGroupAttributeValueCache3Attribute); } else { - groupToId3Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(groupLinkGroupToId3, variableMap, true, false, true)); + groupAttributeValueCache3Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(grouperProvisioningConfigurationAttributeDbCache3.getTranslationScript(), variableMap, true, false, true)); } - if (!StringUtils.equals(groupToId3Value, gcGrouperSyncGroup.getGroupToId3())) { - gcGrouperSyncGroup.setGroupToId3(groupToId3Value); + if (!StringUtils.equals(groupAttributeValueCache3Value, gcGrouperSyncGroup.getGroupAttributeValueCache3())) { + gcGrouperSyncGroup.setGroupAttributeValueCache3(groupAttributeValueCache3Value); hasChange = true; } } @@ -382,26 +439,44 @@ public void updateEntityLink(Collection provisioningE } // If using subject attributes and those are not in the member sync object, then resolve the subject, and put in the member sync object - String entityLinkMemberFromId2 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityLinkMemberFromId2(); - GrouperProvisioningConfigurationAttribute entityLinkMemberFromId2Attribute = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getEntityLinkMemberFromId2Attribute(); - boolean hasEntityLinkMemberFromId2 = !StringUtils.isBlank(entityLinkMemberFromId2) || entityLinkMemberFromId2Attribute != null; - String entityLinkMemberFromId3 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityLinkMemberFromId3(); - GrouperProvisioningConfigurationAttribute entityLinkMemberFromId3Attribute = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getEntityLinkMemberFromId3Attribute(); - boolean hasEntityLinkMemberFromId3 = !StringUtils.isBlank(entityLinkMemberFromId3) || entityLinkMemberFromId3Attribute != null; - - String entityLinkMemberToId2 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityLinkMemberToId2(); - GrouperProvisioningConfigurationAttribute entityLinkMemberToId2Attribute = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getEntityLinkMemberToId2Attribute(); - boolean hasEntityLinkMemberToId2 = !StringUtils.isBlank(entityLinkMemberToId2) || entityLinkMemberToId2Attribute != null; - - String entityLinkMemberToId3 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityLinkMemberToId3(); - GrouperProvisioningConfigurationAttribute entityLinkMemberToId3Attribute = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getEntityLinkMemberToId3Attribute(); - boolean hasEntityLinkMemberToId3 = !StringUtils.isBlank(entityLinkMemberToId3) || entityLinkMemberToId3Attribute != null; - - if (!hasEntityLinkMemberFromId2 && !hasEntityLinkMemberFromId3 && !hasEntityLinkMemberToId2 && !hasEntityLinkMemberToId3) { + if (!this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().isEntityAttributeValueCacheHas()) { return; } - + // If using subject attributes and those are not in the member sync object, then resolve the subject, and put in the member sync object + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache0 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[0]; + boolean hasEntityLinkAttributeValueCache0 = grouperProvisioningConfigurationAttributeDbCache0 != null + && grouperProvisioningConfigurationAttributeDbCache0.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + GrouperProvisioningConfigurationAttribute entityLinkGroupAttributeValueCache0Attribute = + grouperProvisioningConfigurationAttributeDbCache0 == null ? null : grouperProvisioningConfigurationAttributeDbCache0.retrieveAttribute(); + + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache1 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[1]; + boolean hasEntityLinkAttributeValueCache1 = grouperProvisioningConfigurationAttributeDbCache1 != null + && grouperProvisioningConfigurationAttributeDbCache1.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + GrouperProvisioningConfigurationAttribute entityLinkGroupAttributeValueCache1Attribute = + grouperProvisioningConfigurationAttributeDbCache1 == null ? null : grouperProvisioningConfigurationAttributeDbCache1.retrieveAttribute(); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache2 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[2]; + boolean hasEntityLinkAttributeValueCache2 = grouperProvisioningConfigurationAttributeDbCache2 != null + && grouperProvisioningConfigurationAttributeDbCache2.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + GrouperProvisioningConfigurationAttribute entityLinkGroupAttributeValueCache2Attribute = + grouperProvisioningConfigurationAttributeDbCache2 == null ? null : grouperProvisioningConfigurationAttributeDbCache2.retrieveAttribute(); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache3 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[3]; + boolean hasEntityLinkAttributeValueCache3 = grouperProvisioningConfigurationAttributeDbCache3 != null + && grouperProvisioningConfigurationAttributeDbCache3.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + GrouperProvisioningConfigurationAttribute entityLinkGroupAttributeValueCache3Attribute = + grouperProvisioningConfigurationAttributeDbCache3 == null ? null : grouperProvisioningConfigurationAttributeDbCache3.retrieveAttribute(); + + if (!hasEntityLinkAttributeValueCache0 && !hasEntityLinkAttributeValueCache1 && !hasEntityLinkAttributeValueCache2 && !hasEntityLinkAttributeValueCache3) { + return; + } + int entitiesCannotFindLinkData = 0; int entitiesCannotFindSyncMember = 0; @@ -432,54 +507,54 @@ public void updateEntityLink(Collection provisioningE Map variableMap = new HashMap(); variableMap.put("targetEntity", targetEntity); - if (hasEntityLinkMemberFromId2) { + if (hasEntityLinkAttributeValueCache0) { String entityFromId2Value = null; - if (entityLinkMemberFromId2Attribute != null) { - entityFromId2Value = targetEntity.retrieveAttributeValueString(entityLinkMemberFromId2Attribute); + if (entityLinkGroupAttributeValueCache0Attribute != null) { + entityFromId2Value = targetEntity.retrieveAttributeValueString(entityLinkGroupAttributeValueCache0Attribute); } else { - entityFromId2Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(entityLinkMemberFromId2, variableMap, true, false, true)); + entityFromId2Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(grouperProvisioningConfigurationAttributeDbCache0.getTranslationScript(), variableMap, true, false, true)); } - if (!StringUtils.equals(entityFromId2Value, gcGrouperSyncEntity.getMemberFromId2())) { - gcGrouperSyncEntity.setMemberFromId2(entityFromId2Value); + if (!StringUtils.equals(entityFromId2Value, gcGrouperSyncEntity.getEntityAttributeValueCache0())) { + gcGrouperSyncEntity.setEntityAttributeValueCache0(entityFromId2Value); hasChange = true; } } - if (hasEntityLinkMemberFromId3) { + if (hasEntityLinkAttributeValueCache1) { String entityFromId3Value = null; - if (entityLinkMemberFromId3Attribute != null) { - entityFromId3Value = targetEntity.retrieveAttributeValueString(entityLinkMemberFromId3Attribute); + if (entityLinkGroupAttributeValueCache1Attribute != null) { + entityFromId3Value = targetEntity.retrieveAttributeValueString(entityLinkGroupAttributeValueCache1Attribute); } else { - entityFromId3Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(entityLinkMemberFromId3, variableMap, true, false, true)); + entityFromId3Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(grouperProvisioningConfigurationAttributeDbCache1.getTranslationScript(), variableMap, true, false, true)); } - if (!StringUtils.equals(entityFromId3Value, gcGrouperSyncEntity.getMemberFromId3())) { - gcGrouperSyncEntity.setMemberFromId3(entityFromId3Value); + if (!StringUtils.equals(entityFromId3Value, gcGrouperSyncEntity.getEntityAttributeValueCache1())) { + gcGrouperSyncEntity.setEntityAttributeValueCache1(entityFromId3Value); hasChange = true; } } - if (hasEntityLinkMemberToId2) { + if (hasEntityLinkAttributeValueCache2) { String entityToId2Value = null; - if (entityLinkMemberToId2Attribute != null) { - entityToId2Value = targetEntity.retrieveAttributeValueString(entityLinkMemberToId2Attribute); + if (entityLinkGroupAttributeValueCache2Attribute != null) { + entityToId2Value = targetEntity.retrieveAttributeValueString(entityLinkGroupAttributeValueCache2Attribute); } else { - entityToId2Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(entityLinkMemberToId2, variableMap, true, false, true)); + entityToId2Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(grouperProvisioningConfigurationAttributeDbCache2.getTranslationScript(), variableMap, true, false, true)); } - if (!StringUtils.equals(entityToId2Value, gcGrouperSyncEntity.getMemberToId2())) { - gcGrouperSyncEntity.setMemberToId2(entityToId2Value); + if (!StringUtils.equals(entityToId2Value, gcGrouperSyncEntity.getEntityAttributeValueCache2())) { + gcGrouperSyncEntity.setEntityAttributeValueCache2(entityToId2Value); hasChange = true; } } - if (hasEntityLinkMemberToId3) { + if (hasEntityLinkAttributeValueCache3) { String entityToId3Value = null; - if (entityLinkMemberToId3Attribute != null) { - entityToId3Value = targetEntity.retrieveAttributeValueString(entityLinkMemberToId3Attribute); + if (entityLinkGroupAttributeValueCache3Attribute != null) { + entityToId3Value = targetEntity.retrieveAttributeValueString(entityLinkGroupAttributeValueCache3Attribute); } else { - entityToId3Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(entityLinkMemberToId3, variableMap, true, false, true)); + entityToId3Value = StringUtils.trimToNull(GrouperUtil.substituteExpressionLanguage(grouperProvisioningConfigurationAttributeDbCache3.getTranslationScript(), variableMap, true, false, true)); } - if (!StringUtils.equals(entityToId3Value, gcGrouperSyncEntity.getMemberToId3())) { - gcGrouperSyncEntity.setMemberToId3(entityToId3Value); + if (!StringUtils.equals(entityToId3Value, gcGrouperSyncEntity.getEntityAttributeValueCache3())) { + gcGrouperSyncEntity.setEntityAttributeValueCache3(entityToId3Value); hasChange = true; } } @@ -542,23 +617,35 @@ public boolean subjectLinkMissing(GcGrouperSyncMember gcGrouperSyncMember) { } // If using subject attributes and those are not in the member sync object, then resolve the subject, and put in the member sync object - String subjectLinkMemberFromId2 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getSubjectLinkMemberFromId2(); - boolean hasSubjectLinkMemberFromId2 = !StringUtils.isBlank(subjectLinkMemberFromId2); - - String subjectLinkMemberFromId3 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getSubjectLinkMemberFromId3(); - boolean hasSubjectLinkMemberFromId3 = !StringUtils.isBlank(subjectLinkMemberFromId3); - - String subjectLinkMemberToId2 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getSubjectLinkMemberToId2(); - boolean hasSubjectLinkMemberToId2 = !StringUtils.isBlank(subjectLinkMemberToId2); - - String subjectLinkMemberToId3 = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getSubjectLinkMemberToId3(); - boolean hasSubjectLinkMemberToId3 = !StringUtils.isBlank(subjectLinkMemberToId3); + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache0 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[0]; + boolean hasSubjectLinkEntityAttributeValueCache0 = grouperProvisioningConfigurationAttributeDbCache0 != null + && grouperProvisioningConfigurationAttributeDbCache0.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache0.getTranslationScript()); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache1 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[1]; + boolean hasSubjectLinkEntityAttributeValueCache1 = grouperProvisioningConfigurationAttributeDbCache1 != null + && grouperProvisioningConfigurationAttributeDbCache1.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache1.getTranslationScript()); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache2 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[2]; + boolean hasSubjectLinkEntityAttributeValueCache2 = grouperProvisioningConfigurationAttributeDbCache2 != null + && grouperProvisioningConfigurationAttributeDbCache2.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache2.getTranslationScript()); + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache3 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()[3]; + boolean hasSubjectLinkEntityAttributeValueCache3 = grouperProvisioningConfigurationAttributeDbCache3 != null + && grouperProvisioningConfigurationAttributeDbCache3.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.subjectTranslationScript + && !StringUtils.isBlank(grouperProvisioningConfigurationAttributeDbCache3.getTranslationScript()); boolean needsRefresh = false; - needsRefresh = needsRefresh || (hasSubjectLinkMemberFromId2 && StringUtils.isBlank(gcGrouperSyncMember.getMemberFromId2())); - needsRefresh = needsRefresh || (hasSubjectLinkMemberFromId3 && StringUtils.isBlank(gcGrouperSyncMember.getMemberFromId3())); - needsRefresh = needsRefresh || (hasSubjectLinkMemberToId2 && StringUtils.isBlank(gcGrouperSyncMember.getMemberToId2())); - needsRefresh = needsRefresh || (hasSubjectLinkMemberToId3 && StringUtils.isBlank(gcGrouperSyncMember.getMemberToId3())); + needsRefresh = needsRefresh || (hasSubjectLinkEntityAttributeValueCache0 && StringUtils.isBlank(gcGrouperSyncMember.getEntityAttributeValueCache0())); + needsRefresh = needsRefresh || (hasSubjectLinkEntityAttributeValueCache1 && StringUtils.isBlank(gcGrouperSyncMember.getEntityAttributeValueCache1())); + needsRefresh = needsRefresh || (hasSubjectLinkEntityAttributeValueCache2 && StringUtils.isBlank(gcGrouperSyncMember.getEntityAttributeValueCache2())); + needsRefresh = needsRefresh || (hasSubjectLinkEntityAttributeValueCache3 && StringUtils.isBlank(gcGrouperSyncMember.getEntityAttributeValueCache3())); return needsRefresh; } @@ -580,14 +667,27 @@ public List retrieveIncrementalNonRecalcTargetEntitiesThatNe if (!GrouperUtil.booleanValue(this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().isHasTargetEntityLink(), false)) { return grouperTargetEntities; } + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache0 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[0]; + boolean hasEntityLinkAttributeValueCache0 = grouperProvisioningConfigurationAttributeDbCache0 != null + && grouperProvisioningConfigurationAttributeDbCache0.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; - // If using subject attributes and those are not in the member sync object, then resolve the subject, and put in the member sync object - boolean hasEntityLinkMemberFromId2 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasEntityLinkMemberFromId2(); - boolean hasEntityLinkMemberFromId3 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasEntityLinkMemberFromId3(); - boolean hasEntityLinkMemberToId2 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasEntityLinkMemberToId2(); - boolean hasEntityLinkMemberToId3 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasEntityLinkMemberToId3(); + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache1 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[1]; + boolean hasEntityLinkAttributeValueCache1 = grouperProvisioningConfigurationAttributeDbCache1 != null + && grouperProvisioningConfigurationAttributeDbCache1.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache2 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[2]; + boolean hasEntityLinkAttributeValueCache2 = grouperProvisioningConfigurationAttributeDbCache2 != null + && grouperProvisioningConfigurationAttributeDbCache2.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; - if (!hasEntityLinkMemberFromId2 && !hasEntityLinkMemberFromId3 && !hasEntityLinkMemberToId2 && !hasEntityLinkMemberToId3) { + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache3 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[3]; + boolean hasEntityLinkAttributeValueCache3 = grouperProvisioningConfigurationAttributeDbCache3 != null + && grouperProvisioningConfigurationAttributeDbCache3.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + + if (!hasEntityLinkAttributeValueCache0 && !hasEntityLinkAttributeValueCache1 && !hasEntityLinkAttributeValueCache2 && !hasEntityLinkAttributeValueCache3) { return grouperTargetEntities; } @@ -612,19 +712,19 @@ public List retrieveIncrementalNonRecalcTargetEntitiesThatNe continue; } - if (hasEntityLinkMemberFromId2 && StringUtils.isBlank(gcGrouperSyncEntity.getMemberFromId2())) { + if (hasEntityLinkAttributeValueCache0 && StringUtils.isBlank(gcGrouperSyncEntity.getEntityAttributeValueCache0())) { hasChange = true; } - if (hasEntityLinkMemberFromId3 && StringUtils.isBlank(gcGrouperSyncEntity.getMemberFromId3())) { + if (hasEntityLinkAttributeValueCache1 && StringUtils.isBlank(gcGrouperSyncEntity.getEntityAttributeValueCache1())) { hasChange = true; } - if (hasEntityLinkMemberToId2 && StringUtils.isBlank(gcGrouperSyncEntity.getMemberToId2())) { + if (hasEntityLinkAttributeValueCache2 && StringUtils.isBlank(gcGrouperSyncEntity.getEntityAttributeValueCache2())) { hasChange = true; } - if (hasEntityLinkMemberFromId3 && StringUtils.isBlank(gcGrouperSyncEntity.getMemberToId3())) { + if (hasEntityLinkAttributeValueCache1 && StringUtils.isBlank(gcGrouperSyncEntity.getEntityAttributeValueCache3())) { hasChange = true; } if (hasChange) { @@ -653,13 +753,27 @@ public List retrieveIncrementalNonRecalcTargetGroupsThatNeedL return grouperTargetGroups; } - // If using subject attributes and those are not in the member sync object, then resolve the subject, and put in the member sync object - boolean hasGroupLinkGroupFromId2 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasGroupLinkGroupFromId2(); - boolean hasGroupLinkGroupFromId3 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasGroupLinkGroupFromId3(); - boolean hasGroupLinkGroupToId2 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasGroupLinkGroupToId2(); - boolean hasGroupLinkGroupToId3 = this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isHasGroupLinkGroupToId3(); - - if (!hasGroupLinkGroupFromId2 && !hasGroupLinkGroupFromId3 && !hasGroupLinkGroupToId2 && !hasGroupLinkGroupToId3) { + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache0 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[0]; + boolean hasGroupLinkAttributeValueCache0 = grouperProvisioningConfigurationAttributeDbCache0 != null + && grouperProvisioningConfigurationAttributeDbCache0.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache1 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[1]; + boolean hasGroupLinkAttributeValueCache1 = grouperProvisioningConfigurationAttributeDbCache1 != null + && grouperProvisioningConfigurationAttributeDbCache1.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache2 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[2]; + boolean hasGroupLinkAttributeValueCache2 = grouperProvisioningConfigurationAttributeDbCache2 != null + && grouperProvisioningConfigurationAttributeDbCache2.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + + GrouperProvisioningConfigurationAttributeDbCache grouperProvisioningConfigurationAttributeDbCache3 = + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()[3]; + boolean hasGroupLinkAttributeValueCache3 = grouperProvisioningConfigurationAttributeDbCache3 != null + && grouperProvisioningConfigurationAttributeDbCache3.getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.target; + + if (!hasGroupLinkAttributeValueCache0 && !hasGroupLinkAttributeValueCache1 && !hasGroupLinkAttributeValueCache2 && !hasGroupLinkAttributeValueCache3) { return grouperTargetGroups; } @@ -684,19 +798,19 @@ public List retrieveIncrementalNonRecalcTargetGroupsThatNeedL continue; } - if (hasGroupLinkGroupFromId2 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupFromId2())) { + if (hasGroupLinkAttributeValueCache0 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupAttributeValueCache0())) { hasChange = true; } - if (hasGroupLinkGroupFromId3 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupFromId3())) { + if (hasGroupLinkAttributeValueCache1 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupAttributeValueCache1())) { hasChange = true; } - if (hasGroupLinkGroupToId2 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupToId2())) { + if (hasGroupLinkAttributeValueCache2 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupAttributeValueCache2())) { hasChange = true; } - if (hasGroupLinkGroupFromId3 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupToId3())) { + if (hasGroupLinkAttributeValueCache1 && StringUtils.isBlank(gcGrouperSyncGroup.getGroupAttributeValueCache3())) { hasChange = true; } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLog.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLog.java index a33cd7cad557..51b29e96ae3e 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLog.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLog.java @@ -1,5 +1,6 @@ package edu.internet2.middleware.grouper.app.provisioning; +import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; @@ -11,6 +12,55 @@ */ public class GrouperProvisioningLog { + public String prefixLogLinesWithInstanceId(String logMessage) { + GrouperUtil.whitespaceNormalizeNewLines(logMessage); + String logMessageString = GrouperUtil.replace(logMessage.toString(), "\n", "\n(" + this.grouperProvisioner.getInstanceId() + "): "); + return logMessageString; + } + + /** + * reference back up to the provisioner + */ + private GrouperProvisioner grouperProvisioner = null; + + /** + * reference back up to the provisioner + * @return the provisioner + */ + public GrouperProvisioner getGrouperProvisioner() { + return this.grouperProvisioner; + } + + /** + * reference back up to the provisioner + * @param grouperProvisioner1 + */ + public void setGrouperProvisioner(GrouperProvisioner grouperProvisioner1) { + this.grouperProvisioner = grouperProvisioner1; + } + + + /** + * type of log (label) to count so we dont log too much + */ + private Map errorTypeToCountLogged = new HashMap(); + + /** + * type of log (label) to count so we dont log too much + * @return the map + */ + public Map getErrorTypeToCountLogged() { + return errorTypeToCountLogged; + } + + /** + * type of log (label) to count so we dont log too much + * @param errorTypeToCountLogged + */ + public void setErrorTypeToCountLogged(Map errorTypeToCountLogged) { + this.errorTypeToCountLogged = errorTypeToCountLogged; + } + /** * debug log * @param debugMap @@ -39,5 +89,25 @@ public static boolean isDebugEnabled() { /** logger */ private static final Log LOG = GrouperUtil.getLog(GrouperProvisioningLog.class); + + /** + * if the threshold of this error label is less than the max + * @param errorLabelForCounts + * @return true or false + */ + public boolean shouldLogError(String errorLabelForCounts) { + Integer errorCountByLabel = this.errorTypeToCountLogged.get(errorLabelForCounts); + if (errorCountByLabel == null) { + errorCountByLabel = 0; + } + errorCountByLabel++; + + this.errorTypeToCountLogged.put(errorLabelForCounts, errorCountByLabel); + + if (errorCountByLabel <= this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getLogMaxErrorsPerType()) { + return true; + } + return false; + } } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLogic.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLogic.java index d90162878e2e..e4f4c608dd5c 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLogic.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLogic.java @@ -1,543 +1,639 @@ -package edu.internet2.middleware.grouper.app.provisioning; - -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.Log; - -import com.fasterxml.jackson.databind.JsonNode; - -import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoInsertEntitiesRequest; -import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoInsertGroupsRequest; -import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveAllDataRequest; -import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveAllDataResponse; -import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveEntitiesRequest; -import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveEntitiesResponse; -import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveGroupsRequest; -import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveGroupsResponse; -import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoSendChangesToTargetRequest; -import edu.internet2.middleware.grouper.cfg.GrouperConfig; -import edu.internet2.middleware.grouper.ldap.LdapAttribute; -import edu.internet2.middleware.grouper.ldap.LdapEntry; -import edu.internet2.middleware.grouper.ldap.LdapSearchScope; -import edu.internet2.middleware.grouper.ldap.LdapSessionUtils; -import edu.internet2.middleware.grouper.util.GrouperUtil; -import edu.internet2.middleware.grouperClient.collections.MultiKey; -import edu.internet2.middleware.grouperClient.jdbc.GcDbAccess; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSync; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncGroup; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncJob; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncLogState; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncMember; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncMembership; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSync; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncConfiguration; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncOutput; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncRowData; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncSubtype; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncTableBean; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncTableData; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncTableMetadata; -import edu.internet2.middleware.grouperClient.util.GrouperClientUtils; - -/** - * does the logic to use the data from the DAOs and call the correct methods to synnc things up or dry run or send messages for async - * @author mchyzer - * - */ -public class GrouperProvisioningLogic { - - /** - * - */ - public void provision() { - - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.configure); - - Timestamp startTimestamp = new Timestamp(System.currentTimeMillis()); - this.getGrouperProvisioner().getGcGrouperSyncJob().setLastSyncStart(startTimestamp); - - this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningType().provision(this.grouperProvisioner); - - } - - /** - * - */ - public void provisionFull() { - - Map debugMap = this.getGrouperProvisioner().getDebugMap(); - Timestamp startTimestamp = new Timestamp(System.currentTimeMillis()); - - { - debugMap.put("state", "propagateProvisioningAttributes"); - long start = System.currentTimeMillis(); - grouperProvisioner.propagateProvisioningAttributes(); - long propagateProvisioningAttributes = System.currentTimeMillis()-start; - debugMap.put("propagateProvisioningAttributes_millis", propagateProvisioningAttributes); - - if (grouperProvisioner.getConfigId().startsWith("junitProvisioningAttributePropagationTest")) { - // just testing attribute propagation - return; - } - } - - // validate the perhaps throw exception - this.validateAndThrowExceptionIfInvalid(); - - try { - debugMap.put("state", "retrieveAllDataFromGrouperAndTarget"); - long start = System.currentTimeMillis(); - grouperProvisioner.retrieveGrouperProvisioningLogic().retrieveAllData(); - long retrieveDataPass1 = System.currentTimeMillis()-start; - debugMap.put("retrieveDataPass1_millis", retrieveDataPass1); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveAllDataFromGrouperAndTarget); - } - - debugMap.put("state", "loadDataToGrouper"); - long start = System.currentTimeMillis(); - grouperProvisioner.retrieveGrouperProvisioningLogic().loadDataToGrouper(); - long retrieveDataPass1 = System.currentTimeMillis()-start; - debugMap.put("loadDataToGrouper_millis", retrieveDataPass1); - - try { - debugMap.put("state", "targetAttributeManipulation"); - // do not assign defaults to target - // filter groups and manipulate attributes and types - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterGroupFieldsAndAttributes( - this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningGroups(), true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes( - this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningEntities(), true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterMembershipFieldsAndAttributes( - this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningMemberships(), true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesGroups( - this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningGroups()); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities( - this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningEntities()); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesMemberships( - this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningMemberships()); - - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.targetAttributeManipulation); - } - - try { - debugMap.put("state", "matchingIdTargetObjects"); - // assign matching id to target objects - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().matchingIdTargetObjects(); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdTargetObjects); - } - - try { - debugMap.put("state", "retrieveSubjectLink"); - this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().retrieveSubjectLink(); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveSubjectLink); - } - - try { - debugMap.put("state", "translateGrouperGroupsEntitiesToTarget"); - - { - List grouperProvisioningGroups = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperProvisioningGroups(); - List grouperTargetGroups = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetGroups(grouperProvisioningGroups, false, false); - this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningGroups(grouperTargetGroups); - } - - { - List grouperProvisioningEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperProvisioningEntities(); - List grouperTargetEntities = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetEntities( - grouperProvisioningEntities, false, false); - this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningEntities(grouperTargetEntities); - } - - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.translateGrouperGroupsEntitiesToTarget); - } - - try { - debugMap.put("state", "manipulateGrouperTargetAttributes"); - List grouperTargetGroups = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetGroups(); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForGroups(grouperTargetGroups, null); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterGroupFieldsAndAttributes(grouperTargetGroups, true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesGroups(grouperTargetGroups); - - List grouperTargetEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForEntities(grouperTargetEntities, null); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes(grouperTargetEntities, true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities(grouperTargetEntities); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.manipulateGrouperTargetGroupsEntitiesAttributes); - } - - try { - debugMap.put("state", "matchingIdGrouperGroupsEntities"); - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups( - this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetGroups()); - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetEntities( - this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetEntities()); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdGrouperGroupsEntities); - } - - try { - debugMap.put("state", "retrieveIndividualEntitiesIfNeeded"); - // when select all entities is false e.g AWS then we need to fetch entities one by one. - this.grouperProvisioner.retrieveGrouperProvisioningLogic().retrieveIndividualEntitiesIfNeeded(); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveIndividualEntitiesIfNeeded); - } - - { - debugMap.put("state", "indexMatchingIdGroups"); - - // index the groups and entity matching ids - this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdGroups(); - - debugMap.put("state", "indexMatchingIdEntities"); - - this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdEntities(); - } - - { - debugMap.put("state", "assignRecalc"); - // everything in a full sync is a recalc - for (ProvisioningGroupWrapper provisioningGroupWrapper : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningGroupWrappers())) { - provisioningGroupWrapper.setRecalc(true); - } - for (ProvisioningEntityWrapper provisioningEntityWrapper : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningEntityWrappers())) { - provisioningEntityWrapper.setRecalc(true); - } - for (ProvisioningMembershipWrapper provisioningMembershipWrapper : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningMembershipWrappers())) { - provisioningMembershipWrapper.setRecalc(true); - } - - } - debugMap.put("state", "insertGroups"); - createMissingGroupsFull(); - - debugMap.put("state", "insertEntities"); - createMissingEntitiesFull(); - - try { - debugMap.put("state", "retrieveTargetGroupLink"); - this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().updateGroupLinkFull(); - - debugMap.put("state", "retrieveTargetEntityLink"); - this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().updateEntityLinkFull(); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.linkData); - } - - // validate - debugMap.put("state", "validateGroupsAndEntities"); - this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateEntities(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(), false, false); - this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateGroups(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetGroups(), false, false); - - try { - - debugMap.put("state", "translateGrouperMembershipsToTarget"); - { - List grouperProvisioningMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperProvisioningMemberships(false); - List grouperTargetMemberships = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetMemberships( - grouperProvisioningMemberships, false); - this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningMemberships(grouperTargetMemberships); - } - - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.translateGrouperMembershipsToTarget); - } - - try { - debugMap.put("state", "manipulateGrouperMembershipTargetAttributes"); - List grouperTargetMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForMemberships(grouperTargetMemberships); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterMembershipFieldsAndAttributes(grouperTargetMemberships, true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesMemberships(grouperTargetMemberships); - - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.manipulateGrouperTargetMembershipsAttributes); - } - - try { - debugMap.put("state", "matchingIdGrouperMemberships"); - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetMemberships(this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(false)); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdGrouperMemberships); - } - - // index the memberships - this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdMemberships(); - - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsSelectGroupsFull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers()); - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsSelectEntitiesFull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningEntityWrappers()); - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsSelectMembershipsFull( - this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers(), - this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningEntityWrappers(), - this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningMembershipWrappers()); - - // validate memberships - this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateMemberships(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(false), false); - this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateEntities(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(), false, true); - - try { - debugMap.put("state", "compareTargetObjects"); - this.grouperProvisioner.retrieveGrouperProvisioningCompare().compareTargetObjects(); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.compareTargetObjects); - } - - this.getGrouperProvisioner().retrieveGrouperProvisioningFailsafe().processFailsafesAtStart(); - this.getGrouperProvisioner().retrieveGrouperProvisioningFailsafe().processFailsafes(); - - RuntimeException runtimeException = null; - try { - debugMap.put("state", "sendChangesToTarget"); - TargetDaoSendChangesToTargetRequest targetDaoSendChangesToTargetRequest = new TargetDaoSendChangesToTargetRequest(); - targetDaoSendChangesToTargetRequest.setTargetObjectInserts(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts()); - targetDaoSendChangesToTargetRequest.setTargetObjectUpdates(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates()); - targetDaoSendChangesToTargetRequest.setTargetObjectReplaces(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectReplaces()); - targetDaoSendChangesToTargetRequest.setTargetObjectDeletes(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes()); - this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter().sendChangesToTarget(targetDaoSendChangesToTargetRequest); - } catch (RuntimeException e) { - runtimeException = e; - } finally { - try { - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsInserts(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts()); - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsUpdatesFull(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates()); - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsReplaces(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectReplaces()); - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsDeletes(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes()); - } catch (RuntimeException e) { - GrouperUtil.exceptionFinallyInjectOrThrow(runtimeException, e); - } - //TODO this.getGrouperProvisioner().getGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.sendChangesToTarget); - - } - - { - // counts for sync - this.countInsertsUpdatesDeletes(); - - // count total for full sync - int totalCount = 0; - for (GcGrouperSyncGroup gcGrouperSyncGroup : GrouperUtil.nonNull(this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncGroupDao().groupRetrieveAll())) { - if (gcGrouperSyncGroup.isInTarget()) { - totalCount++; - } - } - for (GcGrouperSyncMember gcGrouperSyncMember : GrouperUtil.nonNull(this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncMemberDao().memberRetrieveAll())) { - if (gcGrouperSyncMember.isInTarget()) { - totalCount++; - } - } - for (GcGrouperSyncMembership gcGrouperSyncMembership : GrouperUtil.nonNull(this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncMembershipDao().membershipRetrieveAll())) { - if (gcGrouperSyncMembership.isInTarget()) { - totalCount++; - } - } - GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningOutput().setTotalCount(totalCount); - GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningOutput().copyToHib3LoaderLog(); - } - - { - Timestamp nowTimestamp = new Timestamp(System.currentTimeMillis()); - - GcGrouperSync gcGrouperSync = this.grouperProvisioner.getGcGrouperSync(); - gcGrouperSync.setLastFullSyncStart(startTimestamp); - gcGrouperSync.setLastFullSyncRun(nowTimestamp); - - GcGrouperSyncJob gcGrouperSyncJob = this.grouperProvisioner.getGcGrouperSyncJob(); - gcGrouperSyncJob.setErrorMessage(null); - gcGrouperSyncJob.setErrorTimestamp(null); - gcGrouperSyncJob.setLastSyncTimestamp(nowTimestamp); - if (this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().wasWorkDone()) { - gcGrouperSyncJob.setLastTimeWorkWasDone(nowTimestamp); - } - gcGrouperSyncJob.setPercentComplete(100); - // 257 this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncMemberDao() - // do this in the right spot, after assigning correct sync info about sync - int objectStoreCount = this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncDao().storeAllObjects(); - this.grouperProvisioner.getProvisioningSyncResult().setSyncObjectStoreCount(objectStoreCount); - - this.grouperProvisioner.getDebugMap().put("syncObjectStoreCount", objectStoreCount); - } - - // TODO flesh this out, resolve subjects, linked cached data, etc, try individually again -// this.getGrouperProvisioner().retrieveTargetDao().resolveErrors(); -// this.getGrouperProvisioner().retrieveTargetDao().sendErrorFixesToTarget(); - -// this.getGrouperProvisioner().getGrouperProvisioningLogicAlgorithm().syncGrouperTranslatedGroupsToTarget(); -// this.getGrouperProvisioner().getGrouperProvisioningLogicAlgorithm().syncGrouperTranslatedMembershipsToTarget(); - - // make sure the sync objects are correct -// new ProvisioningSyncIntegration().assignTarget(this.getGrouperProvisioner().getConfigId()).fullSync(); - -// // step 1 -// debugMap.put("state", "retrieveData"); -// this.gcTableSyncConfiguration.getGcTableSyncSubtype().retrieveData(debugMap, this); -// -// this.gcGrouperSyncLog.setRecordsProcessed(Math.max(this.gcTableSyncOutput.getRowsSelectedFrom(), this.gcTableSyncOutput.getRowsSelectedTo())); -// -// if (this.gcGrouperSyncHeartbeat.isInterrupted()) { -// debugMap.put("interrupted", true); -// debugMap.put("state", "done"); -// gcGrouperSyncLog.setStatus(GcGrouperSyncLogState.INTERRUPTED); -// return; -// } - if (GrouperClientUtils.isBlank(this.getGrouperProvisioner().getGcGrouperSyncLog().getStatus())) { - this.getGrouperProvisioner().getGcGrouperSyncLog().setStatus(GcGrouperSyncLogState.SUCCESS); - } - - } - - public void validateAndThrowExceptionIfInvalid() { - int fatalValidationProblems = 0; - int nonfatalValidationProblems = 0; - - List validationIssues = this.grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); - - ProvisioningValidationIssue fatalError = null; - for (ProvisioningValidationIssue provisioningValidationIssue : GrouperUtil.nonNull(validationIssues)) { - if (provisioningValidationIssue.isRuntimeError()) { - if (fatalError == null) { - fatalError = provisioningValidationIssue; - } - fatalValidationProblems++; - } else { - nonfatalValidationProblems++; - } - } - - if (fatalValidationProblems > 0) { - this.getGrouperProvisioner().getDebugMap().put("fatalValidationProblems", fatalValidationProblems); - } - if (nonfatalValidationProblems > 0) { - this.getGrouperProvisioner().getDebugMap().put("nonfatalValidationProblems", nonfatalValidationProblems); - } - - if (fatalError != null) { - throw new RuntimeException("Fatal validation problem: " + fatalError.getMessage()); - } - } - - public void loadDataToGrouper() { - - if (!this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().isLoadEntitiesToGrouperTable()) { - return; - } - - // we need to get data from the table - GcTableSync loadUsersToTableGcTableSync = new GcTableSync(); - - //retrieve the existing data from database - GcTableSyncTableBean loadUsersToTableGcTableSyncTableBeanSql = new GcTableSyncTableBean(loadUsersToTableGcTableSync); - - GrouperProvisioningLoader grouperProvisioningLoader = this.grouperProvisioner.retrieveGrouperProvisioningLoader(); - String tableName = grouperProvisioningLoader.getLoaderEntityTableName(); - GrouperUtil.assertion(StringUtils.isNotBlank(tableName), "grouperLoaderEntityTableName is blank."); - - - loadUsersToTableGcTableSyncTableBeanSql.configureMetadata("grouper", tableName); - loadUsersToTableGcTableSync.setDataBeanTo(loadUsersToTableGcTableSyncTableBeanSql); - - Set databaseColumnNames = new LinkedHashSet(grouperProvisioningLoader.getLoaderEntityColumnNames()); - - Set loadUsersToTableUniqueKeyColumnNames = new LinkedHashSet(grouperProvisioningLoader.getLoaderEntityKeyColumnNames()); - - GcTableSyncTableMetadata gcTableSyncTableMetadata = loadUsersToTableGcTableSyncTableBeanSql.getTableMetadata(); - - gcTableSyncTableMetadata.assignColumns(GrouperUtil.join(databaseColumnNames.iterator(), ',')); - gcTableSyncTableMetadata.assignPrimaryKeyColumns(GrouperUtil.join(loadUsersToTableUniqueKeyColumnNames.iterator(), ',')); - - GcDbAccess gcDbAccess = new GcDbAccess().connectionName("grouper"); - - String configId = this.getGrouperProvisioner().getConfigId(); - - String sql = "select " + gcTableSyncTableMetadata.columnListAll() + " from " + gcTableSyncTableMetadata.getTableName() + " where config_id = ?"; - - List results = gcDbAccess.sql(sql).addBindVar(configId).selectList(Object[].class); - - GcTableSyncTableData loadUsersToTableGcTableSyncTableDataSql = new GcTableSyncTableData(); - loadUsersToTableGcTableSyncTableDataSql.init(loadUsersToTableGcTableSyncTableBeanSql, gcTableSyncTableMetadata.lookupColumns(loadUsersToTableGcTableSyncTableBeanSql.getTableMetadata().columnListAll()), results); - loadUsersToTableGcTableSyncTableDataSql.indexData(); - - loadUsersToTableGcTableSyncTableBeanSql.setDataInitialQuery(loadUsersToTableGcTableSyncTableDataSql); - loadUsersToTableGcTableSyncTableBeanSql.setGcTableSync(loadUsersToTableGcTableSync); - - Map debugMap = this.getGrouperProvisioner().getDebugMap(); - debugMap.put("loadUsersDbUniqueKeys", loadUsersToTableGcTableSyncTableDataSql.allPrimaryKeys().size()); - - GcTableSyncTableBean gcTableSyncTableBeanFrom = new GcTableSyncTableBean(); - loadUsersToTableGcTableSync.setDataBeanFrom(gcTableSyncTableBeanFrom); - gcTableSyncTableBeanFrom.setTableMetadata(loadUsersToTableGcTableSyncTableBeanSql.getTableMetadata()); - gcTableSyncTableBeanFrom.setGcTableSync(loadUsersToTableGcTableSync); - - GcTableSyncTableData loadUsersToTableGcTableSyncTableDataLdap = new GcTableSyncTableData(); - loadUsersToTableGcTableSync.getDataBeanFrom().setDataInitialQuery(loadUsersToTableGcTableSyncTableDataLdap); - - loadUsersToTableGcTableSyncTableDataLdap.setColumnMetadata(loadUsersToTableGcTableSyncTableDataSql.getColumnMetadata()); - - loadUsersToTableGcTableSyncTableDataLdap.setGcTableSyncTableBean(loadUsersToTableGcTableSyncTableDataSql.getGcTableSyncTableBean()); - - List gcTableSyncRowDatas = new ArrayList(); - - List targetTableData = grouperProvisioningLoader.retrieveLoaderEntityTableDataFromDataBean(); - - for (Object[] rowData: targetTableData) { - - GcTableSyncRowData gcTableSyncRowData = new GcTableSyncRowData(); - gcTableSyncRowDatas.add(gcTableSyncRowData); - - gcTableSyncRowData.setGcTableSyncTableData(loadUsersToTableGcTableSyncTableDataLdap); - - gcTableSyncRowData.setData(rowData); - - } - - - loadUsersToTableGcTableSyncTableDataLdap.setRows(gcTableSyncRowDatas); - - // compare and sync - GcTableSyncConfiguration gcTableSyncConfiguration = new GcTableSyncConfiguration(); - loadUsersToTableGcTableSync.setGcTableSyncConfiguration(gcTableSyncConfiguration); - - loadUsersToTableGcTableSync.setGcTableSyncOutput(new GcTableSyncOutput()); - - Map debugMapLocal = new LinkedHashMap(); - GcTableSyncSubtype.fullSyncFull.syncData(debugMapLocal, loadUsersToTableGcTableSync); - - // merge the debug maps - for (String key : debugMapLocal.keySet()) { - - Object newValue = debugMapLocal.get(key); - - // convert micros to millis - if (key.endsWith("Millis")) { - if (newValue instanceof Number) { - newValue = ((Number)newValue).longValue()/1000; - } - } - - - String newKey = "loadUsers" + StringUtils.capitalize(key); - debugMap.put(newKey, newValue); - - } - - } - - /** +package edu.internet2.middleware.grouper.app.provisioning; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; + +import com.fasterxml.jackson.databind.JsonNode; + +import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoInsertEntitiesRequest; +import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoInsertGroupsRequest; +import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveAllDataRequest; +import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveAllDataResponse; +import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveEntitiesRequest; +import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveEntitiesResponse; +import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveGroupsRequest; +import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveGroupsResponse; +import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoSendChangesToTargetRequest; +import edu.internet2.middleware.grouper.cfg.GrouperConfig; +import edu.internet2.middleware.grouper.ldap.LdapAttribute; +import edu.internet2.middleware.grouper.ldap.LdapEntry; +import edu.internet2.middleware.grouper.ldap.LdapSearchScope; +import edu.internet2.middleware.grouper.ldap.LdapSessionUtils; +import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClient.collections.MultiKey; +import edu.internet2.middleware.grouperClient.jdbc.GcDbAccess; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSync; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncGroup; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncJob; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncLogState; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncMember; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncMembership; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSync; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncConfiguration; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncOutput; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncRowData; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncSubtype; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncTableBean; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncTableData; +import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncTableMetadata; +import edu.internet2.middleware.grouperClient.util.GrouperClientUtils; + +/** + * does the logic to use the data from the DAOs and call the correct methods to synnc things up or dry run or send messages for async + * @author mchyzer + * + */ +public class GrouperProvisioningLogic { + + /** + * + */ + public void provision() { + + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.configure); + + Timestamp startTimestamp = new Timestamp(System.currentTimeMillis()); + this.getGrouperProvisioner().getGcGrouperSyncJob().setLastSyncStart(startTimestamp); + + this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningType().provision(this.grouperProvisioner); + + } + + /** + * + */ + public void provisionFull() { + + Map debugMap = this.getGrouperProvisioner().getDebugMap(); + Timestamp startTimestamp = new Timestamp(System.currentTimeMillis()); + + { + debugMap.put("state", "propagateProvisioningAttributes"); + long start = System.currentTimeMillis(); + grouperProvisioner.propagateProvisioningAttributes(); + long propagateProvisioningAttributes = System.currentTimeMillis()-start; + debugMap.put("propagateProvisioningAttributes_millis", propagateProvisioningAttributes); + + if (grouperProvisioner.getConfigId().startsWith("junitProvisioningAttributePropagationTest")) { + // just testing attribute propagation + return; + } + } + + // validate the perhaps throw exception + this.validateAndThrowExceptionIfInvalid(); + + try { + debugMap.put("state", "retrieveAllDataFromGrouperAndTarget"); + long start = System.currentTimeMillis(); + grouperProvisioner.retrieveGrouperProvisioningLogic().retrieveAllData(); + long retrieveDataPass1 = System.currentTimeMillis()-start; + debugMap.put("retrieveDataPass1_millis", retrieveDataPass1); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveAllDataFromGrouperAndTarget); + } + + debugMap.put("state", "loadDataToGrouper"); + long start = System.currentTimeMillis(); + grouperProvisioner.retrieveGrouperProvisioningLogic().loadDataToGrouper(); + long retrieveDataPass1 = System.currentTimeMillis()-start; + debugMap.put("loadDataToGrouper_millis", retrieveDataPass1); + + try { + debugMap.put("state", "targetAttributeManipulation"); + // do not assign defaults to target + // filter groups and manipulate attributes and types + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterGroupFieldsAndAttributes( + this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningGroups(), true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes( + this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningEntities(), true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterMembershipFieldsAndAttributes( + this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningMemberships(), true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesGroups( + this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningGroups()); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities( + this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningEntities()); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesMemberships( + this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningMemberships()); + + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.targetAttributeManipulation); + } + + try { + debugMap.put("state", "matchingIdTargetObjects"); + // assign matching id to target objects + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().matchingIdTargetObjects(); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdTargetObjects); + } + + try { + debugMap.put("state", "retrieveSubjectLink"); + this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().retrieveSubjectLink(); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveSubjectLink); + } + + try { + debugMap.put("state", "translateGrouperGroupsEntitiesToTarget"); + + { + List grouperProvisioningGroups = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperProvisioningGroups(); + List grouperTargetGroups = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetGroups(grouperProvisioningGroups, false, false); + this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningGroups(grouperTargetGroups); + } + + { + List grouperProvisioningEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperProvisioningEntities(); + List grouperTargetEntities = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetEntities( + grouperProvisioningEntities, false, false); + this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningEntities(grouperTargetEntities); + } + + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.translateGrouperGroupsEntitiesToTarget); + } + + try { + debugMap.put("state", "manipulateGrouperTargetAttributes"); + List grouperTargetGroups = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetGroups(); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForGroups(grouperTargetGroups, null); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterGroupFieldsAndAttributes(grouperTargetGroups, true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesGroups(grouperTargetGroups); + + List grouperTargetEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForEntities(grouperTargetEntities, null); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes(grouperTargetEntities, true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities(grouperTargetEntities); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.manipulateGrouperTargetGroupsEntitiesAttributes); + } + + try { + debugMap.put("state", "matchingIdGrouperGroupsEntities"); + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups( + this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetGroups()); + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetEntities( + this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetEntities()); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdGrouperGroupsEntities); + } + + try { + debugMap.put("state", "retrieveIndividualEntitiesIfNeeded"); + // when select all entities is false e.g AWS then we need to fetch entities one by one. + this.grouperProvisioner.retrieveGrouperProvisioningLogic().retrieveIndividualEntitiesIfNeeded(); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveIndividualEntitiesIfNeeded); + } + + { + debugMap.put("state", "indexMatchingIdGroups"); + + // index the groups and entity matching ids + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdGroups(); + + debugMap.put("state", "indexMatchingIdEntities"); + + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdEntities(); + } + + { + debugMap.put("state", "indexMatchingIdGroupsUnmatched"); + + // index the groups and entity matching ids + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdGroupsUnmatched(null); + +// debugMap.put("state", "indexMatchingIdEntities"); +// +// this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdEntities(); + } + + +// try { +// debugMap.put("state", "retrieveIndividualMissingGroups"); +// // if a group was renamed in grouper or the target, and doesn't match then look for it by other search attributes or past search attributes +// this.grouperProvisioner.retrieveGrouperProvisioningLogic().retrieveIndividualMissingGroups(); +// } finally { +// this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveIndividualMissingGroups); +// } + + + + { + debugMap.put("state", "assignRecalc"); + // everything in a full sync is a recalc + for (ProvisioningGroupWrapper provisioningGroupWrapper : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningGroupWrappers())) { + provisioningGroupWrapper.setRecalc(true); + } + for (ProvisioningEntityWrapper provisioningEntityWrapper : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningEntityWrappers())) { + provisioningEntityWrapper.setRecalc(true); + } + for (ProvisioningMembershipWrapper provisioningMembershipWrapper : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningMembershipWrappers())) { + provisioningMembershipWrapper.setRecalc(true); + } + + } + debugMap.put("state", "insertGroups"); + createMissingGroupsFull(); + + debugMap.put("state", "insertEntities"); + createMissingEntitiesFull(); + + try { + debugMap.put("state", "retrieveTargetGroupLink"); + this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().updateGroupLinkFull(); + + debugMap.put("state", "retrieveTargetEntityLink"); + this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().updateEntityLinkFull(); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.linkData); + } + + try { + // validate + debugMap.put("state", "validateGroupsAndEntities"); + this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateEntities(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(), false, false); + this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateGroupsHaveMembers(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetGroups(), false); + this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateGroups(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetGroups(), false, false); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.validateGrouperGroupsEntities); + } + + try { + + debugMap.put("state", "translateGrouperMembershipsToTarget"); + { + List grouperProvisioningMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperProvisioningMemberships(false); + List grouperTargetMemberships = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetMemberships( + grouperProvisioningMemberships, false); + this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningMemberships(grouperTargetMemberships); + } + + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.translateGrouperMembershipsToTarget); + } + + try { + debugMap.put("state", "manipulateGrouperMembershipTargetAttributes"); + List grouperTargetMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForMemberships(grouperTargetMemberships); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterMembershipFieldsAndAttributes(grouperTargetMemberships, true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesMemberships(grouperTargetMemberships); + + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.manipulateGrouperTargetMembershipsAttributes); + } + + try { + debugMap.put("state", "matchingIdGrouperMemberships"); + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetMemberships(this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(false)); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdGrouperMemberships); + } + + // index the memberships + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdMemberships(); + + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsSelectGroupsFull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers()); + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsSelectEntitiesFull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningEntityWrappers()); + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsSelectMembershipsFull( + this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers(), + this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningEntityWrappers(), + this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningMembershipWrappers()); + + // validate memberships + this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateMemberships(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(false), false); + this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateEntities(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(), false, true); + + try { + debugMap.put("state", "compareTargetObjects"); + this.grouperProvisioner.retrieveGrouperProvisioningCompare().compareTargetObjects(); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.compareTargetObjects); + } + + this.getGrouperProvisioner().retrieveGrouperProvisioningFailsafe().processFailsafesAtStart(); + this.getGrouperProvisioner().retrieveGrouperProvisioningFailsafe().processFailsafes(); + + RuntimeException runtimeException = null; + try { + debugMap.put("state", "sendChangesToTarget"); + TargetDaoSendChangesToTargetRequest targetDaoSendChangesToTargetRequest = new TargetDaoSendChangesToTargetRequest(); + targetDaoSendChangesToTargetRequest.setTargetObjectInserts(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts()); + targetDaoSendChangesToTargetRequest.setTargetObjectUpdates(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates()); + targetDaoSendChangesToTargetRequest.setTargetObjectReplaces(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectReplaces()); + targetDaoSendChangesToTargetRequest.setTargetObjectDeletes(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes()); + this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter().sendChangesToTarget(targetDaoSendChangesToTargetRequest); + } catch (RuntimeException e) { + runtimeException = e; + } finally { + try { + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsInserts(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts()); + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsUpdatesFull(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates()); + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsReplaces(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectReplaces()); + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsDeletes(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes()); + } catch (RuntimeException e) { + GrouperUtil.exceptionFinallyInjectOrThrow(runtimeException, e); + } + //TODO this.getGrouperProvisioner().getGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.sendChangesToTarget); + + } + + { + // counts for sync + this.countInsertsUpdatesDeletes(); + + // count total for full sync + int totalCount = 0; + for (GcGrouperSyncGroup gcGrouperSyncGroup : GrouperUtil.nonNull(this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncGroupDao().groupRetrieveAll())) { + if (gcGrouperSyncGroup.isInTarget()) { + totalCount++; + } + } + for (GcGrouperSyncMember gcGrouperSyncMember : GrouperUtil.nonNull(this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncMemberDao().memberRetrieveAll())) { + if (gcGrouperSyncMember.isInTarget()) { + totalCount++; + } + } + for (GcGrouperSyncMembership gcGrouperSyncMembership : GrouperUtil.nonNull(this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncMembershipDao().membershipRetrieveAll())) { + if (gcGrouperSyncMembership.isInTarget()) { + totalCount++; + } + } + GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningOutput().setTotalCount(totalCount); + GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningOutput().copyToHib3LoaderLog(); + } + + { + Timestamp nowTimestamp = new Timestamp(System.currentTimeMillis()); + + GcGrouperSync gcGrouperSync = this.grouperProvisioner.getGcGrouperSync(); + gcGrouperSync.setLastFullSyncStart(startTimestamp); + gcGrouperSync.setLastFullSyncRun(nowTimestamp); + + GcGrouperSyncJob gcGrouperSyncJob = this.grouperProvisioner.getGcGrouperSyncJob(); + gcGrouperSyncJob.setErrorMessage(null); + gcGrouperSyncJob.setErrorTimestamp(null); + gcGrouperSyncJob.setLastSyncTimestamp(nowTimestamp); + if (this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().wasWorkDone()) { + gcGrouperSyncJob.setLastTimeWorkWasDone(nowTimestamp); + } + gcGrouperSyncJob.setPercentComplete(100); + // 257 this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncMemberDao() + // do this in the right spot, after assigning correct sync info about sync + int objectStoreCount = this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncDao().storeAllObjects(); + this.grouperProvisioner.getProvisioningSyncResult().setSyncObjectStoreCount(objectStoreCount); + + this.grouperProvisioner.getDebugMap().put("syncObjectStoreCount", objectStoreCount); + } + + // TODO flesh this out, resolve subjects, linked cached data, etc, try individually again +// this.getGrouperProvisioner().retrieveTargetDao().resolveErrors(); +// this.getGrouperProvisioner().retrieveTargetDao().sendErrorFixesToTarget(); + +// this.getGrouperProvisioner().getGrouperProvisioningLogicAlgorithm().syncGrouperTranslatedGroupsToTarget(); +// this.getGrouperProvisioner().getGrouperProvisioningLogicAlgorithm().syncGrouperTranslatedMembershipsToTarget(); + + // make sure the sync objects are correct +// new ProvisioningSyncIntegration().assignTarget(this.getGrouperProvisioner().getConfigId()).fullSync(); + +// // step 1 +// debugMap.put("state", "retrieveData"); +// this.gcTableSyncConfiguration.getGcTableSyncSubtype().retrieveData(debugMap, this); +// +// this.gcGrouperSyncLog.setRecordsProcessed(Math.max(this.gcTableSyncOutput.getRowsSelectedFrom(), this.gcTableSyncOutput.getRowsSelectedTo())); +// +// if (this.gcGrouperSyncHeartbeat.isInterrupted()) { +// debugMap.put("interrupted", true); +// debugMap.put("state", "done"); +// gcGrouperSyncLog.setStatus(GcGrouperSyncLogState.INTERRUPTED); +// return; +// } + if (GrouperClientUtils.isBlank(this.getGrouperProvisioner().getGcGrouperSyncLog().getStatus())) { + this.getGrouperProvisioner().getGcGrouperSyncLog().setStatus(GcGrouperSyncLogState.SUCCESS); + } + + } + + /** + * if a group was renamed in grouper or the target, and doesn't match then look for it by other search attributes or past search attributes + */ + public void retrieveIndividualMissingGroups() { + + //do we have missing groups? + List missingGroups = new ArrayList(); + List missingGroupWrappers = new ArrayList(); + + for (ProvisioningGroupWrapper provisioningGroupWrapper : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers())) { + + ProvisioningGroup provisioningGroup = provisioningGroupWrapper.getGrouperProvisioningGroup(); + + if (provisioningGroup == null) { + continue; + } + + ProvisioningGroup targetGroup = provisioningGroupWrapper.getTargetProvisioningGroup(); + + if (targetGroup != null) { + continue; + } + + missingGroups.add(provisioningGroup); + missingGroupWrappers.add(provisioningGroupWrapper); + } + + if (GrouperUtil.length(missingGroups) == 0) { + return; + } + + // how many do we have + this.grouperProvisioner.getDebugMap().put("missingGroupsForRetrieve", GrouperUtil.length(missingGroups)); + + List searchAttributes = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupSearchAttributes(); +// for (GrouperProvisioningConfigurationAttribute searchAttribute : GrouperUtil.nonNull(searchAttributes)) { +// String value = searchAttribute.getTranslateFromGrouperProvisioningGroupField(); +// if (value != null && value.startsWith("subjectIdentifier")) { +// currSubjectIdentifierForMemberSyncTable = value; +// } +// } + + Set alreadySearchedForAttributeAndValue = new HashSet<>(); + + for (ProvisioningGroup missingGroup: missingGroups) { + ProvisioningGroupWrapper missingGroupWrapper = missingGroup.getProvisioningGroupWrapper(); + // we've a list of search attributes + // for each attribute we have the current state and we have the past state + // we just need to look everywhere until we find something + // the algo should look first at the past state and then any secondary places + + + for (GrouperProvisioningConfigurationAttribute searchAttribute : GrouperUtil.nonNull(searchAttributes)) { + + String attributeName = searchAttribute.getTranslateFromGrouperProvisioningGroupField(); + + +// if (alreadySearchedForAttributeAndValue.contains(new MultiKey(key1, key2))) { +// +// } + + + } + + + } + + } + + public void validateAndThrowExceptionIfInvalid() { + int fatalValidationProblems = 0; + int nonfatalValidationProblems = 0; + + List validationIssues = this.grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); + + ProvisioningValidationIssue fatalError = null; + for (ProvisioningValidationIssue provisioningValidationIssue : GrouperUtil.nonNull(validationIssues)) { + if (provisioningValidationIssue.isRuntimeError()) { + if (fatalError == null) { + fatalError = provisioningValidationIssue; + } + fatalValidationProblems++; + } else { + nonfatalValidationProblems++; + } + } + + if (fatalValidationProblems > 0) { + this.getGrouperProvisioner().getDebugMap().put("fatalValidationProblems", fatalValidationProblems); + } + if (nonfatalValidationProblems > 0) { + this.getGrouperProvisioner().getDebugMap().put("nonfatalValidationProblems", nonfatalValidationProblems); + } + + if (fatalError != null) { + throw new RuntimeException("Fatal validation problem: " + fatalError.getMessage()); + } + } + + public void loadDataToGrouper() { + + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().isLoadEntitiesToGrouperTable()) { + return; + } + + // we need to get data from the table + GcTableSync loadUsersToTableGcTableSync = new GcTableSync(); + + //retrieve the existing data from database + GcTableSyncTableBean loadUsersToTableGcTableSyncTableBeanSql = new GcTableSyncTableBean(loadUsersToTableGcTableSync); + + GrouperProvisioningLoader grouperProvisioningLoader = this.grouperProvisioner.retrieveGrouperProvisioningLoader(); + String tableName = grouperProvisioningLoader.getLoaderEntityTableName(); + GrouperUtil.assertion(StringUtils.isNotBlank(tableName), "grouperLoaderEntityTableName is blank."); + + + loadUsersToTableGcTableSyncTableBeanSql.configureMetadata("grouper", tableName); + loadUsersToTableGcTableSync.setDataBeanTo(loadUsersToTableGcTableSyncTableBeanSql); + + Set databaseColumnNames = new LinkedHashSet(grouperProvisioningLoader.getLoaderEntityColumnNames()); + + Set loadUsersToTableUniqueKeyColumnNames = new LinkedHashSet(grouperProvisioningLoader.getLoaderEntityKeyColumnNames()); + + GcTableSyncTableMetadata gcTableSyncTableMetadata = loadUsersToTableGcTableSyncTableBeanSql.getTableMetadata(); + + gcTableSyncTableMetadata.assignColumns(GrouperUtil.join(databaseColumnNames.iterator(), ',')); + gcTableSyncTableMetadata.assignPrimaryKeyColumns(GrouperUtil.join(loadUsersToTableUniqueKeyColumnNames.iterator(), ',')); + + GcDbAccess gcDbAccess = new GcDbAccess().connectionName("grouper"); + + String configId = this.getGrouperProvisioner().getConfigId(); + + String sql = "select " + gcTableSyncTableMetadata.columnListAll() + " from " + gcTableSyncTableMetadata.getTableName() + " where config_id = ?"; + + List results = gcDbAccess.sql(sql).addBindVar(configId).selectList(Object[].class); + + GcTableSyncTableData loadUsersToTableGcTableSyncTableDataSql = new GcTableSyncTableData(); + loadUsersToTableGcTableSyncTableDataSql.init(loadUsersToTableGcTableSyncTableBeanSql, gcTableSyncTableMetadata.lookupColumns(loadUsersToTableGcTableSyncTableBeanSql.getTableMetadata().columnListAll()), results); + loadUsersToTableGcTableSyncTableDataSql.indexData(); + + loadUsersToTableGcTableSyncTableBeanSql.setDataInitialQuery(loadUsersToTableGcTableSyncTableDataSql); + loadUsersToTableGcTableSyncTableBeanSql.setGcTableSync(loadUsersToTableGcTableSync); + + Map debugMap = this.getGrouperProvisioner().getDebugMap(); + debugMap.put("loadUsersDbUniqueKeys", loadUsersToTableGcTableSyncTableDataSql.allPrimaryKeys().size()); + + GcTableSyncTableBean gcTableSyncTableBeanFrom = new GcTableSyncTableBean(); + loadUsersToTableGcTableSync.setDataBeanFrom(gcTableSyncTableBeanFrom); + gcTableSyncTableBeanFrom.setTableMetadata(loadUsersToTableGcTableSyncTableBeanSql.getTableMetadata()); + gcTableSyncTableBeanFrom.setGcTableSync(loadUsersToTableGcTableSync); + + GcTableSyncTableData loadUsersToTableGcTableSyncTableDataLdap = new GcTableSyncTableData(); + loadUsersToTableGcTableSync.getDataBeanFrom().setDataInitialQuery(loadUsersToTableGcTableSyncTableDataLdap); + + loadUsersToTableGcTableSyncTableDataLdap.setColumnMetadata(loadUsersToTableGcTableSyncTableDataSql.getColumnMetadata()); + + loadUsersToTableGcTableSyncTableDataLdap.setGcTableSyncTableBean(loadUsersToTableGcTableSyncTableDataSql.getGcTableSyncTableBean()); + + List gcTableSyncRowDatas = new ArrayList(); + + List targetTableData = grouperProvisioningLoader.retrieveLoaderEntityTableDataFromDataBean(); + + for (Object[] rowData: targetTableData) { + + GcTableSyncRowData gcTableSyncRowData = new GcTableSyncRowData(); + gcTableSyncRowDatas.add(gcTableSyncRowData); + + gcTableSyncRowData.setGcTableSyncTableData(loadUsersToTableGcTableSyncTableDataLdap); + + gcTableSyncRowData.setData(rowData); + + } + + + loadUsersToTableGcTableSyncTableDataLdap.setRows(gcTableSyncRowDatas); + + // compare and sync + GcTableSyncConfiguration gcTableSyncConfiguration = new GcTableSyncConfiguration(); + loadUsersToTableGcTableSync.setGcTableSyncConfiguration(gcTableSyncConfiguration); + + loadUsersToTableGcTableSync.setGcTableSyncOutput(new GcTableSyncOutput()); + + Map debugMapLocal = new LinkedHashMap(); + GcTableSyncSubtype.fullSyncFull.syncData(debugMapLocal, loadUsersToTableGcTableSync); + + // merge the debug maps + for (String key : debugMapLocal.keySet()) { + + Object newValue = debugMapLocal.get(key); + + // convert micros to millis + if (key.endsWith("Millis")) { + if (newValue instanceof Number) { + newValue = ((Number)newValue).longValue()/1000; + } + } + + + String newKey = "loadUsers" + StringUtils.capitalize(key); + debugMap.put(newKey, newValue); + + } + + } + + /** * when data was retrieved (i.e. when the group syncs start) */ private long retrieveDataStartMillisSince1970 = -1; @@ -548,2352 +644,2335 @@ public void loadDataToGrouper() { */ public long getRetrieveDataStartMillisSince1970() { return retrieveDataStartMillisSince1970; - } - - /** - * - */ - public void retrieveIndividualEntitiesIfNeeded() { - - if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectEntitiesAll() || !this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectEntities()) { - return; - } - - // Step 1 - Get all the grouper target entities and select them from the target (Call the batch method that gets all at once) - - List grouperTargetEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(); - - TargetDaoRetrieveEntitiesRequest targetDaoRetrieveEntitiesRequest = new TargetDaoRetrieveEntitiesRequest(grouperTargetEntities, false); - - TargetDaoRetrieveEntitiesResponse targetEntitiesResponse = this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter().retrieveEntities(targetDaoRetrieveEntitiesRequest); - - // Step 2 - Go through retrieveAllData method and whatever processing is done on the target entities; perform them here as well - GrouperProvisioningLists targetProvisioningObjects = this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects(); - if (targetProvisioningObjects.getProvisioningEntities() == null) { - targetProvisioningObjects.setProvisioningEntities(targetEntitiesResponse.getTargetEntities()); - } else { - targetProvisioningObjects.getProvisioningEntities().addAll(targetEntitiesResponse.getTargetEntities()); - } - - Set provisioningEntityWrappers = this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningEntityWrappers(); - - // add wrappers for all groups - for (ProvisioningEntity targetProvisioningEntity : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningEntities())) { - ProvisioningEntityWrapper provisioningEntityWrapper = new ProvisioningEntityWrapper(); - provisioningEntityWrapper.setGrouperProvisioner(this.grouperProvisioner); - provisioningEntityWrappers.add(provisioningEntityWrapper); - - provisioningEntityWrapper.setTargetProvisioningEntity(targetProvisioningEntity); - } - - // Step 3 - Go through the full logic and see if any other processing is done on the target entities - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForEntities( - this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningEntities(), null); - - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes( - this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningEntities(), true, false, false); - - - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities( - this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningEntities()); - - - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetEntities(this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveTargetProvisioningEntities()); - + } + + /** + * + */ + public void retrieveIndividualEntitiesIfNeeded() { + + if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectEntitiesAll() || !this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectEntities()) { + return; + } + + // Step 1 - Get all the grouper target entities and select them from the target (Call the batch method that gets all at once) + + List grouperTargetEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(); + + TargetDaoRetrieveEntitiesRequest targetDaoRetrieveEntitiesRequest = new TargetDaoRetrieveEntitiesRequest(grouperTargetEntities, false); + + TargetDaoRetrieveEntitiesResponse targetEntitiesResponse = this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter().retrieveEntities(targetDaoRetrieveEntitiesRequest); + + // Step 2 - Go through retrieveAllData method and whatever processing is done on the target entities; perform them here as well + GrouperProvisioningLists targetProvisioningObjects = this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects(); + if (targetProvisioningObjects.getProvisioningEntities() == null) { + targetProvisioningObjects.setProvisioningEntities(targetEntitiesResponse.getTargetEntities()); + } else { + targetProvisioningObjects.getProvisioningEntities().addAll(targetEntitiesResponse.getTargetEntities()); + } + + Set provisioningEntityWrappers = this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningEntityWrappers(); + + // add wrappers for all groups + for (ProvisioningEntity targetProvisioningEntity : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningEntities())) { + ProvisioningEntityWrapper provisioningEntityWrapper = new ProvisioningEntityWrapper(); + provisioningEntityWrapper.setGrouperProvisioner(this.grouperProvisioner); + provisioningEntityWrappers.add(provisioningEntityWrapper); + + provisioningEntityWrapper.setTargetProvisioningEntity(targetProvisioningEntity); + } + + // Step 3 - Go through the full logic and see if any other processing is done on the target entities + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForEntities( + this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningEntities(), null); + + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes( + this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningEntities(), true, false, false); + + + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities( + this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveTargetProvisioningEntities()); + + + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetEntities(this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveTargetProvisioningEntities()); + } /** - * - */ - public void provisionIncremental() { - - Map debugMap = this.getGrouperProvisioner().getDebugMap(); - - GrouperProvisioningLogicIncremental grouperProvisioningLogicIncremental = this.getGrouperProvisioner().retrieveGrouperProvisioningLogicIncremental(); - - this.getGrouperProvisioner().retrieveGrouperProvisioningFailsafe().processFailsafesAtStart(); - - try { - // ######### STEP 1: propagate provisioning data to group sync table - debugMap.put("state", "propagateProvisioningAttributes"); - grouperProvisioningLogicIncremental.propagateProvisioningAttributes(); - - // validate the perhaps throw exception - this.validateAndThrowExceptionIfInvalid(); - - // ######### STEP 2: check messages - debugMap.put("state", "incrementalCheckMessages"); - grouperProvisioningLogicIncremental.incrementalCheckMessages(); - - if (this.getGrouperProvisioner().getConfigId().startsWith("junitProvisioningAttributePropagationTest")) { - // just testing attribute propagation - return; - } - - // ######### STEP 3: check for esb events - debugMap.put("state", "incrementalCheckChangeLog"); - grouperProvisioningLogicIncremental.incrementalCheckChangeLog(); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.logIncomingDataUnprocessed); - } - - if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { - - // ######### STEP 4: see if any actions happened before the last full sync - debugMap.put("state", "filterByProvisioningFullSync"); - grouperProvisioningLogicIncremental.filterByProvisioningFullSync(); - } - - if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isFullSync()) { - - debugMap.put("runFullSync", "true"); - - runFullSyncFromIncremental(); - - } else { - - if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { - // ######### STEP 5: events without recalc that occurred during full sync (after start before finish), should be recalc'ed - debugMap.put("state", "recalcActionsDuringFullSync"); - grouperProvisioningLogicIncremental.recalcEventsDuringFullSync(); - } - - // ######### STEP 6: look for errors based on algorithm and retry those actions - debugMap.put("state", "addErrorsToQueue"); - grouperProvisioningLogicIncremental.addErrorsToQueue(); - - if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { - // ######### STEP 7: filter out non recalc actions captures in recalc - debugMap.put("state", "filterNonRecalcActionsCapturedByRecalc"); - grouperProvisioningLogicIncremental.filterNonRecalcActionsCapturedByRecalc(); - } - -// // ######### STEP 8: organize recalc and non recalc requests groups -// debugMap.put("state", "organizeRecalcAndNonRecalcRequestsGroups"); -// grouperProvisioningLogicIncremental.organizeRecalcAndNonRecalcRequestsGroups(); - - if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { - // ######### STEP 8: retrieve all group sync objects for - debugMap.put("state", "retrieveIncrementalSyncGroups"); - { - this.getGrouperProvisioner().retrieveGrouperProvisioningSyncDao().retrieveIncrementalSyncGroups(); - Map grouperSyncGroupIdToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncGroupIdToProvisioningGroupWrapper(); - assignSyncObjectsToWrappersGroups(grouperSyncGroupIdToProvisioningGroupWrapper); - } - - // ######### STEP 9: retrieve provisioning attributes for recalc groups and adjust sync objects - //debugMap.put("state", "retrieveProvisioningGroupAttributesAndFixGroupSync"); - //grouperProvisioningLogicIncremental.retrieveProvisioningGroupAttributesAndFixGroupSync(); - - // ######### STEP 10: filter if not provisionable - debugMap.put("state", "filterByNotProvisionable"); - grouperProvisioningLogicIncremental.filterByGroupNotProvisionable(); - } - - if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { - // ######### STEP 11: filter by group sync - debugMap.put("state", "filterByGroupSync"); - grouperProvisioningLogicIncremental.filterByGroupSync(); - } - - if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { - // ######### STEP 12: convert to group sync - debugMap.put("state", "convertToGroupSync"); - grouperProvisioningLogicIncremental.convertToGroupSync(); - } - - if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { - // ######### STEP 13: convert to full sync - debugMap.put("state", "convertToFullSync"); - grouperProvisioningLogicIncremental.convertToFullSync(); - } - - if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isFullSync()) { - - debugMap.put("runFullSync", "true"); - - runFullSyncFromIncremental(); - - } else { - - if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { - // ######### STEP 14: events without recalc that occurred during group sync (after start before finish), should be recalc'ed - debugMap.put("state", "recalcActionsDuringGroupSync"); - grouperProvisioningLogicIncremental.recalcEventsDuringGroupSync(); - } - - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.logIncomingDataToProcess); - + * + */ + public void provisionIncremental() { + + Map debugMap = this.getGrouperProvisioner().getDebugMap(); + + GrouperProvisioningLogicIncremental grouperProvisioningLogicIncremental = this.getGrouperProvisioner().retrieveGrouperProvisioningLogicIncremental(); + + this.getGrouperProvisioner().retrieveGrouperProvisioningFailsafe().processFailsafesAtStart(); + + try { + // ######### STEP 1: propagate provisioning data to group sync table + debugMap.put("state", "propagateProvisioningAttributes"); + grouperProvisioningLogicIncremental.propagateProvisioningAttributes(); + + // validate the perhaps throw exception + this.validateAndThrowExceptionIfInvalid(); + + // ######### STEP 2: check messages + debugMap.put("state", "incrementalCheckMessages"); + grouperProvisioningLogicIncremental.incrementalCheckMessages(); + + if (this.getGrouperProvisioner().getConfigId().startsWith("junitProvisioningAttributePropagationTest")) { + // just testing attribute propagation + return; + } + + // ######### STEP 3: check for esb events + debugMap.put("state", "incrementalCheckChangeLog"); + grouperProvisioningLogicIncremental.incrementalCheckChangeLog(); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.logIncomingDataUnprocessed); + } + + if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { + + // ######### STEP 4: see if any actions happened before the last full sync + debugMap.put("state", "filterByProvisioningFullSync"); + grouperProvisioningLogicIncremental.filterByProvisioningFullSync(); + } + + if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isFullSync()) { + + debugMap.put("runFullSync", "true"); + + runFullSyncFromIncremental(); + + } else { + + if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { + // ######### STEP 5: events without recalc that occurred during full sync (after start before finish), should be recalc'ed + debugMap.put("state", "recalcActionsDuringFullSync"); + grouperProvisioningLogicIncremental.recalcEventsDuringFullSync(); + } + + // ######### STEP 6: look for errors based on algorithm and retry those actions + debugMap.put("state", "addErrorsToQueue"); + grouperProvisioningLogicIncremental.addErrorsToQueue(); + + if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { + // ######### STEP 7: filter out non recalc actions captures in recalc + debugMap.put("state", "filterNonRecalcActionsCapturedByRecalc"); + grouperProvisioningLogicIncremental.filterNonRecalcActionsCapturedByRecalc(); + } + +// // ######### STEP 8: organize recalc and non recalc requests groups +// debugMap.put("state", "organizeRecalcAndNonRecalcRequestsGroups"); +// grouperProvisioningLogicIncremental.organizeRecalcAndNonRecalcRequestsGroups(); + + if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { + // ######### STEP 8: retrieve all group sync objects for + debugMap.put("state", "retrieveIncrementalSyncGroups"); + { + this.getGrouperProvisioner().retrieveGrouperProvisioningSyncDao().retrieveIncrementalSyncGroups(); + Map grouperSyncGroupIdToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncGroupIdToProvisioningGroupWrapper(); + assignSyncObjectsToWrappersGroups(grouperSyncGroupIdToProvisioningGroupWrapper); + } + + // ######### STEP 9: retrieve provisioning attributes for recalc groups and adjust sync objects + //debugMap.put("state", "retrieveProvisioningGroupAttributesAndFixGroupSync"); + //grouperProvisioningLogicIncremental.retrieveProvisioningGroupAttributesAndFixGroupSync(); + + // ######### STEP 10: filter if not provisionable + debugMap.put("state", "filterByNotProvisionable"); + grouperProvisioningLogicIncremental.filterByGroupNotProvisionable(); + } + + if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { + // ######### STEP 11: filter by group sync + debugMap.put("state", "filterByGroupSync"); + grouperProvisioningLogicIncremental.filterByGroupSync(); + } + + if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { + // ######### STEP 12: convert to group sync + debugMap.put("state", "convertToGroupSync"); + grouperProvisioningLogicIncremental.convertToGroupSync(); + } + + if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { + // ######### STEP 13: convert to full sync + debugMap.put("state", "convertToFullSync"); + grouperProvisioningLogicIncremental.convertToFullSync(); + } + + if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isFullSync()) { + + debugMap.put("runFullSync", "true"); + + runFullSyncFromIncremental(); + + } else { + + if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { + // ######### STEP 14: events without recalc that occurred during group sync (after start before finish), should be recalc'ed + debugMap.put("state", "recalcActionsDuringGroupSync"); + grouperProvisioningLogicIncremental.recalcEventsDuringGroupSync(); + } + + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.logIncomingDataToProcess); + // index recalc data this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().indexIncrementalData(); - if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { - // ######### STEP 15: retrieve all membership sync objects - // ######### STEP 16: retrieve all members sync objects - debugMap.put("state", "retrieveIncrementalSyncMemberships"); - { - this.getGrouperProvisioner().retrieveGrouperProvisioningSyncDao().retrieveIncrementalSyncMemberships(); - this.getGrouperProvisioner().retrieveGrouperProvisioningSyncDao().retrieveIncrementalSyncMembers(); - - Map grouperSyncMemberIdToProvisioningEntityWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncMemberIdToProvisioningEntityWrapper(); - assignSyncObjectsToWrappersMembers(grouperSyncMemberIdToProvisioningEntityWrapper); - - Map grouperSyncGroupIdToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncGroupIdToProvisioningGroupWrapper(); - Map grouperSyncGroupIdGrouperSyncMemberIdToProvisioningMembershipWrapper - = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncGroupIdGrouperSyncMemberIdToProvisioningMembershipWrapper(); - assignSyncObjectsToWrappersMemberships(grouperSyncGroupIdToProvisioningGroupWrapper, grouperSyncMemberIdToProvisioningEntityWrapper, grouperSyncGroupIdGrouperSyncMemberIdToProvisioningMembershipWrapper); - } - - // ######### STEP 17: retrieve grouper data - try { - debugMap.put("state", "retrieveIncrementalDataFromGrouper"); - long start = System.currentTimeMillis(); + if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { + // ######### STEP 15: retrieve all membership sync objects + // ######### STEP 16: retrieve all members sync objects + debugMap.put("state", "retrieveIncrementalSyncMemberships"); + { + this.getGrouperProvisioner().retrieveGrouperProvisioningSyncDao().retrieveIncrementalSyncMemberships(); + this.getGrouperProvisioner().retrieveGrouperProvisioningSyncDao().retrieveIncrementalSyncMembers(); + + Map grouperSyncMemberIdToProvisioningEntityWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncMemberIdToProvisioningEntityWrapper(); + assignSyncObjectsToWrappersMembers(grouperSyncMemberIdToProvisioningEntityWrapper); + + Map grouperSyncGroupIdToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncGroupIdToProvisioningGroupWrapper(); + Map grouperSyncGroupIdGrouperSyncMemberIdToProvisioningMembershipWrapper + = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncGroupIdGrouperSyncMemberIdToProvisioningMembershipWrapper(); + assignSyncObjectsToWrappersMemberships(grouperSyncGroupIdToProvisioningGroupWrapper, grouperSyncMemberIdToProvisioningEntityWrapper, grouperSyncGroupIdGrouperSyncMemberIdToProvisioningMembershipWrapper); + } + + // ######### STEP 17: retrieve grouper data + try { + debugMap.put("state", "retrieveIncrementalDataFromGrouper"); + long start = System.currentTimeMillis(); this.retrieveDataStartMillisSince1970 = start; // keep track of when this started so we can update when group syncs occurred debugMap.put("retrieveDataStartMillisSince1970", start); - grouperProvisioner.retrieveGrouperProvisioningLogic().retrieveGrouperDataIncremental(); - long retrieveGrouperDataMillis = System.currentTimeMillis()-start; - debugMap.put("retrieveGrouperDataMillis", retrieveGrouperDataMillis); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveIncrementalDataFromGrouper); - } - - // ######### STEP 18: filter unneeded actions - debugMap.put("state", "filterUnneededActions"); - grouperProvisioningLogicIncremental.filterUnneededActions(); - - // ######### STEP 19: convert inconsistent events to recalc - debugMap.put("state", "convertInconsistentEventsToRecalc"); - grouperProvisioningLogicIncremental.convertInconsistentEventsToRecalc(); - - // ######### STEP 20: copy incremental state to wrappers (so wrapper knows if recalc or whatever) - debugMap.put("state", "copyIncrementalStateToWrappers"); - grouperProvisioningLogicIncremental.copyIncrementalStateToWrappers(); - - // ######### STEP 21: resolve subjects for subject link if recalc or for subjects missing data - try { - debugMap.put("state", "retrieveSubjectLink"); - this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().retrieveSubjectLink(); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveSubjectLink); - } - } - - if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { - // ######### STEP 22: translate grouper groups/entities to target format - try { - debugMap.put("state", "translateGrouperGroupsEntitiesToTarget"); - - { - List grouperProvisioningGroups = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperProvisioningGroups(); - List grouperTargetGroups = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetGroups(grouperProvisioningGroups, false, false); - this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningGroups(grouperTargetGroups); - } - - { - List grouperProvisioningEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperProvisioningEntities(); - - List grouperTargetEntities = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetEntities( - grouperProvisioningEntities, false, false); - this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningEntities(grouperTargetEntities); - } - - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.translateGrouperGroupsEntitiesToTarget); - } - - // ######### STEP 23: based on configs manipulate the defaults, types, etc for grouper target groups/entities translated attributes and fields - try { - debugMap.put("state", "manipulateGrouperTargetAttributes"); - List grouperTargetGroups = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetGroups(); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForGroups(grouperTargetGroups, null); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterGroupFieldsAndAttributes(grouperTargetGroups, true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesGroups(grouperTargetGroups); - - List grouperTargetEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForEntities(grouperTargetEntities, null); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes(grouperTargetEntities, true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities(grouperTargetEntities); - - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.manipulateGrouperTargetGroupsEntitiesAttributes); - } - - // ######### STEP 24: calculate the matching id of grouper translated groups/entities - try { - debugMap.put("state", "matchingIdGrouperGroupsEntities"); - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups( - this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetGroups()); - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetEntities( - this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetEntities()); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdGrouperGroupsEntities); - } - - // ######### STEP 25: take all the matching ids of grouper groups/entities and index those for quick lookups - { - debugMap.put("state", "indexMatchingIdGroups"); - - // index the groups and entity matching ids - this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdGroups(); - - debugMap.put("state", "indexMatchingIdEntities"); - - this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdEntities(); - - } - - // ######### STEP 26: take all the matching ids of grouper groups/entities and index those for quick lookups - // validate - this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateEntities(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(), false, false); - this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateGroups(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetGroups(), false, false); - this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateMemberships(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(false), false); - - // ######### STEP 27: recalc retrieve data from target - try { - debugMap.put("state", "retrieveIncrementalTargetData"); - long start = System.currentTimeMillis(); - grouperProvisioningLogicIncremental.retrieveIncrementalTargetData(); - long retrieveTargetDataMillis = System.currentTimeMillis()-start; - debugMap.put("retrieveTargetDataMillis", retrieveTargetDataMillis); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveTargetDataIncremental); - } - - // ######### STEP 28: target object attribute manipulation - try { - debugMap.put("state", "targetAttributeManipulation"); - // do not assign defaults to target - // filter groups and manipulate attributes and types - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterGroupFieldsAndAttributes( - this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningGroups(), true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes( - this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningEntities(), true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterMembershipFieldsAndAttributes( - this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningMemberships(), true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesGroups( - this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningGroups()); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities( - this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningEntities()); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesMemberships( - this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningMemberships()); - - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.targetAttributeManipulation); - } - - // ######### STEP 29: matching id target objects - try { - debugMap.put("state", "matchingIdTargetObjects"); - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningGroups()); - for (ProvisioningGroup targetGroup : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningGroups())) { - ProvisioningGroupWrapper provisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupMatchingIdToProvisioningGroupWrapper().get(targetGroup.getMatchingId()); - if (provisioningGroupWrapper != null) { - provisioningGroupWrapper.setTargetProvisioningGroup(targetGroup); - } - } - - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetEntities(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningEntities()); - for (ProvisioningEntity targetEntity : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningEntities())) { - ProvisioningEntityWrapper provisioningEntityWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getEntityMatchingIdToProvisioningEntityWrapper().get(targetEntity.getMatchingId()); - if (provisioningEntityWrapper != null) { - provisioningEntityWrapper.setTargetProvisioningEntity(targetEntity); - } - } - - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetMemberships(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningMemberships()); - for (ProvisioningMembership targetMembership : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningMemberships())) { - ProvisioningMembershipWrapper provisioningMembershipWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getMembershipMatchingIdToProvisioningMembershipWrapper().get(targetMembership.getMatchingId()); - if (provisioningMembershipWrapper != null) { - provisioningMembershipWrapper.setTargetProvisioningMembership(targetMembership); - } - } - - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdTargetObjects); - } - - // ######### STEP 30: create groups / entities - debugMap.put("state", "insertGroups"); - createMissingGroupsFull(); - - debugMap.put("state", "insertEntities"); - createMissingEntitiesFull(); - - // ######### STEP 31: retrieve target group and entity link - try { - debugMap.put("state", "retrieveTargetGroupLink"); - this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().updateGroupLinkFull(); - - debugMap.put("state", "retrieveTargetEntityLink"); - this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().updateEntityLinkFull(); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.linkData); - } - - // ######### STEP 32: translate grouper memberships to target format - try { - debugMap.put("state", "translateGrouperMembershipsToTarget"); - - { - List grouperProvisioningMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperProvisioningMemberships(false); - List grouperTargetMemberships = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetMemberships( - grouperProvisioningMemberships, true); - this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningMemberships(grouperTargetMemberships); - } - - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.translateGrouperMembershipsToTarget); - } - - // ######### STEP 33: based on configs manipulate the defaults, types, etc for grouper target memberships translated attributes and fields - try { - debugMap.put("state", "manipulateGrouperTargetMembershipAttributes"); - - List grouperTargetMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForMemberships(grouperTargetMemberships); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterMembershipFieldsAndAttributes(grouperTargetMemberships, true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesMemberships(grouperTargetMemberships); - - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.manipulateGrouperTargetMembershipsAttributes); - } - - // ######### STEP 34: calculate the matching id of grouper translated membership data - try { - debugMap.put("state", "matchingIdGrouperMemberships"); - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetMemberships( - this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(false)); - - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdGrouperMemberships); - } - - // ######### STEP 35: index matching ID of grouper and target objects - debugMap.put("state", "indexMatchingIdOfGrouperObjects"); - this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdGroups(); - this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdEntities(); - this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdMemberships(); - - - for (ProvisioningMembership targetMembership : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningMemberships())) { - ProvisioningMembershipWrapper provisioningMembershipWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getMembershipMatchingIdToProvisioningMembershipWrapper().get(targetMembership.getMatchingId()); - if (provisioningMembershipWrapper != null) { - provisioningMembershipWrapper.setTargetProvisioningMembership(targetMembership); - } - - } - - - // ######## Retrieve memberships from target that are recalc where the group is not recalc - try { - debugMap.put("state", "retrieveTargetIncrementalMembershipsWithRecalcWhereGroupIsNotRecalc"); - long start = System.currentTimeMillis(); - grouperProvisioningLogicIncremental.retrieveTargetIncrementalMembershipsWithRecalcWhereGroupIsNotRecalc(); - long retrieveTargetDataMillis = System.currentTimeMillis()-start; - debugMap.put("retrieveTargetDataMillis", retrieveTargetDataMillis); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveTargetIncrementalMembershipsWithRecalcWhereGroupIsNotRecalc); - } - - { - // index the memberships -// this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdMemberships(); - - if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectGroups()) { - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsSelectGroupsFull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers()); - } - - if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectEntities()) { - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsSelectEntitiesFull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningEntityWrappers()); - } - - if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectMemberships()) { - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsSelectMembershipsFull( - this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers(), - this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningEntityWrappers(), - this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningMembershipWrappers()); - } - - // validate memberships -// this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateMemberships(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(), false); - - this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateEntities(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(), false, true); - } - - // ######### STEP 36: compare target objects - try { - debugMap.put("state", "compareTargetObjectsIncremental"); - this.grouperProvisioner.retrieveGrouperProvisioningCompare().compareTargetObjects(); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.compareTargetObjects); - } - - this.getGrouperProvisioner().retrieveGrouperProvisioningFailsafe().processFailsafes(); - - // ######### STEP 37: send changes to target - RuntimeException runtimeException = null; - try { - debugMap.put("state", "sendChangesToTarget"); - TargetDaoSendChangesToTargetRequest targetDaoSendChangesToTargetRequest = new TargetDaoSendChangesToTargetRequest(); - targetDaoSendChangesToTargetRequest.setTargetObjectInserts(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts()); - targetDaoSendChangesToTargetRequest.setTargetObjectUpdates(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates()); - targetDaoSendChangesToTargetRequest.setTargetObjectReplaces(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectReplaces()); - targetDaoSendChangesToTargetRequest.setTargetObjectDeletes(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes()); - this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter().sendChangesToTarget(targetDaoSendChangesToTargetRequest); - } catch (RuntimeException e) { - runtimeException = e; - } finally { - try { - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsInserts(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts()); - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsUpdatesFull(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates()); - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsReplaces(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectReplaces()); - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsDeletes(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes()); - } catch (RuntimeException e) { - GrouperUtil.exceptionFinallyInjectOrThrow(runtimeException, e); - } - //TODO this.getGrouperProvisioner().getGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.sendChangesToTarget); - - } - - this.countInsertsUpdatesDeletes(); - - } - - { - Timestamp nowTimestamp = new Timestamp(System.currentTimeMillis()); - - GcGrouperSyncJob gcGrouperSyncJob = this.grouperProvisioner.getGcGrouperSyncJob(); - gcGrouperSyncJob.setErrorMessage(null); - gcGrouperSyncJob.setErrorTimestamp(null); - gcGrouperSyncJob.setLastSyncTimestamp(nowTimestamp); - if (this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().wasWorkDone()) { - gcGrouperSyncJob.setLastTimeWorkWasDone(nowTimestamp); - } - gcGrouperSyncJob.setPercentComplete(100); - - // do this in the right spot, after assigning correct sync info about sync - int objectStoreCount = this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncDao().storeAllObjects(); - this.grouperProvisioner.getProvisioningSyncResult().setSyncObjectStoreCount(objectStoreCount); - - this.grouperProvisioner.getDebugMap().put("syncObjectStoreCount", objectStoreCount); - } - - // TODO flesh this out, resolve subjects, linked cached data, etc, try individually again -// this.getGrouperProvisioner().retrieveTargetDao().resolveErrors(); -// this.getGrouperProvisioner().retrieveTargetDao().sendErrorFixesToTarget(); - -// this.getGrouperProvisioner().getGrouperProvisioningLogicAlgorithm().syncGrouperTranslatedGroupsToTarget(); -// this.getGrouperProvisioner().getGrouperProvisioningLogicAlgorithm().syncGrouperTranslatedMembershipsToTarget(); - - // make sure the sync objects are correct -// new ProvisioningSyncIntegration().assignTarget(this.getGrouperProvisioner().getConfigId()).fullSync(); - -// // step 1 -// debugMap.put("state", "retrieveData"); -// this.gcTableSyncConfiguration.getGcTableSyncSubtype().retrieveData(debugMap, this); -// -// this.gcGrouperSyncLog.setRecordsProcessed(Math.max(this.gcTableSyncOutput.getRowsSelectedFrom(), this.gcTableSyncOutput.getRowsSelectedTo())); - // -// if (this.gcGrouperSyncHeartbeat.isInterrupted()) { -// debugMap.put("interrupted", true); -// debugMap.put("state", "done"); -// gcGrouperSyncLog.setStatus(GcGrouperSyncLogState.INTERRUPTED); -// return; -// } - if (GrouperClientUtils.isBlank(this.getGrouperProvisioner().getGcGrouperSyncLog().getStatus())) { - this.getGrouperProvisioner().getGcGrouperSyncLog().setStatus(GcGrouperSyncLogState.SUCCESS); - } - - } - - } - - // ######### STEP 36: acknowledge messages - this.getGrouperProvisioner().retrieveGrouperProvisioningLogicIncremental().acknowledgeMessagesProcessed(); - - } - - public void storeAllSyncObjects() { - { - // do this in the right spot, after assigning correct sync info about sync - int objectStoreCount = this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncDao().storeAllObjects(); - this.grouperProvisioner.getProvisioningSyncResult().setSyncObjectStoreCount(objectStoreCount); - - this.grouperProvisioner.getDebugMap().put("syncObjectStoreCount", objectStoreCount); - } - } - - public void runFullSyncFromIncremental() { - - // end out this provisioner - storeAllSyncObjects(); - this.getGrouperProvisioner().provisionFinallyBlock(); - - // run a full sync - GrouperProvisioner grouperProvisionerFullSync = GrouperProvisioner.retrieveProvisioner(this.getGrouperProvisioner().getConfigId()); - grouperProvisionerFullSync.setGcGrouperSyncHeartbeat(this.getGrouperProvisioner().getGcGrouperSyncHeartbeat()); - Map newDebugMap = new LinkedHashMap(); - newDebugMap.put("incrementalDebugMap", GrouperUtil.mapToString(this.getGrouperProvisioner().getDebugMap()) + "\n\n"); - - grouperProvisionerFullSync.setDebugMap(newDebugMap); - grouperProvisionerFullSync.setGrouperProvisioningOutput(this.getGrouperProvisioner().retrieveGrouperProvisioningOutput()); - grouperProvisionerFullSync.provision(GrouperProvisioningType.fullProvisionFull); - } - - public void createMissingGroupsFull() { - // first lets see if we should even be doing this - if (!GrouperUtil.booleanValue(this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isInsertGroups(), false)) { - return; - } - - //do we have missing groups? - List missingGroups = new ArrayList(); - List missingGroupWrappers = new ArrayList(); - - for (ProvisioningGroupWrapper provisioningGroupWrapper : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers())) { - - ProvisioningGroup provisioningGroup = provisioningGroupWrapper.getGrouperProvisioningGroup(); - - if (provisioningGroup == null || !provisioningGroupWrapper.isRecalc()) { - continue; - } - - // shouldnt be null at this point - GcGrouperSyncGroup gcGrouperSyncGroup = provisioningGroupWrapper.getGcGrouperSyncGroup(); - - if (!gcGrouperSyncGroup.isProvisionable()) { - continue; - } - - ProvisioningGroup targetGroup = provisioningGroupWrapper.getTargetProvisioningGroup(); - - if (targetGroup != null) { - continue; - } - - missingGroups.add(provisioningGroup); - missingGroupWrappers.add(provisioningGroupWrapper); - } - - if (GrouperUtil.length(missingGroups) == 0) { - return; - } - - // how many do we have - this.grouperProvisioner.getDebugMap().put("missingGroupsForCreate", GrouperUtil.length(missingGroups)); - - this.grouperProvisioner.retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjectsMissing().setProvisioningGroups(missingGroups); - - // log this - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingGroupsForCreate); - - List grouperTargetGroupsToInsert = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetGroups(missingGroups, false, true); - - if (GrouperUtil.length(grouperTargetGroupsToInsert) == 0) { - this.grouperProvisioner.getDebugMap().put("groupTranslationEndedInNoGroupsOnInsert", true); - return; - } - - translateAndManipulateMembershipsForGroupsEntitiesCreate(); - - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForGroups(grouperTargetGroupsToInsert, null); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterGroupFieldsAndAttributes(grouperTargetGroupsToInsert, false, true, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesGroups(grouperTargetGroupsToInsert); - - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups(grouperTargetGroupsToInsert); - this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdGroups(); - - this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getGrouperTargetObjectsMissing().setProvisioningGroups(grouperTargetGroupsToInsert); - - // validate that groups have members - this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateGroupsHaveMembers(grouperTargetGroupsToInsert, true); - - // validate - this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateGroups(grouperTargetGroupsToInsert, true, false); - - if (GrouperUtil.length(grouperTargetGroupsToInsert) == 0) { - this.grouperProvisioner.getDebugMap().put("groupTranslationEndedInNoGroupsOnInsert", true); - return; - } - - // add object change entries - this.grouperProvisioner.retrieveGrouperProvisioningCompare().addInternalObjectChangeForGroupsToInsert(grouperTargetGroupsToInsert); - - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingGrouperTargetGroupsForCreate); - - //lets create these - RuntimeException runtimeException = null; - try { - this.grouperProvisioner.retrieveGrouperProvisioningTargetDaoAdapter().insertGroups(new TargetDaoInsertGroupsRequest(grouperTargetGroupsToInsert)); - } catch (RuntimeException re) { - runtimeException = re; - } finally { - try { - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsInsertGroups(grouperTargetGroupsToInsert, false); - - } catch (RuntimeException e) { - GrouperUtil.exceptionFinallyInjectOrThrow(runtimeException, e); - } - } - - List targetGroups = null; - if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectGroups()) { - //retrieve so we have a copy - TargetDaoRetrieveGroupsResponse targetDaoRetrieveGroupsResponse = - this.grouperProvisioner.retrieveGrouperProvisioningTargetDaoAdapter().retrieveGroups(new TargetDaoRetrieveGroupsRequest(grouperTargetGroupsToInsert, true)); - - targetGroups = GrouperUtil.nonNull(targetDaoRetrieveGroupsResponse == null ? null : targetDaoRetrieveGroupsResponse.getTargetGroups()); - - if (GrouperUtil.length(grouperTargetGroupsToInsert) != GrouperUtil.length(targetGroups)) { - // maybe this should be an exception??? - throw new RuntimeException("Searched for " + GrouperUtil.length(grouperTargetGroupsToInsert) + " but retrieved " + GrouperUtil.length(targetGroups) + " maybe a config is off?"); - } - - registerRetrievedGroups(grouperTargetGroupsToInsert, targetGroups); - - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterGroupFieldsAndAttributes(targetGroups, true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesGroups(targetGroups); - - // index - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups(targetGroups); - this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdGroups(); - - this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjectsMissingCreated().setProvisioningGroups(targetGroups); - - } - - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingTargetGroupsCreated); - - if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectGroups()) { - Map matchingIdToProvisioningGroupWrapper = grouperProvisioner.retrieveGrouperProvisioningDataIndex().getGroupMatchingIdToProvisioningGroupWrapper(); - - // match these up with retrieved groups - // set these in the wrapper so they are linked with grouper group - for (ProvisioningGroup targetGroup : GrouperUtil.nonNull(targetGroups)) { - - // look up the grouper group that looked this up - ProvisioningGroupWrapper provisioningGroupWrapper = matchingIdToProvisioningGroupWrapper.get(targetGroup.getMatchingId()); - - // not sure why it wouldnt match or exist... - provisioningGroupWrapper.setTargetProvisioningGroup(targetGroup); - - // this is already created! :) - provisioningGroupWrapper.setCreate(false); - } - } - - } - - //TODO duplicate method in the translator. Try to merge to have only one copy. - public void translateAndManipulateMembershipsForGroupsEntitiesCreate() { - if (!this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().isCreateGroupsAndEntitiesBeforeTranslatingMemberships()) { - - Map debugMap = this.getGrouperProvisioner().getDebugMap(); - - try { - debugMap.put("state", "translateGrouperMembershipsToTarget"); - { - List grouperProvisioningMemberships = new ArrayList(this.getGrouperProvisioner(). - retrieveGrouperProvisioningData().retrieveGrouperProvisioningMemberships(true)); - - List grouperTargetMemberships = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetMemberships( - grouperProvisioningMemberships, false); - this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningMemberships(grouperTargetMemberships); - } - - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.translateGrouperMembershipsToTarget); - } - - try { - debugMap.put("state", "manipulateGrouperMembershipTargetAttributes"); - List grouperTargetMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(true); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForMemberships(grouperTargetMemberships); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterMembershipFieldsAndAttributes(grouperTargetMemberships, true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesMemberships(grouperTargetMemberships); - - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.manipulateGrouperTargetMembershipsAttributes); - } - - try { - debugMap.put("state", "matchingIdGrouperMemberships"); - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetMemberships(this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(true)); - } finally { - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdGrouperMemberships); - } - - // index the memberships - this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdMemberships(); - - } - } - - /** - * - * @param grouperTargetGroupsToInsert - * @param targetProvisioningGroups - */ - public void registerRetrievedGroups( - List grouperTargetGroups, - List targetProvisioningGroups) { - - GrouperProvisioningConfigurationAttribute searchAttribute = null; - - for (Collection grouperProvisioningConfigurationAttributes : - new Collection[] { - this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values(), - this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values()}) { - - // look for required fields - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - grouperProvisioningConfigurationAttributes) { - - if (grouperProvisioningConfigurationAttribute.isSearchAttribute()) { - searchAttribute = grouperProvisioningConfigurationAttribute; - break; - } - - //default is id I guess - if ("id".equals(grouperProvisioningConfigurationAttribute.getName())) { - searchAttribute = grouperProvisioningConfigurationAttribute; - } - } - } - - if (searchAttribute == null) { - throw new RuntimeException("Identify a group search attribute!"); - } - - Map searchAttributeValueToGrouperTargetGroup = new HashMap(); - - // index by search attribute - for (ProvisioningGroup grouperTargetGroup : GrouperUtil.nonNull(grouperTargetGroups)) { - Object searchAttributeValue = grouperTargetGroup.retrieveAttributeValue(searchAttribute); - if (searchAttributeValue != null) { - searchAttributeValueToGrouperTargetGroup.put(searchAttributeValue, grouperTargetGroup); - } - } - - for (ProvisioningGroup targetProvisioningGroup : GrouperUtil.nonNull(targetProvisioningGroups)) { - Object searchAttributeValue = targetProvisioningGroup.retrieveAttributeValue(searchAttribute); - if (searchAttributeValue != null) { - ProvisioningGroup grouperTargetGroup = searchAttributeValueToGrouperTargetGroup.get(searchAttributeValue); - if (grouperTargetGroup != null) { - ProvisioningGroupWrapper provisioningGroupWrapper = grouperTargetGroup.getProvisioningGroupWrapper(); - if (provisioningGroupWrapper != null) { - targetProvisioningGroup.setProvisioningGroupWrapper(provisioningGroupWrapper); - provisioningGroupWrapper.setTargetProvisioningGroup(targetProvisioningGroup); - } - } - } - } - } - - /** - * - * @param grouperTargetEntitiesToInsert - * @param targetProvisioningEntities - */ - public void registerRetrievedEntities( - List grouperTargetEntities, - List targetProvisioningEntities) { - - GrouperProvisioningConfigurationAttribute searchAttribute = null; - - for (Collection grouperProvisioningConfigurationAttributes : - new Collection[] { - this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values(), - this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values()}) { - - // look for required fields - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : - grouperProvisioningConfigurationAttributes) { - - if (grouperProvisioningConfigurationAttribute.isSearchAttribute()) { - searchAttribute = grouperProvisioningConfigurationAttribute; - break; - } - - //default is id I guess - if ("id".equals(grouperProvisioningConfigurationAttribute.getName())) { - searchAttribute = grouperProvisioningConfigurationAttribute; - } - } - } - - if (searchAttribute == null) { - throw new RuntimeException("Identify an entity search attribute!"); - } - - Map searchAttributeValueToGrouperTargetEntity = new HashMap(); - - // index by search attribute - for (ProvisioningEntity grouperTargetEntity : GrouperUtil.nonNull(grouperTargetEntities)) { - Object searchAttributeValue = grouperTargetEntity.retrieveAttributeValue(searchAttribute); - if (searchAttributeValue != null) { - searchAttributeValueToGrouperTargetEntity.put(searchAttributeValue, grouperTargetEntity); - } - } - - for (ProvisioningEntity targetProvisioningEntity : GrouperUtil.nonNull(targetProvisioningEntities)) { - Object searchAttributeValue = targetProvisioningEntity.retrieveAttributeValue(searchAttribute); - if (searchAttributeValue != null) { - ProvisioningEntity grouperTargetEntity = searchAttributeValueToGrouperTargetEntity.get(searchAttributeValue); - if (grouperTargetEntity != null) { - ProvisioningEntityWrapper provisioningEntityWrapper = grouperTargetEntity.getProvisioningEntityWrapper(); - if (provisioningEntityWrapper != null) { - targetProvisioningEntity.setProvisioningEntityWrapper(provisioningEntityWrapper); - provisioningEntityWrapper.setTargetProvisioningEntity(targetProvisioningEntity); - } - } - } - } - } - - - public void createMissingEntitiesFull() { - // first lets see if we should even be doing this - if (!GrouperUtil.booleanValue(this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isInsertEntities(), false)) { - return; - } - - - //do we have missing entities? - List missingEntities = new ArrayList(); - List missingEntityWrappers = new ArrayList(); - for (ProvisioningEntityWrapper provisioningEntityWrapper : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningEntityWrappers())) { - - ProvisioningEntity provisioningEntity = provisioningEntityWrapper.getGrouperProvisioningEntity(); - - if (provisioningEntity == null || !provisioningEntityWrapper.isRecalc() || provisioningEntityWrapper.isDelete()) { - continue; - } - - // shouldnt be null at this point - GcGrouperSyncMember gcGrouperSyncMember = provisioningEntityWrapper.getGcGrouperSyncMember(); - - if (!gcGrouperSyncMember.isProvisionable()) { - continue; - } - ProvisioningEntity targetEntity = provisioningEntityWrapper.getTargetProvisioningEntity(); - - if (targetEntity != null) { - continue; - } - - missingEntities.add(provisioningEntity); - missingEntityWrappers.add(provisioningEntityWrapper); - } - if (GrouperUtil.length(missingEntities) == 0) { - return; - } - - // how many do we have - this.grouperProvisioner.getDebugMap().put("missingEntitiesForCreate", GrouperUtil.length(missingEntities)); - - this.grouperProvisioner.retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjectsMissing().setProvisioningEntities(missingEntities); - // log this - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingEntitiesForCreate); - - // translate - List grouperTargetEntitiesToInsert = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetEntities(missingEntities, false, true); - - if (GrouperUtil.length(grouperTargetEntitiesToInsert) == 0) { - this.grouperProvisioner.getDebugMap().put("groupTranslationEndedInNoEntitiesOnInsert", true); - return; - } - - - translateAndManipulateMembershipsForGroupsEntitiesCreate(); - - - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForEntities(grouperTargetEntitiesToInsert, null); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes(grouperTargetEntitiesToInsert, false, true, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities(grouperTargetEntitiesToInsert); - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetEntities(grouperTargetEntitiesToInsert); - this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdEntities(); - this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getGrouperTargetObjectsMissing().setProvisioningEntities(grouperTargetEntitiesToInsert); - // validate - this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateEntities(grouperTargetEntitiesToInsert, true, null); - // add object change entries - this.grouperProvisioner.retrieveGrouperProvisioningCompare().addInternalObjectChangeForEntitiesToInsert(grouperTargetEntitiesToInsert); - - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingGrouperTargetEntitiesForCreate); - //lets create these - RuntimeException runtimeException = null; - try { - this.grouperProvisioner.retrieveGrouperProvisioningTargetDaoAdapter().insertEntities(new TargetDaoInsertEntitiesRequest(grouperTargetEntitiesToInsert)); - } catch (RuntimeException re) { - runtimeException = re; - } finally { - try { - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsInsertEntities(grouperTargetEntitiesToInsert, false); - - } catch (RuntimeException e) { - GrouperUtil.exceptionFinallyInjectOrThrow(runtimeException, e); - } - } - - List targetEntities = null; - if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectEntities()) { - //retrieve so we have a copy - TargetDaoRetrieveEntitiesResponse targetDaoRetrieveEntitiesResponse = - this.grouperProvisioner.retrieveGrouperProvisioningTargetDaoAdapter().retrieveEntities(new TargetDaoRetrieveEntitiesRequest(grouperTargetEntitiesToInsert, false)); - - targetEntities = GrouperUtil.nonNull(targetDaoRetrieveEntitiesResponse == null ? null : targetDaoRetrieveEntitiesResponse.getTargetEntities()); - - if (GrouperUtil.length(grouperTargetEntitiesToInsert) != GrouperUtil.length(targetEntities)) { - // maybe this should be an exception??? - throw new RuntimeException("Searched for " + GrouperUtil.length(grouperTargetEntitiesToInsert) + " but retrieved " + GrouperUtil.length(targetEntities) + " maybe a config is off?"); - } - - registerRetrievedEntities(grouperTargetEntitiesToInsert, targetEntities); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes(targetEntities, true, false, false); - this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities(targetEntities); - // index - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetEntities(targetEntities); - this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdEntities(); - this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjectsMissingCreated().setProvisioningEntities(targetEntities); - } - - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingTargetEntitiesCreated); - - if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectEntities()) { - Map matchingIdToProvisioningEntityWrapper = grouperProvisioner.retrieveGrouperProvisioningDataIndex().getEntityMatchingIdToProvisioningEntityWrapper(); - - // match these up with retrieved entities - // set these in the wrapper so they are linked with grouper entity - for (ProvisioningEntity targetEntity : GrouperUtil.nonNull(targetEntities)) { - - // look up the grouper group that looked this up - ProvisioningEntityWrapper provisioningEntityWrapper = matchingIdToProvisioningEntityWrapper.get(targetEntity.getMatchingId()); - - // not sure why it wouldnt match or exist... - provisioningEntityWrapper.setTargetProvisioningEntity(targetEntity); - // this is already created! :) - provisioningEntityWrapper.setCreate(false); - } - } - - } - - /** - * retrieve all data from both sides, grouper and target, do this in a thread - */ - public void retrieveAllData() { - - final RuntimeException[] RUNTIME_EXCEPTION = new RuntimeException[1]; - - Thread targetQueryThread = new Thread(new Runnable() { - - @Override - public void run() { - - try { - TargetDaoRetrieveAllDataResponse targetDaoRetrieveAllDataResponse - = GrouperProvisioningLogic.this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter() - .retrieveAllData(new TargetDaoRetrieveAllDataRequest()); - // retrieve all the target data and put in GrouperProvisioningDataTarget - GrouperProvisioningLists targetData = targetDaoRetrieveAllDataResponse.getTargetData(); - GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningDataTarget() - .setTargetProvisioningObjects(targetData); - - // get the total count of what is in the target - int totalTargetCount = 0; - if (targetData != null) { - - GrouperProvisioningLogic.this.grouperProvisioner.getDebugMap().put("originalTargetGroupCount", GrouperUtil.length(targetData.getProvisioningGroups())); - GrouperProvisioningLogic.this.grouperProvisioner.getDebugMap().put("originalTargetEntityCount", GrouperUtil.length(targetData.getProvisioningEntities())); - - totalTargetCount += GrouperUtil.length(targetData.getProvisioningEntities()) - + GrouperUtil.length(targetData.getProvisioningGroups()); - - int originalTargetMembershipCount = GrouperUtil.length(targetData.getProvisioningMemberships()); - - String membershipAttribute = GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getAttributeNameForMemberships(); - if (!StringUtils.isBlank(membershipAttribute)) { - if (GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() - == GrouperProvisioningBehaviorMembershipType.groupAttributes) { - - for (ProvisioningGroup provisioningGroup : GrouperUtil.nonNull(targetData.getProvisioningGroups())) { - originalTargetMembershipCount += GrouperUtil.length(provisioningGroup.retrieveAttributeValueSet(membershipAttribute)); - } - } - if (GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() - == GrouperProvisioningBehaviorMembershipType.entityAttributes) { - - for (ProvisioningEntity provisioningEntity : GrouperUtil.nonNull(targetData.getProvisioningEntities())) { - originalTargetMembershipCount += GrouperUtil.length(provisioningEntity.retrieveAttributeValueSet(membershipAttribute)); - } - } - } - totalTargetCount += originalTargetMembershipCount; - GrouperProvisioningLogic.this.grouperProvisioner.getDebugMap().put("originalTargetMembershipCount", originalTargetMembershipCount); - } - - GrouperProvisioningLogic.this.grouperProvisioner.getDebugMap().put("originalTargetTotalCount", totalTargetCount); - - - } catch (RuntimeException re) { - LOG.error("error querying target: " + GrouperProvisioningLogic.this.getGrouperProvisioner().getConfigId(), re); - RUNTIME_EXCEPTION[0] = re; - } - - } - }); - - targetQueryThread.start(); - - retrieveGrouperDataFull(); - - enhanceEntityAttributesWithSqlResolver(true); - - enhanceEntityAttributesWithLdapResolver(); - - GrouperClientUtils.join(targetQueryThread); - if (RUNTIME_EXCEPTION[0] != null) { - throw RUNTIME_EXCEPTION[0]; - } - - retrieveAllTargetAndGrouperDataPost(); - - processTargetWrappers(); - - } - - public void enhanceEntityAttributesWithSqlResolver(boolean isFullSync) { - - GrouperProvisioningConfiguration provisioningConfiguration = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration(); - - if (!provisioningConfiguration.isResolveAttributesWithSql()) { - return; - } - - String dbConnectionName = null; - String grouperAttributeThatMatchesRow = null; - String subjectSearchMatchingColumn = null; - String subjectSourceIdColumn = null; - String tableOrViewName = null; - String expression = null; - String commaSeparatedColumns = null; - String lastUpdatedColumn = null; - String lastUpdatedColumnType = null; - - String globalSqlResolver = provisioningConfiguration.getGlobalSqlResolver(); - - if (StringUtils.isNotBlank(globalSqlResolver)) { - - boolean isEnabled = GrouperConfig.retrieveConfig().propertyValueBoolean("entityAttributeResolver."+globalSqlResolver+".enabled", true); - - if (!isEnabled) { - return; - } - - dbConnectionName = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalSqlResolver+".sqlConfigId"); - - grouperAttributeThatMatchesRow = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalSqlResolver+".grouperAttributeThatMatchesRow"); - - subjectSearchMatchingColumn = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalSqlResolver+".subjectSearchMatchingColumn"); - - tableOrViewName = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalSqlResolver+".tableOrViewName"); - - commaSeparatedColumns = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalSqlResolver+".columnNames"); - - subjectSourceIdColumn = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalSqlResolver+".subjectSourceIdColumn"); - - lastUpdatedColumn = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalSqlResolver+".lastUpdatedColumn"); - - lastUpdatedColumnType = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalSqlResolver+".lastUpdatedType"); - - } else { - - dbConnectionName = provisioningConfiguration.getEntityAttributesSqlExternalSystem(); - - grouperAttributeThatMatchesRow = provisioningConfiguration.getEntityAttributesSqlMappingEntityAttribute(); - - subjectSearchMatchingColumn = provisioningConfiguration.getEntityAttributesSubjectSearchMatchingColumn(); - - tableOrViewName = provisioningConfiguration.getEntityAttributesTableViewName(); - - commaSeparatedColumns = provisioningConfiguration.getEntityAttributesColumnNames(); - - subjectSourceIdColumn = provisioningConfiguration.getEntityAttributesSubjectSourceIdColumn(); - - expression = provisioningConfiguration.getEntityAttributesSqlMappingExpression(); - - lastUpdatedColumn = provisioningConfiguration.getEntityAttributesLastUpdatedColumn(); - - lastUpdatedColumnType = provisioningConfiguration.getEntityAttributesLastUpdatedType(); - - } - - Set columnsWhichAreAttributes = GrouperUtil.splitTrimToSet(commaSeparatedColumns, ","); - - Set columnNamesToFetch = GrouperUtil.splitTrimToSet(commaSeparatedColumns, ","); - - if (StringUtils.isNotBlank(lastUpdatedColumn) && !columnNamesToFetch.contains(lastUpdatedColumn.trim())) { - columnNamesToFetch.add(lastUpdatedColumn.trim()); - } - - if (!columnNamesToFetch.contains(subjectSearchMatchingColumn.trim())) { - columnNamesToFetch.add(subjectSearchMatchingColumn.trim()); - } - - String commaSeparatedColNames = GrouperUtil.setToString(columnNamesToFetch); - - boolean selectAllSqlOnFull = provisioningConfiguration.isSelectAllSqlOnFull(); - - GrouperProvisioningLists grouperProvisioningObjects = - this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects(); - - List provisioningEntities = grouperProvisioningObjects.getProvisioningEntities(); - - StringBuilder sqlInitial = new StringBuilder("select "); - sqlInitial.append(commaSeparatedColNames); - sqlInitial.append(" from "); - sqlInitial.append(tableOrViewName); - - List attributesFromTable = new ArrayList(); - - if ( (isFullSync && !selectAllSqlOnFull) || !isFullSync) { - if (provisioningEntities.size() == 0) { - return; - } - - int numberOfBatches = GrouperUtil.batchNumberOfBatches(provisioningEntities.size(), 900); - - Map elVariableMap = new HashMap(); - - for (int i = 0; i < numberOfBatches; i++) { - - List currentBatchProvisioningEntities = GrouperUtil.batchList(provisioningEntities, 900, i); - StringBuilder sql = new StringBuilder(sqlInitial); - - sql.append(" where "+ subjectSearchMatchingColumn + " in ( "); - - GcDbAccess gcDbAccess = new GcDbAccess().connectionName(dbConnectionName); - - for (int j=0; j0) { - sql.append(","); - } - sql.append("?"); - } - sql.append(" ) "); - attributesFromTable.addAll(gcDbAccess.sql(sql.toString()).selectList(Object[].class)); - - } - } else { - attributesFromTable.addAll(new GcDbAccess().connectionName(dbConnectionName).sql(sqlInitial.toString()).selectList(Object[].class)); - } - - String[] colNamesFromAttributesTable = GrouperUtil.splitTrim(commaSeparatedColNames, ","); - - Map subjectSearchMatchingColumnToAttributes = new HashMap(); - - int indexOfSubjectSearchMatchingColumn = GrouperUtil.indexOf(colNamesFromAttributesTable, subjectSearchMatchingColumn); - - for (Object[] oneRowOfAttributes: attributesFromTable) { - Object subjectSearchMatchingValue = oneRowOfAttributes[indexOfSubjectSearchMatchingColumn]; - if (subjectSearchMatchingValue != null) { - - String subjectSearchMatchingValueString = GrouperUtil.stringValue(subjectSearchMatchingValue); - - MultiKey identifier = null; - if (StringUtils.isNotBlank(subjectSourceIdColumn)) { - identifier = new MultiKey(subjectSearchMatchingValueString, subjectSourceIdColumn); - } else { - identifier = new MultiKey(new String[] {subjectSearchMatchingValueString}); - } - - subjectSearchMatchingColumnToAttributes.put(identifier, oneRowOfAttributes); - } - } - - /** - * subjectSearchMatchingColumnToAttributes looks like - * test.subject.0 -> [school0, description0,....] - */ - - Map elVariableMap = new HashMap(); - - for (ProvisioningEntity provisioningEntity: provisioningEntities) { - - String subjectMatchingIdentifier = null; - - if (StringUtils.isNotBlank(expression)) { - elVariableMap.clear(); - elVariableMap.put("grouperProvisioningEntity", provisioningEntity); - Object object = this.getGrouperProvisioner().retrieveGrouperProvisioningTranslator().runScript(expression, elVariableMap); - subjectMatchingIdentifier = GrouperUtil.stringValue(object); - } else if (StringUtils.equals(grouperAttributeThatMatchesRow, "subjectId")) { - subjectMatchingIdentifier = provisioningEntity.getSubjectId(); - } else if (StringUtils.equals(grouperAttributeThatMatchesRow, "subjectIdentifier0")) { - subjectMatchingIdentifier = (String)provisioningEntity.retrieveAttributeValueString("subjectIdentifier0"); - } else { - throw new RuntimeException("invalid grouperAttributeThatMatchesRow: "+grouperAttributeThatMatchesRow + " expected 'subjectId' or 'subjectIdentifier0'"); - } - - MultiKey identifier = null; - if (StringUtils.isNotBlank(subjectSourceIdColumn)) { - String subjectSourceIdFromProvisioningEntity = provisioningEntity.retrieveAttributeValueString("subjectSourceId"); - identifier = new MultiKey(subjectMatchingIdentifier, subjectSourceIdFromProvisioningEntity); - } else { - identifier = new MultiKey(new String[] {subjectMatchingIdentifier}); - } - - Object[] attributeValues = subjectSearchMatchingColumnToAttributes.get(identifier); - if (attributeValues != null) { - int i = 0; - for (String attributeName: colNamesFromAttributesTable) { - - if (columnsWhichAreAttributes.contains(attributeName)) { - - provisioningEntity.assignAttributeValue("entityAttributeResolverSql__"+attributeName.toLowerCase(), attributeValues[i]); - } - - i++; - - } - } - - } - - } - - public void enhanceEntityAttributesWithLdapResolver() { - - GrouperProvisioningConfiguration provisioningConfiguration = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration(); - - if (!provisioningConfiguration.isResolveAttributesWithLdap()) { - return; - } - - GrouperProvisioningLists grouperProvisioningObjects = this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects(); - - List provisioningEntities = grouperProvisioningObjects.getProvisioningEntities(); - - String globalLdapResolver = provisioningConfiguration.getGlobalLdapResolver(); - - String ldapConfigId = null; - String baseDn = null; - String searchScope = null; - String ldapAttributes = null; - String subjectSearchMatchingAttribute = null; - String subjectSourceId = null; - String grouperAttributeThatMatchesRecord = null; - String filterPart = null; - String lastUpdatedAttribute = null; - String multiValuedLdapAttributes = null; - String expression = null; - String lastUpdatedAttributeFormat = null; - boolean filterAllLdapOnFull = true; - - if (StringUtils.isNotBlank(globalLdapResolver)) { - - boolean isEnabled = GrouperConfig.retrieveConfig().propertyValueBoolean("entityAttributeResolver."+globalLdapResolver+".enabled", true); - - if (!isEnabled) { - return; - } - - ldapConfigId = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalLdapResolver+".ldapConfigId"); - baseDn = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalLdapResolver+".baseDn"); - subjectSourceId = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalLdapResolver+".subjectSourceId"); - searchScope = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalLdapResolver+".searchScope"); - ldapAttributes = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalLdapResolver+".ldapAttributes"); - subjectSearchMatchingAttribute = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalLdapResolver+".subjectSearchMatchingAttribute"); - grouperAttributeThatMatchesRecord = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalLdapResolver+".grouperAttributeThatMatchesRecord"); - filterPart = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalLdapResolver+".filterPart"); - lastUpdatedAttribute = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalLdapResolver+".lastUpdatedAttribute"); - lastUpdatedAttributeFormat = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalLdapResolver+".ldapLastUpdatedFormat"); - multiValuedLdapAttributes = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalLdapResolver+".multiValuedLdapAttributes"); - - } else { - - ldapConfigId = provisioningConfiguration.getEntityAttributesLdapExternalSystem(); - baseDn = provisioningConfiguration.getEntityAttributesLdapBaseDn(); - subjectSourceId = provisioningConfiguration.getEntityAttributesLdapSubjectSource(); - searchScope = provisioningConfiguration.getEntityAttributesLdapSearchScope(); - ldapAttributes = provisioningConfiguration.getEntityAttributesLdapAttributes(); - subjectSearchMatchingAttribute = provisioningConfiguration.getEntityAttributesLdapMatchingSearchAttribute(); - grouperAttributeThatMatchesRecord = provisioningConfiguration.getEntityAttributesLdapMappingEntityAttribute(); - filterPart = provisioningConfiguration.getEntityAttributesLdapFilterPart(); - lastUpdatedAttribute = provisioningConfiguration.getEntityAttributesLdapLastUpdatedAttribute(); - lastUpdatedAttributeFormat = provisioningConfiguration.getEntityAttributesLdapLastUpdatedAttributeFormat(); - expression = provisioningConfiguration.getEntityAttributesLdapMatchingExpression(); - } - - List ldapEntries = new ArrayList(); - - filterAllLdapOnFull = provisioningConfiguration.isFilterAllLDAPOnFull(); - - Set ldapAttributesSet = GrouperUtil.splitTrimToSet(ldapAttributes, ","); - - Set multiValuedAttributesSet = GrouperUtil.nonNull(GrouperUtil.splitTrimToSet(multiValuedLdapAttributes, ",")); - - if (StringUtils.isNotBlank(multiValuedLdapAttributes)) { - ldapAttributesSet.addAll(multiValuedAttributesSet); - } - - if (StringUtils.isNotBlank(subjectSearchMatchingAttribute)) { - ldapAttributesSet.add(subjectSearchMatchingAttribute); - } - - String[] ldapAttributesArray = GrouperUtil.toArray(ldapAttributesSet, String.class); - - LdapSearchScope ldapSearchScope = LdapSearchScope.valueOfIgnoreCase(searchScope, true); - - if (!filterAllLdapOnFull) { - - if (provisioningEntities.size() == 0) { - return; - } - - int numberOfBatches = GrouperUtil.batchNumberOfBatches(provisioningEntities.size(), 900); - - Map elVariableMap = new HashMap(); - - for (int i = 0; i < numberOfBatches; i++) { - - List currentBatchProvisioningEntities = GrouperUtil.batchList(provisioningEntities, 900, i); - - String filter = null; - if (StringUtils.isNotBlank(filterPart)) { - filter = "(&"; - filterPart = filterPart.trim(); - if (filterPart.startsWith("(")) { - filter += filterPart; - } else { - filter += "(" + filterPart + ")"; - } - } else { - filter = "(|"; - } - - - for (int j=0; j identifierToLdapEntry = new HashMap(); - - for (LdapEntry ldapEntry: GrouperUtil.nonNull(ldapEntries)) { - - LdapAttribute attribute = ldapEntry.getAttribute(subjectSearchMatchingAttribute); - if (attribute != null) { - - Collection stringValues = attribute.getStringValues(); - if (GrouperUtil.length(stringValues) == 1) { - - MultiKey identifier = null; - if (StringUtils.isNotBlank(subjectSourceId)) { - identifier = new MultiKey(stringValues.iterator().next(), subjectSourceId); - } else { - identifier = new MultiKey(new String[] {stringValues.iterator().next()}); - } - identifierToLdapEntry.put(identifier, ldapEntry); - } - } - } - - Map elVariableMap = new HashMap(); - - for (ProvisioningEntity provisioningEntity: provisioningEntities) { - - String subjectMatchingIdentifier = null; - if (StringUtils.isNotBlank(expression)) { - elVariableMap.clear(); - elVariableMap.put("grouperProvisioningEntity", provisioningEntity); - Object object = this.getGrouperProvisioner().retrieveGrouperProvisioningTranslator().runScript(expression, elVariableMap); - subjectMatchingIdentifier = GrouperUtil.stringValue(object); - } else if (StringUtils.equals(grouperAttributeThatMatchesRecord, "subjectId")) { - subjectMatchingIdentifier = provisioningEntity.getSubjectId(); - } - else if (StringUtils.equals(grouperAttributeThatMatchesRecord, "subjectIdentifier0")) { - subjectMatchingIdentifier = (String)provisioningEntity.retrieveAttributeValueString("subjectIdentifier0"); - } else { - throw new RuntimeException("invalid grouperAttributeThatMatchesRecord: "+grouperAttributeThatMatchesRecord + " expected 'subjectId' or 'subjectIdentifier0'"); - } - - MultiKey identifier = null; - if (StringUtils.isNotBlank(subjectSourceId)) { - String subjectSourceIdFromProvisioningEntity = provisioningEntity.retrieveAttributeValueString("subjectSourceId"); - identifier = new MultiKey(subjectMatchingIdentifier, subjectSourceIdFromProvisioningEntity); - } else { - identifier = new MultiKey(new String[] {subjectMatchingIdentifier}); - } - - LdapEntry ldapEntry = identifierToLdapEntry.get(identifier); - if (ldapEntry != null) { - - for (String ldapAttributeName: ldapAttributesArray) { - - if (StringUtils.equals(ldapAttributeName, "lastUpdatedAttribute")) { - continue; - } - - LdapAttribute attribute = ldapEntry.getAttribute(ldapAttributeName); - if (attribute != null) { - - if (multiValuedAttributesSet.contains(attribute.getName())) { - - for ( String attributeValue: GrouperUtil.nonNull(attribute.getStringValues())) { - provisioningEntity.addAttributeValue("entityAttributeResolverLdap__"+attribute.getName().toLowerCase(), attributeValue); - } - - } else { - - if (GrouperUtil.length(attribute.getStringValues()) == 0) { - continue; - } - - if (GrouperUtil.length(attribute.getStringValues()) == 1) { - provisioningEntity.assignAttributeValue("entityAttributeResolverLdap__"+attribute.getName().toLowerCase(), attribute.getStringValues().iterator().next()); - } else { - - String concatenatedAttributeValues = GrouperUtil.join(attribute.getStringValues().iterator(), ","); - provisioningEntity.assignAttributeValue("entityAttributeResolverLdap__"+attribute.getName().toLowerCase(), concatenatedAttributeValues); - - } - - - } - - } - } - - } - - } - - } - - /** - * override this method to do some logic after all grouper and target data is retrieved (e.g. if there are DN overrides) - */ - public void retrieveAllTargetAndGrouperDataPost() { - - - } - - /** - * take target data and add wrapper and add to data store - */ - public void processTargetWrappers() { - - Set provisioningGroupWrappers = this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningGroupWrappers(); - - // add wrappers for all groups - for (ProvisioningGroup targetProvisioningGroup : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningGroups())) { - ProvisioningGroupWrapper provisioningGroupWrapper = new ProvisioningGroupWrapper(); - provisioningGroupWrapper.setGrouperProvisioner(this.grouperProvisioner); - provisioningGroupWrappers.add(provisioningGroupWrapper); - - provisioningGroupWrapper.setTargetProvisioningGroup(targetProvisioningGroup); - } - - - Set provisioningEntityWrappers = this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningEntityWrappers(); - - // add wrappers for all groups - for (ProvisioningEntity targetProvisioningEntity : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningEntities())) { - ProvisioningEntityWrapper provisioningEntityWrapper = new ProvisioningEntityWrapper(); - provisioningEntityWrapper.setGrouperProvisioner(this.grouperProvisioner); - provisioningEntityWrappers.add(provisioningEntityWrapper); - - provisioningEntityWrapper.setTargetProvisioningEntity(targetProvisioningEntity); - } - - Set provisioningMembershipWrappers = this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningMembershipWrappers(); - - // add wrappers for all groups - for (ProvisioningMembership targetProvisioningMembership : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningMemberships())) { - ProvisioningMembershipWrapper provisioningMembershipWrapper = new ProvisioningMembershipWrapper(); - provisioningMembershipWrapper.setGrouperProvisioner(this.grouperProvisioner); - provisioningMembershipWrappers.add(provisioningMembershipWrapper); - - provisioningMembershipWrapper.setTargetProvisioningMembership(targetProvisioningMembership); - } - - } - - public void retrieveGrouperDataFull() { - - // get all grouper data for the provisioner - // and put in GrouperProvisioningDataSyncGrouper - this.grouperProvisioner.retrieveGrouperDao().retrieveGrouperDataFull(); - - // put wrappers on the grouper objects and put in the grouper uuid maps in data object - // put these wrapper in the GrouperProvisioningData and GrouperProvisioningDataIndex - this.grouperProvisioner.retrieveGrouperDao().processWrappers(); - - // point the membership pointers to groups and entities to what they should point to - // and fix data problems (for instance race conditions as data was retrieved) - this.grouperProvisioner.retrieveGrouperDao().fixGrouperProvisioningMembershipReferences(); - - // add / update / delete sync objects based on grouper data - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().fixSyncObjects(); - - // put the sync objects in their respective wrapper objects - // this is where additional wrapper objects can be added - assignSyncObjectsToWrappers(); - - // incrementals need to consult sync objects to know what to delete - calculateProvisioningDataToDelete(); - - GcGrouperSync gcGrouperSync = this.grouperProvisioner.getGcGrouperSync(); - gcGrouperSync.setGroupCount(GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects().getProvisioningGroups())); - gcGrouperSync.setUserCount(GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects().getProvisioningEntities())); - gcGrouperSync.setRecordsCount( - GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects().getProvisioningEntities()) - + GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects().getProvisioningGroups()) - + GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects().getProvisioningMemberships()) - ); - - } - - - public void assignSyncObjectsToWrappers() { - - Map grouperSyncGroupIdToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncGroupIdToProvisioningGroupWrapper(); - assignSyncObjectsToWrappersGroups(grouperSyncGroupIdToProvisioningGroupWrapper); - - Map grouperSyncMemberIdToProvisioningEntityWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncMemberIdToProvisioningEntityWrapper(); - assignSyncObjectsToWrappersMembers(grouperSyncMemberIdToProvisioningEntityWrapper); - - Map groupUuidMemberUuidToProvisioningMembershipWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupUuidMemberUuidToProvisioningMembershipWrapper(); - assignSyncObjectsToWrappersMemberships(grouperSyncGroupIdToProvisioningGroupWrapper, - grouperSyncMemberIdToProvisioningEntityWrapper, - groupUuidMemberUuidToProvisioningMembershipWrapper); - } - - public void assignSyncObjectsToWrappersMemberships( - Map grouperSyncGroupIdToProvisioningGroupWrapper, - Map grouperSyncMemberIdToProvisioningEntityWrapper, - Map grouperSyncGroupIdGrouperSyncMemberIdToProvisioningMembershipWrapper) { - { - - List gcGrouperSyncMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningDataSync().getGcGrouperSyncMemberships(); - - Map groupUuidMemberUuidToProvisioningMembershipWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupUuidMemberUuidToProvisioningMembershipWrapper(); - - if (GrouperUtil.length(gcGrouperSyncMemberships) > 0) { - - int syncMembershipReferenceMissing = 0; - - for (GcGrouperSyncMembership gcGrouperSyncMembership : gcGrouperSyncMemberships) { - - // data is not consistent just ignore for now - ProvisioningGroupWrapper provisioningGroupWrapper = grouperSyncGroupIdToProvisioningGroupWrapper.get(gcGrouperSyncMembership.getGrouperSyncGroupId()); - if (provisioningGroupWrapper == null) { - syncMembershipReferenceMissing++; - continue; - } - GcGrouperSyncGroup gcGrouperSyncGroup = provisioningGroupWrapper.getGcGrouperSyncGroup(); - - ProvisioningEntityWrapper provisioningEntityWrapper = grouperSyncMemberIdToProvisioningEntityWrapper.get(gcGrouperSyncMembership.getGrouperSyncMemberId()); - if (provisioningEntityWrapper == null) { - syncMembershipReferenceMissing++; - continue; - } - GcGrouperSyncMember gcGrouperSyncMember = provisioningEntityWrapper.getGcGrouperSyncMember(); - - MultiKey groupIdMemberId = new MultiKey(gcGrouperSyncGroup.getGroupId(), - gcGrouperSyncMember.getMemberId()); - - ProvisioningMembershipWrapper provisioningMembershipWrapper = groupUuidMemberUuidToProvisioningMembershipWrapper.get(groupIdMemberId); - - if (provisioningMembershipWrapper == null) { - provisioningMembershipWrapper = new ProvisioningMembershipWrapper(); - provisioningMembershipWrapper.setGrouperProvisioner(this.grouperProvisioner); - groupUuidMemberUuidToProvisioningMembershipWrapper.put(groupIdMemberId, provisioningMembershipWrapper); - this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningMembershipWrappers().add(provisioningMembershipWrapper); - } - - provisioningMembershipWrapper.setGcGrouperSyncMembership(gcGrouperSyncMembership); - - MultiKey syncGroupIdSyncMemberId = new MultiKey(gcGrouperSyncMembership.getGrouperSyncGroupId(), gcGrouperSyncMembership.getGrouperSyncMemberId()); - provisioningMembershipWrapper.setSyncGroupIdSyncMemberId(syncGroupIdSyncMemberId); - grouperSyncGroupIdGrouperSyncMemberIdToProvisioningMembershipWrapper.put(syncGroupIdSyncMemberId, provisioningMembershipWrapper); - } - if (syncMembershipReferenceMissing > 0) { - this.getGrouperProvisioner().getDebugMap().put("syncMembershipReferenceMissing", syncMembershipReferenceMissing); - } - } - - } - } - - public void assignSyncObjectsToWrappersMembers( - Map grouperSyncMemberIdToProvisioningEntityWrapper) { - { - Map memberUuidToProvisioningEntityWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getMemberUuidToProvisioningEntityWrapper(); - - // loop through sync groups - for (GcGrouperSyncMember gcGrouperSyncMember : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningDataSync().getGcGrouperSyncMembers())) { - - ProvisioningEntityWrapper provisioningEntityWrapper = memberUuidToProvisioningEntityWrapper.get(gcGrouperSyncMember.getMemberId()); - - if (provisioningEntityWrapper == null) { - provisioningEntityWrapper = new ProvisioningEntityWrapper(); - provisioningEntityWrapper.setGrouperProvisioner(this.grouperProvisioner); - memberUuidToProvisioningEntityWrapper.put(gcGrouperSyncMember.getMemberId(), provisioningEntityWrapper); - this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningEntityWrappers().add(provisioningEntityWrapper); - } - provisioningEntityWrapper.setGcGrouperSyncMember(gcGrouperSyncMember); - - grouperSyncMemberIdToProvisioningEntityWrapper.put(gcGrouperSyncMember.getId(), provisioningEntityWrapper); - } - } - } - - public void assignSyncObjectsToWrappersGroups( - Map grouperSyncGroupIdToProvisioningGroupWrapper) { - { - Map groupUuidToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupUuidToProvisioningGroupWrapper(); - - // loop through sync groups - for (GcGrouperSyncGroup gcGrouperSyncGroup : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningDataSync().getGcGrouperSyncGroups())) { - - ProvisioningGroupWrapper provisioningGroupWrapper = groupUuidToProvisioningGroupWrapper.get(gcGrouperSyncGroup.getGroupId()); - - if (provisioningGroupWrapper == null) { - provisioningGroupWrapper = new ProvisioningGroupWrapper(); - provisioningGroupWrapper.setGrouperProvisioner(this.grouperProvisioner); - groupUuidToProvisioningGroupWrapper.put(gcGrouperSyncGroup.getGroupId(), provisioningGroupWrapper); - this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningGroupWrappers().add(provisioningGroupWrapper); - } - provisioningGroupWrapper.setGcGrouperSyncGroup(gcGrouperSyncGroup); - - grouperSyncGroupIdToProvisioningGroupWrapper.put(gcGrouperSyncGroup.getId(), provisioningGroupWrapper); - } - } - } - - public void retrieveGrouperDataIncremental() { - - // get all grouper data for the provisioner - // and put in GrouperProvisioningDataGrouper - this.grouperProvisioner.retrieveGrouperDao().retrieveGrouperDataIncremental(); - - // put wrappers on the grouper objects and put in the grouper uuid maps in data object - // put these wrapper in the GrouperProvisioningData and GrouperProvisioningDataIndex - this.grouperProvisioner.retrieveGrouperDao().processWrappers(); - - // point the membership pointers to groups and entities to what they should point to - // and fix data problems (for instance race conditions as data was retrieved) - this.grouperProvisioner.retrieveGrouperDao().fixGrouperProvisioningMembershipReferences(); - -// // incrementals need to clone and setup sync objects as deletes -// this.getGrouperProvisioner().retrieveGrouperProvisioningLogicIncremental().setupIncrementalClonesOfGroupProvisioningObjects(); - - // add / update / delete sync objects based on grouper data - this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().fixSyncObjects(); - - // put the sync objects in their respective wrapper objects - assignSyncObjectsToWrappers(); - - // incrementals need to consult sync objects to know what to delete - calculateProvisioningDataToDelete(); - - } - - protected void countInsertsUpdatesDeletes() { - countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.insert, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectInserts().getProvisioningGroups()); - countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.insert, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectInserts().getProvisioningEntities()); - countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.insert, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectInserts().getProvisioningMemberships()); - - { - //TODO: Is this correct? - //countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.replace, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectReplaces().getProvisioningMemberships()); - List targetMemberships = new ArrayList(); - - Collection> targetMembershipsLists = this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectReplaces().getProvisioningMemberships().values(); - for (List provisioningMemberships: targetMembershipsLists) { - targetMemberships.addAll(provisioningMemberships); - } - this.grouperProvisioner.retrieveGrouperProvisioningOutput().addReplace(GrouperUtil.length(targetMemberships)); - - } - - countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.insert, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getGrouperTargetObjectsMissing().getProvisioningGroups()); - countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.insert, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getGrouperTargetObjectsMissing().getProvisioningEntities()); - - - countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.update, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningGroups()); - countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.update, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningEntities()); - countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.update, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningMemberships()); - countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.delete, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes().getProvisioningGroups()); - countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.delete, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes().getProvisioningEntities()); - countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.delete, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes().getProvisioningMemberships()); - - } - - /** - * make sure we dont doublecount actions - */ - private Set alreadyCounted = new HashSet(); - - protected void countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction provisioningObjectChangeAction, List provisioningUpdatables) { - // maybe not count fields? - if (provisioningUpdatables == null) { - return; - } - - String membershipAttribute = GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getAttributeNameForMemberships(); - boolean groupAttributes = GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() - == GrouperProvisioningBehaviorMembershipType.groupAttributes; - boolean entityAttributes = GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() - == GrouperProvisioningBehaviorMembershipType.entityAttributes; - - - for (ProvisioningUpdatable provisioningUpdatable : GrouperUtil.nonNull(provisioningUpdatables)) { - - MultiKey multiKey = new MultiKey(provisioningObjectChangeAction, provisioningUpdatable.provisioningUpdatableTypeShort(), provisioningUpdatable.getMatchingId()); - - // if this is an update, dont doublecount the inserts if we are only updating the membership objects - MultiKey insertMultiKey = provisioningObjectChangeAction == ProvisioningObjectChangeAction.update ? new MultiKey(ProvisioningObjectChangeAction.insert, provisioningUpdatable.provisioningUpdatableTypeShort(), provisioningUpdatable.getMatchingId()) : null; - - if (!alreadyCounted.contains(multiKey) && provisioningUpdatable.getProvisioned() != null && provisioningUpdatable.getProvisioned()) { - switch(provisioningObjectChangeAction) { - case insert: - this.grouperProvisioner.retrieveGrouperProvisioningOutput().addInsert(1); - alreadyCounted.add(multiKey); - break; - case update: - // its an update if we are doing something other than membership stuff and it is also an insert - if (!alreadyCounted.contains(insertMultiKey) || StringUtils.isBlank(membershipAttribute) || (!groupAttributes && !entityAttributes) - || (groupAttributes && (!(provisioningUpdatable instanceof ProvisioningGroup))) - || (entityAttributes && (!(provisioningUpdatable instanceof ProvisioningEntity)))) { - this.grouperProvisioner.retrieveGrouperProvisioningOutput().addUpdate(1); - alreadyCounted.add(multiKey); - } else { - - for (ProvisioningObjectChange provisioningObjectChange : GrouperUtil.nonNull(provisioningUpdatable.getInternal_objectChanges())) { - if (!StringUtils.equals(provisioningObjectChange.getAttributeName(), membershipAttribute) - && provisioningObjectChange.getProvisioned() != null && provisioningObjectChange.getProvisioned()) { - this.grouperProvisioner.retrieveGrouperProvisioningOutput().addUpdate(1); - alreadyCounted.add(multiKey); - break; - } - } - } - break; - case replace: - this.grouperProvisioner.retrieveGrouperProvisioningOutput().addReplace(1); - alreadyCounted.add(multiKey); - break; - case delete: - this.grouperProvisioner.retrieveGrouperProvisioningOutput().addDelete(1); - alreadyCounted.add(multiKey); - break; - } - - } - - // go through the membership attributes and count as memberships - if (!StringUtils.isBlank(membershipAttribute) && (groupAttributes || entityAttributes)) { - if ((groupAttributes && provisioningUpdatable instanceof ProvisioningGroup) - || entityAttributes && provisioningUpdatable instanceof ProvisioningEntity) { - - for (ProvisioningObjectChange provisioningObjectChange : GrouperUtil.nonNull(provisioningUpdatable.getInternal_objectChanges())) { - - if (!StringUtils.equals(provisioningObjectChange.getAttributeName(), membershipAttribute)) { - - } - - if (StringUtils.equals(provisioningObjectChange.getAttributeName(), membershipAttribute) - && provisioningObjectChange.getProvisioned() != null && provisioningObjectChange.getProvisioned()) { - - ProvisioningObjectChangeAction attributeProvisioningObjectChangeAction = provisioningObjectChange.getProvisioningObjectChangeAction(); - Object value = null; - switch (attributeProvisioningObjectChangeAction) { - case insert: - case update: - value = provisioningObjectChange.getNewValue(); - break; - case delete: - value = provisioningObjectChange.getOldValue(); - break; - } - - multiKey = new MultiKey(attributeProvisioningObjectChangeAction, provisioningUpdatable.provisioningUpdatableTypeShort(), provisioningUpdatable.getMatchingId(), value); - - if (alreadyCounted.contains(multiKey)) { - continue; - } - alreadyCounted.add(multiKey); - - switch (attributeProvisioningObjectChangeAction) { - case insert: - this.grouperProvisioner.retrieveGrouperProvisioningOutput().addInsert(1); - break; - case update: - this.grouperProvisioner.retrieveGrouperProvisioningOutput().addUpdate(1); - break; - case delete: - this.grouperProvisioner.retrieveGrouperProvisioningOutput().addDelete(1); - break; - - } - } - } - } - } - - - } - - } - - /** - * reference back up to the provisioner - */ - private GrouperProvisioner grouperProvisioner = null; - - /** logger */ - private static final Log LOG = GrouperUtil.getLog(GrouperProvisioningLogic.class); - - /** - * reference back up to the provisioner - * @return the provisioner - */ - public GrouperProvisioner getGrouperProvisioner() { - return this.grouperProvisioner; - } - - /** - * reference back up to the provisioner - * @param grouperProvisioner1 - */ - public void setGrouperProvisioner(GrouperProvisioner grouperProvisioner1) { - this.grouperProvisioner = grouperProvisioner1; - } - - - - - public void calculateProvisioningDataToDelete() { - this.calculateProvisioningGroupsToDelete(); - this.calculateProvisioningEntitiesToDelete(); - this.calculateProvisioningMembershipsToDelete(); - - } - - - /** - * take the sync members and see which ones do not correspond to a grouper member - */ - public void calculateProvisioningEntitiesToDelete() { - - Map memberUuidToProvisioningMemberWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getMemberUuidToProvisioningEntityWrapper(); - - int provisioningEntitiesToDelete = 0; - - List grouperProvisioningObjectMetadataItems = - this.grouperProvisioner.retrieveGrouperProvisioningObjectMetadata().getGrouperProvisioningObjectMetadataItems(); - - Map memberIdToEntityWrapperToDelete = new HashMap<>(); - - // loop through sync groups - for (ProvisioningEntityWrapper provisioningEntityWrapper : this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningEntityWrappers()) { - - GcGrouperSyncMember gcGrouperSyncMember = provisioningEntityWrapper.getGcGrouperSyncMember(); - ProvisioningEntity grouperProvisioningEntity = provisioningEntityWrapper.getGrouperProvisioningEntity(); - - // if a entity has been deleted in grouper_members table but copy still exists in grouper_sync_member - // we are sending the copy over to the target so that target can also delete - if (grouperProvisioningEntity == null && gcGrouperSyncMember != null) { - - memberIdToEntityWrapperToDelete.put(gcGrouperSyncMember.getMemberId(), provisioningEntityWrapper); - provisioningEntitiesToDelete++; - - } - } - - if (memberIdToEntityWrapperToDelete.size() == 0) { - return; - } - - List membersNonProvisionable = this.getGrouperProvisioner().retrieveGrouperDao().retrieveMembersNonProvisionable(memberIdToEntityWrapperToDelete.keySet()); - - Map memberIdToProvisioningEntityToDelete = new HashMap<>(); - - for (ProvisioningEntity provisioningEntityNotProvisionable: GrouperUtil.nonNull(membersNonProvisionable)) { - memberIdToProvisioningEntityToDelete.put(provisioningEntityNotProvisionable.getId(), provisioningEntityNotProvisionable); - } - - for (String memberIdToDelete: memberIdToEntityWrapperToDelete.keySet()) { - - ProvisioningEntity grouperProvisioningEntity = memberIdToProvisioningEntityToDelete.get(memberIdToDelete); - - ProvisioningEntityWrapper provisioningEntityWrapper = memberIdToEntityWrapperToDelete.get(memberIdToDelete); - - if (grouperProvisioningEntity == null) { - - GcGrouperSyncMember gcGrouperSyncMember = provisioningEntityWrapper.getGcGrouperSyncMember(); - grouperProvisioningEntity = new ProvisioningEntity(); - grouperProvisioningEntity.setId(gcGrouperSyncMember.getMemberId()); - grouperProvisioningEntity.setSubjectId(gcGrouperSyncMember.getSubjectId()); - grouperProvisioningEntity.assignAttributeValue("subjectSourceId", gcGrouperSyncMember.getSourceId()); - if ("subjectIdentifier1".equals(grouperProvisioner.retrieveGrouperProvisioningBehavior().getSubjectIdentifierForMemberSyncTable())) { - grouperProvisioningEntity.assignAttributeValue("subjectIdentifier1", gcGrouperSyncMember.getSubjectIdentifier()); - } else if ("subjectIdentifier2".equals(grouperProvisioner.retrieveGrouperProvisioningBehavior().getSubjectIdentifierForMemberSyncTable())) { - grouperProvisioningEntity.assignAttributeValue("subjectIdentifier2", gcGrouperSyncMember.getSubjectIdentifier()); - } else { - grouperProvisioningEntity.assignAttributeValue("subjectIdentifier0", gcGrouperSyncMember.getSubjectIdentifier()); - } - - if (GrouperUtil.length(grouperProvisioningObjectMetadataItems) > 0) { - - String jsonMetadata = gcGrouperSyncMember.getMetadataJson(); - - if (!StringUtils.isBlank(jsonMetadata) && !StringUtils.equals("{}", jsonMetadata)) { - JsonNode jsonNode = GrouperUtil.jsonJacksonNode(jsonMetadata); - for (GrouperProvisioningObjectMetadataItem grouperProvisioningObjectMetadataItem : grouperProvisioningObjectMetadataItems) { - if (grouperProvisioningObjectMetadataItem.isShowForMember()) { - - String metadataItemName = grouperProvisioningObjectMetadataItem.getName(); - if (metadataItemName.startsWith("md_")) { - if (jsonNode.has(metadataItemName)) { - GrouperProvisioningObjectMetadataItemValueType grouperProvisioningObjectMetadataItemValueType = - GrouperUtil.defaultIfNull(grouperProvisioningObjectMetadataItem.getValueType(), GrouperProvisioningObjectMetadataItemValueType.STRING); - String value = GrouperUtil.jsonJacksonGetString(jsonNode, metadataItemName); - grouperProvisioningEntity.assignAttributeValue(metadataItemName, grouperProvisioningObjectMetadataItemValueType.convert(value)); - } - } - } - } - } - } - -// //TODO select in bulk from grouper members -// Member member = MemberFinder.findByUuid(GrouperSession.staticGrouperSession(), gcGrouperSyncMember.getMemberId(), false); -// if (member != null) { -// grouperProvisioningEntity.setName(member.getName()); -// grouperProvisioningEntity.setEmail(member.getEmail0()); -// -// grouperProvisioningEntity.assignAttributeValue("description", member.getDescription()); -// } - - } - - provisioningEntityWrapper.setGrouperProvisioningEntity(grouperProvisioningEntity); - provisioningEntityWrapper.setDelete(true); - - memberUuidToProvisioningMemberWrapper.put(grouperProvisioningEntity.getId(), provisioningEntityWrapper); - - } - - if (provisioningEntitiesToDelete > 0) { - this.getGrouperProvisioner().getDebugMap().put("provisioningEntitiesToDelete", provisioningEntitiesToDelete); - } - - } - - - /** - * take the sync groups and see which ones do not correspond to a grouper group - */ - public void calculateProvisioningGroupsToDelete() { - - Map groupUuidToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupUuidToProvisioningGroupWrapper(); - - int provisioningGroupsToDeleteCount = 0; - - List grouperProvisioningObjectMetadataItems = - this.grouperProvisioner.retrieveGrouperProvisioningObjectMetadata().getGrouperProvisioningObjectMetadataItems(); - - Set provisioningGroupWrappers = this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningGroupWrappers(); - - // loop through sync groups - for (ProvisioningGroupWrapper provisioningGroupWrapper : provisioningGroupWrappers) { - - //TODO Perhaps look at grouper_groups information for unprovisionable groups that aren't deleted from grouper just like - // we did for entities. - - // if a group has been deleted in grouper_groups table but copy still exists in grouper_sync_group - // we are sending the copy over to the target so that target can also delete - ProvisioningGroup grouperProvisioningGroup = provisioningGroupWrapper.getGrouperProvisioningGroup(); - GcGrouperSyncGroup gcGrouperSyncGroup = provisioningGroupWrapper.getGcGrouperSyncGroup(); - if (grouperProvisioningGroup == null && gcGrouperSyncGroup != null) { - - provisioningGroupsToDeleteCount++; - - // create a provisioning group to delete - grouperProvisioningGroup = new ProvisioningGroup(); - grouperProvisioningGroup.setId(gcGrouperSyncGroup.getGroupId()); - grouperProvisioningGroup.setName(gcGrouperSyncGroup.getGroupName()); - grouperProvisioningGroup.setIdIndex(gcGrouperSyncGroup.getGroupIdIndex()); - - if (GrouperUtil.length(grouperProvisioningObjectMetadataItems) > 0) { - - String jsonMetadata = gcGrouperSyncGroup.getMetadataJson(); - - if (!StringUtils.isBlank(jsonMetadata) && !StringUtils.equals("{}", jsonMetadata)) { - JsonNode jsonNode = GrouperUtil.jsonJacksonNode(jsonMetadata); - for (GrouperProvisioningObjectMetadataItem grouperProvisioningObjectMetadataItem : grouperProvisioningObjectMetadataItems) { - if (grouperProvisioningObjectMetadataItem.isShowForMember()) { - - String metadataItemName = grouperProvisioningObjectMetadataItem.getName(); - if (metadataItemName.startsWith("md_")) { - if (jsonNode.has(metadataItemName)) { - GrouperProvisioningObjectMetadataItemValueType grouperProvisioningObjectMetadataItemValueType = - GrouperUtil.defaultIfNull(grouperProvisioningObjectMetadataItem.getValueType(), GrouperProvisioningObjectMetadataItemValueType.STRING); - String value = GrouperUtil.jsonJacksonGetString(jsonNode, metadataItemName); - grouperProvisioningGroup.assignAttributeValue(metadataItemName, grouperProvisioningObjectMetadataItemValueType.convert(value)); - } - } - } - } - } - } - - provisioningGroupWrapper.setGrouperProvisioningGroup(grouperProvisioningGroup); - provisioningGroupWrapper.setDelete(true); - - groupUuidToProvisioningGroupWrapper.put(gcGrouperSyncGroup.getGroupId(), provisioningGroupWrapper); - - } - - } - if (provisioningGroupsToDeleteCount > 0) { - this.getGrouperProvisioner().getDebugMap().put("provisioningGroupsToDeleteCount", provisioningGroupsToDeleteCount); - } - - } - - - /** - * take the sync groups and see which ones do not correspond to a grouper group - */ - public void calculateProvisioningMembershipsToDelete() { - - Map memberUuidToProvisioningEntityWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getMemberUuidToProvisioningEntityWrapper(); - Map groupUuidToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupUuidToProvisioningGroupWrapper(); - Map gcGrouperSyncMemberIdToProvisioningEntityWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncMemberIdToProvisioningEntityWrapper(); - Map gcGrouperSyncGroupIdToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncGroupIdToProvisioningGroupWrapper(); - - Map groupUuidMemberUuidToProvisioningMembershipWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupUuidMemberUuidToProvisioningMembershipWrapper(); - - int provisioningMshipsToDelete = 0; - - // loop through sync groups - for (ProvisioningMembershipWrapper provisioningMembershipWrapper : this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningMembershipWrappers()) { - - ProvisioningMembership grouperProvisioningMembership = provisioningMembershipWrapper.getGrouperProvisioningMembership(); - - GcGrouperSyncMembership gcGrouperSyncMembership = provisioningMembershipWrapper.getGcGrouperSyncMembership(); - - if (grouperProvisioningMembership == null && gcGrouperSyncMembership != null) { - - provisioningMshipsToDelete++; - - ProvisioningGroupWrapper provisioningGroupWrapper = gcGrouperSyncGroupIdToProvisioningGroupWrapper.get(gcGrouperSyncMembership.getGrouperSyncGroupId()); - if (provisioningGroupWrapper == null) { - throw new RuntimeException("Cant find groupId: '" + gcGrouperSyncMembership.getGrouperSyncGroupId() + "'"); - } - ProvisioningEntityWrapper provisioningEntityWrapper = gcGrouperSyncMemberIdToProvisioningEntityWrapper.get(gcGrouperSyncMembership.getGrouperSyncMemberId()); - if (provisioningEntityWrapper == null) { - throw new RuntimeException("Cant find entityId: '" + gcGrouperSyncMembership.getGrouperSyncMemberId() + "'"); - } - - GcGrouperSyncGroup gcGrouperSyncGroup = provisioningGroupWrapper.getGcGrouperSyncGroup(); - GcGrouperSyncMember gcGrouperSyncMember = provisioningEntityWrapper.getGcGrouperSyncMember(); - - // these can be null if in the index - - String groupId = gcGrouperSyncGroup.getGroupId(); - String memberId = gcGrouperSyncMember.getMemberId(); - - - // create a provisioning group to delete - ProvisioningMembership provisioningMembership = new ProvisioningMembership(); - provisioningMembership.setProvisioningGroupId(groupId); - provisioningMembership.setProvisioningEntityId(memberId); - - // the group is either the provisioning group or provisioning group to delete - if (provisioningGroupWrapper.getGrouperProvisioningGroup() != null) { - provisioningMembership.setProvisioningGroup(provisioningGroupWrapper.getGrouperProvisioningGroup()); - } else { - throw new RuntimeException("Cant find provisioning group: '" + groupId + "'"); - } - - // the group is either the provisioning group or provisioning group to delete - if (provisioningEntityWrapper.getGrouperProvisioningEntity() != null) { - provisioningMembership.setProvisioningEntity(provisioningEntityWrapper.getGrouperProvisioningEntity()); - } else { - throw new RuntimeException("Cant find provisioning entity: '" + memberId + "'"); - } - - provisioningMembershipWrapper.setGrouperProvisioningMembership(provisioningMembership); - provisioningMembershipWrapper.setDelete(true); - - groupUuidMemberUuidToProvisioningMembershipWrapper.put(provisioningMembershipWrapper.getGroupIdMemberId(), provisioningMembershipWrapper); - - } - provisioningMembershipWrapper.setGcGrouperSyncMembership(gcGrouperSyncMembership); - } - if (provisioningMshipsToDelete > 0) { - this.getGrouperProvisioner().getDebugMap().put("provisioningMshipsToDelete", provisioningMshipsToDelete); - } - - - } - - /** - * if incremental, and there are missing groups or entities, then retrieve them - */ - public void retrieveMissingObjectsIncremental() { - retrieveMissingGroupsIncremental(); - retrieveMissingEntitiesIncremental(); - } - - /** - * if incremental, and there are missing groups or entities, then retrieve them - */ - public void retrieveMissingGroupsIncremental() { - - // first lets see if we should even be doing this - if (!this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectGroupMissingIncremental()) { - return; - } - - //do we have missing groups? - List missingGroups = new ArrayList(); - - for (ProvisioningGroup provisioningGroup : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperProvisioningGroups())) { - - // shouldnt be null at this point - GcGrouperSyncGroup gcGrouperSyncGroup = provisioningGroup.getProvisioningGroupWrapper().getGcGrouperSyncGroup(); - - if (!gcGrouperSyncGroup.isProvisionable()) { - continue; - } - if (this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().groupLinkMissing(gcGrouperSyncGroup)) { - missingGroups.add(provisioningGroup); - } - } - - if (GrouperUtil.length(missingGroups) == 0) { - return; - } - // how many do we have - this.grouperProvisioner.getDebugMap().put("missingIncrementalGroupsForRetrieve", missingGroups); - - this.grouperProvisioner.retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjectsMissing().setProvisioningGroups(missingGroups); - - // log this - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingGroups); - - // translate - List grouperTargetGroups = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetGroups(missingGroups, false, false); - this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getGrouperTargetObjectsMissing().setProvisioningGroups(grouperTargetGroups); - - // index - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups(grouperTargetGroups); - - // log this - //TODO this.getGrouperProvisioner().getGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingTargetGroups); - - //lets retrieve these - TargetDaoRetrieveGroupsResponse targetDaoRetrieveGroupsResponse = - this.grouperProvisioner.retrieveGrouperProvisioningTargetDaoAdapter().retrieveGroups(new TargetDaoRetrieveGroupsRequest(grouperTargetGroups, false)); - - List targetGroups = GrouperUtil.nonNull(targetDaoRetrieveGroupsResponse == null ? null : targetDaoRetrieveGroupsResponse.getTargetGroups()); - - // index - this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups(targetGroups); - - this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjectsMissingRetrieved().setProvisioningGroups(targetGroups); - - this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingTargetGroupsRetrieved); - - Map matchingIdToGrouperTargetGroup = new HashMap(); - - for (ProvisioningGroup grouperTargetGroup : GrouperUtil.nonNull(grouperTargetGroups)) { - matchingIdToGrouperTargetGroup.put(grouperTargetGroup.getMatchingId(), grouperTargetGroup); - } - - // set these in the wrapper so they are linked with grouper group - for (ProvisioningGroup targetGroup : GrouperUtil.nonNull(targetGroups)) { - - // look up the grouper group that looked this up - ProvisioningGroup grouperTargetGroup = matchingIdToGrouperTargetGroup.get(targetGroup.getMatchingId()); - - // not sure why it wouldnt match or exist... - grouperTargetGroup.getProvisioningGroupWrapper().setTargetProvisioningGroup(targetGroup); - } - - } - - /** - * if incremental, and there are missing groups or entities, then retrieve them - */ - public void retrieveMissingEntitiesIncremental() { - - } - -} + grouperProvisioner.retrieveGrouperProvisioningLogic().retrieveGrouperDataIncremental(); + long retrieveGrouperDataMillis = System.currentTimeMillis()-start; + debugMap.put("retrieveGrouperDataMillis", retrieveGrouperDataMillis); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveIncrementalDataFromGrouper); + } + + // ######### STEP 18: filter unneeded actions + debugMap.put("state", "filterUnneededActions"); + grouperProvisioningLogicIncremental.filterUnneededActions(); + + // ######### STEP 19: convert inconsistent events to recalc + debugMap.put("state", "convertInconsistentEventsToRecalc"); + grouperProvisioningLogicIncremental.convertInconsistentEventsToRecalc(); + + // ######### STEP 20: copy incremental state to wrappers (so wrapper knows if recalc or whatever) + debugMap.put("state", "copyIncrementalStateToWrappers"); + grouperProvisioningLogicIncremental.copyIncrementalStateToWrappers(); + + // ######### STEP 21: resolve subjects for subject link if recalc or for subjects missing data + try { + debugMap.put("state", "retrieveSubjectLink"); + this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().retrieveSubjectLink(); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveSubjectLink); + } + } + + if (this.getGrouperProvisioner().retrieveGrouperProvisioningDataIncrementalInput().isHasIncrementalDataToProcess()) { + // ######### STEP 22: translate grouper groups/entities to target format + try { + debugMap.put("state", "translateGrouperGroupsEntitiesToTarget"); + + { + List grouperProvisioningGroups = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperProvisioningGroups(); + List grouperTargetGroups = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetGroups(grouperProvisioningGroups, false, false); + this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningGroups(grouperTargetGroups); + } + + { + List grouperProvisioningEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperProvisioningEntities(); + + List grouperTargetEntities = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetEntities( + grouperProvisioningEntities, false, false); + this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningEntities(grouperTargetEntities); + } + + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.translateGrouperGroupsEntitiesToTarget); + } + + // ######### STEP 23: based on configs manipulate the defaults, types, etc for grouper target groups/entities translated attributes and fields + try { + debugMap.put("state", "manipulateGrouperTargetAttributes"); + List grouperTargetGroups = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetGroups(); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForGroups(grouperTargetGroups, null); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterGroupFieldsAndAttributes(grouperTargetGroups, true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesGroups(grouperTargetGroups); + + List grouperTargetEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForEntities(grouperTargetEntities, null); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes(grouperTargetEntities, true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities(grouperTargetEntities); + + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.manipulateGrouperTargetGroupsEntitiesAttributes); + } + + // ######### STEP 24: calculate the matching id of grouper translated groups/entities + try { + debugMap.put("state", "matchingIdGrouperGroupsEntities"); + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups( + this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetGroups()); + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetEntities( + this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetEntities()); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdGrouperGroupsEntities); + } + + // ######### STEP 25: take all the matching ids of grouper groups/entities and index those for quick lookups + { + debugMap.put("state", "indexMatchingIdGroups"); + + // index the groups and entity matching ids + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdGroups(); + + debugMap.put("state", "indexMatchingIdEntities"); + + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdEntities(); + + } + + // ######### STEP 26: validate groups + try { + // validate + this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateEntities(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(), false, false); + this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateGroupsHaveMembers(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetGroups(), false); + this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateGroups(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetGroups(), false, false); + this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateMemberships(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(false), false); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.validateGrouperGroupsEntities); + } + + // ######### STEP 27: recalc retrieve data from target + try { + debugMap.put("state", "retrieveIncrementalTargetData"); + long start = System.currentTimeMillis(); + grouperProvisioningLogicIncremental.retrieveIncrementalTargetData(); + long retrieveTargetDataMillis = System.currentTimeMillis()-start; + debugMap.put("retrieveTargetDataMillis", retrieveTargetDataMillis); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveTargetDataIncremental); + } + + // ######### STEP 28: target object attribute manipulation + try { + debugMap.put("state", "targetAttributeManipulation"); + // do not assign defaults to target + // filter groups and manipulate attributes and types + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterGroupFieldsAndAttributes( + this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningGroups(), true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes( + this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningEntities(), true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterMembershipFieldsAndAttributes( + this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningMemberships(), true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesGroups( + this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningGroups()); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities( + this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningEntities()); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesMemberships( + this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningMemberships()); + + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.targetAttributeManipulation); + } + + // ######### STEP 29: matching id target objects + try { + debugMap.put("state", "matchingIdTargetObjects"); + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningGroups()); + for (ProvisioningGroup targetGroup : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningGroups())) { + ProvisioningGroupWrapper provisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupMatchingIdToProvisioningGroupWrapper().get(targetGroup.getMatchingId()); + if (provisioningGroupWrapper != null) { + provisioningGroupWrapper.setTargetProvisioningGroup(targetGroup); + } + } + + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetEntities(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningEntities()); + for (ProvisioningEntity targetEntity : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningEntities())) { + ProvisioningEntityWrapper provisioningEntityWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getEntityMatchingIdToProvisioningEntityWrapper().get(targetEntity.getMatchingId()); + if (provisioningEntityWrapper != null) { + provisioningEntityWrapper.setTargetProvisioningEntity(targetEntity); + } + } + + { + debugMap.put("state", "indexMatchingIdGroupsUnmatched"); + + // index the groups and entity matching ids + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdGroupsUnmatched(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningGroups()); + +// debugMap.put("state", "indexMatchingIdEntities"); +// +// this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdEntities(); + } + + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetMemberships(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningMemberships()); + for (ProvisioningMembership targetMembership : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningMemberships())) { + ProvisioningMembershipWrapper provisioningMembershipWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getMembershipMatchingIdToProvisioningMembershipWrapper().get(targetMembership.getMatchingId()); + if (provisioningMembershipWrapper != null) { + provisioningMembershipWrapper.setTargetProvisioningMembership(targetMembership); + } + } + + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdTargetObjects); + } + + // ######### STEP 30: create groups / entities + debugMap.put("state", "insertGroups"); + createMissingGroupsFull(); + + debugMap.put("state", "insertEntities"); + createMissingEntitiesFull(); + + // ######### STEP 31: retrieve target group and entity link + try { + debugMap.put("state", "retrieveTargetGroupLink"); + this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().updateGroupLinkFull(); + + debugMap.put("state", "retrieveTargetEntityLink"); + this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().updateEntityLinkFull(); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.linkData); + } + + // ######### STEP 32: translate grouper memberships to target format + try { + debugMap.put("state", "translateGrouperMembershipsToTarget"); + + { + List grouperProvisioningMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperProvisioningMemberships(false); + List grouperTargetMemberships = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetMemberships( + grouperProvisioningMemberships, true); + this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningMemberships(grouperTargetMemberships); + } + + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.translateGrouperMembershipsToTarget); + } + + // ######### STEP 33: based on configs manipulate the defaults, types, etc for grouper target memberships translated attributes and fields + try { + debugMap.put("state", "manipulateGrouperTargetMembershipAttributes"); + + List grouperTargetMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForMemberships(grouperTargetMemberships); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterMembershipFieldsAndAttributes(grouperTargetMemberships, true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesMemberships(grouperTargetMemberships); + + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.manipulateGrouperTargetMembershipsAttributes); + } + + // ######### STEP 34: calculate the matching id of grouper translated membership data + try { + debugMap.put("state", "matchingIdGrouperMemberships"); + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetMemberships( + this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(false)); + + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdGrouperMemberships); + } + + // ######### STEP 35: index matching ID of grouper and target objects + debugMap.put("state", "indexMatchingIdOfGrouperObjects"); + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdGroups(); + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdEntities(); + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdMemberships(); + + for (ProvisioningMembership targetMembership : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningMemberships())) { + ProvisioningMembershipWrapper provisioningMembershipWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getMembershipMatchingIdToProvisioningMembershipWrapper().get(targetMembership.getMatchingId()); + if (provisioningMembershipWrapper != null) { + provisioningMembershipWrapper.setTargetProvisioningMembership(targetMembership); + } + + } + + + // ######## Retrieve memberships from target that are recalc where the group is not recalc + try { + debugMap.put("state", "retrieveTargetIncrementalMembershipsWithRecalcWhereContainerIsNotRecalc"); + long start = System.currentTimeMillis(); + grouperProvisioningLogicIncremental.retrieveTargetIncrementalMembershipsWithRecalcWhereContainerIsNotRecalc(); + long retrieveTargetDataMillis = System.currentTimeMillis()-start; + debugMap.put("retrieveTargetIncrementalMembershipsMillis", retrieveTargetDataMillis); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.retrieveTargetIncrementalMembershipsWithRecalcWhereContainerIsNotRecalc); + } + + { + // index the memberships +// this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdMemberships(); + + if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectGroups()) { + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsSelectGroupsFull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers()); + } + + if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectEntities()) { + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsSelectEntitiesFull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningEntityWrappers()); + } + + if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectMemberships()) { + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsSelectMembershipsFull( + this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers(), + this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningEntityWrappers(), + this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningMembershipWrappers()); + } + + // validate memberships +// this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateMemberships(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(), false); + + this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateEntities(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(), false, true); + } + + // ######### STEP 36: compare target objects + try { + debugMap.put("state", "compareTargetObjectsIncremental"); + this.grouperProvisioner.retrieveGrouperProvisioningCompare().compareTargetObjects(); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.compareTargetObjects); + } + + this.getGrouperProvisioner().retrieveGrouperProvisioningFailsafe().processFailsafes(); + + // ######### STEP 37: send changes to target + RuntimeException runtimeException = null; + try { + debugMap.put("state", "sendChangesToTarget"); + TargetDaoSendChangesToTargetRequest targetDaoSendChangesToTargetRequest = new TargetDaoSendChangesToTargetRequest(); + targetDaoSendChangesToTargetRequest.setTargetObjectInserts(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts()); + targetDaoSendChangesToTargetRequest.setTargetObjectUpdates(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates()); + targetDaoSendChangesToTargetRequest.setTargetObjectReplaces(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectReplaces()); + targetDaoSendChangesToTargetRequest.setTargetObjectDeletes(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes()); + this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter().sendChangesToTarget(targetDaoSendChangesToTargetRequest); + } catch (RuntimeException e) { + runtimeException = e; + } finally { + try { + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsInserts(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts()); + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsUpdatesFull(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates()); + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsReplaces(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectReplaces()); + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsDeletes(this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes()); + } catch (RuntimeException e) { + GrouperUtil.exceptionFinallyInjectOrThrow(runtimeException, e); + } + //TODO this.getGrouperProvisioner().getGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.sendChangesToTarget); + + } + + this.countInsertsUpdatesDeletes(); + + } + + { + Timestamp nowTimestamp = new Timestamp(System.currentTimeMillis()); + + GcGrouperSyncJob gcGrouperSyncJob = this.grouperProvisioner.getGcGrouperSyncJob(); + gcGrouperSyncJob.setErrorMessage(null); + gcGrouperSyncJob.setErrorTimestamp(null); + gcGrouperSyncJob.setLastSyncTimestamp(nowTimestamp); + if (this.grouperProvisioner.retrieveGrouperProvisioningDataChanges().wasWorkDone()) { + gcGrouperSyncJob.setLastTimeWorkWasDone(nowTimestamp); + } + gcGrouperSyncJob.setPercentComplete(100); + + // do this in the right spot, after assigning correct sync info about sync + int objectStoreCount = this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncDao().storeAllObjects(); + this.grouperProvisioner.getProvisioningSyncResult().setSyncObjectStoreCount(objectStoreCount); + + this.grouperProvisioner.getDebugMap().put("syncObjectStoreCount", objectStoreCount); + } + + // TODO flesh this out, resolve subjects, linked cached data, etc, try individually again +// this.getGrouperProvisioner().retrieveTargetDao().resolveErrors(); +// this.getGrouperProvisioner().retrieveTargetDao().sendErrorFixesToTarget(); + +// this.getGrouperProvisioner().getGrouperProvisioningLogicAlgorithm().syncGrouperTranslatedGroupsToTarget(); +// this.getGrouperProvisioner().getGrouperProvisioningLogicAlgorithm().syncGrouperTranslatedMembershipsToTarget(); + + // make sure the sync objects are correct +// new ProvisioningSyncIntegration().assignTarget(this.getGrouperProvisioner().getConfigId()).fullSync(); + +// // step 1 +// debugMap.put("state", "retrieveData"); +// this.gcTableSyncConfiguration.getGcTableSyncSubtype().retrieveData(debugMap, this); +// +// this.gcGrouperSyncLog.setRecordsProcessed(Math.max(this.gcTableSyncOutput.getRowsSelectedFrom(), this.gcTableSyncOutput.getRowsSelectedTo())); + // +// if (this.gcGrouperSyncHeartbeat.isInterrupted()) { +// debugMap.put("interrupted", true); +// debugMap.put("state", "done"); +// gcGrouperSyncLog.setStatus(GcGrouperSyncLogState.INTERRUPTED); +// return; +// } + if (GrouperClientUtils.isBlank(this.getGrouperProvisioner().getGcGrouperSyncLog().getStatus())) { + this.getGrouperProvisioner().getGcGrouperSyncLog().setStatus(GcGrouperSyncLogState.SUCCESS); + } + + } + + } + + // ######### STEP 36: acknowledge messages + this.getGrouperProvisioner().retrieveGrouperProvisioningLogicIncremental().acknowledgeMessagesProcessed(); + + } + + public void storeAllSyncObjects() { + { + // do this in the right spot, after assigning correct sync info about sync + int objectStoreCount = this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncDao().storeAllObjects(); + this.grouperProvisioner.getProvisioningSyncResult().setSyncObjectStoreCount(objectStoreCount); + + this.grouperProvisioner.getDebugMap().put("syncObjectStoreCount", objectStoreCount); + } + } + + public void runFullSyncFromIncremental() { + + // end out this provisioner + storeAllSyncObjects(); + this.getGrouperProvisioner().provisionFinallyBlock(); + + // run a full sync + GrouperProvisioner grouperProvisionerFullSync = GrouperProvisioner.retrieveProvisioner(this.getGrouperProvisioner().getConfigId()); + grouperProvisionerFullSync.setGcGrouperSyncHeartbeat(this.getGrouperProvisioner().getGcGrouperSyncHeartbeat()); + Map newDebugMap = new LinkedHashMap(); + newDebugMap.put("incrementalDebugMap", GrouperUtil.mapToString(this.getGrouperProvisioner().getDebugMap()) + "\n\n"); + + grouperProvisionerFullSync.setDebugMap(newDebugMap); + grouperProvisionerFullSync.setGrouperProvisioningOutput(this.getGrouperProvisioner().retrieveGrouperProvisioningOutput()); + grouperProvisionerFullSync.provision(GrouperProvisioningType.fullProvisionFull); + } + + public void createMissingGroupsFull() { + // first lets see if we should even be doing this + if (!GrouperUtil.booleanValue(this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isInsertGroups(), false)) { + return; + } + + //do we have missing groups? + List missingGroups = new ArrayList(); + List missingGroupWrappers = new ArrayList(); + + for (ProvisioningGroupWrapper provisioningGroupWrapper : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers())) { + + ProvisioningGroup provisioningGroup = provisioningGroupWrapper.getGrouperProvisioningGroup(); + + if (provisioningGroup == null || !provisioningGroupWrapper.isRecalc()) { + continue; + } + + // shouldnt be null at this point + GcGrouperSyncGroup gcGrouperSyncGroup = provisioningGroupWrapper.getGcGrouperSyncGroup(); + + if (!gcGrouperSyncGroup.isProvisionable()) { + continue; + } + + ProvisioningGroup targetGroup = provisioningGroupWrapper.getTargetProvisioningGroup(); + + if (targetGroup != null) { + continue; + } + + missingGroups.add(provisioningGroup); + missingGroupWrappers.add(provisioningGroupWrapper); + } + + if (GrouperUtil.length(missingGroups) == 0) { + return; + } + + // how many do we have + this.grouperProvisioner.getDebugMap().put("missingGroupsForCreate", GrouperUtil.length(missingGroups)); + + this.grouperProvisioner.retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjectsMissing().setProvisioningGroups(missingGroups); + + // log this + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingGroupsForCreate); + + List grouperTargetGroupsToInsert = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetGroups(missingGroups, false, true); + + if (GrouperUtil.length(grouperTargetGroupsToInsert) == 0) { + this.grouperProvisioner.getDebugMap().put("groupTranslationEndedInNoGroupsOnInsert", true); + return; + } + + translateAndManipulateMembershipsForGroupsEntitiesCreate(); + + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForGroups(grouperTargetGroupsToInsert, null); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterGroupFieldsAndAttributes(grouperTargetGroupsToInsert, false, true, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesGroups(grouperTargetGroupsToInsert); + + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups(grouperTargetGroupsToInsert); + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdGroups(); + + this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getGrouperTargetObjectsMissing().setProvisioningGroups(grouperTargetGroupsToInsert); + + // validate that groups have members + this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateGroupsHaveMembers(grouperTargetGroupsToInsert, true); + + // validate + this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateGroups(grouperTargetGroupsToInsert, true, false); + + if (GrouperUtil.length(grouperTargetGroupsToInsert) == 0) { + this.grouperProvisioner.getDebugMap().put("groupTranslationEndedInNoGroupsOnInsert", true); + return; + } + + // add object change entries + this.grouperProvisioner.retrieveGrouperProvisioningCompare().addInternalObjectChangeForGroupsToInsert(grouperTargetGroupsToInsert); + + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingGrouperTargetGroupsForCreate); + + //lets create these + RuntimeException runtimeException = null; + try { + this.grouperProvisioner.retrieveGrouperProvisioningTargetDaoAdapter().insertGroups(new TargetDaoInsertGroupsRequest(grouperTargetGroupsToInsert)); + } catch (RuntimeException re) { + runtimeException = re; + } finally { + try { + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsInsertGroups(grouperTargetGroupsToInsert, false); + + } catch (RuntimeException e) { + GrouperUtil.exceptionFinallyInjectOrThrow(runtimeException, e); + } + } + + List targetGroups = null; + if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectGroups()) { + //retrieve so we have a copy + TargetDaoRetrieveGroupsResponse targetDaoRetrieveGroupsResponse = + this.grouperProvisioner.retrieveGrouperProvisioningTargetDaoAdapter().retrieveGroups(new TargetDaoRetrieveGroupsRequest(grouperTargetGroupsToInsert, true)); + + targetGroups = GrouperUtil.nonNull(targetDaoRetrieveGroupsResponse == null ? null : targetDaoRetrieveGroupsResponse.getTargetGroups()); + + if (GrouperUtil.length(grouperTargetGroupsToInsert) != GrouperUtil.length(targetGroups)) { + // maybe this should be an exception??? + throw new RuntimeException("Searched for " + GrouperUtil.length(grouperTargetGroupsToInsert) + " but retrieved " + GrouperUtil.length(targetGroups) + " maybe a config is off?"); + } + + registerRetrievedGroups(grouperTargetGroupsToInsert, targetGroups); + + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterGroupFieldsAndAttributes(targetGroups, true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesGroups(targetGroups); + + // index + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups(targetGroups); + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdGroups(); + + this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjectsMissingCreated().setProvisioningGroups(targetGroups); + + } + + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingTargetGroupsCreated); + + if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectGroups()) { + Map matchingIdToProvisioningGroupWrapper = grouperProvisioner.retrieveGrouperProvisioningDataIndex().getGroupMatchingIdToProvisioningGroupWrapper(); + + // match these up with retrieved groups + // set these in the wrapper so they are linked with grouper group + for (ProvisioningGroup targetGroup : GrouperUtil.nonNull(targetGroups)) { + + // look up the grouper group that looked this up + ProvisioningGroupWrapper provisioningGroupWrapper = matchingIdToProvisioningGroupWrapper.get(targetGroup.getMatchingId()); + + // not sure why it wouldnt match or exist... + provisioningGroupWrapper.setTargetProvisioningGroup(targetGroup); + + // this is already created! :) + provisioningGroupWrapper.setCreate(false); + } + } + + } + + //TODO duplicate method in the translator. Try to merge to have only one copy. + public void translateAndManipulateMembershipsForGroupsEntitiesCreate() { + if (!this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().isCreateGroupsAndEntitiesBeforeTranslatingMemberships()) { + + Map debugMap = this.getGrouperProvisioner().getDebugMap(); + + try { + debugMap.put("state", "translateGrouperMembershipsToTarget"); + { + List grouperProvisioningMemberships = new ArrayList(this.getGrouperProvisioner(). + retrieveGrouperProvisioningData().retrieveGrouperProvisioningMemberships(true)); + + List grouperTargetMemberships = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetMemberships( + grouperProvisioningMemberships, false); + this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouperTarget().getGrouperTargetObjects().setProvisioningMemberships(grouperTargetMemberships); + } + + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.translateGrouperMembershipsToTarget); + } + + try { + debugMap.put("state", "manipulateGrouperMembershipTargetAttributes"); + List grouperTargetMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(true); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForMemberships(grouperTargetMemberships); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterMembershipFieldsAndAttributes(grouperTargetMemberships, true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesMemberships(grouperTargetMemberships); + + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.manipulateGrouperTargetMembershipsAttributes); + } + + try { + debugMap.put("state", "matchingIdGrouperMemberships"); + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetMemberships(this.getGrouperProvisioner().retrieveGrouperProvisioningData().retrieveGrouperTargetMemberships(true)); + } finally { + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.matchingIdGrouperMemberships); + } + + // index the memberships + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdMemberships(); + + } + } + + /** + * + * @param grouperTargetGroups + * @param targetProvisioningGroups + */ + public void registerRetrievedGroups( + List grouperTargetGroups, + List targetProvisioningGroups) { + + GrouperProvisioningConfigurationAttribute searchAttribute = null; + + // TODO handle multiple search attributes + if (GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupSearchAttributes()) > 0) { + searchAttribute = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupSearchAttributes().get(0); + } + + if (searchAttribute == null) { + throw new RuntimeException("Identify a group search attribute!"); + } + + Map searchAttributeValueToGrouperTargetGroup = new HashMap(); + + // index by search attribute + for (ProvisioningGroup grouperTargetGroup : GrouperUtil.nonNull(grouperTargetGroups)) { + Object searchAttributeValue = grouperTargetGroup.retrieveAttributeValue(searchAttribute); + if (searchAttributeValue != null) { + searchAttributeValueToGrouperTargetGroup.put(searchAttributeValue, grouperTargetGroup); + } + } + + for (ProvisioningGroup targetProvisioningGroup : GrouperUtil.nonNull(targetProvisioningGroups)) { + Object searchAttributeValue = targetProvisioningGroup.retrieveAttributeValue(searchAttribute); + if (searchAttributeValue != null) { + ProvisioningGroup grouperTargetGroup = searchAttributeValueToGrouperTargetGroup.get(searchAttributeValue); + if (grouperTargetGroup != null) { + ProvisioningGroupWrapper provisioningGroupWrapper = grouperTargetGroup.getProvisioningGroupWrapper(); + if (provisioningGroupWrapper != null) { + targetProvisioningGroup.setProvisioningGroupWrapper(provisioningGroupWrapper); + provisioningGroupWrapper.setTargetProvisioningGroup(targetProvisioningGroup); + } + } + } + } + } + + /** + * + * @param grouperTargetEntitiesToInsert + * @param targetProvisioningEntities + */ + public void registerRetrievedEntities( + List grouperTargetEntities, + List targetProvisioningEntities) { + + GrouperProvisioningConfigurationAttribute searchAttribute = null; + + // TODO handle multiple search attributes + if (GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntitySearchAttributes()) > 0) { + searchAttribute = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntitySearchAttributes().get(0); + } + + if (searchAttribute == null) { + throw new RuntimeException("Identify an entity search attribute!"); + } + + Map searchAttributeValueToGrouperTargetEntity = new HashMap(); + + // index by search attribute + for (ProvisioningEntity grouperTargetEntity : GrouperUtil.nonNull(grouperTargetEntities)) { + Object searchAttributeValue = grouperTargetEntity.retrieveAttributeValue(searchAttribute); + if (searchAttributeValue != null) { + searchAttributeValueToGrouperTargetEntity.put(searchAttributeValue, grouperTargetEntity); + } + } + + for (ProvisioningEntity targetProvisioningEntity : GrouperUtil.nonNull(targetProvisioningEntities)) { + Object searchAttributeValue = targetProvisioningEntity.retrieveAttributeValue(searchAttribute); + if (searchAttributeValue != null) { + ProvisioningEntity grouperTargetEntity = searchAttributeValueToGrouperTargetEntity.get(searchAttributeValue); + if (grouperTargetEntity != null) { + ProvisioningEntityWrapper provisioningEntityWrapper = grouperTargetEntity.getProvisioningEntityWrapper(); + if (provisioningEntityWrapper != null) { + targetProvisioningEntity.setProvisioningEntityWrapper(provisioningEntityWrapper); + provisioningEntityWrapper.setTargetProvisioningEntity(targetProvisioningEntity); + } + } + } + } + } + + + public void createMissingEntitiesFull() { + // first lets see if we should even be doing this + if (!GrouperUtil.booleanValue(this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isInsertEntities(), false)) { + return; + } + + + //do we have missing entities? + List missingEntities = new ArrayList(); + List missingEntityWrappers = new ArrayList(); + for (ProvisioningEntityWrapper provisioningEntityWrapper : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningEntityWrappers())) { + + ProvisioningEntity provisioningEntity = provisioningEntityWrapper.getGrouperProvisioningEntity(); + + if (provisioningEntity == null || !provisioningEntityWrapper.isRecalc() || provisioningEntityWrapper.isDelete()) { + continue; + } + + // shouldnt be null at this point + GcGrouperSyncMember gcGrouperSyncMember = provisioningEntityWrapper.getGcGrouperSyncMember(); + + if (!gcGrouperSyncMember.isProvisionable()) { + continue; + } + ProvisioningEntity targetEntity = provisioningEntityWrapper.getTargetProvisioningEntity(); + + if (targetEntity != null) { + continue; + } + + missingEntities.add(provisioningEntity); + missingEntityWrappers.add(provisioningEntityWrapper); + } + if (GrouperUtil.length(missingEntities) == 0) { + return; + } + + // how many do we have + this.grouperProvisioner.getDebugMap().put("missingEntitiesForCreate", GrouperUtil.length(missingEntities)); + + this.grouperProvisioner.retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjectsMissing().setProvisioningEntities(missingEntities); + // log this + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingEntitiesForCreate); + + // translate + List grouperTargetEntitiesToInsert = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetEntities(missingEntities, false, true); + + if (GrouperUtil.length(grouperTargetEntitiesToInsert) == 0) { + this.grouperProvisioner.getDebugMap().put("groupTranslationEndedInNoEntitiesOnInsert", true); + return; + } + + + translateAndManipulateMembershipsForGroupsEntitiesCreate(); + + + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().assignDefaultsForEntities(grouperTargetEntitiesToInsert, null); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes(grouperTargetEntitiesToInsert, false, true, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities(grouperTargetEntitiesToInsert); + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetEntities(grouperTargetEntitiesToInsert); + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdEntities(); + this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getGrouperTargetObjectsMissing().setProvisioningEntities(grouperTargetEntitiesToInsert); + // validate + this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validateEntities(grouperTargetEntitiesToInsert, true, null); + // add object change entries + this.grouperProvisioner.retrieveGrouperProvisioningCompare().addInternalObjectChangeForEntitiesToInsert(grouperTargetEntitiesToInsert); + + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingGrouperTargetEntitiesForCreate); + //lets create these + RuntimeException runtimeException = null; + try { + this.grouperProvisioner.retrieveGrouperProvisioningTargetDaoAdapter().insertEntities(new TargetDaoInsertEntitiesRequest(grouperTargetEntitiesToInsert)); + } catch (RuntimeException re) { + runtimeException = re; + } finally { + try { + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().processResultsInsertEntities(grouperTargetEntitiesToInsert, false); + + } catch (RuntimeException e) { + GrouperUtil.exceptionFinallyInjectOrThrow(runtimeException, e); + } + } + + List targetEntities = null; + if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectEntities()) { + //retrieve so we have a copy + TargetDaoRetrieveEntitiesResponse targetDaoRetrieveEntitiesResponse = + this.grouperProvisioner.retrieveGrouperProvisioningTargetDaoAdapter().retrieveEntities(new TargetDaoRetrieveEntitiesRequest(grouperTargetEntitiesToInsert, false)); + + targetEntities = GrouperUtil.nonNull(targetDaoRetrieveEntitiesResponse == null ? null : targetDaoRetrieveEntitiesResponse.getTargetEntities()); + + if (GrouperUtil.length(grouperTargetEntitiesToInsert) != GrouperUtil.length(targetEntities)) { + // maybe this should be an exception??? + throw new RuntimeException("Searched for " + GrouperUtil.length(grouperTargetEntitiesToInsert) + " but retrieved " + GrouperUtil.length(targetEntities) + " maybe a config is off?"); + } + + registerRetrievedEntities(grouperTargetEntitiesToInsert, targetEntities); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().filterEntityFieldsAndAttributes(targetEntities, true, false, false); + this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateAttributesEntities(targetEntities); + // index + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetEntities(targetEntities); + this.grouperProvisioner.retrieveGrouperProvisioningMatchingIdIndex().indexMatchingIdEntities(); + this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjectsMissingCreated().setProvisioningEntities(targetEntities); + } + + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingTargetEntitiesCreated); + + if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectEntities()) { + Map matchingIdToProvisioningEntityWrapper = grouperProvisioner.retrieveGrouperProvisioningDataIndex().getEntityMatchingIdToProvisioningEntityWrapper(); + + // match these up with retrieved entities + // set these in the wrapper so they are linked with grouper entity + for (ProvisioningEntity targetEntity : GrouperUtil.nonNull(targetEntities)) { + + // look up the grouper group that looked this up + ProvisioningEntityWrapper provisioningEntityWrapper = matchingIdToProvisioningEntityWrapper.get(targetEntity.getMatchingId()); + + // not sure why it wouldnt match or exist... + provisioningEntityWrapper.setTargetProvisioningEntity(targetEntity); + // this is already created! :) + provisioningEntityWrapper.setCreate(false); + } + } + + } + + /** + * retrieve all data from both sides, grouper and target, do this in a thread + */ + public void retrieveAllData() { + + final RuntimeException[] RUNTIME_EXCEPTION = new RuntimeException[1]; + + Thread targetQueryThread = new Thread(new Runnable() { + + @Override + public void run() { + + try { + TargetDaoRetrieveAllDataResponse targetDaoRetrieveAllDataResponse + = GrouperProvisioningLogic.this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter() + .retrieveAllData(new TargetDaoRetrieveAllDataRequest()); + // retrieve all the target data and put in GrouperProvisioningDataTarget + GrouperProvisioningLists targetData = targetDaoRetrieveAllDataResponse.getTargetData(); + GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningDataTarget() + .setTargetProvisioningObjects(targetData); + + // get the total count of what is in the target + int totalTargetCount = 0; + if (targetData != null) { + + GrouperProvisioningLogic.this.grouperProvisioner.getDebugMap().put("originalTargetGroupCount", GrouperUtil.length(targetData.getProvisioningGroups())); + GrouperProvisioningLogic.this.grouperProvisioner.getDebugMap().put("originalTargetEntityCount", GrouperUtil.length(targetData.getProvisioningEntities())); + + totalTargetCount += GrouperUtil.length(targetData.getProvisioningEntities()) + + GrouperUtil.length(targetData.getProvisioningGroups()); + + int originalTargetMembershipCount = GrouperUtil.length(targetData.getProvisioningMemberships()); + + String membershipAttribute = GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getAttributeNameForMemberships(); + if (!StringUtils.isBlank(membershipAttribute)) { + if (GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() + == GrouperProvisioningBehaviorMembershipType.groupAttributes) { + + for (ProvisioningGroup provisioningGroup : GrouperUtil.nonNull(targetData.getProvisioningGroups())) { + originalTargetMembershipCount += GrouperUtil.length(provisioningGroup.retrieveAttributeValueSet(membershipAttribute)); + } + } + if (GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() + == GrouperProvisioningBehaviorMembershipType.entityAttributes) { + + for (ProvisioningEntity provisioningEntity : GrouperUtil.nonNull(targetData.getProvisioningEntities())) { + originalTargetMembershipCount += GrouperUtil.length(provisioningEntity.retrieveAttributeValueSet(membershipAttribute)); + } + } + } + totalTargetCount += originalTargetMembershipCount; + GrouperProvisioningLogic.this.grouperProvisioner.getDebugMap().put("originalTargetMembershipCount", originalTargetMembershipCount); + } + + GrouperProvisioningLogic.this.grouperProvisioner.getDebugMap().put("originalTargetTotalCount", totalTargetCount); + + + } catch (RuntimeException re) { + LOG.error("error querying target: " + GrouperProvisioningLogic.this.getGrouperProvisioner().getConfigId(), re); + RUNTIME_EXCEPTION[0] = re; + } + + } + }); + + targetQueryThread.start(); + + retrieveGrouperDataFull(); + + enhanceEntityAttributesWithSqlResolver(true); + + enhanceEntityAttributesWithLdapResolver(); + + GrouperClientUtils.join(targetQueryThread); + if (RUNTIME_EXCEPTION[0] != null) { + throw RUNTIME_EXCEPTION[0]; + } + + retrieveAllTargetAndGrouperDataPost(); + + processTargetWrappers(); + + } + + public void enhanceEntityAttributesWithSqlResolver(boolean isFullSync) { + + GrouperProvisioningConfiguration provisioningConfiguration = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration(); + + if (!provisioningConfiguration.isResolveAttributesWithSql()) { + return; + } + + String dbConnectionName = null; + String grouperAttributeThatMatchesRow = null; + String subjectSearchMatchingColumn = null; + String subjectSourceIdColumn = null; + String tableOrViewName = null; + String expression = null; + String commaSeparatedColumns = null; + String lastUpdatedColumn = null; + String lastUpdatedColumnType = null; + + String globalSqlResolver = provisioningConfiguration.getGlobalSqlResolver(); + + if (StringUtils.isNotBlank(globalSqlResolver)) { + + boolean isEnabled = GrouperConfig.retrieveConfig().propertyValueBoolean("entityAttributeResolver."+globalSqlResolver+".enabled", true); + + if (!isEnabled) { + return; + } + + dbConnectionName = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalSqlResolver+".sqlConfigId"); + + grouperAttributeThatMatchesRow = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalSqlResolver+".grouperAttributeThatMatchesRow"); + + subjectSearchMatchingColumn = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalSqlResolver+".subjectSearchMatchingColumn"); + + tableOrViewName = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalSqlResolver+".tableOrViewName"); + + commaSeparatedColumns = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalSqlResolver+".columnNames"); + + subjectSourceIdColumn = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalSqlResolver+".subjectSourceIdColumn"); + + lastUpdatedColumn = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalSqlResolver+".lastUpdatedColumn"); + + lastUpdatedColumnType = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalSqlResolver+".lastUpdatedType"); + + } else { + + dbConnectionName = provisioningConfiguration.getEntityAttributesSqlExternalSystem(); + + grouperAttributeThatMatchesRow = provisioningConfiguration.getEntityAttributesSqlMappingEntityAttribute(); + + subjectSearchMatchingColumn = provisioningConfiguration.getEntityAttributesSubjectSearchMatchingColumn(); + + tableOrViewName = provisioningConfiguration.getEntityAttributesTableViewName(); + + commaSeparatedColumns = provisioningConfiguration.getEntityAttributesColumnNames(); + + subjectSourceIdColumn = provisioningConfiguration.getEntityAttributesSubjectSourceIdColumn(); + + expression = provisioningConfiguration.getEntityAttributesSqlMappingExpression(); + + lastUpdatedColumn = provisioningConfiguration.getEntityAttributesLastUpdatedColumn(); + + lastUpdatedColumnType = provisioningConfiguration.getEntityAttributesLastUpdatedType(); + + } + + Set columnsWhichAreAttributes = GrouperUtil.splitTrimToSet(commaSeparatedColumns, ","); + + Set columnNamesToFetch = GrouperUtil.splitTrimToSet(commaSeparatedColumns, ","); + + if (StringUtils.isNotBlank(lastUpdatedColumn) && !columnNamesToFetch.contains(lastUpdatedColumn.trim())) { + columnNamesToFetch.add(lastUpdatedColumn.trim()); + } + + if (!columnNamesToFetch.contains(subjectSearchMatchingColumn.trim())) { + columnNamesToFetch.add(subjectSearchMatchingColumn.trim()); + } + + String commaSeparatedColNames = GrouperUtil.setToString(columnNamesToFetch); + + boolean selectAllSqlOnFull = provisioningConfiguration.isSelectAllSqlOnFull(); + + GrouperProvisioningLists grouperProvisioningObjects = + this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects(); + + List provisioningEntities = grouperProvisioningObjects.getProvisioningEntities(); + + StringBuilder sqlInitial = new StringBuilder("select "); + sqlInitial.append(commaSeparatedColNames); + sqlInitial.append(" from "); + sqlInitial.append(tableOrViewName); + + List attributesFromTable = new ArrayList(); + + if ( (isFullSync && !selectAllSqlOnFull) || !isFullSync) { + if (provisioningEntities.size() == 0) { + return; + } + + int numberOfBatches = GrouperUtil.batchNumberOfBatches(provisioningEntities.size(), 900); + + Map elVariableMap = new HashMap(); + + for (int i = 0; i < numberOfBatches; i++) { + + List currentBatchProvisioningEntities = GrouperUtil.batchList(provisioningEntities, 900, i); + StringBuilder sql = new StringBuilder(sqlInitial); + + sql.append(" where "+ subjectSearchMatchingColumn + " in ( "); + + GcDbAccess gcDbAccess = new GcDbAccess().connectionName(dbConnectionName); + + for (int j=0; j0) { + sql.append(","); + } + sql.append("?"); + } + sql.append(" ) "); + attributesFromTable.addAll(gcDbAccess.sql(sql.toString()).selectList(Object[].class)); + + } + } else { + attributesFromTable.addAll(new GcDbAccess().connectionName(dbConnectionName).sql(sqlInitial.toString()).selectList(Object[].class)); + } + + String[] colNamesFromAttributesTable = GrouperUtil.splitTrim(commaSeparatedColNames, ","); + + Map subjectSearchMatchingColumnToAttributes = new HashMap(); + + int indexOfSubjectSearchMatchingColumn = GrouperUtil.indexOf(colNamesFromAttributesTable, subjectSearchMatchingColumn); + + for (Object[] oneRowOfAttributes: attributesFromTable) { + Object subjectSearchMatchingValue = oneRowOfAttributes[indexOfSubjectSearchMatchingColumn]; + if (subjectSearchMatchingValue != null) { + + String subjectSearchMatchingValueString = GrouperUtil.stringValue(subjectSearchMatchingValue); + + MultiKey identifier = null; + if (StringUtils.isNotBlank(subjectSourceIdColumn)) { + identifier = new MultiKey(subjectSearchMatchingValueString, subjectSourceIdColumn); + } else { + identifier = new MultiKey(new String[] {subjectSearchMatchingValueString}); + } + + subjectSearchMatchingColumnToAttributes.put(identifier, oneRowOfAttributes); + } + } + + /** + * subjectSearchMatchingColumnToAttributes looks like + * test.subject.0 -> [school0, description0,....] + */ + + Map elVariableMap = new HashMap(); + + for (ProvisioningEntity provisioningEntity: provisioningEntities) { + + String subjectMatchingIdentifier = null; + + if (StringUtils.isNotBlank(expression)) { + elVariableMap.clear(); + elVariableMap.put("grouperProvisioningEntity", provisioningEntity); + Object object = this.getGrouperProvisioner().retrieveGrouperProvisioningTranslator().runScript(expression, elVariableMap); + subjectMatchingIdentifier = GrouperUtil.stringValue(object); + } else if (StringUtils.equals(grouperAttributeThatMatchesRow, "subjectId")) { + subjectMatchingIdentifier = provisioningEntity.getSubjectId(); + } else if (StringUtils.equals(grouperAttributeThatMatchesRow, "subjectIdentifier0")) { + subjectMatchingIdentifier = (String)provisioningEntity.retrieveAttributeValueString("subjectIdentifier0"); + } else { + throw new RuntimeException("invalid grouperAttributeThatMatchesRow: "+grouperAttributeThatMatchesRow + " expected 'subjectId' or 'subjectIdentifier0'"); + } + + MultiKey identifier = null; + if (StringUtils.isNotBlank(subjectSourceIdColumn)) { + String subjectSourceIdFromProvisioningEntity = provisioningEntity.retrieveAttributeValueString("subjectSourceId"); + identifier = new MultiKey(subjectMatchingIdentifier, subjectSourceIdFromProvisioningEntity); + } else { + identifier = new MultiKey(new String[] {subjectMatchingIdentifier}); + } + + Object[] attributeValues = subjectSearchMatchingColumnToAttributes.get(identifier); + if (attributeValues != null) { + int i = 0; + for (String attributeName: colNamesFromAttributesTable) { + + if (columnsWhichAreAttributes.contains(attributeName)) { + + provisioningEntity.assignAttributeValue("entityAttributeResolverSql__"+attributeName.toLowerCase(), attributeValues[i]); + } + + i++; + + } + } + + } + + } + + public void enhanceEntityAttributesWithLdapResolver() { + + GrouperProvisioningConfiguration provisioningConfiguration = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration(); + + if (!provisioningConfiguration.isResolveAttributesWithLdap()) { + return; + } + + GrouperProvisioningLists grouperProvisioningObjects = this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects(); + + List provisioningEntities = grouperProvisioningObjects.getProvisioningEntities(); + + String globalLdapResolver = provisioningConfiguration.getGlobalLdapResolver(); + + String ldapConfigId = null; + String baseDn = null; + String searchScope = null; + String ldapAttributes = null; + String subjectSearchMatchingAttribute = null; + String subjectSourceId = null; + String grouperAttributeThatMatchesRecord = null; + String filterPart = null; + String lastUpdatedAttribute = null; + String multiValuedLdapAttributes = null; + String expression = null; + String lastUpdatedAttributeFormat = null; + boolean filterAllLdapOnFull = true; + + if (StringUtils.isNotBlank(globalLdapResolver)) { + + boolean isEnabled = GrouperConfig.retrieveConfig().propertyValueBoolean("entityAttributeResolver."+globalLdapResolver+".enabled", true); + + if (!isEnabled) { + return; + } + + ldapConfigId = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalLdapResolver+".ldapConfigId"); + baseDn = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalLdapResolver+".baseDn"); + subjectSourceId = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalLdapResolver+".subjectSourceId"); + searchScope = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalLdapResolver+".searchScope"); + ldapAttributes = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalLdapResolver+".ldapAttributes"); + subjectSearchMatchingAttribute = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalLdapResolver+".subjectSearchMatchingAttribute"); + grouperAttributeThatMatchesRecord = GrouperConfig.retrieveConfig().propertyValueStringRequired("entityAttributeResolver."+globalLdapResolver+".grouperAttributeThatMatchesRecord"); + filterPart = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalLdapResolver+".filterPart"); + lastUpdatedAttribute = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalLdapResolver+".lastUpdatedAttribute"); + lastUpdatedAttributeFormat = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalLdapResolver+".ldapLastUpdatedFormat"); + multiValuedLdapAttributes = GrouperConfig.retrieveConfig().propertyValueString("entityAttributeResolver."+globalLdapResolver+".multiValuedLdapAttributes"); + + } else { + + ldapConfigId = provisioningConfiguration.getEntityAttributesLdapExternalSystem(); + baseDn = provisioningConfiguration.getEntityAttributesLdapBaseDn(); + subjectSourceId = provisioningConfiguration.getEntityAttributesLdapSubjectSource(); + searchScope = provisioningConfiguration.getEntityAttributesLdapSearchScope(); + ldapAttributes = provisioningConfiguration.getEntityAttributesLdapAttributes(); + subjectSearchMatchingAttribute = provisioningConfiguration.getEntityAttributesLdapMatchingSearchAttribute(); + grouperAttributeThatMatchesRecord = provisioningConfiguration.getEntityAttributesLdapMappingEntityAttribute(); + filterPart = provisioningConfiguration.getEntityAttributesLdapFilterPart(); + lastUpdatedAttribute = provisioningConfiguration.getEntityAttributesLdapLastUpdatedAttribute(); + lastUpdatedAttributeFormat = provisioningConfiguration.getEntityAttributesLdapLastUpdatedAttributeFormat(); + expression = provisioningConfiguration.getEntityAttributesLdapMatchingExpression(); + } + + List ldapEntries = new ArrayList(); + + filterAllLdapOnFull = provisioningConfiguration.isFilterAllLDAPOnFull(); + + Set ldapAttributesSet = GrouperUtil.splitTrimToSet(ldapAttributes, ","); + + Set multiValuedAttributesSet = GrouperUtil.nonNull(GrouperUtil.splitTrimToSet(multiValuedLdapAttributes, ",")); + + if (StringUtils.isNotBlank(multiValuedLdapAttributes)) { + ldapAttributesSet.addAll(multiValuedAttributesSet); + } + + if (StringUtils.isNotBlank(subjectSearchMatchingAttribute)) { + ldapAttributesSet.add(subjectSearchMatchingAttribute); + } + + String[] ldapAttributesArray = GrouperUtil.toArray(ldapAttributesSet, String.class); + + LdapSearchScope ldapSearchScope = LdapSearchScope.valueOfIgnoreCase(searchScope, true); + + if (!filterAllLdapOnFull) { + + if (provisioningEntities.size() == 0) { + return; + } + + int numberOfBatches = GrouperUtil.batchNumberOfBatches(provisioningEntities.size(), 900); + + Map elVariableMap = new HashMap(); + + for (int i = 0; i < numberOfBatches; i++) { + + List currentBatchProvisioningEntities = GrouperUtil.batchList(provisioningEntities, 900, i); + + String filter = null; + if (StringUtils.isNotBlank(filterPart)) { + filter = "(&"; + filterPart = filterPart.trim(); + if (filterPart.startsWith("(")) { + filter += filterPart; + } else { + filter += "(" + filterPart + ")"; + } + } else { + filter = "(|"; + } + + + for (int j=0; j identifierToLdapEntry = new HashMap(); + + for (LdapEntry ldapEntry: GrouperUtil.nonNull(ldapEntries)) { + + LdapAttribute attribute = ldapEntry.getAttribute(subjectSearchMatchingAttribute); + if (attribute != null) { + + Collection stringValues = attribute.getStringValues(); + if (GrouperUtil.length(stringValues) == 1) { + + MultiKey identifier = null; + if (StringUtils.isNotBlank(subjectSourceId)) { + identifier = new MultiKey(stringValues.iterator().next(), subjectSourceId); + } else { + identifier = new MultiKey(new String[] {stringValues.iterator().next()}); + } + identifierToLdapEntry.put(identifier, ldapEntry); + } + } + } + + Map elVariableMap = new HashMap(); + + for (ProvisioningEntity provisioningEntity: provisioningEntities) { + + String subjectMatchingIdentifier = null; + if (StringUtils.isNotBlank(expression)) { + elVariableMap.clear(); + elVariableMap.put("grouperProvisioningEntity", provisioningEntity); + Object object = this.getGrouperProvisioner().retrieveGrouperProvisioningTranslator().runScript(expression, elVariableMap); + subjectMatchingIdentifier = GrouperUtil.stringValue(object); + } else if (StringUtils.equals(grouperAttributeThatMatchesRecord, "subjectId")) { + subjectMatchingIdentifier = provisioningEntity.getSubjectId(); + } + else if (StringUtils.equals(grouperAttributeThatMatchesRecord, "subjectIdentifier0")) { + subjectMatchingIdentifier = (String)provisioningEntity.retrieveAttributeValueString("subjectIdentifier0"); + } else { + throw new RuntimeException("invalid grouperAttributeThatMatchesRecord: "+grouperAttributeThatMatchesRecord + " expected 'subjectId' or 'subjectIdentifier0'"); + } + + MultiKey identifier = null; + if (StringUtils.isNotBlank(subjectSourceId)) { + String subjectSourceIdFromProvisioningEntity = provisioningEntity.retrieveAttributeValueString("subjectSourceId"); + identifier = new MultiKey(subjectMatchingIdentifier, subjectSourceIdFromProvisioningEntity); + } else { + identifier = new MultiKey(new String[] {subjectMatchingIdentifier}); + } + + LdapEntry ldapEntry = identifierToLdapEntry.get(identifier); + if (ldapEntry != null) { + + for (String ldapAttributeName: ldapAttributesArray) { + + if (StringUtils.equals(ldapAttributeName, "lastUpdatedAttribute")) { + continue; + } + + LdapAttribute attribute = ldapEntry.getAttribute(ldapAttributeName); + if (attribute != null) { + + if (multiValuedAttributesSet.contains(attribute.getName())) { + + for ( String attributeValue: GrouperUtil.nonNull(attribute.getStringValues())) { + provisioningEntity.addAttributeValue("entityAttributeResolverLdap__"+attribute.getName().toLowerCase(), attributeValue); + } + + } else { + + if (GrouperUtil.length(attribute.getStringValues()) == 0) { + continue; + } + + if (GrouperUtil.length(attribute.getStringValues()) == 1) { + provisioningEntity.assignAttributeValue("entityAttributeResolverLdap__"+attribute.getName().toLowerCase(), attribute.getStringValues().iterator().next()); + } else { + + String concatenatedAttributeValues = GrouperUtil.join(attribute.getStringValues().iterator(), ","); + provisioningEntity.assignAttributeValue("entityAttributeResolverLdap__"+attribute.getName().toLowerCase(), concatenatedAttributeValues); + + } + + + } + + } + } + + } + + } + + } + + /** + * override this method to do some logic after all grouper and target data is retrieved (e.g. if there are DN overrides) + */ + public void retrieveAllTargetAndGrouperDataPost() { + + + } + + /** + * take target data and add wrapper and add to data store + */ + public void processTargetWrappers() { + + Set provisioningGroupWrappers = this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningGroupWrappers(); + + // add wrappers for all groups + for (ProvisioningGroup targetProvisioningGroup : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningGroups())) { + ProvisioningGroupWrapper provisioningGroupWrapper = new ProvisioningGroupWrapper(); + provisioningGroupWrapper.setGrouperProvisioner(this.grouperProvisioner); + provisioningGroupWrappers.add(provisioningGroupWrapper); + + provisioningGroupWrapper.setTargetProvisioningGroup(targetProvisioningGroup); + } + + + Set provisioningEntityWrappers = this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningEntityWrappers(); + + // add wrappers for all groups + for (ProvisioningEntity targetProvisioningEntity : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningEntities())) { + ProvisioningEntityWrapper provisioningEntityWrapper = new ProvisioningEntityWrapper(); + provisioningEntityWrapper.setGrouperProvisioner(this.grouperProvisioner); + provisioningEntityWrappers.add(provisioningEntityWrapper); + + provisioningEntityWrapper.setTargetProvisioningEntity(targetProvisioningEntity); + } + + Set provisioningMembershipWrappers = this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningMembershipWrappers(); + + // add wrappers for all groups + for (ProvisioningMembership targetProvisioningMembership : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjects().getProvisioningMemberships())) { + ProvisioningMembershipWrapper provisioningMembershipWrapper = new ProvisioningMembershipWrapper(); + provisioningMembershipWrapper.setGrouperProvisioner(this.grouperProvisioner); + provisioningMembershipWrappers.add(provisioningMembershipWrapper); + + provisioningMembershipWrapper.setTargetProvisioningMembership(targetProvisioningMembership); + } + + } + + public void retrieveGrouperDataFull() { + + // get all grouper data for the provisioner + // and put in GrouperProvisioningDataSyncGrouper + this.grouperProvisioner.retrieveGrouperDao().retrieveGrouperDataFull(); + + // put wrappers on the grouper objects and put in the grouper uuid maps in data object + // put these wrapper in the GrouperProvisioningData and GrouperProvisioningDataIndex + this.grouperProvisioner.retrieveGrouperDao().processWrappers(); + + // point the membership pointers to groups and entities to what they should point to + // and fix data problems (for instance race conditions as data was retrieved) + this.grouperProvisioner.retrieveGrouperDao().fixGrouperProvisioningMembershipReferences(); + + // add / update / delete sync objects based on grouper data + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().fixSyncObjects(); + + // put the sync objects in their respective wrapper objects + // this is where additional wrapper objects can be added + assignSyncObjectsToWrappers(); + + // incrementals need to consult sync objects to know what to delete + calculateProvisioningDataToDelete(); + + GcGrouperSync gcGrouperSync = this.grouperProvisioner.getGcGrouperSync(); + gcGrouperSync.setGroupCount(GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects().getProvisioningGroups())); + gcGrouperSync.setUserCount(GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects().getProvisioningEntities())); + gcGrouperSync.setRecordsCount( + GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects().getProvisioningEntities()) + + GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects().getProvisioningGroups()) + + GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjects().getProvisioningMemberships()) + ); + + } + + + public void assignSyncObjectsToWrappers() { + + Map grouperSyncGroupIdToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncGroupIdToProvisioningGroupWrapper(); + assignSyncObjectsToWrappersGroups(grouperSyncGroupIdToProvisioningGroupWrapper); + + Map grouperSyncMemberIdToProvisioningEntityWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncMemberIdToProvisioningEntityWrapper(); + assignSyncObjectsToWrappersMembers(grouperSyncMemberIdToProvisioningEntityWrapper); + + Map groupUuidMemberUuidToProvisioningMembershipWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupUuidMemberUuidToProvisioningMembershipWrapper(); + assignSyncObjectsToWrappersMemberships(grouperSyncGroupIdToProvisioningGroupWrapper, + grouperSyncMemberIdToProvisioningEntityWrapper, + groupUuidMemberUuidToProvisioningMembershipWrapper); + } + + public void assignSyncObjectsToWrappersMemberships( + Map grouperSyncGroupIdToProvisioningGroupWrapper, + Map grouperSyncMemberIdToProvisioningEntityWrapper, + Map grouperSyncGroupIdGrouperSyncMemberIdToProvisioningMembershipWrapper) { + { + + List gcGrouperSyncMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningDataSync().getGcGrouperSyncMemberships(); + + Map groupUuidMemberUuidToProvisioningMembershipWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupUuidMemberUuidToProvisioningMembershipWrapper(); + + if (GrouperUtil.length(gcGrouperSyncMemberships) > 0) { + + int syncMembershipReferenceMissing = 0; + + for (GcGrouperSyncMembership gcGrouperSyncMembership : gcGrouperSyncMemberships) { + + // data is not consistent just ignore for now + ProvisioningGroupWrapper provisioningGroupWrapper = grouperSyncGroupIdToProvisioningGroupWrapper.get(gcGrouperSyncMembership.getGrouperSyncGroupId()); + if (provisioningGroupWrapper == null) { + syncMembershipReferenceMissing++; + continue; + } + GcGrouperSyncGroup gcGrouperSyncGroup = provisioningGroupWrapper.getGcGrouperSyncGroup(); + + ProvisioningEntityWrapper provisioningEntityWrapper = grouperSyncMemberIdToProvisioningEntityWrapper.get(gcGrouperSyncMembership.getGrouperSyncMemberId()); + if (provisioningEntityWrapper == null) { + syncMembershipReferenceMissing++; + continue; + } + GcGrouperSyncMember gcGrouperSyncMember = provisioningEntityWrapper.getGcGrouperSyncMember(); + + MultiKey groupIdMemberId = new MultiKey(gcGrouperSyncGroup.getGroupId(), + gcGrouperSyncMember.getMemberId()); + + ProvisioningMembershipWrapper provisioningMembershipWrapper = groupUuidMemberUuidToProvisioningMembershipWrapper.get(groupIdMemberId); + + if (provisioningMembershipWrapper == null) { + provisioningMembershipWrapper = new ProvisioningMembershipWrapper(); + provisioningMembershipWrapper.setGrouperProvisioner(this.grouperProvisioner); + groupUuidMemberUuidToProvisioningMembershipWrapper.put(groupIdMemberId, provisioningMembershipWrapper); + this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningMembershipWrappers().add(provisioningMembershipWrapper); + } + + provisioningMembershipWrapper.setGcGrouperSyncMembership(gcGrouperSyncMembership); + + MultiKey syncGroupIdSyncMemberId = new MultiKey(gcGrouperSyncMembership.getGrouperSyncGroupId(), gcGrouperSyncMembership.getGrouperSyncMemberId()); + provisioningMembershipWrapper.setSyncGroupIdSyncMemberId(syncGroupIdSyncMemberId); + grouperSyncGroupIdGrouperSyncMemberIdToProvisioningMembershipWrapper.put(syncGroupIdSyncMemberId, provisioningMembershipWrapper); + } + if (syncMembershipReferenceMissing > 0) { + this.getGrouperProvisioner().getDebugMap().put("syncMembershipReferenceMissing", syncMembershipReferenceMissing); + } + } + + } + } + + public void assignSyncObjectsToWrappersMembers( + Map grouperSyncMemberIdToProvisioningEntityWrapper) { + { + Map memberUuidToProvisioningEntityWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getMemberUuidToProvisioningEntityWrapper(); + + // loop through sync groups + for (GcGrouperSyncMember gcGrouperSyncMember : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningDataSync().getGcGrouperSyncMembers())) { + + ProvisioningEntityWrapper provisioningEntityWrapper = memberUuidToProvisioningEntityWrapper.get(gcGrouperSyncMember.getMemberId()); + + if (provisioningEntityWrapper == null) { + provisioningEntityWrapper = new ProvisioningEntityWrapper(); + provisioningEntityWrapper.setGrouperProvisioner(this.grouperProvisioner); + memberUuidToProvisioningEntityWrapper.put(gcGrouperSyncMember.getMemberId(), provisioningEntityWrapper); + this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningEntityWrappers().add(provisioningEntityWrapper); + } + provisioningEntityWrapper.setGcGrouperSyncMember(gcGrouperSyncMember); + + grouperSyncMemberIdToProvisioningEntityWrapper.put(gcGrouperSyncMember.getId(), provisioningEntityWrapper); + } + } + } + + public void assignSyncObjectsToWrappersGroups( + Map grouperSyncGroupIdToProvisioningGroupWrapper) { + { + Map groupUuidToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupUuidToProvisioningGroupWrapper(); + + // loop through sync groups + for (GcGrouperSyncGroup gcGrouperSyncGroup : GrouperUtil.nonNull(this.getGrouperProvisioner().retrieveGrouperProvisioningDataSync().getGcGrouperSyncGroups())) { + + ProvisioningGroupWrapper provisioningGroupWrapper = groupUuidToProvisioningGroupWrapper.get(gcGrouperSyncGroup.getGroupId()); + + if (provisioningGroupWrapper == null) { + provisioningGroupWrapper = new ProvisioningGroupWrapper(); + provisioningGroupWrapper.setGrouperProvisioner(this.grouperProvisioner); + groupUuidToProvisioningGroupWrapper.put(gcGrouperSyncGroup.getGroupId(), provisioningGroupWrapper); + this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningGroupWrappers().add(provisioningGroupWrapper); + } + provisioningGroupWrapper.setGcGrouperSyncGroup(gcGrouperSyncGroup); + + grouperSyncGroupIdToProvisioningGroupWrapper.put(gcGrouperSyncGroup.getId(), provisioningGroupWrapper); + } + } + } + + public void retrieveGrouperDataIncremental() { + + // get all grouper data for the provisioner + // and put in GrouperProvisioningDataGrouper + this.grouperProvisioner.retrieveGrouperDao().retrieveGrouperDataIncremental(); + + // put wrappers on the grouper objects and put in the grouper uuid maps in data object + // put these wrapper in the GrouperProvisioningData and GrouperProvisioningDataIndex + this.grouperProvisioner.retrieveGrouperDao().processWrappers(); + + // point the membership pointers to groups and entities to what they should point to + // and fix data problems (for instance race conditions as data was retrieved) + this.grouperProvisioner.retrieveGrouperDao().fixGrouperProvisioningMembershipReferences(); + +// // incrementals need to clone and setup sync objects as deletes +// this.getGrouperProvisioner().retrieveGrouperProvisioningLogicIncremental().setupIncrementalClonesOfGroupProvisioningObjects(); + + // add / update / delete sync objects based on grouper data + this.grouperProvisioner.retrieveGrouperProvisioningSyncDao().fixSyncObjects(); + + // put the sync objects in their respective wrapper objects + assignSyncObjectsToWrappers(); + + // incrementals need to consult sync objects to know what to delete + calculateProvisioningDataToDelete(); + + } + + protected void countInsertsUpdatesDeletes() { + countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.insert, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectInserts().getProvisioningGroups()); + countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.insert, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectInserts().getProvisioningEntities()); + countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.insert, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectInserts().getProvisioningMemberships()); + + { + //TODO: Is this correct? + //countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.replace, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectReplaces().getProvisioningMemberships()); + List targetMemberships = new ArrayList(); + + Collection> targetMembershipsLists = this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectReplaces().getProvisioningMemberships().values(); + for (List provisioningMemberships: targetMembershipsLists) { + targetMemberships.addAll(provisioningMemberships); + } + this.grouperProvisioner.retrieveGrouperProvisioningOutput().addReplace(GrouperUtil.length(targetMemberships)); + + } + + countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.insert, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getGrouperTargetObjectsMissing().getProvisioningGroups()); + countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.insert, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getGrouperTargetObjectsMissing().getProvisioningEntities()); + + + countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.update, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningGroups()); + countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.update, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningEntities()); + countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.update, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningMemberships()); + countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.delete, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes().getProvisioningGroups()); + countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.delete, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes().getProvisioningEntities()); + countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction.delete, this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes().getProvisioningMemberships()); + + } + + /** + * make sure we dont doublecount actions + */ + private Set alreadyCounted = new HashSet(); + + protected void countAttributesFieldsInsertsUpdatesDeletes(ProvisioningObjectChangeAction provisioningObjectChangeAction, List provisioningUpdatables) { + // maybe not count fields? + if (provisioningUpdatables == null) { + return; + } + + String membershipAttribute = GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getAttributeNameForMemberships(); + boolean groupAttributes = GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() + == GrouperProvisioningBehaviorMembershipType.groupAttributes; + boolean entityAttributes = GrouperProvisioningLogic.this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() + == GrouperProvisioningBehaviorMembershipType.entityAttributes; + + + for (ProvisioningUpdatable provisioningUpdatable : GrouperUtil.nonNull(provisioningUpdatables)) { + + MultiKey multiKey = new MultiKey(provisioningObjectChangeAction, provisioningUpdatable.provisioningUpdatableTypeShort(), provisioningUpdatable.getMatchingId()); + + // if this is an update, dont doublecount the inserts if we are only updating the membership objects + MultiKey insertMultiKey = provisioningObjectChangeAction == ProvisioningObjectChangeAction.update ? new MultiKey(ProvisioningObjectChangeAction.insert, provisioningUpdatable.provisioningUpdatableTypeShort(), provisioningUpdatable.getMatchingId()) : null; + + if (!alreadyCounted.contains(multiKey) && provisioningUpdatable.getProvisioned() != null && provisioningUpdatable.getProvisioned()) { + switch(provisioningObjectChangeAction) { + case insert: + this.grouperProvisioner.retrieveGrouperProvisioningOutput().addInsert(1); + alreadyCounted.add(multiKey); + break; + case update: + // its an update if we are doing something other than membership stuff and it is also an insert + if (!alreadyCounted.contains(insertMultiKey) || StringUtils.isBlank(membershipAttribute) || (!groupAttributes && !entityAttributes) + || (groupAttributes && (!(provisioningUpdatable instanceof ProvisioningGroup))) + || (entityAttributes && (!(provisioningUpdatable instanceof ProvisioningEntity)))) { + this.grouperProvisioner.retrieveGrouperProvisioningOutput().addUpdate(1); + alreadyCounted.add(multiKey); + } else { + + for (ProvisioningObjectChange provisioningObjectChange : GrouperUtil.nonNull(provisioningUpdatable.getInternal_objectChanges())) { + if (!StringUtils.equals(provisioningObjectChange.getAttributeName(), membershipAttribute) + && provisioningObjectChange.getProvisioned() != null && provisioningObjectChange.getProvisioned()) { + this.grouperProvisioner.retrieveGrouperProvisioningOutput().addUpdate(1); + alreadyCounted.add(multiKey); + break; + } + } + } + break; + case replace: + this.grouperProvisioner.retrieveGrouperProvisioningOutput().addReplace(1); + alreadyCounted.add(multiKey); + break; + case delete: + this.grouperProvisioner.retrieveGrouperProvisioningOutput().addDelete(1); + alreadyCounted.add(multiKey); + break; + } + + } + + // go through the membership attributes and count as memberships + if (!StringUtils.isBlank(membershipAttribute) && (groupAttributes || entityAttributes)) { + if ((groupAttributes && provisioningUpdatable instanceof ProvisioningGroup) + || entityAttributes && provisioningUpdatable instanceof ProvisioningEntity) { + + for (ProvisioningObjectChange provisioningObjectChange : GrouperUtil.nonNull(provisioningUpdatable.getInternal_objectChanges())) { + + if (!StringUtils.equals(provisioningObjectChange.getAttributeName(), membershipAttribute)) { + + } + + if (StringUtils.equals(provisioningObjectChange.getAttributeName(), membershipAttribute) + && provisioningObjectChange.getProvisioned() != null && provisioningObjectChange.getProvisioned()) { + + ProvisioningObjectChangeAction attributeProvisioningObjectChangeAction = provisioningObjectChange.getProvisioningObjectChangeAction(); + Object value = null; + switch (attributeProvisioningObjectChangeAction) { + case insert: + case update: + value = provisioningObjectChange.getNewValue(); + break; + case delete: + value = provisioningObjectChange.getOldValue(); + break; + } + + multiKey = new MultiKey(attributeProvisioningObjectChangeAction, provisioningUpdatable.provisioningUpdatableTypeShort(), provisioningUpdatable.getMatchingId(), value); + + if (alreadyCounted.contains(multiKey)) { + continue; + } + alreadyCounted.add(multiKey); + + switch (attributeProvisioningObjectChangeAction) { + case insert: + this.grouperProvisioner.retrieveGrouperProvisioningOutput().addInsert(1); + break; + case update: + this.grouperProvisioner.retrieveGrouperProvisioningOutput().addUpdate(1); + break; + case delete: + this.grouperProvisioner.retrieveGrouperProvisioningOutput().addDelete(1); + break; + + } + } + } + } + } + + + } + + } + + /** + * reference back up to the provisioner + */ + private GrouperProvisioner grouperProvisioner = null; + + /** logger */ + private static final Log LOG = GrouperUtil.getLog(GrouperProvisioningLogic.class); + + /** + * reference back up to the provisioner + * @return the provisioner + */ + public GrouperProvisioner getGrouperProvisioner() { + return this.grouperProvisioner; + } + + /** + * reference back up to the provisioner + * @param grouperProvisioner1 + */ + public void setGrouperProvisioner(GrouperProvisioner grouperProvisioner1) { + this.grouperProvisioner = grouperProvisioner1; + } + + + + + public void calculateProvisioningDataToDelete() { + this.calculateProvisioningGroupsToDelete(); + this.calculateProvisioningEntitiesToDelete(); + this.calculateProvisioningMembershipsToDelete(); + + } + + + /** + * take the sync members and see which ones do not correspond to a grouper member + */ + public void calculateProvisioningEntitiesToDelete() { + + Map memberUuidToProvisioningMemberWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getMemberUuidToProvisioningEntityWrapper(); + + int provisioningEntitiesToDelete = 0; + + List grouperProvisioningObjectMetadataItems = + this.grouperProvisioner.retrieveGrouperProvisioningObjectMetadata().getGrouperProvisioningObjectMetadataItems(); + + Map memberIdToEntityWrapperToDelete = new HashMap<>(); + + // loop through sync groups + for (ProvisioningEntityWrapper provisioningEntityWrapper : this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningEntityWrappers()) { + + GcGrouperSyncMember gcGrouperSyncMember = provisioningEntityWrapper.getGcGrouperSyncMember(); + ProvisioningEntity grouperProvisioningEntity = provisioningEntityWrapper.getGrouperProvisioningEntity(); + + // if a entity has been deleted in grouper_members table but copy still exists in grouper_sync_member + // we are sending the copy over to the target so that target can also delete + if (grouperProvisioningEntity == null && gcGrouperSyncMember != null) { + + memberIdToEntityWrapperToDelete.put(gcGrouperSyncMember.getMemberId(), provisioningEntityWrapper); + provisioningEntitiesToDelete++; + + } + } + + if (memberIdToEntityWrapperToDelete.size() == 0) { + return; + } + + List membersNonProvisionable = this.getGrouperProvisioner().retrieveGrouperDao().retrieveMembersNonProvisionable(memberIdToEntityWrapperToDelete.keySet()); + + Map memberIdToProvisioningEntityToDelete = new HashMap<>(); + + for (ProvisioningEntity provisioningEntityNotProvisionable: GrouperUtil.nonNull(membersNonProvisionable)) { + memberIdToProvisioningEntityToDelete.put(provisioningEntityNotProvisionable.getId(), provisioningEntityNotProvisionable); + } + + for (String memberIdToDelete: memberIdToEntityWrapperToDelete.keySet()) { + + ProvisioningEntity grouperProvisioningEntity = memberIdToProvisioningEntityToDelete.get(memberIdToDelete); + + ProvisioningEntityWrapper provisioningEntityWrapper = memberIdToEntityWrapperToDelete.get(memberIdToDelete); + + if (grouperProvisioningEntity == null) { + + GcGrouperSyncMember gcGrouperSyncMember = provisioningEntityWrapper.getGcGrouperSyncMember(); + grouperProvisioningEntity = new ProvisioningEntity(); + grouperProvisioningEntity.setId(gcGrouperSyncMember.getMemberId()); + grouperProvisioningEntity.setSubjectId(gcGrouperSyncMember.getSubjectId()); + grouperProvisioningEntity.assignAttributeValue("subjectSourceId", gcGrouperSyncMember.getSourceId()); + if ("subjectIdentifier1".equals(grouperProvisioner.retrieveGrouperProvisioningBehavior().getSubjectIdentifierForMemberSyncTable())) { + grouperProvisioningEntity.assignAttributeValue("subjectIdentifier1", gcGrouperSyncMember.getSubjectIdentifier()); + } else if ("subjectIdentifier2".equals(grouperProvisioner.retrieveGrouperProvisioningBehavior().getSubjectIdentifierForMemberSyncTable())) { + grouperProvisioningEntity.assignAttributeValue("subjectIdentifier2", gcGrouperSyncMember.getSubjectIdentifier()); + } else { + grouperProvisioningEntity.assignAttributeValue("subjectIdentifier0", gcGrouperSyncMember.getSubjectIdentifier()); + } + + if (GrouperUtil.length(grouperProvisioningObjectMetadataItems) > 0) { + + String jsonMetadata = gcGrouperSyncMember.getMetadataJson(); + + if (!StringUtils.isBlank(jsonMetadata) && !StringUtils.equals("{}", jsonMetadata)) { + JsonNode jsonNode = GrouperUtil.jsonJacksonNode(jsonMetadata); + for (GrouperProvisioningObjectMetadataItem grouperProvisioningObjectMetadataItem : grouperProvisioningObjectMetadataItems) { + if (grouperProvisioningObjectMetadataItem.isShowForMember()) { + + String metadataItemName = grouperProvisioningObjectMetadataItem.getName(); + if (metadataItemName.startsWith("md_")) { + if (jsonNode.has(metadataItemName)) { + GrouperProvisioningObjectMetadataItemValueType grouperProvisioningObjectMetadataItemValueType = + GrouperUtil.defaultIfNull(grouperProvisioningObjectMetadataItem.getValueType(), GrouperProvisioningObjectMetadataItemValueType.STRING); + String value = GrouperUtil.jsonJacksonGetString(jsonNode, metadataItemName); + grouperProvisioningEntity.assignAttributeValue(metadataItemName, grouperProvisioningObjectMetadataItemValueType.convert(value)); + } + } + } + } + } + } + +// //TODO select in bulk from grouper members +// Member member = MemberFinder.findByUuid(GrouperSession.staticGrouperSession(), gcGrouperSyncMember.getMemberId(), false); +// if (member != null) { +// grouperProvisioningEntity.setName(member.getName()); +// grouperProvisioningEntity.setEmail(member.getEmail0()); +// +// grouperProvisioningEntity.assignAttributeValue("description", member.getDescription()); +// } + + } + + provisioningEntityWrapper.setGrouperProvisioningEntity(grouperProvisioningEntity); + provisioningEntityWrapper.setDelete(true); + + memberUuidToProvisioningMemberWrapper.put(grouperProvisioningEntity.getId(), provisioningEntityWrapper); + + } + + if (provisioningEntitiesToDelete > 0) { + this.getGrouperProvisioner().getDebugMap().put("provisioningEntitiesToDelete", provisioningEntitiesToDelete); + } + + } + + + /** + * take the sync groups and see which ones do not correspond to a grouper group + */ + public void calculateProvisioningGroupsToDelete() { + + Map groupUuidToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupUuidToProvisioningGroupWrapper(); + + int provisioningGroupsToDeleteCount = 0; + + List grouperProvisioningObjectMetadataItems = + this.grouperProvisioner.retrieveGrouperProvisioningObjectMetadata().getGrouperProvisioningObjectMetadataItems(); + + Set provisioningGroupWrappers = this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningGroupWrappers(); + + // loop through sync groups + for (ProvisioningGroupWrapper provisioningGroupWrapper : provisioningGroupWrappers) { + + //TODO Perhaps look at grouper_groups information for unprovisionable groups that aren't deleted from grouper just like + // we did for entities. + + // if a group has been deleted in grouper_groups table but copy still exists in grouper_sync_group + // we are sending the copy over to the target so that target can also delete + ProvisioningGroup grouperProvisioningGroup = provisioningGroupWrapper.getGrouperProvisioningGroup(); + GcGrouperSyncGroup gcGrouperSyncGroup = provisioningGroupWrapper.getGcGrouperSyncGroup(); + if (grouperProvisioningGroup == null && gcGrouperSyncGroup != null) { + + provisioningGroupsToDeleteCount++; + + // create a provisioning group to delete + grouperProvisioningGroup = new ProvisioningGroup(); + grouperProvisioningGroup.setId(gcGrouperSyncGroup.getGroupId()); + grouperProvisioningGroup.setName(gcGrouperSyncGroup.getGroupName()); + grouperProvisioningGroup.setIdIndex(gcGrouperSyncGroup.getGroupIdIndex()); + + if (GrouperUtil.length(grouperProvisioningObjectMetadataItems) > 0) { + + String jsonMetadata = gcGrouperSyncGroup.getMetadataJson(); + + if (!StringUtils.isBlank(jsonMetadata) && !StringUtils.equals("{}", jsonMetadata)) { + JsonNode jsonNode = GrouperUtil.jsonJacksonNode(jsonMetadata); + for (GrouperProvisioningObjectMetadataItem grouperProvisioningObjectMetadataItem : grouperProvisioningObjectMetadataItems) { + if (grouperProvisioningObjectMetadataItem.isShowForMember()) { + + String metadataItemName = grouperProvisioningObjectMetadataItem.getName(); + if (metadataItemName.startsWith("md_")) { + if (jsonNode.has(metadataItemName)) { + GrouperProvisioningObjectMetadataItemValueType grouperProvisioningObjectMetadataItemValueType = + GrouperUtil.defaultIfNull(grouperProvisioningObjectMetadataItem.getValueType(), GrouperProvisioningObjectMetadataItemValueType.STRING); + String value = GrouperUtil.jsonJacksonGetString(jsonNode, metadataItemName); + grouperProvisioningGroup.assignAttributeValue(metadataItemName, grouperProvisioningObjectMetadataItemValueType.convert(value)); + } + } + } + } + } + } + + provisioningGroupWrapper.setGrouperProvisioningGroup(grouperProvisioningGroup); + provisioningGroupWrapper.setDelete(true); + + groupUuidToProvisioningGroupWrapper.put(gcGrouperSyncGroup.getGroupId(), provisioningGroupWrapper); + + } + + } + if (provisioningGroupsToDeleteCount > 0) { + this.getGrouperProvisioner().getDebugMap().put("provisioningGroupsToDeleteCount", provisioningGroupsToDeleteCount); + } + + } + + + /** + * take the sync groups and see which ones do not correspond to a grouper group + */ + public void calculateProvisioningMembershipsToDelete() { + + Map memberUuidToProvisioningEntityWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getMemberUuidToProvisioningEntityWrapper(); + Map groupUuidToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupUuidToProvisioningGroupWrapper(); + Map gcGrouperSyncMemberIdToProvisioningEntityWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncMemberIdToProvisioningEntityWrapper(); + Map gcGrouperSyncGroupIdToProvisioningGroupWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGrouperSyncGroupIdToProvisioningGroupWrapper(); + + Map groupUuidMemberUuidToProvisioningMembershipWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex().getGroupUuidMemberUuidToProvisioningMembershipWrapper(); + + int provisioningMshipsToDelete = 0; + + // loop through sync groups + for (ProvisioningMembershipWrapper provisioningMembershipWrapper : this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningMembershipWrappers()) { + + ProvisioningMembership grouperProvisioningMembership = provisioningMembershipWrapper.getGrouperProvisioningMembership(); + + GcGrouperSyncMembership gcGrouperSyncMembership = provisioningMembershipWrapper.getGcGrouperSyncMembership(); + + if (grouperProvisioningMembership == null && gcGrouperSyncMembership != null) { + + provisioningMshipsToDelete++; + + ProvisioningGroupWrapper provisioningGroupWrapper = gcGrouperSyncGroupIdToProvisioningGroupWrapper.get(gcGrouperSyncMembership.getGrouperSyncGroupId()); + if (provisioningGroupWrapper == null) { + throw new RuntimeException("Cant find groupId: '" + gcGrouperSyncMembership.getGrouperSyncGroupId() + "'"); + } + ProvisioningEntityWrapper provisioningEntityWrapper = gcGrouperSyncMemberIdToProvisioningEntityWrapper.get(gcGrouperSyncMembership.getGrouperSyncMemberId()); + if (provisioningEntityWrapper == null) { + throw new RuntimeException("Cant find entityId: '" + gcGrouperSyncMembership.getGrouperSyncMemberId() + "'"); + } + + GcGrouperSyncGroup gcGrouperSyncGroup = provisioningGroupWrapper.getGcGrouperSyncGroup(); + GcGrouperSyncMember gcGrouperSyncMember = provisioningEntityWrapper.getGcGrouperSyncMember(); + + // these can be null if in the index + + String groupId = gcGrouperSyncGroup.getGroupId(); + String memberId = gcGrouperSyncMember.getMemberId(); + + + // create a provisioning group to delete + ProvisioningMembership provisioningMembership = new ProvisioningMembership(); + provisioningMembership.setProvisioningGroupId(groupId); + provisioningMembership.setProvisioningEntityId(memberId); + + // the group is either the provisioning group or provisioning group to delete + if (provisioningGroupWrapper.getGrouperProvisioningGroup() != null) { + provisioningMembership.setProvisioningGroup(provisioningGroupWrapper.getGrouperProvisioningGroup()); + } else { + throw new RuntimeException("Cant find provisioning group: '" + groupId + "'"); + } + + // the group is either the provisioning group or provisioning group to delete + if (provisioningEntityWrapper.getGrouperProvisioningEntity() != null) { + provisioningMembership.setProvisioningEntity(provisioningEntityWrapper.getGrouperProvisioningEntity()); + } else { + throw new RuntimeException("Cant find provisioning entity: '" + memberId + "'"); + } + + provisioningMembershipWrapper.setGrouperProvisioningMembership(provisioningMembership); + provisioningMembershipWrapper.setDelete(true); + + groupUuidMemberUuidToProvisioningMembershipWrapper.put(provisioningMembershipWrapper.getGroupIdMemberId(), provisioningMembershipWrapper); + + } + provisioningMembershipWrapper.setGcGrouperSyncMembership(gcGrouperSyncMembership); + } + if (provisioningMshipsToDelete > 0) { + this.getGrouperProvisioner().getDebugMap().put("provisioningMshipsToDelete", provisioningMshipsToDelete); + } + + + } + + /** + * if incremental, and there are missing groups or entities, then retrieve them + */ + public void retrieveMissingObjectsIncremental() { + retrieveMissingGroupsIncremental(); + retrieveMissingEntitiesIncremental(); + } + + /** + * if incremental, and there are missing groups or entities, then retrieve them + */ + public void retrieveMissingGroupsIncremental() { + + // first lets see if we should even be doing this + if (!this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectGroupMissingIncremental()) { + return; + } + + //do we have missing groups? + List missingGroups = new ArrayList(); + + for (ProvisioningGroup provisioningGroup : GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperProvisioningGroups())) { + + // shouldnt be null at this point + GcGrouperSyncGroup gcGrouperSyncGroup = provisioningGroup.getProvisioningGroupWrapper().getGcGrouperSyncGroup(); + + if (!gcGrouperSyncGroup.isProvisionable()) { + continue; + } + if (this.grouperProvisioner.retrieveGrouperProvisioningLinkLogic().groupLinkMissing(gcGrouperSyncGroup)) { + missingGroups.add(provisioningGroup); + } + } + + if (GrouperUtil.length(missingGroups) == 0) { + return; + } + // how many do we have + this.grouperProvisioner.getDebugMap().put("missingIncrementalGroupsForRetrieve", missingGroups); + + this.grouperProvisioner.retrieveGrouperProvisioningDataGrouper().getGrouperProvisioningObjectsMissing().setProvisioningGroups(missingGroups); + + // log this + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingGroups); + + // translate + List grouperTargetGroups = this.grouperProvisioner.retrieveGrouperProvisioningTranslator().translateGrouperToTargetGroups(missingGroups, false, false); + this.getGrouperProvisioner().retrieveGrouperProvisioningDataChanges().getGrouperTargetObjectsMissing().setProvisioningGroups(grouperTargetGroups); + + // index + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups(grouperTargetGroups); + + // log this + //TODO this.getGrouperProvisioner().getGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingTargetGroups); + + //lets retrieve these + TargetDaoRetrieveGroupsResponse targetDaoRetrieveGroupsResponse = + this.grouperProvisioner.retrieveGrouperProvisioningTargetDaoAdapter().retrieveGroups(new TargetDaoRetrieveGroupsRequest(grouperTargetGroups, false)); + + List targetGroups = GrouperUtil.nonNull(targetDaoRetrieveGroupsResponse == null ? null : targetDaoRetrieveGroupsResponse.getTargetGroups()); + + // index + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetGroups(targetGroups); + + this.getGrouperProvisioner().retrieveGrouperProvisioningDataTarget().getTargetProvisioningObjectsMissingRetrieved().setProvisioningGroups(targetGroups); + + this.getGrouperProvisioner().retrieveGrouperProvisioningObjectLog().debug(GrouperProvisioningObjectLogType.missingTargetGroupsRetrieved); + + Map matchingIdToGrouperTargetGroup = new HashMap(); + + for (ProvisioningGroup grouperTargetGroup : GrouperUtil.nonNull(grouperTargetGroups)) { + matchingIdToGrouperTargetGroup.put(grouperTargetGroup.getMatchingId(), grouperTargetGroup); + } + + // set these in the wrapper so they are linked with grouper group + for (ProvisioningGroup targetGroup : GrouperUtil.nonNull(targetGroups)) { + + // look up the grouper group that looked this up + ProvisioningGroup grouperTargetGroup = matchingIdToGrouperTargetGroup.get(targetGroup.getMatchingId()); + + // not sure why it wouldnt match or exist... + grouperTargetGroup.getProvisioningGroupWrapper().setTargetProvisioningGroup(targetGroup); + } + + } + + /** + * if incremental, and there are missing groups or entities, then retrieve them + */ + public void retrieveMissingEntitiesIncremental() { + + } + +} diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLogicIncremental.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLogicIncremental.java index d6c99c2f4bfe..b28c81c20adc 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLogicIncremental.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLogicIncremental.java @@ -3,6 +3,7 @@ import java.lang.reflect.Array; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -22,6 +23,8 @@ import edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig; import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveIncrementalDataRequest; import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveIncrementalDataResponse; +import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveMembershipsByEntityRequest; +import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveMembershipsByEntityResponse; import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveMembershipsRequest; import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveMembershipsResponse; import edu.internet2.middleware.grouper.app.tableSync.ProvisioningSyncIntegration; @@ -170,7 +173,7 @@ public void filterByGroupNotProvisionable() { } int count = this.getGrouperProvisioner().getGcGrouperSync().getGcGrouperSyncMembershipDao(). - internal_membershipRetrieveFromDbCountInTargetByGroupSyncId(gcGrouperSyncGroup.getId()); + internal_membershipRetrieveFromDbCountByGroupSyncId(gcGrouperSyncGroup.getId()); // if we're doing entity attributes and a group is deleted, it's not provisionable but if there are still memberships for this group // we need to address them @@ -2219,7 +2222,7 @@ public void copyIncrementalStateToWrappers() { } - public void retrieveTargetIncrementalMembershipsWithRecalcWhereGroupIsNotRecalc() { + public void retrieveTargetIncrementalMembershipsWithRecalcWhereContainerIsNotRecalc() { if (!this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isSelectMemberships()) { return; @@ -2272,7 +2275,9 @@ public void retrieveTargetIncrementalMembershipsWithRecalcWhereGroupIsNotRecalc( requestGrouperTargetGroups.add(clonedGrouperTargetGroup); } - + if (GrouperUtil.length(requestGrouperTargetGroups) == 0) { + return; + } targetDaoRetrieveMembershipsRequest.setTargetMemberships(requestGrouperTargetGroups); TargetDaoRetrieveMembershipsResponse membershipsResponse = this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter().retrieveMemberships(targetDaoRetrieveMembershipsRequest); @@ -2300,9 +2305,116 @@ public void retrieveTargetIncrementalMembershipsWithRecalcWhereGroupIsNotRecalc( } + } else if (this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.entityAttributes) { + + Set entityWrappersFromMembershipsWithoutRecalc = new HashSet(); + for (ProvisioningMembershipWrapper provisioningMembershipWrapper : this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningMembershipWrappers()) { + + ProvisioningEntityWrapper entityWrapper = provisioningMembershipWrapper.getGrouperProvisioningMembership().getProvisioningEntity().getProvisioningEntityWrapper(); + if (!entityWrapper.isRecalc() && provisioningMembershipWrapper.isRecalc()) { + entityWrappersFromMembershipsWithoutRecalc.add(entityWrapper); + } + } + + // we need to send this list to the target dao and ask about certain memberships + List requestGrouperTargetEntities = new ArrayList(); + + String attributeForMemberships = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getAttributeNameForMemberships(); + + for (ProvisioningEntityWrapper entityWrapperFromMembership: entityWrappersFromMembershipsWithoutRecalc) { + + ProvisioningEntity clonedGrouperTargetEntity = entityWrapperFromMembership.getGrouperTargetEntity().clone(); + + Object attributeValue = clonedGrouperTargetEntity.retrieveAttributeValue(attributeForMemberships); + + ProvisioningAttribute grouperAttribute = GrouperUtil.nonNull(clonedGrouperTargetEntity.getAttributes()).get(attributeForMemberships); + + if (attributeValue instanceof Collection) { + + Iterator valueIterator = ((Collection) attributeValue).iterator(); + + while (valueIterator.hasNext()) { + Object value = valueIterator.next(); + ProvisioningMembershipWrapper provisioningMembershipWrapper = grouperAttribute.getValueToProvisioningMembershipWrapper().get(value); + if (!provisioningMembershipWrapper.isRecalc()) { + valueIterator.remove(); + } + + } + } + + requestGrouperTargetEntities.add(clonedGrouperTargetEntity); + + } + + if (GrouperUtil.length(requestGrouperTargetEntities) == 0) { + return; + } + + targetDaoRetrieveMembershipsRequest.setTargetMemberships(requestGrouperTargetEntities); + + TargetDaoRetrieveMembershipsResponse membershipsResponse = this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter().retrieveMemberships(targetDaoRetrieveMembershipsRequest); + + List targetEntitiesWithMemberships = membershipsResponse.getTargetMemberships(); + + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetEntities((List)(Object)targetEntitiesWithMemberships); + + for (Object provisioningEntityObject: GrouperUtil.nonNull(targetEntitiesWithMemberships)) { // because memberships are stored in group attributes, so we receive groups for memberships call + + ProvisioningEntity provisioningEntityFromTarget = (ProvisioningEntity) provisioningEntityObject; + + Set attributeValueSet = (Set)provisioningEntityFromTarget.retrieveAttributeValueSet(attributeForMemberships); + + ProvisioningEntityWrapper originalTargetEntityWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex() + .getEntityMatchingIdToProvisioningEntityWrapper().get(provisioningEntityFromTarget.getMatchingId()); + + ProvisioningEntity originalTargetEntity = originalTargetEntityWrapper.getTargetProvisioningEntity(); + + for (Object value: GrouperUtil.nonNull(attributeValueSet)) { + + originalTargetEntity.addAttributeValue(attributeForMemberships, value); + + } + + } + + } else if (this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.membershipObjects) { + + List membershipsWithRecalc = new ArrayList(); + for (ProvisioningMembershipWrapper provisioningMembershipWrapper : this.getGrouperProvisioner().retrieveGrouperProvisioningData().getProvisioningMembershipWrappers()) { + + if (provisioningMembershipWrapper.isRecalc() && provisioningMembershipWrapper.getGrouperProvisioningMembership() != null) { + membershipsWithRecalc.add(provisioningMembershipWrapper.getGrouperTargetMembership()); + } + } + + if (GrouperUtil.length(membershipsWithRecalc) == 0) { + return; + } + + targetDaoRetrieveMembershipsRequest.setTargetMemberships((List)(Object)membershipsWithRecalc); + + TargetDaoRetrieveMembershipsResponse membershipsResponse = this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter().retrieveMemberships(targetDaoRetrieveMembershipsRequest); + + List targetMemberships = membershipsResponse.getTargetMemberships(); + + this.grouperProvisioner.retrieveGrouperProvisioningTranslator().idTargetMemberships((List)(Object)targetMemberships); + + for (Object provisioningMembershipObject: GrouperUtil.nonNull(targetMemberships)) { + + ProvisioningMembership targetProvisioningMembership = (ProvisioningMembership) provisioningMembershipObject; + + ProvisioningMembershipWrapper originalTargetMembershipWrapper = this.getGrouperProvisioner().retrieveGrouperProvisioningDataIndex() + .getMembershipMatchingIdToProvisioningMembershipWrapper().get(targetProvisioningMembership.getMatchingId()); + + originalTargetMembershipWrapper.setTargetProvisioningMembership(targetProvisioningMembership); + + } + + } else { + throw new RuntimeException("Not expecting membership type: " + this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType()); } - } public void retrieveIncrementalTargetData() { diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningMatchingIdIndex.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningMatchingIdIndex.java index 3b9c807334d1..344417c9cf3d 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningMatchingIdIndex.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningMatchingIdIndex.java @@ -1,7 +1,9 @@ package edu.internet2.middleware.grouper.app.provisioning; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -23,6 +25,9 @@ public void setGrouperProvisioner(GrouperProvisioner grouperProvisioner) { } + /** + * look through group wrappers and add matching IDs to the index and make sure everything is linked up + */ public void indexMatchingIdGroups() { int provisioningGroupWrappersWithNullIds = 0; @@ -65,7 +70,7 @@ public void indexMatchingIdGroups() { if (grouperWrapper == null || targetWrapper == null || grouperWrapper == targetWrapper) { - throw new NullPointerException("Why do multiple groups have the same matching id???\n" + throw new RuntimeException("Why do multiple groups have the same matching id???\n" + provisioningGroupWrapper.getGrouperTargetGroup() + "\n" + provisioningGroupWrapper.getTargetProvisioningGroup() + "\n" + provisioningGroupWrapperExisting.getGrouperTargetGroup() + "\n" @@ -93,6 +98,136 @@ public void indexMatchingIdGroups() { } + /** + * look through group wrappers focus on grouper and target data which is not yet matched + */ + public void indexMatchingIdGroupsUnmatched(List extraTargetProvisioningGroups) { + + Set grouperTargetGroupsUnmatched = new HashSet(); + Set targetProvisioningGroupsUnmatched = new HashSet(); + + Map groupMatchingIdToProvisioningGroupWrapper = + this.grouperProvisioner.retrieveGrouperProvisioningDataIndex().getGroupMatchingIdToProvisioningGroupWrapper(); + + for (ProvisioningGroupWrapper provisioningGroupWrapper : new ArrayList( + GrouperUtil.nonNull(this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers()))) { + + // this is a match + if (provisioningGroupWrapper.getGrouperTargetGroup() != null && provisioningGroupWrapper.getTargetProvisioningGroup() != null) { + continue; + } + + // this is weird, but skip it + if (provisioningGroupWrapper.getGrouperTargetGroup() == null && provisioningGroupWrapper.getTargetProvisioningGroup() == null) { + continue; + } + + // this grouperTargetGroup with no match + if (provisioningGroupWrapper.getGrouperTargetGroup() != null && provisioningGroupWrapper.getTargetProvisioningGroup() == null) { + grouperTargetGroupsUnmatched.add(provisioningGroupWrapper.getGrouperTargetGroup()); + continue; + } + + // this targetProvisioningGroup with no match + if (provisioningGroupWrapper.getGrouperTargetGroup() == null && provisioningGroupWrapper.getTargetProvisioningGroup() != null) { + targetProvisioningGroupsUnmatched.add(provisioningGroupWrapper.getTargetProvisioningGroup()); + continue; + } + } + + for (ProvisioningGroup extraTargetProvisioningGroup : GrouperUtil.nonNull(extraTargetProvisioningGroups)) { + if (extraTargetProvisioningGroup.getProvisioningGroupWrapper() == null || extraTargetProvisioningGroup.getProvisioningGroupWrapper().getGrouperTargetGroup() == null) { + targetProvisioningGroupsUnmatched.add(extraTargetProvisioningGroup); + } + } + + if (grouperTargetGroupsUnmatched.size() > 0) { + Integer oldCount = GrouperUtil.defaultIfNull((Integer)this.getGrouperProvisioner().getDebugMap().get("grouperTargetGroupsUnmatched"), 0); + this.getGrouperProvisioner().getDebugMap().put("grouperTargetGroupsUnmatched", oldCount + grouperTargetGroupsUnmatched.size()); + } + if (targetProvisioningGroupsUnmatched.size() > 0) { + Integer oldCount = GrouperUtil.defaultIfNull((Integer)this.getGrouperProvisioner().getDebugMap().get("targetProvisioningGroupsUnmatched"), 0); + this.getGrouperProvisioner().getDebugMap().put("targetProvisioningGroupsUnmatched", oldCount + grouperTargetGroupsUnmatched.size()); + } + if (grouperTargetGroupsUnmatched.size() == 0 || targetProvisioningGroupsUnmatched.size() == 0) { + // if none on either side then we cannot find a deeper match + return; + } + // loop through matching ids + int provisioningGroupWrappersMatchedFromCache = 0; + int provisioningGroupWrappersMatchedFromAlternateMatchAttr = 0; + for (GrouperProvisioningConfigurationAttribute matchingAttribute : this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupMatchingAttributes()) { + String matchingAttributeName = matchingAttribute.getName(); + Map matchingValueToTargetProvisioningGroup = new HashMap(); + for (ProvisioningGroup targetProvisioningGroup : targetProvisioningGroupsUnmatched) { + // dont worry if dupes... oh well + Object targetProvisioningGroupCurrentValue = targetProvisioningGroup.retrieveAttributeValue(matchingAttributeName); + if(!GrouperUtil.isBlank(targetProvisioningGroupCurrentValue)) { + matchingValueToTargetProvisioningGroup.put(targetProvisioningGroupCurrentValue, targetProvisioningGroup); + } + } + for (ProvisioningGroup grouperTargetGroup : new HashSet(grouperTargetGroupsUnmatched)) { + ProvisioningGroup targetProvisioningGroup = null; + + Object grouperTargetGroupCurrentValue = grouperTargetGroup.retrieveAttributeValue(matchingAttributeName); + if (targetProvisioningGroup == null + && !GrouperUtil.isEmpty(grouperTargetGroupCurrentValue)) { + targetProvisioningGroup = matchingValueToTargetProvisioningGroup.get(grouperTargetGroupCurrentValue); + if (targetProvisioningGroup != null) { + provisioningGroupWrappersMatchedFromAlternateMatchAttr++; + } + } + + if (targetProvisioningGroup == null) { + Set cachedValues = GrouperProvisioningConfigurationAttributeDbCache.cachedValuesForGroup(grouperTargetGroup, matchingAttributeName); + for (Object cachedValue : GrouperUtil.nonNull(cachedValues)) { + if (targetProvisioningGroup == null + && !GrouperUtil.isEmpty(cachedValue)) { + targetProvisioningGroup = matchingValueToTargetProvisioningGroup.get(cachedValue); + if (targetProvisioningGroup != null) { + provisioningGroupWrappersMatchedFromCache++; + } + } + } + } + + if (targetProvisioningGroup != null) { + // we have a match!!!! + + // i guess use the grouper matching id... hmmm... since they dont match + groupMatchingIdToProvisioningGroupWrapper.put(grouperTargetGroup.getMatchingId(), grouperTargetGroup.getProvisioningGroupWrapper()); + + // link to group wrapper + grouperTargetGroup.getProvisioningGroupWrapper().setTargetProvisioningGroup(targetProvisioningGroup); + grouperTargetGroup.getProvisioningGroupWrapper().setTargetNativeGroup(targetProvisioningGroup.getProvisioningGroupWrapper().getTargetNativeGroup()); + + // unlink from its wrapper + if (targetProvisioningGroup.getProvisioningGroupWrapper() != grouperTargetGroup.getProvisioningGroupWrapper()) { + this.grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers().remove(targetProvisioningGroup.getProvisioningGroupWrapper()); + targetProvisioningGroup.getProvisioningGroupWrapper().setTargetProvisioningGroup(null); + targetProvisioningGroup.getProvisioningGroupWrapper().setTargetNativeGroup(null); + targetProvisioningGroup.getProvisioningGroupWrapper().setGcGrouperSyncGroup(null); + } + + targetProvisioningGroup.setProvisioningGroupWrapper(grouperTargetGroup.getProvisioningGroupWrapper()); + + grouperTargetGroupsUnmatched.remove(grouperTargetGroup); + targetProvisioningGroupsUnmatched.remove(targetProvisioningGroup); + } + } + } + + if (provisioningGroupWrappersMatchedFromAlternateMatchAttr > 0) { + Integer oldCount = GrouperUtil.defaultIfNull((Integer)this.getGrouperProvisioner().getDebugMap().get("provisioningGroupWrappersMatchedFromAlternateMatchAttr"), 0); + this.getGrouperProvisioner().getDebugMap().put("provisioningGroupWrappersMatchedFromAlternateMatchAttr", oldCount + provisioningGroupWrappersMatchedFromAlternateMatchAttr); + } + if (provisioningGroupWrappersMatchedFromCache > 0) { + Integer oldCount = GrouperUtil.defaultIfNull((Integer)this.getGrouperProvisioner().getDebugMap().get("provisioningGroupWrappersMatchedFromCache"), 0); + this.getGrouperProvisioner().getDebugMap().put("provisioningGroupWrappersMatchedFromCache", oldCount + provisioningGroupWrappersMatchedFromCache); + } + + } + public void indexMatchingIdMemberships() { int provisioningMembershipWrappersWithNullIds = 0; @@ -136,7 +271,7 @@ public void indexMatchingIdMemberships() { if (grouperWrapper == null || targetWrapper == null || grouperWrapper == targetWrapper) { - throw new NullPointerException("Why do multiple memberships have the same matching id???\n" + throw new RuntimeException("Why do multiple memberships have the same matching id???\n" + provisioningMembershipWrapper.getGrouperTargetMembership() + "\n" + provisioningMembershipWrapper.getTargetProvisioningMembership() + "\n" + membershipMatchingIdToProvisioningMembershipWrapper.get(matchingId).getGrouperTargetMembership() + "\n" @@ -213,7 +348,7 @@ public void indexMatchingIdEntities() { if (grouperWrapper == null || targetWrapper == null || grouperWrapper == targetWrapper) { - throw new NullPointerException("Why do multiple entities have the same matching id???\n" + throw new RuntimeException("Why do multiple entities have the same matching id???\n" + provisioningEntityWrapper.getGrouperTargetEntity() + "\n" + provisioningEntityWrapper.getTargetProvisioningEntity() + "\n" + entityMatchingIdToProvisioningEntityWrapper.get(matchingId).getGrouperTargetEntity() + "\n" diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningObjectLog.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningObjectLog.java index 9d8c9a2a27a8..277bf6caa814 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningObjectLog.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningObjectLog.java @@ -67,7 +67,7 @@ public void debug(GrouperProvisioningObjectLogType state) { } if (LOG.isDebugEnabled()) { // put id on each line - String logMessageString = GrouperUtil.replace(logMessage.toString(), "\n", "\n(" + this.grouperProvisioner.getInstanceId() + "): "); + String logMessageString = this.grouperProvisioner.retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId(logMessage.toString()); LOG.debug(logMessageString); } } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningObjectLogType.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningObjectLogType.java index 377d8d798482..91b9a4b1648f 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningObjectLogType.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningObjectLogType.java @@ -295,7 +295,7 @@ void logState(GrouperProvisioningObjectLog grouperProvisioningObjectLog, } }, - retrieveTargetIncrementalMembershipsWithRecalcWhereGroupIsNotRecalc { + retrieveTargetIncrementalMembershipsWithRecalcWhereContainerIsNotRecalc { @Override void logState(GrouperProvisioningObjectLog grouperProvisioningObjectLog, @@ -315,6 +315,17 @@ void logState(GrouperProvisioningObjectLog grouperProvisioningObjectLog, } }, + validateGrouperGroupsEntities { + + @Override + void logState(GrouperProvisioningObjectLog grouperProvisioningObjectLog, + GrouperProvisioner grouperProvisioner, StringBuilder logMessage) { + appendProvisioningObjectsOfType(grouperProvisioner, logMessage, "Grouper target", grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetGroups(), "groups"); + appendProvisioningObjectsOfType(grouperProvisioner, logMessage, "Grouper target", grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetEntities(), "entities"); + + } + }, + retrieveIndividualEntitiesIfNeeded { @Override @@ -324,6 +335,17 @@ void logState(GrouperProvisioningObjectLog grouperProvisioningObjectLog, } + }, + + retrieveIndividualMissingGroups { + + @Override + void logState(GrouperProvisioningObjectLog grouperProvisioningObjectLog, + GrouperProvisioner grouperProvisioner, StringBuilder logMessage) { + appendProvisioningObjectsOfType(grouperProvisioner, logMessage, "Grouper target", grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetGroups(), "groups"); + + } + }, matchingIdGrouperMemberships { diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningOutput.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningOutput.java index 537329f9ff28..5b8d21e58924 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningOutput.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningOutput.java @@ -548,6 +548,7 @@ public void copyToHib3LoaderLog() { hib3GrouperLoaderLog.setInsertCount(this.insert); hib3GrouperLoaderLog.setUpdateCount(this.update); hib3GrouperLoaderLog.setTotalCount(this.totalCount); + hib3GrouperLoaderLog.appendJobMessage(this.message); } public GrouperProvisioner getGrouperProvisioner() { diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningService.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningService.java index 1b8bd8b9e7e2..d55f161920e9 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningService.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningService.java @@ -9,6 +9,7 @@ import static edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningAttributeNames.retrieveAttributeDefNameBase; import static edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningSettings.provisioningConfigStemName; +import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -48,6 +49,7 @@ import edu.internet2.middleware.grouper.misc.GrouperSessionHandler; import edu.internet2.middleware.grouper.privs.PrivilegeHelper; import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClient.collections.MultiKey; import edu.internet2.middleware.grouperClient.jdbc.GcDbAccess; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSync; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncDao; @@ -62,6 +64,10 @@ public class GrouperProvisioningService { + + private static final ExpirableCache viewableGroupToSubject = new ExpirableCache(5); + private static final ExpirableCache editableGroupToSubject = new ExpirableCache(5); + /** * find all groups provisionable in target @@ -387,6 +393,7 @@ public static GrouperProvisioningAttributeValue getProvisioningAttributeValue(Gr GrouperProvisioner provisioner = GrouperProvisioner.retrieveProvisioner(targetName); provisioner.retrieveGrouperProvisioningConfiguration().configureProvisionableSettings(); + GrouperProvisioningObjectAttributes grouperProvisioningObjectAttributes; String parentStemId; @@ -824,12 +831,6 @@ public static boolean saveOrUpdateProvisioningAttributes(GrouperProvisioningAttr */ public static boolean isTargetEditable(GrouperProvisioningTarget target, Subject subject, GrouperObject grouperObject) { - boolean readOnly = target.isReadOnly(); - - if(readOnly) { - return false; - } - boolean isEditable = true; if (grouperObject != null) { @@ -843,6 +844,22 @@ public static boolean isTargetEditable(GrouperProvisioningTarget target, Subject return isEditable && isTargetEditableBySubject(target, subject); } + /** + * is given target viewable for given subject and grouper object + * @param target + * @param subject + * @param grouperObject + * @return + */ + public static boolean isTargetViewable(GrouperProvisioningTarget target, Subject subject, GrouperObject grouperObject) { + + if (isTargetEditable(target, subject, grouperObject)) { + return true; + } + + return isTargetViewableBySubject(target, subject); + } + /** * delete all the attribute assigns where the config doesn't exist */ @@ -1528,28 +1545,88 @@ private static boolean isTargetEditableBySubject(GrouperProvisioningTarget targe return PrivilegeHelper.isWheelOrRoot(subject); // only grouper system admin is allowed when no specific group is allowed to assign the given target } - Group group = GroupFinder.findByName(GrouperSession.staticGrouperSession(), groupAllowedToAssign, false); - if (group == null) { - try { // try looking up group by id - Long groupId = Long.valueOf(groupAllowedToAssign); - group = GroupFinder.findByIdIndexSecure(groupId, false, new QueryOptions()); + MultiKey multiKey = new MultiKey(groupAllowedToAssign, subject.getId()); + + Boolean isEditable = viewableGroupToSubject.get(multiKey); + if (isEditable != null) { + return isEditable; + } + + Boolean isMember = (Boolean)GrouperSession.internal_callbackRootGrouperSession(new GrouperSessionHandler() { + + @Override + public Object callback(GrouperSession grouperSession) + throws GrouperSessionException { + + + Group group = GroupFinder.findByName(grouperSession, groupAllowedToAssign, false); if (group == null) { - throw new RuntimeException(groupAllowedToAssign+" is not a valid group id or group name"); + group = GroupFinder.findByUuid(grouperSession, groupAllowedToAssign, false); + if (group == null) { + throw new RuntimeException(groupAllowedToAssign+" is not a valid group id or group name"); + } } - } catch (NumberFormatException e) { - throw new RuntimeException(groupAllowedToAssign+" is not a valid group id or group name"); + + return group.hasMember(subject); + } - + + }); + + editableGroupToSubject.put(multiKey, isMember); + + return isMember; + + } + + /** + * can the given subject view the given target + * @param target + * @param subject + * @return + */ + private static boolean isTargetViewableBySubject(GrouperProvisioningTarget target, Subject subject) { + + if (PrivilegeHelper.isWheelOrRootOrViewonlyRoot(subject)) { + return true; } - for (Member member: group.getMembers()) { - Subject groupSubject = member.getSubject(); - if (subject.getId().equals(groupSubject.getId())) { - return true; - } + String groupAllowedToView = target.getGroupAllowedToView(); + + if (StringUtils.isBlank(groupAllowedToView)) { + return false; } - return false; + MultiKey multiKey = new MultiKey(groupAllowedToView, subject.getId()); + + Boolean isViewable = viewableGroupToSubject.get(multiKey); + if (isViewable != null) { + return isViewable; + } + + Boolean isMember = (Boolean)GrouperSession.internal_callbackRootGrouperSession(new GrouperSessionHandler() { + + @Override + public Object callback(GrouperSession grouperSession) + throws GrouperSessionException { + + Group group = GroupFinder.findByName(grouperSession, groupAllowedToView, false); + if (group == null) { + group = GroupFinder.findByUuid(grouperSession, groupAllowedToView, false); + if (group == null) { + throw new RuntimeException(groupAllowedToView+" is not a valid group id or group name"); + } + } + + return group.hasMember(subject); + + } + + }); + + viewableGroupToSubject.put(multiKey, isMember); + + return isMember; } @@ -1673,4 +1750,78 @@ private static String getProvisionableRegex(GrouperProvisioner grouperProvisione return grouperProvisioner.retrieveGrouperProvisioningConfiguration().getProvisionableRegex(); } + + public static List retrieveGcGrouperSyncMembershipsByMemberIdAndInTargetStartTimeRange(String memberId, Timestamp inTargetStartTimeFrom, Timestamp inTargetStartTimeTo) { + String grouperSyncMembershipQuery = "select gsm.* from grouper_sync_membership gsm, grouper_sync_group gsg, grouper_sync_member gsmem " + + "where gsm.grouper_sync_group_id = gsg.id " + + " and gsm.grouper_sync_member_id = gsmem.id " + + " and gsmem.member_id = ? " + + " and gsm.in_target_start is not null " + + " and gsm.in_target_start > ? " + + " and gsm.in_target_start < ? "; + + String grouperSyncQuery = "select * from grouper_sync gs where id = ? "; + + List grouperSyncMemberships = new GcDbAccess().sql(grouperSyncMembershipQuery) + .addBindVar(memberId) + .addBindVar(inTargetStartTimeFrom) + .addBindVar(inTargetStartTimeTo) + .selectList(GcGrouperSyncMembership.class); + + for (GcGrouperSyncMembership grouperSyncMembership : GrouperUtil.nonNull(grouperSyncMemberships)) { + String grouperSyncId = grouperSyncMembership.getGrouperSyncId(); + + GcGrouperSync gcGrouperSync = new GcDbAccess().sql(grouperSyncQuery) + .addBindVar(grouperSyncId) + .select(GcGrouperSync.class); + grouperSyncMembership.setGrouperSync(gcGrouperSync); + + GcGrouperSyncMember grouperSyncMember = GcGrouperSyncDao.retrieveById(null, grouperSyncId) + .getGcGrouperSyncMemberDao().memberRetrieveById(grouperSyncMembership.getGrouperSyncMemberId()); + grouperSyncMembership.setGrouperSyncMember(grouperSyncMember); + + GcGrouperSyncGroup grouperSyncGroup = GcGrouperSyncDao.retrieveById(null, grouperSyncId) + .getGcGrouperSyncGroupDao().groupRetrieveById(grouperSyncMembership.getGrouperSyncGroupId()); + grouperSyncMembership.setGrouperSyncGroup(grouperSyncGroup); + } + + return grouperSyncMemberships; + } + + public static List retrieveGcGrouperSyncMembershipsByMemberIdAndInTargetEndTimeRange(String memberId, Timestamp inTargetEndTimeFrom, Timestamp inTargetEndTimeTo) { + String grouperSyncMembershipQuery = "select gsm.* from grouper_sync_membership gsm, grouper_sync_group gsg, grouper_sync_member gsmem " + + "where gsm.grouper_sync_group_id = gsg.id " + + " and gsm.grouper_sync_member_id = gsmem.id " + + " and gsmem.member_id = ? " + + " and gsm.in_target_end is not null " + + " and gsm.in_target_end > ? " + + " and gsm.in_target_end < ? "; + + String grouperSyncQuery = "select * from grouper_sync gs where id = ? "; + + List grouperSyncMemberships = new GcDbAccess().sql(grouperSyncMembershipQuery) + .addBindVar(memberId) + .addBindVar(inTargetEndTimeFrom) + .addBindVar(inTargetEndTimeTo) + .selectList(GcGrouperSyncMembership.class); + + for (GcGrouperSyncMembership grouperSyncMembership : GrouperUtil.nonNull(grouperSyncMemberships)) { + String grouperSyncId = grouperSyncMembership.getGrouperSyncId(); + + GcGrouperSync gcGrouperSync = new GcDbAccess().sql(grouperSyncQuery) + .addBindVar(grouperSyncId) + .select(GcGrouperSync.class); + grouperSyncMembership.setGrouperSync(gcGrouperSync); + + GcGrouperSyncMember grouperSyncMember = GcGrouperSyncDao.retrieveById(null, grouperSyncId) + .getGcGrouperSyncMemberDao().memberRetrieveById(grouperSyncMembership.getGrouperSyncMemberId()); + grouperSyncMembership.setGrouperSyncMember(grouperSyncMember); + + GcGrouperSyncGroup grouperSyncGroup = GcGrouperSyncDao.retrieveById(null, grouperSyncId) + .getGcGrouperSyncGroupDao().groupRetrieveById(grouperSyncMembership.getGrouperSyncGroupId()); + grouperSyncMembership.setGrouperSyncGroup(grouperSyncGroup); + } + + return grouperSyncMemberships; + } } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningSettings.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningSettings.java index 822cb59b56f6..8a77a49cfde2 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningSettings.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningSettings.java @@ -57,11 +57,13 @@ private static Map populateTargets() { String name = matcher.group(1); String groupAllowedToAssign = GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner."+name+".groupAllowedToAssign", null); + String groupAllowedToView = GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner."+name+".groupAllowedToView", null); boolean allowAssignmentsOnlyOnOneStem = GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner."+name+".allowAssignmentsOnlyOnOneStem", false); boolean readOnly = GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner."+name+".readOnly", false); GrouperProvisioningTarget target = new GrouperProvisioningTarget(name, name); target.setGroupAllowedToAssign(groupAllowedToAssign); + target.setGroupAllowedToView(groupAllowedToView); target.setAllowAssignmentsOnlyOnOneStem(allowAssignmentsOnlyOnOneStem); target.setReadOnly(readOnly); result.put(name, target); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningTarget.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningTarget.java index ddf5805faf5b..4410df3ba590 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningTarget.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningTarget.java @@ -19,6 +19,11 @@ public class GrouperProvisioningTarget { */ private String groupAllowedToAssign; + /** + * group whose members are allowed to view this target + */ + private String groupAllowedToView; + /** * should the target be assignable to only one stem */ @@ -91,6 +96,22 @@ public void setGroupAllowedToAssign(String groupAllowedToAssign) { public String getGroupAllowedToAssign() { return groupAllowedToAssign; } + + /** + * group whose members are allowed to view this target + * @return + */ + public String getGroupAllowedToView() { + return groupAllowedToView; + } + + /** + * group whose members are allowed to view this target + * @param groupAllowedToView + */ + public void setGroupAllowedToView(String groupAllowedToView) { + this.groupAllowedToView = groupAllowedToView; + } /** * should the target be assignable to only one stem diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningTranslator.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningTranslator.java index 9247d4b270ff..305958146f15 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningTranslator.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningTranslator.java @@ -6,7 +6,7 @@ import java.util.List; import java.util.Map; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import edu.internet2.middleware.grouper.util.GrouperUtil; import edu.internet2.middleware.grouperClient.collections.MultiKey; @@ -62,7 +62,7 @@ public List translateGrouperToTargetMemberships( // clear out the membership attribute, it might have a default value in there if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.groupAttributes) { - String groupMembershipAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeNameForMemberships(); + String groupMembershipAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupMembershipAttributeName(); if (!StringUtils.isBlank(groupMembershipAttribute)) { for (ProvisioningGroup provisioningGroup : this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetGroups()) { provisioningGroup.clearAttribute(groupMembershipAttribute); @@ -70,7 +70,7 @@ public List translateGrouperToTargetMemberships( } } if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.entityAttributes) { - String entityMembershipAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeNameForMemberships(); + String entityMembershipAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityMembershipAttributeName(); if (!StringUtils.isBlank(entityMembershipAttribute)) { for (ProvisioningEntity provisioningEntity : this.grouperProvisioner.retrieveGrouperProvisioningData().retrieveGrouperTargetEntities()) { provisioningEntity.clearAttribute(entityMembershipAttribute); @@ -135,14 +135,12 @@ public List translateGrouperToTargetMemberships( // attribute translations for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetMembershipAttributeNameToConfig().values()) { - String expressionToUse = getTargetExpressionToUse(false, grouperProvisioningConfigurationAttribute); + String expressionToUse = getTargetExpressionToUse(!gcGrouperSyncMembership.isInTarget(), grouperProvisioningConfigurationAttribute); if (StringUtils.isNotBlank(expressionToUse) - || StringUtils.isNotBlank(grouperProvisioningConfigurationAttribute.getTranslateFromGroupSyncField()) - || StringUtils.isNotBlank(grouperProvisioningConfigurationAttribute.getTranslateFromMemberSyncField()) || StringUtils.isNotBlank(grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningGroupField()) || StringUtils.isNotBlank(grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningEntityField())) { Object result = attributeTranslation( - grouperTargetMembership.retrieveAttributeValue(grouperProvisioningConfigurationAttribute.getName()), elVariableMap, false, + grouperTargetMembership.retrieveAttributeValue(grouperProvisioningConfigurationAttribute.getName()), elVariableMap, !gcGrouperSyncMembership.isInTarget(), grouperProvisioningConfigurationAttribute, provisioningGroupWrapper, provisioningEntityWrapper); grouperTargetMembership.assignAttributeValue(grouperProvisioningConfigurationAttribute.getName(), result); @@ -152,19 +150,19 @@ public List translateGrouperToTargetMemberships( } } - if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.groupAttributes) { - String groupMembershipAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeNameForMemberships(); + // if the group is missing, has an invalid attribute don't bother setting the membership + if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.groupAttributes + && provisioningGroupWrapper.getGrouperTargetGroup() != null) { + String groupMembershipAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupMembershipAttributeName(); if (!StringUtils.isEmpty(groupMembershipAttribute)) { GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().get(groupMembershipAttribute); if (grouperProvisioningConfigurationAttribute != null) { Object result = null; - if (!StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateExpressionFromMembership())) { - result = runScript(grouperProvisioningConfigurationAttribute.getTranslateExpressionFromMembership(), elVariableMap); - } else if (!StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateFromMemberSyncField())) { - result = translateFromMemberSyncField(provisioningEntityWrapper.getGcGrouperSyncMember(), - grouperProvisioningConfigurationAttribute.getTranslateFromMemberSyncField()); + if (!StringUtils.isBlank(this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupMembershipAttributeValue())) { + result = translateFromGrouperProvisioningEntityField(provisioningEntityWrapper, + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupMembershipAttributeValue()); } if (result != null) { @@ -191,8 +189,10 @@ public List translateGrouperToTargetMemberships( } } - if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.entityAttributes) { - String userMembershipAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeNameForMemberships(); + // if the entity is missing, has an invalid attribute don't bother setting the membership + if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.entityAttributes + && provisioningEntityWrapper.getGrouperTargetEntity() != null) { + String userMembershipAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityMembershipAttributeName(); if (!StringUtils.isEmpty(userMembershipAttribute)) { GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().get(userMembershipAttribute); @@ -200,12 +200,11 @@ public List translateGrouperToTargetMemberships( Object result = null; - if (!StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateExpressionFromMembership())) { - result = runScript(grouperProvisioningConfigurationAttribute.getTranslateExpressionFromMembership(), elVariableMap); - } else if (!StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateFromGroupSyncField())) { - result = translateFromGroupSyncField(provisioningGroupWrapper.getGcGrouperSyncGroup(), - grouperProvisioningConfigurationAttribute.getTranslateFromGroupSyncField()); + if (!StringUtils.isBlank(this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityMembershipAttributeValue())) { + result = translateFromGrouperProvisioningGroupField(provisioningGroupWrapper, + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityMembershipAttributeValue()); } + if (result != null) { if (!grouperProvisioningMembership.getProvisioningEntity().getProvisioningEntityWrapper().isDelete()) { MultiKey validationError = this.getGrouperProvisioner().retrieveGrouperProvisioningValidation().validFieldOrAttributeValue(grouperTargetEntity, grouperProvisioningConfigurationAttribute, result); @@ -287,7 +286,7 @@ public List translateGrouperToTargetMemberships( // set default for membership attribute, it might be blank and have a default value in there if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.groupAttributes) { - String groupMembershipAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeNameForMemberships(); + String groupMembershipAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupMembershipAttributeName(); GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().get(groupMembershipAttribute); if (!StringUtils.isBlank(groupMembershipAttribute) && grouperProvisioningConfigurationAttribute != null && !StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getDefaultValue())) { @@ -295,7 +294,7 @@ public List translateGrouperToTargetMemberships( } } if (this.grouperProvisioner.retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.entityAttributes) { - String entityMembershipAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeNameForMemberships(); + String entityMembershipAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityMembershipAttributeName(); GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().get(entityMembershipAttribute); if (!StringUtils.isBlank(entityMembershipAttribute) && grouperProvisioningConfigurationAttribute != null && !StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getDefaultValue())) { @@ -340,14 +339,13 @@ public List translateGrouperToTargetEntities( // do the required's first for (boolean required : new boolean[] {true, false}) { // attribute translations - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values()) { + for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : entityTargetAttributesInTranslationOrder()) { if (grouperProvisioningConfigurationAttribute.isRequired() == required) { - - if (!grouperProvisioningConfigurationAttribute.isUpdate() && StringUtils.isNotBlank(grouperProvisioningConfigurationAttribute.getTranslateGrouperToMemberSyncField()) - && !GrouperUtil.isBlank(gcGrouperSyncMember.retrieveField(grouperProvisioningConfigurationAttribute.getTranslateGrouperToMemberSyncField()))) { + if (!grouperProvisioningConfigurationAttribute.isUpdate() && StringUtils.isNotBlank(grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningEntityField()) + && !GrouperUtil.isBlank(translateFromGrouperProvisioningEntityField(grouperProvisioningEntity.getProvisioningEntityWrapper(), grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningEntityField()))) { - Object result = gcGrouperSyncMember.retrieveField(grouperProvisioningConfigurationAttribute.getTranslateGrouperToMemberSyncField()); + Object result = translateFromGrouperProvisioningEntityField(grouperProvisioningEntity.getProvisioningEntityWrapper(), grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningEntityField()); String attributeOrFieldName = grouperProvisioningConfigurationAttribute.getName(); grouperTargetEntity.assignAttributeValue(attributeOrFieldName, result); this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateValue(grouperTargetEntity, grouperProvisioningConfigurationAttribute, null); @@ -361,14 +359,15 @@ public List translateGrouperToTargetEntities( String grouperProvisioningEntityField = getTranslateFromGrouperProvisioningEntityField(forCreate, grouperProvisioningConfigurationAttribute); if (!StringUtils.isBlank(expressionToUse) || !StringUtils.isBlank(staticValuesToUse) || !StringUtils.isBlank(grouperProvisioningEntityField) - || !StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { + || this.grouperProvisioner.retrieveGrouperProvisioningBehavior().isEntityAttributeNameHasCache(grouperProvisioningConfigurationAttribute.getName())) { Object result = attributeTranslation( grouperTargetEntity.retrieveAttributeValue(grouperProvisioningConfigurationAttribute.getName()), elVariableMap, forCreate, grouperProvisioningConfigurationAttribute, null, grouperProvisioningEntity.getProvisioningEntityWrapper()); - if (!StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateGrouperToMemberSyncField())) { - gcGrouperSyncMember.assignField(grouperProvisioningConfigurationAttribute.getTranslateGrouperToMemberSyncField(), result); + if (grouperProvisioningConfigurationAttribute.getSyncMemberCacheAttribute() != null + && grouperProvisioningConfigurationAttribute.getSyncMemberCacheAttribute().getSource() == GrouperProvisioningConfigurationAttributeDbCacheSource.grouper) { + gcGrouperSyncMember.assignField(grouperProvisioningConfigurationAttribute.getSyncMemberCacheAttribute().getCacheName(), result); } grouperTargetEntity.assignAttributeValue(grouperProvisioningConfigurationAttribute.getName(), result); this.grouperProvisioner.retrieveGrouperProvisioningAttributeManipulation().manipulateValue(grouperTargetEntity, grouperProvisioningConfigurationAttribute, null); @@ -411,6 +410,10 @@ public List translateGrouperToTargetEntities( return grouperTargetEntities; } + public Collection entityTargetAttributesInTranslationOrder() { + return this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values(); + } + public List translateGrouperToTargetGroups(List grouperProvisioningGroups, boolean includeDelete, boolean forCreate) { List scripts = GrouperUtil.nonNull(GrouperUtil.nonNull( @@ -442,13 +445,13 @@ public List translateGrouperToTargetGroups(List translateGrouperToTargetGroups(List translateGrouperToTargetGroups(List groupAttributesInTranslationOrder() { + return this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values(); } - + /** * translate from gc grouper sync entity and field name to the value - * @param gcGrouperSyncEntity + * @param provisioningEntityWrapper * @param field * @return the value */ - public Object translateFromGrouperProvisioningEntityField(ProvisioningEntity provisioningEntity, String field) { + public Object translateFromGrouperProvisioningEntityField(ProvisioningEntityWrapper provisioningEntityWrapper, String field) { - if (StringUtils.equals("id", field)) { - return provisioningEntity.getId(); - } - if (StringUtils.equals("email", field)) { - return provisioningEntity.getEmail(); - } - if (StringUtils.equals("loginid", field)) { - return GrouperUtil.stringValue(provisioningEntity.getLoginId()); - } - if (StringUtils.equals("name", field)) { - return GrouperUtil.stringValue(provisioningEntity.getName()); - } - if (StringUtils.equals("subjectId", field)) { - return GrouperUtil.stringValue(provisioningEntity.getSubjectId()); - } - if (StringUtils.equals("subjectSourceId", field)) { - return GrouperUtil.stringValue(provisioningEntity.retrieveAttributeValueString("subjectSourceId")); - } - if (StringUtils.equals("description", field)) { - return GrouperUtil.stringValue(provisioningEntity.retrieveAttributeValueString("description")); + // "id", "email", "loginid", "memberId", "entityAttributeValueCache0", "entityAttributeValueCache1", "entityAttributeValueCache2", "entityAttributeValueCache3", "name", "subjectId", "subjectSourceId", "description", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2" + if (provisioningEntityWrapper == null) { + return null; } - if (StringUtils.equals("subjectIdentifier0", field)) { - return GrouperUtil.stringValue(provisioningEntity.retrieveAttributeValueString("subjectIdentifier0")); + + ProvisioningEntity provisioningEntity = provisioningEntityWrapper.getGrouperProvisioningEntity(); + + if (provisioningEntity != null) { + + if (StringUtils.equals("id", field) && !StringUtils.isBlank(provisioningEntity.getId())) { + return provisioningEntity.getId(); + } + if (StringUtils.equals("email", field)) { + return provisioningEntity.getEmail(); + } + if (StringUtils.equals("loginid", field)) { + return provisioningEntity.getLoginId(); + } + if (StringUtils.equals("name", field)) { + return provisioningEntity.getName(); + } + if (StringUtils.equals("subjectId", field) && !StringUtils.isBlank(provisioningEntity.getSubjectId())) { + return provisioningEntity.getSubjectId(); + } + if (StringUtils.equals("subjectSourceId", field) && !StringUtils.isBlank(provisioningEntity.getSubjectSourceId())) { + return provisioningEntity.getSubjectSourceId(); + } + if (StringUtils.equals("description", field)) { + return provisioningEntity.getDescription(); + } + if (StringUtils.equals("subjectIdentifier0", field) && !StringUtils.isBlank(provisioningEntity.getSubjectIdentifier0())) { + return provisioningEntity.getSubjectIdentifier0(); + } + if (StringUtils.equals("subjectIdentifier1", field)) { + return provisioningEntity.getSubjectIdentifier1(); + } + if (StringUtils.equals("subjectIdentifier2", field)) { + return provisioningEntity.getSubjectIdentifier2(); + } } - if (StringUtils.equals("subjectIdentifier1", field)) { - return GrouperUtil.stringValue(provisioningEntity.retrieveAttributeValueString("subjectIdentifier1")); + + GcGrouperSyncMember gcGrouperSyncMember = provisioningEntityWrapper.getGcGrouperSyncMember(); + + if (gcGrouperSyncMember != null) { + if (StringUtils.equals("id", field)) { + return gcGrouperSyncMember.getId(); + } + if (StringUtils.equals("subjectId", field)) { + return gcGrouperSyncMember.getSubjectId(); + } + if (StringUtils.equals("subjectSourceId", field)) { + return gcGrouperSyncMember.getSourceId(); + } + if (StringUtils.equals("subjectIdentifier", field)) { + return gcGrouperSyncMember.getSubjectIdentifier(); + } + if (StringUtils.equals("entityAttributeValueCache0", field)) { + return gcGrouperSyncMember.getEntityAttributeValueCache0(); + } + if (StringUtils.equals("entityAttributeValueCache1", field)) { + return gcGrouperSyncMember.getEntityAttributeValueCache1(); + } + if (StringUtils.equals("entityAttributeValueCache2", field)) { + return gcGrouperSyncMember.getEntityAttributeValueCache2(); + } + if (StringUtils.equals("entityAttributeValueCache3", field)) { + return gcGrouperSyncMember.getEntityAttributeValueCache3(); + } } - if (StringUtils.equals("subjectIdentifier2", field)) { - return GrouperUtil.stringValue(provisioningEntity.retrieveAttributeValueString("subjectIdentifier2")); + + //if we couldnt find the data but the field was ok, its just null + if (StringUtils.equalsAny(field, "id", "email", "loginid", "memberId", "entityAttributeValueCache0", + "entityAttributeValueCache1", "entityAttributeValueCache2", "entityAttributeValueCache3", "name", + "subjectId", "subjectSourceId", "description", "subjectIdentifier", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2")) { + return null; } + throw new RuntimeException("Not expecting grouperProvisioningEntityField: '" + field + "'"); } - /** - * translate from gc grouper sync member and field name to the value - * @param gcGrouperSyncMember - * @param field - * @return the value - */ - public Object translateFromMemberSyncField(GcGrouperSyncMember gcGrouperSyncMember, String field) { - - if (StringUtils.equals("memberId", field)) { - return gcGrouperSyncMember.getMemberId(); - } - if (StringUtils.equals("subjectId", field)) { - return gcGrouperSyncMember.getSubjectId(); - } - if (StringUtils.equals("subjectIdentifier", field)) { - return gcGrouperSyncMember.getSubjectIdentifier(); - } - if (StringUtils.equals("memberFromId2", field)) { - return gcGrouperSyncMember.getMemberFromId2(); - } - if (StringUtils.equals("memberFromId3", field)) { - return gcGrouperSyncMember.getMemberFromId3(); - } - if (StringUtils.equals("memberToId2", field)) { - return gcGrouperSyncMember.getMemberToId2(); - } - if (StringUtils.equals("memberToId3", field)) { - return gcGrouperSyncMember.getMemberToId3(); - } - throw new RuntimeException("Not expecting memberSyncField: '" + field + "'"); - } - public Object attributeTranslation(Object currentValue, Map elVariableMap, boolean forCreate, GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute, ProvisioningGroupWrapper provisioningGroupWrapper, ProvisioningEntityWrapper provisioningEntityWrapper) { @@ -645,60 +633,72 @@ public Object attributeTranslation(Object currentValue, Map elVa translate = true; } else if (provisioningGroupWrapper != null && provisioningGroupWrapper.getGrouperProvisioningGroup() != null && !StringUtils.isBlank(grouperProvisioningGroupField)) { - result = translateFromGrouperProvisioningGroupField(provisioningGroupWrapper.getGrouperProvisioningGroup(), + result = translateFromGrouperProvisioningGroupField(provisioningGroupWrapper, grouperProvisioningGroupField); translate = true; } else if (provisioningEntityWrapper != null && provisioningEntityWrapper.getGrouperProvisioningEntity() != null && !StringUtils.isBlank(grouperProvisioningEntityField)) { - result = translateFromGrouperProvisioningEntityField(provisioningEntityWrapper.getGrouperProvisioningEntity(), + result = translateFromGrouperProvisioningEntityField(provisioningEntityWrapper, grouperProvisioningEntityField); translate = true; - } else if (provisioningGroupWrapper != null && provisioningGroupWrapper.getGcGrouperSyncGroup() != null && !StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateFromGroupSyncField())) { - result = translateFromGroupSyncField(provisioningGroupWrapper.getGcGrouperSyncGroup(), - grouperProvisioningConfigurationAttribute.getTranslateFromGroupSyncField()); - translate = true; - } else if (provisioningEntityWrapper != null && provisioningEntityWrapper.getGcGrouperSyncMember() != null && !StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateFromMemberSyncField())) { - result = translateFromMemberSyncField(provisioningEntityWrapper.getGcGrouperSyncMember(), - grouperProvisioningConfigurationAttribute.getTranslateFromMemberSyncField()); - translate = true; - } else if (provisioningGroupWrapper != null && provisioningGroupWrapper.getGcGrouperSyncGroup() != null && !StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateToGroupSyncField())) { - result = translateFromGroupSyncField(provisioningGroupWrapper.getGcGrouperSyncGroup(), - grouperProvisioningConfigurationAttribute.getTranslateToGroupSyncField()); - translate = true; - } else if (provisioningEntityWrapper != null && provisioningEntityWrapper.getGcGrouperSyncMember() != null && !StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { - result = translateFromMemberSyncField(provisioningEntityWrapper.getGcGrouperSyncMember(), - grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField()); - translate = true; + } else { + if (provisioningGroupWrapper != null && provisioningGroupWrapper.getGcGrouperSyncGroup() != null + && grouperProvisioningConfigurationAttribute.getGrouperProvisioningConfigurationAttributeType() == GrouperProvisioningConfigurationAttributeType.group) { + // look for grouper source first, then target + for (GrouperProvisioningConfigurationAttributeDbCache groupCache : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()) { + if (groupCache != null && StringUtils.equals(groupCache.getAttributeName(), grouperProvisioningConfigurationAttribute.getName()) + && groupCache.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.attribute) { + result = translateFromGrouperProvisioningGroupField(provisioningGroupWrapper, + "groupAttributeValueCache" + groupCache.getIndex()); + translate = true; + break; + } + } + } + if (provisioningEntityWrapper != null && provisioningEntityWrapper.getGcGrouperSyncMember() != null + && grouperProvisioningConfigurationAttribute.getGrouperProvisioningConfigurationAttributeType() == GrouperProvisioningConfigurationAttributeType.entity) { + // look for grouper source first, then target + for (GrouperProvisioningConfigurationAttributeDbCache entityCache : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()) { + if (entityCache != null && StringUtils.equals(entityCache.getAttributeName(), grouperProvisioningConfigurationAttribute.getName()) + && entityCache.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.attribute) { + result = translateFromGrouperProvisioningEntityField(provisioningEntityWrapper, + "entityAttributeValueCache" + entityCache.getIndex()); + translate = true; + break; + } + } + } } + // TODO still translate if in cache, maybe have both values? if (translate) { - if (GrouperUtil.isBlank(result) && provisioningEntityWrapper != null && provisioningEntityWrapper.isDelete() && provisioningEntityWrapper.getGcGrouperSyncMember() != null) { - if (StringUtils.isNotBlank(grouperProvisioningConfigurationAttribute.getTranslateGrouperToMemberSyncField())) { - result = provisioningEntityWrapper.getGcGrouperSyncMember().retrieveField(grouperProvisioningConfigurationAttribute.getTranslateGrouperToMemberSyncField()); - } - - if (StringUtils.isNotBlank(grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { - result = provisioningEntityWrapper.getGcGrouperSyncMember().retrieveField(grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField()); + if (GrouperUtil.isBlank(result) && provisioningEntityWrapper != null && provisioningEntityWrapper.isDelete() + && provisioningEntityWrapper.getGcGrouperSyncMember() != null + && grouperProvisioningConfigurationAttribute.getGrouperProvisioningConfigurationAttributeType() == GrouperProvisioningConfigurationAttributeType.entity) { + + for (GrouperProvisioningConfigurationAttributeDbCache entityCache : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getEntityAttributeDbCaches()) { + if (entityCache != null && StringUtils.equals(entityCache.getAttributeName(), grouperProvisioningConfigurationAttribute.getName()) + && entityCache.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.attribute) { + result = translateFromGrouperProvisioningEntityField(provisioningEntityWrapper, + "entityAttributeValueCache" + entityCache.getIndex()); + break; + } } } - if (GrouperUtil.isBlank(result) && provisioningGroupWrapper != null && provisioningGroupWrapper.isDelete() && provisioningGroupWrapper.getGcGrouperSyncGroup() != null) { - if (StringUtils.isNotBlank(grouperProvisioningConfigurationAttribute.getTranslateGrouperToMemberSyncField())) { - result = provisioningGroupWrapper.getGcGrouperSyncGroup().retrieveField(grouperProvisioningConfigurationAttribute.getTranslateGrouperToMemberSyncField()); - } - - if (StringUtils.isNotBlank(grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField())) { - result = provisioningGroupWrapper.getGcGrouperSyncGroup().retrieveField(grouperProvisioningConfigurationAttribute.getTranslateToMemberSyncField()); + if (GrouperUtil.isBlank(result) && provisioningGroupWrapper != null && provisioningGroupWrapper.isDelete() + && provisioningGroupWrapper.getGcGrouperSyncGroup() != null + && grouperProvisioningConfigurationAttribute.getGrouperProvisioningConfigurationAttributeType() == GrouperProvisioningConfigurationAttributeType.group) { + for (GrouperProvisioningConfigurationAttributeDbCache groupCache : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()) { + if (groupCache != null && StringUtils.equals(groupCache.getAttributeName(), grouperProvisioningConfigurationAttribute.getName()) + && groupCache.getType() == GrouperProvisioningConfigurationAttributeDbCacheType.attribute) { + result = translateFromGrouperProvisioningGroupField(provisioningGroupWrapper, + "groupAttributeValueCache" + groupCache.getIndex()); + break; + } } } - if (!StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateGrouperToGroupSyncField())) { - provisioningGroupWrapper.getGcGrouperSyncGroup().assignField(grouperProvisioningConfigurationAttribute.getTranslateGrouperToGroupSyncField(), result); - } - if (!StringUtils.isBlank(grouperProvisioningConfigurationAttribute.getTranslateGrouperToMemberSyncField())) { - provisioningEntityWrapper.getGcGrouperSyncMember().assignField(grouperProvisioningConfigurationAttribute.getTranslateGrouperToMemberSyncField(), result); - } - return result; } return currentValue; @@ -727,20 +727,13 @@ public void idTargetGroups(List targetGroups) { return; } - String groupIdScript = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupMatchingIdExpression(); - - String groupIdAttribute = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupMatchingIdAttribute(); + String groupIdScript = null; // this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupMatchingIdExpression(); - if (StringUtils.isBlank(groupIdScript) && StringUtils.isBlank(groupIdAttribute)) { - - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetGroupAttributeNameToConfig().values()) { - if (grouperProvisioningConfigurationAttribute.isMatchingId()) { - groupIdAttribute = grouperProvisioningConfigurationAttribute.getName(); - break; - } - } - + String groupIdAttribute = null; + if (GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupMatchingAttributes()) > 0) { + groupIdAttribute = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupMatchingAttributes().get(0).getName(); } + if (StringUtils.isBlank(groupIdScript) && StringUtils.isBlank(groupIdAttribute)) { return; } @@ -763,7 +756,7 @@ public void idTargetGroups(List targetGroups) { id = runScript(groupIdScript, elVariableMap); } else { - throw new RuntimeException("Must have groupMatchingIdField, groupMatchingIdAttribute, or groupMatchingIdExpression"); + throw new RuntimeException("Must have groupMatchingIdAttribute, or groupMatchingIdExpression"); } id = massageToString(id, 2); if (!GrouperUtil.isBlank(id) && targetGroup.getProvisioningGroupWrapper() != null) { @@ -780,21 +773,14 @@ public void idTargetEntities(List targetEntities) { return; } - String entityIdScript = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityMatchingIdExpression(); - - String entityIdAttribute = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityMatchingIdAttribute(); + String entityIdScript = null; // this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityMatchingIdExpression(); - if (StringUtils.isBlank(entityIdScript) && StringUtils.isBlank(entityIdAttribute)) { - - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetEntityAttributeNameToConfig().values()) { - if (grouperProvisioningConfigurationAttribute.isMatchingId()) { - entityIdAttribute = grouperProvisioningConfigurationAttribute.getName(); - break; - } - } - + String entityIdAttribute = null; + + if (GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityMatchingAttributes()) > 0) { + entityIdAttribute = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityMatchingAttributes().get(0).getName(); } - + if (StringUtils.isBlank(entityIdScript) && StringUtils.isBlank(entityIdAttribute)) { return; } @@ -817,7 +803,7 @@ public void idTargetEntities(List targetEntities) { id = runScript(entityIdScript, elVariableMap); } else { - throw new RuntimeException("Must have entityMatchingIdField, entityMatchingIdAttribute, or entityMatchingIdExpression"); + throw new RuntimeException("Must have entityMatchingIdAttribute, or entityMatchingIdExpression"); } id = massageToString(id, 2); @@ -863,19 +849,8 @@ public void idTargetMemberships(List targetMemberships) } String membershipIdScript = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getMembershipMatchingIdExpression(); - String membershipIdAttribute = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getMembershipMatchingIdAttribute(); - - if (StringUtils.isBlank(membershipIdScript) && StringUtils.isBlank(membershipIdAttribute)) { - - for (GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute : this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getTargetMembershipAttributeNameToConfig().values()) { - if (grouperProvisioningConfigurationAttribute.isMatchingId()) { - membershipIdAttribute = grouperProvisioningConfigurationAttribute.getName(); - break; - } - } - } + String membershipIdAttribute = null; //this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getMembershipMatchingIdAttribute(); - //this is a legacy typo if (StringUtils.equals(membershipIdAttribute, "provisioningGroupId,provisioningMembershipId")) { membershipIdAttribute = "provisioningGroupId,provisioningEntityId"; @@ -911,7 +886,7 @@ public void idTargetMemberships(List targetMemberships) } else { - throw new RuntimeException("Must have membershipMatchingIdField, membershipMatchingIdAttribute, or membershipMatchingIdExpression"); + throw new RuntimeException("Must have membershipMatchingIdAttribute, or membershipMatchingIdExpression"); } id = massageToString(id, 2); if (!GrouperUtil.isBlank(id) && targetMembership.getProvisioningMembershipWrapper() != null) { @@ -958,37 +933,89 @@ public void matchingIdTargetObjects() { /** * translate from gc grouper sync group and field name to the value - * @param gcGrouperSyncGroup + * @param provisioningGroupWrapper * @param field * @return the value */ - public Object translateFromGrouperProvisioningGroupField(ProvisioningGroup provisioningGroup, String field) { + public Object translateFromGrouperProvisioningGroupField(ProvisioningGroupWrapper provisioningGroupWrapper, String field) { - if (StringUtils.equals("id", field)) { - return provisioningGroup.getId(); - } - if (StringUtils.equals("idIndex", field)) { - return provisioningGroup.getIdIndex(); - } - if (StringUtils.equals("idIndexString", field)) { - return GrouperUtil.stringValue(provisioningGroup.getIdIndex()); - } - if (StringUtils.equals("displayExtension", field)) { - return GrouperUtil.stringValue(provisioningGroup.getDisplayExtension()); - } - if (StringUtils.equals("displayName", field)) { - return GrouperUtil.stringValue(provisioningGroup.getDisplayName()); + // "id", "idIndex", "idIndexString", "displayExtension", "displayName", "extension", "groupAttributeValueCache0", "groupAttributeValueCache1", "groupAttributeValueCache2", "groupAttributeValueCache3", "name", "description" + if (provisioningGroupWrapper == null) { + return null; } - if (StringUtils.equals("extension", field)) { - return GrouperUtil.stringValue(provisioningGroup.getExtension()); + + ProvisioningGroup provisioningGroup = provisioningGroupWrapper.getGrouperProvisioningGroup(); + + if (provisioningGroup != null) { + if (StringUtils.equals("id", field) && !StringUtils.isBlank(provisioningGroup.getId())) { + return provisioningGroup.getId(); + } + if (StringUtils.equals("idIndex", field) && provisioningGroup.getIdIndex() != null) { + return provisioningGroup.getIdIndex(); + } + if (StringUtils.equals("idIndexString", field) && provisioningGroup.getIdIndex() != null) { + return GrouperUtil.stringValue(provisioningGroup.getIdIndex()); + } + if (StringUtils.equals("displayExtension", field)) { + return GrouperUtil.stringValue(provisioningGroup.getDisplayExtension()); + } + if (StringUtils.equals("displayName", field)) { + return GrouperUtil.stringValue(provisioningGroup.getDisplayName()); + } + if (StringUtils.equals("extension", field) && !StringUtils.isBlank(provisioningGroup.getExtension())) { + return GrouperUtil.stringValue(provisioningGroup.getExtension()); + } + if (StringUtils.equals("name", field) && !StringUtils.isBlank(provisioningGroup.getName())) { + return GrouperUtil.stringValue(provisioningGroup.getName()); + } + if (StringUtils.equals("description", field)) { + return GrouperUtil.stringValue(provisioningGroup.retrieveAttributeValueString("description")); + } + } - if (StringUtils.equals("name", field)) { - return GrouperUtil.stringValue(provisioningGroup.getName()); + + GcGrouperSyncGroup gcGrouperSyncGroup = provisioningGroupWrapper.getGcGrouperSyncGroup(); + + if (gcGrouperSyncGroup != null) { + if (StringUtils.equals("id", field)) { + return gcGrouperSyncGroup.getGroupId(); + } + if (StringUtils.equals("idIndex", field)) { + return gcGrouperSyncGroup.getGroupIdIndex(); + } + if (StringUtils.equals("idIndexString", field)) { + return GrouperUtil.stringValue(gcGrouperSyncGroup.getGroupIdIndex()); + } + if (StringUtils.equals("extension", field)) { + return GrouperUtil.extensionFromName(gcGrouperSyncGroup.getGroupName()); + } + if (StringUtils.equals("name", field)) { + return gcGrouperSyncGroup.getGroupName(); + } + if (StringUtils.equals("groupAttributeValueCache0", field)) { + return gcGrouperSyncGroup.getGroupAttributeValueCache0(); + } + if (StringUtils.equals("groupAttributeValueCache1", field)) { + return gcGrouperSyncGroup.getGroupAttributeValueCache1(); + } + if (StringUtils.equals("groupAttributeValueCache2", field)) { + return gcGrouperSyncGroup.getGroupAttributeValueCache2(); + } + if (StringUtils.equals("groupAttributeValueCache3", field)) { + return gcGrouperSyncGroup.getGroupAttributeValueCache3(); + } + } - if (StringUtils.equals("description", field)) { - return GrouperUtil.stringValue(provisioningGroup.retrieveAttributeValueString("description")); + + //if we couldnt find the data but the field was ok, its just null + if (StringUtils.equalsAny(field, "id", "idIndex", "idIndexString", "displayExtension", "displayName", "extension", + "groupAttributeValueCache0", "groupAttributeValueCache1", "groupAttributeValueCache2", "groupAttributeValueCache3", + "name", "description")) { + return null; } + throw new RuntimeException("Not expecting grouperProvisioningGroupField: '" + field + "'"); + } private boolean translateGrouperToTargetAutomatically; @@ -1002,7 +1029,7 @@ public boolean isTranslateGrouperToTargetAutomatically() { return translateGrouperToTargetAutomatically; } - private String getTranslateFromGrouperProvisioningGroupField(boolean forCreate, GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute) { + public String getTranslateFromGrouperProvisioningGroupField(boolean forCreate, GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute) { String expression = grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningGroupField(); boolean hasExpression = !StringUtils.isBlank(expression); String expressionCreateOnly = grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningGroupFieldCreateOnly(); @@ -1017,7 +1044,7 @@ private String getTranslateFromGrouperProvisioningGroupField(boolean forCreate, return expressionToUse; } - private String getTranslateFromGrouperProvisioningEntityField(boolean forCreate, GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute) { + public String getTranslateFromGrouperProvisioningEntityField(boolean forCreate, GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute) { String expression = grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningEntityField(); boolean hasExpression = !StringUtils.isBlank(expression); String expressionCreateOnly = grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningEntityFieldCreateOnly(); @@ -1033,7 +1060,7 @@ private String getTranslateFromGrouperProvisioningEntityField(boolean forCreate, } - private String getTargetExpressionToUse(boolean forCreate, GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute) { + public String getTargetExpressionToUse(boolean forCreate, GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute) { String expression = grouperProvisioningConfigurationAttribute.getTranslateExpression(); boolean hasExpression = !StringUtils.isBlank(expression); String expressionCreateOnly = grouperProvisioningConfigurationAttribute.getTranslateExpressionCreateOnly(); @@ -1048,7 +1075,7 @@ private String getTargetExpressionToUse(boolean forCreate, GrouperProvisioningCo return expressionToUse; } - private String getTranslateFromStaticValuesToUse(boolean forCreate, GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute) { + public String getTranslateFromStaticValuesToUse(boolean forCreate, GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute) { String staticValues = grouperProvisioningConfigurationAttribute.getTranslateFromStaticValues(); boolean hasStaticValues = !StringUtils.isBlank(staticValues); String staticValuesCreateOnly = grouperProvisioningConfigurationAttribute.getTranslateFromStaticValuesCreateOnly(); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningValidation.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningValidation.java index d04cb2dd1f9d..8fd0dc66b6ca 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningValidation.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningValidation.java @@ -66,7 +66,7 @@ public void validateGroups(Collection provisioningGroups, boo String membershipAttributeName = null; if (this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.groupAttributes) { - membershipAttributeName = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupAttributeNameForMemberships(); + membershipAttributeName = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupMembershipAttributeName(); } //check for required attributes @@ -151,7 +151,7 @@ public void validateEntities(Collection provisioningEntities String membershipAttributeName = null; if (this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.entityAttributes) { - membershipAttributeName = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityAttributeNameForMemberships(); + membershipAttributeName = this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getEntityMembershipAttributeName(); } //check for required attributes @@ -552,7 +552,6 @@ public void validateGroupsHaveMembers(Collection provisioning if (!this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().isGroupsRequireMembers()) { return; } - Map groupIdToGroupWrapperToCheck = new HashMap(); @@ -588,6 +587,7 @@ public void validateGroupsHaveMembers(Collection provisioning for (int i=0;i groupIdsBatch = GrouperUtil.batchList(groupIdsList, 900, i); + //TODO make this more efficient List groupIdCounts = new GcDbAccess().sql("select gmlv.group_id, count(*) from grouper_memberships_lw_v gmlv where gmlv.list_name = 'members' " + " and gmlv.group_id in (" + GrouperClientUtils.appendQuestions(groupIdsBatch.size()) + ") group by group_id").addBindVars(groupIdsBatch).selectList(Object[].class); @@ -604,11 +604,16 @@ public void validateGroupsHaveMembers(Collection provisioning ProvisioningGroupWrapper provisioningGroupWrapper = provisioningGroup.getProvisioningGroupWrapper(); ProvisioningGroup grouperProvisioningGroup = provisioningGroupWrapper.getGrouperProvisioningGroup(); Integer count = groupIdToCount.get(grouperProvisioningGroup.getId()); - if (count != null && count == 0) { + if (count == null || count == 0) { + groupsMissingMembers++; assignGroupError(provisioningGroupWrapper, GcGrouperSyncErrorCode.MEM, "Group has no members and members are required"); if (removeInvalid) { iterator.remove(); - + } else { + // remove the target group + if (provisioningGroupWrapper != null) { + provisioningGroupWrapper.setDelete(true); + } } } } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningConfiguration.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningConfiguration.java index 328d073c9f36..086d26af4318 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningConfiguration.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningConfiguration.java @@ -5,20 +5,32 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.RandomUtils; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import edu.internet2.middleware.grouper.GrouperSession; import edu.internet2.middleware.grouper.app.azure.AzureProvisionerConfiguration; import edu.internet2.middleware.grouper.app.config.GrouperConfigurationModuleAttribute; import edu.internet2.middleware.grouper.app.config.GrouperConfigurationModuleBase; +import edu.internet2.middleware.grouper.app.daemon.GrouperDaemonOtherJobProvisioningFullSyncConfiguration; +import edu.internet2.middleware.grouper.app.daemon.GrouperDaemonProvisioningIncrementalSyncConfiguration; import edu.internet2.middleware.grouper.app.duo.DuoProvisionerConfiguration; import edu.internet2.middleware.grouper.app.duo.role.DuoRoleProvisionerConfiguration; import edu.internet2.middleware.grouper.app.google.GoogleProvisionerConfiguration; import edu.internet2.middleware.grouper.app.ldapProvisioning.LdapProvisionerConfiguration; +import edu.internet2.middleware.grouper.app.loader.GrouperLoader; import edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig; import edu.internet2.middleware.grouper.app.messagingProvisioning.MessagingProvisionerConfiguration; import edu.internet2.middleware.grouper.app.scim2Provisioning.GrouperScim2Configuration; import edu.internet2.middleware.grouper.app.sqlProvisioning.SqlProvisionerConfiguration; +import edu.internet2.middleware.grouper.cfg.dbConfig.ConfigItemFormElement; +import edu.internet2.middleware.grouper.exception.GrouperSessionException; +import edu.internet2.middleware.grouper.misc.GrouperSessionHandler; import edu.internet2.middleware.grouper.util.GrouperUtil; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSync; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncDao; @@ -118,6 +130,69 @@ public void deleteConfig(boolean fromUi) { } grouperSync.getGcGrouperSyncDao().delete(); + + // delete full sync and incremental sync daemon + boolean foundConfig = false; + + Pattern pattern = Pattern.compile("^otherJob\\.(.*)\\.provisionerConfigId$"); + Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(pattern); + + for (String configId: configIds) { + String className = "otherJob."+configId+".class"; + String provisionerConfigId = "otherJob."+configId+".provisionerConfigId"; + if (StringUtils.equals(GrouperLoaderConfig.retrieveConfig().propertyValueString(className), GrouperProvisioningFullSyncJob.class.getName()) && + StringUtils.equals(GrouperLoaderConfig.retrieveConfig().propertyValueString(provisionerConfigId), getConfigId() )) { + foundConfig = true; + } + } + + if (foundConfig) { + + GrouperDaemonOtherJobProvisioningFullSyncConfiguration fullSyncConfig = new GrouperDaemonOtherJobProvisioningFullSyncConfiguration(); + fullSyncConfig.setConfigId("provisioner_full_"+getConfigId()); + + fullSyncConfig.deleteConfig(true); + + try { + Scheduler scheduler = GrouperLoader.schedulerFactory().getScheduler(); + + JobKey jobKey = new JobKey(fullSyncConfig.getDaemonJobPrefix()+fullSyncConfig.getConfigId()); + scheduler.deleteJob(jobKey); + } catch (Exception e) { + throw new RuntimeException("Could not delete full sync daemon with job key "+fullSyncConfig.getDaemonJobPrefix()+fullSyncConfig.getConfigId()); + } + + } + + pattern = Pattern.compile("^changeLog\\.consumer\\.(.*)\\.provisionerConfigId$"); + configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(pattern); + foundConfig = false; + + for (String configId: configIds) { + String className = "changeLog.consumer."+configId+".publisher.class"; + String provisionerConfigId = "changeLog.consumer."+configId+".provisionerConfigId"; + if (StringUtils.equals(GrouperLoaderConfig.retrieveConfig().propertyValueString(className), ProvisioningConsumer.class.getName()) && + StringUtils.equals(GrouperLoaderConfig.retrieveConfig().propertyValueString(provisionerConfigId), getConfigId() )) { + foundConfig = true; + } + } + + if (foundConfig) { + GrouperDaemonProvisioningIncrementalSyncConfiguration incrementalSyncConfig = new GrouperDaemonProvisioningIncrementalSyncConfiguration(); + incrementalSyncConfig.setConfigId("provisioner_incremental_"+getConfigId()); + incrementalSyncConfig.deleteConfig(true); + + try { + Scheduler scheduler = GrouperLoader.schedulerFactory().getScheduler(); + + JobKey jobKey = new JobKey(incrementalSyncConfig.getDaemonJobPrefix()+incrementalSyncConfig.getConfigId()); + scheduler.deleteJob(jobKey); + } catch (Exception e) { + throw new RuntimeException("Could not delete incremental sync daemon with job key "+incrementalSyncConfig.getDaemonJobPrefix()+incrementalSyncConfig.getConfigId()); + } + } + + } /** @@ -286,6 +361,153 @@ public void validatePreSave(boolean isInsert, List errorsToDisplay, } } + + public void correctFormFieldsForExpressionLanguageValues() { + + for (GrouperConfigurationModuleAttribute grouperConfigurationModuleAttribute : GrouperUtil.nonNull(this.retrieveAttributes()).values()) { + + if (grouperConfigurationModuleAttribute.isExpressionLanguage()) { + grouperConfigurationModuleAttribute.setFormElement(ConfigItemFormElement.TEXT); + } + + } + + } + + @Override + public void insertConfig(boolean fromUi, StringBuilder message, + List errorsToDisplay, Map validationErrorsToDisplay, + List actionsPerformed) { + + super.insertConfig(fromUi, message, errorsToDisplay, validationErrorsToDisplay, + actionsPerformed); + + if (errorsToDisplay.size() == 0 && validationErrorsToDisplay.size() == 0) { + + GrouperConfigurationModuleAttribute disabledFullSyncAttribute = this.retrieveAttributes().get("addDisabledFullSyncDaemon"); + + if (disabledFullSyncAttribute != null && GrouperUtil.booleanValue(disabledFullSyncAttribute.getValueOrExpressionEvaluation(), false)) { + + boolean foundConfig = false; + + Pattern pattern = Pattern.compile("^otherJob\\.(.*)\\.provisionerConfigId$"); + Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(pattern); + + for (String configId: configIds) { + String className = "otherJob."+configId+".class"; + String provisionerConfigId = "otherJob."+configId+".provisionerConfigId"; + if (StringUtils.equals(GrouperLoaderConfig.retrieveConfig().propertyValueString(className), GrouperProvisioningFullSyncJob.class.getName()) && + StringUtils.equals(GrouperLoaderConfig.retrieveConfig().propertyValueString(provisionerConfigId), getConfigId() )) { + foundConfig = true; + } + } + + + if (!foundConfig) { + + GrouperDaemonOtherJobProvisioningFullSyncConfiguration fullSyncConfig = new GrouperDaemonOtherJobProvisioningFullSyncConfiguration(); + fullSyncConfig.setConfigId("provisioner_full_"+getConfigId()); + + Map attributes = fullSyncConfig.retrieveAttributes(); + + attributes.get("class").setValue("edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningFullSyncJob"); + attributes.get("provisionerConfigId").setValue(this.getConfigId()); + + int hour = RandomUtils.nextInt(3, 8); + int minute = RandomUtils.nextInt(0, 60); + + String cronExpression = "0 "+minute + " " + hour + " * * ?"; + + attributes.get("quartzCron").setValue(cronExpression); + + fullSyncConfig.insertConfig(true, message, errorsToDisplay, validationErrorsToDisplay, new ArrayList()); + + if (errorsToDisplay.size() > 0 || validationErrorsToDisplay.size() > 0) { + return; + } + + try { + GrouperLoader.scheduleJobs(); + Scheduler scheduler = GrouperLoader.schedulerFactory().getScheduler(); + JobKey jobKey = new JobKey(fullSyncConfig.getDaemonJobPrefix()+fullSyncConfig.getConfigId()); + scheduler.pauseJob(jobKey); + } catch (SchedulerException e) { + throw new RuntimeException("Could not pause the job successfully"); + } + + } + + } + + GrouperConfigurationModuleAttribute disabledIncrementalSyncAttribute = this.retrieveAttributes().get("addDisabledIncrementalSyncDaemon"); + + if (disabledIncrementalSyncAttribute != null && GrouperUtil.booleanValue(disabledIncrementalSyncAttribute.getValueOrExpressionEvaluation(), false)) { + + + boolean foundConfig = false; + + Pattern pattern = Pattern.compile("^changeLog\\.consumer\\.(.*)\\.provisionerConfigId$"); + Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(pattern); + + for (String configId: configIds) { + String className = "changeLog.consumer."+configId+".publisher.class"; + String provisionerConfigId = "changeLog.consumer."+configId+".provisionerConfigId"; + if (StringUtils.equals(GrouperLoaderConfig.retrieveConfig().propertyValueString(className), ProvisioningConsumer.class.getName()) && + StringUtils.equals(GrouperLoaderConfig.retrieveConfig().propertyValueString(provisionerConfigId), getConfigId() )) { + foundConfig = true; + } + } + + + if (!foundConfig) { + + GrouperDaemonProvisioningIncrementalSyncConfiguration incrementalSyncConfig = new GrouperDaemonProvisioningIncrementalSyncConfiguration(); + incrementalSyncConfig.setConfigId("provisioner_incremental_"+getConfigId()); + + Map attributes = incrementalSyncConfig.retrieveAttributes(); + + attributes.get("class").setValue("edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbConsumer"); + attributes.get("provisionerConfigId").setValue(this.getConfigId()); + + attributes.get("quartzCron").setValue("0 * * * * ?"); + attributes.get("publisher.class").setValue("edu.internet2.middleware.grouper.app.provisioning.ProvisioningConsumer"); + + GrouperSession.internal_callbackRootGrouperSession(new GrouperSessionHandler() { + + @Override + public Object callback(GrouperSession grouperSession) throws GrouperSessionException { + incrementalSyncConfig.insertConfig(true, message, errorsToDisplay, validationErrorsToDisplay, new ArrayList()); + return null; + } + }); + + if (errorsToDisplay.size() > 0 || validationErrorsToDisplay.size() > 0) { + return; + } + + try { + GrouperLoader.scheduleJobs(); + Scheduler scheduler = GrouperLoader.schedulerFactory().getScheduler(); + JobKey jobKey = new JobKey(incrementalSyncConfig.getDaemonJobPrefix()+incrementalSyncConfig.getConfigId()); + scheduler.pauseJob(jobKey); + } catch (SchedulerException e) { + throw new RuntimeException("Could not pause the job successfully"); + } + + } + + + } + + + } + + + } + + + + } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningEntity.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningEntity.java index ba9b9071f9dc..1ec64029182f 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningEntity.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningEntity.java @@ -15,6 +15,87 @@ */ public class ProvisioningEntity extends ProvisioningUpdatable { + /** + * + * @return subjectIdentifier0 + */ + public String getSubjectIdentifier0() { + return this.retrieveAttributeValueString("subjectIdentifier0"); + } + + /** + * + * @param subjectIdentifier0 + */ + public void setSubjectIdentifier0(String subjectIdentifier0) { + this.assignAttributeValue("subjectIdentifier0", subjectIdentifier0); + } + + /** + * + * @return subjectIdentifier1 + */ + public String getSubjectIdentifier1() { + return this.retrieveAttributeValueString("subjectIdentifier1"); + } + + /** + * + * @param subjectIdentifier1 + */ + public void setSubjectIdentifier1(String subjectIdentifier1) { + this.assignAttributeValue("subjectIdentifier1", subjectIdentifier1); + } + + /** + * + * @return subjectIdentifier2 + */ + public String getSubjectIdentifier2() { + return this.retrieveAttributeValueString("subjectIdentifier2"); + } + + /** + * + * @param subjectIdentifier2 + */ + public void setSubjectIdentifier2(String subjectIdentifier2) { + this.assignAttributeValue("subjectIdentifier2", subjectIdentifier2); + } + + + /** + * + * @return description + */ + public String getDescription() { + return this.retrieveAttributeValueString("description"); + } + + /** + * + * @param description + */ + public void setDescription(String description) { + this.assignAttributeValue("description", description); + } + + /** + * + * @return subject source id + */ + public String getSubjectSourceId() { + return this.retrieveAttributeValueString("subjectSourceId"); + } + + /** + * + * @param subjectSourceId + */ + public void setSubjectSourceId(String subjectSourceId) { + this.assignAttributeValue("subjectSourceId", subjectSourceId); + } + /** * * @return @@ -62,7 +143,7 @@ public String getLoginId() { * @param login1 */ public void setLoginId(String login1) { - this.assignAttributeValue("login", login1); + this.assignAttributeValue("loginId", login1); } /** diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningEntityAttributeDropdownOptions.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningEntityAttributeDropdownOptions.java new file mode 100644 index 000000000000..9319ebbcf5de --- /dev/null +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningEntityAttributeDropdownOptions.java @@ -0,0 +1,54 @@ +package edu.internet2.middleware.grouper.app.provisioning; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import edu.internet2.middleware.grouper.app.config.GrouperConfigurationModuleAttribute; +import edu.internet2.middleware.grouper.cfg.dbConfig.OptionValueDriver; +import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClient.collections.MultiKey; +import edu.internet2.middleware.grouperClientExt.org.apache.commons.lang3.StringUtils; + +public class ProvisioningEntityAttributeDropdownOptions implements OptionValueDriver { + + private Map configSuffixToConfigModuleAttribute; + + + @Override + public void setConfigSuffixToConfigModuleAttribute( + Map configSuffixToConfigModuleAttribute) { + + this.configSuffixToConfigModuleAttribute = configSuffixToConfigModuleAttribute; + + } + + + + @Override + public List retrieveKeysAndLabels() { + + List result = new ArrayList(); + + GrouperConfigurationModuleAttribute grouperConfigurationModuleAttribute = configSuffixToConfigModuleAttribute.get("numberOfEntityAttributes"); + if (grouperConfigurationModuleAttribute != null) { + + int countOfAttributes = GrouperUtil.intValue(grouperConfigurationModuleAttribute.getValueOrExpressionEvaluation(), 0); + + for (int i=0; i configSuffixToConfigModuleAttribute; + + + @Override + public void setConfigSuffixToConfigModuleAttribute( + Map configSuffixToConfigModuleAttribute) { + + this.configSuffixToConfigModuleAttribute = configSuffixToConfigModuleAttribute; + + } + + + + @Override + public List retrieveKeysAndLabels() { + + // alpha order + Set options = new TreeSet(); + options.add("entityAttributeValueCache0"); + options.add("entityAttributeValueCache1"); + options.add("entityAttributeValueCache2"); + options.add("entityAttributeValueCache3"); + options.add("subjectId"); + options.add("subjectIdentifier"); + + GrouperConfigurationModuleAttribute grouperConfigurationModuleAttribute = configSuffixToConfigModuleAttribute.get("numberOfEntityAttributes"); + if (grouperConfigurationModuleAttribute != null) { + + int countOfAttributes = GrouperUtil.intValue(grouperConfigurationModuleAttribute.getValueOrExpressionEvaluation(), 0); + + for (int i=0; i result = new ArrayList(); + for (String option : options) { + result.add(new MultiKey(option, option)); + } + + return result; + } + +} diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroup.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroup.java index 097d10a7d258..ad29e075110b 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroup.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroup.java @@ -1,10 +1,15 @@ package edu.internet2.middleware.grouper.app.provisioning; +import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.apache.commons.lang.StringUtils; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + import edu.internet2.middleware.grouper.util.GrouperUtil; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncMembership; @@ -15,6 +20,23 @@ */ public class ProvisioningGroup extends ProvisioningUpdatable { + public static void main(String[] args) { + ProvisioningGroup provisioningGroup = new ProvisioningGroup(); + provisioningGroup.assignAttributeValue("name", "someName"); + provisioningGroup.assignAttributeValue("id", "abc123"); + provisioningGroup.addAttributeValue("member", "jsmith"); + provisioningGroup.addAttributeValue("member", "ajackson"); + provisioningGroup.addAttributeValue("member", "tjohnson"); + provisioningGroup.addAttributeValue("objectClass", "groupOfNames"); + provisioningGroup.addAttributeValue("objectClass", "top"); + provisioningGroup.addAttributeValue("objectClass", "memberGroup"); + provisioningGroup.assignAttributeValue("description", "This is the description of the group"); + provisioningGroup.assignAttributeValue("displayName", "Some name"); + provisioningGroup.assignAttributeValue("uuid", "abc123xyz456"); + String json = provisioningGroup.toJsonForCache("member"); + System.out.println(json); + } + private ProvisioningGroupWrapper provisioningGroupWrapper; /** @@ -241,11 +263,8 @@ public boolean canDeleteAttributeValue(String name, Object deleteValue) { * @param value */ public String retrieveAttributeValueString(GrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute) { - return GrouperUtil.stringValue(this.retrieveAttributeValue(grouperProvisioningConfigurationAttribute)); - } - /** * base on attribute get the value diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroupAttributeDropdownOptions.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroupAttributeDropdownOptions.java index 1ea9ed1c238d..f4a3fd1ff7fa 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroupAttributeDropdownOptions.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroupAttributeDropdownOptions.java @@ -1,51 +1,51 @@ -package edu.internet2.middleware.grouper.app.provisioning; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import edu.internet2.middleware.grouper.app.config.GrouperConfigurationModuleAttribute; -import edu.internet2.middleware.grouper.cfg.dbConfig.OptionValueDriver; -import edu.internet2.middleware.grouper.util.GrouperUtil; -import edu.internet2.middleware.grouperClient.collections.MultiKey; -import edu.internet2.middleware.grouperClientExt.org.apache.commons.lang3.StringUtils; - -public class ProvisioningGroupAttributeDropdownOptions implements OptionValueDriver { - - private Map configSuffixToConfigModuleAttribute; - - - @Override - public void setConfigSuffixToConfigModuleAttribute( - Map configSuffixToConfigModuleAttribute) { - - this.configSuffixToConfigModuleAttribute = configSuffixToConfigModuleAttribute; - - } - - - - @Override - public List retrieveKeysAndLabels() { - - GrouperConfigurationModuleAttribute grouperConfigurationModuleAttribute = configSuffixToConfigModuleAttribute.get("numberOfGroupAttributes"); - int countOfAttributes = GrouperUtil.intValue(grouperConfigurationModuleAttribute.getValueOrExpressionEvaluation(), 0); - - List result = new ArrayList(); - - for (int i=0; i configSuffixToConfigModuleAttribute; + + + @Override + public void setConfigSuffixToConfigModuleAttribute( + Map configSuffixToConfigModuleAttribute) { + + this.configSuffixToConfigModuleAttribute = configSuffixToConfigModuleAttribute; + + } + + + + @Override + public List retrieveKeysAndLabels() { + + GrouperConfigurationModuleAttribute grouperConfigurationModuleAttribute = configSuffixToConfigModuleAttribute.get("numberOfGroupAttributes"); + int countOfAttributes = GrouperUtil.intValue(grouperConfigurationModuleAttribute.getValueOrExpressionEvaluation(), 0); + + List result = new ArrayList(); + + for (int i=0; i configSuffixToConfigModuleAttribute; + + + @Override + public void setConfigSuffixToConfigModuleAttribute( + Map configSuffixToConfigModuleAttribute) { + + this.configSuffixToConfigModuleAttribute = configSuffixToConfigModuleAttribute; + + } + + + + @Override + public List retrieveKeysAndLabels() { + + // alpha order + Set options = new TreeSet(); + options.add("groupAttributeValueCache0"); + options.add("groupAttributeValueCache1"); + options.add("groupAttributeValueCache2"); + options.add("groupAttributeValueCache3"); + options.add("id"); + options.add("idIndexString"); + options.add("name"); + options.add("extension"); + + GrouperConfigurationModuleAttribute grouperConfigurationModuleAttribute = configSuffixToConfigModuleAttribute.get("numberOfGroupAttributes"); + if (grouperConfigurationModuleAttribute != null) { + + int countOfAttributes = GrouperUtil.intValue(grouperConfigurationModuleAttribute.getValueOrExpressionEvaluation(), 0); + + for (int i=0; i result = new ArrayList(); + for (String option : options) { + result.add(new MultiKey(option, option)); + } + + return result; + } + +} diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroupWrapper.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroupWrapper.java index e823d770dac5..b2a094cf44d7 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroupWrapper.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroupWrapper.java @@ -5,6 +5,38 @@ public class ProvisioningGroupWrapper { + private boolean grouperTargetGroupFromCacheInitted = false; + private ProvisioningGroup grouperTargetGroupFromCache; + + //TODO finish this for cached objects + public ProvisioningGroup getGrouperTargetGroupFromCache() { + if (grouperTargetGroupFromCacheInitted + || this.gcGrouperSyncGroup == null || this.grouperProvisioner == null) { + return grouperTargetGroupFromCache; + } + + // see if there is an object cached + for (GrouperProvisioningConfigurationAttributeDbCache cache : + this.grouperProvisioner.retrieveGrouperProvisioningConfiguration().getGroupAttributeDbCaches()) { + if (cache == null + || cache.getSource() != GrouperProvisioningConfigurationAttributeDbCacheSource.grouper + || cache.getType() != GrouperProvisioningConfigurationAttributeDbCacheType.object) { + continue; + } + + } + return grouperTargetGroupFromCache; + } + + private boolean targetProvisioningGroupFromCacheInitted = false; + private ProvisioningGroup targetProvisioningGroupFromCache; + + + + public ProvisioningGroup getTargetProvisioningGroupFromCache() { + return targetProvisioningGroupFromCache; + } + /** * if this object should not be provisioned because there is an error, list it here */ diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningMembershipAttributeDropdownOptions.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningMembershipAttributeDropdownOptions.java new file mode 100644 index 000000000000..71fd4ad2708b --- /dev/null +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/ProvisioningMembershipAttributeDropdownOptions.java @@ -0,0 +1,51 @@ +package edu.internet2.middleware.grouper.app.provisioning; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import edu.internet2.middleware.grouper.app.config.GrouperConfigurationModuleAttribute; +import edu.internet2.middleware.grouper.cfg.dbConfig.OptionValueDriver; +import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClient.collections.MultiKey; +import edu.internet2.middleware.grouperClientExt.org.apache.commons.lang3.StringUtils; + +public class ProvisioningMembershipAttributeDropdownOptions implements OptionValueDriver { + + private Map configSuffixToConfigModuleAttribute; + + + @Override + public void setConfigSuffixToConfigModuleAttribute( + Map configSuffixToConfigModuleAttribute) { + + this.configSuffixToConfigModuleAttribute = configSuffixToConfigModuleAttribute; + + } + + + + @Override + public List retrieveKeysAndLabels() { + + GrouperConfigurationModuleAttribute grouperConfigurationModuleAttribute = configSuffixToConfigModuleAttribute.get("numberOfMembershipAttributes"); + int countOfAttributes = GrouperUtil.intValue(grouperConfigurationModuleAttribute.getValueOrExpressionEvaluation(), 0); + + List result = new ArrayList(); + + for (int i=0; i attributeNames = rootNode.fieldNames(); + while(attributeNames.hasNext()) { + String attributeName = attributeNames.next(); + JsonNode fieldNode = rootNode.get(attributeName); + if (fieldNode instanceof NullNode) { + continue; + } + if (StringUtils.equals(attributeName, TRUNC_ATTRS)) { + // this is an array of strings + if (fieldNode != null) { + + if (fieldNode.isArray()) { + this.truncatedAttributeNames = new HashSet(); + for (int i=0;i truncatedAttributeNames; + + /** + * if hydrating from json cache, these are the attribute names that were truncated + * @return the attribute names that were truncated + */ + public Set getTruncatedAttributeNames() { + return this.truncatedAttributeNames; + } + + /** + * convert to json for cache, keep under 4k, keep track of truncated fields + * @param membershipAttribute + * @return the json of this group for cache + */ + public String toJsonForCache(String membershipAttribute) { + + Map theAttributes = this.getAttributes(); + Map attributeSize = new HashMap(); + Integer overByChars = null; + + ObjectNode objectNode = GrouperUtil.jsonJacksonNode(); + Set theTruncatedAttributeNames = new TreeSet(); + + // max length of each field as we try to fit into 4k + for (int truncateTo : new int[] {-1, 2000, 1000, 500, 250, 100}) { + + for (String attributeName : GrouperUtil.nonNull(theAttributes).keySet()) { + + // ignore memberships + if (StringUtils.equals(membershipAttribute, attributeName)) { + continue; + } + + // ignore nulls + Object value = theAttributes.get(attributeName); + if (value == null) { + continue; + } + + if (value instanceof ProvisioningAttribute) { + ProvisioningAttribute provisioningAttribute = (ProvisioningAttribute)value; + value = provisioningAttribute.getValue(); + } + if (value == null) { + continue; + } + + if (value instanceof Integer || value instanceof Long) { + // just add during first pass + if (truncateTo == -1) { + GrouperUtil.jsonJacksonAssignLong(objectNode, attributeName, GrouperUtil.longValue(value)); + } + } else if (value instanceof String) { + + if (truncateTo > -1 && ((String)value).length() > truncateTo && overByChars != null && overByChars > 0) { + + theTruncatedAttributeNames.add(attributeName); + int oldSize = GrouperUtil.intValue(attributeSize.get(attributeName), ((String)value).length()); + overByChars -= oldSize - truncateTo; + value = StringUtils.abbreviate((String)value, truncateTo); + GrouperUtil.jsonJacksonAssignString(objectNode, attributeName, (String)value); + attributeSize.put(attributeName, ((String)value).length()); + } else { + if (truncateTo == -1) { + GrouperUtil.jsonJacksonAssignString(objectNode, attributeName, (String)value); + attributeSize.put(attributeName, ((String)value).length()); + } + } + } else if (value instanceof Collection) { + // if its the first pass or has already been yanked for being too big + if (truncateTo == -1 || !theTruncatedAttributeNames.contains(attributeName)) { + int collectionSize = GrouperUtil.intValue(attributeSize.get(attributeName), -1); + ArrayNode arrayNode = (ArrayNode)objectNode.get(attributeName); + if (collectionSize == -1) { + arrayNode = GrouperUtil.jsonJacksonArrayNode(); + collectionSize = 0; + Collection valueCollection = (Collection)value; + for (Object eachValue : valueCollection) { + if (eachValue == null) { + continue; + } + if (eachValue instanceof Integer) { + collectionSize += 8; + arrayNode.add((Integer)eachValue); + } else if (eachValue instanceof Long) { + collectionSize += 12; + arrayNode.add((Long)eachValue); + } else if (eachValue instanceof String) { + collectionSize += ((String)eachValue).length(); + arrayNode.add((String)eachValue); + } else { + throw new RuntimeException("Invalid collection type: " + eachValue.getClass()); + } + } + attributeSize.put(attributeName, collectionSize); + } + if (truncateTo > -1 && collectionSize > truncateTo && overByChars != null && overByChars > 0) { + + // just skip it + theTruncatedAttributeNames.add(attributeName); + overByChars -= collectionSize; + } else { + + if (truncateTo == -1) { + objectNode.set(attributeName, arrayNode); + } + } + } + } else { + throw new RuntimeException("Invalid field type: " + value.getClass()); + } + + } + if (theTruncatedAttributeNames.size() > 0) { + ArrayNode arrayNode = GrouperUtil.jsonJacksonArrayNode(); + for (String truncatedAttributeName : theTruncatedAttributeNames) { + arrayNode.add(truncatedAttributeName); + } + objectNode.set(TRUNC_ATTRS, arrayNode); + } + String json = GrouperUtil.jsonJacksonToString(objectNode); + if (json.length() <= 3700) { + return json; + } + // add 50 so we can add some truncated fields or whatever + overByChars = 50+json.length() - 3700; + } + + return null; + } + + /** + * see which attribute names are different when comparing to a cached object from json + * note if there is a truncated field, consider that so the same prefix is ok + * @param provisioningUpdatable + * @param membershipAttribute + * @return the changed fields + */ + public Set attributeNamesDifferentForCache(ProvisioningUpdatable provisioningUpdatable, String membershipAttribute) { + + boolean isGroup = this instanceof ProvisioningGroup && provisioningUpdatable instanceof ProvisioningGroup; + boolean isEntity = this instanceof ProvisioningEntity && provisioningUpdatable instanceof ProvisioningEntity; + boolean isMembership = this instanceof ProvisioningMembership && provisioningUpdatable instanceof ProvisioningMembership; + + if (!isGroup && !isEntity && !isMembership) { + throw new RuntimeException("Not expecting object type: " + this.getClass() + " not compatible with " + (provisioningUpdatable == null ? null : provisioningUpdatable.getClass())); + } + + Map thisAttributes = GrouperUtil.nonNull(this.getAttributes()); + Map thatAttributes = GrouperUtil.nonNull(provisioningUpdatable.getAttributes()); + + Set thisTruncatedAttributeNames = GrouperUtil.nonNull(this.getTruncatedAttributeNames()); + Set thatTruncatedAttributeNames = GrouperUtil.nonNull(provisioningUpdatable.getTruncatedAttributeNames()); + + Set differentAttributes = new HashSet(); + + for (String attributeName : GrouperUtil.nonNull(thisAttributes).keySet()) { + + // ignore memberships + if (StringUtils.equals(membershipAttribute, attributeName)) { + continue; + } + + Object thisValue = thisAttributes.get(attributeName); + Object thatValue = thatAttributes.get(attributeName); + + if (thisValue instanceof ProvisioningAttribute) { + ProvisioningAttribute provisioningAttribute = (ProvisioningAttribute)thisValue; + thisValue = provisioningAttribute.getValue(); + } + if (thatValue instanceof ProvisioningAttribute) { + ProvisioningAttribute provisioningAttribute = (ProvisioningAttribute)thatValue; + thatValue = provisioningAttribute.getValue(); + } + + // null or empty is ok + if ((thisValue == null || GrouperUtil.isEmpty(thisValue)) && (thatValue == null || GrouperUtil.isEmpty(thatValue))) { + continue; + } + + + if (thisValue instanceof Collection || thatValue instanceof Collection) { + + if (thisTruncatedAttributeNames.contains(attributeName) || thatTruncatedAttributeNames.contains(attributeName)) { + // we ignore this... + continue; + } + + if (!(thisValue instanceof Collection) || !(thatValue instanceof Collection)) { + differentAttributes.add(attributeName); + continue; + } + + Collection thisCollection = (Collection)thisValue; + Collection thatCollection = (Collection)thatValue; + + if (GrouperUtil.equalsCollectionStringLong(thisCollection, thatCollection)) { + continue; + } + + differentAttributes.add(attributeName); + continue; + } + + // if one is its different + if (thisValue == null || GrouperUtil.isEmpty(thisValue) || thatValue == null || GrouperUtil.isEmpty(thatValue)) { + differentAttributes.add(attributeName); + continue; + } + + if (thisValue instanceof Integer || thisValue instanceof Long || thatValue instanceof Integer || thatValue instanceof Long) { + + if (GrouperUtil.equalsLong(thisValue, thatValue)) { + continue; + } + + differentAttributes.add(attributeName); + continue; + + } + + if (thisValue instanceof String || thatValue instanceof String) { + + thisValue = GrouperUtil.stringValue(thisValue); + thatValue = GrouperUtil.stringValue(thatValue); + + if (thisTruncatedAttributeNames.contains(attributeName)) { + thatValue = StringUtils.abbreviate((String)thatValue, ((String)thisValue).length()); + } + if (thatTruncatedAttributeNames.contains(attributeName)) { + thisValue = StringUtils.abbreviate((String)thisValue, ((String)thatValue).length()); + } + + if (GrouperUtil.equalsString(thisValue, thatValue)) { + continue; + } + + differentAttributes.add(attributeName); + continue; + } + // not sure how it got here + differentAttributes.add(attributeName); + } + return differentAttributes; + } + public String provisioningUpdatableTypeShort() { if (this instanceof ProvisioningGroup) { @@ -255,7 +634,7 @@ public void addAttributeValueForMembership(String name, Object value) { if (provisioningAttribute == null) { // maybe this is a delete? if (this.attributes == null) { - this.attributes = new HashMap(); + this.attributes = new TreeMap(); } provisioningAttribute = new ProvisioningAttribute(); @@ -285,7 +664,7 @@ public void addAttributeValueForMembership(String name, Object value) { public void addAttributeValue(String name, Object value) { if (this.attributes == null) { - this.attributes = new HashMap(); + this.attributes = new TreeMap(); } ProvisioningAttribute provisioningAttribute = this.attributes.get(name); @@ -301,7 +680,7 @@ public void addAttributeValue(String name, Object value) { } if (values == null) { - values = new HashSet(); + values = new TreeSet(); provisioningAttribute.setValue(values); } @@ -317,7 +696,7 @@ public void addAttributeValue(String name, Object value) { public void assignAttributeValue(String name, Object value) { if (this.attributes == null) { - this.attributes = new HashMap(); + this.attributes = new TreeMap(); } ProvisioningAttribute provisioningAttribute = this.attributes.get(name); @@ -499,7 +878,7 @@ protected boolean toStringProvisioningUpdatable(StringBuilder result, boolean fi firstField = false; } - result.append(provisioningObjectChange.getProvisioningObjectChangeAction()).append(" "); + result.append(provisioningObjectChange.getProvisioningObjectChangeAction().name().substring(0, 3)).append(" ").append(provisioningObjectChange.getAttributeName()).append(" "); switch(provisioningObjectChange.getProvisioningObjectChangeAction()) { case insert: result.append(stringValueWithType(provisioningObjectChange.getNewValue())); @@ -590,7 +969,7 @@ public void cloneUpdatable(ProvisioningUpdatable provisioningUpdatable) { Map newAttributes = null; if (this.attributes != null) { - newAttributes = new HashMap(); + newAttributes = new TreeMap(); for (String attributeName : this.attributes.keySet()) { ProvisioningAttribute provisioningAttributeToClone = this.attributes.get(attributeName); ProvisioningAttribute newProvisioningAttribute = null; diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/GrouperProvisionerTargetDaoAdapter.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/GrouperProvisionerTargetDaoAdapter.java index ead865c169be..df8aab7397e3 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/GrouperProvisionerTargetDaoAdapter.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/GrouperProvisionerTargetDaoAdapter.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -16,6 +17,8 @@ import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioner; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningBehaviorMembershipType; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningConfigurationAttribute; +import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningConfigurationAttributeDbCache; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningLists; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningLogCommands; import edu.internet2.middleware.grouper.app.provisioning.ProvisioningAttribute; @@ -238,12 +241,18 @@ public TargetDaoDeleteGroupResponse deleteGroup( } return targetDaoDeleteGroupResponse; } catch (RuntimeException e) { + + GrouperUtil.injectInException(e, targetGroup.toString()); hasError = true; + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("groupDelete")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error deleting group, " + GrouperUtil.getFullStackTrace(e))); + } + if (targetGroup.getProvisioned() == null) { targetGroup.setProvisioned(false); } if (targetGroup.getException() == null) { - GrouperUtil.injectInException(e, targetGroup.toString()); targetGroup.setException(e); } logGroup(targetGroup); @@ -282,12 +291,18 @@ public TargetDaoInsertGroupResponse insertGroup(TargetDaoInsertGroupRequest targ } return targetDaoInsertGroupResponse; } catch (RuntimeException e) { + GrouperUtil.injectInException(e, targetGroup.toString()); hasError = true; + + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("groupInsert")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error inserting group " + GrouperUtil.getFullStackTrace(e))); + } + if (targetGroup.getProvisioned() == null) { targetGroup.setProvisioned(false); } if (targetGroup.getException() == null) { - GrouperUtil.injectInException(e, targetGroup.toString()); targetGroup.setException(e); } logGroup(targetGroup); @@ -444,15 +459,23 @@ public TargetDaoUpdateGroupsResponse updateGroups( } return targetDaoUpdateGroupsResponse; } catch (RuntimeException e) { + boolean first = true; hasError = true; + for (ProvisioningGroup targetGroup : targetDaoUpdateGroupsRequest.getTargetGroups()) { + if(first) { + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("entityUpdate")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error updating groups, e.g. " + (targetGroup == null ? null : targetGroup.toString()) + GrouperUtil.getFullStackTrace(e))); + } + } + first = false; + if (targetGroup.getProvisioned() == null) { targetGroup.setProvisioned(false); } - if (targetGroup.getException() == null) { - GrouperUtil.injectInException(e, targetGroup.toString()); - targetGroup.setException(e); + if (targetGroup.getException() == null) { targetGroup.setException(e); } setExceptionForMembershipsWhenGroupOrEntityAttributes(null, targetGroup, e); } @@ -497,13 +520,20 @@ public TargetDaoDeleteMembershipsResponse deleteMemberships( return targetDaoDeleteMembershipsResponse; } catch (RuntimeException e) { hasError = true; + boolean first = true; for (ProvisioningMembership targetMembership : targetDaoDeleteMembershipsRequest.getTargetMemberships()) { + if(first) { + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("membershipDelete")) { + LOG.error("Error deleting memberships, e.g. " + (targetMembership == null ? null : targetMembership.toString()), e); + } + } + first = false; + if (targetMembership.getProvisioned() == null) { targetMembership.setProvisioned(false); } if (targetMembership.getException() == null) { - GrouperUtil.injectInException(e, targetMembership.toString()); targetMembership.setException(e); } } @@ -650,7 +680,6 @@ public TargetDaoRetrieveIncrementalDataResponse retrieveIncrementalData( } - @Override public TargetDaoRetrieveGroupsResponse retrieveGroups( TargetDaoRetrieveGroupsRequest targetDaoRetrieveGroupsRequest) { @@ -668,9 +697,97 @@ public TargetDaoRetrieveGroupsResponse retrieveGroups( boolean commandLogStarted = false; try { commandLogStarted = commandLogStartLoggingIfConfigured(); - TargetDaoRetrieveGroupsResponse targetDaoRetrieveGroupsResponse = this.wrappedDao.retrieveGroups(targetDaoRetrieveGroupsRequest); - hasError = logGroups(targetDaoRetrieveGroupsResponse.getTargetGroups()); - return targetDaoRetrieveGroupsResponse; + + if (GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupSearchAttributes()) == 0) { + TargetDaoRetrieveGroupsResponse targetDaoRetrieveGroupsResponse = this.wrappedDao.retrieveGroups(targetDaoRetrieveGroupsRequest); + hasError = logGroups(targetDaoRetrieveGroupsResponse.getTargetGroups()); + return targetDaoRetrieveGroupsResponse; + } + + TargetDaoRetrieveGroupsResponse overallResponse = new TargetDaoRetrieveGroupsResponse(); + + List targetGroupsFound = new ArrayList(); + + Set groupsRemainingToFind = new HashSet(targetDaoRetrieveGroupsRequest.getTargetGroups()); + + // cycle through search attributes and past values + int retrieveGroupsFromCache = 0; + int retrieveGroupsFromAlternateSearchAttr = 0; + boolean first = true; + OUTER: for (GrouperProvisioningConfigurationAttribute searchAttribute : this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupSearchAttributes()) { + String searchAttributeName = searchAttribute.getName(); + + // current value or historical values + for (boolean currentValue : new boolean[] {true, false}) { + + Map searchValueToSearchGrouperTargetGroup = new HashMap(); + for (ProvisioningGroup grouperTargetGroup : groupsRemainingToFind) { + if (currentValue) { + // dont worry if dupes... oh well + Object targetProvisioningGroupCurrentValue = grouperTargetGroup.retrieveAttributeValue(searchAttributeName); + if(!GrouperUtil.isBlank(targetProvisioningGroupCurrentValue)) { + searchValueToSearchGrouperTargetGroup.put(targetProvisioningGroupCurrentValue, grouperTargetGroup); + } + } else { + // historical values + Set attributeValues = GrouperProvisioningConfigurationAttributeDbCache.cachedValuesForGroup(grouperTargetGroup, searchAttributeName); + + for (Object attributeValue : GrouperUtil.nonNull(attributeValues)) { + if(!GrouperUtil.isBlank(attributeValue)) { + searchValueToSearchGrouperTargetGroup.put(attributeValue, grouperTargetGroup); + } + } + + } + + } + if (searchValueToSearchGrouperTargetGroup.size() > 0) { + // search based on those + TargetDaoRetrieveGroupsRequest targetDaoRetrieveGroupsRequestNew = new TargetDaoRetrieveGroupsRequest(); + targetDaoRetrieveGroupsRequestNew.setIncludeAllMembershipsIfApplicable(targetDaoRetrieveGroupsRequest.isIncludeAllMembershipsIfApplicable()); + targetDaoRetrieveGroupsRequestNew.setTargetGroups(new ArrayList(searchValueToSearchGrouperTargetGroup.values())); + targetDaoRetrieveGroupsRequestNew.setSearchAttribute(searchAttributeName); + targetDaoRetrieveGroupsRequestNew.setSearchAttributeValues(new HashSet(searchValueToSearchGrouperTargetGroup.keySet())); + + TargetDaoRetrieveGroupsResponse targetDaoRetrieveGroupsResponse = this.wrappedDao.retrieveGroups(targetDaoRetrieveGroupsRequestNew); + hasError = logGroups(targetDaoRetrieveGroupsResponse.getTargetGroups()) || hasError; + + // add these to the overall result + targetGroupsFound.addAll(GrouperUtil.nonNull(targetDaoRetrieveGroupsResponse.getTargetGroups())); + + // pluck each one out from the remaining groups to find + for (ProvisioningGroup retrievedTargetGroup : GrouperUtil.nonNull(targetDaoRetrieveGroupsResponse.getTargetGroups())) { + Object targetGroupValue = retrievedTargetGroup.retrieveAttributeValue(searchAttributeName); + if(!GrouperUtil.isBlank(targetGroupValue)) { + ProvisioningGroup grouperTargetGroup = searchValueToSearchGrouperTargetGroup.get(targetGroupValue); + if (grouperTargetGroup != null) { + if (!currentValue) { + retrieveGroupsFromCache++; + } else if (!first) { + retrieveGroupsFromAlternateSearchAttr++; + } + groupsRemainingToFind.remove(grouperTargetGroup); + } + } + } + } + if (groupsRemainingToFind.size() == 0) { + break OUTER; + } + } + first = false; + } + + if (retrieveGroupsFromAlternateSearchAttr > 0) { + Integer oldCount = GrouperUtil.defaultIfNull((Integer)this.getGrouperProvisioner().getDebugMap().get("retrieveGroupsFromAlternateSearchAttr"), 0); + this.getGrouperProvisioner().getDebugMap().put("retrieveGroupsFromAlternateSearchAttr", oldCount + retrieveGroupsFromAlternateSearchAttr); + } + if (retrieveGroupsFromCache > 0) { + Integer oldCount = GrouperUtil.defaultIfNull((Integer)this.getGrouperProvisioner().getDebugMap().get("retrieveGroupsFromCache"), 0); + this.getGrouperProvisioner().getDebugMap().put("retrieveGroupsFromCache", oldCount + retrieveGroupsFromCache); + } + overallResponse.setTargetGroups(targetGroupsFound); + return overallResponse; } catch (RuntimeException e) { hasError = true; throw e; @@ -1038,6 +1155,167 @@ public TargetDaoRetrieveMembershipsResponse retrieveMemberships( } } + if (this.getGrouperProvisioner().retrieveGrouperProvisioningBehavior().getGrouperProvisioningBehaviorMembershipType() == GrouperProvisioningBehaviorMembershipType.membershipObjects) { + + Map> grouperTargetEntityToGroupIds = new HashMap<>(); + + Map> grouperTargetGroupToEntityIds = new HashMap<>(); + + if (GrouperUtil.booleanValue(this.wrappedDao.getGrouperProvisionerDaoCapabilities().getCanRetrieveMembershipsByEntity(), false) || + GrouperUtil.booleanValue(this.wrappedDao.getGrouperProvisionerDaoCapabilities().getCanRetrieveMembershipsByEntities(), false)) { + + List targetMemberships = targetDaoRetrieveMembershipsRequest.getTargetMemberships(); + + for (Object targetMembership: targetMemberships) { + + ProvisioningMembership grouperTargetMembership = (ProvisioningMembership) targetMembership; + + Set groupIds = grouperTargetEntityToGroupIds.get(grouperTargetMembership.getProvisioningEntity()); + + if (groupIds == null) { + groupIds = new HashSet<>(); + grouperTargetEntityToGroupIds.put(grouperTargetMembership.getProvisioningEntity(), groupIds); + } + groupIds.add(grouperTargetMembership.getProvisioningGroupId()); + + } + } + + if (GrouperUtil.booleanValue(this.wrappedDao.getGrouperProvisionerDaoCapabilities().getCanRetrieveMembershipsByGroup(), false) || + GrouperUtil.booleanValue(this.wrappedDao.getGrouperProvisionerDaoCapabilities().getCanRetrieveMembershipsByGroups(), false)) { + + List targetMemberships = targetDaoRetrieveMembershipsRequest.getTargetMemberships(); + + for (Object targetMembership: targetMemberships) { + + ProvisioningMembership grouperTargetMembership = (ProvisioningMembership) targetMembership; + + Set entityIds = grouperTargetGroupToEntityIds.get(grouperTargetMembership.getProvisioningGroup()); + + if (entityIds == null) { + entityIds = new HashSet<>(); + grouperTargetGroupToEntityIds.put(grouperTargetMembership.getProvisioningGroup(), entityIds); + } + entityIds.add(grouperTargetMembership.getProvisioningEntityId()); + + } + } + + if (GrouperUtil.booleanValue(this.wrappedDao.getGrouperProvisionerDaoCapabilities().getCanRetrieveMembershipsByEntities(), false)) { + + Map entityIdToEntity = new HashMap<>(); + + for (ProvisioningEntity provisioningEntity: grouperTargetEntityToGroupIds.keySet()) { + entityIdToEntity.put(provisioningEntity.getId(), provisioningEntity); + } + + List provisioningMemberships = new ArrayList<>(); + + TargetDaoRetrieveMembershipsByEntitiesRequest request = new TargetDaoRetrieveMembershipsByEntitiesRequest(); + request.setTargetEntities(new ArrayList(entityIdToEntity.values())); + TargetDaoRetrieveMembershipsByEntitiesResponse membershipsByEntities = this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter().retrieveMembershipsByEntities(request); + + + for (Object targetMembershipObj: GrouperUtil.nonNull(membershipsByEntities.getTargetMemberships())) { + + ProvisioningMembership targetMembership = (ProvisioningMembership)targetMembershipObj; + + ProvisioningEntity provisioningEntity = entityIdToEntity.get(targetMembership.getProvisioningEntityId()); + + Set groupIds = grouperTargetEntityToGroupIds.get(provisioningEntity); + + if (groupIds.contains(targetMembership.getProvisioningGroupId())) { + provisioningMemberships.add(targetMembership); + } + + } + + return new TargetDaoRetrieveMembershipsResponse(provisioningMemberships); + + } else if (GrouperUtil.booleanValue(this.wrappedDao.getGrouperProvisionerDaoCapabilities().getCanRetrieveMembershipsByEntity(), false)) { + + List provisioningMemberships = new ArrayList<>(); + + for (ProvisioningEntity provisioningEntity: grouperTargetEntityToGroupIds.keySet()) { + TargetDaoRetrieveMembershipsByEntityResponse membershipsByEntity = this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter().retrieveMembershipsByEntity(new TargetDaoRetrieveMembershipsByEntityRequest(provisioningEntity)); + + Set groupIds = grouperTargetEntityToGroupIds.get(provisioningEntity); + + for (Object targetMembership: GrouperUtil.nonNull(membershipsByEntity.getTargetMemberships())) { + + ProvisioningMembership grouperTargetMembership = (ProvisioningMembership) targetMembership; + + if (groupIds.contains(grouperTargetMembership.getProvisioningGroupId())) { + provisioningMemberships.add(grouperTargetMembership); + } + + } + + } + + return new TargetDaoRetrieveMembershipsResponse(provisioningMemberships); + + } + + if (GrouperUtil.booleanValue(this.wrappedDao.getGrouperProvisionerDaoCapabilities().getCanRetrieveMembershipsByGroups(), false)) { + + Map groupIdToGroup = new HashMap<>(); + + for (ProvisioningGroup provisioningGroup: grouperTargetGroupToEntityIds.keySet()) { + groupIdToGroup.put(provisioningGroup.getId(), provisioningGroup); + } + + List provisioningMemberships = new ArrayList<>(); + + TargetDaoRetrieveMembershipsByGroupsRequest request = new TargetDaoRetrieveMembershipsByGroupsRequest(); + request.setTargetGroups(new ArrayList(groupIdToGroup.values())); + TargetDaoRetrieveMembershipsByGroupsResponse membershipsByGroups = this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter().retrieveMembershipsByGroups(request); + + + for (Object targetMembershipObj: GrouperUtil.nonNull(membershipsByGroups.getTargetMemberships())) { + + ProvisioningMembership targetMembership = (ProvisioningMembership)targetMembershipObj; + + ProvisioningGroup provisioningGroup = groupIdToGroup.get(targetMembership.getProvisioningGroupId()); + + Set entityIds = grouperTargetGroupToEntityIds.get(provisioningGroup); + + if (entityIds.contains(targetMembership.getProvisioningEntityId())) { + provisioningMemberships.add(targetMembership); + } + + } + + return new TargetDaoRetrieveMembershipsResponse(provisioningMemberships); + + } else if (GrouperUtil.booleanValue(this.wrappedDao.getGrouperProvisionerDaoCapabilities().getCanRetrieveMembershipsByGroup(), false)) { + + List provisioningMemberships = new ArrayList<>(); + + for (ProvisioningGroup provisioningGroup: grouperTargetGroupToEntityIds.keySet()) { + TargetDaoRetrieveMembershipsByGroupResponse membershipsByGroup = this.getGrouperProvisioner().retrieveGrouperProvisioningTargetDaoAdapter().retrieveMembershipsByGroup(new TargetDaoRetrieveMembershipsByGroupRequest(provisioningGroup)); + + Set entityIds = grouperTargetGroupToEntityIds.get(provisioningGroup); + + for (Object targetMembership: GrouperUtil.nonNull(membershipsByGroup.getTargetMemberships())) { + + ProvisioningMembership grouperTargetMembership = (ProvisioningMembership) targetMembership; + + if (entityIds.contains(grouperTargetMembership.getProvisioningEntityId())) { + provisioningMemberships.add(grouperTargetMembership); + } + + } + + } + + return new TargetDaoRetrieveMembershipsResponse(provisioningMemberships); + + } + + } + + throw new RuntimeException("Dao cannot retrieve memberships or membership"); } @@ -1102,19 +1380,86 @@ public TargetDaoRetrieveGroupResponse retrieveGroup( targetDaoRetrieveGroupRequest.getTargetGroup().assignSearchFilter(); if (GrouperUtil.booleanValue(this.wrappedDao.getGrouperProvisionerDaoCapabilities().getCanRetrieveGroup(), false)) { + boolean hasError = false; boolean commandLogStarted = false; + int retrieveGroupsFromCache = 0; + int retrieveGroupsFromAlternateSearchAttr = 0; try { commandLogStarted = commandLogStartLoggingIfConfigured(); + + if (GrouperUtil.length(this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupSearchAttributes()) == 0) { + + TargetDaoRetrieveGroupResponse targetDaoRetrieveGroupResponse = this.wrappedDao.retrieveGroup(targetDaoRetrieveGroupRequest); + hasError = logGroup(targetDaoRetrieveGroupRequest.getTargetGroup()); + return targetDaoRetrieveGroupResponse; + } + + TargetDaoRetrieveGroupResponse targetDaoRetrieveGroupResponse = new TargetDaoRetrieveGroupResponse(); + + // cycle through search attributes and past values + boolean first = true; + for (GrouperProvisioningConfigurationAttribute searchAttribute : this.getGrouperProvisioner().retrieveGrouperProvisioningConfiguration().getGroupSearchAttributes()) { + String searchAttributeName = searchAttribute.getName(); - TargetDaoRetrieveGroupResponse targetDaoRetrieveGroupResponse = this.wrappedDao.retrieveGroup(targetDaoRetrieveGroupRequest); - hasError = logGroup(targetDaoRetrieveGroupRequest.getTargetGroup()); + // current value or historical values + for (boolean currentValue : new boolean[] {true, false}) { + + Set searchValues = new HashSet(); + if (currentValue) { + // dont worry if dupes... oh well + Object targetProvisioningGroupCurrentValue = targetDaoRetrieveGroupRequest.getTargetGroup().retrieveAttributeValue(searchAttributeName); + if(!GrouperUtil.isBlank(targetProvisioningGroupCurrentValue)) { + searchValues.add(targetProvisioningGroupCurrentValue); + } + } else { + // historical values + Set attributeValues = GrouperProvisioningConfigurationAttributeDbCache.cachedValuesForGroup(targetDaoRetrieveGroupRequest.getTargetGroup(), searchAttributeName); + + for (Object attributeValue : GrouperUtil.nonNull(attributeValues)) { + if(!GrouperUtil.isBlank(attributeValue)) { + searchValues.add(attributeValue); + } + } + + } + for (Object searchValue : searchValues) { + // search based on those + TargetDaoRetrieveGroupRequest targetDaoRetrieveGroupRequestNew = new TargetDaoRetrieveGroupRequest(); + targetDaoRetrieveGroupRequestNew.setIncludeAllMembershipsIfApplicable(targetDaoRetrieveGroupRequest.isIncludeAllMembershipsIfApplicable()); + targetDaoRetrieveGroupRequestNew.setTargetGroup(targetDaoRetrieveGroupRequest.getTargetGroup()); + targetDaoRetrieveGroupRequestNew.setSearchAttribute(searchAttributeName); + targetDaoRetrieveGroupRequestNew.setSearchAttributeValue(searchValue); + + targetDaoRetrieveGroupResponse = this.wrappedDao.retrieveGroup(targetDaoRetrieveGroupRequestNew); + if (targetDaoRetrieveGroupResponse.getTargetGroup() != null) { + if (!currentValue) { + retrieveGroupsFromCache++; + } else if (!first) { + retrieveGroupsFromAlternateSearchAttr++; + } + hasError = logGroup(targetDaoRetrieveGroupResponse.getTargetGroup()) || hasError; + return targetDaoRetrieveGroupResponse; + } + } + } + first = false; + } + return targetDaoRetrieveGroupResponse; } catch (RuntimeException e) { hasError = true; throw e; } finally { - commandLogFinallyBlock(commandLogStarted, hasError, "retrieveGroup"); + if (retrieveGroupsFromAlternateSearchAttr > 0) { + Integer oldCount = GrouperUtil.defaultIfNull((Integer)this.getGrouperProvisioner().getDebugMap().get("retrieveGroupsFromAlternateSearchAttr"), 0); + this.getGrouperProvisioner().getDebugMap().put("retrieveGroupsFromAlternateSearchAttr", oldCount + retrieveGroupsFromAlternateSearchAttr); + } + if (retrieveGroupsFromCache > 0) { + Integer oldCount = GrouperUtil.defaultIfNull((Integer)this.getGrouperProvisioner().getDebugMap().get("retrieveGroupsFromCache"), 0); + this.getGrouperProvisioner().getDebugMap().put("retrieveGroupsFromCache", oldCount + retrieveGroupsFromCache); + } + commandLogFinallyBlock(commandLogStarted, hasError, "retrieveGroups"); } } @@ -1236,13 +1581,18 @@ public TargetDaoUpdateGroupResponse updateGroup( return targetDaoUpdateGroupResponse; } catch (RuntimeException e) { + GrouperUtil.injectInException(e, targetGroup.toString()); hasError = true; + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("groupUpdate")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error updating group " + GrouperUtil.getFullStackTrace(e))); + } + if (targetGroup.getProvisioned() == null) { targetGroup.setProvisioned(false); } if (targetGroup.getException() == null) { - GrouperUtil.injectInException(e, targetGroup.toString()); targetGroup.setException(e); } @@ -1299,13 +1649,21 @@ public TargetDaoInsertGroupsResponse insertGroups( return targetDaoInsertGroupsResponse; } catch (RuntimeException e) { hasError = true; + + boolean first = true; for (ProvisioningGroup targetGroup : targetDaoInsertGroupsRequest.getTargetGroups()) { - + if(first) { + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("groupInsert")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error inserting groups, e.g. " + (targetGroup == null ? null : targetGroup.toString()) + GrouperUtil.getFullStackTrace(e))); + } + } + first = false; + if (targetGroup.getProvisioned() == null) { targetGroup.setProvisioned(false); } if (targetGroup.getException() == null) { - GrouperUtil.injectInException(e, targetGroup.toString()); targetGroup.setException(e); } } @@ -1348,13 +1706,18 @@ public TargetDaoDeleteEntityResponse deleteEntity( } return targetDaoDeleteEntityResponse; } catch (RuntimeException e) { + GrouperUtil.injectInException(e, targetEntity.toString()); hasError = true; + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("entityDelete")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error deleting entity, " + GrouperUtil.getFullStackTrace(e))); + } + if (targetEntity.getProvisioned() == null) { targetEntity.setProvisioned(false); } if (targetEntity.getException() == null) { - GrouperUtil.injectInException(e, targetEntity.toString()); targetEntity.setException(e); } logEntity(targetEntity); @@ -1445,6 +1808,7 @@ private boolean logGroups(List provisioningGroups) { * @param provisioningEntities */ private boolean logGroup(ProvisioningGroup provisioningGroup) { + // TODO only log 10 based on config and type of log... if (provisioningGroup != null && provisioningGroup.getException() != null) { LOG.error("Error in provisioner '" + this.getGrouperProvisioner().getConfigId() + "' - '" + this.getGrouperProvisioner().getInstanceId() + "' with group: " + provisioningGroup, @@ -1544,13 +1908,20 @@ public TargetDaoDeleteEntitiesResponse deleteEntities( return targetDaoDeleteEntitiesResponse; } catch (RuntimeException e) { hasError = true; + boolean first = true; for (ProvisioningEntity targetEntity : targetDaoDeleteEntitiesRequest.getTargetEntities()) { + if(first) { + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("entityDelete")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error deleting entities, e.g. " + (targetEntity == null ? null : targetEntity.toString()) + GrouperUtil.getFullStackTrace(e))); + } + } + first = false; if (targetEntity.getProvisioned() == null) { targetEntity.setProvisioned(false); } if (targetEntity.getException() == null) { - GrouperUtil.injectInException(e, targetEntity.toString()); targetEntity.setException(e); } } @@ -1593,13 +1964,18 @@ public TargetDaoInsertEntityResponse insertEntity( } return targetDaoInsertEntityResponse; } catch (RuntimeException e) { + GrouperUtil.injectInException(e, targetEntity.toString()); hasError = true; + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("entityInsert")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error inserting entity " + GrouperUtil.getFullStackTrace(e))); + } + if (targetEntity.getProvisioned() == null) { targetEntity.setProvisioned(false); } if (targetEntity.getException() == null) { - GrouperUtil.injectInException(e, targetEntity.toString()); targetEntity.setException(e); } logEntity(targetEntity); @@ -1640,13 +2016,19 @@ public TargetDaoInsertEntitiesResponse insertEntities( return targetDaoInsertEntitiesResponse; } catch (RuntimeException e) { hasError = true; + boolean first = true; for (ProvisioningEntity targetEntity : targetDaoInsertEntitiesRequest.getTargetEntityInserts()) { - + if(first) { + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("entityInsert")) { + LOG.error("Error inserting entities, e.g. " + (targetEntity == null ? null : targetEntity.toString()), e); + } + } + first = false; + if (targetEntity.getProvisioned() == null) { targetEntity.setProvisioned(false); } if (targetEntity.getException() == null) { - GrouperUtil.injectInException(e, targetEntity.toString()); targetEntity.setException(e); } } @@ -1666,7 +2048,6 @@ public TargetDaoInsertEntitiesResponse insertEntities( throw new RuntimeException("Dao cannot insert entity or entities"); } - @Override public TargetDaoUpdateEntityResponse updateEntity( TargetDaoUpdateEntityRequest targetDaoUpdateEntityRequest) { @@ -1689,13 +2070,16 @@ public TargetDaoUpdateEntityResponse updateEntity( } return targetDaoUpdateEntityResponse; } catch (RuntimeException e) { + GrouperUtil.injectInException(e, targetEntity.toString()); hasError = true; - + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("entityUpdate")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error updating entity " + GrouperUtil.getFullStackTrace(e))); + } if (targetEntity.getProvisioned() == null) { targetEntity.setProvisioned(false); } if (targetEntity.getException() == null) { - GrouperUtil.injectInException(e, targetEntity.toString()); targetEntity.setException(e); } @@ -1830,13 +2214,21 @@ public TargetDaoUpdateEntitiesResponse updateEntities( } catch (RuntimeException e) { hasError = true; + boolean first = true; for (ProvisioningEntity targetEntity : targetDaoUpdateEntitiesRequest.getTargetEntities()) { + if(first) { + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("entityUpdate")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error updating entities, e.g. " + (targetEntity == null ? null : targetEntity.toString()) + GrouperUtil.getFullStackTrace(e))); + } + } + first = false; + if (targetEntity.getProvisioned() == null) { targetEntity.setProvisioned(false); } if (targetEntity.getException() == null) { - GrouperUtil.injectInException(e, targetEntity.toString()); targetEntity.setException(e); } @@ -1881,13 +2273,18 @@ public TargetDaoDeleteMembershipResponse deleteMembership( } return targetDaoDeleteMembershipResponse; } catch (RuntimeException e) { + GrouperUtil.injectInException(e, targetMembership.toString()); hasError = true; + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("membershipDelete")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error deleting membership, " + GrouperUtil.getFullStackTrace(e))); + } + if (targetMembership.getProvisioned() == null) { targetMembership.setProvisioned(false); } if (targetMembership.getException() == null) { - GrouperUtil.injectInException(e, targetMembership.toString()); targetMembership.setException(e); } logMembership(targetMembership); @@ -1929,13 +2326,24 @@ public TargetDaoDeleteGroupsResponse deleteGroups( return targetDaoDeleteGroupsResponse; } catch (RuntimeException e) { hasError = true; + + boolean first = true; + for (ProvisioningGroup targetGroup : targetDaoDeleteGroupsRequest.getTargetGroups()) { + if(first) { + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("groupDelete")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error deleting groups, e.g. " + (targetGroup == null ? null : targetGroup.toString()) + GrouperUtil.getFullStackTrace(e))); + + } + } + first = false; + if (targetGroup.getProvisioned() == null) { targetGroup.setProvisioned(false); } if (targetGroup.getException() == null) { - GrouperUtil.injectInException(e, targetGroup.toString()); targetGroup.setException(e); } } @@ -1978,13 +2386,18 @@ public TargetDaoInsertMembershipResponse insertMembership( } return targetDaoInsertMembershipResponse; } catch (RuntimeException e) { + GrouperUtil.injectInException(e, targetMembership.toString()); hasError = true; + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("membershipInsert")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error inserting membership " + (targetMembership == null ? null : targetMembership.toString()) + GrouperUtil.getFullStackTrace(e))); + } + if (targetMembership.getProvisioned() == null) { targetMembership.setProvisioned(false); } if (targetMembership.getException() == null) { - GrouperUtil.injectInException(e, targetMembership.toString()); targetMembership.setException(e); } logMembership(targetMembership); @@ -2025,13 +2438,20 @@ public TargetDaoInsertMembershipsResponse insertMemberships( return targetDaoInsertMembershipsResponse; } catch (RuntimeException e) { hasError = true; + boolean first = true; for (ProvisioningMembership targetMembership : targetDaoInsertMembershipsRequest.getTargetMemberships()) { - + if(first) { + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("membershipInsert")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error inserting memberships, e.g. " + (targetMembership == null ? null : targetMembership.toString()) + GrouperUtil.getFullStackTrace(e))); + } + } + first = false; + if (targetMembership.getProvisioned() == null) { targetMembership.setProvisioned(false); } if (targetMembership.getException() == null) { - GrouperUtil.injectInException(e, targetMembership.toString()); targetMembership.setException(e); } } @@ -2073,13 +2493,18 @@ public TargetDaoUpdateMembershipResponse updateMembership( } return targetDaoUpdateMembershipResponse; } catch (RuntimeException e) { + GrouperUtil.injectInException(e, targetMembership.toString()); hasError = true; + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("membershipUpdate")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error updating membership " + GrouperUtil.getFullStackTrace(e))); + } + if (targetMembership.getProvisioned() == null) { targetMembership.setProvisioned(false); } if (targetMembership.getException() == null) { - GrouperUtil.injectInException(e, targetMembership.toString()); targetMembership.setException(e); } logMembership(targetDaoUpdateMembershipRequest.getTargetMembership()); @@ -2120,13 +2545,21 @@ public TargetDaoUpdateMembershipsResponse updateMemberships( } catch (RuntimeException e) { hasError = true; + boolean first = true; for (ProvisioningMembership targetMembership : targetDaoUpdateMembershipsRequest.getTargetMemberships()) { + if(first) { + if (this.getGrouperProvisioner().retrieveGrouperProvisioningLog().shouldLogError("membershipUpdate")) { + LOG.error(this.getGrouperProvisioner().retrieveGrouperProvisioningLog().prefixLogLinesWithInstanceId( + "Error updating memberships, e.g. " + (targetMembership == null ? null : targetMembership.toString()) + GrouperUtil.getFullStackTrace(e))); + } + } + first = false; + if (targetMembership.getProvisioned() == null) { targetMembership.setProvisioned(false); } if (targetMembership.getException() == null) { - GrouperUtil.injectInException(e, targetMembership.toString()); targetMembership.setException(e); } } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/GrouperProvisionerTargetDaoBase.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/GrouperProvisionerTargetDaoBase.java index e2d4863d0070..8bf4ccc4b1c9 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/GrouperProvisionerTargetDaoBase.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/GrouperProvisionerTargetDaoBase.java @@ -236,7 +236,7 @@ public TargetDaoRetrieveMembershipsByEntityResponse retrieveMembershipsByEntity( /** * bulk retrieve target provisioning Memberships, generally use the matching Ids in the targetMemberships - * @ptouperTargetMemberships + * @param targetDaoRetrieveMembershipsRequest * @return the target provisioning Memberships */ public TargetDaoRetrieveMembershipsResponse retrieveMemberships(TargetDaoRetrieveMembershipsRequest targetDaoRetrieveMembershipsRequest) { diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/TargetDaoRetrieveGroupRequest.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/TargetDaoRetrieveGroupRequest.java index 861f9ec1714c..92dd44ff931d 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/TargetDaoRetrieveGroupRequest.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/TargetDaoRetrieveGroupRequest.java @@ -1,5 +1,7 @@ package edu.internet2.middleware.grouper.app.provisioning.targetDao; +import java.util.Set; + import edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroup; public class TargetDaoRetrieveGroupRequest { @@ -7,6 +9,48 @@ public class TargetDaoRetrieveGroupRequest { public TargetDaoRetrieveGroupRequest() { } + /** + * to search for + */ + private String searchAttribute; + + /** + * values to search for + */ + private Object searchAttributeValue; + + /** + * to search for + * @return + */ + public String getSearchAttribute() { + return searchAttribute; + } + + /** + * to search for + * @param searchAttribute + */ + public void setSearchAttribute(String searchAttribute) { + this.searchAttribute = searchAttribute; + } + + /** + * value to search for + * @return + */ + public Object getSearchAttributeValue() { + return searchAttributeValue; + } + + /** + * value to search for + * @param searchAttributeValue + */ + public void setSearchAttributeValue(Object searchAttributeValue) { + this.searchAttributeValue = searchAttributeValue; + } + private ProvisioningGroup targetGroup; diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/TargetDaoRetrieveGroupsRequest.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/TargetDaoRetrieveGroupsRequest.java index 8a32f1eb41af..9792b38a2702 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/TargetDaoRetrieveGroupsRequest.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/provisioning/targetDao/TargetDaoRetrieveGroupsRequest.java @@ -1,6 +1,7 @@ package edu.internet2.middleware.grouper.app.provisioning.targetDao; import java.util.List; +import java.util.Set; import edu.internet2.middleware.grouper.app.provisioning.ProvisioningGroup; @@ -9,6 +10,48 @@ public class TargetDaoRetrieveGroupsRequest { public TargetDaoRetrieveGroupsRequest() { } + /** + * to search for + */ + private String searchAttribute; + + /** + * values to search for + */ + private Set searchAttributeValues; + + /** + * to search for + * @return + */ + public String getSearchAttribute() { + return searchAttribute; + } + + /** + * to search for + * @param searchAttribute + */ + public void setSearchAttribute(String searchAttribute) { + this.searchAttribute = searchAttribute; + } + + /** + * values to search for + * @return + */ + public Set getSearchAttributeValues() { + return searchAttributeValues; + } + + /** + * values to search for + * @param searchAttributeValues + */ + public void setSearchAttributeValues(Set searchAttributeValues) { + this.searchAttributeValues = searchAttributeValues; + } + private List targetGroups; diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/scim2Provisioning/AwsScim2MockServiceHandler.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/scim2Provisioning/AwsScim2MockServiceHandler.java index 89894e0f37a6..1bd1646b2f1e 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/scim2Provisioning/AwsScim2MockServiceHandler.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/scim2Provisioning/AwsScim2MockServiceHandler.java @@ -27,6 +27,7 @@ import edu.internet2.middleware.grouper.j2ee.MockServiceResponse; import edu.internet2.middleware.grouper.j2ee.MockServiceServlet; import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClient.config.ConfigPropertiesCascadeBase; import edu.internet2.middleware.grouperClient.jdbc.GcDbAccess; public class AwsScim2MockServiceHandler extends MockServiceHandler { @@ -175,6 +176,8 @@ public boolean checkAuthorization(MockServiceRequest mockServiceRequest, MockSer } String authorizationToken = GrouperUtil.prefixOrSuffix(bearerToken, "Bearer ", false); + ConfigPropertiesCascadeBase.clearCache(); + Pattern clientIdPattern = Pattern.compile("^grouper\\.wsBearerToken\\.([^.]+)\\.accessTokenPassword$"); String configId = null; for (String propertyName : GrouperLoaderConfig.retrieveConfig().propertyNames()) { diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/scim2Provisioning/GithubScim2MockServiceHandler.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/scim2Provisioning/GithubScim2MockServiceHandler.java index 55eaa9fd240c..6a4c7ac4322c 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/scim2Provisioning/GithubScim2MockServiceHandler.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/scim2Provisioning/GithubScim2MockServiceHandler.java @@ -28,6 +28,7 @@ import edu.internet2.middleware.grouper.j2ee.MockServiceResponse; import edu.internet2.middleware.grouper.j2ee.MockServiceServlet; import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClient.config.ConfigPropertiesCascadeBase; import edu.internet2.middleware.grouperClient.jdbc.GcDbAccess; public class GithubScim2MockServiceHandler extends MockServiceHandler { @@ -158,7 +159,9 @@ public boolean checkAuthorization(MockServiceRequest mockServiceRequest, MockSer throw new RuntimeException("Authorization token must start with 'Bearer '"); } String authorizationToken = GrouperUtil.prefixOrSuffix(bearerToken, "Bearer ", false); - + + ConfigPropertiesCascadeBase.clearCache(); + Pattern clientIdPattern = Pattern.compile("^grouper\\.wsBearerToken\\.([^.]+)\\.accessTokenPassword$"); String configId = null; for (String propertyName : GrouperLoaderConfig.retrieveConfig().propertyNames()) { @@ -173,6 +176,7 @@ public boolean checkAuthorization(MockServiceRequest mockServiceRequest, MockSer } if (StringUtils.isBlank(configId)) { + mockServiceRequest.getDebugMap().put("authnError", "Cant find client id! WS bearer token external system not configured or invalid secret!"); mockServiceResponse.setResponseCode(401); return false; diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerConfiguration.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerConfiguration.java index e6385381ee53..725503748ddb 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerConfiguration.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerConfiguration.java @@ -21,8 +21,7 @@ public class SqlProvisionerConfiguration extends ProvisioningConfiguration { public final static Set startWithConfigClassNames = new LinkedHashSet(); static { - startWithConfigClassNames.add(SqlProvisioningGroupTableStartWith.class.getName()); - startWithConfigClassNames.add(SqlProvisioningEntityTableStartWith.class.getName()); + startWithConfigClassNames.add(SqlProvisioningStartWith.class.getName()); } @Override diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningConfiguration.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningConfiguration.java index 435fb744a12e..199301b913dd 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningConfiguration.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningConfiguration.java @@ -2,7 +2,10 @@ import java.util.Map; +import org.apache.commons.lang.StringUtils; + import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningConfigurationAttribute; +import edu.internet2.middleware.grouper.util.GrouperUtil; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningConfiguration; @@ -68,24 +71,50 @@ protected Class grouperProv private String entityAttributesLastModifiedColumn; private String entityAttributesLastModifiedColumnType; + private boolean useSeparateTableForGroupAttributes; + + private boolean useSeparateTableForEntityAttributes; /** * columns in the group table */ // private String groupAttributeNames; + public boolean isUseSeparateTableForEntityAttributes() { + return useSeparateTableForEntityAttributes; + } + + + + + public void setUseSeparateTableForEntityAttributes(boolean useSeparateTableForEntityAttributes) { + this.useSeparateTableForEntityAttributes = useSeparateTableForEntityAttributes; + } + + + + /** * if there is a group attribute table (like ldap), this is the table name */ // private String groupAttributeTableName; + public boolean isUseSeparateTableForGroupAttributes() { + return useSeparateTableForGroupAttributes; + } + + + + + public void setUseSeparateTableForGroupAttributes(boolean useSeparateTableForGroupAttributes) { + this.useSeparateTableForGroupAttributes = useSeparateTableForGroupAttributes; + } + /** * if group table has one primary key, this is it */ private String groupTableIdColumn; - private String membershipTableIdColumn; - /** * single column in group attribute table that links back to group pk */ @@ -258,10 +287,14 @@ public void configureSpecificSettings() { this.entityAttributesLastModifiedColumn = this.retrieveConfigString("entityAttributesLastModifiedColumn", false); this.entityAttributesLastModifiedColumnType = this.retrieveConfigString("entityAttributesLastModifiedColumnType", false); - this.membershipTableIdColumn = this.retrieveConfigString("membershipPrimaryKey", false); + this.useSeparateTableForGroupAttributes = GrouperUtil.booleanValue(this.retrieveConfigBoolean("useSeparateTableForGroupAttributes", false), false); - //setMembershipMatchingIdExpression("${new edu.internet2.middleware.grouperClient.collections.MultiKey(targetMembership.getProvisioningGroup().retrieveAttributeValueString('"+groupTableIdColumn+"'), targetMembership.getProvisioningEntity().retrieveAttributeValueString('"+entityTableIdColumn+"'))}"); - setMembershipMatchingIdExpression("${new('edu.internet2.middleware.grouperClient.collections.MultiKey', targetMembership.retrieveAttributeValueString('"+membershipGroupForeignKeyColumn+"'), targetMembership.retrieveAttributeValueString('"+membershipEntityForeignKeyColumn+"'))}"); + this.useSeparateTableForEntityAttributes = GrouperUtil.booleanValue(this.retrieveConfigBoolean("useSeparateTableForEntityAttributes", false), false); + + if (!StringUtils.isBlank(this.membershipTableName) && StringUtils.isBlank(this.getMembershipMatchingIdExpression())) { + //setMembershipMatchingIdExpression("${new edu.internet2.middleware.grouperClient.collections.MultiKey(targetMembership.getProvisioningGroup().retrieveAttributeValueString('"+groupTableIdColumn+"'), targetMembership.getProvisioningEntity().retrieveAttributeValueString('"+entityTableIdColumn+"'))}"); + setMembershipMatchingIdExpression("${new('edu.internet2.middleware.grouperClient.collections.MultiKey', targetMembership.retrieveAttributeValueString('"+getMembershipGroupMatchingIdAttribute()+"'), targetMembership.retrieveAttributeValueString('"+getMembershipEntityMatchingIdAttribute()+"'))}"); + } // this.groupAttributeTableForeignKeyToGroup = this.retrieveConfigString("groupAttributeTableForeignKeyToGroup", false); // this.groupAttributeTableIdColumn = this.retrieveConfigString("groupAttributeTableIdColumn", false); // this.groupAttributeTableAttributeNameColumn = this.retrieveConfigString("groupAttributeTableAttributeNameColumn", false); @@ -293,6 +326,85 @@ public void configureSpecificSettings() { } + /** + * find the matching ID part for membership table that goes to the group + * @return the column which is the matching ID in memberships for group + */ + public String getMembershipGroupMatchingIdAttribute() { + if (StringUtils.isBlank(this.membershipTableName)) { + return null; + } + if (!StringUtils.isBlank(membershipGroupMatchingIdAttribute)) { + return this.membershipGroupMatchingIdAttribute; + } + + if (!StringUtils.isBlank(this.membershipGroupForeignKeyColumn)) { + membershipGroupMatchingIdAttribute = membershipGroupForeignKeyColumn; + return this.membershipGroupMatchingIdAttribute; + } + + // "id", "idIndex", "idIndexString", "displayExtension", "displayName", "extension", "groupAttributeValueCache0", "groupAttributeValueCache1", "groupAttributeValueCache2", "groupAttributeValueCache3", "name", "description" + // configureProvisionerSuffix(provisioningTestConfigInput, "targetMembershipAttribute.0.name", "group_name"); + // configureProvisionerSuffix(provisioningTestConfigInput, "targetMembershipAttribute.0.translateFromGrouperProvisioningGroupField", "name"); + // configureProvisionerSuffix(provisioningTestConfigInput, "targetMembershipAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); + + for (String groupMapping : new String[] {"id", "idIndex", "idIndexString", "name", "displayName", "extension", "displayExtension", "groupAttributeValueCache0", "groupAttributeValueCache1", "groupAttributeValueCache2", "groupAttributeValueCache3"}) { + for (String name: getTargetMembershipAttributeNameToConfig().keySet()) { + + SqlGrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = (SqlGrouperProvisioningConfigurationAttribute) this.getTargetMembershipAttributeNameToConfig().get(name); + + if (StringUtils.equals(groupMapping, grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningGroupField())) { + membershipGroupMatchingIdAttribute = name; + return this.membershipGroupMatchingIdAttribute; + } + + } + + } + throw new RuntimeException("Cant find membership column to use for matching when it involves groups"); + } + + private String membershipEntityMatchingIdAttribute; + + private String membershipGroupMatchingIdAttribute; + + /** + * find the matching ID part for membership table that goes to the entity + * @return the column which is the matching ID in memberships for entity + */ + public String getMembershipEntityMatchingIdAttribute() { + if (StringUtils.isBlank(this.membershipTableName)) { + return null; + } + if (!StringUtils.isBlank(membershipEntityMatchingIdAttribute)) { + return this.membershipEntityMatchingIdAttribute; + } + + if (!StringUtils.isBlank(this.membershipEntityForeignKeyColumn)) { + membershipEntityMatchingIdAttribute = membershipEntityForeignKeyColumn; + return this.membershipEntityMatchingIdAttribute; + } + + // "id", "email", "loginid", "memberId", "entityAttributeValueCache0", "entityAttributeValueCache1", "entityAttributeValueCache2", "entityAttributeValueCache3", "name", "subjectId", "subjectSourceId", "description", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2" + // configureProvisionerSuffix(provisioningTestConfigInput, "targetMembershipAttribute.1.name", "subject_id"); + // configureProvisionerSuffix(provisioningTestConfigInput, "targetMembershipAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); + // configureProvisionerSuffix(provisioningTestConfigInput, "targetMembershipAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + + for (String entityMapping : new String[] {"memberId", "subjectId", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2", "email", "loginid", "entityAttributeValueCache0", "entityAttributeValueCache1", "entityAttributeValueCache2", "entityAttributeValueCache3", "id"}) { + for (String name: getTargetMembershipAttributeNameToConfig().keySet()) { + + SqlGrouperProvisioningConfigurationAttribute grouperProvisioningConfigurationAttribute = (SqlGrouperProvisioningConfigurationAttribute) this.getTargetMembershipAttributeNameToConfig().get(name); + + if (StringUtils.equals(entityMapping, grouperProvisioningConfigurationAttribute.getTranslateFromGrouperProvisioningEntityField())) { + membershipEntityMatchingIdAttribute = name; + return this.membershipEntityMatchingIdAttribute; + } + + } + + } + throw new RuntimeException("Cant find membership column to use for matching when it involves entities"); + } public String getDbExternalSystemConfigId() { @@ -318,15 +430,6 @@ public void setMembershipTableName(String membershipTableName) { } - public String getMembershipTableIdColumn() { - return membershipTableIdColumn; - } - - - public void setMembershipTableIdColumn(String membershipTableIdColumn) { - this.membershipTableIdColumn = membershipTableIdColumn; - } - public String getGroupAttributesTableName() { return groupAttributesTableName; diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningDao.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningDao.java index 8349452b8f72..022b4a7646c8 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningDao.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningDao.java @@ -3,10 +3,8 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import org.apache.commons.lang.StringUtils; @@ -43,11 +41,14 @@ import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveGroupsResponse; import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveMembershipsBulkRequest; import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveMembershipsBulkResponse; +import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveMembershipsRequest; +import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoRetrieveMembershipsResponse; import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoUpdateEntitiesRequest; import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoUpdateEntitiesResponse; import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoUpdateGroupsRequest; import edu.internet2.middleware.grouper.app.provisioning.targetDao.TargetDaoUpdateGroupsResponse; import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClient.collections.MultiKey; /** * @@ -93,6 +94,38 @@ public TargetDaoRetrieveAllMembershipsResponse retrieveAllMemberships(TargetDaoR return new TargetDaoRetrieveAllMembershipsResponse(result); } + /** + * bulk retrieve target provisioning Memberships, generally use the matching Ids in the targetMemberships + * @param targetDaoRetrieveMembershipsRequest + * @return the target provisioning Memberships + */ + public TargetDaoRetrieveMembershipsResponse retrieveMemberships(TargetDaoRetrieveMembershipsRequest targetDaoRetrieveMembershipsRequest) { + TargetDaoRetrieveMembershipsResponse targetDaoRetrieveMembershipsResponse = new TargetDaoRetrieveMembershipsResponse(); + if (GrouperUtil.length(targetDaoRetrieveMembershipsRequest.getTargetMemberships()) == 0) { + return targetDaoRetrieveMembershipsResponse; + } + + List grouperTargetGroups = new ArrayList(); + List grouperTargetEntities = new ArrayList(); + List grouperTargetMemberships = new ArrayList(); + + for (Object object : targetDaoRetrieveMembershipsRequest.getTargetMemberships()) { + if (object instanceof ProvisioningGroup) { + grouperTargetGroups.add((ProvisioningGroup)object); + } + if (object instanceof ProvisioningEntity) { + grouperTargetEntities.add((ProvisioningEntity)object); + } + if (object instanceof ProvisioningMembership) { + grouperTargetMemberships.add((ProvisioningMembership)object); + } + } + + List memberships = retrieveMemberships(grouperTargetGroups, grouperTargetEntities, (List)(Object)grouperTargetMemberships); + targetDaoRetrieveMembershipsResponse.setTargetMemberships((List)(Object)memberships); + return targetDaoRetrieveMembershipsResponse; + } + /** * * @param grouperTargetGroups @@ -107,9 +140,9 @@ public List retrieveMemberships(List String dbExternalSystemConfigId = sqlProvisioningConfiguration.getDbExternalSystemConfigId(); - String membershipGroupColumn = sqlProvisioningConfiguration.getMembershipGroupForeignKeyColumn(); - String membershipEntityColumn = sqlProvisioningConfiguration.getMembershipEntityForeignKeyColumn(); - + String membershipGroupColumn = sqlProvisioningConfiguration.getMembershipGroupMatchingIdAttribute(); + String membershipEntityColumn = sqlProvisioningConfiguration.getMembershipEntityMatchingIdAttribute(); + String entityTableIdColumn = sqlProvisioningConfiguration.getEntityTableIdColumn(); String groupTableIdColumn = sqlProvisioningConfiguration.getGroupTableIdColumn(); @@ -294,9 +327,16 @@ public TargetDaoUpdateGroupsResponse updateGroups(TargetDaoUpdateGroupsRequest t for (ProvisioningGroup targetGroup: targetGroups) { - String groupIdentifierValue = targetGroup.retrieveAttributeValueString(groupTableIdColumn); + String groupIdentifierValueNew = targetGroup.retrieveAttributeValueString(groupTableIdColumn); + String groupIdentifierValueOld = groupIdentifierValueNew; + if (targetGroup.getProvisioningGroupWrapper() != null && targetGroup.getProvisioningGroupWrapper().getTargetProvisioningGroup() != null) { + groupIdentifierValueOld = targetGroup.getProvisioningGroupWrapper().getTargetProvisioningGroup().retrieveAttributeValueString(groupTableIdColumn); + if (StringUtils.isBlank(groupIdentifierValueOld)) { + groupIdentifierValueOld = groupIdentifierValueNew; + } + } - if (StringUtils.isBlank(groupIdentifierValue)) { + if (StringUtils.isBlank(groupIdentifierValueNew)) { throw new RuntimeException("Unable to retrieve entitiy identifier value"); } Object[] mainData = new Object[primaryColumnsToUpdate.size()]; @@ -309,6 +349,13 @@ public TargetDaoUpdateGroupsResponse updateGroups(TargetDaoUpdateGroupsRequest t for (ProvisioningObjectChange provisioningObjectChange : GrouperUtil.nonNull(targetGroup.getInternal_objectChanges())) { String attributeName = provisioningObjectChange.getAttributeName(); + + if (StringUtils.equals(attributeName, groupTableIdColumn) && provisioningObjectChange.getProvisioningObjectChangeAction() == ProvisioningObjectChangeAction.update + && !GrouperUtil.isBlank(provisioningObjectChange.getOldValue()) + && !StringUtils.equals(groupIdentifierValueNew, GrouperUtil.stringValue(provisioningObjectChange.getOldValue()))) { + groupIdentifierValueOld = GrouperUtil.stringValue(provisioningObjectChange.getOldValue()); + } + SqlGrouperProvisioningConfigurationAttribute configurationAttribute = (SqlGrouperProvisioningConfigurationAttribute) attributeNameToConfig.get(attributeName); GrouperUtil.assertion(configurationAttribute!=null, "Configuration attribute is null: '" + attributeName + "'"); if (StringUtils.equals(configurationAttribute.getStorageType(), "separateAttributesTable")) { @@ -317,7 +364,7 @@ public TargetDaoUpdateGroupsResponse updateGroups(TargetDaoUpdateGroupsRequest t Object[] updateData = new Object[attributeColumnsToUpdate.size()]; attributeTableUpdates.add(updateData); - updateData[0] = groupIdentifierValue; + updateData[0] = groupIdentifierValueNew; updateData[1] = attributeName; updateData[2] = provisioningObjectChange.getNewValue(); if (StringUtils.isNotBlank(groupAttributesLastModifiedColumn)) { @@ -329,13 +376,13 @@ public TargetDaoUpdateGroupsResponse updateGroups(TargetDaoUpdateGroupsRequest t throw new RuntimeException("Invalid groupAttributesLastModifiedColumnType: '"+groupAttributesLastModifiedColumnType+"'"); } } - attributeTableUpdatesWhereClause.add(new Object[] {groupIdentifierValue, attributeName, provisioningObjectChange.getOldValue()}); + attributeTableUpdatesWhereClause.add(new Object[] {groupIdentifierValueNew, attributeName, provisioningObjectChange.getOldValue()}); } else if (provisioningObjectChange.getProvisioningObjectChangeAction() == ProvisioningObjectChangeAction.insert) { Object[] insertData = new Object[attributeColumnsToInsert.size()]; attributeTableInserts.add(insertData); - insertData[0] = groupIdentifierValue; + insertData[0] = groupIdentifierValueNew; insertData[1] = attributeName; insertData[2] = provisioningObjectChange.getNewValue(); if (StringUtils.isNotBlank(groupAttributesLastModifiedColumn)) { @@ -351,10 +398,10 @@ public TargetDaoUpdateGroupsResponse updateGroups(TargetDaoUpdateGroupsRequest t } else if (provisioningObjectChange.getProvisioningObjectChangeAction() == ProvisioningObjectChangeAction.delete) { Object[] deleteData = new Object[attributeColumnsToDelete.size()]; attributeTableDeletes.add(deleteData); - deleteData[0] = groupIdentifierValue; + deleteData[0] = groupIdentifierValueNew; deleteData[1] = attributeName; deleteData[2] = provisioningObjectChange.getOldValue(); - attributeTableDeletesWhereClause.add(new Object[] {groupIdentifierValue}); + attributeTableDeletesWhereClause.add(new Object[] {groupIdentifierValueNew}); } } else { @@ -368,10 +415,23 @@ public TargetDaoUpdateGroupsResponse updateGroups(TargetDaoUpdateGroupsRequest t } if (hasPrimaryUpdate) { primaryTableUpdates.add(mainData); - primaryTableWhereClause.add(new Object[] {groupIdentifierValue}); + primaryTableWhereClause.add(new Object[] {groupIdentifierValueOld}); } - } - + + // if the groupIdentiferNew and groupIdentifierOld do not match... + if (!StringUtils.equals(groupIdentifierValueNew, groupIdentifierValueOld) && sqlProvisioningConfiguration.isUseSeparateTableForGroupAttributes()) { + + List groupAttributesGroupForeignKeyColumnOld = new ArrayList(); + groupAttributesGroupForeignKeyColumnOld.add(new Object[] {groupIdentifierValueOld}); + List groupAttributesGroupForeignKeyColumnNew = new ArrayList(); + groupAttributesGroupForeignKeyColumnNew.add(new Object[] {groupIdentifierValueNew}); + + + SqlProvisionerCommands.updateObjects(dbExternalSystemConfigId, groupAttributesTableName, + GrouperUtil.toList(groupAttributesGroupForeignKeyColumn), groupAttributesGroupForeignKeyColumnNew, + GrouperUtil.toList(groupAttributesGroupForeignKeyColumn), groupAttributesGroupForeignKeyColumnOld); + } + } if (primaryTableUpdates.size() > 0) { SqlProvisionerCommands.updateObjects(dbExternalSystemConfigId, groupTableName, primaryColumnsToUpdate, primaryTableUpdates, primaryColumnsWhereClause, primaryTableWhereClause); @@ -397,7 +457,7 @@ public TargetDaoUpdateGroupsResponse updateGroups(TargetDaoUpdateGroupsRequest t } for (ProvisioningGroup targetGroup: targetGroups) { - + targetGroup.setProvisioned(true); for (ProvisioningObjectChange provisioningObjectChange : GrouperUtil.nonNull(targetGroup.getInternal_objectChanges())) { provisioningObjectChange.setProvisioned(true); @@ -488,9 +548,16 @@ public TargetDaoUpdateEntitiesResponse updateEntities(TargetDaoUpdateEntitiesReq for (ProvisioningEntity targetEntity: targetEntities) { - String entityIdentifierValue = targetEntity.retrieveAttributeValueString(entityTableIdColumn); - - if (StringUtils.isBlank(entityIdentifierValue)) { + String entityIdentifierValueNew = targetEntity.retrieveAttributeValueString(entityTableIdColumn); + String entityIdentifierValueOld = entityIdentifierValueNew; + if (targetEntity.getProvisioningEntityWrapper() != null && targetEntity.getProvisioningEntityWrapper().getTargetProvisioningEntity() != null) { + entityIdentifierValueOld = targetEntity.getProvisioningEntityWrapper().getTargetProvisioningEntity().retrieveAttributeValueString(entityTableIdColumn); + if (StringUtils.isBlank(entityIdentifierValueOld)) { + entityIdentifierValueOld = entityIdentifierValueNew; + } + } + + if (StringUtils.isBlank(entityIdentifierValueNew)) { throw new RuntimeException("Unable to retrieve entitiy identifier value"); } Object[] mainData = new Object[primaryColumnsToUpdate.size()]; @@ -503,6 +570,13 @@ public TargetDaoUpdateEntitiesResponse updateEntities(TargetDaoUpdateEntitiesReq for (ProvisioningObjectChange provisioningObjectChange : GrouperUtil.nonNull(targetEntity.getInternal_objectChanges())) { String attributeName = provisioningObjectChange.getAttributeName(); + + if (StringUtils.equals(attributeName, entityTableIdColumn) && provisioningObjectChange.getProvisioningObjectChangeAction() == ProvisioningObjectChangeAction.update + && !GrouperUtil.isBlank(provisioningObjectChange.getOldValue()) + && !StringUtils.equals(entityIdentifierValueNew, GrouperUtil.stringValue(provisioningObjectChange.getOldValue()))) { + entityIdentifierValueOld = GrouperUtil.stringValue(provisioningObjectChange.getOldValue()); + } + SqlGrouperProvisioningConfigurationAttribute configurationAttribute = (SqlGrouperProvisioningConfigurationAttribute) attributeNameToConfig.get(attributeName); GrouperUtil.assertion(configurationAttribute!=null, "Configuration attribute is null: '" + attributeName + "'"); if (StringUtils.equals(configurationAttribute.getStorageType(), "separateAttributesTable")) { @@ -511,7 +585,7 @@ public TargetDaoUpdateEntitiesResponse updateEntities(TargetDaoUpdateEntitiesReq Object[] updateData = new Object[attributeColumnsToUpdate.size()]; attributeTableUpdates.add(updateData); - updateData[0] = entityIdentifierValue; + updateData[0] = entityIdentifierValueNew; updateData[1] = attributeName; updateData[2] = provisioningObjectChange.getNewValue(); if (StringUtils.isNotBlank(entityAttributesLastModifiedColumn)) { @@ -523,13 +597,13 @@ public TargetDaoUpdateEntitiesResponse updateEntities(TargetDaoUpdateEntitiesReq throw new RuntimeException("Invalid entityAttributesLastModifiedColumnType: '"+entityAttributesLastModifiedColumnType+"'"); } } - attributeTableUpdatesWhereClause.add(new Object[] {entityIdentifierValue, attributeName, provisioningObjectChange.getOldValue()}); + attributeTableUpdatesWhereClause.add(new Object[] {entityIdentifierValueNew, attributeName, provisioningObjectChange.getOldValue()}); } else if (provisioningObjectChange.getProvisioningObjectChangeAction() == ProvisioningObjectChangeAction.insert) { Object[] insertData = new Object[attributeColumnsToInsert.size()]; attributeTableInserts.add(insertData); - insertData[0] = entityIdentifierValue; + insertData[0] = entityIdentifierValueNew; insertData[1] = attributeName; insertData[2] = provisioningObjectChange.getNewValue(); if (StringUtils.isNotBlank(entityAttributesLastModifiedColumn)) { @@ -545,10 +619,10 @@ public TargetDaoUpdateEntitiesResponse updateEntities(TargetDaoUpdateEntitiesReq } else if (provisioningObjectChange.getProvisioningObjectChangeAction() == ProvisioningObjectChangeAction.delete) { Object[] deleteData = new Object[attributeColumnsToDelete.size()]; attributeTableDeletes.add(deleteData); - deleteData[0] = entityIdentifierValue; + deleteData[0] = entityIdentifierValueNew; deleteData[1] = attributeName; deleteData[2] = provisioningObjectChange.getOldValue(); - attributeTableDeletesWhereClause.add(new Object[] {entityIdentifierValue}); + attributeTableDeletesWhereClause.add(new Object[] {entityIdentifierValueNew}); } } else { @@ -561,8 +635,22 @@ public TargetDaoUpdateEntitiesResponse updateEntities(TargetDaoUpdateEntitiesReq } if (hasPrimaryUpdate) { primaryTableUpdates.add(mainData); - primaryTableWhereClause.add(new Object[] {entityIdentifierValue}); + primaryTableWhereClause.add(new Object[] {entityIdentifierValueOld}); } + // if the groupIdentiferNew and groupIdentifierOld do not match... + if (!StringUtils.equals(entityIdentifierValueNew, entityIdentifierValueOld) && sqlProvisioningConfiguration.isUseSeparateTableForGroupAttributes()) { + + List entityAttributesEntityForeignKeyColumnOld = new ArrayList(); + entityAttributesEntityForeignKeyColumnOld.add(new Object[] {entityIdentifierValueOld}); + List entityAttributesEntityForeignKeyColumnNew = new ArrayList(); + entityAttributesEntityForeignKeyColumnNew.add(new Object[] {entityIdentifierValueNew}); + + + SqlProvisionerCommands.updateObjects(dbExternalSystemConfigId, entityAttributesTableName, + GrouperUtil.toList(entityAttributesEntityForeignKeyColumn), entityAttributesEntityForeignKeyColumnNew, + GrouperUtil.toList(entityAttributesEntityForeignKeyColumn), entityAttributesEntityForeignKeyColumnOld); + } + } if (primaryTableUpdates.size() > 0) { @@ -701,19 +789,18 @@ public TargetDaoDeleteMembershipsResponse deleteMemberships(TargetDaoDeleteMembe GrouperUtil.assertion(!StringUtils.isBlank(objectTableName), "Need membership table name"); - String entityIdForeignKeyColumn = sqlProvisioningConfiguration.getMembershipEntityForeignKeyColumn(); - String groupIdForeignKeyColumn = sqlProvisioningConfiguration.getMembershipGroupForeignKeyColumn(); + String groupIdColumn = sqlProvisioningConfiguration.getMembershipGroupMatchingIdAttribute(); + String entityIdColumn = sqlProvisioningConfiguration.getMembershipEntityMatchingIdAttribute(); List ownerIds = new ArrayList(); for (ProvisioningMembership targetMembership: targetMemberships) { - String groupIdValue = targetMembership.retrieveAttributeValueString(groupIdForeignKeyColumn); - String entityIdValue = targetMembership.retrieveAttributeValueString(entityIdForeignKeyColumn); - ownerIds.add(new Object[] {groupIdValue, entityIdValue}); + MultiKey membershipMatchingId = new MultiKey(targetMembership.retrieveAttributeValueString(groupIdColumn), targetMembership.retrieveAttributeValueString(entityIdColumn)); + ownerIds.add(membershipMatchingId.getKeys()); } SqlProvisionerCommands.deleteObjects(ownerIds, dbExternalSystemConfigId, objectTableName, - GrouperUtil.toList(groupIdForeignKeyColumn, entityIdForeignKeyColumn), null, null); + GrouperUtil.toList(groupIdColumn, entityIdColumn), null, null); for (ProvisioningMembership targetMembership: targetMemberships) { @@ -1049,10 +1136,15 @@ public TargetDaoRetrieveAllGroupsResponse retrieveAllGroups(TargetDaoRetrieveAll continue; } + boolean isMembershipAttribute = false; + if (isGroupAttributes && !StringUtils.isBlank(sqlProvisioningConfiguration.getGroupMembershipAttributeName()) && StringUtils.equals(sqlProvisioningConfiguration.getGroupMembershipAttributeName(), attributeName)) { + isMembershipAttribute = true; + } + // maybe we dont want memberships if (StringUtils.equals(configurationAttribute.getStorageType(), "separateAttributesTable")) { - if (!configurationAttribute.isMembershipAttribute() || (isGroupAttributes && includeMemberships)) { + if (!isMembershipAttribute || (isGroupAttributes && includeMemberships)) { attributeTableAttributesNamesList.add(attributeName); @@ -1299,24 +1391,22 @@ public TargetDaoRetrieveGroupsResponse retrieveGroups(TargetDaoRetrieveGroupsReq Map groupAttributeNameToConfigAttribute = sqlProvisioningConfiguration.getTargetGroupAttributeNameToConfig(); - List searchAttributes = sqlProvisioningConfiguration.getGroupSearchAttributes(); - if (searchAttributes.size() != 1) { - throw new RuntimeException("Can currently only have one searchAttribute! " + GrouperUtil.toStringForLog(searchAttributes)); - } - - GrouperProvisioningConfigurationAttribute searchAttribute = searchAttributes.get(0); - for (String attributeName: groupAttributeNameToConfigAttribute.keySet()) { SqlGrouperProvisioningConfigurationAttribute configurationAttribute = (SqlGrouperProvisioningConfigurationAttribute) groupAttributeNameToConfigAttribute.get(attributeName); GrouperUtil.assertion(configurationAttribute!=null, "Configuration attribute is null: '" + attributeName + "'"); - if (!configurationAttribute.isSelect() && !StringUtils.equals(searchAttribute.getName(), attributeName)) { + if (!configurationAttribute.isSelect() && !StringUtils.equals(targetDaoRetrieveGroupsRequest.getSearchAttribute(), attributeName)) { continue; } + boolean isMembershipAttribute = false; + if (isGroupAttributes && !StringUtils.isBlank(sqlProvisioningConfiguration.getGroupMembershipAttributeName()) && StringUtils.equals(sqlProvisioningConfiguration.getGroupMembershipAttributeName(), attributeName)) { + isMembershipAttribute = true; + } + // maybe we dont want memberships if (StringUtils.equals(configurationAttribute.getStorageType(), "separateAttributesTable")) { - if (!configurationAttribute.isMembershipAttribute() || (isGroupAttributes && includeMemberships)) { + if (!isMembershipAttribute || (isGroupAttributes && includeMemberships)) { attributeTableAttributesNamesList.add(attributeName); @@ -1330,37 +1420,34 @@ public TargetDaoRetrieveGroupsResponse retrieveGroups(TargetDaoRetrieveGroupsReq } } - boolean filterByColumn = groupTablePrimaryColNamesList.contains(searchAttribute.getName()); + boolean filterByColumn = groupTablePrimaryColNamesList.contains(targetDaoRetrieveGroupsRequest.getSearchAttribute()); - boolean filterByAttribute = searchAttribute != null && attributeTableAttributesNamesList.contains(searchAttribute.getName()); + boolean filterByAttribute = attributeTableAttributesNamesList.contains(targetDaoRetrieveGroupsRequest.getSearchAttribute()); GrouperUtil.assertion(filterByAttribute || filterByColumn, "Must filter by attribute or column"); if (attributeTableAttributesNamesList.size() > 0 ) { - GrouperUtil.assertion(!StringUtils.isBlank(groupAttributesGroupForeignKeyColumn), "entity attributes foreign key column must be configured"); - GrouperUtil.assertion(!StringUtils.isBlank(groupAttributesAttributeNameColumn), "entity attributes attribute name column must be configured"); - GrouperUtil.assertion(!StringUtils.isBlank(groupAttributesAttributeValueColumn), "entity attributes attribute value column must be configured"); + GrouperUtil.assertion(!StringUtils.isBlank(groupAttributesGroupForeignKeyColumn), "group attributes foreign key column must be configured"); + GrouperUtil.assertion(!StringUtils.isBlank(groupAttributesAttributeNameColumn), "group attributes attribute name column must be configured"); + GrouperUtil.assertion(!StringUtils.isBlank(groupAttributesAttributeValueColumn), "group attributes attribute value column must be configured"); groupTableAttributesColNamesList = GrouperUtil.toList(groupAttributesGroupForeignKeyColumn, groupAttributesAttributeNameColumn, groupAttributesAttributeValueColumn); } - if (GrouperUtil.length(targetDaoRetrieveGroupsRequest.getTargetGroups()) > 0) { + if (GrouperUtil.length(targetDaoRetrieveGroupsRequest.getSearchAttributeValues()) > 0) { - List idsToRetrieve = new ArrayList(); - for (ProvisioningGroup provisioningGroup : targetDaoRetrieveGroupsRequest.getTargetGroups()) { - idsToRetrieve.add(provisioningGroup.retrieveAttributeValue(searchAttribute.getName())); - } + List idsToRetrieve = new ArrayList(targetDaoRetrieveGroupsRequest.getSearchAttributeValues()); List groupPrimaryAttributeValues = null; if (filterByColumn) { groupPrimaryAttributeValues = SqlProvisionerCommands.retrieveObjectsColumnFilter( - dbExternalSystemConfigId, groupTablePrimaryColNamesList, groupTableName, null, null, GrouperUtil.toList(searchAttribute.getName()), idsToRetrieve); + dbExternalSystemConfigId, groupTablePrimaryColNamesList, groupTableName, null, null, GrouperUtil.toList(targetDaoRetrieveGroupsRequest.getSearchAttribute()), idsToRetrieve); } else if (filterByAttribute) { groupPrimaryAttributeValues = SqlProvisionerCommands.retrieveObjectsAttributeFilter(dbExternalSystemConfigId, groupTablePrimaryColNamesList, groupTableName, groupTableIdColumn, groupAttributesTableName, groupAttributesGroupForeignKeyColumn, - groupAttributesAttributeNameColumn, groupAttributesAttributeValueColumn, searchAttribute.getName(), idsToRetrieve); + groupAttributesAttributeNameColumn, groupAttributesAttributeValueColumn, targetDaoRetrieveGroupsRequest.getSearchAttribute(), idsToRetrieve); } @@ -1456,10 +1543,15 @@ public TargetDaoRetrieveAllEntitiesResponse retrieveAllEntities(TargetDaoRetriev continue; } + boolean isMembershipAttribute = false; + if (isEntityAttributes && !StringUtils.isBlank(sqlProvisioningConfiguration.getGroupMembershipAttributeName()) && StringUtils.equals(sqlProvisioningConfiguration.getGroupMembershipAttributeName(), attributeName)) { + isMembershipAttribute = true; + } + // maybe we dont want memberships if (StringUtils.equals(configurationAttribute.getStorageType(), "separateAttributesTable")) { - if (!configurationAttribute.isMembershipAttribute() || (isEntityAttributes && includeMemberships)) { + if (!isMembershipAttribute || (isEntityAttributes && includeMemberships)) { attributeTableAttributesNamesList.add(attributeName); @@ -1565,10 +1657,15 @@ public TargetDaoRetrieveEntitiesResponse retrieveEntities(TargetDaoRetrieveEntit continue; } + boolean isMembershipAttribute = false; + if (isEntityAttributes && !StringUtils.isBlank(sqlProvisioningConfiguration.getGroupMembershipAttributeName()) && StringUtils.equals(sqlProvisioningConfiguration.getGroupMembershipAttributeName(), attributeName)) { + isMembershipAttribute = true; + } + // maybe we dont want memberships if (StringUtils.equals(configurationAttribute.getStorageType(), "separateAttributesTable")) { - if (!configurationAttribute.isMembershipAttribute() || (isEntityAttributes && includeMemberships)) { + if (!isMembershipAttribute || (isEntityAttributes && includeMemberships)) { attributeTableAttributesNamesList.add(attributeName); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningEntityTableStartWith.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningEntityTableStartWith.java deleted file mode 100644 index 5b264c56c08d..000000000000 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningEntityTableStartWith.java +++ /dev/null @@ -1,121 +0,0 @@ -package edu.internet2.middleware.grouper.app.sqlProvisioning; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.lang3.StringUtils; - -import edu.internet2.middleware.grouper.app.config.GrouperConfigurationModuleAttribute; -import edu.internet2.middleware.grouper.app.provisioning.ProvisionerStartWithBase; -import edu.internet2.middleware.grouper.cfg.text.GrouperTextContainer; -import edu.internet2.middleware.grouper.util.GrouperUtil; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncColumnMetadata; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncTableMetadata; - -/** - * - */ -public class SqlProvisioningEntityTableStartWith extends ProvisionerStartWithBase { - - @Override - public String getPropertyValueThatIdentifiesThisConfig() { - return "sqlEntityTable"; - } - - @Override - public void validatePreSave(boolean isInsert, List errorsToDisplay, Map validationErrorsToDisplay) { - super.validatePreSave(isInsert, errorsToDisplay, validationErrorsToDisplay); - - GrouperConfigurationModuleAttribute sqlExternalSystemConnectionName = this.retrieveAttributes().get("dbExternalSystemConfigId"); - GrouperConfigurationModuleAttribute userTableName = this.retrieveAttributes().get("userTableName"); - GrouperConfigurationModuleAttribute userTableIdColumn = this.retrieveAttributes().get("userPrimaryKey"); - GrouperConfigurationModuleAttribute columnNames = this.retrieveAttributes().get("columnNames"); - - GcTableSyncTableMetadata tableMetadata = null; - try { - tableMetadata = GcTableSyncTableMetadata.retrieveTableMetadataFromCacheOrDatabase(sqlExternalSystemConnectionName.getValueOrExpressionEvaluation(), - userTableName.getValueOrExpressionEvaluation()); - } catch (Exception e) { - String errorMessage = GrouperTextContainer.textOrNull("grouperStartWithEntityTableConfigurationValidationUserTableNotFound"); - errorMessage = errorMessage.replace("$$userTableName$$", userTableName.getValueOrExpressionEvaluation()); - validationErrorsToDisplay.put(userTableName.getHtmlForElementIdHandle(), errorMessage); - return; - } - - if (tableMetadata == null) { - String errorMessage = GrouperTextContainer.textOrNull("grouperStartWithEntityTableConfigurationValidationUserTableNotFound"); - errorMessage = errorMessage.replace("$$userTableName$$", userTableName.getValueOrExpressionEvaluation()); - validationErrorsToDisplay.put(userTableName.getHtmlForElementIdHandle(), errorMessage); - return; - } - - - String columnNamesCommaSeparated = columnNames.getValueOrExpressionEvaluation(); - Set colNamesSet = GrouperUtil.splitTrimToSet(columnNamesCommaSeparated.toLowerCase(), ","); - - String userTableIdColumnValue = GrouperUtil.trim(userTableIdColumn.getValueOrExpressionEvaluation()).toLowerCase(); - - List columnsMetadata = tableMetadata.getColumnMetadata(); - - boolean userTableIdColumnFound = false; - - for (GcTableSyncColumnMetadata columnMetadata: GrouperUtil.nonNull(columnsMetadata)) { - String columnName = columnMetadata.getColumnName().toLowerCase(); - if (StringUtils.equals(columnName, userTableIdColumnValue)) { - userTableIdColumnFound = true; - } - if (colNamesSet.contains(columnName)) { - colNamesSet.remove(columnName); - } - } - - if (!userTableIdColumnFound) { - String errorMessage = GrouperTextContainer.textOrNull("grouperStartWithEntityTableConfigurationValidationUserIdColumnNotFound"); - errorMessage = errorMessage.replace("$$userTableIdColumn$$", userTableIdColumn.getValueOrExpressionEvaluation()); - validationErrorsToDisplay.put(userTableIdColumn.getHtmlForElementIdHandle(), errorMessage); - } - - if (colNamesSet.size() > 0) { - String notFoundColNames = GrouperUtil.join(colNamesSet.iterator(), ','); - String errorMessage = GrouperTextContainer.textOrNull("grouperStartWithEntityTableConfigurationValidationEntityColumnsNotFound"); - errorMessage = errorMessage.replace("$$userTableColumns$$", notFoundColNames); - validationErrorsToDisplay.put(columnNames.getHtmlForElementIdHandle(), errorMessage); - } - - } - - /** - * return provisioning suffix to value - * @param startWithSuffixToValue - * @param provisionerSuffixToValue - * @return - */ - @Override - public void populateProvisionerConfigurationValuesFromStartWith(Map startWithSuffixToValue, - Map provisionerSuffixToValue) { - - String columnNames = startWithSuffixToValue.get("columnNames"); - String[] colNames = GrouperUtil.splitTrim(columnNames, ","); - provisionerSuffixToValue.put("numberOfGroupAttributes", colNames.length); - - for (int i=0; i screenRedraw(Map suffixToValue, - Set suffixesUserJustChanged) { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningGroupTableStartWith.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningGroupTableStartWith.java deleted file mode 100644 index 4a865ca5b4ed..000000000000 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisioningGroupTableStartWith.java +++ /dev/null @@ -1,129 +0,0 @@ -package edu.internet2.middleware.grouper.app.sqlProvisioning; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.lang3.StringUtils; - -import edu.internet2.middleware.grouper.app.config.GrouperConfigurationModuleAttribute; -import edu.internet2.middleware.grouper.app.provisioning.ProvisionerStartWithBase; -import edu.internet2.middleware.grouper.cfg.dbConfig.ConfigFileName; -import edu.internet2.middleware.grouper.cfg.text.GrouperTextContainer; -import edu.internet2.middleware.grouper.util.GrouperUtil; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncColumnMetadata; -import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcTableSyncTableMetadata; - -/** - */ -public class SqlProvisioningGroupTableStartWith extends ProvisionerStartWithBase { - - @Override - public ConfigFileName getConfigFileName() { - return ConfigFileName.GROUPER_LOADER_PROPERTIES; - } - - @Override - public String getPropertyValueThatIdentifiesThisConfig() { - return "sqlGroupTable"; - } - - @Override - public Map screenRedraw(Map suffixToValue, Set suffixesUserJustChanged) { - - /** - * have a hidden uuid on the form, save the state based on the that on the server side in an expirable cache map - * of Map> - */ - - return null; - } - - @Override - public void validatePreSave(boolean isInsert, List errorsToDisplay, Map validationErrorsToDisplay) { - super.validatePreSave(isInsert, errorsToDisplay, validationErrorsToDisplay); - - GrouperConfigurationModuleAttribute sqlExternalSystemConnectionName = this.retrieveAttributes().get("dbExternalSystemConfigId"); - GrouperConfigurationModuleAttribute groupTableName = this.retrieveAttributes().get("groupTableName"); - GrouperConfigurationModuleAttribute groupTableIdColumn = this.retrieveAttributes().get("groupTableIdColumn"); - GrouperConfigurationModuleAttribute columnNames = this.retrieveAttributes().get("columnNames"); - - GcTableSyncTableMetadata tableMetadata = null; - try { - tableMetadata = GcTableSyncTableMetadata.retrieveTableMetadataFromCacheOrDatabase(sqlExternalSystemConnectionName.getValueOrExpressionEvaluation(), - groupTableName.getValueOrExpressionEvaluation()); - } catch (Exception e) { - String errorMessage = GrouperTextContainer.textOrNull("grouperStartWithGroupTableConfigurationValidationGroupTableNotFound"); - errorMessage = errorMessage.replace("$$groupTableName$$", groupTableName.getValueOrExpressionEvaluation()); - validationErrorsToDisplay.put(groupTableName.getHtmlForElementIdHandle(), errorMessage); - return; - } - - if (tableMetadata == null) { - String errorMessage = GrouperTextContainer.textOrNull("grouperStartWithGroupTableConfigurationValidationGroupTableNotFound"); - errorMessage = errorMessage.replace("$$groupTableName$$", groupTableName.getValueOrExpressionEvaluation()); - validationErrorsToDisplay.put(groupTableName.getHtmlForElementIdHandle(), errorMessage); - return; - } - - - String columnNamesCommaSeparated = columnNames.getValueOrExpressionEvaluation(); - Set colNamesSet = GrouperUtil.splitTrimToSet(columnNamesCommaSeparated.toLowerCase(), ","); - - String groupTableIdColumnValue = GrouperUtil.trim(groupTableIdColumn.getValueOrExpressionEvaluation()).toLowerCase(); - - List columnsMetadata = tableMetadata.getColumnMetadata(); - - boolean groupTableIdColumnFound = false; - - for (GcTableSyncColumnMetadata columnMetadata: GrouperUtil.nonNull(columnsMetadata)) { - String columnName = columnMetadata.getColumnName().toLowerCase(); - if (StringUtils.equals(columnName, groupTableIdColumnValue)) { - groupTableIdColumnFound = true; - } - if (colNamesSet.contains(columnName)) { - colNamesSet.remove(columnName); - } - } - - if (!groupTableIdColumnFound) { - String errorMessage = GrouperTextContainer.textOrNull("grouperStartWithGroupTableConfigurationValidationGroupIdColumnNotFound"); - errorMessage = errorMessage.replace("$$groupTableIdColumn$$", groupTableIdColumn.getValueOrExpressionEvaluation()); - validationErrorsToDisplay.put(groupTableIdColumn.getHtmlForElementIdHandle(), errorMessage); - } - - if (colNamesSet.size() > 0) { - String notFoundColNames = GrouperUtil.join(colNamesSet.iterator(), ','); - String errorMessage = GrouperTextContainer.textOrNull("grouperStartWithGroupTableConfigurationValidationGroupColumnsNotFound"); - errorMessage = errorMessage.replace("$$groupTableColumns$$", notFoundColNames); - validationErrorsToDisplay.put(columnNames.getHtmlForElementIdHandle(), errorMessage); - } - - } - - /** - * return provisioning suffix to value - * @param startWithSuffixToValue - * @param provisionerSuffixToValue - * @return - */ - @Override - public void populateProvisionerConfigurationValuesFromStartWith(Map startWithSuffixToValue, - Map provisionerSuffixToValue) { - - String columnNames = startWithSuffixToValue.get("columnNames"); - String[] colNames = GrouperUtil.splitTrim(columnNames, ","); - provisionerSuffixToValue.put("numberOfGroupAttributes", colNames.length); - - for (int i=0; i screenRedraw(Map suffixToValue, Set suffixesUserJustChanged) { + + Map result = new HashMap<>(); + + for (String suffixUserJustChanged: suffixesUserJustChanged) { + + if (StringUtils.equals(suffixUserJustChanged, "sqlPattern")) { + String valueUserEnteredOnScreen = suffixToValue.get(suffixUserJustChanged); + + if (StringUtils.isNotBlank(valueUserEnteredOnScreen)) { + result.put("userAttributesType", "core"); + } + + if (StringUtils.equals(valueUserEnteredOnScreen, "entityTable")) { + result.put("membershipStructure", "notApplicable"); + result.put("hasEntityTable", "true"); + result.put("entityTableName", "from_grouper_entity"); + result.put("entityTableIdColumn", "entity_uuid"); + result.put("entityTablePrimaryKeyValue", "entityUuid"); + result.put("entityTableColumnNames", "subject_id"); + result.put("needEntityLink", "false"); + } else if (StringUtils.equals(valueUserEnteredOnScreen, "entityTableWithAttributeTable")) { + result.put("membershipStructure", "notApplicable"); + result.put("hasEntityTable", "true"); + result.put("entityTableName", "from_grouper_entity"); + result.put("entityTableIdColumn", "entity_uuid"); + result.put("entityTablePrimaryKeyValue", "entityUuid"); + result.put("entityTableColumnNames", "subject_id"); + result.put("needEntityLink", "false"); + result.put("hasEntityAttributeTable", "true"); + result.put("entityAttributeTableName", "from_grouper_entity_attr"); + result.put("columnNameForeignKeyToEntityTable", "entity_uuid"); + result.put("entityAttributeNameColumnName", "attribute_name"); + result.put("entityAttributeNameColumnValue", "attribute_value"); + } else if (StringUtils.equals(valueUserEnteredOnScreen, "entityTableWithAttributeTableAndMemberships")) { + result.put("membershipStructure", "entityAttributes"); + result.put("hasEntityTable", "true"); + result.put("entityTableName", "from_grouper_entity"); + result.put("entityTableIdColumn", "entity_uuid"); + result.put("entityTablePrimaryKeyValue", "entityUuid"); + result.put("entityTableColumnNames", "subject_id"); + result.put("hasEntityAttributeTable", "true"); + result.put("entityAttributeTableName", "from_grouper_entity_attr"); + result.put("columnNameForeignKeyToEntityTable", "entity_uuid"); + result.put("entityAttributeNameColumnName", "attribute_name"); + result.put("entityAttributeNameColumnValue", "attribute_value"); + result.put("entityMembershipAttributeName", "memberOf"); + result.put("needEntityLink", "true"); + } else if (StringUtils.equals(valueUserEnteredOnScreen, "entityTableMembershipTable")) { + result.put("hasEntityTable", "true"); + result.put("entityTableName", "from_grouper_entity"); + result.put("entityTableIdColumn", "entity_uuid"); + result.put("entityTablePrimaryKeyValue", "entityUuid"); + result.put("entityTableColumnNames", "subject_id"); + result.put("membershipStructure", "membershipObjects"); + result.put("hasMembershipTable", "true"); + result.put("membershipTableName", "from_grouper_mship"); + result.put("membershipTableGroupColumn", "group_name"); + result.put("membershipTableGroupValue", "groupName"); + result.put("membershipTableEntityColumn", "entity_uuid"); + result.put("membershipTableEntityValue", "entityUuid"); + result.put("needGroupLink", "false"); + result.put("needEntityLink", "true"); + } else if (StringUtils.equals(valueUserEnteredOnScreen, "groupTable")) { + result.put("membershipStructure", "notApplicable"); + result.put("hasGroupTable", "true"); + result.put("groupTableName", "from_grouper_group"); + result.put("groupTableIdColumn", "group_id_index"); + result.put("groupTablePrimaryKeyValue", "groupIdIndex"); + result.put("groupTableColumnNames", "groupIdIndex"); + result.put("needGroupLink", "false"); + } else if (StringUtils.equals(valueUserEnteredOnScreen, "groupTableWithAttributeTable")) { + result.put("membershipStructure", "notApplicable"); + result.put("hasGroupTable", "true"); + result.put("groupTableName", "from_grouper_group"); + result.put("groupTableIdColumn", "group_id_index"); + result.put("groupTablePrimaryKeyValue", "groupIdIndex"); + result.put("groupTableColumnNames", "groupIdIndex"); + result.put("needGroupLink", "false"); + result.put("hasGroupAttributeTable", "true"); + result.put("groupAttributeTableName", "from_grouper_group_attr"); + result.put("columnNameForeignKeyToGroupTable", "group_id_index"); + result.put("groupAttributeNameColumnName", "attribute_name"); + result.put("groupAttributeNameColumnValue", "attribute_value"); + } else if (StringUtils.equals(valueUserEnteredOnScreen, "groupTableWithAttributeTableAndMemberships")) { + result.put("membershipStructure", "groupAttributes"); + result.put("hasGroupTable", "true"); + result.put("groupTableName", "from_grouper_group"); + result.put("groupTableIdColumn", "group_id_index"); + result.put("groupTablePrimaryKeyValue", "groupIdIndex"); + result.put("groupTableColumnNames", "groupIdIndex"); + result.put("hasGroupAttributeTable", "true"); + result.put("groupAttributeTableName", "from_grouper_group_attr"); + result.put("columnNameForeignKeyToGroupTable", "group_id_index"); + result.put("groupAttributeNameColumnName", "attribute_name"); + result.put("groupAttributeNameColumnValue", "attribute_value"); + result.put("groupMembershipAttributeName", "hasMember"); + result.put("needGroupLink", "true"); + } else if (StringUtils.equals(valueUserEnteredOnScreen, "groupTableMembershipTable")) { + result.put("hasGroupTable", "true"); + result.put("groupTableName", "from_grouper_group"); + result.put("groupTableIdColumn", "group_id_index"); + result.put("groupTablePrimaryKeyValue", "groupIdIndex"); + result.put("groupTableColumnNames", "groupIdIndex"); + result.put("needGroupLink", "true"); + result.put("membershipStructure", "membershipObjects"); + result.put("hasMembershipTable", "true"); + result.put("membershipTableName", "from_grouper_mship"); + result.put("membershipTableGroupColumn", "group_id_index"); + result.put("membershipTableGroupValue", "groupIdIndex"); + result.put("membershipTableEntityColumn", "subject_id"); + result.put("membershipTableEntityValue", "subjectId"); + result.put("needEntityLink", "false"); + } else if (StringUtils.equals(valueUserEnteredOnScreen, "groupTableEntityTableMembershipTable")) { + result.put("membershipStructure", "notApplicable"); + result.put("hasEntityTable", "true"); + result.put("entityTableName", "from_grouper_entity"); + result.put("entityTableIdColumn", "entity_uuid"); + result.put("entityTablePrimaryKeyValue", "entityUuid"); + result.put("entityTableColumnNames", "subject_id"); + result.put("needEntityLink", "true"); + result.put("membershipStructure", "notApplicable"); + result.put("hasGroupTable", "true"); + result.put("groupTableName", "from_grouper_group"); + result.put("groupTableIdColumn", "group_id_index"); + result.put("groupTablePrimaryKeyValue", "groupIdIndex"); + result.put("groupTableColumnNames", "groupIdIndex"); + result.put("needGroupLink", "true"); + result.put("membershipStructure", "membershipObjects"); + result.put("hasMembershipTable", "true"); + result.put("membershipTableName", "from_grouper_mship"); + result.put("membershipTableGroupColumn", "group_id_index"); + result.put("membershipTableGroupValue", "groupIdIndex"); + result.put("membershipTableEntityColumn", "entity_uuid"); + result.put("membershipTableEntityValue", "entityUuid"); + } else if (StringUtils.equals(valueUserEnteredOnScreen, "membershipTable")) { + result.put("membershipStructure", "membershipObjects"); + result.put("hasMembershipTable", "true"); + result.put("membershipTableName", "from_grouper_mship"); + result.put("membershipTableGroupColumn", "group_name"); + result.put("membershipTableGroupValue", "groupName"); + result.put("membershipTableEntityColumn", "subject_id"); + result.put("membershipTableEntityValue", "subjectId"); + result.put("needGroupLink", "false"); + result.put("needEntityLink", "false"); + } else if (StringUtils.equals(valueUserEnteredOnScreen, "other")) { + result.clear(); + } + } + + } + + return result; + } + + @Override + public void validatePreSave(boolean isInsert, List errorsToDisplay, Map validationErrorsToDisplay) { + super.validatePreSave(isInsert, errorsToDisplay, validationErrorsToDisplay); + + GrouperConfigurationModuleAttribute hasGroupTableAttribute = this.retrieveAttributes().get("hasGroupTable"); + + if (hasGroupTableAttribute != null && GrouperUtil.booleanValue(hasGroupTableAttribute.getValue(), false)) { + GrouperConfigurationModuleAttribute sqlExternalSystemConnectionName = this.retrieveAttributes().get("dbExternalSystemConfigId"); + GrouperConfigurationModuleAttribute groupTableName = this.retrieveAttributes().get("groupTableName"); + GrouperConfigurationModuleAttribute groupTableIdColumn = this.retrieveAttributes().get("groupTableIdColumn"); + GrouperConfigurationModuleAttribute groupTableColumnNames = this.retrieveAttributes().get("groupTableColumnNames"); + + validateTableAndColumns(validationErrorsToDisplay, sqlExternalSystemConnectionName, groupTableName, groupTableIdColumn, groupTableColumnNames); + + GrouperConfigurationModuleAttribute hasGroupAttributeTableAttribute = this.retrieveAttributes().get("hasGroupAttributeTable"); + if (GrouperUtil.booleanValue(hasGroupAttributeTableAttribute.getValueOrExpressionEvaluation(), false)) { + + GrouperConfigurationModuleAttribute attributeTableName = this.retrieveAttributes().get("groupAttributeTableName"); + GrouperConfigurationModuleAttribute attributeTableIdColumn = this.retrieveAttributes().get("columnNameForeignKeyToGroupTable"); + GrouperConfigurationModuleAttribute attributeTableColumnName = this.retrieveAttributes().get("groupAttributeNameColumnName"); + GrouperConfigurationModuleAttribute attributeTableValueColumn = this.retrieveAttributes().get("groupAttributeValueColumnName"); + + validateTableAndColumns(validationErrorsToDisplay, sqlExternalSystemConnectionName, attributeTableName, attributeTableColumnName, attributeTableValueColumn); + validateTableAndColumns(validationErrorsToDisplay, sqlExternalSystemConnectionName, attributeTableName, attributeTableIdColumn, null); + + } + } + + GrouperConfigurationModuleAttribute hasEntityTableAttribute = this.retrieveAttributes().get("hasEntityTable"); + + if (hasGroupTableAttribute != null && GrouperUtil.booleanValue(hasEntityTableAttribute.getValue(), false)) { + + GrouperConfigurationModuleAttribute sqlExternalSystemConnectionName = this.retrieveAttributes().get("dbExternalSystemConfigId"); + + GrouperConfigurationModuleAttribute entityTableName = this.retrieveAttributes().get("entityTableName"); + GrouperConfigurationModuleAttribute entityTableIdColumn = this.retrieveAttributes().get("entityTableIdColumn"); + GrouperConfigurationModuleAttribute entityTableColumnNames = this.retrieveAttributes().get("entityTableColumnNames"); + + validateTableAndColumns(validationErrorsToDisplay, sqlExternalSystemConnectionName, entityTableName, entityTableIdColumn, entityTableColumnNames); + + GrouperConfigurationModuleAttribute hasEntityAttributeTableAttribute = this.retrieveAttributes().get("hasEntityAttributeTable"); + if (GrouperUtil.booleanValue(hasEntityAttributeTableAttribute.getValueOrExpressionEvaluation(), false)) { + + GrouperConfigurationModuleAttribute attributeTableName = this.retrieveAttributes().get("entityAttributeTableName"); + GrouperConfigurationModuleAttribute attributeTableIdColumn = this.retrieveAttributes().get("columnNameForeignKeyToEntityTable"); + GrouperConfigurationModuleAttribute attributeTableColumnName = this.retrieveAttributes().get("entityAttributeNameColumnName"); + GrouperConfigurationModuleAttribute attributeTableValueColumn = this.retrieveAttributes().get("entityAttributeValueColumnName"); + + validateTableAndColumns(validationErrorsToDisplay, sqlExternalSystemConnectionName, attributeTableName, attributeTableColumnName, attributeTableValueColumn); + validateTableAndColumns(validationErrorsToDisplay, sqlExternalSystemConnectionName, attributeTableName, attributeTableIdColumn, null); + + } + } + + GrouperConfigurationModuleAttribute membershipStructureAttribute = this.retrieveAttributes().get("membershipStructure"); + GrouperConfigurationModuleAttribute hasMembershipTableAttribute = this.retrieveAttributes().get("hasMembershipTable"); + + if (membershipStructureAttribute != null && StringUtils.equals(membershipStructureAttribute.getValue(), "notApplicable") && + hasMembershipTableAttribute != null && GrouperUtil.booleanValue(hasMembershipTableAttribute.getValue(), false)) { + GrouperTextContainer.textOrNull("grouperStartWithInvalidMembershipStructureHasMembershipTable"); + } + + GrouperConfigurationModuleAttribute subjectSourceEntityResoverModuleAttribute = this.retrieveAttributes().get("subjectSourceEntityResolverAttributes"); + if (subjectSourceEntityResoverModuleAttribute != null && StringUtils.isNotBlank(subjectSourceEntityResoverModuleAttribute.getValue())) { + String commaSeparatedResolverAttributes = subjectSourceEntityResoverModuleAttribute.getValue(); + List list = GrouperUtil.splitTrimToList(commaSeparatedResolverAttributes, ","); + if (list.size() > 3) { + String errorMessage = GrouperTextContainer.textOrNull("subjectSourceEntityResolverAttributesMoreThanThreeAttributes"); + validationErrorsToDisplay.put(subjectSourceEntityResoverModuleAttribute.getHtmlForElementIdHandle(), errorMessage); + } + } + + + } + + + private void validateTableAndColumns(Map validationErrorsToDisplay, GrouperConfigurationModuleAttribute sqlExternalSystemConnectionName, + GrouperConfigurationModuleAttribute tableName, GrouperConfigurationModuleAttribute column, GrouperConfigurationModuleAttribute columnNames) { + + GcTableSyncTableMetadata tableMetadata = null; + try { + tableMetadata = GcTableSyncTableMetadata.retrieveTableMetadataFromCacheOrDatabase(sqlExternalSystemConnectionName.getValueOrExpressionEvaluation(), + tableName.getValueOrExpressionEvaluation()); + } catch (Exception e) { + String errorMessage = GrouperTextContainer.textOrNull("grouperStartWithGroupTableConfigurationValidationGroupTableNotFound"); + errorMessage = errorMessage.replace("$$tableName$$", tableName.getValueOrExpressionEvaluation()); + validationErrorsToDisplay.put(tableName.getHtmlForElementIdHandle(), errorMessage); + return; + } + + if (tableMetadata == null) { + String errorMessage = GrouperTextContainer.textOrNull("grouperStartWithGroupTableConfigurationValidationGroupTableNotFound"); + errorMessage = errorMessage.replace("$$tableName$$", tableName.getValueOrExpressionEvaluation()); + validationErrorsToDisplay.put(tableName.getHtmlForElementIdHandle(), errorMessage); + return; + } + + if (columnNames != null && StringUtils.isNotBlank(columnNames.getValueOrExpressionEvaluation())) { + + String columnNamesCommaSeparated = columnNames.getValueOrExpressionEvaluation(); + Set colNamesSet = GrouperUtil.splitTrimToSet(columnNamesCommaSeparated.toLowerCase(), ","); + + List columnsMetadata = tableMetadata.getColumnMetadata(); + + for (GcTableSyncColumnMetadata columnMetadata: GrouperUtil.nonNull(columnsMetadata)) { + String columnName = columnMetadata.getColumnName().toLowerCase(); + + if (colNamesSet.contains(columnName)) { + colNamesSet.remove(columnName); + } + } + + if (colNamesSet.size() > 0) { + String notFoundColNames = GrouperUtil.join(colNamesSet.iterator(), ','); + String errorMessage = GrouperTextContainer.textOrNull("grouperStartWithGroupTableConfigurationValidationGroupIdColumnNotFound"); + errorMessage = errorMessage.replace("$$column$$", notFoundColNames); + validationErrorsToDisplay.put(columnNames.getHtmlForElementIdHandle(), errorMessage); + } + + } + + if (column != null && StringUtils.isNotBlank(column.getValueOrExpressionEvaluation())) { + String groupTableIdColumnValue = GrouperUtil.trim(column.getValueOrExpressionEvaluation()).toLowerCase(); + boolean groupTableIdColumnFound = false; + + List columnsMetadata = tableMetadata.getColumnMetadata(); + + for (GcTableSyncColumnMetadata columnMetadata: GrouperUtil.nonNull(columnsMetadata)) { + String columnName = columnMetadata.getColumnName().toLowerCase(); + if (StringUtils.equals(columnName, groupTableIdColumnValue)) { + groupTableIdColumnFound = true; + break; + } + } + + if (!groupTableIdColumnFound) { + String errorMessage = GrouperTextContainer.textOrNull("grouperStartWithGroupTableConfigurationValidationGroupIdColumnNotFound"); + errorMessage = errorMessage.replace("$$column$$", column.getValueOrExpressionEvaluation()); + validationErrorsToDisplay.put(column.getHtmlForElementIdHandle(), errorMessage); + } + + } + + + } + + /** + * return provisioning suffix to value + * @param startWithSuffixToValue + * @param provisionerSuffixToValue + * @return + */ + @Override + public void populateProvisionerConfigurationValuesFromStartWith(Map startWithSuffixToValue, + Map provisionerSuffixToValue) { + + if (StringUtils.equals(startWithSuffixToValue.get("userAttributesType"), "entityResolver") || StringUtils.equals(startWithSuffixToValue.get("userAttributesType"), "subjectSourceAndEntityResolver")) { + provisionerSuffixToValue.put("entityResolver.entityAttributesNotInSubjectSource", "true"); + } + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("hasTargetEntityLink"), false)) { + provisionerSuffixToValue.put("operateOnGrouperEntities", "true"); + + provisionerSuffixToValue.put("entityAttributeValueCacheHas", "true"); + provisionerSuffixToValue.put("entityAttributeValueCache0has", "true"); + provisionerSuffixToValue.put("entityAttributeValueCache0source", "target"); + provisionerSuffixToValue.put("entityAttributeValueCache0type", "entityAttribute"); + + //TODO debug why this is not getting populated + provisionerSuffixToValue.put("entityAttributeValueCache0entityAttribute", startWithSuffixToValue.get("entityTableIdColumn")); + + } + + if (StringUtils.equals(startWithSuffixToValue.get("userAttributesType"), "subjectSource") || StringUtils.equals(startWithSuffixToValue.get("userAttributesType"), "subjectSourceAndEntityResolver")) { + provisionerSuffixToValue.put("operateOnGrouperEntities", "true"); + + String attributesCommaSeparated = startWithSuffixToValue.get("subjectSourceEntityResolverAttributes"); + if (StringUtils.isNotBlank(attributesCommaSeparated)) { + provisionerSuffixToValue.put("entityAttributeValueCacheHas", "true"); + String[] attributes = GrouperUtil.splitTrim(attributesCommaSeparated, ","); + // by this time the validation is already done that there are no more than 3 attributes + for (int i=0; i otherAttributeNamesSet = new HashSet<>(); + + String entityMembershipAttributeName = null; + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("hasEntityAttributeTable"), false)) { + provisionerSuffixToValue.put("useSeparateTableForEntityAttributes", "true"); + + String otherAttributeNames = startWithSuffixToValue.get("entityOtherAttributeNames"); + otherAttributeNamesSet = GrouperUtil.nonNull(GrouperUtil.splitTrimToSet(otherAttributeNames, ",")); + + entityMembershipAttributeName = startWithSuffixToValue.get("entityMembershipAttributeName"); + + } + + String commaSeparatedColNames = startWithSuffixToValue.get("entityTableColumnNames"); + Set entityTableCols = GrouperUtil.nonNull(GrouperUtil.splitTrimToSet(commaSeparatedColNames, ",")); + + int numberOfEntityAttributes = entityTableCols.size() + otherAttributeNamesSet.size() + 1; // +1 for entityTableIdColumn + + if (StringUtils.isNotBlank(entityMembershipAttributeName)) { + if (entityTableCols.contains(entityMembershipAttributeName) || otherAttributeNamesSet.contains(entityMembershipAttributeName) || StringUtils.equalsIgnoreCase(startWithSuffixToValue.get("entityTableIdColumn"), entityMembershipAttributeName)) { + provisionerSuffixToValue.put("entityMembershipAttributeName", entityMembershipAttributeName); + } else { + numberOfEntityAttributes++; + } + } + + provisionerSuffixToValue.put("numberOfEntityAttributes", numberOfEntityAttributes); + + provisionerSuffixToValue.put("targetEntityAttribute.0.name", startWithSuffixToValue.get("entityTableIdColumn")); + provisionerSuffixToValue.put("targetEntityAttribute.0.translateExpressionType", "grouperProvisioningEntityField"); + provisionerSuffixToValue.put("targetEntityAttribute.0.storageType", "entityTableColumn"); + + String startWithEntityTablePrimaryKeyValue = startWithSuffixToValue.get("entityTablePrimaryKeyValue"); + String grouperProvisioningEntityFieldValue = null; + + if (StringUtils.equals("email", startWithEntityTablePrimaryKeyValue)) { + grouperProvisioningEntityFieldValue = "email"; + } else if (StringUtils.equals("entityUuid", startWithEntityTablePrimaryKeyValue)) { + grouperProvisioningEntityFieldValue = "id"; + } else if (StringUtils.equals("entityDescription", startWithEntityTablePrimaryKeyValue)) { + grouperProvisioningEntityFieldValue = "description"; + } else if (StringUtils.equals("entityName", startWithEntityTablePrimaryKeyValue)) { + grouperProvisioningEntityFieldValue = "name"; + } else if (StringUtils.equals("subjectId", startWithEntityTablePrimaryKeyValue)) { + grouperProvisioningEntityFieldValue = "subjectId"; + } else if (StringUtils.equals("subjectIdentifier0", startWithEntityTablePrimaryKeyValue)) { + grouperProvisioningEntityFieldValue = "subjectIdentifier0"; + } else if (StringUtils.equals("subjectIdentifier1", startWithEntityTablePrimaryKeyValue)) { + grouperProvisioningEntityFieldValue = "subjectIdentifier1"; + } else if (StringUtils.equals("subjectIdentifier2", startWithEntityTablePrimaryKeyValue)) { + grouperProvisioningEntityFieldValue = "subjectIdentifier2"; + } else if (StringUtils.equals("other", startWithEntityTablePrimaryKeyValue) || StringUtils.equals("script", startWithEntityTablePrimaryKeyValue)) { + provisionerSuffixToValue.put("targetEntityAttribute.0.translateExpressionType", "translationScript"); + } + + if (grouperProvisioningEntityFieldValue != null) { + provisionerSuffixToValue.put("targetEntityAttribute.0.translateFromGrouperProvisioningEntityField", grouperProvisioningEntityFieldValue); + } + + int i = 1; + for (String entityTableCol: entityTableCols) { + provisionerSuffixToValue.put("targetEntityAttribute."+i+".name", entityTableCol); + + if (StringUtils.equalsIgnoreCase(entityTableCol, "entity_uuid") || StringUtils.equalsIgnoreCase(entityTableCol, "uuid") || StringUtils.equalsIgnoreCase(entityTableCol, "id")) { + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateExpressionType", "grouperProvisioningEntityField"); + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateFromGrouperProvisioningEntityField", "id"); + } else if (StringUtils.equalsIgnoreCase(entityTableCol, "entity_name") || StringUtils.equalsIgnoreCase(entityTableCol, "name")) { + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateExpressionType", "grouperProvisioningEntityField"); + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateFromGrouperProvisioningEntityField", "name"); + } else if (StringUtils.equalsIgnoreCase(entityTableCol, "email")) { + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateExpressionType", "grouperProvisioningEntityField"); + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateFromGrouperProvisioningEntityField", "email"); + } else if (StringUtils.equalsIgnoreCase(entityTableCol, "entity_description")) { + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateExpressionType", "grouperProvisioningEntityField"); + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateFromGrouperProvisioningEntityField", "description"); + } else if (StringUtils.equalsIgnoreCase(entityTableCol, "subject_id")) { + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateExpressionType", "grouperProvisioningEntityField"); + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateFromGrouperProvisioningEntityField", "subjectId"); + } else if (StringUtils.equalsIgnoreCase(entityTableCol, "subject_identifier0")) { + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateExpressionType", "grouperProvisioningEntityField"); + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateFromGrouperProvisioningEntityField", "subjectIdentifier0"); + } else if (StringUtils.equalsIgnoreCase(entityTableCol, "subject_identifier1")) { + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateExpressionType", "grouperProvisioningEntityField"); + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateFromGrouperProvisioningEntityField", "subjectIdentifier1"); + } else if (StringUtils.equalsIgnoreCase(entityTableCol, "subject_identifier2")) { + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateExpressionType", "grouperProvisioningEntityField"); + provisionerSuffixToValue.put("targetEntityAttribute."+i+".translateFromGrouperProvisioningEntityField", "subjectIdentifier2"); + } + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("hasEntityAttributeTable"), false)) { + provisionerSuffixToValue.put("targetEntityAttribute."+i+".storageType", "entityTableColumn"); // storageType is visible only when hasEntityAttributeTable is true + } + + i++; + } + + for (String otherAttributeCol: otherAttributeNamesSet) { + provisionerSuffixToValue.put("targetEntityAttribute."+i+".name", otherAttributeCol); + provisionerSuffixToValue.put("targetEntityAttribute."+i+".storageType", "separateAttributesTable"); + i++; + } + + if (i <= numberOfEntityAttributes - 1) { + provisionerSuffixToValue.put("targetEntityAttribute."+i+".name", entityMembershipAttributeName); + provisionerSuffixToValue.put("targetEntityAttribute."+i+".storageType", "separateAttributesTable"); + i++; + } + + //TODO debug why this is not getting populated + provisionerSuffixToValue.put("userPrimaryKey", startWithSuffixToValue.get("entityTableIdColumn")); + + } + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("hasGroupTable"), false)) { + + provisionerSuffixToValue.put("operateOnGrouperGroups", "true"); + provisionerSuffixToValue.put("groupTableName", startWithSuffixToValue.get("groupTableName")); + + Set otherAttributeNamesSet = new HashSet<>(); + String groupMembershipAttributeName = null; + + //TODO Later + String groupMembershipAttributeValue = null; + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("hasGroupAttributeTable"), false)) { + provisionerSuffixToValue.put("useSeparateTableForGroupAttributes", "true"); + groupMembershipAttributeName = startWithSuffixToValue.get("groupMembershipAttributeName"); + groupMembershipAttributeValue = startWithSuffixToValue.get("groupMembershipAttributeValue"); + + String otherAttributeNames = startWithSuffixToValue.get("groupOtherAttributeNames"); + otherAttributeNamesSet = GrouperUtil.nonNull(GrouperUtil.splitTrimToSet(otherAttributeNames, ",")); + + } + + String commaSeparatedColNames = startWithSuffixToValue.get("groupTableColumnNames"); + Set groupTableCols = GrouperUtil.nonNull(GrouperUtil.splitTrimToSet(commaSeparatedColNames, ",")); + + int numberOfGroupAttributes = groupTableCols.size() + otherAttributeNamesSet.size() + 1; // +1 for groupTableIdColumn + + if (StringUtils.isNotBlank(groupMembershipAttributeName)) { + if (groupTableCols.contains(groupMembershipAttributeName) || otherAttributeNamesSet.contains(groupMembershipAttributeName) || StringUtils.equalsIgnoreCase(startWithSuffixToValue.get("groupTableIdColumn"), groupMembershipAttributeName)) { + provisionerSuffixToValue.put("groupMembershipAttributeName", groupMembershipAttributeName); + } else { + numberOfGroupAttributes++; + } + } + + provisionerSuffixToValue.put("numberOfGroupAttributes", numberOfGroupAttributes); + + provisionerSuffixToValue.put("targetGroupAttribute.0.name", startWithSuffixToValue.get("groupTableIdColumn")); + provisionerSuffixToValue.put("targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); + + String startWithGroupTablePrimaryKeyValue = startWithSuffixToValue.get("groupTablePrimaryKeyValue"); + String grouperProvisioningGroupFieldValue = null; + + if (StringUtils.equals("groupExtension", startWithGroupTablePrimaryKeyValue)) { + grouperProvisioningGroupFieldValue = "extension"; + } else if (StringUtils.equals("groupIdIndex", startWithGroupTablePrimaryKeyValue)) { + grouperProvisioningGroupFieldValue = "idIndex"; + } else if (StringUtils.equals("groupName", startWithGroupTablePrimaryKeyValue)) { + grouperProvisioningGroupFieldValue = "name"; + } else if (StringUtils.equals("groupUuid", startWithGroupTablePrimaryKeyValue)) { + grouperProvisioningGroupFieldValue = "id"; + } else if (StringUtils.equals("other", startWithGroupTablePrimaryKeyValue) || StringUtils.equals("script", startWithGroupTablePrimaryKeyValue)) { + provisionerSuffixToValue.put("targetGroupAttribute.0.translateExpressionType", "translationScript"); + } + + if (grouperProvisioningGroupFieldValue != null) { + provisionerSuffixToValue.put("targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", grouperProvisioningGroupFieldValue); + } + + provisionerSuffixToValue.put("groupTableIdColumn", startWithSuffixToValue.get("groupTableIdColumn")); + + int i = 1; + for (String groupTableCol: groupTableCols) { + provisionerSuffixToValue.put("targetGroupAttribute."+i+".name", groupTableCol); + + if (StringUtils.equalsIgnoreCase(groupTableCol, "group_uuid") || StringUtils.equalsIgnoreCase(groupTableCol, "uuid") || StringUtils.equalsIgnoreCase(groupTableCol, "id")) { + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateExpressionType", "grouperProvisioningGroupField"); + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateFromGrouperProvisioningGroupField", "id"); + } else if (StringUtils.equalsIgnoreCase(groupTableCol, "group_name") || StringUtils.equalsIgnoreCase(groupTableCol, "name")) { + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateExpressionType", "grouperProvisioningGroupField"); + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateFromGrouperProvisioningGroupField", "name"); + } else if (StringUtils.equalsIgnoreCase(groupTableCol, "group_id_index") || StringUtils.equalsIgnoreCase(groupTableCol, "id_index")) { + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateExpressionType", "grouperProvisioningGroupField"); + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateFromGrouperProvisioningGroupField", "idIndex"); + } else if (StringUtils.equalsIgnoreCase(groupTableCol, "group_extension") || StringUtils.equalsIgnoreCase(groupTableCol, "extension")) { + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateExpressionType", "grouperProvisioningGroupField"); + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateFromGrouperProvisioningGroupField", "extension"); + } else if (StringUtils.equalsIgnoreCase(groupTableCol, "group_display_name") || StringUtils.equalsIgnoreCase(groupTableCol, "display_name")) { + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateExpressionType", "grouperProvisioningGroupField"); + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateFromGrouperProvisioningGroupField", "displayName"); + } else if (StringUtils.equalsIgnoreCase(groupTableCol, "group_display_extension") || StringUtils.equalsIgnoreCase(groupTableCol, "display_extension")) { + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateExpressionType", "grouperProvisioningGroupField"); + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateFromGrouperProvisioningGroupField", "displayExtension"); + } else if (StringUtils.equalsIgnoreCase(groupTableCol, "group_description") || StringUtils.equalsIgnoreCase(groupTableCol, "description")) { + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateExpressionType", "grouperProvisioningGroupField"); + provisionerSuffixToValue.put("targetGroupAttribute."+i+".translateFromGrouperProvisioningGroupField", "description"); + } + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("hasGroupAttributeTable"), false)) { + provisionerSuffixToValue.put("targetGroupAttribute."+i+".storageType", "groupTableColumn"); // storageType is visible only when hasGroupAttributeTable is true + } + + i++; + } + + for (String otherAttributeCol: otherAttributeNamesSet) { + provisionerSuffixToValue.put("targetGroupAttribute."+i+".name", otherAttributeCol); + provisionerSuffixToValue.put("targetGroupAttribute."+i+".storageType", "separateAttributesTable"); + i++; + } + + if ( i <= numberOfGroupAttributes - 1) { + provisionerSuffixToValue.put("targetGroupAttribute."+i+".name", groupMembershipAttributeName); + provisionerSuffixToValue.put("targetGroupAttribute."+i+".storageType", "separateAttributesTable"); + i++; + } + + } + + if (StringUtils.equals(startWithSuffixToValue.get("membershipStructure"), "membershipObjects") || + StringUtils.equals(startWithSuffixToValue.get("membershipStructure"), "groupAttributes") || + StringUtils.equals(startWithSuffixToValue.get("membershipStructure"), "entityAttributes")) { + + provisionerSuffixToValue.put("operateOnGrouperMemberships", "true"); + + provisionerSuffixToValue.put("provisioningType", startWithSuffixToValue.get("membershipStructure")); + } + + if (StringUtils.equals(startWithSuffixToValue.get("membershipStructure"), "membershipObjects")) { + + provisionerSuffixToValue.put("membershipTableName", startWithSuffixToValue.get("membershipTableName")); + + provisionerSuffixToValue.put("numberOfMembershipAttributes", 2); + + String membershipTableGroupColumn = startWithSuffixToValue.get("membershipTableGroupColumn"); + + provisionerSuffixToValue.put("targetMembershipAttribute.0.name", membershipTableGroupColumn); + + String membershipTableGroupValue = startWithSuffixToValue.get("membershipTableGroupValue"); + + if (StringUtils.equalsAny(membershipTableGroupValue, "groupName", "groupExtension", "groupIdIndex", "groupUUID")) { + + provisionerSuffixToValue.put("targetMembershipAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); + if (StringUtils.equals("groupName", membershipTableGroupValue)) { + provisionerSuffixToValue.put("targetMembershipAttribute.0.translateFromGrouperProvisioningGroupField", "name"); + } + if (StringUtils.equals("groupExtension", membershipTableGroupValue)) { + provisionerSuffixToValue.put("targetMembershipAttribute.0.translateFromGrouperProvisioningGroupField", "extension"); + } + if (StringUtils.equals("groupIdIndex", membershipTableGroupValue)) { + provisionerSuffixToValue.put("targetMembershipAttribute.0.translateFromGrouperProvisioningGroupField", "idIndex"); + } + if (StringUtils.equals("groupUUID", membershipTableGroupValue)) { + provisionerSuffixToValue.put("targetMembershipAttribute.0.translateFromGrouperProvisioningGroupField", "id"); + } + + } + + String membershipTableEntityColumn = startWithSuffixToValue.get("membershipTableEntityColumn"); + + provisionerSuffixToValue.put("targetMembershipAttribute.1.name", membershipTableEntityColumn); + + String membershipTableEntityValue = startWithSuffixToValue.get("membershipTableEntityValue"); + + if (StringUtils.equalsAny(membershipTableEntityValue, "email", "entityUuid", "subjectId", "subjectIdentifier0", "subjectIdentifier1", "subjectIdentifier2")) { + + provisionerSuffixToValue.put("targetMembershipAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); + if (StringUtils.equals("email", membershipTableEntityValue)) { + provisionerSuffixToValue.put("targetMembershipAttribute.1.translateFromGrouperProvisioningEntityField", "email"); + } + if (StringUtils.equals("entityUuid", membershipTableEntityValue)) { + provisionerSuffixToValue.put("targetMembershipAttribute.1.translateFromGrouperProvisioningEntityField", "id"); + } + if (StringUtils.equals("subjectId", membershipTableEntityValue)) { + provisionerSuffixToValue.put("targetMembershipAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + } + if (StringUtils.equals("subjectIdentifier0", membershipTableEntityValue)) { + provisionerSuffixToValue.put("targetMembershipAttribute.1.translateFromGrouperProvisioningEntityField", "subjectIdentifier0"); + } + if (StringUtils.equals("subjectIdentifier1", membershipTableEntityValue)) { + provisionerSuffixToValue.put("targetMembershipAttribute.1.translateFromGrouperProvisioningEntityField", "subjectIdentifier1"); + } + if (StringUtils.equals("subjectIdentifier2", membershipTableEntityValue)) { + provisionerSuffixToValue.put("targetMembershipAttribute.1.translateFromGrouperProvisioningEntityField", "subjectIdentifier2"); + } + + } + + provisionerSuffixToValue.put("membershipGroupForeignKeyColumn", membershipTableGroupColumn); + provisionerSuffixToValue.put("membershipEntityForeignKeyColumn", membershipTableEntityColumn); + } + + if (GrouperUtil.booleanValue(startWithSuffixToValue.get("addDisabledFullSyncDaemon"), false) || GrouperUtil.booleanValue(startWithSuffixToValue.get("addDisabledIncrementalSyncDaemon"), false)) { + provisionerSuffixToValue.put("showAdvanced", "true"); + } + + + } +} diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/upgradeTasks/UpgradeTasks.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/upgradeTasks/UpgradeTasks.java index ccd6d29c0c8e..b5994fc6aad3 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/upgradeTasks/UpgradeTasks.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/upgradeTasks/UpgradeTasks.java @@ -201,42 +201,42 @@ public void updateVersionFromPrevious() { } } - }, - V8 { - - @Override - public void updateVersionFromPrevious() { - - v8_provisioningLdapDnAttributeChange(); - - v8_provisioningFieldNameToAttributeChange(); - - v8_provisioningSelectAllEntitiesDefault(); - - v8_provisioningEntityResolverRefactor(); - - v8_provisioningCustomizeMembershipCrud(); - - v8_provisioningCustomizeGroupCrud(); - - v8_provisioningCustomizeEntityCrud(); - - v8_provisioningMembershipShowValidation(); - - v8_provisioningGroupShowValidation(); - - v8_provisioningEntityShowValidation(); - - v8_provisioningMembershipShowAttributeCrud(); - - v8_provisioningGroupShowAttributeCrud(); - - v8_provisioningEntityShowAttributeCrud(); - - v8_provisioningMembershipShowAttributeValueSettings(); - - v8_provisioningGroupShowAttributeValueSettings(); - } +// } +// , V8 { +// +// @Override +// public void updateVersionFromPrevious() { +// + // v8_provisioningLdapDnAttributeChange(); + // + // v8_provisioningFieldNameToAttributeChange(); + // + // v8_provisioningSelectAllEntitiesDefault(); + // + // v8_provisioningEntityResolverRefactor(); + // + // v8_provisioningCustomizeMembershipCrud(); + // + // v8_provisioningCustomizeGroupCrud(); + // + // v8_provisioningCustomizeEntityCrud(); + // + // v8_provisioningMembershipShowValidation(); + // + // v8_provisioningGroupShowValidation(); + // + // v8_provisioningEntityShowValidation(); + // + // v8_provisioningMembershipShowAttributeCrud(); + // + // v8_provisioningGroupShowAttributeCrud(); + // + // v8_provisioningEntityShowAttributeCrud(); + // + // v8_provisioningMembershipShowAttributeValueSettings(); + // + // v8_provisioningGroupShowAttributeValueSettings(); +// } }; /** logger */ @@ -261,114 +261,6 @@ public static int currentVersion() { return currentVersion; } - /** - * @return if did something - */ - public static boolean v8_provisioningLdapDnAttributeChange() { - // GRP-3931: change ldap DN from field name to attribute ldap_dn - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - String className = GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configId + ".class"); - if (!StringUtils.equals(className, LdapSync.class.getName())) { - continue; - } - for (String objectType : new String[] {"Entity", "Group" }) { - // lets look at group and entity attributes - for (int i=0;i<20;i++) { - String fieldNameKey = "provisioner." + configId + ".target" + objectType + "Attribute." + i + ".fieldName"; - String fieldName = GrouperLoaderConfig.retrieveConfig().propertyValueString(fieldNameKey); - if (!StringUtils.isBlank(fieldName) && StringUtils.equals(fieldName, "name")) { - didSomething = true; - - { - String nameKey = "provisioner." + configId + ".target" + objectType + "Attribute." + i + ".name"; - grouperLoaderConfigUpdate(nameKey, "ldap_dn"); - } - - { - String isFieldElseAttributeKey = "provisioner." + configId + ".target" + objectType + "Attribute." + i + ".isFieldElseAttribute"; - boolean isFieldElseAttribute =GrouperLoaderConfig.retrieveConfig().propertyValueBoolean(isFieldElseAttributeKey, false); - if (isFieldElseAttribute) { - grouperLoaderConfigUpdate(isFieldElseAttributeKey, "false"); - } - } - grouperLoaderConfigDelete(fieldNameKey); - } - } - } - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for LDAP DN field name change to ldap_dn attribute"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - - /** - * - * @return if did something - */ - public static boolean v8_provisioningFieldNameToAttributeChange() { - // GRP-3927: There is no provisioning concept of field anymore, only attribute - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - for (String objectType : new String[] {"Entity", "Group", "Membership" }) { - - // lets look at group and entity and membership attributes - Set existingAttributeNames = new HashSet(); - for (int i=0;i<20;i++) { - String attributeNameKey = "provisioner." + configId + ".target" + objectType + "Attribute." + i + ".name"; - String attributeName = GrouperLoaderConfig.retrieveConfig().propertyValueString(attributeNameKey); - if (!StringUtils.isBlank(attributeName)) { - existingAttributeNames.add(attributeName); - } - } - - for (int i=0;i<20;i++) { - String fieldNameKey = "provisioner." + configId + ".target" + objectType + "Attribute." + i + ".fieldName"; - String fieldName = GrouperLoaderConfig.retrieveConfig().propertyValueString(fieldNameKey); - if (!StringUtils.isBlank(fieldName)) { - didSomething = true; - - if (existingAttributeNames.contains(fieldName)) { - throw new RuntimeException("Cannot continue since provisioning configId '" + configId + "' has a field with name '" + fieldName + "' and an attribute with the same name. Either rename the attribute or contact the grouper team."); - } - - - { - String nameKey = "provisioner." + configId + ".target" + objectType + "Attribute." + i + ".name"; - grouperLoaderConfigUpdate(nameKey, fieldName); - } - grouperLoaderConfigDelete(fieldNameKey); - - } - { - String isFieldElseAttributeKey = "provisioner." + configId + ".target" + objectType + "Attribute." + i + ".isFieldElseAttribute"; - String isFieldElseAttribute =GrouperLoaderConfig.retrieveConfig().propertyValueString(isFieldElseAttributeKey); - if (!StringUtils.isBlank(isFieldElseAttribute)) { - didSomething = true; - grouperLoaderConfigDelete(isFieldElseAttributeKey); - } - } - - } - } - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for migrating provisioning fields to attributes"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - public static final Set v8_entityResolverSuffixesToRefactor = GrouperUtil.toSet("entityAttributesNotInSubjectSource", "resolveAttributesWithSQL", "useGlobalSQLResolver", @@ -401,811 +293,5 @@ public static boolean v8_provisioningFieldNameToAttributeChange() { "filterAllLDAPOnFull", "lastUpdatedAttribute", "lastUpdatedFormat" ); - - /** - * - * @return if did something - */ - public static boolean v8_provisioningEntityResolverRefactor() { - - // FROM provisioner.genericProvisioner.entityAttributesNotInSubjectSource - // TO provisioner.genericProvisioner.entityResolver.entityAttributesNotInSubjectSource - - // GRP-3939: Refactor entity attribute resolver config - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - - for (String suffixToRefactor : v8_entityResolverSuffixesToRefactor) { - - String resolverKeyOld = "provisioner." + configId + "." + suffixToRefactor; - String resolverKeyNew = "provisioner." + configId + ".entityResolver." + suffixToRefactor; - String resolverValue = GrouperLoaderConfig.retrieveConfig().propertyValueString(resolverKeyOld); - if (StringUtils.isBlank(resolverValue)) { - continue; - } - didSomething = true; - - grouperLoaderConfigUpdate(resolverKeyNew, resolverValue); - grouperLoaderConfigDelete(resolverKeyOld); - - } - - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for entity resolver refactor"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - - /** - * - * @return if did something - */ - public static boolean v8_provisioningSelectAllEntitiesDefault() { - // GRP-3938: provisioning selectAllEntities should not have a default - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - String selectAllEntitiesKey = "provisioner." + configId + ".selectAllEntities"; - String selectAllEntities = GrouperLoaderConfig.retrieveConfig().propertyValueString(selectAllEntitiesKey); - if (StringUtils.isBlank(selectAllEntities)) { - continue; - } - didSomething = true; - grouperLoaderConfigUpdate(selectAllEntitiesKey, "false"); - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for 'select all entities' default"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - - /** - * - * @return if did something - */ - public static boolean v8_provisioningCustomizeMembershipCrud() { - // GRP-3953: add provisioning customizeMembershipCrud - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - String operateOnGrouperMembershipsKey = "provisioner." + configId + ".operateOnGrouperMemberships"; - String customizeMembershipCrudKey = "provisioner." + configId + ".customizeMembershipCrud"; - String insertMembershipsKey = "provisioner." + configId + ".insertMemberships"; - String selectMembershipsKey = "provisioner." + configId + ".selectMemberships"; - String deleteMembershipsKey = "provisioner." + configId + ".deleteMemberships"; - String deleteMembershipsIfNotExistInGrouperKey = "provisioner." + configId + ".deleteMembershipsIfNotExistInGrouper"; - String deleteMembershipsIfGrouperDeletedKey = "provisioner." + configId + ".deleteMembershipsIfGrouperDeleted"; - String deleteMembershipsIfGrouperCreatedKey = "provisioner." + configId + ".deleteMembershipsIfGrouperCreated"; - - Boolean customizeMembershipCrud = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(customizeMembershipCrudKey)); - - // if we are already up to date - if (customizeMembershipCrud != null) { - continue; - } - - Boolean operateOnGrouperMemberships = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(operateOnGrouperMembershipsKey)); - Boolean insertMemberships = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(insertMembershipsKey)); - Boolean selectMemberships = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(selectMembershipsKey)); - Boolean deleteMemberships = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(deleteMembershipsKey)); - Boolean deleteMembershipsIfNotExistInGrouper = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(deleteMembershipsIfNotExistInGrouperKey)); - Boolean deleteMembershipsIfGrouperDeleted = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(deleteMembershipsIfGrouperDeletedKey)); - Boolean deleteMembershipsIfGrouperCreated = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(deleteMembershipsIfGrouperCreatedKey)); - - // if nothing set thats ok - if ((operateOnGrouperMemberships == null || !operateOnGrouperMemberships) - && customizeMembershipCrud == null - && insertMemberships == null - && deleteMemberships == null - && deleteMembershipsIfNotExistInGrouper == null - && deleteMembershipsIfGrouperDeleted == null - && deleteMembershipsIfGrouperCreated == null ) { - continue; - } - - didSomething = true; - - - // if we are somehow at the default - if (operateOnGrouperMemberships && insertMemberships != null && insertMemberships - && selectMemberships != null && selectMemberships - && deleteMemberships != null && deleteMemberships - && deleteMembershipsIfNotExistInGrouper == null - && deleteMembershipsIfGrouperDeleted == null - && deleteMembershipsIfGrouperCreated != null && deleteMembershipsIfGrouperCreated) { - grouperLoaderConfigDelete(insertMembershipsKey); - grouperLoaderConfigDelete(selectMembershipsKey); - grouperLoaderConfigDelete(deleteMembershipsKey); - grouperLoaderConfigDelete(deleteMembershipsIfGrouperCreatedKey); - } else { - - grouperLoaderConfigUpdate(customizeMembershipCrudKey, "true"); - - if (insertMemberships == null) { - grouperLoaderConfigUpdate(insertMembershipsKey, "false"); - } - if (selectMemberships == null) { - grouperLoaderConfigUpdate(selectMembershipsKey, "false"); - } - if (deleteMemberships == null) { - grouperLoaderConfigUpdate(deleteMembershipsKey, "false"); - } - if (deleteMemberships != null && deleteMemberships && deleteMembershipsIfNotExistInGrouper == null && deleteMembershipsIfGrouperDeleted == null && deleteMembershipsIfGrouperCreated == null) { - grouperLoaderConfigUpdate(deleteMembershipsIfGrouperCreatedKey, "false"); - } - - } - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for 'membership CRUD defaults'"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - - /** - * - * @return if did something - */ - public static boolean v8_provisioningCustomizeGroupCrud() { - // GRP-3953: add provisioning customizeGroupCrud - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - String operateOnGrouperGroupsKey = "provisioner." + configId + ".operateOnGrouperGroups"; - String customizeGroupCrudKey = "provisioner." + configId + ".customizeGroupCrud"; - String insertGroupsKey = "provisioner." + configId + ".insertGroups"; - String updateGroupsKey = "provisioner." + configId + ".updateGroups"; - String selectGroupsKey = "provisioner." + configId + ".selectGroups"; - String deleteGroupsKey = "provisioner." + configId + ".deleteGroups"; - String deleteGroupsIfNotExistInGrouperKey = "provisioner." + configId + ".deleteGroupsIfNotExistInGrouper"; - String deleteGroupsIfGrouperDeletedKey = "provisioner." + configId + ".deleteGroupsIfGrouperDeleted"; - String deleteGroupsIfGrouperCreatedKey = "provisioner." + configId + ".deleteGroupsIfGrouperCreated"; - - Boolean customizeGroupCrud = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(customizeGroupCrudKey)); - Boolean operateOnGrouperGroups = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(operateOnGrouperGroupsKey)); - - // if we are already up to date - if (operateOnGrouperGroups != null && operateOnGrouperGroups && customizeGroupCrud != null) { - continue; - } - - Boolean insertGroups = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(insertGroupsKey)); - Boolean updateGroups = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(updateGroupsKey)); - Boolean selectGroups = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(selectGroupsKey)); - Boolean deleteGroups = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(deleteGroupsKey)); - Boolean deleteGroupsIfNotExistInGrouper = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(deleteGroupsIfNotExistInGrouperKey)); - Boolean deleteGroupsIfGrouperDeleted = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(deleteGroupsIfGrouperDeletedKey)); - Boolean deleteGroupsIfGrouperCreated = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(deleteGroupsIfGrouperCreatedKey)); - - // if nothing set thats ok - if ((operateOnGrouperGroups == null || !operateOnGrouperGroups) - && customizeGroupCrud == null - && insertGroups == null - && updateGroups == null - && deleteGroups == null - && deleteGroupsIfNotExistInGrouper == null - && deleteGroupsIfGrouperDeleted == null - && deleteGroupsIfGrouperCreated == null ) { - continue; - } - - didSomething = true; - - // if we are somehow at the default - if (operateOnGrouperGroups && insertGroups != null && insertGroups - && updateGroups != null && updateGroups - && selectGroups != null && selectGroups - && deleteGroups != null && deleteGroups - && deleteGroupsIfNotExistInGrouper == null - && deleteGroupsIfGrouperDeleted == null - && deleteGroupsIfGrouperCreated != null && deleteGroupsIfGrouperCreated) { - grouperLoaderConfigDelete(insertGroupsKey); - grouperLoaderConfigDelete(updateGroupsKey); - grouperLoaderConfigDelete(selectGroupsKey); - grouperLoaderConfigDelete(deleteGroupsKey); - grouperLoaderConfigDelete(deleteGroupsIfGrouperCreatedKey); - } else { - grouperLoaderConfigUpdate(customizeGroupCrudKey, "true"); - - if (insertGroups == null) { - grouperLoaderConfigUpdate(insertGroupsKey, "false"); - } - if (selectGroups == null) { - grouperLoaderConfigUpdate(selectGroupsKey, "false"); - } - if (updateGroups == null) { - grouperLoaderConfigUpdate(updateGroupsKey, "false"); - } - if (deleteGroups == null) { - grouperLoaderConfigUpdate(deleteGroupsKey, "false"); - } - if (deleteGroups != null && deleteGroups && deleteGroupsIfNotExistInGrouper == null && deleteGroupsIfGrouperDeleted == null && deleteGroupsIfGrouperCreated == null) { - grouperLoaderConfigUpdate(deleteGroupsIfGrouperCreatedKey, "false"); - } - } - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for 'group CRUD defaults'"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - - /** - * - * @return if did something - */ - public static boolean v8_provisioningCustomizeEntityCrud() { - // GRP-3955: add provisioning customizeEntityCrud - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - String operateOnGrouperEntitiesKey = "provisioner." + configId + ".operateOnGrouperEntities"; - String makeChangesToEntitiesKey = "provisioner." + configId + ".makeChangesToEntities"; - String customizeEntityCrudKey = "provisioner." + configId + ".customizeEntityCrud"; - String insertEntitiesKey = "provisioner." + configId + ".insertEntities"; - String updateEntitiesKey = "provisioner." + configId + ".updateEntities"; - String selectEntitiesKey = "provisioner." + configId + ".selectEntities"; - String deleteEntitiesKey = "provisioner." + configId + ".deleteEntities"; - String deleteEntitiesIfNotExistInGrouperKey = "provisioner." + configId + ".deleteEntitiesIfNotExistInGrouper"; - String deleteEntitiesIfGrouperDeletedKey = "provisioner." + configId + ".deleteEntitiesIfGrouperDeleted"; - String deleteEntitiesIfGrouperCreatedKey = "provisioner." + configId + ".deleteEntitiesIfGrouperCreated"; - - Boolean customizeEntityCrud = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(customizeEntityCrudKey)); - Boolean operateOnGrouperEntities = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(operateOnGrouperEntitiesKey)); - Boolean makeChangesToEntities = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(makeChangesToEntitiesKey)); - - // if we are already up to date - if (operateOnGrouperEntities != null && operateOnGrouperEntities && (customizeEntityCrud != null || makeChangesToEntities != null)) { - continue; - } - - Boolean insertEntities = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(insertEntitiesKey)); - Boolean updateEntities = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(updateEntitiesKey)); - Boolean selectEntities = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(selectEntitiesKey)); - Boolean deleteEntities = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(deleteEntitiesKey)); - Boolean deleteEntitiesIfNotExistInGrouper = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(deleteEntitiesIfNotExistInGrouperKey)); - Boolean deleteEntitiesIfGrouperDeleted = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(deleteEntitiesIfGrouperDeletedKey)); - Boolean deleteEntitiesIfGrouperCreated = GrouperUtil.booleanObjectValue(GrouperLoaderConfig.retrieveConfig().propertyValueString(deleteEntitiesIfGrouperCreatedKey)); - - // if nothing set thats ok - if ((operateOnGrouperEntities == null || !operateOnGrouperEntities) - && customizeEntityCrud == null - && insertEntities == null - && updateEntities == null - && deleteEntities == null - && deleteEntitiesIfNotExistInGrouper == null - && deleteEntitiesIfGrouperDeleted == null - && deleteEntitiesIfGrouperCreated == null ) { - continue; - } - - didSomething = true; - - // if we are somehow at the default readonly - if (operateOnGrouperEntities - && insertEntities == null - && updateEntities == null - && selectEntities != null && selectEntities - && deleteEntities == null - && deleteEntitiesIfNotExistInGrouper == null - && deleteEntitiesIfGrouperDeleted == null - && deleteEntitiesIfGrouperCreated == null) { - grouperLoaderConfigDelete(selectEntitiesKey); - - // if we are somehow at the default - } else if (operateOnGrouperEntities && insertEntities != null && insertEntities - && updateEntities != null && updateEntities - && selectEntities != null && selectEntities - && deleteEntities != null && deleteEntities - && deleteEntitiesIfNotExistInGrouper == null - && deleteEntitiesIfGrouperDeleted == null - && deleteEntitiesIfGrouperCreated != null && deleteEntitiesIfGrouperCreated) { - grouperLoaderConfigUpdate(makeChangesToEntitiesKey, "true"); - grouperLoaderConfigDelete(insertEntitiesKey); - grouperLoaderConfigDelete(updateEntitiesKey); - grouperLoaderConfigDelete(selectEntitiesKey); - grouperLoaderConfigDelete(deleteEntitiesKey); - grouperLoaderConfigDelete(deleteEntitiesIfGrouperCreatedKey); - } else { - - grouperLoaderConfigUpdate(customizeEntityCrudKey, "true"); - - if ((insertEntities!= null && insertEntities) - || (updateEntities!= null && updateEntities) - || (deleteEntitiesIfNotExistInGrouper!= null && deleteEntitiesIfNotExistInGrouper) - || (deleteEntitiesIfGrouperDeleted!= null && deleteEntitiesIfGrouperDeleted) - || (deleteEntitiesIfGrouperCreated!= null && deleteEntitiesIfGrouperCreated)) { - grouperLoaderConfigUpdate(makeChangesToEntitiesKey, "true"); - } - - if (insertEntities == null) { - grouperLoaderConfigUpdate(insertEntitiesKey, "false"); - } - if (selectEntities == null) { - grouperLoaderConfigUpdate(selectEntitiesKey, "false"); - } - if (updateEntities == null) { - grouperLoaderConfigUpdate(updateEntitiesKey, "false"); - } - if (deleteEntities == null) { - grouperLoaderConfigUpdate(deleteEntitiesKey, "false"); - } - if (deleteEntities != null && deleteEntities && deleteEntitiesIfNotExistInGrouper == null && deleteEntitiesIfGrouperDeleted == null && deleteEntitiesIfGrouperCreated == null) { - grouperLoaderConfigUpdate(deleteEntitiesIfGrouperCreatedKey, "false"); - } - } - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for 'entity CRUD defaults'"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - - /** - * - * @return if did something - */ - public static boolean v8_provisioningMembershipShowValidation() { - // GRP-3957: provisioning membership show validation settings - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - - for (int i=0;i<20;i++) { - - if (!GrouperLoaderConfig.retrieveConfig().containsKey("provisioner." + configId + ".targetMembershipAttribute." + i + ".name")) { - continue; - } - String requiredKey = "provisioner." + configId + ".targetMembershipAttribute." + i + ".required"; - String maxlengthKey = "provisioner." + configId + ".targetMembershipAttribute." + i + ".maxlength"; - String validExpressionKey = "provisioner." + configId + ".targetMembershipAttribute." + i + ".validExpression"; - String showAttributeValidationKey = "provisioner." + configId + ".targetMembershipAttribute." + i + ".showAttributeValidation"; - - if (GrouperLoaderConfig.retrieveConfig().containsKey(showAttributeValidationKey)) { - // already done - continue; - } - - if (GrouperLoaderConfig.retrieveConfig().containsKey(requiredKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(maxlengthKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(validExpressionKey)) { - didSomething = true; - grouperLoaderConfigUpdate(showAttributeValidationKey, "true"); - } - - } - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for 'membership attribute show validation'"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - - /** - * - * @return if did something - */ - public static boolean v8_provisioningMembershipShowAttributeValueSettings() { - // GRP-3963: provisioning membership attribute value settings - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - - for (int i=0;i<20;i++) { - - if (!GrouperLoaderConfig.retrieveConfig().containsKey("provisioner." + configId + ".targetMembershipAttribute." + i + ".name")) { - continue; - } - String valueTypeKey = "provisioner." + configId + ".targetMembershipAttribute." + i + ".valueType"; - String ignoreIfMatchesValueKey = "provisioner." + configId + ".targetMembershipAttribute." + i + ".ignoreIfMatchesValue"; - String defaultValueKey = "provisioner." + configId + ".targetMembershipAttribute." + i + ".defaultValue"; - String multiValuedKey = "provisioner." + configId + ".targetMembershipAttribute." + i + ".multiValued"; - String showAttributeValueSettingsKey = "provisioner." + configId + ".targetMembershipAttribute." + i + ".showAttributeValueSettings"; - - if (GrouperLoaderConfig.retrieveConfig().containsKey(showAttributeValueSettingsKey)) { - // already done - continue; - } - - if (GrouperLoaderConfig.retrieveConfig().containsKey(valueTypeKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(ignoreIfMatchesValueKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(defaultValueKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(multiValuedKey)) { - didSomething = true; - grouperLoaderConfigUpdate(showAttributeValueSettingsKey, "true"); - } - - } - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for 'membership attribute show attribute value settings'"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - - /** - * - * @return if did something - */ - public static boolean v8_provisioningMembershipShowAttributeCrud() { - // GRP-3960: provisioning membership attribute customize CRUD - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - - for (int i=0;i<20;i++) { - - if (!GrouperLoaderConfig.retrieveConfig().containsKey("provisioner." + configId + ".targetMembershipAttribute." + i + ".name")) { - continue; - } - String showAttributeCrudKey = "provisioner." + configId + ".targetMembershipAttribute." + i + ".showAttributeCrud"; - - if (GrouperLoaderConfig.retrieveConfig().containsKey(showAttributeCrudKey)) { - // already done - continue; - } - - String insertKey = "provisioner." + configId + ".targetMembershipAttribute." + i + ".insert"; - String selectKey = "provisioner." + configId + ".targetMembershipAttribute." + i + ".select"; - - if (GrouperLoaderConfig.retrieveConfig().containsKey(insertKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(selectKey)) { - didSomething = true; - grouperLoaderConfigUpdate(showAttributeCrudKey, "true"); - } - - if (GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".operateOnGrouperMemberships", false)) { - if (!GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".customizeMembershipCrud", false) - || GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".selectMemberships", true)) { - if (!GrouperLoaderConfig.retrieveConfig().containsKey(selectKey)) { - didSomething = true; - grouperLoaderConfigUpdate(selectKey, "false"); - - } - } - if (!GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".customizeMembershipCrud", false) - || GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".insertMemberships", true)) { - if (!GrouperLoaderConfig.retrieveConfig().containsKey(insertKey)) { - didSomething = true; - grouperLoaderConfigUpdate(insertKey, "false"); - } - } - } - } - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for 'membership attribute show crud'"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - - /** - * - * @return if did something - */ - public static boolean v8_provisioningGroupShowAttributeCrud() { - // GRP-3961: provisioning group attribute customize CRUD - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - - for (int i=0;i<20;i++) { - - if (!GrouperLoaderConfig.retrieveConfig().containsKey("provisioner." + configId + ".targetGroupAttribute." + i + ".name")) { - continue; - } - - String showAttributeCrudKey = "provisioner." + configId + ".targetGroupAttribute." + i + ".showAttributeCrud"; - - if (GrouperLoaderConfig.retrieveConfig().containsKey(showAttributeCrudKey)) { - // already done - continue; - } - - String insertKey = "provisioner." + configId + ".targetGroupAttribute." + i + ".insert"; - String updateKey = "provisioner." + configId + ".targetGroupAttribute." + i + ".update"; - String selectKey = "provisioner." + configId + ".targetGroupAttribute." + i + ".select"; - - if (GrouperLoaderConfig.retrieveConfig().containsKey(insertKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(updateKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(selectKey)) { - didSomething = true; - grouperLoaderConfigUpdate(showAttributeCrudKey, "true"); - } - if (GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".operateOnGrouperGroups", false)) { - if (!GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".customizeGroupCrud", false) - || GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".selectGroups", true)) { - if (!GrouperLoaderConfig.retrieveConfig().containsKey(selectKey)) { - didSomething = true; - grouperLoaderConfigUpdate(selectKey, "false"); - - } - } - if (!GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".customizeGroupCrud", false) - || GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".insertGroups", true)) { - if (!GrouperLoaderConfig.retrieveConfig().containsKey(insertKey)) { - didSomething = true; - grouperLoaderConfigUpdate(insertKey, "false"); - } - } - if (!GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".customizeGroupCrud", false) - || GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".updateGroups", true)) { - if (!GrouperLoaderConfig.retrieveConfig().containsKey(updateKey)) { - didSomething = true; - grouperLoaderConfigUpdate(updateKey, "false"); - } - } - } - } - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for 'group attribute show crud'"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - - /** - * - * @return if did something - */ - public static boolean v8_provisioningGroupShowValidation() { - // GRP-3956: provisioning group show validation settings - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - - for (int i=0;i<20;i++) { - - if (!GrouperLoaderConfig.retrieveConfig().containsKey("provisioner." + configId + ".targetGroupAttribute." + i + ".name")) { - continue; - } - String requiredKey = "provisioner." + configId + ".targetGroupAttribute." + i + ".required"; - String maxlengthKey = "provisioner." + configId + ".targetGroupAttribute." + i + ".maxlength"; - String validExpressionKey = "provisioner." + configId + ".targetGroupAttribute." + i + ".validExpression"; - String showAttributeValidationKey = "provisioner." + configId + ".targetGroupAttribute." + i + ".showAttributeValidation"; - - if (GrouperLoaderConfig.retrieveConfig().containsKey(showAttributeValidationKey)) { - // already done - continue; - } - - if (GrouperLoaderConfig.retrieveConfig().containsKey(requiredKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(maxlengthKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(validExpressionKey)) { - didSomething = true; - grouperLoaderConfigUpdate(showAttributeValidationKey, "true"); - } - - } - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for 'group attribute show validation'"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - - /** - * - * @return if did something - */ - public static boolean v8_provisioningEntityShowValidation() { - // GRP-3959: provisioning Entity show validation settings - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - - for (int i=0;i<20;i++) { - - if (!GrouperLoaderConfig.retrieveConfig().containsKey("provisioner." + configId + ".targetEntityAttribute." + i + ".name")) { - continue; - } - String requiredKey = "provisioner." + configId + ".targetEntityAttribute." + i + ".required"; - String maxlengthKey = "provisioner." + configId + ".targetEntityAttribute." + i + ".maxlength"; - String validExpressionKey = "provisioner." + configId + ".targetEntityAttribute." + i + ".validExpression"; - String showAttributeValidationKey = "provisioner." + configId + ".targetEntityAttribute." + i + ".showAttributeValidation"; - - if (GrouperLoaderConfig.retrieveConfig().containsKey(showAttributeValidationKey)) { - // already done - continue; - } - - if (GrouperLoaderConfig.retrieveConfig().containsKey(requiredKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(maxlengthKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(validExpressionKey)) { - didSomething = true; - grouperLoaderConfigUpdate(showAttributeValidationKey, "true"); - } - - } - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for 'entity attribute show validation'"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - - private static void grouperLoaderConfigDelete(String key) { - if (!key.startsWith("provisioner.")) { - throw new RuntimeException("Invalid key, should start with provisioner."); - } - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName(key).delete(); - String action = "Provisioning upgrade: deleting grouper-loader.properties " + key; - LOG.warn(action); - System.out.println(action); - - } - - private static void grouperLoaderConfigUpdate(String key, String value) { - if (!key.startsWith("provisioner.")) { - throw new RuntimeException("Invalid key, should start with provisioner."); - } - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName(key).value(value).store(); - String action = "Provisioning upgrade: setting grouper-loader.properties " + key + " = " + value; - LOG.warn(action); - System.out.println(action); - - } - - /** - * - * @return if did something - */ - public static boolean v8_provisioningEntityShowAttributeCrud() { - // GRP-3962: provisioning Entity attribute customize CRUD - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - - for (int i=0;i<20;i++) { - - if (!GrouperLoaderConfig.retrieveConfig().containsKey("provisioner." + configId + ".targetEntityAttribute." + i + ".name")) { - continue; - } - - String showAttributeCrudKey = "provisioner." + configId + ".targetEntityAttribute." + i + ".showAttributeCrud"; - - if (GrouperLoaderConfig.retrieveConfig().containsKey(showAttributeCrudKey)) { - // already done - continue; - } - - String insertKey = "provisioner." + configId + ".targetEntityAttribute." + i + ".insert"; - String updateKey = "provisioner." + configId + ".targetEntityAttribute." + i + ".update"; - String selectKey = "provisioner." + configId + ".targetEntityAttribute." + i + ".select"; - - if (GrouperLoaderConfig.retrieveConfig().containsKey(insertKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(updateKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(selectKey)) { - didSomething = true; - grouperLoaderConfigUpdate(showAttributeCrudKey, "true"); - } - if (GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".operateOnGrouperEntities", false)) { - if (!GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".customizeEntityCrud", false) - || GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".selectEntities", true)) { - if (!GrouperLoaderConfig.retrieveConfig().containsKey(selectKey)) { - didSomething = true; - grouperLoaderConfigUpdate(selectKey, "false"); - - } - } - if (!GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".customizeEntityCrud", false) - || GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".insertEntities", true)) { - if (!GrouperLoaderConfig.retrieveConfig().containsKey(insertKey)) { - didSomething = true; - grouperLoaderConfigUpdate(insertKey, "false"); - } - } - if (!GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".customizeEntityCrud", false) - || GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configId + ".updateEntities", true)) { - if (!GrouperLoaderConfig.retrieveConfig().containsKey(updateKey)) { - didSomething = true; - grouperLoaderConfigUpdate(updateKey, "false"); - } - } - } - } - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for 'entity attribute show crud'"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - - /** - * - * @return if did something - */ - public static boolean v8_provisioningGroupShowAttributeValueSettings() { - // GRP-3963: provisioning Group attribute value settings - boolean didSomething = false; - Set configIds = GrouperLoaderConfig.retrieveConfig().propertyConfigIds(Pattern.compile("^provisioner\\.([^.]+)\\.class$")); - for (String configId : GrouperUtil.nonNull(configIds)) { - - for (int i=0;i<20;i++) { - - if (!GrouperLoaderConfig.retrieveConfig().containsKey("provisioner." + configId + ".targetGroupAttribute." + i + ".name")) { - continue; - } - String valueTypeKey = "provisioner." + configId + ".targetGroupAttribute." + i + ".valueType"; - String ignoreIfMatchesValueKey = "provisioner." + configId + ".targetGroupAttribute." + i + ".ignoreIfMatchesValue"; - String defaultValueKey = "provisioner." + configId + ".targetGroupAttribute." + i + ".defaultValue"; - String multiValuedKey = "provisioner." + configId + ".targetGroupAttribute." + i + ".multiValued"; - String showAttributeValueSettingsKey = "provisioner." + configId + ".targetGroupAttribute." + i + ".showAttributeValueSettings"; - - if (GrouperLoaderConfig.retrieveConfig().containsKey(showAttributeValueSettingsKey)) { - // already done - continue; - } - - if (GrouperLoaderConfig.retrieveConfig().containsKey(valueTypeKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(ignoreIfMatchesValueKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(defaultValueKey) - || GrouperLoaderConfig.retrieveConfig().containsKey(multiValuedKey)) { - didSomething = true; - grouperLoaderConfigUpdate(showAttributeValueSettingsKey, "true"); - } - - } - } - if (!didSomething) { - String action = "Provisioning upgrade: no change for 'group attribute show attribute value settings'"; - LOG.warn(action); - System.out.println(action); - } else { - ConfigPropertiesCascadeBase.clearCache(); - } - return didSomething; - } - } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/usdu/UsduJob.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/usdu/UsduJob.java index 43900616ac09..8ee68430431c 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/usdu/UsduJob.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/usdu/UsduJob.java @@ -292,7 +292,7 @@ private int syncProvisioningData(List memberIds, Map me int totalObjectsStored = 0; - Pattern provisionerPatternWithMemberInfo = Pattern.compile("^provisioner\\.(\\w+)\\.common\\.subjectLink\\.(memberFromId2|memberFromId3|memberToId2|memberToId3)$"); + Pattern provisionerPatternWithMemberInfo = Pattern.compile("^provisioner\\.(\\w+)\\.(entityAttributeValueCache0has|entityAttributeValueCache1has|entityAttributeValueCache2has|entityAttributeValueCache3has)$"); Map provisionerPropsWithMemberInfo = GrouperLoaderConfig.retrieveConfig().propertiesMap(provisionerPatternWithMemberInfo); Set configNames = new HashSet(); for (String property : provisionerPropsWithMemberInfo.keySet()) { @@ -305,25 +305,57 @@ private int syncProvisioningData(List memberIds, Map me RuntimeException runtimeException = null; for (String configName : configNames) { - boolean isEnabled = GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".common.enabled", true); // what is the default here?? - if (!isEnabled) { + + boolean entityAttributeValueCache = GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".entityAttributeValueCacheHas", false); + + if (!entityAttributeValueCache) { continue; } - String memberFromId2 = GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".common.subjectLink.memberFromId2"); - String memberFromId3 = GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".common.subjectLink.memberFromId3"); - String memberToId2 = GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".common.subjectLink.memberToId2"); - String memberToId3 = GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".common.subjectLink.memberToId3"); + String entityAttributeValueCache0 = null; + String entityAttributeValueCache1 = null; + String entityAttributeValueCache2 = null; + String entityAttributeValueCache3 = null; - boolean autoMemberFromId2 = GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".common.subjectLink.autoMemberFromId2", true); - boolean autoMemberFromId3 = GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".common.subjectLink.autoMemberFromId3", true); - boolean autoMemberToId2 = GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".common.subjectLink.autoMemberToId2", true); - boolean autoMemberToId3 = GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".common.subjectLink.autoMemberToId3", true); - - if ((!autoMemberFromId2 || GrouperUtil.isBlank(memberFromId2)) && - (!autoMemberFromId3 || GrouperUtil.isBlank(memberFromId3)) && - (!autoMemberToId2 || GrouperUtil.isBlank(memberToId2)) && - (!autoMemberToId3 || GrouperUtil.isBlank(memberToId3))) { + boolean autoEntityAttributeValueCache0 = false; + boolean autoEntityAttributeValueCache1 = false; + boolean autoEntityAttributeValueCache2 = false; + boolean autoEntityAttributeValueCache3 = false; + + if (GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".entityAttributeValueCache0has", false) + && StringUtils.equals("grouper", GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".entityAttributeValueCache0source")) + && StringUtils.equals("subjectTranslationScript", GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".entityAttributeValueCache0type"))) { + + entityAttributeValueCache0 = GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".entityAttributeValueCache0translationScript"); + autoEntityAttributeValueCache0 = GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".entityAttributeValueCache0auto", true); + } + + if (GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".entityAttributeValueCache1has", false) + && StringUtils.equals("grouper", GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".entityAttributeValueCache1source")) + && StringUtils.equals("subjectTranslationScript", GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".entityAttributeValueCache1type"))) { + + entityAttributeValueCache1 = GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".entityAttributeValueCache1translationScript"); + autoEntityAttributeValueCache1 = GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".entityAttributeValueCache1auto", true); + } + if (GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".entityAttributeValueCache2has", false) + && StringUtils.equals("grouper", GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".entityAttributeValueCache2source")) + && StringUtils.equals("subjectTranslationScript", GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".entityAttributeValueCache2type"))) { + + entityAttributeValueCache2 = GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".entityAttributeValueCache2translationScript"); + autoEntityAttributeValueCache2 = GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".entityAttributeValueCache2auto", true); + } + if (GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".entityAttributeValueCache3has", false) + && StringUtils.equals("grouper", GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".entityAttributeValueCache3source")) + && StringUtils.equals("subjectTranslationScript", GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".entityAttributeValueCache3type"))) { + + entityAttributeValueCache3 = GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner." + configName + ".entityAttributeValueCache3translationScript"); + autoEntityAttributeValueCache3 = GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner." + configName + ".entityAttributeValueCache3auto", true); + } + + if ((!autoEntityAttributeValueCache0 || GrouperUtil.isBlank(entityAttributeValueCache0)) && + (!autoEntityAttributeValueCache1 || GrouperUtil.isBlank(entityAttributeValueCache1)) && + (!autoEntityAttributeValueCache2 || GrouperUtil.isBlank(entityAttributeValueCache2)) && + (!autoEntityAttributeValueCache3 || GrouperUtil.isBlank(entityAttributeValueCache3))) { // nothing to do continue; } @@ -366,24 +398,24 @@ private int syncProvisioningData(List memberIds, Map me Map variableMap = new HashMap(); variableMap.put("subject", subject); - if (autoMemberFromId2 && !StringUtils.isBlank(memberFromId2)) { - String memberFromId2Value = GrouperUtil.substituteExpressionLanguage(memberFromId2, variableMap); - gcGrouperSyncMember.setMemberFromId2(memberFromId2Value); + if (autoEntityAttributeValueCache0 && !StringUtils.isBlank(entityAttributeValueCache0)) { + String entityAttributeValueCache0Value = GrouperUtil.substituteExpressionLanguage(entityAttributeValueCache0, variableMap); + gcGrouperSyncMember.setEntityAttributeValueCache0(entityAttributeValueCache0Value); } - if (autoMemberFromId3 && !StringUtils.isBlank(memberFromId3)) { - String memberFromId3Value = GrouperUtil.substituteExpressionLanguage(memberFromId3, variableMap); - gcGrouperSyncMember.setMemberFromId3(memberFromId3Value); + if (autoEntityAttributeValueCache1 && !StringUtils.isBlank(entityAttributeValueCache1)) { + String entityAttributeValueCache1Value = GrouperUtil.substituteExpressionLanguage(entityAttributeValueCache1, variableMap); + gcGrouperSyncMember.setEntityAttributeValueCache1(entityAttributeValueCache1Value); } - if (autoMemberToId2 && !StringUtils.isBlank(memberToId2)) { - String memberToId2Value = GrouperUtil.substituteExpressionLanguage(memberToId2, variableMap); - gcGrouperSyncMember.setMemberToId2(memberToId2Value); + if (autoEntityAttributeValueCache2 && !StringUtils.isBlank(entityAttributeValueCache2)) { + String entityAttributeValueCache2Value = GrouperUtil.substituteExpressionLanguage(entityAttributeValueCache2, variableMap); + gcGrouperSyncMember.setEntityAttributeValueCache2(entityAttributeValueCache2Value); } - if (autoMemberToId3 && !StringUtils.isBlank(memberToId3)) { - String memberToId3Value = GrouperUtil.substituteExpressionLanguage(memberToId3, variableMap); - gcGrouperSyncMember.setMemberToId3(memberToId3Value); + if (autoEntityAttributeValueCache3 && !StringUtils.isBlank(entityAttributeValueCache3)) { + String entityAttributeValueCache3Value = GrouperUtil.substituteExpressionLanguage(entityAttributeValueCache3, variableMap); + gcGrouperSyncMember.setEntityAttributeValueCache3(entityAttributeValueCache3Value); } } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/app/workflow/GrouperWorkflowDaemonJob.java b/grouper/src/grouper/edu/internet2/middleware/grouper/app/workflow/GrouperWorkflowDaemonJob.java index 6228acf58906..7e5ea38a6371 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/app/workflow/GrouperWorkflowDaemonJob.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/app/workflow/GrouperWorkflowDaemonJob.java @@ -31,6 +31,8 @@ import edu.internet2.middleware.grouper.app.loader.GrouperLoaderType; import edu.internet2.middleware.grouper.app.loader.OtherJobBase; import edu.internet2.middleware.grouper.app.loader.db.Hib3GrouperLoaderLog; +import edu.internet2.middleware.grouper.exception.GrouperSessionException; +import edu.internet2.middleware.grouper.misc.GrouperSessionHandler; import edu.internet2.middleware.grouper.util.GrouperUtil; import edu.internet2.middleware.subject.Subject; @@ -77,11 +79,17 @@ public static void runDaemonStandalone() { @Override public OtherJobOutput run(OtherJobInput otherJobInput) { - GrouperSession session = GrouperSession.startRootSession(); - Set groupsWithWorkflowInstance = GrouperWorkflowInstanceService.findGroupsWithWorkflowInstance(); - Set instancesNeedingEmail = instancesNeedingEmail(groupsWithWorkflowInstance); - - updateInstances(instancesNeedingEmail, session); + GrouperSession.internal_callbackRootGrouperSession(new GrouperSessionHandler() { + + @Override + public Object callback(GrouperSession grouperSession) throws GrouperSessionException { + Set groupsWithWorkflowInstance = GrouperWorkflowInstanceService.findGroupsWithWorkflowInstance(); + Set instancesNeedingEmail = instancesNeedingEmail(groupsWithWorkflowInstance); + + updateInstances(instancesNeedingEmail, grouperSession); + return null; + } + }); return null; } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/cfg/dbConfig/ConfigItemMetadata.java b/grouper/src/grouper/edu/internet2/middleware/grouper/cfg/dbConfig/ConfigItemMetadata.java index 3cc080b0a100..84e9eb8d3f3e 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/cfg/dbConfig/ConfigItemMetadata.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/cfg/dbConfig/ConfigItemMetadata.java @@ -329,6 +329,28 @@ public void setRequiredEl(String requiredEl) { this.requiredEl = requiredEl; } + /** + * number of levels to indent in hide/show + */ + private int indent = 0; + + + /** + * number of levels to indent in hide/show + * @return + */ + public int getIndent() { + return indent; + } + + /** + * number of levels to indent in hide/show + * @param indent + */ + public void setIndent(int indent) { + this.indent = indent; + } + /** * replace $i$ with repeat index * @param repeatIndex @@ -354,6 +376,7 @@ public ConfigItemMetadata clone(int repeatIndex) { copy.subSection = GrouperUtil.replace(this.subSection, "$i$", GrouperUtil.stringValue(repeatIndex)); copy.formElement = this.formElement; + copy.indent = this.indent; copy.multiple = this.multiple; copy.optionValues = this.optionValues; copy.order = this.order; @@ -375,6 +398,7 @@ public ConfigItemMetadata clone(int repeatIndex) { */ public void processMetadata() { + this.indent = 0; this.multiple = false; this.mustExtendClass = null; this.mustImplementInterface = null; @@ -422,6 +446,11 @@ public void processMetadata() { jsonNode.remove("order"); } + if (jsonNode.has("indent")) { + this.indent = GrouperUtil.jsonJacksonGetInteger(jsonNode, "indent"); + jsonNode.remove("indent"); + } + if (jsonNode.has("mustExtendClass")) { this.mustExtendClass = GrouperUtil.jsonJacksonGetString(jsonNode, "mustExtendClass"); jsonNode.remove("mustExtendClass"); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/GroupDAO.java b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/GroupDAO.java index deeed590422a..fbe66e2331e9 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/GroupDAO.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/GroupDAO.java @@ -1055,8 +1055,47 @@ public Set getAllGroupsSecure(String scope, GrouperSession grouperSession Collection groupNames, Boolean compositeOwner, String idOfAttributeDefName, Object attributeValue, Set attributeValuesOnAssignment, Boolean attributeCheckReadOnAttributeDef , String idOfAttributeDefName2, Object attributeValue2, Set attributeValuesOnAssignment2, - boolean attributeNotAssigned); - + boolean attributeNotAssigned); + + /** + * + * @param scope + * @param grouperSession + * @param subject + * @param privileges + * @param queryOptions + * @param typeOfGroup or null for all + * @param splitScope + * @param membershipSubject + * @param field + * @param parentStemId + * @param stemScope + * @param findByUuidOrName + * @param subjectNotInGroup is a subject which does not have a membership in the group + * @param groupIds are the group ids to search for + * @param groupNames are the group names to search for + * @param compositeOwner if we are filtering for groups which are or are not composite owners + * @param idOfAttributeDefName if looking for groups that have this attribute def name + * @param attributeValue if looking for groups that have this attribute value on the attribute def name + * @param attributeValuesOnAssignment if looking for an attribute value on an assignment, could be multiple values + * @param attributeCheckReadOnAttributeDef use security around attribute def? default is true + * @param idOfAttributeDefName2 if looking for groups that have this attribute def name2 + * @param attributeValue2 if looking for groups that have this attribute value2 on the attribute def name2 + * @param attributeValuesOnAssignment2 if looking for an attribute value on an assignment2, could be multiple values + * @param attributeNotAssigned + * @param excludeAlternateNames whether to exclude alternate names from name/scope search + * @return + */ + public Set getAllGroupsSecure(String scope, GrouperSession grouperSession, + Subject subject, Set privileges, QueryOptions queryOptions, + Set typeOfGroup, boolean splitScope, + Subject membershipSubject, Field field, String parentStemId, Scope stemScope, + boolean findByUuidOrName, Subject subjectNotInGroup, Collection groupIds, + Collection groupNames, Boolean compositeOwner, String idOfAttributeDefName, Object attributeValue, + Set attributeValuesOnAssignment, Boolean attributeCheckReadOnAttributeDef + , String idOfAttributeDefName2, Object attributeValue2, Set attributeValuesOnAssignment2, + boolean attributeNotAssigned, boolean excludeAlternateNames); + /** * find by uuid secure * @param uuids diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/PITGroupSetDAO.java b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/PITGroupSetDAO.java index 3b678d78ee94..44a55b4c1802 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/PITGroupSetDAO.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/PITGroupSetDAO.java @@ -130,6 +130,14 @@ public interface PITGroupSetDAO extends GrouperDAO { */ public PITGroupSet findActiveImmediateByPITOwnerAndPITMemberAndPITField(String ownerId, String memberId, String fieldId); + /** + * @param ownerId + * @param memberId + * @param fieldId + * @return pit group sets + */ + public Set findAllImmediateByPITOwnerAndPITMemberAndPITField(String ownerId, String memberId, String fieldId); + /** * @param groupId * @param field diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/PITMembershipDAO.java b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/PITMembershipDAO.java index 0e01337cfa5e..9c27935c487a 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/PITMembershipDAO.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/PITMembershipDAO.java @@ -117,6 +117,15 @@ public interface PITMembershipDAO extends GrouperDAO { */ public Set findAllByPITMember(String memberId); + /** + * Get memberships by owner, member, field + * @param ownerId + * @param memberId + * @param fieldId + * @return set of pit memberships + */ + public Set findAllByPITOwnerAndPITMemberAndPITField(String ownerId, String memberId, String fieldId); + /** * @return active memberships that are missing in point in time */ diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/PITMembershipViewDAO.java b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/PITMembershipViewDAO.java index f75f3980587b..bd343bb08dd8 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/PITMembershipViewDAO.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/PITMembershipViewDAO.java @@ -120,4 +120,24 @@ public Set findAllByGroupOwnerOptions(Collection totalGroupIds Set sources, Stem stem, Scope stemScope, Boolean checkSecurity, FieldType fieldType, QueryOptions queryOptionsForMember, String filterForMember, boolean splitScopeForMember, boolean hasFieldForMember, Timestamp pointInTimeFrom, Timestamp pointInTimeTo); + + /** + * @param memberId + * @param fieldId + * @param endTimeFrom + * @param endTimeTo + * @return set of PITMembershipView + */ + public Set findAllByPITMemberAndPITFieldAndEndTimeRange(String memberId, String fieldId, + Timestamp endTimeFrom, Timestamp endTimeTo); + + /** + * @param memberId + * @param fieldId + * @param startTimeFrom + * @param startTimeTo + * @returnset of PITMembershipView + */ + public Set findAllByPITMemberAndPITFieldAndStartTimeRange(String memberId, String fieldId, + Timestamp startTimeFrom, Timestamp startTimeTo); } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/StemDAO.java b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/StemDAO.java index 27b9bff584a2..13a754fa2faf 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/StemDAO.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/StemDAO.java @@ -642,7 +642,44 @@ Set getAllStemsSecure(String scope, GrouperSession grouperSession, Set attributeValuesOnAssignment, String idOfAttributeDefName2, Object attributeValue2, Set attributeValuesOnAssignment2, boolean attributeNotAssigned) throws GrouperDAOException; - + + /** + * + * @param scope is blank for no scope + * @param grouperSession + * @param subject + * @param queryOptions + * @param inPrivSet means that each row must have a matching priv in this set to user or GrouperAll. + * There are some constants in NamingPrivilege of pre-canned sets + * @param splitScope true to split scopes by whitespace + * @param parentStemId true if filtering by parent of ancestor + * @param stemScope ONE or SUB + * @param findByUuidOrName if we are looking up a stem, only look by uuid or name + * @param userHasInGroupFields find stems where the user has these fields in a group + * @param userHasInAttributeFields find stems where the user has these fields in an attribute + * @param stemIds + * @param idOfAttributeDefName if looking for groups that have this attribute def name + * @param attributeValue if looking for groups that have this attribute value on the attribute def name + * @param attributeCheckReadOnAttributeDef if check read on attribute for attribute on stem + * @param attributeValuesOnAssignment if looking for an attribute value on an assignment, could be multiple values + * @param idOfAttributeDefName2 if looking for groups that have this attribute def name2 + * @param attributeValue2 if looking for groups that have this attribute value2 on the attribute def name2 + * @param attributeValuesOnAssignment2 if looking for an attribute value on an assignment2, could be multiple values + * @param attributeNotAssigned find stems that don't have the given type assigned + * @param excludeAlternateNames whether to exclude alternate names from name or scope search + * @return the stems + * @throws GrouperDAOException + * @since v2.4.0 + */ + Set getAllStemsSecure(String scope, GrouperSession grouperSession, + Subject subject, Set inPrivSet, QueryOptions queryOptions, + boolean splitScope, String parentStemId, Scope stemScope, boolean findByUuidOrName, + Collection userHasInGroupFields, Collection userHasInAttributeFields, + Collection stemIds, String idOfAttributeDefName, Object attributeValue, + Boolean attributeCheckReadOnAttributeDef, + Set attributeValuesOnAssignment, String idOfAttributeDefName2, Object attributeValue2, + Set attributeValuesOnAssignment2, boolean attributeNotAssigned, boolean excludeAlternateNames) + throws GrouperDAOException; diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3GroupDAO.java b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3GroupDAO.java index 851b0e7b63f3..2c25e1e70a35 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3GroupDAO.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3GroupDAO.java @@ -2978,7 +2978,7 @@ public Set getAllGroupsSplitScopeSecure(String scope, Set typeOfGroups = typeOfGroup == null ? null : GrouperUtil.toSet(typeOfGroup); return findAllGroupsSecureHelper(scope, grouperSession, subject, privileges, queryOptions, true, typeOfGroups, null, null, null, null, false, null, null, null, null, null, null, - null, null, null, null, null, false); + null, null, null, null, null, false, false); } /** @@ -2990,7 +2990,7 @@ public Set getAllGroupsSplitScopeSecure(String scope, QueryOptions queryOptions, Set typeOfGroups) { return findAllGroupsSecureHelper(scope, grouperSession, subject, privileges, queryOptions, true, typeOfGroups, null, null, null, null, false, null, null, null, null, null, null, null, - null, null, null, null, false); + null, null, null, null, false, false); } /** @@ -3018,6 +3018,7 @@ public Set getAllGroupsSplitScopeSecure(String scope, * @param attributeValue2 * @param attributeValuesOnAssignment2 * @param attributeNotAssigned + * @param excludeAlternateNames * @return groups * */ @@ -3028,7 +3029,7 @@ private Set findAllGroupsSecureHelper(String scope, Collection totalGroupIds, Collection totalGroupNames, Boolean compositeOwner, final String idOfAttributeDefName, Object attributeValue, Set attributeValuesOnAssignment, Boolean attributeCheckReadOnAttributeDef, final String idOfAttributeDefName2, Object attributeValue2, - Set attributeValuesOnAssignment2, boolean attributeNotAssigned) { + Set attributeValuesOnAssignment2, boolean attributeNotAssigned, boolean excludeAlternateNames) { if ((attributeValue != null || GrouperUtil.length(attributeValuesOnAssignment) > 0) && StringUtils.isBlank(idOfAttributeDefName)) { throw new RuntimeException("If you are searching by attributeValue then you must specify an attribute definition name"); @@ -3313,10 +3314,14 @@ private Set findAllGroupsSecureHelper(String scope, whereClause.append(" ( theGroup.nameDb in ( "); whereClause.append(HibUtils.convertToInClause(groupNames, byHqlStatic)); - whereClause.append(") or theGroup.alternateNameDb in ( "); - whereClause.append(HibUtils.convertToInClause(groupNames, byHqlStatic)); + + if (!excludeAlternateNames){ + whereClause.append(") or theGroup.alternateNameDb in ( "); + whereClause.append(HibUtils.convertToInClause(groupNames, byHqlStatic)); + } + whereClause.append(" ) "); - + //if entities, then also allow entity identifier if (typeOfGroups != null && typeOfGroups.contains(TypeOfGroup.entity)) { @@ -3397,7 +3402,7 @@ private Set findAllGroupsSecureHelper(String scope, //see if there is a scope if (!StringUtils.isBlank(scope)) { - scope = assignFilterToQuery(scope, splitScope, whereClause, byHqlStatic, findByUuidOrName, "theGroup", false); + scope = assignFilterToQuery(scope, splitScope, whereClause, byHqlStatic, findByUuidOrName, "theGroup", false, excludeAlternateNames); //if entities, then also allow entity identifier if (typeOfGroups != null && typeOfGroups.contains(TypeOfGroup.entity)) { @@ -3509,9 +3514,11 @@ private Set findAllGroupsSecureHelper(String scope, } //get the one with alternate name - for (Group group : overallResults) { - if (StringUtils.equals(scope, group.getAlternateName())) { - return GrouperUtil.toSet(group); + if (!excludeAlternateNames) { + for (Group group : overallResults) { + if (StringUtils.equals(scope, group.getAlternateName())) { + return GrouperUtil.toSet(group); + } } } @@ -3523,17 +3530,22 @@ private Set findAllGroupsSecureHelper(String scope, } - /** - * @param byHqlStatic - * @param filter - * @param splitScope default true - * @param whereClause - * @param findByUuidOrName generally this is false - * @param alias e.g. theGroup whatever alias in hql query - * @param addFinalParen - * @return scope lowercased - */ public static String assignFilterToQuery(String filter, Boolean splitScope, StringBuilder whereClause, ByHqlStatic byHqlStatic, boolean findByUuidOrName, String alias, boolean addFinalParen) { + return assignFilterToQuery(filter, splitScope, whereClause, byHqlStatic, findByUuidOrName, alias, addFinalParen, false); + } + + /** + * @param byHqlStatic + * @param filter + * @param splitScope default true + * @param whereClause + * @param findByUuidOrName generally this is false + * @param alias e.g. theGroup whatever alias in hql query + * @param addFinalParen + * @return scope lowercased + */ + public static String assignFilterToQuery(String filter, Boolean splitScope, StringBuilder whereClause, + ByHqlStatic byHqlStatic, boolean findByUuidOrName, String alias, boolean addFinalParen, boolean excludeAlternateNames) { // default scplitScope to true splitScope = GrouperUtil.booleanValue(splitScope, true); @@ -3562,13 +3574,18 @@ public static String assignFilterToQuery(String filter, Boolean splitScope, Stri } if (findByUuidOrName) { - whereClause.append(" " + alias + ".nameDb = :scope" + index + " or " + alias + ".alternateNameDb = :scope" + index - + " or " + alias + ".displayNameDb = :scope" + index + " "); + whereClause.append(" " + alias + ".nameDb = :scope" + index); + if (!excludeAlternateNames) { + whereClause.append(" or " + alias + ".alternateNameDb = :scope" + index); + } + whereClause.append(" or " + alias + ".displayNameDb = :scope" + index + " "); byHqlStatic.setString("scope" + index, theScope); } else { - whereClause.append(" ( lower(" + alias + ".nameDb) like :scope" + index - + " or lower(" + alias + ".alternateNameDb) like :scope" + index - + " or lower(" + alias + ".displayNameDb) like :scope" + index + whereClause.append(" ( lower(" + alias + ".nameDb) like :scope" + index); + if (!excludeAlternateNames) { + whereClause.append(" or lower(" + alias + ".alternateNameDb) like :scope" + index); + } + whereClause.append(" or lower(" + alias + ".displayNameDb) like :scope" + index + " or lower(" + alias + ".descriptionDb) like :scope" + index + " ) "); if (splitScope) { theScope = "%" + theScope + "%"; @@ -3950,7 +3967,7 @@ public Set getAllGroupsSecure(String scope, GrouperSession grouperSession Set typeOfGroups, boolean splitScope, Subject membershipSubject, Field field) { return findAllGroupsSecureHelper(scope, grouperSession, subject, privileges, queryOptions, splitScope, typeOfGroups, membershipSubject, field, null, null, false, null, null, null, null, null, null, - null, null, null, null, null, false); + null, null, null, null, null, false, false); } /** @@ -3966,7 +3983,7 @@ public Set getAllGroupsSecure(String scope, GrouperSession grouperSession return findAllGroupsSecureHelper(scope, grouperSession, subject, privileges, queryOptions, splitScope, typeOfGroups, membershipSubject, field, parentStemId, stemScope, findByUuidOrName, subjectNotInGroup, groupIds, groupNames, compositeOwner, null, null, null, null, - null, null, null, false); + null, null, null, false, false); } /** @@ -3982,7 +3999,7 @@ public Set getAllGroupsSecure(String scope, GrouperSession grouperSession return findAllGroupsSecureHelper(scope, grouperSession, subject, privileges, queryOptions, splitScope, typeOfGroups, membershipSubject, field, parentStemId, stemScope, findByUuidOrName, subjectNotInGroup, groupIds, groupNames, compositeOwner, idOfAttributeDefName, - attributeValue, null, null, null, null, null, false); + attributeValue, null, null, null, null, null, false, false); } /** @@ -3999,7 +4016,7 @@ public Set getAllGroupsSecure(String scope, GrouperSession grouperSession return findAllGroupsSecureHelper(scope, grouperSession, subject, privileges, queryOptions, splitScope, typeOfGroup, membershipSubject, field, parentStemId, stemScope, findByUuidOrName, subjectNotInGroup, groupIds, groupNames, compositeOwner, idOfAttributeDefName, - attributeValue, attributeValuesOnAssignment, attributeCheckReadOnAttributeDef, null, null, null, false); + attributeValue, attributeValuesOnAssignment, attributeCheckReadOnAttributeDef, null, null, null, false, false); } /** @@ -4099,6 +4116,22 @@ public Set findGroupsInStemWithPrivilege(GrouperSession grouperSession, } + public Set getAllGroupsSecure(String scope, GrouperSession grouperSession, + Subject subject, Set privileges, QueryOptions queryOptions, + Set typeOfGroup, boolean splitScope, + Subject membershipSubject, Field field, String parentStemId, Scope stemScope, + boolean findByUuidOrName, Subject subjectNotInGroup, Collection groupIds, + Collection groupNames, Boolean compositeOwner, String idOfAttributeDefName, Object attributeValue, + Set attributeValuesOnAssignment, Boolean attributeCheckReadOnAttributeDef + , String idOfAttributeDefName2, Object attributeValue2, Set attributeValuesOnAssignment2, + boolean attributeNotAssigned) { + return findAllGroupsSecureHelper(scope, grouperSession, subject, privileges, queryOptions, + splitScope, typeOfGroup, membershipSubject, field, parentStemId, stemScope, + findByUuidOrName, subjectNotInGroup, groupIds, groupNames, compositeOwner, idOfAttributeDefName, + attributeValue, attributeValuesOnAssignment, attributeCheckReadOnAttributeDef, + idOfAttributeDefName2,attributeValue2, attributeValuesOnAssignment2, attributeNotAssigned, + false); + } /** * @see GroupDAO#getAllGroupsSecure(String, GrouperSession, Subject, Set, QueryOptions, Set, boolean, Subject, Field, String, Scope, boolean, Subject, Collection, Collection, Boolean, String, Object, Set, Boolean, String, Object) */ @@ -4111,12 +4144,13 @@ public Set getAllGroupsSecure(String scope, GrouperSession grouperSession Collection groupNames, Boolean compositeOwner, String idOfAttributeDefName, Object attributeValue, Set attributeValuesOnAssignment, Boolean attributeCheckReadOnAttributeDef, String idOfAttributeDefName2, - Object attributeValue2, Set attributeValuesOnAssignment2, boolean attributeNotAssigned) { + Object attributeValue2, Set attributeValuesOnAssignment2, boolean attributeNotAssigned, boolean excludeAlternateNames) { return findAllGroupsSecureHelper(scope, grouperSession, subject, privileges, queryOptions, splitScope, typeOfGroup, membershipSubject, field, parentStemId, stemScope, findByUuidOrName, subjectNotInGroup, groupIds, groupNames, compositeOwner, idOfAttributeDefName, attributeValue, attributeValuesOnAssignment, attributeCheckReadOnAttributeDef, - idOfAttributeDefName2,attributeValue2, attributeValuesOnAssignment2, attributeNotAssigned); + idOfAttributeDefName2,attributeValue2, attributeValuesOnAssignment2, attributeNotAssigned, + excludeAlternateNames); } /** diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3GrouperSyncGroupDAO.hbm.xml b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3GrouperSyncGroupDAO.hbm.xml index a0b7be0de987..1f347384ed40 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3GrouperSyncGroupDAO.hbm.xml +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3GrouperSyncGroupDAO.hbm.xml @@ -62,13 +62,13 @@ - - + + - - + + - - + + - - + + diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3MembershipDAO.java b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3MembershipDAO.java index 72ef107bf9dc..8438fb1693aa 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3MembershipDAO.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3MembershipDAO.java @@ -479,7 +479,7 @@ public Set findAllByStemOwnerAndMemberAndField(String ownerStemId, S public Set findAllByGroupOwnerAndMemberAndField(String ownerGroupId, String memberUUID, Field f, boolean enabledOnly) throws GrouperDAOException { - StringBuilder sql = new StringBuilder("select distinct ms, m from MembershipEntry as ms, Member as m, Field as field where " + StringBuilder sql = new StringBuilder("select distinct ms, m from MembershipEntry as ms, Member as m where " + " ms.ownerGroupId = :owner " + "and ms.memberUuid = :member " + "and ms.fieldId = :fuuid " @@ -1762,7 +1762,7 @@ public Membership findByStemOwnerAndMemberAndFieldAndType(String ownerStemId, MembershipType membershipType = MembershipType.valueOfIgnoreCase(type, true); StringBuilder sql = new StringBuilder( - "select distinct ms, m from MembershipEntry as ms, Member as m, Field as field where " + "select distinct ms, m from MembershipEntry as ms, Member as m where " + " ms.ownerStemId = :owner " + "and ms.memberUuid = :member " + "and ms.fieldId = :fuuid " @@ -1882,7 +1882,7 @@ public Set findAllEffectiveByStemOwner(String ownerStemId, String me } StringBuilder sql = new StringBuilder( - "select ms, m from MembershipEntry as ms, Member as m, Field as field where " + "select ms, m from MembershipEntry as ms, Member as m where " + " ms.ownerStemId = :owner " + "and ms.memberUuid = :member " + "and ms.fieldId = :fuuid " @@ -1951,7 +1951,7 @@ public Set findAllEffectiveByGroupOwnerAndMemberAndField(String owne throws GrouperDAOException { StringBuilder sql = new StringBuilder( - "select ms, m from MembershipEntry as ms, Member as m, Field as field where " + "select ms, m from MembershipEntry as ms, Member as m where " + " ms.ownerGroupId = :owner " + "and ms.memberUuid = :member " + "and ms.fieldId = :fuuid " @@ -2475,7 +2475,7 @@ public Membership findByAttrDefOwnerAndMemberAndFieldAndType(String ownerAttrDef MembershipType membershipType = MembershipType.valueOfIgnoreCase(type, true); StringBuilder sql = new StringBuilder( - "select distinct ms, m from MembershipEntry as ms, Member as m, Field as field where " + "select distinct ms, m from MembershipEntry as ms, Member as m where " + " ms.ownerAttrDefId = :owner " + "and ms.memberUuid = :member " + "and ms.fieldId = :fuuid " @@ -2516,7 +2516,7 @@ public Set findAllEffectiveByAttrDefOwner(String ownerAttrDefId, } StringBuilder sql = new StringBuilder( - "select ms, m from MembershipEntry as ms, Member as m, Field as field where " + "select ms, m from MembershipEntry as ms, Member as m where " + " ms.ownerAttrDefId = :owner " + "and ms.memberUuid = :member " + "and ms.fieldId = :fuuid " diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3PITGroupSetDAO.java b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3PITGroupSetDAO.java index d07f55c1a510..62453f875ff6 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3PITGroupSetDAO.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3PITGroupSetDAO.java @@ -319,6 +319,26 @@ public PITGroupSet findActiveImmediateByPITOwnerAndPITMemberAndPITField(String o return pitGroupSet; } + /** + * @see edu.internet2.middleware.grouper.internal.dao.PITGroupSetDAO#findAllImmediateByPITOwnerAndPITMemberAndPITField(java.lang.String, java.lang.String, java.lang.String) + */ + public Set findAllImmediateByPITOwnerAndPITMemberAndPITField(String ownerId, String memberId, String fieldId) { + Set pitGroupSets = HibernateSession + .byHqlStatic() + .createQuery("select pitGroupSet from PITGroupSet as pitGroupSet " + + "where ownerId = :ownerId " + + "and memberId = :memberId " + + "and fieldId = :fieldId " + + "and depth = '1'") + .setCacheable(false).setCacheRegion(KLASS + ".FindAllImmediateByPITOwnerAndPITMemberAndPITField") + .setString("ownerId", ownerId) + .setString("memberId", memberId) + .setString("fieldId", fieldId) + .listSet(PITGroupSet.class); + + return pitGroupSets; + } + /** * @see edu.internet2.middleware.grouper.internal.dao.PITGroupSetDAO#findAllActiveByPITGroupOwnerAndPITField(java.lang.String, edu.internet2.middleware.grouper.pit.PITField) */ diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3PITMembershipDAO.java b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3PITMembershipDAO.java index 0867eebbe6ef..538b245b3d57 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3PITMembershipDAO.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3PITMembershipDAO.java @@ -285,6 +285,27 @@ public Set findAllByPITMember(String memberId) { .setString("memberId", memberId) .listSet(PITMembership.class); } + + /** + * + */ + public Set findAllByPITOwnerAndPITMemberAndPITField(String ownerId, String memberId, String fieldId) { + + StringBuilder sql = new StringBuilder("select ms " + + "from PITMembership ms where " + + "ms.ownerId = :ownerId " + + "and ms.memberId = :memberId " + + "and ms.fieldId = :fieldId"); + + return HibernateSession.byHqlStatic() + .createQuery(sql.toString()) + .setCacheable(false) + .setCacheRegion(KLASS + ".FindAllByPITOwnerAndPITMemberAndPITField") + .setString("ownerId", ownerId) + .setString("memberId", memberId) + .setString("fieldId", fieldId) + .listSet(PITMembership.class); + } /** * @see edu.internet2.middleware.grouper.internal.dao.PITMembershipDAO#findMissingActivePITMemberships() diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3PITMembershipViewDAO.java b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3PITMembershipViewDAO.java index 083c16d709a6..ae8d2a521b17 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3PITMembershipViewDAO.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3PITMembershipViewDAO.java @@ -273,6 +273,64 @@ public Set findAllByPITOwnerAndPITMemberAndPITField(String ow .setString("fieldId", fieldId) .listSet(PITMembershipView.class); } + + public Set findAllByPITMemberAndPITFieldAndStartTimeRange(String memberId, String fieldId, + Timestamp startTimeFrom, Timestamp startTimeTo) { + + Long startTimeFromLong = startTimeFrom.getTime() * 1000; + Long startTimeToLong = startTimeTo.getTime() * 1000; + + StringBuilder sql = new StringBuilder("select pitms " + + "from PITMembershipView pitms where " + + "pitms.memberId = :memberId " + + "and pitms.fieldId = :fieldId"); + + sql.append(" and ((pitms.membershipStartTimeDb > '" + startTimeFromLong + "' and pitms.membershipStartTimeDb < '" + startTimeToLong + "' and pitms.groupSetStartTimeDb < '" + startTimeToLong + "')"); + sql.append(" or (pitms.groupSetStartTimeDb > '" + startTimeFromLong + "' and pitms.groupSetStartTimeDb < '" + startTimeToLong + "' and pitms.membershipStartTimeDb < '" + startTimeToLong + "'))"); + + // make sure membership object didn't end before group set object started + sql.append(" and (pitms.membershipEndTimeDb is null or pitms.membershipEndTimeDb > pitms.groupSetStartTimeDb) "); + + // make sure group set object didn't end before membership object started + sql.append(" and (pitms.groupSetEndTimeDb is null or pitms.groupSetEndTimeDb > pitms.membershipStartTimeDb) "); + + return HibernateSession.byHqlStatic() + .createQuery(sql.toString()) + .setCacheable(false) + .setCacheRegion(KLASS + ".FindAllByPITMemberAndPITFieldAndStartTimeRange") + .setString("memberId", memberId) + .setString("fieldId", fieldId) + .listSet(PITMembershipView.class); + } + + public Set findAllByPITMemberAndPITFieldAndEndTimeRange(String memberId, String fieldId, + Timestamp endTimeFrom, Timestamp endTimeTo) { + + Long endTimeFromLong = endTimeFrom.getTime() * 1000; + Long endTimeToLong = endTimeTo.getTime() * 1000; + + StringBuilder sql = new StringBuilder("select pitms " + + "from PITMembershipView pitms where " + + "pitms.memberId = :memberId " + + "and pitms.fieldId = :fieldId"); + + sql.append(" and ((pitms.membershipEndTimeDb > '" + endTimeFromLong + "' and pitms.membershipEndTimeDb < '" + endTimeToLong + "' and (pitms.groupSetEndTimeDb is null or pitms.groupSetEndTimeDb > '" + endTimeFromLong + "'))"); + sql.append(" or (pitms.groupSetEndTimeDb > '" + endTimeFromLong + "' and pitms.groupSetEndTimeDb < '" + endTimeToLong + "' and (pitms.membershipEndTimeDb is null or pitms.membershipEndTimeDb > '" + endTimeFromLong + "')))"); + + // make sure membership object didn't end before group set object started + sql.append(" and (pitms.membershipEndTimeDb is null or pitms.membershipEndTimeDb > pitms.groupSetStartTimeDb) "); + + // make sure group set object didn't end before membership object started + sql.append(" and (pitms.groupSetEndTimeDb is null or pitms.groupSetEndTimeDb > pitms.membershipStartTimeDb) "); + + return HibernateSession.byHqlStatic() + .createQuery(sql.toString()) + .setCacheable(false) + .setCacheRegion(KLASS + ".FindAllByPITMemberAndPITFieldAndEndTimeRange") + .setString("memberId", memberId) + .setString("fieldId", fieldId) + .listSet(PITMembershipView.class); + } /** * @see edu.internet2.middleware.grouper.internal.dao.PITMembershipViewDAO#findAllByGroupOwnerOptions(java.util.Collection, java.util.Collection, java.util.Collection, java.util.Set, java.lang.Boolean, edu.internet2.middleware.grouper.FieldType, edu.internet2.middleware.grouper.internal.dao.QueryOptions, java.lang.String, boolean, boolean, java.sql.Timestamp, java.sql.Timestamp) diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3StemDAO.java b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3StemDAO.java index 44160d2d04f2..2238c23a4c7e 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3StemDAO.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/internal/dao/hib3/Hib3StemDAO.java @@ -1415,33 +1415,47 @@ public Set getAllStemsSecure(String scope, GrouperSession grouperSession, Subject subject, Set inPrivSet, QueryOptions queryOptions) throws GrouperDAOException { return getAllStemsSecureHelper(scope, grouperSession, subject, inPrivSet, - queryOptions, false, null, null, false, null, null, null, null, null, null, null, null, null, null, false); + queryOptions, false, null, null, false, null, null, null, null, null, null, null, null, null, null, false, false); } - /** - * @param scope - * @param grouperSession - * @param subject - * @param inPrivSet - * @param queryOptions - * @param splitScope - * @param parentStemId - * @param stemScope - * @param findByUuidOrName if we are looking by uuid or name - * @param userHasInGroupFields find stems where the user has these fields in a group - * @param userHasInAttributeFields find stems where the user has these fields in an attribute - * @param totalStemIds - * @param idOfAttributeDefName - * @param attributeValue - * @param attributeCheckReadOnAttributeDef - * @param attributeValuesOnAssignment - * @param idOfAttributeDefName2 - * @param attributeValue2 - * @param attributeValuesOnAssignment2 - * @param attributeNotAssigned - * @return the matching stems - * @throws GrouperDAOException - */ + private Set getAllStemsSecureHelper(String scope, + GrouperSession grouperSession, Subject subject, Set inPrivSet, + QueryOptions queryOptions, boolean splitScope, + String parentStemId, Scope stemScope, boolean findByUuidOrName, + Collection userHasInGroupFields, Collection userHasInAttributeFields, + Collection totalStemIds, String idOfAttributeDefName, Object attributeValue, + Boolean attributeCheckReadOnAttributeDef, Set attributeValuesOnAssignment, String idOfAttributeDefName2, Object attributeValue2, + Set attributeValuesOnAssignment2, boolean attributeNotAssigned) throws GrouperDAOException { + return getAllStemsSecureHelper(scope, grouperSession, subject, inPrivSet, + queryOptions, splitScope, parentStemId, stemScope, findByUuidOrName, userHasInGroupFields, userHasInAttributeFields, + totalStemIds, idOfAttributeDefName, attributeValue, attributeCheckReadOnAttributeDef, attributeValuesOnAssignment, idOfAttributeDefName2, attributeValue2, attributeValuesOnAssignment2, attributeNotAssigned, false); + } + + /** + * @param scope + * @param grouperSession + * @param subject + * @param inPrivSet + * @param queryOptions + * @param splitScope + * @param parentStemId + * @param stemScope + * @param findByUuidOrName if we are looking by uuid or name + * @param userHasInGroupFields find stems where the user has these fields in a group + * @param userHasInAttributeFields find stems where the user has these fields in an attribute + * @param totalStemIds + * @param idOfAttributeDefName + * @param attributeValue + * @param attributeCheckReadOnAttributeDef + * @param attributeValuesOnAssignment + * @param idOfAttributeDefName2 + * @param attributeValue2 + * @param attributeValuesOnAssignment2 + * @param attributeNotAssigned + * @param excludeAlternateNames + * @return the matching stems + * @throws GrouperDAOException + */ private Set getAllStemsSecureHelper(String scope, GrouperSession grouperSession, Subject subject, Set inPrivSet, QueryOptions queryOptions, boolean splitScope, @@ -1449,7 +1463,7 @@ private Set getAllStemsSecureHelper(String scope, Collection userHasInGroupFields, Collection userHasInAttributeFields, Collection totalStemIds, String idOfAttributeDefName, Object attributeValue, Boolean attributeCheckReadOnAttributeDef, Set attributeValuesOnAssignment, String idOfAttributeDefName2, Object attributeValue2, - Set attributeValuesOnAssignment2, boolean attributeNotAssigned) + Set attributeValuesOnAssignment2, boolean attributeNotAssigned, boolean excludeAlternateNames) throws GrouperDAOException { long startMillis = System.currentTimeMillis(); @@ -1559,9 +1573,8 @@ private Set getAllStemsSecureHelper(String scope, whereClause.append(" where "); } - scope = assignFilterToQuery(scope, splitScope, whereClause, byHqlStatic, findByUuidOrName, "ns"); - - + scope = assignFilterToQuery(scope, splitScope, whereClause, byHqlStatic, findByUuidOrName, excludeAlternateNames, "ns"); + sql.append(whereClause); changedQuery = true; } @@ -1878,9 +1891,11 @@ private Set getAllStemsSecureHelper(String scope, } //get the one with alternate name - for (Stem stem : overallResults) { - if (StringUtils.equals(scope, stem.getAlternateName())) { - return GrouperUtil.toSet(stem); + if (!excludeAlternateNames) { + for (Stem stem : overallResults) { + if (StringUtils.equals(scope, stem.getAlternateName())) { + return GrouperUtil.toSet(stem); + } } } @@ -1913,6 +1928,20 @@ private Set getAllStemsSecureHelper(String scope, * @return scope lowercased */ public static String assignFilterToQuery(String scope, Boolean splitScope, StringBuilder whereClause, ByHqlStatic byHqlStatic, boolean findByUuidOrName, String alias) { + return assignFilterToQuery(scope, splitScope, whereClause, byHqlStatic, findByUuidOrName, false, alias); + } + + /** + * @param byHqlStatic + * @param scope + * @param splitScope default true + * @param whereClause + * @param findByUuidOrName generally this is false + * @param excludeAlternateNames whether to exclude alternate names when using scope or splitScope + * @param alias e.g. theGroup whatever alias in hql query + * @return scope lowercased + */ + public static String assignFilterToQuery(String scope, Boolean splitScope, StringBuilder whereClause, ByHqlStatic byHqlStatic, boolean findByUuidOrName, boolean excludeAlternateNames, String alias) { // default scplitScope to true splitScope = GrouperUtil.booleanValue(splitScope, true); @@ -1938,13 +1967,18 @@ public static String assignFilterToQuery(String scope, Boolean splitScope, Strin } if (findByUuidOrName) { - whereClause.append(" " + alias + ".nameDb = :scope" + index + " or " + alias + ".alternateNameDb = :scope" + index - + " or " + alias + ".displayNameDb = :scope" + index + " "); + whereClause.append(" " + alias + ".nameDb = :scope" + index); + if (!excludeAlternateNames) { + whereClause.append(" or " + alias + ".alternateNameDb = :scope" + index); + } + whereClause.append(" or " + alias + ".displayNameDb = :scope" + index + " "); byHqlStatic.setString("scope" + index, theScope); } else { - whereClause.append(" ( lower(" + alias + ".nameDb) like :scope" + index - + " or lower(" + alias + ".alternateNameDb) like :scope" + index - + " or lower(" + alias + ".displayNameDb) like :scope" + index + whereClause.append(" ( lower(" + alias + ".nameDb) like :scope" + index); + if (!excludeAlternateNames) { + whereClause.append(" or lower(" + alias + ".alternateNameDb) like :scope" + index); + } + whereClause.append(" or lower(" + alias + ".displayNameDb) like :scope" + index + " or lower(" + alias + ".descriptionDb) like :scope" + index + " ) "); if (splitScope) { theScope = "%" + theScope + "%"; @@ -2516,7 +2550,7 @@ public Set getAllStemsSplitScopeSecure(String scope, GrouperSession grouperSession, Subject subject, Set privileges, QueryOptions queryOptions) { return this.getAllStemsSecureHelper(scope, grouperSession, subject, privileges, - queryOptions, true, null, null, false, null, null, null, null, null, null, null, null, null, null, false); + queryOptions, true, null, null, false, null, null, null, null, null, null, null, null, null, null, false, false); } /** @@ -2600,7 +2634,7 @@ public Set getAllStemsSecure(String scope, GrouperSession grouperSession, throws GrouperDAOException { return getAllStemsSecureHelper(scope, grouperSession, subject, inPrivSet, queryOptions, splitScope, parentStemId, stemScope, findByUuidOrName, userHasInGroupFields, userHasInAttributeFields, - totalStemIds, null, null, null, null, null, null, null, false); + totalStemIds, null, null, null, null, null, null, null, false, false); } /** @@ -2615,7 +2649,7 @@ public Set getAllStemsSecure(String scope, GrouperSession grouperSession, throws GrouperDAOException { return getAllStemsSecureHelper(scope, grouperSession, subject, inPrivSet, queryOptions, splitScope, parentStemId, stemScope, findByUuidOrName, userHasInGroupFields, userHasInAttributeFields, - totalStemIds, idOfAttributeDefName, attributeValue, attributeCheckReadOnAttributeDef, null, null, null, null, false); + totalStemIds, idOfAttributeDefName, attributeValue, attributeCheckReadOnAttributeDef, null, null, null, null, false, false); } @Override @@ -2627,7 +2661,7 @@ public Set getAllStemsSecure(String scope, GrouperSession grouperSession, Boolean attributeCheckReadOnAttributeDef, Set attributeValuesOnAssignment) throws GrouperDAOException { return getAllStemsSecureHelper(scope, grouperSession, subject, inPrivSet, queryOptions, splitScope, parentStemId, stemScope, findByUuidOrName, userHasInGroupFields, userHasInAttributeFields, - stemIds, idOfAttributeDefName, attributeValue, attributeCheckReadOnAttributeDef, attributeValuesOnAssignment, null, null, null, false); + stemIds, idOfAttributeDefName, attributeValue, attributeCheckReadOnAttributeDef, attributeValuesOnAssignment, null, null, null, false, false); } @@ -2646,7 +2680,23 @@ public Set getAllStemsSecure(String scope, GrouperSession grouperSession, splitScope, parentStemId, stemScope, findByUuidOrName, userHasInGroupFields, userHasInAttributeFields, stemIds, idOfAttributeDefName, attributeValue, attributeCheckReadOnAttributeDef, attributeValuesOnAssignment, idOfAttributeDefName2, attributeValue2, - attributeValuesOnAssignment2, attributeNotAssigned); + attributeValuesOnAssignment2, attributeNotAssigned, false); + } + + public Set getAllStemsSecure(String scope, GrouperSession grouperSession, + Subject subject, Set inPrivSet, QueryOptions queryOptions, + boolean splitScope, String parentStemId, Scope stemScope, boolean findByUuidOrName, + Collection userHasInGroupFields, Collection userHasInAttributeFields, + Collection stemIds, String idOfAttributeDefName, Object attributeValue, + Boolean attributeCheckReadOnAttributeDef, Set attributeValuesOnAssignment, + String idOfAttributeDefName2, Object attributeValue2, + Set attributeValuesOnAssignment2, boolean attributeNotAssigned, + boolean excludeAlternateName) throws GrouperDAOException { + return getAllStemsSecureHelper(scope, grouperSession, subject, inPrivSet, queryOptions, + splitScope, parentStemId, stemScope, findByUuidOrName, userHasInGroupFields, userHasInAttributeFields, + stemIds, idOfAttributeDefName, attributeValue, attributeCheckReadOnAttributeDef, attributeValuesOnAssignment, + idOfAttributeDefName2, attributeValue2, + attributeValuesOnAssignment2, attributeNotAssigned, excludeAlternateName); } /** diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/j2ee/Authentication.java b/grouper/src/grouper/edu/internet2/middleware/grouper/j2ee/Authentication.java index aa851d6299b4..3036a0b5657a 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/j2ee/Authentication.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/j2ee/Authentication.java @@ -134,6 +134,37 @@ public static final String retrieveUsername(final String authHeader) { return null; } + public static final String retrievePassword(final String authHeader) { + + if (StringUtils.isBlank(authHeader)) { + return null; + } + + try { + StringTokenizer st = new StringTokenizer(authHeader); + + if (st.hasMoreTokens()) { + String basic = st.nextToken(); + if (basic.equalsIgnoreCase("Basic")) { + + String credentials = new String(Base64.getDecoder().decode(st.nextToken()), "UTF-8"); + int p = colonIndexOf(credentials); + if (p != -1) { + String password = credentials.substring(p + 1).trim(); + password = unescapeColons(password); + return password; + } + + } + + } + } catch (Exception e) { + LOG.error("Error retrieving username from authHeader"); + return null; + } + return null; + } + /** * system enum, user, and encrypted password */ diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/j2ee/CommonServletContainerInitializer.java b/grouper/src/grouper/edu/internet2/middleware/grouper/j2ee/CommonServletContainerInitializer.java index 07b19b4514ce..8bb6e0fc019f 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/j2ee/CommonServletContainerInitializer.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/j2ee/CommonServletContainerInitializer.java @@ -1,12 +1,16 @@ package edu.internet2.middleware.grouper.j2ee; +import java.util.Collection; import java.util.Set; +import java.util.stream.Collectors; import javax.servlet.FilterRegistration.Dynamic; import javax.servlet.ServletContainerInitializer; import javax.servlet.ServletContext; import javax.servlet.ServletException; +import edu.internet2.middleware.grouper.misc.GrouperStartup; +import edu.internet2.middleware.grouper.plugins.FrameworkStarter; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; @@ -15,6 +19,8 @@ import edu.internet2.middleware.grouper.cfg.GrouperHibernateConfig; import edu.internet2.middleware.grouper.ui.util.GrouperUiConfigInApi; import edu.internet2.middleware.grouper.util.GrouperUtil; +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; public class CommonServletContainerInitializer implements ServletContainerInitializer { @@ -25,7 +31,27 @@ public class CommonServletContainerInitializer implements ServletContainerInitia @Override public void onStartup(Set> arg0, ServletContext context) throws ServletException { - + GrouperStartup.startup(); + GrouperStartup.waitForGrouperStartup(); + + // setup ServletContainerInitializer from OSGI + { + BundleContext bundleContext = FrameworkStarter.getInstance().getFramework().getBundleContext(); + + try { + Collection initializerCollection = FrameworkStarter.getInstance().getFramework().getBundleContext().getServiceReferences(ServletContainerInitializer.class, null).stream().map(r -> bundleContext.getService(r)).collect(Collectors.toList()); + initializerCollection.stream().forEach(r -> { + try { + r.onStartup(arg0, context); + } catch (ServletException e) { + throw new RuntimeException(e); + } + }); + } catch (InvalidSyntaxException e) { + throw new RuntimeException(e); + } + } + boolean runGrouperUi = GrouperHibernateConfig.retrieveConfig().propertyValueBoolean("grouper.is.ui", false); boolean runMockServices = GrouperHibernateConfig.retrieveConfig().propertyValueBoolean("grouper.is.mockServices", false); @@ -180,5 +206,4 @@ public void run() { } } - } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/j2ee/servlet/filter/PluginFilterDelegate.java b/grouper/src/grouper/edu/internet2/middleware/grouper/j2ee/servlet/filter/PluginFilterDelegate.java new file mode 100644 index 000000000000..c56d95b550fc --- /dev/null +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/j2ee/servlet/filter/PluginFilterDelegate.java @@ -0,0 +1,63 @@ +package edu.internet2.middleware.grouper.j2ee.servlet.filter; + +import edu.internet2.middleware.grouper.plugins.GrouperPluginManager; +import edu.internet2.middleware.grouper.util.GrouperUtil; +import org.apache.commons.logging.Log; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.io.IOException; + +/** + * PluginFilterDelegate will delegate behavior to the correct grouper-authentication plugin filter. If the plugin is not properly + * installed, this delegate should fail silently and simply pass control onto the next filter in the filter chain without issue + */ +public class PluginFilterDelegate implements Filter { + private static final Log LOG = GrouperUtil.getLog(PluginFilterDelegate.class); + + protected Filter delegateFilter = new Filter() { + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + filterChain.doFilter(servletRequest, servletResponse); + } + + @Override + public void destroy() { + } + }; + + public PluginFilterDelegate(String moduleJarNameInput, String pluginClassName) { + try { + delegateFilter = GrouperPluginManager.retrievePluginImplementation(moduleJarNameInput, Filter.class, pluginClassName); + } + catch (Throwable e) { + LOG.error("Error retrieving plugin implementation : [" + pluginClassName + "]", e); + } + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + delegateFilter.init(filterConfig); + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + delegateFilter.doFilter(servletRequest, servletResponse, filterChain); + } + + @Override + public void destroy() { + delegateFilter.destroy(); + } + +} \ No newline at end of file diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl.java b/grouper/src/grouper/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl.java index b92c9d08dc5a..dcab94c3488d 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/ldap/ldaptive/LdaptiveSessionImpl.java @@ -749,6 +749,21 @@ private AttributeModificationType translateModificationType(LdapModificationType private SearchResult processSearchRequest(String ldapServerId, Connection ldap, String searchDn, LdapSearchScope ldapSearchScope, String filter, String[] attributeNames, Long sizeLimit) throws LdapException { SearchRequest searchRequest = new SearchRequest(); + + if (filter != null) { + filter = filter.trim(); + if (filter.startsWith("${") && filter.endsWith("}")) { + + if (this.debug) { + this.debugLog.append("Ldaptive filterJexl '").append(filter).append("'\n"); + } + filter = StringUtils.replace(filter, "$newline$", "\n"); + Map variableMap = new HashMap(); + variableMap.put("grouperUtil", new GrouperUtil()); + filter = (String)GrouperUtil.substituteExpressionLanguageScript(filter, variableMap, true, false, false); + } + } + searchRequest.setSearchFilter(new SearchFilter(filter)); searchRequest.setReturnAttributes(attributeNames); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/misc/GrouperStartup.java b/grouper/src/grouper/edu/internet2/middleware/grouper/misc/GrouperStartup.java index 614a9048c8e6..7772abf0b724 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/misc/GrouperStartup.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/misc/GrouperStartup.java @@ -24,6 +24,7 @@ import java.io.File; import java.util.List; +import edu.internet2.middleware.grouper.plugins.FrameworkStarter; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.logging.Log; @@ -398,6 +399,8 @@ public Object callback(GrouperSession grouperSession) throws GrouperSessionExcep } }); + setupOsgi(); + return true; } } catch (RuntimeException re) { @@ -870,6 +873,13 @@ public static void initData(boolean logError) { } } } + + /** + * setup the osgi framework + */ + private static void setupOsgi() { + FrameworkStarter.getInstance().start(); + } /** if we should run the boot strap from startup */ public static boolean runDdlBootstrap = true; diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/plugins/BundleStarter.java b/grouper/src/grouper/edu/internet2/middleware/grouper/plugins/BundleStarter.java new file mode 100644 index 000000000000..ee77b9ab43e7 --- /dev/null +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/plugins/BundleStarter.java @@ -0,0 +1,53 @@ +package edu.internet2.middleware.grouper.plugins; + +import edu.internet2.middleware.grouper.cfg.GrouperConfig; +import edu.internet2.middleware.grouper.util.GrouperUtil; +import org.apache.commons.logging.Log; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +public class BundleStarter { + private static final Log LOG = GrouperUtil.getLog(BundleStarter.class); + private final BundleContext bundleContext; + + private final String bundleDirWithLastSlash; + + public BundleStarter(BundleContext bundleContext) { + this.bundleContext = bundleContext; + + try { + Path tmpDir = Files.createTempDirectory("grouper"); + bundleDirWithLastSlash = GrouperUtil.stripLastSlashIfExists(GrouperConfig.retrieveConfig().propertyValueString("grouper.osgi.jar.dir", tmpDir.toString())) + File.separator; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public void start() { + Map, Set>> pluginJarNameToInterfaceToImplementationClasses = new HashMap, Set>>(); + + Pattern pattern = Pattern.compile("^grouperOsgiPlugin\\.([^.]+)\\.jarName$"); + Set configIds = GrouperConfig.retrieveConfig().propertyConfigIds(pattern); + if (GrouperUtil.length(configIds) > 0) { + for (String configId: configIds) { + String jarName = GrouperConfig.retrieveConfig().propertyValueString("grouperOsgiPlugin." + configId + ".jarName"); + try { + Bundle bundle = bundleContext.installBundle("file:" + bundleDirWithLastSlash + jarName); + bundle.start(); + } catch (BundleException e) { + LOG.error("Problem installing plugin: " + jarName, e); + } + } + } + } +} diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/plugins/FrameworkStarter.java b/grouper/src/grouper/edu/internet2/middleware/grouper/plugins/FrameworkStarter.java new file mode 100644 index 000000000000..9adc7eedcf7d --- /dev/null +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/plugins/FrameworkStarter.java @@ -0,0 +1,125 @@ +package edu.internet2.middleware.grouper.plugins; + +import edu.internet2.middleware.grouper.app.externalSystem.GrouperExternalSystem; +import edu.internet2.middleware.grouper.cfg.GrouperConfig; +import edu.internet2.middleware.grouper.cfg.GrouperHibernateConfig; +import edu.internet2.middleware.grouperClient.config.ConfigPropertiesCascadeBase; +import org.apache.commons.logging.LogFactory; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; +import org.osgi.framework.Constants; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.launch.Framework; +import org.osgi.framework.launch.FrameworkFactory; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.Set; + +/** + * Class used to start up the OSGI framework + * + * @author jj + */ +public class FrameworkStarter { + private final static FrameworkStarter frameworkStarter = new FrameworkStarter(); + + private Framework framework; + + private FrameworkStarter(){} + + public static FrameworkStarter getInstance() { + return frameworkStarter; + } + + public void start() { + Map configMap = new HashMap<>(); + + configMap.put(Constants.FRAMEWORK_BUNDLE_PARENT, Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK); + + // if it caches modules, they might not ever get reloaded + configMap.put(Constants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT); + + //TODO: maybe make this more dynamic. currently we're very opinionated on what we export + configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, GrouperConfig.retrieveConfig().propertyValueString("grouper.osgi.framework.system.packages.extra","javax.servlet,javax.servlet.http")); + + try { + // set up cachedir + Path cacheDir = Files.createTempDirectory("osgi-cache"); + String grouperOsgiCacheDir = GrouperConfig.retrieveConfig().propertyValueString("grouper.osgi.cache.rootdir", cacheDir.toString()); + configMap.put(Constants.FRAMEWORK_STORAGE, grouperOsgiCacheDir); + } catch (IOException e) { + throw new RuntimeException("problem with setting up osgi cache directory", e); + } + + // usually, this is a bad idea, but we have several classes that must be loaded from the framework classpath to work, + // e.g., logging, configuration + String packagesForBootDelegationString; + if (null != GrouperConfig.retrieveConfig().propertyValueString("grouper.osgi.framework.boot.delegation")) { + packagesForBootDelegationString = GrouperConfig.retrieveConfig().propertyValueString("grouper.osgi.framework.boot.delegation"); + } else { + Set packagesForBootDelegation = new HashSet<>(); + packagesForBootDelegation.add(LogFactory.class.getPackage().getName()); + packagesForBootDelegation.add(ConfigPropertiesCascadeBase.class.getPackage().getName()); + // TODO: why oh why... need to fix this + packagesForBootDelegation.add(GrouperExternalSystem.class.getPackage().getName()); + packagesForBootDelegationString = String.join(",", packagesForBootDelegation); + } + configMap.put(Constants.FRAMEWORK_BOOTDELEGATION, packagesForBootDelegationString); + + try { + FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator().next(); + framework = frameworkFactory.newFramework(configMap); + framework.start(); + + this.registerConfigurationServices(); + + BundleStarter bundleStarter = new BundleStarter(framework.getBundleContext()); + bundleStarter.start(); + } catch (BundleException e) { + throw new RuntimeException(e); + } + } + + /** + * register various Grouper services + */ + private void registerConfigurationServices() { + BundleContext context = framework.getBundleContext(); + + try { + context.registerService(LogFactory.class, LogFactory.getFactory(), new Hashtable<>()); + context.registerService(ConfigPropertiesCascadeBase.class, GrouperConfig.retrieveConfig(), buildSimpleDictionary("type", "grouper")); + context.registerService(ConfigPropertiesCascadeBase.class, GrouperHibernateConfig.retrieveConfig(), buildSimpleDictionary("type", "hibernate")); + if (GrouperHibernateConfig.retrieveConfig().propertyValueBoolean("grouper.is.ui", false)) { + context.registerService(ConfigPropertiesCascadeBase.class, (ConfigPropertiesCascadeBase) Class.forName("edu.internet2.middleware.grouper.ui.util.GrouperUiConfigInApi").getMethod("retrieveConfig").invoke(null), buildSimpleDictionary("type", "ui")); + } + if (GrouperHibernateConfig.retrieveConfig().propertyValueBoolean("grouper.is.ws", false)) { + context.registerService(ConfigPropertiesCascadeBase.class, (ConfigPropertiesCascadeBase) Class.forName("edu.internet2.middleware.grouper.ws.GrouperWsConfigInApi").getMethod("retrieveConfig").invoke(null), buildSimpleDictionary("type", "ws")); + } + if (GrouperHibernateConfig.retrieveConfig().propertyValueBoolean("grouper.is.daemon", false)) { + context.registerService(ConfigPropertiesCascadeBase.class, (ConfigPropertiesCascadeBase) Class.forName("edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig").getMethod("retrieveConfig").invoke(null), buildSimpleDictionary("type", "daemon")); + } + } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException("There is a problem with your configuration. Things will not work", e); + } + } + + private static Dictionary buildSimpleDictionary(String key, String value) { + Map tMap = new HashMap(); + tMap.put(key, value); + return FrameworkUtil.asDictionary(tMap); + } + + public Framework getFramework() { + return this.framework; + } +} diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/plugins/GrouperPluginManager.java b/grouper/src/grouper/edu/internet2/middleware/grouper/plugins/GrouperPluginManager.java index 7dcc0bf4c514..d4177056cb03 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/plugins/GrouperPluginManager.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/plugins/GrouperPluginManager.java @@ -233,7 +233,7 @@ public static T retrievePluginImplementation(String moduleJarNameInput, Clas try { clazz = bundle.loadClass(pluginClassName); } catch (Exception e) { - throw new RuntimeException("Cannot load class '" + pluginClassName + "' from bundle: " + (bundle == null ? null : bundle.getSymbolicName()) + ", " + moduleJarNameInput); + throw new RuntimeException("Cannot load class '" + pluginClassName + "' from bundle: " + (bundle == null ? null : bundle.getSymbolicName()) + ", " + moduleJarNameInput, e); } // this is an instance from the module, though from a different classloader @@ -242,7 +242,7 @@ public static T retrievePluginImplementation(String moduleJarNameInput, Clas try { providerImpl = clazz.newInstance(); } catch (Exception e) { - throw new RuntimeException("Cannot instantiate class '" + pluginClassName + "' from bundle: " + (bundle == null ? null : bundle.getSymbolicName()) + ", " + moduleJarNameInput); + throw new RuntimeException("Cannot instantiate class '" + pluginClassName + "' from bundle: " + (bundle == null ? null : bundle.getSymbolicName()) + ", " + moduleJarNameInput, e); } // this converts that instance to the interface which is implements (but cant be typecast since different classloader) diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/subj/CachingResolver.java b/grouper/src/grouper/edu/internet2/middleware/grouper/subj/CachingResolver.java index 0b27dff657ec..f5754eb97386 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/subj/CachingResolver.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/subj/CachingResolver.java @@ -120,9 +120,25 @@ public Subject find(String id) SubjectNotFoundException, SubjectNotUniqueException { - Subject subj = this.getFromFindCache(id, null); + return find(id, false); + } + + /** + * @see SubjectResolver#find(String, boolean) + */ + public Subject find(String id, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SubjectNotFoundException, + SubjectNotUniqueException + { + Subject subj = null; + + if (!ignoreCachedSubjects) { + subj = this.getFromFindCache(id, null); + } + if (subj == null) { - subj = super.getDecoratedResolver().find(id); + subj = super.getDecoratedResolver().find(id, ignoreCachedSubjects); this.putInFindCache(subj); } return subj; @@ -138,9 +154,27 @@ public Subject find(String id, String source) SubjectNotFoundException, SubjectNotUniqueException { - Subject subj = this.getFromFindCache(id, source); + return find(id, source, false); + } + + /** + * @see SubjectResolver#find(String, String, boolean) + * @since 1.2.1 + */ + public Subject find(String id, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SourceUnavailableException, + SubjectNotFoundException, + SubjectNotUniqueException + { + Subject subj = null; + + if (!ignoreCachedSubjects) { + subj = this.getFromFindCache(id, source); + } + if (subj == null) { - subj = super.getDecoratedResolver().find(id, source); + subj = super.getDecoratedResolver().find(id, source, ignoreCachedSubjects); this.putInFindCache(subj); } return subj; @@ -186,13 +220,29 @@ public Subject findByIdentifier(String id) SubjectNotFoundException, SubjectNotUniqueException { - Subject subj = this.getFromFindByIdentifierCache(id, null); + return findByIdentifier(id, false); + } + + /** + * @see SubjectResolver#findByIdentifier(String, boolean) + */ + public Subject findByIdentifier(String id, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SubjectNotFoundException, + SubjectNotUniqueException + { + Subject subj = null; + + if (!ignoreCachedSubjects) { + subj = this.getFromFindByIdentifierCache(id, null); + } + if (subj == null) { - subj = super.getDecoratedResolver().findByIdentifier(id); + subj = super.getDecoratedResolver().findByIdentifier(id, ignoreCachedSubjects); this.putInFindByIdentifierCache(id, subj); } return subj; - } + } /** * @see SubjectResolver#findByIdentifier(String, String) @@ -204,9 +254,26 @@ public Subject findByIdentifier(String id, String source) SubjectNotFoundException, SubjectNotUniqueException { - Subject subj = this.getFromFindByIdentifierCache(id, source); + return findByIdentifier(id, source, false); + } + + /** + * @see SubjectResolver#findByIdentifier(String, String, boolean) + */ + public Subject findByIdentifier(String id, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SourceUnavailableException, + SubjectNotFoundException, + SubjectNotUniqueException + { + Subject subj = null; + + if (!ignoreCachedSubjects) { + subj = this.getFromFindByIdentifierCache(id, source); + } + if (subj == null) { - subj = super.getDecoratedResolver().findByIdentifier(id, source); + subj = super.getDecoratedResolver().findByIdentifier(id, source, ignoreCachedSubjects); this.putInFindByIdentifierCache(id, subj); } return subj; @@ -401,9 +468,22 @@ private void putInFindByIdOrIdentifierCache(String idfr, Set sources, Su */ public Subject findByIdOrIdentifier(String id) throws IllegalArgumentException, SubjectNotFoundException, SubjectNotUniqueException { - Subject subj = this.getFromFindByIdOrIdentifierCache(id, (String)null); + return findByIdOrIdentifier(id, false); + } + + /** + * + */ + public Subject findByIdOrIdentifier(String id, boolean ignoreCachedSubjects) throws IllegalArgumentException, + SubjectNotFoundException, SubjectNotUniqueException { + Subject subj = null; + + if (!ignoreCachedSubjects) { + subj = this.getFromFindByIdOrIdentifierCache(id, (String)null); + } + if (subj == null) { - subj = super.getDecoratedResolver().findByIdOrIdentifier(id); + subj = super.getDecoratedResolver().findByIdOrIdentifier(id, ignoreCachedSubjects); this.putInFindByIdOrIdentifierCache(id, subj); } return subj; @@ -415,9 +495,23 @@ public Subject findByIdOrIdentifier(String id) throws IllegalArgumentException, public Subject findByIdOrIdentifier(String id, String source) throws IllegalArgumentException, SourceUnavailableException, SubjectNotFoundException, SubjectNotUniqueException { - Subject subj = this.getFromFindByIdOrIdentifierCache(id, source); + return findByIdOrIdentifier(id, source, false); + } + + /** + * @see SubjectResolver#findByIdOrIdentifier(String, String, boolean) + */ + public Subject findByIdOrIdentifier(String id, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, SourceUnavailableException, + SubjectNotFoundException, SubjectNotUniqueException { + Subject subj = null; + + if (!ignoreCachedSubjects) { + subj = this.getFromFindByIdOrIdentifierCache(id, source); + } + if (subj == null) { - subj = super.getDecoratedResolver().findByIdOrIdentifier(id, source); + subj = super.getDecoratedResolver().findByIdOrIdentifier(id, source, ignoreCachedSubjects); this.putInFindByIdOrIdentifierCache(id, subj); } return subj; @@ -930,32 +1024,44 @@ public Map findByIds(Collection ids) return result; } - + /** * @see SubjectResolver#findByIds(Collection, String) */ public Map findByIds(Collection ids, String source) throws IllegalArgumentException, SourceUnavailableException { + return findByIds(ids, source, false); + } + + /** + * @see SubjectResolver#findByIds(Collection, String, boolean) + */ + public Map findByIds(Collection ids, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, SourceUnavailableException { Map result = new HashMap(); Set idsNotFoundInCache = new HashSet(); - //lets get from cache - for (String id : ids) { - Subject subject = this.getFromFindCache(id, source); - if (subject == null) { - //if not found, batch these up - idsNotFoundInCache.add(id); - } else { - result.put(id, subject); + if (ignoreCachedSubjects) { + idsNotFoundInCache.addAll(ids); + } else { + //lets get from cache + for (String id : ids) { + Subject subject = this.getFromFindCache(id, source); + if (subject == null) { + //if not found, batch these up + idsNotFoundInCache.add(id); + } else { + result.put(id, subject); + } } } //if not everything in cache, get the batch if (GrouperUtil.length(idsNotFoundInCache) > 0) { - Map nonCachedResult = super.getDecoratedResolver().findByIds(idsNotFoundInCache, source); + Map nonCachedResult = super.getDecoratedResolver().findByIds(idsNotFoundInCache, source, ignoreCachedSubjects); for (Subject subject : nonCachedResult.values()) { diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/subj/SourcesXmlResolver.java b/grouper/src/grouper/edu/internet2/middleware/grouper/subj/SourcesXmlResolver.java index 64c616803701..6fb33220a335 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/subj/SourcesXmlResolver.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/subj/SourcesXmlResolver.java @@ -57,6 +57,7 @@ import edu.internet2.middleware.grouper.misc.GrouperStartup; import edu.internet2.middleware.grouper.subj.cache.SubjectSourceCache; import edu.internet2.middleware.grouper.util.GrouperUtil; +import edu.internet2.middleware.grouperClient.collections.MultiKey; import edu.internet2.middleware.subject.SearchPageResult; import edu.internet2.middleware.subject.Source; import edu.internet2.middleware.subject.SourceUnavailableException; @@ -102,6 +103,16 @@ public SourcesXmlResolver() { * @since 1.2.1 */ public Subject find(final String id) + throws IllegalArgumentException, + SubjectNotFoundException, + SubjectNotUniqueException { + return find(id, false); + } + + /** + * @see SubjectResolver#find(String, boolean) + */ + public Subject find(final String id, boolean ignoreCachedSubjects) throws IllegalArgumentException, SubjectNotFoundException, SubjectNotUniqueException { @@ -118,7 +129,7 @@ public Subject find(final String id) callables.add(new LogLabelCallable("find on source: " + sa.getId() + ", '" + id + "'") { public Subject callLogic() throws Exception { - return SubjectSourceCache.getSubjectFromCacheOrSource(SOURCE, id, false); + return SubjectSourceCache.getSubjectFromCacheOrSource(SOURCE, id, ignoreCachedSubjects, false); } }); @@ -138,7 +149,7 @@ public Subject callLogic() throws Exception { subject = SubjectFinder.filterSubject(GrouperSession.staticGrouperSession(), subject, null); return subject; - } + } /** @@ -296,19 +307,32 @@ public T call() throws Exception { } return results; - } - + } + /** * @see SubjectResolver#find(String, String, String) * @since 1.2.1 */ public Subject find(String id, String source) + throws IllegalArgumentException, + SourceUnavailableException, + SubjectNotFoundException, + SubjectNotUniqueException { + return find(id, source, false); + } + + /** + * @param id + * @param source + * @param ignoreCachedSubjects + */ + public Subject find(String id, String source, boolean ignoreCachedSubjects) throws IllegalArgumentException, SourceUnavailableException, SubjectNotFoundException, SubjectNotUniqueException { - Subject subj = SubjectSourceCache.getSubjectFromCacheOrSource(getSource(source), id, true); + Subject subj = SubjectSourceCache.getSubjectFromCacheOrSource(getSource(source), id, ignoreCachedSubjects, true); updateMemberAttributes(subj); //before we have started up, it wont find the session :) @@ -372,6 +396,17 @@ public Subject findByIdentifier(final String id) throws IllegalArgumentException, SubjectNotFoundException, SubjectNotUniqueException + { + return findByIdentifier(id, false); + } + + /** + * @see SubjectResolver#findByIdentifier(String, boolean) + */ + public Subject findByIdentifier(final String id, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SubjectNotFoundException, + SubjectNotUniqueException { List subjects = new ArrayList(); @@ -387,7 +422,7 @@ public Subject findByIdentifier(final String id) public Subject callLogic() throws Exception { - return SubjectSourceCache.getSubjectByIdentifierFromCacheOrSource(SOURCE, id, false); + return SubjectSourceCache.getSubjectByIdentifierFromCacheOrSource(SOURCE, id, ignoreCachedSubjects, false); } }); @@ -403,7 +438,7 @@ public Subject callLogic() throws Exception { Subject subject = this.thereCanOnlyBeOne(subjects, id); subject = SubjectFinder.filterSubject(GrouperSession.staticGrouperSession(), subject, null); return subject; - } + } /** * @see SubjectResolver#findByIdentifier(String, String, String) @@ -415,7 +450,19 @@ public Subject findByIdentifier(String id, String source) SubjectNotFoundException, SubjectNotUniqueException { - Subject subj = SubjectSourceCache.getSubjectByIdentifierFromCacheOrSource(getSource(source), id, true); + return findByIdentifier(id, source, false); + } + + /** + * @see SubjectResolver#findByIdentifier(String, String, String, boolean) + */ + public Subject findByIdentifier(String id, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SourceUnavailableException, + SubjectNotFoundException, + SubjectNotUniqueException + { + Subject subj = SubjectSourceCache.getSubjectByIdentifierFromCacheOrSource(getSource(source), id, ignoreCachedSubjects, true); updateMemberAttributes(subj); subj = SubjectFinder.filterSubject(GrouperSession.staticGrouperSession(), subj, null); return subj; @@ -500,6 +547,14 @@ private Subject thereCanOnlyBeOne(List subjects, String id) */ public Subject findByIdOrIdentifier(final String idOrIdentifier) throws IllegalArgumentException, SubjectNotFoundException, SubjectNotUniqueException { + return findByIdOrIdentifier(idOrIdentifier, false); + } + + /** + * @see SubjectResolver#findByIdOrIdentifier(String, boolean) + */ + public Subject findByIdOrIdentifier(final String idOrIdentifier, boolean ignoreCachedSubjects) throws IllegalArgumentException, + SubjectNotFoundException, SubjectNotUniqueException { List subjects = new ArrayList(); @@ -515,7 +570,7 @@ public Subject findByIdOrIdentifier(final String idOrIdentifier) throws IllegalA public Subject callLogic() throws Exception { - return SubjectSourceCache.getSubjectByIdOrIdentifierFromCacheOrSource(SOURCE, idOrIdentifier, false); + return SubjectSourceCache.getSubjectByIdOrIdentifierFromCacheOrSource(SOURCE, idOrIdentifier, ignoreCachedSubjects, false); } }); @@ -539,8 +594,17 @@ public Subject callLogic() throws Exception { public Subject findByIdOrIdentifier(String id, String source) throws IllegalArgumentException, SourceUnavailableException, SubjectNotFoundException, SubjectNotUniqueException { + return findByIdOrIdentifier(id, source, false); + } + + /** + * @see SubjectResolver#findByIdOrIdentifier(String, String, boolean) + */ + public Subject findByIdOrIdentifier(String id, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, SourceUnavailableException, + SubjectNotFoundException, SubjectNotUniqueException { - Subject subj = SubjectSourceCache.getSubjectByIdOrIdentifierFromCacheOrSource(getSource(source), id, true); + Subject subj = SubjectSourceCache.getSubjectByIdOrIdentifierFromCacheOrSource(getSource(source), id, ignoreCachedSubjects, true); updateMemberAttributes(subj); subj = SubjectFinder.filterSubject(GrouperSession.staticGrouperSession(), subj, null); return subj; @@ -596,6 +660,38 @@ private void updateMemberAttributes(Subject subj) { } } } + + /** + * @param subj + */ + private void updateMemberAttributes(Set subjects) { + + //if not started, then maybe not initted... + if (GrouperStartup.isFinishedStartupSuccessfully() && !UsduJob.isInUsduThread()) { + + Map nonGroupSubjects = new HashMap(); + + for (Subject subject : subjects) { + if (!"g:gsa".equals(subject.getSourceId())) { + MultiKey nonGroupSubjectMultiKey = new MultiKey(subject.getSourceId(), subject.getId()); + nonGroupSubjects.put(nonGroupSubjectMultiKey, subject); + } + } + + if (nonGroupSubjects.size() > 0) { + // update member attributes + Set members = MemberFinder.findBySubjects(nonGroupSubjects.values(), false); + for (Member member : members) { + MultiKey key = new MultiKey(member.getSubjectSourceId(), member.getSubjectId()); + Subject subject = nonGroupSubjects.get(key); + + if (subject != null) { + member.updateMemberAttributes(subject, true); + } + } + } + } + } /** @@ -1093,6 +1189,21 @@ public Map callLogic() throws Exception { } + /** + * @see SubjectResolver#findByIds(Collection, String, boolean) + */ + public Map findByIds(Collection ids, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, SourceUnavailableException { + + Map subjectMap = SubjectSourceCache.getSubjectsByIdsFromCacheOrSource(this.getSource(source), ids, ignoreCachedSubjects); + if (subjectMap != null) { + updateMemberAttributes(new HashSet(subjectMap.values())); + } + subjectMap = SubjectFinder.filterSubjects(GrouperSession.staticGrouperSession(), subjectMap, null); + return subjectMap; + + } + /** * @see SubjectResolver#findByIds(Collection, String) */ diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/subj/SubjectResolver.java b/grouper/src/grouper/edu/internet2/middleware/grouper/subj/SubjectResolver.java index fb97137ba21c..785686e6ee04 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/subj/SubjectResolver.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/subj/SubjectResolver.java @@ -71,6 +71,20 @@ Subject find(String id) SubjectNotUniqueException ; + /** + * @return Subject matching search parameters. + * @param id Subject id to search on. + * @param ignoreCachedSubjects + * @throws IllegalArgumentException if any parameter is null. + * @throws SubjectNotFoundException if no matching subject is found. + * @throws SubjectNotUniqueException if more than one matching subject is found. + */ + Subject find(String id, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SubjectNotFoundException, + SubjectNotUniqueException + ; + /** * @return Subject matching search parameters. * @param id Subject id to search on. @@ -87,6 +101,23 @@ Subject find(String id, String source) SubjectNotFoundException, SubjectNotUniqueException ; + + /** + * @return Subject matching search parameters. + * @param id Subject id to search on. + * @param source Source adapter to search within. + * @param ignoreCachedSubjects + * @throws IllegalArgumentException if any parameter is null. + * @throws SourceUnavailableException if source is unavailable. + * @throws SubjectNotFoundException if no matching subject is found. + * @throws SubjectNotUniqueException if more than one matching subject is found. + */ + Subject find(String id, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SourceUnavailableException, + SubjectNotFoundException, + SubjectNotUniqueException + ; /** * @param query A source-appropraite query string. @@ -153,6 +184,20 @@ Subject findByIdentifier(String id) SubjectNotFoundException, SubjectNotUniqueException ; + + /** + * @return Subject matching search parameters. + * @param id Subject identifier to search on. + * @param ignoreCachedSubjects + * @throws IllegalArgumentException if any parameter is null. + * @throws SubjectNotFoundException if no matching subject is found. + * @throws SubjectNotUniqueException if more than one matching subject is found. + */ + Subject findByIdentifier(String id, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SubjectNotFoundException, + SubjectNotUniqueException + ; /** * @return Subject matching search parameters. @@ -170,6 +215,23 @@ Subject findByIdentifier(String id, String source) SubjectNotFoundException, SubjectNotUniqueException ; + + /** + * @return Subject matching search parameters. + * @param id Subject identifier to search on. + * @param source Source adapter to search within. + * @param ignoreCachedSubjects + * @throws IllegalArgumentException if any parameter is null. + * @throws SourceUnavailableException if source is unavailable. + * @throws SubjectNotFoundException if no matching subject is found. + * @throws SubjectNotUniqueException if more than one matching subject is found. + */ + Subject findByIdentifier(String id, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SourceUnavailableException, + SubjectNotFoundException, + SubjectNotUniqueException + ; /** * @param id @@ -202,6 +264,20 @@ Subject findByIdOrIdentifier(String id) SubjectNotFoundException, SubjectNotUniqueException ; + + /** + * @return Subject matching search parameters. + * @param id Subject identifier to search on. + * @param ignoreCachedSubjects + * @throws IllegalArgumentException if any parameter is null. + * @throws SubjectNotFoundException if no matching subject is found. + * @throws SubjectNotUniqueException if more than one matching subject is found. + */ + Subject findByIdOrIdentifier(String id, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SubjectNotFoundException, + SubjectNotUniqueException + ; /** * @return Subject matching search parameters. @@ -220,6 +296,24 @@ Subject findByIdOrIdentifier(String id, String source) SubjectNotFoundException, SubjectNotUniqueException ; + + /** + * @return Subject matching search parameters. + * @param id Subject identifier to search on. + * @param type Subject type to search on. + * @param source Source adapter to search within. + * @param ignoreCachedSubjects + * @throws IllegalArgumentException if any parameter is null. + * @throws SourceUnavailableException if source is unavailable. + * @throws SubjectNotFoundException if no matching subject is found. + * @throws SubjectNotUniqueException if more than one matching subject is found. + */ + Subject findByIdOrIdentifier(String id, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SourceUnavailableException, + SubjectNotFoundException, + SubjectNotUniqueException + ; /** * @param query A source-appropraite query string. @@ -329,6 +423,21 @@ Map findByIds(Collection ids) Map findByIds(Collection ids, String source) throws IllegalArgumentException, SourceUnavailableException; + + /** + * @return map of search param to subject + * @param id Subject id to search on. + * @param source Source adapter to search within. + * @param ignoreCachedSubjects + * @throws IllegalArgumentException if any parameter is null. + * @throws SourceUnavailableException if source is unavailable. + * @throws SubjectNotFoundException if no matching subject is found. + * @throws SubjectNotUniqueException if more than one matching subject is found. + * @since 2.0.2 + */ + Map findByIds(Collection ids, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SourceUnavailableException; /** * @return map of search param to subject diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/subj/ValidatingResolver.java b/grouper/src/grouper/edu/internet2/middleware/grouper/subj/ValidatingResolver.java index 2d59c22b3307..0e5c130efb29 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/subj/ValidatingResolver.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/subj/ValidatingResolver.java @@ -86,10 +86,21 @@ public Subject find(String id) throws IllegalArgumentException, SubjectNotFoundException, SubjectNotUniqueException + { + return find(id, false); + } + + /** + * @see SubjectResolver#find(String, boolean) + */ + public Subject find(String id, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SubjectNotFoundException, + SubjectNotUniqueException { this.param.notNullString(id, "null Subject Id"); - return super.getDecoratedResolver().find(id); - } + return super.getDecoratedResolver().find(id, ignoreCachedSubjects); + } /** * @see SubjectResolver#find(String, String) @@ -100,9 +111,21 @@ public Subject find(String id, String source) SourceUnavailableException, SubjectNotFoundException, SubjectNotUniqueException + { + return find(id, source, false); + } + + /** + * @see SubjectResolver#find(String, String, boolean) + */ + public Subject find(String id, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SourceUnavailableException, + SubjectNotFoundException, + SubjectNotUniqueException { this.param.notNullString(id, "null Subject Id").notNullString(source, "null Source Id"); - return super.getDecoratedResolver().find(id, source); + return super.getDecoratedResolver().find(id, source, ignoreCachedSubjects); } /** @@ -155,10 +178,22 @@ public Subject findByIdentifier(String id) throws IllegalArgumentException, SubjectNotFoundException, SubjectNotUniqueException + { + return findByIdentifier(id, false); + } + + /** + * @see SubjectResolver#findByIdentifier(String, boolean) + */ + public Subject findByIdentifier(String id, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SubjectNotFoundException, + SubjectNotUniqueException { this.param.notNullString(id, "null Subject Id"); - return super.getDecoratedResolver().findByIdentifier(id); - } + return super.getDecoratedResolver().findByIdentifier(id, ignoreCachedSubjects); + } + /** * @see SubjectResolver#findByIdentifier(String, String) @@ -169,9 +204,21 @@ public Subject findByIdentifier(String id,String source) SourceUnavailableException, SubjectNotFoundException, SubjectNotUniqueException + { + return findByIdentifier(id, source, false); + } + + /** + * @see SubjectResolver#findByIdentifier(String, String, boolean) + */ + public Subject findByIdentifier(String id,String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, + SourceUnavailableException, + SubjectNotFoundException, + SubjectNotUniqueException { this.param.notNullString(id, "null Subject Id").notNullString(source, "null Source Id"); - return super.getDecoratedResolver().findByIdentifier(id, source); + return super.getDecoratedResolver().findByIdentifier(id, source, ignoreCachedSubjects); } /** @@ -199,8 +246,16 @@ public Set getSources() { */ public Subject findByIdOrIdentifier(String id) throws IllegalArgumentException, SubjectNotFoundException, SubjectNotUniqueException { + return findByIdOrIdentifier(id, false); + } + + /** + * @see SubjectResolver#findByIdOrIdentifier(String, boolean) + */ + public Subject findByIdOrIdentifier(String id, boolean ignoreCachedSubjects) throws IllegalArgumentException, + SubjectNotFoundException, SubjectNotUniqueException { this.param.notNullString(id, "null Subject Id"); - return super.getDecoratedResolver().findByIdOrIdentifier(id); + return super.getDecoratedResolver().findByIdOrIdentifier(id, ignoreCachedSubjects); } /** @@ -209,8 +264,17 @@ public Subject findByIdOrIdentifier(String id) throws IllegalArgumentException, public Subject findByIdOrIdentifier(String id, String source) throws IllegalArgumentException, SourceUnavailableException, SubjectNotFoundException, SubjectNotUniqueException { + return findByIdOrIdentifier(id, source, false); + } + + /** + * @see SubjectResolver#findByIdOrIdentifier(String, String, boolean) + */ + public Subject findByIdOrIdentifier(String id, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, SourceUnavailableException, + SubjectNotFoundException, SubjectNotUniqueException { this.param.notNullString(id, "null Subject Id").notNullString(source, "null Source Id"); - return super.getDecoratedResolver().findByIdOrIdentifier(id, source); + return super.getDecoratedResolver().findByIdOrIdentifier(id, source, ignoreCachedSubjects); } /** @@ -309,9 +373,17 @@ public Map findByIds(Collection ids) */ public Map findByIds(Collection ids, String source) throws IllegalArgumentException, SourceUnavailableException { + return findByIds(ids, source, false); + } + + /** + * @see SubjectResolver#findByIds(Collection, String, boolean) + */ + public Map findByIds(Collection ids, String source, boolean ignoreCachedSubjects) + throws IllegalArgumentException, SourceUnavailableException { this.param.notNullCollectionString(ids, "null Subject Ids"); - return super.getDecoratedResolver().findByIds(ids, source); + return super.getDecoratedResolver().findByIds(ids, source, ignoreCachedSubjects); } diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/subj/cache/SubjectSourceCache.java b/grouper/src/grouper/edu/internet2/middleware/grouper/subj/cache/SubjectSourceCache.java index d996cdc29e3c..0ce64c432dc4 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/subj/cache/SubjectSourceCache.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/subj/cache/SubjectSourceCache.java @@ -1183,6 +1183,18 @@ private static void updateSubjectInCache(Subject subject, SubjectSourceCacheItem * @return subject */ public static Subject getSubjectFromCacheOrSource(Source source, String id, boolean exceptionIfNotFound) { + return getSubjectFromCacheOrSource(source, id, false, exceptionIfNotFound); + } + + /** + * get a subject by id or from cache + * @param source + * @param id + * @param ignoreCachedSubjects + * @param exceptionIfNotFound + * @return subject + */ + public static Subject getSubjectFromCacheOrSource(Source source, String id, boolean ignoreCachedSubjects, boolean exceptionIfNotFound) { initCacheIfNotInitted(); @@ -1237,7 +1249,7 @@ public static Subject getSubjectFromCacheOrSource(Source source, String id, bool } boolean retrieved = false; - if (subjectSourceCacheItem == null || subjectSourceCacheItem.expired()) { + if (subjectSourceCacheItem == null || subjectSourceCacheItem.expired() || ignoreCachedSubjects) { subject = source.getSubject(id, false); if (subjectSourceCacheItem != null) { subjectSourceCacheItem.setSubject(subject); @@ -1304,6 +1316,17 @@ public static Subject getSubjectFromCacheOrSource(Source source, String id, bool * @return subject */ public static Map getSubjectsByIdsFromCacheOrSource(Source source, Collection ids) { + return getSubjectsByIdsFromCacheOrSource(source, ids, false); + } + + /** + * get a subject by id or from cache + * @param source + * @param ids + * @param ignoreCachedSubjects + * @return subject + */ + public static Map getSubjectsByIdsFromCacheOrSource(Source source, Collection ids, boolean ignoreCachedSubjects) { initCacheIfNotInitted(); @@ -1367,7 +1390,7 @@ public static Map getSubjectsByIdsFromCacheOrSource(Source sour SubjectSourceCacheItem subjectSourceCacheItem = subjectCache.get(multiKey); Subject subject = null; - if (subjectSourceCacheItem == null || subjectSourceCacheItem.expired()) { + if (subjectSourceCacheItem == null || subjectSourceCacheItem.expired() || ignoreCachedSubjects) { idsToRetrieveFromSource.add(id); } else { @@ -1443,8 +1466,6 @@ public static Map getSubjectsByIdsFromCacheOrSource(Source sour } - - /** * get a subject by identifier or from cache * @param source @@ -1453,6 +1474,18 @@ public static Map getSubjectsByIdsFromCacheOrSource(Source sour * @return subject */ public static Subject getSubjectByIdentifierFromCacheOrSource(Source source, String identifier, boolean exceptionIfNotFound) { + return getSubjectByIdentifierFromCacheOrSource(source, identifier, false, exceptionIfNotFound); + } + + /** + * get a subject by identifier or from cache + * @param source + * @param identifier + * @param ignoreCachedSubjects + * @param exceptionIfNotFound + * @return subject + */ + public static Subject getSubjectByIdentifierFromCacheOrSource(Source source, String identifier, boolean ignoreCachedSubjects, boolean exceptionIfNotFound) { initCacheIfNotInitted(); @@ -1506,7 +1539,7 @@ public static Subject getSubjectByIdentifierFromCacheOrSource(Source source, Str } boolean retrieved = false; - if (subjectSourceCacheItem == null || subjectSourceCacheItem.expired()) { + if (subjectSourceCacheItem == null || subjectSourceCacheItem.expired() || ignoreCachedSubjects) { subject = source.getSubjectByIdentifier(identifier, false); if (subjectSourceCacheItem != null) { subjectSourceCacheItem.setSubject(subject); @@ -1579,6 +1612,18 @@ public static boolean cacheEnabled() { * @return subject */ public static Subject getSubjectByIdOrIdentifierFromCacheOrSource(Source source, String idOrIdentifier, boolean exceptionIfNotFound) { + return getSubjectByIdOrIdentifierFromCacheOrSource(source, idOrIdentifier, false, exceptionIfNotFound); + } + + /** + * get a subject by identifier or from cache + * @param source + * @param idOrIdentifier + * @param ignoreCachedSubjects + * @param exceptionIfNotFound + * @return subject + */ + public static Subject getSubjectByIdOrIdentifierFromCacheOrSource(Source source, String idOrIdentifier, boolean ignoreCachedSubjects, boolean exceptionIfNotFound) { initCacheIfNotInitted(); @@ -1651,7 +1696,7 @@ public static Subject getSubjectByIdOrIdentifierFromCacheOrSource(Source source, } boolean retrieved = false; - if (subjectSourceCacheItem == null || subjectSourceCacheItem.expired()) { + if (subjectSourceCacheItem == null || subjectSourceCacheItem.expired() || ignoreCachedSubjects) { subject = source.getSubjectByIdOrIdentifier(idOrIdentifier, false); if (subjectSourceCacheItem != null) { subjectSourceCacheItem.setSubject(subject); diff --git a/grouper/src/grouper/edu/internet2/middleware/grouper/util/GrouperUtil.java b/grouper/src/grouper/edu/internet2/middleware/grouper/util/GrouperUtil.java index a5cb0ebda7d3..70409cdc31db 100644 --- a/grouper/src/grouper/edu/internet2/middleware/grouper/util/GrouperUtil.java +++ b/grouper/src/grouper/edu/internet2/middleware/grouper/util/GrouperUtil.java @@ -352,6 +352,19 @@ public static void main(String[] args) throws Exception { // // System.out.println(GrouperUtil.toStringForLog(listObjectArray)); +// Map variableMap = new HashMap(); +// ProvisioningGroup grouperProvisioningGroup = new ProvisioningGroup(); +// grouperProvisioningGroup.setName("w:e:r:t"); +// variableMap.put("grouperProvisioningGroup", grouperProvisioningGroup); +// +// String result = (String)GrouperUtil.substituteExpressionLanguageScript( +// "${edu.internet2.middleware.grouper.util.GrouperUtil.ldapBushyDn(edu.internet2.middleware.grouper.util.GrouperUtil.stripPrefix(grouperProvisioningGroup.name, 'w:e:'), 'cn', 'ou', true, false) + ',ou=groups,dc=school,dc=edu'}" +// , variableMap, true, false, false); +// +// System.out.println(result); + + System.out.println(GrouperUtil.stringFormatNameReverseReplaceTruncate("penn:isc:ait:apps:twoFactor:groups:requiredUsersStaff:twoFactorStaff", ".", 64)); + } /** @@ -1109,7 +1122,7 @@ public static String byteCountToDisplaySize(long size) { * @return the logger */ public static Log getLog(Class theClass) { - logDirsCreateIfNotDone(); + // logDirsCreateIfNotDone(); return LogFactory.getLog(theClass); } @@ -1803,6 +1816,35 @@ public static String ldapEscapeRdnValue(String rdnValue) { RDN rdn = new RDN("cn", rdnValue); return rdn.toMinimallyEncodedString().substring("cn=".length()); } + + /** + * active directory date from millis 1970 date + * @return the AD date + */ + public static long ldapAdDateCurrent() { + return ldapAdDateFromMillis1970(System.currentTimeMillis()); + } + + /** + * active directory date from millis 1970 date + * @param millisSince1970 + * @return the AD date + */ + public static long ldapAdDateFromMillis1970(long millisSince1970) { + + // Calendar calendar = java.util.Calendar.getInstance(); + // + // calendar.setTime(new Date("1/1/1601")); + // long base_1601_time = calendar.getTimeInMillis(); + // + // calendar.setTime(new Date("1/1/1970")); + // long base_1970_time = calendar.getTimeInMillis(); + // + // // 11644473600000 + // long ms_offset = base_1970_time - base_1601_time; + + return (millisSince1970 + 11644473600000L) * 10000; + } /** * @@ -7438,7 +7480,9 @@ public static String stringValue(Object input) { return decimalFormat.format(((Number) input).doubleValue()); } - + if (input instanceof byte[]) { + return new String((byte[])input, StandardCharsets.UTF_8); + } return input.toString(); } @@ -9063,13 +9107,13 @@ public synchronized static Properties propertiesFromResourceName(String resource * @param generic type * * @param string - * @param exceptionOnNotFound true if exception should be thrown on not found + * @param exceptionOnBlank true if exception should be thrown on not found * @return the enum or null or exception if not found * @throws RuntimeException if there is a problem */ public static > E enumValueOfIgnoreCase(Class theEnumClass, String string, - boolean exceptionOnNotFound) throws RuntimeException { - return enumValueOfIgnoreCase(theEnumClass, string, exceptionOnNotFound, true); + boolean exceptionOnBlank) throws RuntimeException { + return enumValueOfIgnoreCase(theEnumClass, string, exceptionOnBlank, true); } @@ -9079,15 +9123,15 @@ public static > E enumValueOfIgnoreCase(Class theEnumClass, * @param generic type * * @param string - * @param exceptionOnNotFound true if exception should be thrown on not found + * @param exceptionOnBlank true if exception should be thrown on not found * @param exceptionIfInvalid if there is a string, but it is invalid, if should throw exception * @return the enum or null or exception if not found * @throws RuntimeException if there is a problem */ public static > E enumValueOfIgnoreCase(Class theEnumClass, String string, - boolean exceptionOnNotFound, boolean exceptionIfInvalid) throws RuntimeException { + boolean exceptionOnBlank, boolean exceptionIfInvalid) throws RuntimeException { - if (!exceptionOnNotFound && isBlank(string)) { + if (!exceptionOnBlank && isBlank(string)) { return null; } for (E e : theEnumClass.getEnumConstants()) { @@ -10646,6 +10690,149 @@ public static boolean equalsSet(Set set1, Set set2) { return newSet.size() == 0; } + /** + * see if two collections are deep equals based on strings or longs (or conversions) + * @param collection1 + * @param collection2 + * @return if lists are equal or empty + */ + public static boolean equalsCollectionStringLong(Collection collection1, Collection collection2) { + int collection1length = length(collection1); + int collection2length = length(collection2); + if (collection1length == collection2length && collection1length == 0) { + return true; + } + if (collection1 == null || collection2 == null) { + return false; + } + + if (collection1length != collection2length) { + return false; + } + + Object collection1firstValue = collection1.iterator().next(); + Object collection2firstValue = collection2.iterator().next(); + + if (collection1firstValue instanceof Integer || collection1firstValue instanceof Long || collection2firstValue instanceof Integer || collection2firstValue instanceof Long) { + + // lets treat as longs + Collection collection2longs = new HashSet(); + for (Object object : collection2) { + try { + collection2longs.add(GrouperUtil.longObjectValue(object, true)); + } catch (Exception e) { + return false; + } + } + + for (Object object : collection1) { + try { + Long objectLong = GrouperUtil.longObjectValue(object, true); + if (!collection2longs.contains(objectLong)) { + return false; + } + } catch (Exception e) { + return false; + } + } + return true; + } + if (collection1firstValue instanceof String || collection2firstValue instanceof String) { + + // lets treat as strings + Collection collection2strings = new HashSet(); + for (Object object : collection2) { + try { + collection2strings.add(GrouperUtil.stringValue(object)); + } catch (Exception e) { + return false; + } + } + + for (Object object : collection1) { + try { + String objectString = GrouperUtil.stringValue(object); + if (!collection2strings.contains(objectString)) { + return false; + } + } catch (Exception e) { + return false; + } + } + return true; + } + + // not sure why not one of those... + return false; + } + + /** + * see if two objects long value is the same + * @param thisValue + * @param thatValue + * @return if equal + */ + public static boolean equalsLong(Object thisValue, Object thatValue) { + + if (thisValue == thatValue) { + return true; + } + if (thisValue == null || thatValue == null) { + return false; + } + try { + thisValue = GrouperUtil.longObjectValue(thisValue, true); + } catch (RuntimeException re) { + + } + try { + thatValue = GrouperUtil.longObjectValue(thatValue, true); + } catch (RuntimeException re) { + + } + + if (!(thisValue instanceof Long) || !(thatValue instanceof Long)) { + return false; + } + + //they are both longs + return ((Long)thisValue).equals(thatValue); + + } + + /** + * see if two strings are equal (or the strings they convert into) + * @param thisValue + * @param thatValue + * @return true if equal + */ + public static boolean equalsString(Object thisValue, Object thatValue) { + if (thisValue == thatValue) { + return true; + } + if (thisValue == null || thatValue == null) { + return false; + } + try { + thisValue = GrouperUtil.stringValue(thisValue); + } catch (RuntimeException re) { + + } + try { + thatValue = GrouperUtil.stringValue(thatValue); + } catch (RuntimeException re) { + + } + + if (!(thisValue instanceof String) || !(thatValue instanceof String)) { + return false; + } + + //they are both strings + return ((String)thisValue).equals(thatValue); + + } + /** * see if two lists are deep equals using the equals() method on each item * @param list1 @@ -10960,7 +11147,9 @@ public static String substituteExpressionLanguage(String stringToParse, } //allow utility methods - jc.set("grouperUtil", new GrouperUtilElSafe()); + if (!variableMap.containsKey("grouperUtil")) { + jc.set("grouperUtil", new GrouperUtilElSafe()); + } //if you add another one here, add it in the logs below // matching ${ exp } (non-greedy) @@ -11146,7 +11335,9 @@ public static Object substituteExpressionLanguageScript(String script, } //allow utility methods - jc.set("grouperUtil", new GrouperUtilElSafe()); + if (!variableMap.containsKey("grouperUtil")) { + jc.set("grouperUtil", new GrouperUtilElSafe()); + } //if you add another one here, add it in the logs below script = script.trim(); @@ -14122,7 +14313,9 @@ public static String substituteExpressionLanguageTemplate(String script, } //allow utility methods - jc.set("grouperUtil", new GrouperUtilElSafe()); + if (!variableMap.containsKey("grouperUtil")) { + jc.set("grouperUtil", new GrouperUtilElSafe()); + } //if you add another one here, add it in the logs below script = script.trim(); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/TestStemApi.java b/grouper/src/test/edu/internet2/middleware/grouper/TestStemApi.java index de28e442dc8a..d878d52e56b7 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/TestStemApi.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/TestStemApi.java @@ -47,6 +47,7 @@ import edu.internet2.middleware.grouper.attr.finder.AttributeDefFinder; import edu.internet2.middleware.grouper.attr.finder.AttributeDefNameFinder; import edu.internet2.middleware.grouper.audit.AuditEntry; +import edu.internet2.middleware.grouper.audit.AuditTypeBuiltin; import edu.internet2.middleware.grouper.cfg.GrouperConfig; import edu.internet2.middleware.grouper.entity.Entity; import edu.internet2.middleware.grouper.entity.EntityFinder; @@ -123,7 +124,7 @@ public TestStemApi(String name) { * @param args */ public static void main(String[] args) { - TestRunner.run(new TestStemApi("test_copy_stem_inherit_privileges")); + TestRunner.run(new TestStemApi("testStemCreateEditDeleteAudit")); } /** size before getting started */ @@ -1305,6 +1306,42 @@ public void testStemMoveAudit() throws Exception { } + /** + * @throws Exception + */ + public void testStemCreateEditDeleteAudit() throws Exception { + R r = R.populateRegistry(0, 0, 2); + Subject a = r.getSubject("a"); + Subject b = r.getSubject("b"); + + HibernateSession.bySqlStatic().executeSql("delete from grouper_audit_entry"); + int newAuditCount = -1; + + int auditCount = HibernateSession.bySqlStatic().select(int.class, + "select count(1) from grouper_audit_entry"); + + this.top_new = this.root.addChildStem("top new", "top new display name"); + + newAuditCount = HibernateSession.bySqlStatic().select(int.class, + "select count(1) from grouper_audit_entry"); + + assertEquals("Should have added exactly one audit", auditCount+1, newAuditCount); + + AuditEntry auditEntry = HibernateSession.byHqlStatic() + .createQuery("from AuditEntry").uniqueResult(AuditEntry.class); + + assertTrue("contextId should exist", StringUtils.isNotBlank(auditEntry.getContextId())); + assertTrue("durationMicros should exist", auditEntry.getDurationMicroseconds() > 0); + assertTrue("query count should exist, and be at least 2: " + auditEntry.getQueryCount(), 2 <= auditEntry.getQueryCount()); + + assertEquals("Context id's should match", auditEntry.getContextId(), top_new.getContextId()); + + assertEquals(AuditTypeBuiltin.STEM_ADD.getAuditCategory(), auditEntry.getAuditType().getAuditCategory()); + assertEquals(AuditTypeBuiltin.STEM_ADD.getActionName(), auditEntry.getAuditType().getActionName()); + + + } + /** * @throws Exception */ diff --git a/grouper/src/test/edu/internet2/middleware/grouper/TestStemFinder.java b/grouper/src/test/edu/internet2/middleware/grouper/TestStemFinder.java index aa8711450d4a..ac3b24b46ea7 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/TestStemFinder.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/TestStemFinder.java @@ -74,7 +74,7 @@ public class TestStemFinder extends GrouperTest { * @param args */ public static void main(String[] args) { - TestRunner.run(new TestStemFinder("testFindByNameSecure")); + TestRunner.run(new TestStemFinder("testChainingStemFinderExcludingAlternateNames")); } // Private Class Constants @@ -844,5 +844,31 @@ public void testFindAllByApproximateName_whenUpperCaseInRegistry() { } } // public void testFindAllByApproximateName_whenUpperCaseInRegistry + public void testChainingStemFinderExcludingAlternateNames() { + GrouperSession grouperSession = GrouperSession.startRootSession(); + Stem stem = new StemSave(grouperSession).assignName("stem-name").assignCreateParentStemsIfNotExist(true).save(); + stem.addAlternateName("stem-alternate"); + stem.store(); + + Set foundStems = new StemFinder().assignScope("stem-n%").findStems(); + assertEquals("find 1 stem by name with scope", foundStems.size(), 1); + assertContainsStem(foundStems, stem, "Found correct stem by name with scope"); + + foundStems = new StemFinder().assignScope("stem-a%").findStems(); + assertEquals("find 1 stem by alternate name with scope", foundStems.size(), 1); + assertContainsStem(foundStems, stem, "Found correct stem by name with scope"); + + foundStems = new StemFinder().assignScope("bogus%").findStems(); + assertEquals("find 0 stems with non-existent name with scope", foundStems.size(), 0); + + /* When excluding alternate name in finder, should find by name but not alternate name */ + foundStems = new StemFinder().assignScope("stem-n%").assignExcludeAlternateNames(true).findStems(); + assertEquals("find 1 stem by name with scope excluding alternate name", foundStems.size(), 1); + assertContainsStem(foundStems, stem, "Found correct stem by name with scope excluding alternate name"); + + foundStems = new StemFinder().assignScope("stem-a%").assignExcludeAlternateNames(true).findStems(); + assertEquals("find 0 stems by alternate name with scope excluding alternate name", foundStems.size(), 0); + } + } diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/azure/AzureProvisionerTestConfigInput.java b/grouper/src/test/edu/internet2/middleware/grouper/app/azure/AzureProvisionerTestConfigInput.java index 800bae1f8805..ea54aa6cb299 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/azure/AzureProvisionerTestConfigInput.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/azure/AzureProvisionerTestConfigInput.java @@ -9,6 +9,20 @@ * */ public class AzureProvisionerTestConfigInput { + + private String displayNameMapping = "name"; + + + + public String getDisplayNameMapping() { + return displayNameMapping; + } + + + public AzureProvisionerTestConfigInput assignDisplayNameMapping(String displayNameMapping) { + this.displayNameMapping = displayNameMapping; + return this; + } /** * extra config by suffix and value diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/azure/AzureProvisionerTestUtils.java b/grouper/src/test/edu/internet2/middleware/grouper/app/azure/AzureProvisionerTestUtils.java index 89949aa0ebd9..32731db96456 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/azure/AzureProvisionerTestUtils.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/azure/AzureProvisionerTestUtils.java @@ -64,7 +64,7 @@ public static void configureAzureProvisioner(AzureProvisionerTestConfigInput pro configureProvisionerSuffix(provisioningTestConfigInput, "azureExternalSystemConfigId", "myAzure"); configureProvisionerSuffix(provisioningTestConfigInput, "class", "edu.internet2.middleware.grouper.app.azure.GrouperAzureProvisioner"); - configureProvisionerSuffix(provisioningTestConfigInput, "common.subjectLink.memberFromId2", "${subject.getAttributeValue('email')}"); + configureProvisionerSuffix(provisioningTestConfigInput, "debugLog", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "deleteEntities", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "deleteEntitiesIfNotExistInGrouper", "true"); @@ -99,15 +99,31 @@ public static void configureAzureProvisioner(AzureProvisionerTestConfigInput pro configureProvisionerSuffix(provisioningTestConfigInput, "showProvisioningDiagnostics", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "subjectSourcesToProvision", "jdbc"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.name", "id"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCacheHas", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0source", "grouper"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0type", "subjectTranslationScript"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0translationScript", "${subject.getAttributeValue('email')}"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2type", "entityAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2entityAttribute", "id"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.name", "accountEnabled"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateExpression", "${'true'}"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateExpressionType", "translationScript"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.matchingId", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.name", "displayName"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.searchAttribute", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.translateExpressionType", "grouperProvisioningEntityField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.translateFromGrouperProvisioningEntityField", "name"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttribute0name", "displayName"); + + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.name", "mailNickname"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.translateExpressionType", "grouperProvisioningEntityField"); @@ -118,23 +134,45 @@ public static void configureAzureProvisioner(AzureProvisionerTestConfigInput pro } configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.name", "userPrincipalName"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateExpression", "${gcGrouperSyncMember.memberFromId2}"); +// configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateExpressionType", "grouperProvisioningEntityField"); +// configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateFromGrouperProvisioningEntityField", "name"); + + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateExpression", "${gcGrouperSyncMember.getEntityAttributeValueCache0()}"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateExpressionType", "translationScript"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.name", "id"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.matchingId", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2type", "groupAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2groupAttribute", "id"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0type", "groupAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0groupAttribute", "displayName"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.name", "displayName"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.searchAttribute", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "name"); + + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", provisioningTestConfigInput.getDisplayNameMapping()); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttribute0name", "displayName"); + + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.name", "mailEnabled"); if (provisioningTestConfigInput.getGroupAttributeCount() == 5) { configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateExpression", "${'true'}"); } else { configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateExpression", "${'false'}"); } + + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.showAttributeCrud", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateExpressionType", "translationScript"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.update", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.showAttributeCrud", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.insert", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.name", "mailNickname"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.select", "true"); @@ -145,6 +183,7 @@ public static void configureAzureProvisioner(AzureProvisionerTestConfigInput pro configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.translateFromGrouperProvisioningGroupField", "extension"); } configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.update", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.showAttributeCrud", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.insert", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.name", "securityEnabled"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.select", "true"); @@ -158,18 +197,21 @@ public static void configureAzureProvisioner(AzureProvisionerTestConfigInput pro configureProvisionerSuffix(provisioningTestConfigInput, "allowOnlyMembersToPost", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "resourceProvisioningOptionsTeams", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "hideGroupInOutlook", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.showAttributeCrud", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.insert", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.name", "allowOnlyMembersToPost"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.select", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.translateExpression", "${grouperUtil.defaultString(grouperProvisioningGroup.retrieveAttributeValueString('md_grouper_allowOnlyMembersToPost'), 'false')}"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.translateExpressionType", "translationScript"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.update", "false"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.6.showAttributeCrud", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.6.insert", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.6.name", "welcomeEmailDisabled"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.6.select", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.6.translateExpression", "${'true'}"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.6.translateExpressionType", "translationScript"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.6.update", "false"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.7.showAttributeCrud", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.7.insert", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.7.name", "resourceProvisioningOptionsTeams"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.7.select", "true"); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/azure/GrouperAzureProvisionerTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/azure/GrouperAzureProvisionerTest.java index 6f268a6920dd..0fe9e09ce4b8 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/azure/GrouperAzureProvisionerTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/azure/GrouperAzureProvisionerTest.java @@ -26,15 +26,21 @@ import edu.internet2.middleware.grouper.helper.SubjectTestHelper; import edu.internet2.middleware.grouper.hibernate.HibernateSession; import edu.internet2.middleware.grouper.misc.GrouperStartup; +import edu.internet2.middleware.grouper.misc.SaveMode; import edu.internet2.middleware.grouper.util.CommandLineExec; import edu.internet2.middleware.grouper.util.GrouperUtil; import edu.internet2.middleware.grouperClient.jdbc.GcDbAccess; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSync; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncDao; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncGroup; +import junit.textui.TestRunner; public class GrouperAzureProvisionerTest extends GrouperTest { + + public static void main(String[] args) { + TestRunner.run(new GrouperAzureProvisionerTest("testFullSyncAzureDisplayName")); + } public GrouperAzureProvisionerTest(String name) { super(name); @@ -140,7 +146,135 @@ public void testFullSyncAzure() { GcGrouperSyncGroup gcGrouperSyncGroup = gcGrouperSync.getGcGrouperSyncGroupDao().groupRetrieveByGroupId(testGroup.getId()); assertEquals(testGroup.getId(), gcGrouperSyncGroup.getGroupId()); assertEquals(testGroup.getName(), gcGrouperSyncGroup.getGroupName()); - assertEquals(grouperAzureGroup.getId(), gcGrouperSyncGroup.getGroupToId2()); + assertEquals(grouperAzureGroup.getId(), gcGrouperSyncGroup.getGroupAttributeValueCache2()); + + + //now remove one of the subjects from the testGroup + testGroup.deleteMember(SubjectTestHelper.SUBJ1); + + // now run the full sync again and the member should be deleted from mock_azure_membership also + grouperProvisioner = GrouperProvisioner.retrieveProvisioner("myAzureProvisioner"); + grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); + assertEquals(1, HibernateSession.byHqlStatic().createQuery("from GrouperAzureGroup").list(GrouperAzureGroup.class).size()); + assertEquals(2, HibernateSession.byHqlStatic().createQuery("from GrouperAzureUser").list(GrouperAzureUser.class).size()); + assertEquals(1, HibernateSession.byHqlStatic().createQuery("from GrouperAzureMembership").list(GrouperAzureMembership.class).size()); + + //now add one subject + testGroup.addMember(SubjectTestHelper.SUBJ3); + + // now run the full sync again + grouperProvisioner = GrouperProvisioner.retrieveProvisioner("myAzureProvisioner"); + grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); + assertEquals(1, HibernateSession.byHqlStatic().createQuery("from GrouperAzureGroup").list(GrouperAzureGroup.class).size()); + assertEquals(3, HibernateSession.byHqlStatic().createQuery("from GrouperAzureUser").list(GrouperAzureUser.class).size()); + assertEquals(2, HibernateSession.byHqlStatic().createQuery("from GrouperAzureMembership").list(GrouperAzureMembership.class).size()); + + //now delete the group and sync again + testGroup.delete(); + + grouperProvisioner = GrouperProvisioner.retrieveProvisioner("myAzureProvisioner"); + grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); + + assertEquals(0, HibernateSession.byHqlStatic().createQuery("from GrouperAzureGroup").list(GrouperAzureGroup.class).size()); + assertEquals(3, HibernateSession.byHqlStatic().createQuery("from GrouperAzureUser").list(GrouperAzureUser.class).size()); + assertEquals(0, HibernateSession.byHqlStatic().createQuery("from GrouperAzureMembership").list(GrouperAzureMembership.class).size()); + + } finally { + + } + + } + + public void testFullSyncAzureDisplayName() { + + GrouperStartup.startup(); + + if (startTomcat) { + CommandLineExec commandLineExec = tomcatStart(); + } + + try { + AzureProvisionerTestUtils.configureAzureProvisioner( + new AzureProvisionerTestConfigInput().assignGroupAttributeCount(8).assignDisplayNameMapping("displayName")); + + // this will create tables + List grouperAzureGroups = GrouperAzureApiCommands.retrieveAzureGroups("myAzure"); + + new GcDbAccess().connectionName("grouper").sql("delete from mock_azure_membership").executeSql(); + new GcDbAccess().connectionName("grouper").sql("delete from mock_azure_group").executeSql(); + new GcDbAccess().connectionName("grouper").sql("delete from mock_azure_user").executeSql(); + + GrouperSession grouperSession = GrouperSession.startRootSession(); + + Stem stem = new StemSave(grouperSession).assignName("test").save(); + Stem stem2 = new StemSave(grouperSession).assignName("test2").save(); + + // mark some folders to provision + Group testGroup = new GroupSave(grouperSession).assignName("test:testGroup").save(); + Group testGroup2 = new GroupSave(grouperSession).assignName("test2:testGroup2").save(); + + testGroup.addMember(SubjectTestHelper.SUBJ0, false); + testGroup.addMember(SubjectTestHelper.SUBJ1, false); + + testGroup2.addMember(SubjectTestHelper.SUBJ2, false); + testGroup2.addMember(SubjectTestHelper.SUBJ3, false); + + final GrouperProvisioningAttributeValue attributeValue = new GrouperProvisioningAttributeValue(); + attributeValue.setDirectAssignment(true); + attributeValue.setDoProvision("myAzureProvisioner"); + attributeValue.setTargetName("myAzureProvisioner"); + attributeValue.setStemScopeString("sub"); + Map metadataNameValues = new HashMap(); + metadataNameValues.put("md_grouper_allowOnlyMembersToPost", true); + metadataNameValues.put("md_grouper_resourceProvisioningOptionsTeams", true); + attributeValue.setMetadataNameValues(metadataNameValues); + + GrouperProvisioningService.saveOrUpdateProvisioningAttributes(attributeValue, stem); + + //lets sync these over + GrouperProvisioner grouperProvisioner = GrouperProvisioner.retrieveProvisioner("myAzureProvisioner"); + + assertEquals(new Integer(0), new GcDbAccess().connectionName("grouper").sql("select count(1) from mock_azure_group").select(int.class)); + + assertEquals(0, HibernateSession.byHqlStatic().createQuery("from GrouperAzureGroup").list(GrouperAzureGroup.class).size()); + + GrouperProvisioningOutput grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); + assertTrue(1 <= grouperProvisioningOutput.getInsert()); + assertEquals(1, HibernateSession.byHqlStatic().createQuery("from GrouperAzureGroup").list(GrouperAzureGroup.class).size()); + assertEquals(2, HibernateSession.byHqlStatic().createQuery("from GrouperAzureUser").list(GrouperAzureUser.class).size()); + assertEquals(2, HibernateSession.byHqlStatic().createQuery("from GrouperAzureMembership").list(GrouperAzureMembership.class).size()); + GrouperAzureGroup grouperAzureGroup = HibernateSession.byHqlStatic().createQuery("from GrouperAzureGroup").list(GrouperAzureGroup.class).get(0); + + assertTrue(GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers()) > 0); + + for (ProvisioningGroupWrapper provisioningGroupWrapper: grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningGroupWrappers()) { + assertTrue(provisioningGroupWrapper.isRecalc()); + } + + assertTrue(GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningEntityWrappers()) > 0); + + for (ProvisioningEntityWrapper provisioningEntityWrapper: grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningEntityWrappers()) { + assertTrue(provisioningEntityWrapper.isRecalc()); + } + + assertTrue(GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningMembershipWrappers()) > 0); + + for (ProvisioningMembershipWrapper provisioningMembershipWrapper: grouperProvisioner.retrieveGrouperProvisioningData().getProvisioningMembershipWrappers()) { + assertTrue(provisioningMembershipWrapper.isRecalc()); + } + + assertEquals("test:testGroup", grouperAzureGroup.getDisplayName()); + assertEquals("T", grouperAzureGroup.getResourceBehaviorOptionsAllowOnlyMembersToPostDb()); + assertEquals("T", grouperAzureGroup.getResourceBehaviorOptionsWelcomeEmailDisabledDb()); + assertEquals("T", grouperAzureGroup.getResourceProvisioningOptionsTeamsDb()); + + GcGrouperSync gcGrouperSync = GcGrouperSyncDao.retrieveByProvisionerName(null, "myAzureProvisioner"); + assertEquals(1, gcGrouperSync.getGroupCount().intValue()); + + GcGrouperSyncGroup gcGrouperSyncGroup = gcGrouperSync.getGcGrouperSyncGroupDao().groupRetrieveByGroupId(testGroup.getId()); + assertEquals(testGroup.getId(), gcGrouperSyncGroup.getGroupId()); + assertEquals(testGroup.getName(), gcGrouperSyncGroup.getGroupName()); + assertEquals(grouperAzureGroup.getId(), gcGrouperSyncGroup.getGroupAttributeValueCache2()); //now remove one of the subjects from the testGroup @@ -163,6 +297,19 @@ public void testFullSyncAzure() { assertEquals(3, HibernateSession.byHqlStatic().createQuery("from GrouperAzureUser").list(GrouperAzureUser.class).size()); assertEquals(2, HibernateSession.byHqlStatic().createQuery("from GrouperAzureMembership").list(GrouperAzureMembership.class).size()); + // now edit the group + new GroupSave().assignUuid(testGroup.getUuid()).assignDisplayExtension("newDisplayExtension").assignReplaceAllSettings(false).save(); + + grouperProvisioner = GrouperProvisioner.retrieveProvisioner("myAzureProvisioner"); + grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); + + assertEquals(1, HibernateSession.byHqlStatic().createQuery("from GrouperAzureGroup").list(GrouperAzureGroup.class).size()); + assertEquals(3, HibernateSession.byHqlStatic().createQuery("from GrouperAzureUser").list(GrouperAzureUser.class).size()); + assertEquals(2, HibernateSession.byHqlStatic().createQuery("from GrouperAzureMembership").list(GrouperAzureMembership.class).size()); + + GrouperAzureGroup azureGroup = HibernateSession.byHqlStatic().createQuery("from GrouperAzureGroup").list(GrouperAzureGroup.class).get(0); + assertEquals("newDisplayExtension", azureGroup.getDisplayName()); + //now delete the group and sync again testGroup.delete(); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/duo/DuoProvisionerTestUtils.java b/grouper/src/test/edu/internet2/middleware/grouper/app/duo/DuoProvisionerTestUtils.java index 6bb7dc838206..d2fd4d219b3d 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/duo/DuoProvisionerTestUtils.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/duo/DuoProvisionerTestUtils.java @@ -62,7 +62,10 @@ public static void configureDuoProvisioner(DuoProvisionerTestConfigInput provisi configureProvisionerSuffix(provisioningTestConfigInput, "hasTargetEntityLink", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "hasTargetGroupLink", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "insertEntities", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "customizeEntityCrud", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "makeChangesToEntities", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "customizeGroupCrud", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "insertGroups", "true"); @@ -76,24 +79,41 @@ public static void configureDuoProvisioner(DuoProvisionerTestConfigInput provisi configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperMemberships", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "provisioningType", "membershipObjects"); configureProvisionerSuffix(provisioningTestConfigInput, "selectEntities", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "selectAllEntities", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "selectGroups", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "selectMemberships", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "showAdvanced", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "subjectSourcesToProvision", "jdbc"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.matchingId", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.name", "loginId"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.searchAttribute", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateExpressionType", "grouperProvisioningEntityField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateFromGrouperProvisioningEntityField", "subjectId"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttribute0name", "loginId"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.name", "id"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateToMemberSyncField", "memberToId2"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2type", "entityAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2entityAttribute", "id"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.name", "id"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.matchingId", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2type", "groupAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2groupAttribute", "id"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.name", "name"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.searchAttribute", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "extension"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttribute0name", "name"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.name", "description"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateFromGrouperProvisioningGroupField", "description"); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/duo/GrouperDuoProvisionerTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/duo/GrouperDuoProvisionerTest.java index 64aba51c8d93..3c83355a8dcb 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/duo/GrouperDuoProvisionerTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/duo/GrouperDuoProvisionerTest.java @@ -12,7 +12,6 @@ import edu.internet2.middleware.grouper.GrouperSession; import edu.internet2.middleware.grouper.Stem; import edu.internet2.middleware.grouper.StemSave; -import edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig; import edu.internet2.middleware.grouper.app.loader.GrouperLoaderStatus; import edu.internet2.middleware.grouper.app.loader.db.Hib3GrouperLoaderLog; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioner; @@ -20,9 +19,6 @@ import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningOutput; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningService; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningType; -import edu.internet2.middleware.grouper.app.provisioning.ProvisioningConsumer; -import edu.internet2.middleware.grouper.cfg.GrouperConfig; -import edu.internet2.middleware.grouper.cfg.dbConfig.GrouperDbConfig; import edu.internet2.middleware.grouper.changeLog.ChangeLogHelper; import edu.internet2.middleware.grouper.changeLog.ChangeLogTempToEntity; import edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbConsumer; @@ -32,7 +28,6 @@ import edu.internet2.middleware.grouper.misc.GrouperStartup; import edu.internet2.middleware.grouper.util.CommandLineExec; import edu.internet2.middleware.grouper.util.GrouperUtil; -import edu.internet2.middleware.grouperClient.config.ConfigPropertiesCascadeBase; import edu.internet2.middleware.grouperClient.jdbc.GcDbAccess; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSync; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncDao; @@ -43,7 +38,7 @@ public class GrouperDuoProvisionerTest extends GrouperTest { public static void main(String[] args) { GrouperStartup.startup(); - TestRunner.run(new GrouperDuoProvisionerTest("testFullProvisionGroupAndThenDeleteTheGroup")); + TestRunner.run(new GrouperDuoProvisionerTest("testFullProvisionLoadEntitiesIntoDuoUsersTable")); } public GrouperDuoProvisionerTest(String name) { @@ -349,7 +344,7 @@ public void testFullProvisionGroupAndThenDeleteTheGroup() { GcGrouperSyncGroup gcGrouperSyncGroup = gcGrouperSync.getGcGrouperSyncGroupDao().groupRetrieveByGroupId(testGroup.getId()); assertEquals(testGroup.getId(), gcGrouperSyncGroup.getGroupId()); assertEquals(testGroup.getName(), gcGrouperSyncGroup.getGroupName()); - assertEquals(grouperDuoGroup.getGroup_id(), gcGrouperSyncGroup.getGroupToId2()); + assertEquals(grouperDuoGroup.getGroup_id(), gcGrouperSyncGroup.getGroupAttributeValueCache2()); //now remove one of the subjects from the testGroup testGroup.deleteMember(SubjectTestHelper.SUBJ1); @@ -358,7 +353,7 @@ public void testFullProvisionGroupAndThenDeleteTheGroup() { grouperProvisioner = GrouperProvisioner.retrieveProvisioner("myDuoProvisioner"); grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); assertEquals(1, HibernateSession.byHqlStatic().createQuery("from GrouperDuoGroup").list(GrouperDuoGroup.class).size()); - assertEquals(2, HibernateSession.byHqlStatic().createQuery("from GrouperDuoUser").list(GrouperDuoUser.class).size()); + assertEquals(1, HibernateSession.byHqlStatic().createQuery("from GrouperDuoUser").list(GrouperDuoUser.class).size()); assertEquals(1, HibernateSession.byHqlStatic().createQuery("from GrouperDuoMembership").list(GrouperDuoMembership.class).size()); //now delete the group and sync again @@ -369,7 +364,7 @@ public void testFullProvisionGroupAndThenDeleteTheGroup() { //assertEquals(1, grouperProvisioningOutput.getDelete()); assertEquals(0, HibernateSession.byHqlStatic().createQuery("from GrouperDuoGroup").list(GrouperDuoGroup.class).size()); - assertEquals(2, HibernateSession.byHqlStatic().createQuery("from GrouperDuoUser").list(GrouperDuoUser.class).size()); + assertEquals(0, HibernateSession.byHqlStatic().createQuery("from GrouperDuoUser").list(GrouperDuoUser.class).size()); assertEquals(0, HibernateSession.byHqlStatic().createQuery("from GrouperDuoMembership").list(GrouperDuoMembership.class).size()); } finally { @@ -390,7 +385,8 @@ public void testFullProvisionLoadEntitiesIntoDuoUsersTable() { return; } - DuoProvisionerTestUtils.configureDuoProvisioner(new DuoProvisionerTestConfigInput()); + DuoProvisionerTestUtils.configureDuoProvisioner(new DuoProvisionerTestConfigInput() + .addExtraConfig("loadEntitiesToGrouperTable", "true")); GrouperStartup.startup(); if (startTomcat) { @@ -550,7 +546,7 @@ public void testIncrementalProvisionDuo() { runJobs(true, true); assertEquals(1, HibernateSession.byHqlStatic().createQuery("from GrouperDuoGroup").list(GrouperDuoGroup.class).size()); - assertEquals(2, HibernateSession.byHqlStatic().createQuery("from GrouperDuoUser").list(GrouperDuoUser.class).size()); + assertEquals(1, HibernateSession.byHqlStatic().createQuery("from GrouperDuoUser").list(GrouperDuoUser.class).size()); assertEquals(1, HibernateSession.byHqlStatic().createQuery("from GrouperDuoMembership").list(GrouperDuoMembership.class).size()); //now delete the group and sync again @@ -560,7 +556,7 @@ public void testIncrementalProvisionDuo() { //assertEquals(1, grouperProvisioningOutput.getDelete()); assertEquals(0, HibernateSession.byHqlStatic().createQuery("from GrouperDuoGroup").list(GrouperDuoGroup.class).size()); - assertEquals(2, HibernateSession.byHqlStatic().createQuery("from GrouperDuoUser").list(GrouperDuoUser.class).size()); + assertEquals(0, HibernateSession.byHqlStatic().createQuery("from GrouperDuoUser").list(GrouperDuoUser.class).size()); assertEquals(0, HibernateSession.byHqlStatic().createQuery("from GrouperDuoMembership").list(GrouperDuoMembership.class).size()); } finally { diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/duo/role/AllDuoRoleProvisionerTests.java b/grouper/src/test/edu/internet2/middleware/grouper/app/duo/role/AllDuoRoleProvisionerTests.java index 50fcf06bc45b..deede85faeba 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/duo/role/AllDuoRoleProvisionerTests.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/duo/role/AllDuoRoleProvisionerTests.java @@ -1,6 +1,5 @@ package edu.internet2.middleware.grouper.app.duo.role; -import edu.internet2.middleware.grouper.app.duo.AllDuoProvisionerTests; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/duo/role/DuoRoleProvisionerTestUtils.java b/grouper/src/test/edu/internet2/middleware/grouper/app/duo/role/DuoRoleProvisionerTestUtils.java index fafb23f21f21..0ddd2d53f832 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/duo/role/DuoRoleProvisionerTestUtils.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/duo/role/DuoRoleProvisionerTestUtils.java @@ -5,6 +5,7 @@ import edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningType; import edu.internet2.middleware.grouper.app.provisioning.ProvisioningConsumer; +import edu.internet2.middleware.grouper.cfg.GrouperConfig; import edu.internet2.middleware.grouper.cfg.dbConfig.GrouperDbConfig; import edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbConsumer; import edu.internet2.middleware.grouperClient.config.ConfigPropertiesCascadeBase; @@ -27,6 +28,21 @@ private static void configureProvisionerSuffix(DuoRoleProvisionerTestConfigInput } } + public static void setupDuoRoleExternalSystem() { + + int port = GrouperConfig.retrieveConfig().propertyValueInt("junit.test.tomcat.port", 8080); + boolean ssl = GrouperConfig.retrieveConfig().propertyValueBoolean("junit.test.tomcat.ssl", false); + //ssl = true; + String domainName = GrouperConfig.retrieveConfig().propertyValueString("junit.test.tomcat.domainName", "localhost"); + + new GrouperDbConfig().configFileName("grouper.properties").propertyName("grouper.duoConnector.duo1.adminDomainName").value(domainName+":"+port+"/grouper/mockServices/duoRole").store(); + new GrouperDbConfig().configFileName("grouper.properties").propertyName("grouper.duoConnector.duo1.adminIntegrationKey").value("DI3GFYRTLYKA0J3E3U1H").store(); + new GrouperDbConfig().configFileName("grouper.properties").propertyName("grouper.duoConnector.duo1.adminSecretKey").value("PxtwEr5XxxpGHYxj39vQnmjtPKEq1G1rurdwH7N5").store(); + new GrouperDbConfig().configFileName("grouper.properties").propertyName("grouper.duoConnector.duo1.useSsl").value(ssl ? "true":"false").store(); + new GrouperDbConfig().configFileName("grouper.properties").propertyName("grouperTest.duo.mock.configId").value("duo1").store(); + + } + /** * @param provisioningTestConfigInput * DuoRoleProvisionerTestUtils.configureDuoRoleProvisioner( @@ -37,64 +53,87 @@ private static void configureProvisionerSuffix(DuoRoleProvisionerTestConfigInput */ public static void configureDuoRoleProvisioner(DuoRoleProvisionerTestConfigInput provisioningTestConfigInput) { - configureProvisionerSuffix(provisioningTestConfigInput, "class", "edu.internet2.middleware.grouper.app.duo.GrouperDuoProvisioner"); + configureProvisionerSuffix(provisioningTestConfigInput, "class", "edu.internet2.middleware.grouper.app.duo.role.GrouperDuoRoleProvisioner"); configureProvisionerSuffix(provisioningTestConfigInput, "debugLog", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "deleteGroups", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "deleteGroupsIfNotExistInGrouper", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "deleteMemberships", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "deleteMembershipsIfNotExistInGrouper", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "duoExternalSystemConfigId", "duo1"); configureProvisionerSuffix(provisioningTestConfigInput, "hasTargetEntityLink", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "hasTargetGroupLink", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "deleteEntities", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "deleteEntitiesIfGrouperDeleted", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "insertEntities", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "customizeGroupCrud", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "insertGroups", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "customizeMembershipCrud", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "customizeEntityCrud", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "makeChangesToEntities", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "selectGroups", "false"); + configureProvisionerSuffix(provisioningTestConfigInput, "insertMemberships", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "logAllObjectsVerbose", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "numberOfEntityAttributes", "2"); - configureProvisionerSuffix(provisioningTestConfigInput, "numberOfGroupAttributes", "3"); + configureProvisionerSuffix(provisioningTestConfigInput, "numberOfEntityAttributes", "4"); + configureProvisionerSuffix(provisioningTestConfigInput, "numberOfGroupAttributes", "1"); configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperEntities", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperGroups", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperMemberships", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "provisioningType", "membershipObjects"); + configureProvisionerSuffix(provisioningTestConfigInput, "provisioningType", "entityAttributes"); configureProvisionerSuffix(provisioningTestConfigInput, "selectEntities", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "selectGroups", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "selectAllEntities", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "selectMemberships", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "showAdvanced", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "subjectSourcesToProvision", "jdbc"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.matchingId", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.name", "loginId"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.searchAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateExpressionType", "grouperProvisioningEntityField"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateFromGrouperProvisioningEntityField", "subjectId"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.name", "id"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateToMemberSyncField", "memberToId2"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.name", "id"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.select", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.showAttributeCrud", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.insert", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.matchingId", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.name", "name"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.searchAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.select", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "extension"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.update", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.showAttributeCrud", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.insert", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.name", "description"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.select", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateExpressionType", "grouperProvisioningGroupField"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateFromGrouperProvisioningGroupField", "description"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.update", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.showAttributeCrud", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "updateEntities", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "updateGroups", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.name", "email"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateExpressionType", "translationScript"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateExpression", "grouperProvisioningEntity.retrieveAttributeValueString('md_grouper_duoEmail')"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.showAdvancedAttribute", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.showAttributeValidation", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.required", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttribute0name", "email"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0source", "grouper"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0type", "entityAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0entityAttribute", "email"); + + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.name", "name"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "name"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.showAdvancedAttribute", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.showAttributeValidation", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.required", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.name", "id"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2type", "entityAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2entityAttribute", "id"); + + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.name", "role"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.showAdvancedAttribute", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.showAttributeValidation", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.required", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityMembershipAttributeName", "role"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityMembershipAttributeValue", "groupAttributeValueCache0"); + + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.name", "role"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpressionType", "translationScript"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpression", "grouperProvisioningGroup.retrieveAttributeValueString('md_grouper_duoRoles')"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.showAdvancedAttribute", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.showAttributeValidation", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.required", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0source", "grouper"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0type", "groupAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0groupAttribute", "role"); + configureProvisionerSuffix(provisioningTestConfigInput, "customizeGroupCrud", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "customizeMembershipCrud", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "customizeEntityCrud", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "makeChangesToEntities", "true"); + + for (String key: provisioningTestConfigInput.getExtraConfig().keySet()) { String theValue = provisioningTestConfigInput.getExtraConfig().get(key); if (!StringUtils.isBlank(theValue)) { diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/duo/role/GrouperDuoRoleProvisionerTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/duo/role/GrouperDuoRoleProvisionerTest.java index 281a4cbe64ec..64853707d1cd 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/duo/role/GrouperDuoRoleProvisionerTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/duo/role/GrouperDuoRoleProvisionerTest.java @@ -52,7 +52,7 @@ public static void main(String[] args) { public void setUp() { super.setUp(); - DuoProvisionerTestUtils.setupDuoExternalSystem(); + DuoRoleProvisionerTestUtils.setupDuoRoleExternalSystem(); try { GrouperDuoRoleApiCommands.retrieveDuoAdministrators("duo1"); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/google/GoogleProvisionerTestUtils.java b/grouper/src/test/edu/internet2/middleware/grouper/app/google/GoogleProvisionerTestUtils.java index 71610e629fc2..821c08ed6272 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/google/GoogleProvisionerTestUtils.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/google/GoogleProvisionerTestUtils.java @@ -74,7 +74,6 @@ public static void configureGoogleProvisioner(GoogleProvisionerTestConfigInput p configureProvisionerSuffix(provisioningTestConfigInput, "allowWebPosting", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "class", "edu.internet2.middleware.grouper.app.google.GrouperGoogleProvisioner"); - configureProvisionerSuffix(provisioningTestConfigInput, "common.subjectLink.memberFromId2", "${subject.getAttributeValue('email')}"); configureProvisionerSuffix(provisioningTestConfigInput, "debugLog", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "deleteEntities", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "deleteEntitiesIfGrouperDeleted", "true"); @@ -112,24 +111,47 @@ public static void configureGoogleProvisioner(GoogleProvisionerTestConfigInput p configureProvisionerSuffix(provisioningTestConfigInput, "showProvisioningDiagnostics", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "subjectSourcesToProvision", "jdbc"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.name", "id"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCacheHas", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0source", "grouper"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0type", "subjectTranslationScript"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0translationScript", "${subject.getAttributeValue('email')}"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2type", "entityAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2entityAttribute", "id"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.name", "givenName"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "name"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.name", "familyName"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.translateExpressionType", "grouperProvisioningEntityField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.translateFromGrouperProvisioningEntityField", "name"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.matchingId", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.name", "email"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.translateExpression", "${grouperProvisioningEntity.getId() + '@viveksachdeva.com'}"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.translateExpressionType", "translationScript"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttribute0name", "email"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.name", "id"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.matchingId", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2type", "groupAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2groupAttribute", "id"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.name", "name"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.searchAttribute", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "name"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttribute0name", "name"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.name", "description"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateFromGrouperProvisioningGroupField", "description"); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/google/GrouperGoogleProvisionerTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/google/GrouperGoogleProvisionerTest.java index 364113920e57..fbaaf9cfc317 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/google/GrouperGoogleProvisionerTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/google/GrouperGoogleProvisionerTest.java @@ -136,7 +136,7 @@ public void testIncrementalSyncGoogle() throws IOException { GcGrouperSyncGroup gcGrouperSyncGroup = gcGrouperSync.getGcGrouperSyncGroupDao().groupRetrieveByGroupId(testGroup.getId()); assertEquals(testGroup.getId(), gcGrouperSyncGroup.getGroupId()); assertEquals(testGroup.getName(), gcGrouperSyncGroup.getGroupName()); - assertEquals(grouperGoogleGroup.getId(), gcGrouperSyncGroup.getGroupToId2()); + assertEquals(grouperGoogleGroup.getId(), gcGrouperSyncGroup.getGroupAttributeValueCache2()); //now remove one of the subjects from the testGroup @@ -283,7 +283,7 @@ public void testFullSyncGoogle() throws IOException { GcGrouperSyncGroup gcGrouperSyncGroup = gcGrouperSync.getGcGrouperSyncGroupDao().groupRetrieveByGroupId(testGroup.getId()); assertEquals(testGroup.getId(), gcGrouperSyncGroup.getGroupId()); assertEquals(testGroup.getName(), gcGrouperSyncGroup.getGroupName()); - assertEquals(grouperGoogleGroup.getId(), gcGrouperSyncGroup.getGroupToId2()); + assertEquals(grouperGoogleGroup.getId(), gcGrouperSyncGroup.getGroupAttributeValueCache2()); //now remove one of the subjects from the testGroup diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerBushyTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerBushyTest.java index b174ae183dc3..b9f42e4fc973 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerBushyTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerBushyTest.java @@ -40,7 +40,7 @@ public class LdapProvisionerBushyTest extends GrouperTest { * @param args */ public static void main(String[] args) { - TestRunner.run(new LdapProvisionerBushyTest("testIncrementalLdapBushyWithCNName")); + TestRunner.run(new LdapProvisionerBushyTest("testIncrementalLdapBushy")); } public LdapProvisionerBushyTest() { @@ -122,8 +122,12 @@ private void runFullJob() { public void testFullLdapBushy() { LdapProvisionerTestUtils.configureLdapProvisioner( - new LdapProvisionerTestConfigInput() + new LdapProvisionerTestConfigInput() + .assignGroupAttributeCount(6) + .assignEntityAttributeCount(2) .assignGroupDnTypeBushy(true) + .assignTranslateFromGrouperProvisioningGroupField("extension") + .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") .assignUpdateGroupsAndDn(true)); Stem testStem = new StemSave(this.grouperSession).assignName("test").save(); @@ -365,9 +369,16 @@ public void testIncrementalLdapBushy() { LdapProvisionerTestUtils.configureLdapProvisioner(new LdapProvisionerTestConfigInput() .assignGroupDnTypeBushy(true) + .assignTranslateFromGrouperProvisioningGroupField("extension") + .assignGroupAttributeCount(6) + .assignEntityAttributeCount(2) + .assignGroupDnTranslate(false) .assignExplicitFilters(true) + .addExtraConfig("logCommandsAlways", "true") + .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") .assignUpdateGroupsAndDn(true)); + ConfigPropertiesCascadeBase.clearCache(); Stem testStem = new StemSave(this.grouperSession).assignName("test").save(); @@ -613,8 +624,12 @@ public void testFullLdapBushyWithCNName() { LdapProvisionerTestUtils.configureLdapProvisioner( new LdapProvisionerTestConfigInput() .assignGroupDnTypeBushy(true) + .assignTranslateFromGrouperProvisioningGroupField("name") .assignExplicitFilters(true) - .assignUpdateGroupsAndDn(true)); + .assignUpdateGroupsAndDn(true) + .addExtraConfig("logCommandsAlways", "true") + .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") + ); ConfigPropertiesCascadeBase.clearCache(); @@ -858,7 +873,9 @@ public void testIncrementalLdapBushyWithCNName() { LdapProvisionerTestUtils.configureLdapProvisioner( new LdapProvisionerTestConfigInput() .assignGroupDnTypeBushy(true) + .assignTranslateFromGrouperProvisioningGroupField("name") .assignExplicitFilters(true) + .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") .assignUpdateGroupsAndDn(true)); ConfigPropertiesCascadeBase.clearCache(); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerDiagnosticsTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerDiagnosticsTest.java index 4e1812827383..a146950eaab0 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerDiagnosticsTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerDiagnosticsTest.java @@ -40,7 +40,7 @@ public class LdapProvisionerDiagnosticsTest extends GrouperTest { * @param args */ public static void main(String[] args) { - TestRunner.run(new LdapProvisionerDiagnosticsTest("testGroupAndMembershipWithoutEntitiesInsertAndDelete")); + TestRunner.run(new LdapProvisionerDiagnosticsTest("testEntityAndMembershipInsertAndDelete")); } public LdapProvisionerDiagnosticsTest() { @@ -79,6 +79,7 @@ protected void setUp() { public static void setupLdap() { LdapProvisionerTestUtils.stopAndRemoveLdapContainer(); LdapProvisionerTestUtils.startLdapContainer(); + } /** @@ -344,6 +345,7 @@ public void testGroupAndMembershipWithoutEntitiesInsertAndDelete() { .assignEntityAttributeCount(0) .assignSubjectSourcesToProvision("jdbc") .assignGroupDnTypeBushy(true) + .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") .assignTranslateFromGrouperProvisioningGroupField("extension") ); @@ -570,10 +572,18 @@ public void testEntityAndMembershipInsertAndDelete() { .assignGroupAttributeCount(1) .assignUpdateEntitiesAndDn(true) .assignInsertEntityAndAttributes(true) - .assignEntityAttributeCount(6) + .assignEntityDeleteType("deleteEntitiesIfNotExistInGrouper") + .assignEntityAttributeCount(7) + .assignSubjectSourcesToProvision("jdbc") + .addExtraConfig("logCommandsAlways", "true") .addExtraConfig("targetGroupAttribute.0.translateExpression", "${'someprefix:' + grouperProvisioningGroup.name}") ); - + + { + GrouperProvisioningOutput grouperProvisioningOutput = GrouperProvisioner.retrieveProvisioner("ldapProvTest").provision(GrouperProvisioningType.fullProvisionFull); + assertEquals(0, grouperProvisioningOutput.getRecordsWithErrors()); + } + Stem testStem = new StemSave(this.grouperSession).assignName("test").save(); final GrouperProvisioningAttributeValue attributeValue = new GrouperProvisioningAttributeValue(); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerIncrementalTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerIncrementalTest.java index 3b4d502bbeb3..1f7caccc3b44 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerIncrementalTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerIncrementalTest.java @@ -118,7 +118,6 @@ public void testIncremental1() { LdapProvisionerTestUtils.configureLdapProvisioner( new LdapProvisionerTestConfigInput() - .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") .assignExplicitFilters(true)); @@ -246,7 +245,6 @@ public void testIncremental2() { LdapProvisionerTestUtils.configureLdapProvisioner( new LdapProvisionerTestConfigInput() - .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") .assignExplicitFilters(true) .assignUpdateGroupsAndDn(true)); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerJDBCSubjectSourceTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerJDBCSubjectSourceTest.java index e8503227e160..6682ddfb9c15 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerJDBCSubjectSourceTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerJDBCSubjectSourceTest.java @@ -55,7 +55,7 @@ public class LdapProvisionerJDBCSubjectSourceTest extends GrouperTest { * @param args */ public static void main(String[] args) { - TestRunner.run(new LdapProvisionerJDBCSubjectSourceTest("testFullCreateUsersSubjectIdentifier2")); + TestRunner.run(new LdapProvisionerJDBCSubjectSourceTest("testIncrementalDoNotCreateUsers")); } public LdapProvisionerJDBCSubjectSourceTest() { @@ -415,6 +415,7 @@ public void testFullCreateUsers() { .assignMembershipAttribute("description") .assignEntityUidTranslateFromGrouperProvisioningEntityField("subjectIdentifier0") .assignInsertEntityAndAttributes(true) + .assignEntityDnTranslate(false) .assignExplicitFilters(true) .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") .assignBusinessCategoryTranslateFromGrouperProvisioningGroupField("id") @@ -792,6 +793,7 @@ public void testFullCreateUsersSubjectIdentifier1() { .assignUpdateGroupsAndDn(true) .assignEntityAttributeCount(6) .assignInsertEntityAndAttributes(true) + .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") .assignSubjectSourcesToProvision("jdbc") .assignEntityUidTranslateFromGrouperProvisioningEntityField("subjectIdentifier1") .assignBusinessCategoryTranslateFromGrouperProvisioningGroupField("id") diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerTestConfigInput.java b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerTestConfigInput.java index 97a4ad158dc8..963d9a05ebe6 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerTestConfigInput.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerTestConfigInput.java @@ -7,6 +7,19 @@ public class LdapProvisionerTestConfigInput { + private boolean groupAttributeValueCache2dn = true; + + + + public boolean isGroupAttributeValueCache2dn() { + return groupAttributeValueCache2dn; + } + + public LdapProvisionerTestConfigInput assignGroupAttributeValueCache2dn(boolean groupAttributeValueCache2dn) { + this.groupAttributeValueCache2dn = groupAttributeValueCache2dn; + return this; + } + /** * if allow dn override with config (default false) */ @@ -122,6 +135,52 @@ public LdapProvisionerTestConfigInput assignMembershipStructureEntityAttributes( return this; } + /** + * set to false to have grouper auto translate the dn + */ + private boolean entityDnTranslate = true; + + /** + * set to false to have grouper auto translate the dn + * @return + */ + public boolean isEntityDnTranslate() { + return entityDnTranslate; + } + + /** + * set to false to have grouper auto translate the dn + * @param entityDnTranslate + * @return + */ + public LdapProvisionerTestConfigInput assignEntityDnTranslate(boolean entityDnTranslate) { + this.entityDnTranslate = entityDnTranslate; + return this; + } + + /** + * set to false to have grouper auto translate the dn + */ + private boolean groupDnTranslate = true; + + /** + * set to false to have grouper auto translate the dn + * @return + */ + public boolean isGroupDnTranslate() { + return groupDnTranslate; + } + + /** + * set to false to have grouper auto translate the dn + * @param groupDnTranslate + * @return + */ + public LdapProvisionerTestConfigInput assignGroupDnTranslate(boolean groupDnTranslate) { + this.groupDnTranslate = groupDnTranslate; + return this; + } + /** * groupDnType flat (default) or bushy */ @@ -192,15 +251,57 @@ public LdapProvisionerTestConfigInput assignUpdateEntitiesAndDn(boolean updateEn /** * groupDeleteType e.g. deleteGroupsIfNotExistInGrouper or deleteGroupsIfGrouperDeleted or deleteGroupsIfGrouperCreated or null (default) */ - private String groupDeleteType; + private String groupDeleteType; + + /** + * entityDeleteType e.g. deleteEntitiesIfNotExistInGrouper or deleteEntitiesIfGrouperDeleted or deleteEntitiesIfGrouperCreated or null (default) + */ + private String entityDeleteType; + + /** + * entityDeleteType e.g. deleteEntitiesIfNotExistInGrouper or deleteEntitiesIfGrouperDeleted or deleteEntitiesIfGrouperCreated or null (default) + * @return + */ + public String getEntityDeleteType() { + return entityDeleteType; + } + + /** + * entityDeleteType e.g. deleteEntitiesIfNotExistInGrouper or deleteEntitiesIfGrouperDeleted or deleteEntitiesIfGrouperCreated or null (default) + * @param entityDeleteType + */ + public LdapProvisionerTestConfigInput assignEntityDeleteType(String entityDeleteType) { + this.entityDeleteType = entityDeleteType; + return this; + } + + /** + * membershipDeleteType e.g. deleteMembershipsIfNotExistInGrouper (default) or deleteMembershipsIfGrouperDeleted or deleteMembershipsIfGrouperCreated or null + */ + private String membershipDeleteType = "deleteMembershipsIfNotExistInGrouper"; + public String getMembershipDeleteType() { + return membershipDeleteType; + } + /** * groupDeleteType e.g. deleteGroupsIfNotExistInGrouper or deleteGroupsIfGrouperDeleted or deleteGroupsIfGrouperCreated or null (default) */ public String getGroupDeleteType() { return groupDeleteType; } + + + /** + * membershipDeleteType e.g. deleteMembershipsIfNotExistInGrouper or deleteMembershipsIfGrouperDeleted or deleteMembershipsIfGrouperCreated or null (default) + * @param membershipDeleteType + * @return this for chaining + */ + public LdapProvisionerTestConfigInput assignMembershipDeleteType(String membershipDeleteType) { + this.membershipDeleteType = membershipDeleteType; + return this; + } /** * groupDeleteType e.g. deleteGroupsIfNotExistInGrouper or deleteGroupsIfGrouperDeleted or deleteGroupsIfGrouperCreated or null (default) @@ -348,14 +449,14 @@ public LdapProvisionerTestConfigInput assignInsertEntityAndAttributes(boolean in } /** - * 0, 2 (default), 3 or 6 (if has extended entity attributes + * 0, 2 (default), 3 or 6, or 7 (if has extended entity attributes */ public int getEntityAttributeCount() { return entityAttributeCount; } /** - * 0, 2 (default), 3 or 6 (if has extended entity attributes + * 0, 2 (default), 3 or 6, or 7 (if has extended entity attributes */ public LdapProvisionerTestConfigInput assignEntityAttributeCount(int entityAttributeCount) { this.entityAttributeCount = entityAttributeCount; @@ -422,7 +523,7 @@ public LdapProvisionerTestConfigInput assignEntitlementMetadata(boolean entitlem } /** - * 0, 2 (default), 3 or 6 (if has extended entity attributes + * 0, 2 (default), 3 or 6, or 7 (if has extended entity attributes */ private int entityAttributeCount = 2; diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerTestUtils.java b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerTestUtils.java index c925f2074476..e49ab3f53b82 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerTestUtils.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerTestUtils.java @@ -4,13 +4,12 @@ import org.apache.commons.lang.StringUtils; -import edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig; +import edu.internet2.middleware.grouper.GrouperSession; import edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningType; import edu.internet2.middleware.grouper.app.provisioning.ProvisioningConsumer; import edu.internet2.middleware.grouper.cfg.dbConfig.GrouperDbConfig; import edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbConsumer; import edu.internet2.middleware.grouper.ldap.LdapSessionUtils; -import edu.internet2.middleware.grouper.misc.GrouperStartup; import edu.internet2.middleware.grouper.util.CommandLineExec; import edu.internet2.middleware.grouper.util.GrouperUtil; import edu.internet2.middleware.grouperClient.config.ConfigPropertiesCascadeBase; @@ -23,6 +22,10 @@ public class LdapProvisionerTestUtils { public static void main(String args[]) throws Exception { + GrouperSession.startRootSession(); + stopAndRemoveLdapContainer(); + startLdapContainer(); + setupSubjectSource(); } private static String dockerPath = null; @@ -207,6 +210,7 @@ private static void configureProvisionerSuffix(LdapProvisionerTestConfigInput ld * .assignSubjectSourcesToProvision("jdbc") * .assignEntitlementMetadata(true) * .addExtraConfig("allowProvisionableRegexOverride", "true") + * .addExtraConfig("logCommandsAlways", "true") * */ public static void configureLdapProvisioner(LdapProvisionerTestConfigInput provisioningTestConfigInput) { @@ -215,15 +219,22 @@ public static void configureLdapProvisioner(LdapProvisionerTestConfigInput provi && !StringUtils.equals("description", provisioningTestConfigInput.getMembershipAttribute())) { throw new RuntimeException("Expecting member or description but was '" + provisioningTestConfigInput.getMembershipAttribute() + "'"); } - if (0 != provisioningTestConfigInput.getEntityAttributeCount() && 2 != provisioningTestConfigInput.getEntityAttributeCount() && 3 != provisioningTestConfigInput.getEntityAttributeCount() && 6 != provisioningTestConfigInput.getEntityAttributeCount()) { - throw new RuntimeException("Expecting 0, 2 or 6 for entityAttributeCount but was '" + provisioningTestConfigInput.getEntityAttributeCount() + "'"); + if (0 != provisioningTestConfigInput.getEntityAttributeCount() && 2 != provisioningTestConfigInput.getEntityAttributeCount() + && 3 != provisioningTestConfigInput.getEntityAttributeCount() && 6 != provisioningTestConfigInput.getEntityAttributeCount() + && 7 != provisioningTestConfigInput.getEntityAttributeCount()) { + throw new RuntimeException("Expecting 0, 2, 3, 6, or 7 for entityAttributeCount but was '" + provisioningTestConfigInput.getEntityAttributeCount() + "'"); } if (provisioningTestConfigInput.isPosixGroup() && !StringUtils.equals(provisioningTestConfigInput.getBusinessCategoryTranslateFromGrouperProvisioningGroupField(), "idIndex")) { throw new RuntimeException("Cant be posix and business category"); } if (provisioningTestConfigInput.getGroupAttributeCount() > 0) { - configureProvisionerSuffix(provisioningTestConfigInput, "numberOfGroupAttributes", "" + provisioningTestConfigInput.getGroupAttributeCount() + ""); + if (provisioningTestConfigInput.getGroupAttributeCount() == 6 && StringUtils.equals(provisioningTestConfigInput.getMembershipAttribute(), "description") + && provisioningTestConfigInput.isPosixGroup()) { + configureProvisionerSuffix(provisioningTestConfigInput, "numberOfGroupAttributes", "5"); + } else { + configureProvisionerSuffix(provisioningTestConfigInput, "numberOfGroupAttributes", "" + provisioningTestConfigInput.getGroupAttributeCount() + ""); + } if (provisioningTestConfigInput.getGroupAttributeCount() == 1) { @@ -236,40 +247,57 @@ public static void configureLdapProvisioner(LdapProvisionerTestConfigInput provi "${grouperUtil.defaultIfBlank(grouperProvisioningGroup.retrieveAttributeValueString('md_entitlementValue') , grouperProvisioningGroup." + provisioningTestConfigInput.getTranslateFromGrouperProvisioningGroupField() + " )}"); } else { - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", provisioningTestConfigInput.getTranslateFromGrouperProvisioningGroupField()); - + if (!GrouperUtil.nonNull(provisioningTestConfigInput.getExtraConfig()).containsKey("targetGroupAttribute.0.translateExpression")) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", provisioningTestConfigInput.getTranslateFromGrouperProvisioningGroupField()); + } else { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpressionType", "translationScript"); + } } - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateGrouperToGroupSyncField", "groupFromId2"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0source", "grouper"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0type", "groupAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0groupAttribute", "entitlement"); } else { configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.name", "ldap_dn"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpressionType", provisioningTestConfigInput.isDnOverrideScript() ? "translationScript" : "grouperProvisioningGroupField"); - if (provisioningTestConfigInput.isDnOverrideScript()) { - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpression", - "${grouperUtil.defaultString(grouperProvisioningGroup.retrieveAttributeValueString('md_grouper_ldapGroupDnOverride'), 'cn=' + edu.internet2.middleware.grouper.util.GrouperUtil.ldapEscapeRdnValue(grouperProvisioningGroup." - + provisioningTestConfigInput.getTranslateFromGrouperProvisioningGroupField() + ") + ',ou=Groups,dc=example,dc=edu')}"); - } else { - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", - provisioningTestConfigInput.getTranslateFromGrouperProvisioningGroupField()); + if (provisioningTestConfigInput.isGroupDnTranslate()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpressionType", provisioningTestConfigInput.isDnOverrideScript() ? "translationScript" : "grouperProvisioningGroupField"); + String dnAttribute = provisioningTestConfigInput.isGroupDnTypeBushy() ? "name" : provisioningTestConfigInput.getTranslateFromGrouperProvisioningGroupField(); + if (provisioningTestConfigInput.isDnOverrideScript()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpression", + "${grouperUtil.defaultString(grouperProvisioningGroup.retrieveAttributeValueString('md_grouper_ldapGroupDnOverride'), 'cn=' + edu.internet2.middleware.grouper.util.GrouperUtil.ldapEscapeRdnValue(grouperProvisioningGroup." + + dnAttribute + ") + ',ou=Groups,dc=example,dc=edu')}"); + } else { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", + dnAttribute); + } + } + if (provisioningTestConfigInput.isGroupAttributeValueCache2dn()) { + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2type", "groupAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2groupAttribute", "ldap_dn"); } - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); - - + String attributeName = provisioningTestConfigInput.isPosixGroup() ? "gidNumber" : "businessCategory"; configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.name", - provisioningTestConfigInput.isPosixGroup() ? "gidNumber" : "businessCategory"); + attributeName); if (StringUtils.equals(provisioningTestConfigInput.getBusinessCategoryTranslateFromGrouperProvisioningGroupField(), "idIndex")) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.showAdvancedAttribute", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.showAttributeValueSettings", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.valueType", "long"); } - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.matchingId", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.searchAttribute", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", provisioningTestConfigInput.getBusinessCategoryTranslateFromGrouperProvisioningGroupField()); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttribute0name", attributeName); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.name", "cn"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateExpressionType", provisioningTestConfigInput.isDnOverrideScript() ? "translationScript" : "grouperProvisioningGroupField"); @@ -280,39 +308,49 @@ public static void configureLdapProvisioner(LdapProvisionerTestConfigInput provi + provisioningTestConfigInput.getTranslateFromGrouperProvisioningGroupField() + ") + ',ou=Groups,dc=example,dc=edu'))}"); } else { configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateFromGrouperProvisioningGroupField", - provisioningTestConfigInput.isGroupDnTypeBushy() ? "extension" : provisioningTestConfigInput.getTranslateFromGrouperProvisioningGroupField()); + provisioningTestConfigInput.getTranslateFromGrouperProvisioningGroupField()); } configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.name", "objectClass"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.showAdvancedAttribute", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.showAttributeValueSettings", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.multiValued", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.translateExpressionType", "translationScript"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.translateExpression", "${grouperUtil.toSet('top', '" + (provisioningTestConfigInput.isPosixGroup() ? "posixGroup" : "groupOfNames") + "')}"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.name", "member"); if (StringUtils.equals(provisioningTestConfigInput.getMembershipAttribute(), "member")) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.name", "member"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.showAdvancedAttribute", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.showAttributeValueSettings", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.showAttributeValueSettings", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.multiValued", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.membershipAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.translateFromMemberSyncField", provisioningTestConfigInput.getEntityAttributeCount() > 0 ? "memberToId2" : "subjectId"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMembershipAttributeName", "member"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMembershipAttributeValue", provisioningTestConfigInput.getEntityAttributeCount() > 0 ? "entityAttributeValueCache2" : "subjectId"); + + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.name", "description"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.translateExpressionType", "grouperProvisioningGroupField"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.translateFromGrouperProvisioningGroupField", "description"); + + } else if (StringUtils.equals(provisioningTestConfigInput.getMembershipAttribute(), "description")) { + + + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.name", "description"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMembershipAttributeName", "description"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMembershipAttributeValue", provisioningTestConfigInput.getEntityAttributeCount() > 0 ? "entityAttributeValueCache2" : "subjectId"); + + if (!provisioningTestConfigInput.isPosixGroup()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.name", "member"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.translateExpressionType", "translationScript"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.translateExpression", "'cn' + '=' + 'somethingbogussincethisisrequired'"); + + } + } else { - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.translateExpressionType", "translationScript"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.translateExpression", "'cn' + '=' + 'somethingbogussincethisisrequired'"); + throw new RuntimeException("Not expecting membershipAttribute: '" + provisioningTestConfigInput.getMembershipAttribute() + "'"); } - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.name", "description"); - if (StringUtils.equals(provisioningTestConfigInput.getMembershipAttribute(), "description")) { - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.showAttributeValueSettings", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.multiValued", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.membershipAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.translateFromMemberSyncField", provisioningTestConfigInput.getEntityAttributeCount() > 0 ? "memberToId2" : "subjectId"); - } else { - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.translateExpressionType", "grouperProvisioningGroupField"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.translateFromGrouperProvisioningGroupField", "description"); - } } } @@ -321,57 +359,114 @@ public static void configureLdapProvisioner(LdapProvisionerTestConfigInput provi configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.name", "ldap_dn"); if (provisioningTestConfigInput.isInsertEntityAndAttributes()) { - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateExpressionTypeCreateOnly", "translationScript"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateExpressionCreateOnly", "${'uid=' + grouperProvisioningEntity.retrieveAttributeValueString('" - + provisioningTestConfigInput.getEntityUidTranslateFromGrouperProvisioningEntityField() + "') + ',ou=People,dc=example,dc=edu'}"); + + configureProvisionerSuffix(provisioningTestConfigInput, "userRdnAttribute", "uid"); + + if (provisioningTestConfigInput.isEntityDnTranslate()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.showAdvancedAttribute", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateExpressionTypeCreateOnly", "translationScript"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateExpressionCreateOnly", "${'uid=' + grouperProvisioningEntity.retrieveAttributeValueString('" + + provisioningTestConfigInput.getEntityUidTranslateFromGrouperProvisioningEntityField() + "') + ',ou=People,dc=example,dc=edu'}"); + } } - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2type", "entityAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2entityAttribute", "ldap_dn"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.name", "uid"); if (provisioningTestConfigInput.isInsertEntityAndAttributes()) { + + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.showAdvancedAttribute", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.showAttributeValidation", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.required", "true"); } - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.matchingId", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.searchAttribute", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", provisioningTestConfigInput.getEntityUidTranslateFromGrouperProvisioningEntityField()); + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttribute0name", "uid"); + if (provisioningTestConfigInput.getEntityAttributeCount() > 2) { if (!provisioningTestConfigInput.isMembershipStructureEntityAttributes() || provisioningTestConfigInput.getEntityAttributeCount() > 3) { configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.name", "sn"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.translateExpressionTypeCreateOnly", "translationScript"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.translateExpressionCreateOnly", "'something'"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.showAdvancedAttribute", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.translateExpressionType", "translationScript"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.translateExpression", "'something'"); + + if (provisioningTestConfigInput.isInsertEntityAndAttributes()) { + + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.showAdvancedAttribute", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.showAttributeValidation", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.required", "true"); + } + } } - if (provisioningTestConfigInput.getEntityAttributeCount() == 6) { + if (provisioningTestConfigInput.getEntityAttributeCount() >= 6) { configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.name", "cn"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.translateExpressionTypeCreateOnly", "translationScript"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.translateExpressionCreateOnly", "'something'"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.showAdvancedAttribute", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.translateExpressionType", "translationScript"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.translateExpression", "'something'"); + + if (provisioningTestConfigInput.isInsertEntityAndAttributes()) { + + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.showAdvancedAttribute", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.showAttributeValidation", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.required", "true"); + } + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.name", "givenName"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateExpressionTypeCreateOnly", "staticValues"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateFromStaticValuesCreateOnly", "something"); - - if (!provisioningTestConfigInput.isMembershipStructureEntityAttributes()) { - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.5.name", "objectClass"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.5.showAttributeValueSettings", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.5.multiValued", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.5.translateExpressionTypeCreateOnly", "staticValues"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.5.translateFromStaticValuesCreateOnly", "top, organizationalPerson, person, inetOrgPerson, eduPerson"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.showAdvancedAttribute", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateExpressionType", "staticValues"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateFromStaticValues", "something"); + + if (provisioningTestConfigInput.isInsertEntityAndAttributes()) { + + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.showAdvancedAttribute", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.showAttributeValidation", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.required", "true"); + } + + } + if (provisioningTestConfigInput.getEntityAttributeCount() >= 6) { + int objectClassIndex = -1; + if (!provisioningTestConfigInput.isMembershipStructureEntityAttributes() && provisioningTestConfigInput.getEntityAttributeCount() == 6) { + objectClassIndex = 5; + } + if (provisioningTestConfigInput.getEntityAttributeCount() >= 7) { + objectClassIndex = 6; + } + if (objectClassIndex != -1) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + objectClassIndex + ".name", "objectClass"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + objectClassIndex + ".showAdvancedAttribute", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + objectClassIndex + ".showAttributeValueSettings", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + objectClassIndex + ".multiValued", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + objectClassIndex + ".showAttributeValidation", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + objectClassIndex + ".required", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + objectClassIndex + ".translateExpressionType", "staticValues"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + objectClassIndex + ".translateFromStaticValues", "top, organizationalPerson, person, inetOrgPerson, eduPerson"); + } - + } if (provisioningTestConfigInput.isMembershipStructureEntityAttributes()) { - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + (provisioningTestConfigInput.getEntityAttributeCount()-1) + ".name", "eduPersonEntitlement"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + (provisioningTestConfigInput.getEntityAttributeCount()-1) + ".translateFromGroupSyncField", provisioningTestConfigInput.getGroupAttributeCount() == 1 ? "groupFromId2" : "groupExtension"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + (provisioningTestConfigInput.getEntityAttributeCount()-1) + ".membershipAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + (provisioningTestConfigInput.getEntityAttributeCount()-1) + ".showAttributeValueSettings", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + (provisioningTestConfigInput.getEntityAttributeCount()-1) + ".multiValued", "true"); + int membershipIndex = (provisioningTestConfigInput.getEntityAttributeCount()-1); + if (provisioningTestConfigInput.getEntityAttributeCount() == 7) { + membershipIndex = 5; + } + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute." + membershipIndex + ".name", "eduPersonEntitlement"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityMembershipAttributeName", "eduPersonEntitlement"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityMembershipAttributeValue", provisioningTestConfigInput.getGroupAttributeCount() == 1 ? "groupAttributeValueCache0" : "extension"); + } } @@ -381,8 +476,18 @@ public static void configureLdapProvisioner(LdapProvisionerTestConfigInput provi configureProvisionerSuffix(provisioningTestConfigInput, "subjectSourcesToProvision", provisioningTestConfigInput.getSubjectSourcesToProvision()); if (!StringUtils.isBlank(provisioningTestConfigInput.getGroupDeleteType())) { - configureProvisionerSuffix(provisioningTestConfigInput, "deleteGroups", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, provisioningTestConfigInput.getGroupDeleteType(), "true"); + // this is the default + if (!StringUtils.equals(provisioningTestConfigInput.getGroupDeleteType(), "deleteGroupsIfGrouperCreated")) { + configureProvisionerSuffix(provisioningTestConfigInput, "customizeGroupCrud", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "deleteGroups", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, provisioningTestConfigInput.getGroupDeleteType(), "true"); + } + } else { + if (provisioningTestConfigInput.getGroupAttributeCount() > 0) { + + configureProvisionerSuffix(provisioningTestConfigInput, "customizeGroupCrud", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "deleteGroups", "false"); + } } if (provisioningTestConfigInput.getEntityAttributeCount() > 0) { @@ -391,33 +496,30 @@ public static void configureLdapProvisioner(LdapProvisionerTestConfigInput provi if (provisioningTestConfigInput.getGroupAttributeCount() > 0) { configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperGroups", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "hasTargetGroupLink", "true"); + if (provisioningTestConfigInput.getGroupAttributeCount() > 1) { + configureProvisionerSuffix(provisioningTestConfigInput, "hasTargetGroupLink", "true"); + } } configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperMemberships", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "provisioningType", provisioningTestConfigInput.isMembershipStructureEntityAttributes() ? "entityAttributes" : "groupAttributes"); configureProvisionerSuffix(provisioningTestConfigInput, "selectMemberships", "true"); - if (provisioningTestConfigInput.getGroupAttributeCount() > 0) { + if (provisioningTestConfigInput.getGroupAttributeCount() == 1) { + configureProvisionerSuffix(provisioningTestConfigInput, "selectGroups", "false"); + configureProvisionerSuffix(provisioningTestConfigInput, "insertGroups", "false"); + configureProvisionerSuffix(provisioningTestConfigInput, "updateGroups", "false"); + configureProvisionerSuffix(provisioningTestConfigInput, "deleteGroups", "false"); + + } + if (provisioningTestConfigInput.getGroupAttributeCount() > 1) { configureProvisionerSuffix(provisioningTestConfigInput, "groupDnType", provisioningTestConfigInput.isGroupDnTypeBushy() ? "bushy" : "flat"); configureProvisionerSuffix(provisioningTestConfigInput, "groupSearchBaseDn", "ou=Groups,dc=example,dc=edu"); - configureProvisionerSuffix(provisioningTestConfigInput, "insertGroups", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "customizeGroupCrud", "true"); - } - if (provisioningTestConfigInput.getEntityAttributeCount() > 0) { - if (provisioningTestConfigInput.isInsertEntityAndAttributes()) { - configureProvisionerSuffix(provisioningTestConfigInput, "insertEntities", "true"); - } } configureProvisionerSuffix(provisioningTestConfigInput, "customizeMembershipCrud", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "insertMemberships", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "deleteMemberships", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "deleteMembershipsIfNotExistInGrouper", "true"); - if (provisioningTestConfigInput.getGroupAttributeCount() > 0) { - configureProvisionerSuffix(provisioningTestConfigInput, "selectGroups", "true"); - if (provisioningTestConfigInput.isUpdateGroupsAndDn()) { - configureProvisionerSuffix(provisioningTestConfigInput, "updateGroups", "true"); - } + if (!StringUtils.isBlank(provisioningTestConfigInput.getMembershipDeleteType())) { + configureProvisionerSuffix(provisioningTestConfigInput, provisioningTestConfigInput.getMembershipDeleteType(), "true"); } if (provisioningTestConfigInput.isExplicitFilters()) { @@ -438,13 +540,27 @@ public static void configureLdapProvisioner(LdapProvisionerTestConfigInput provi if (provisioningTestConfigInput.getEntityAttributeCount() > 0) { configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperEntities", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "hasTargetEntityLink", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "selectEntities", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "customizeEntityCrud", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "selectAllEntities", "true"); + + if (provisioningTestConfigInput.isUpdateEntitiesAndDn() || provisioningTestConfigInput.isInsertEntityAndAttributes()) { + configureProvisionerSuffix(provisioningTestConfigInput, "customizeEntityCrud", "true"); + if (!StringUtils.isBlank(provisioningTestConfigInput.getEntityDeleteType())) { + // this is the default + if (!StringUtils.equals(provisioningTestConfigInput.getEntityDeleteType(), "deleteEntitiesIfGrouperCreated")) { + configureProvisionerSuffix(provisioningTestConfigInput, provisioningTestConfigInput.getEntityDeleteType(), "true"); + } + } else { + configureProvisionerSuffix(provisioningTestConfigInput, "deleteEntities", "false"); + } - if (provisioningTestConfigInput.isUpdateEntitiesAndDn()) { - configureProvisionerSuffix(provisioningTestConfigInput, "updateEntities", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "makeChangesToEntities", "true"); } + if (!provisioningTestConfigInput.isUpdateEntitiesAndDn() && provisioningTestConfigInput.isInsertEntityAndAttributes()) { + configureProvisionerSuffix(provisioningTestConfigInput, "updateEntities", "false"); + } + if (provisioningTestConfigInput.isUpdateEntitiesAndDn() && !provisioningTestConfigInput.isInsertEntityAndAttributes()) { + configureProvisionerSuffix(provisioningTestConfigInput, "insertEntities", "false"); + } } if (provisioningTestConfigInput.getGroupAttributeCount() > 0) { @@ -462,6 +578,7 @@ public static void configureLdapProvisioner(LdapProvisionerTestConfigInput provi } + configureProvisionerSuffix(provisioningTestConfigInput, "showAdvanced", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "logAllObjectsVerbose", "true"); for (String key: provisioningTestConfigInput.getExtraConfig().keySet()) { diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerWithGroupAndEntityLinksTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerWithGroupAndEntityLinksTest.java index fcced2243cca..e9f55aef00f5 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerWithGroupAndEntityLinksTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/LdapProvisionerWithGroupAndEntityLinksTest.java @@ -53,7 +53,7 @@ public class LdapProvisionerWithGroupAndEntityLinksTest extends GrouperTest { * @param args */ public static void main(String[] args) { - TestRunner.run(new LdapProvisionerWithGroupAndEntityLinksTest("testIncrementalBushyOUCaseChange")); + TestRunner.run(new LdapProvisionerWithGroupAndEntityLinksTest("testIncrementalDnOverrideBushy")); } public LdapProvisionerWithGroupAndEntityLinksTest() { @@ -644,7 +644,6 @@ public void testDoNotDeleteFull() { LdapProvisionerTestUtils.configureLdapProvisioner( new LdapProvisionerTestConfigInput() .assignUpdateGroupsAndDn(true) - .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") .assignExplicitFilters(true)); Stem stem = new StemSave(this.grouperSession).assignName("test").save(); @@ -705,7 +704,6 @@ public void testDoNotDeleteIncremental() { LdapProvisionerTestUtils.configureLdapProvisioner( new LdapProvisionerTestConfigInput() .assignUpdateGroupsAndDn(true) - .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") .assignExplicitFilters(true)); // initialize @@ -1203,6 +1201,7 @@ public void testDnOverrideTranslationScript() { LdapProvisionerTestUtils.configureLdapProvisioner( new LdapProvisionerTestConfigInput() + .assignGroupDeleteType("deleteGroupsIfGrouperDeleted") .assignDnOverrideScript(true)); new StemSave(this.grouperSession).assignName("test").save(); @@ -1290,6 +1289,7 @@ public void testFullDnOverrideFlat() { LdapProvisionerTestUtils.configureLdapProvisioner( new LdapProvisionerTestConfigInput() .addExtraConfig("groupSearchAllFilter", null) + .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") .assignDnOverrideConfig(true) ); @@ -1555,9 +1555,12 @@ public void testIncrementalDnOverrideFlat() { new LdapProvisionerTestConfigInput() .addExtraConfig("groupSearchAllFilter", null) .assignDnOverrideConfig(true) + .assignGroupDeleteType("deleteGroupsIfGrouperCreated") ); // initialize + GrouperProvisioner grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); + grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); runIncrementalJobs(true, true); new StemSave(this.grouperSession).assignName("test").save(); @@ -1816,6 +1819,7 @@ public void testFullDnCompareOUCase() { .addExtraConfig("groupSearchAllFilter", null) ); + GrouperProvisioner grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); GrouperConfig.retrieveConfig().propertiesOverrideMap().put("provisioningInUi.enable", "true"); @@ -1854,7 +1858,6 @@ public void testFullDnCompareOUCase() { assertEquals(0, LdapSessionUtils.ldapSession().list("personLdap", "ou=Groups,dc=example,dc=edu", LdapSearchScope.SUBTREE_SCOPE, "(objectClass=groupOfNames)", new String[] {"objectClass", "cn", "member", "businessCategory"}, null).size()); - GrouperProvisioner grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); GrouperProvisioningOutput grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); assertEquals(0, grouperProvisioningOutput.getRecordsWithErrors()); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/SimpleLdapProvisionerTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/SimpleLdapProvisionerTest.java index a0f77a578b01..eebabe8dac5d 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/SimpleLdapProvisionerTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/ldapProvisioning/SimpleLdapProvisionerTest.java @@ -66,7 +66,7 @@ public class SimpleLdapProvisionerTest extends GrouperTest { * @param args */ public static void main(String[] args) { - TestRunner.run(new SimpleLdapProvisionerTest("testSimpleLdapProvisionerFullLatestConfig_1")); + TestRunner.run(new SimpleLdapProvisionerTest("testSimpleLdapProvisionerRestrictGroup")); // TestRunner.run(new SimpleLdapProvisionerTest("testSimpleLdapProvisionerFullLegacyConfig_1")); } @@ -237,10 +237,10 @@ public void testSimpleLdapProvisionerFullLatestConfig_1() { assertNull(gcGrouperSyncGroup.getProvisionableEnd()); assertTrue(started < gcGrouperSyncGroup.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncGroup.getLastUpdated().getTime()); - assertEquals("cn=test:testGroup,ou=Groups,dc=example,dc=edu", gcGrouperSyncGroup.getGroupToId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId3()); - assertNull(gcGrouperSyncGroup.getGroupToId3()); + assertEquals("cn=test:testGroup,ou=Groups,dc=example,dc=edu", gcGrouperSyncGroup.getGroupAttributeValueCache2()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache0()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache1()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache3()); assertNull(gcGrouperSyncGroup.getLastGroupMetadataSync()); assertNull(gcGrouperSyncGroup.getErrorMessage()); assertNull(gcGrouperSyncGroup.getErrorTimestamp()); @@ -263,10 +263,10 @@ public void testSimpleLdapProvisionerFullLatestConfig_1() { assertNull(gcGrouperSyncMember.getProvisionableEnd()); assertTrue(started < gcGrouperSyncMember.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getLastUpdated().getTime()); - assertNull(gcGrouperSyncMember.getMemberFromId2()); - assertNull(gcGrouperSyncMember.getMemberFromId3()); - assertNull(gcGrouperSyncMember.getMemberToId2()); - assertNull(gcGrouperSyncMember.getMemberToId3()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache0()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache1()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache2()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache3()); assertNull(gcGrouperSyncMember.getLastUserMetadataSync()); assertNull(gcGrouperSyncMember.getErrorMessage()); assertNull(gcGrouperSyncMember.getErrorTimestamp()); @@ -322,11 +322,11 @@ public void testSimpleLdapProvisionerFullSubjectIdentifier2() { .assignPosixGroup(true) .assignMembershipAttribute("description") .assignEntityAttributeCount(0) - .assignSubjectSourcesToProvision("jdbc")); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.ldapProvTest.subjectIdentifierForMemberSyncTable").value("subjectIdentifier2").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.ldapProvTest.targetGroupAttribute.4.translateFromMemberSyncField").value("subjectIdentifier").store(); - + .assignGroupAttributeValueCache2dn(false) + .assignSubjectSourcesToProvision("jdbc") + .addExtraConfig("subjectIdentifierForMemberSyncTable", "subjectIdentifier2") + .addExtraConfig("groupMembershipAttributeValue", "subjectIdentifier") + ); long started = System.currentTimeMillis(); @@ -437,10 +437,10 @@ public void testSimpleLdapProvisionerFullSubjectIdentifier2() { assertNull(gcGrouperSyncGroup.getProvisionableEnd()); assertTrue(started < gcGrouperSyncGroup.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncGroup.getLastUpdated().getTime()); - assertNull(gcGrouperSyncGroup.getGroupToId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId3()); - assertNull(gcGrouperSyncGroup.getGroupToId3()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache2()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache0()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache1()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache3()); assertNull(gcGrouperSyncGroup.getLastGroupMetadataSync()); assertNull(gcGrouperSyncGroup.getErrorMessage()); assertNull(gcGrouperSyncGroup.getErrorTimestamp()); @@ -463,10 +463,10 @@ public void testSimpleLdapProvisionerFullSubjectIdentifier2() { assertNull(gcGrouperSyncMember.getProvisionableEnd()); assertTrue(started < gcGrouperSyncMember.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getLastUpdated().getTime()); - assertNull(gcGrouperSyncMember.getMemberFromId2()); - assertNull(gcGrouperSyncMember.getMemberFromId3()); - assertNull(gcGrouperSyncMember.getMemberToId2()); - assertNull(gcGrouperSyncMember.getMemberToId3()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache0()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache1()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache2()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache3()); assertNull(gcGrouperSyncMember.getLastUserMetadataSync()); assertNull(gcGrouperSyncMember.getErrorMessage()); assertNull(gcGrouperSyncMember.getErrorTimestamp()); @@ -941,36 +941,52 @@ public void testAddGroupThenRemoveManuallyThenAddAgainUsingProvisioning() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.name", "displayName"); GrouperProvisioner grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); + // init the config + grouperProvisioner.initialize(GrouperProvisioningType.fullProvisionFull); List errorsAndSuffixes = grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); GrouperTextContainer.assignThreadLocalVariable("type", "group"); // provisioning.configuration.validation.dnRequired = Error: ${type} field 'name' is required. It represents the LDAP DN // provisioning.configuration.validation.dnString = Error: ${type} field 'name' is must be value type 'string'. It represents the LDAP DN - assertTrue(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains(new MultiKey(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnRequired"), null))); - assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains(new MultiKey(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnString"), "targetGroupAttribute.0.name"))); - GrouperTextContainer.resetThreadLocalVariableMap(); - + assertTrue(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( + new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnRequired")))); + assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( + new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnString")).assignJqueryHandle("targetGroupAttribute.0.name"))); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.name", "ldap_dn"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.valueType", "int"); grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); + // init the config + grouperProvisioner.initialize(GrouperProvisioningType.fullProvisionFull); + errorsAndSuffixes = grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); GrouperTextContainer.assignThreadLocalVariable("type", "group"); - assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains(new MultiKey(new Object[] {GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnRequired")}))); - assertTrue(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains(new MultiKey(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnString"), "#config_targetGroupAttribute.0.fieldName_spanid"))); + + assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( + new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnRequired")))); + assertTrue(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( + new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnString")).assignJqueryHandle("targetGroupAttribute.0.name"))); + GrouperTextContainer.resetThreadLocalVariableMap(); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.valueType", "string"); grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); + // init the config + grouperProvisioner.initialize(GrouperProvisioningType.fullProvisionFull); errorsAndSuffixes = grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); GrouperTextContainer.assignThreadLocalVariable("type", "group"); - assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains(new MultiKey(new Object[] {GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnRequired")}))); - assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains(new MultiKey(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnString"), "#config_targetGroupAttribute.0.fieldName_spanid"))); + + assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( + new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnRequired")))); + assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( + new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.dnString")).assignJqueryHandle("targetGroupAttribute.0.name"))); + GrouperTextContainer.resetThreadLocalVariableMap(); // end test some config @@ -1054,6 +1070,8 @@ public void testSimpleLdapEntityProvisionerFull() { LdapProvisionerTestUtils.configureLdapProvisioner( new LdapProvisionerTestConfigInput() .assignConfigId("eduPersonEntitlement") + .assignMembershipStructureEntityAttributes(true) + .assignMembershipDeleteType("deleteMembershipsIfGrouperDeleted") .assignGroupAttributeCount(0) .assignEntityAttributeCount(3) .assignExplicitFilters(true) @@ -1185,6 +1203,8 @@ public void testSimpleLdapEntityMetadataProvisionerFull() { new LdapProvisionerTestConfigInput() .assignConfigId("eduPersonEntitlement") .assignTranslateFromGrouperProvisioningGroupField("extension") + .assignMembershipStructureEntityAttributes(true) + .assignMembershipDeleteType("deleteMembershipsIfGrouperDeleted") .assignGroupAttributeCount(1) .assignEntityAttributeCount(3) .assignExplicitFilters(true) @@ -1244,10 +1264,10 @@ public void testSimpleLdapEntityMetadataProvisionerFull() { GrouperProvisioningOutput grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); assertEquals(0, grouperProvisioningOutput.getRecordsWithErrors()); - // see that the entitlement value is on groupFromId2 + // see that the entitlement value is on groupAttributeValueCache0 GcGrouperSync gcGrouperSync = GcGrouperSyncDao.retrieveByProvisionerName(null, "eduPersonEntitlement"); GcGrouperSyncGroup gcGrouperSyncGroup = gcGrouperSync.getGcGrouperSyncGroupDao().groupRetrieveByGroupId(testGroup.getId()); - assertEquals("student", gcGrouperSyncGroup.getGroupFromId2()); + assertEquals("student", gcGrouperSyncGroup.getGroupAttributeValueCache0()); List ldapEntries = LdapSessionUtils.ldapSession().list("personLdap", "ou=People,dc=example,dc=edu", LdapSearchScope.SUBTREE_SCOPE, "(uid=banderson)", new String[] {"eduPersonEntitlement"}, null); @@ -1332,6 +1352,7 @@ public void testSimpleLdapProvisionerRestrictGroup() { .assignPosixGroup(true) .assignMembershipAttribute("description") .assignEntityAttributeCount(0) + .assignGroupAttributeValueCache2dn(false) .assignSubjectSourcesToProvision("jdbc")); long started = System.currentTimeMillis(); @@ -1458,10 +1479,10 @@ public void testSimpleLdapProvisionerRestrictGroup() { assertNull(gcGrouperSyncGroup.getProvisionableEnd()); assertTrue(started < gcGrouperSyncGroup.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncGroup.getLastUpdated().getTime()); - assertNull(gcGrouperSyncGroup.getGroupToId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId3()); - assertNull(gcGrouperSyncGroup.getGroupToId3()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache2()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache0()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache1()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache3()); assertNull(gcGrouperSyncGroup.getLastGroupMetadataSync()); assertNull(gcGrouperSyncGroup.getErrorMessage()); assertNull(gcGrouperSyncGroup.getErrorTimestamp()); @@ -1484,10 +1505,10 @@ public void testSimpleLdapProvisionerRestrictGroup() { assertNull(gcGrouperSyncMember.getProvisionableEnd()); assertTrue(started < gcGrouperSyncMember.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getLastUpdated().getTime()); - assertNull(gcGrouperSyncMember.getMemberFromId2()); - assertNull(gcGrouperSyncMember.getMemberFromId3()); - assertNull(gcGrouperSyncMember.getMemberToId2()); - assertNull(gcGrouperSyncMember.getMemberToId3()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache0()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache1()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache2()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache3()); assertNull(gcGrouperSyncMember.getLastUserMetadataSync()); assertNull(gcGrouperSyncMember.getErrorMessage()); assertNull(gcGrouperSyncMember.getErrorTimestamp()); @@ -1538,6 +1559,7 @@ public void testSimpleLdapProvisionerFullOverrideDn() { .assignPosixGroup(true) .assignMembershipAttribute("description") .assignEntityAttributeCount(0) + .assignGroupAttributeValueCache2dn(false) .assignSubjectSourcesToProvision("jdbc")); long started = System.currentTimeMillis(); @@ -1648,10 +1670,10 @@ public void testSimpleLdapProvisionerFullOverrideDn() { assertNull(gcGrouperSyncGroup.getProvisionableEnd()); assertTrue(started <= gcGrouperSyncGroup.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncGroup.getLastUpdated().getTime()); - assertNull(gcGrouperSyncGroup.getGroupToId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId3()); - assertNull(gcGrouperSyncGroup.getGroupToId3()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache2()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache0()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache1()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache3()); assertNull(gcGrouperSyncGroup.getLastGroupMetadataSync()); assertNull(gcGrouperSyncGroup.getErrorMessage()); assertNull(gcGrouperSyncGroup.getErrorTimestamp()); @@ -1674,10 +1696,10 @@ public void testSimpleLdapProvisionerFullOverrideDn() { assertNull(gcGrouperSyncMember.getProvisionableEnd()); assertTrue(started <= gcGrouperSyncMember.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getLastUpdated().getTime()); - assertNull(gcGrouperSyncMember.getMemberFromId2()); - assertNull(gcGrouperSyncMember.getMemberFromId3()); - assertNull(gcGrouperSyncMember.getMemberToId2()); - assertNull(gcGrouperSyncMember.getMemberToId3()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache0()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache1()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache2()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache3()); assertNull(gcGrouperSyncMember.getLastUserMetadataSync()); assertNull(gcGrouperSyncMember.getErrorMessage()); assertNull(gcGrouperSyncMember.getErrorTimestamp()); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/AllProvisioningTests.java b/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/AllProvisioningTests.java index edf0555d7eda..c82ecbf1d628 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/AllProvisioningTests.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/AllProvisioningTests.java @@ -43,6 +43,7 @@ public static Test suite() { suite.addTestSuite(ProvisionableGroupSaveTest.class); suite.addTestSuite(ProvisionableStemFinderTest.class); suite.addTestSuite(ProvisionableGroupFinderTest.class); + suite.addTestSuite(ProvisioningGroupTest.class); //$JUnit-END$ return suite; } diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningAttributePropagationTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningAttributePropagationTest.java index 43ae691df982..db77e84e8a8d 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningAttributePropagationTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningAttributePropagationTest.java @@ -16,6 +16,8 @@ import edu.internet2.middleware.grouper.Stem; import edu.internet2.middleware.grouper.StemSave; import edu.internet2.middleware.grouper.app.grouperTypes.GrouperObjectTypesDaemonLogic; +import edu.internet2.middleware.grouper.app.ldapProvisioning.LdapProvisionerTestConfigInput; +import edu.internet2.middleware.grouper.app.ldapProvisioning.LdapProvisionerTestUtils; import edu.internet2.middleware.grouper.app.ldapProvisioning.LdapSync; import edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig; import edu.internet2.middleware.grouper.app.loader.GrouperLoaderStatus; @@ -39,7 +41,8 @@ /** * Note that for these tests, we don't care about updates to the target (ldap). We're only looking at the - * provisioning attribute propagation. + * provisioning attribute propagation. + * TODO simply the provisioner config to something minimal * * @author shilen */ @@ -50,7 +53,7 @@ public class GrouperProvisioningAttributePropagationTest extends GrouperTest { * @param args */ public static void main(String[] args) { - TestRunner.run(new GrouperProvisioningAttributePropagationTest("testIncrementalPolicyRestrictionUsingFolder")); + TestRunner.run(new GrouperProvisioningAttributePropagationTest("testFullPolicyRestriction")); } public GrouperProvisioningAttributePropagationTest() { @@ -98,18 +101,25 @@ public void testIncrementalRegexRestriction() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2groupAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAdvancedAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.valueType", "long"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "idIndex"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttribute0name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.name", "cn"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.select", "true"); @@ -125,9 +135,9 @@ public void testIncrementalRegexRestriction() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.name", "member"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeValue", "entityAttributeValueCache2"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.name", "description"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.insert", "true"); @@ -141,15 +151,21 @@ public void testIncrementalRegexRestriction() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.name", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2entityAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.name", "uid"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttribute0name", "uid"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.class", LdapSync.class.getName()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.ldapExternalSystemConfigId", "personLdap"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.subjectSourcesToProvision", "jdbc"); @@ -293,18 +309,24 @@ public void testFullRegexRestriction() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2groupAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAdvancedAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.valueType", "long"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "idIndex"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttribute0name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.name", "cn"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.select", "true"); @@ -320,9 +342,9 @@ public void testFullRegexRestriction() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.name", "member"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeValue", "entityAttributeValueCache2"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.name", "description"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.insert", "true"); @@ -336,15 +358,21 @@ public void testFullRegexRestriction() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.name", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2entityAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.name", "uid"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttribute0name", "uid"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.class", LdapSync.class.getName()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.ldapExternalSystemConfigId", "personLdap"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.subjectSourcesToProvision", "jdbc"); @@ -476,115 +504,17 @@ public void testFullRegexRestriction() { } public void testFullPolicyRestriction() { - - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.numberOfGroupAttributes", "6"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.name", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.insert", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.name", "businessCategory"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAttributeValueSettings", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.valueType", "long"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.insert", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.searchAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "idIndex"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.name", "cn"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.insert", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.translateExpressionType", "grouperProvisioningGroupField"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.translateFromGrouperProvisioningGroupField", "name"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.3.name", "objectClass"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.3.insert", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.3.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.3.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.3.translateExpressionType", "translationScript"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.3.translateExpression", "${grouperUtil.toSet('top', 'groupOfNames')}"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.name", "member"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.name", "description"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.insert", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.update", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.delete", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.translateExpressionType", "grouperProvisioningGroupField"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.translateFromGrouperProvisioningGroupField", "description"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.numberOfEntityAttributes", "2"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.name", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.name", "uid"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.searchAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.class", LdapSync.class.getName()); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.ldapExternalSystemConfigId", "personLdap"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.subjectSourcesToProvision", "jdbc"); - - // ldap specific properties - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.provisioningType", "groupAttributes"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupSearchBaseDn", "ou=Groups,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupSearchAllFilter", "(objectClass=groupOfNames)"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupSearchFilter", "(&(objectClass=groupOfNames)(businessCategory=${targetGroup.retrieveAttributeValue('businessCategory')}))"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.userSearchBaseDn", "ou=People,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.userSearchAllFilter", "(&(objectClass=person)(uid=*))"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.userSearchFilter", "(&(objectClass=person)(uid=${targetEntity.retrieveAttributeValue('uid')}))"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupDnType", "flat"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.operateOnGrouperGroups", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.hasTargetGroupLink", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.selectGroups", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.insertGroups", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.deleteGroups", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.deleteGroupsIfNotExistInGrouper", "true"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.operateOnGrouperEntities", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.hasTargetEntityLink", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.selectEntities", "true"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.operateOnGrouperMemberships", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.provisioningType", "groupAttributes"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.selectMemberships", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.deleteMemberships", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.deleteMembershipsIfNotExistInGrouper", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.insertMemberships", "true"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.logAllObjectsVerbose", "true"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.onlyProvisionPolicyGroups", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.allowPolicyGroupOverride", "true"); - - GrouperConfig.retrieveConfig().propertiesOverrideMap().put("provisioningInUi.enable", "true"); - - // edu.internet2.middleware.grouper.changeLog.esb.consumer - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("changeLog.consumer.junitProvisioningAttributePropagationTestCLC.class", EsbConsumer.class.getName()); - // edu.internet2.middleware.grouper.app.provisioning - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("changeLog.consumer.junitProvisioningAttributePropagationTestCLC.publisher.class", ProvisioningConsumer.class.getName()); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("changeLog.consumer.junitProvisioningAttributePropagationTestCLC.quartzCron", "0 0 5 * * 2000"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("changeLog.consumer.junitProvisioningAttributePropagationTestCLC.provisionerConfigId", "junitProvisioningAttributePropagationTest"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("changeLog.consumer.junitProvisioningAttributePropagationTestCLC.provisionerJobSyncType", GrouperProvisioningType.incrementalProvisionChangeLog.name()); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("changeLog.consumer.junitProvisioningAttributePropagationTestCLC.publisher.debug", "true"); + LdapProvisionerTestUtils.configureLdapProvisioner( + new LdapProvisionerTestConfigInput() + .assignPosixGroup(true) + .assignMembershipAttribute("description") + .assignEntityAttributeCount(0) + .assignSubjectSourcesToProvision("jdbc") + .addExtraConfig("onlyProvisionPolicyGroups", "true") + .addExtraConfig("allowPolicyGroupOverride", "true") + .assignConfigId("junitProvisioningAttributePropagationTest")); + Stem testStem = new StemSave(this.grouperSession).assignName("test").save(); Stem test2Stem = new StemSave(this.grouperSession).assignName("test:test2").save(); new StemSave(this.grouperSession).assignName("anotherStem").save(); @@ -675,18 +605,24 @@ public void testIncrementalPolicyRestriction() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2groupAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAdvancedAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.valueType", "long"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "idIndex"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttribute0name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.name", "cn"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.select", "true"); @@ -702,9 +638,9 @@ public void testIncrementalPolicyRestriction() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.name", "member"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeValue", "entityAttributeValueCache2"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.name", "description"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.insert", "true"); @@ -718,15 +654,21 @@ public void testIncrementalPolicyRestriction() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.name", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2entityAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.name", "uid"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttribute0name", "uid"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.class", LdapSync.class.getName()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.ldapExternalSystemConfigId", "personLdap"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.subjectSourcesToProvision", "jdbc"); @@ -871,18 +813,24 @@ public void testIncrementalPolicyRestrictionUsingFolder() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2groupAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAdvancedAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.valueType", "long"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "idIndex"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttribute0name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.name", "cn"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.select", "true"); @@ -898,9 +846,9 @@ public void testIncrementalPolicyRestrictionUsingFolder() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.name", "member"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeValue", "entityAttributeValueCache2"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.name", "description"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.insert", "true"); @@ -914,15 +862,21 @@ public void testIncrementalPolicyRestrictionUsingFolder() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.name", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2entityAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.name", "uid"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttribute0name", "uid"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.class", LdapSync.class.getName()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.ldapExternalSystemConfigId", "personLdap"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.subjectSourcesToProvision", "jdbc"); @@ -1070,18 +1024,24 @@ public void testIncrementalStemScopeOne() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2groupAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAdvancedAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.valueType", "long"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "idIndex"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttribute0name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.name", "cn"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.select", "true"); @@ -1097,9 +1057,9 @@ public void testIncrementalStemScopeOne() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.name", "member"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeValue", "entityAttributeValueCache2"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.name", "description"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.insert", "true"); @@ -1113,15 +1073,21 @@ public void testIncrementalStemScopeOne() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.name", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2entityAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.name", "uid"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttribute0name", "uid"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.class", LdapSync.class.getName()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.ldapExternalSystemConfigId", "personLdap"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.subjectSourcesToProvision", "jdbc"); @@ -1320,18 +1286,24 @@ public void testFullStemScopeOne() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2groupAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAdvancedAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.valueType", "long"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "idIndex"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttribute0name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.name", "cn"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.select", "true"); @@ -1347,9 +1319,9 @@ public void testFullStemScopeOne() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.name", "member"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeValue", "entityAttributeValueCache2"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.name", "description"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.insert", "true"); @@ -1363,15 +1335,21 @@ public void testFullStemScopeOne() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.name", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2entityAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.name", "uid"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttribute0name", "uid"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.class", LdapSync.class.getName()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.ldapExternalSystemConfigId", "personLdap"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.subjectSourcesToProvision", "jdbc"); @@ -1567,18 +1545,24 @@ public void testIncrementalStemNotProvisionable() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2groupAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAdvancedAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.valueType", "long"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "idIndex"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttribute0name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.name", "cn"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.select", "true"); @@ -1594,9 +1578,9 @@ public void testIncrementalStemNotProvisionable() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.name", "member"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeValue", "entityAttributeValueCache2"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.name", "description"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.insert", "true"); @@ -1609,15 +1593,21 @@ public void testIncrementalStemNotProvisionable() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.name", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2entityAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.name", "uid"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttribute0name", "uid"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.class", LdapSync.class.getName()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.ldapExternalSystemConfigId", "personLdap"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.subjectSourcesToProvision", "jdbc"); @@ -1766,17 +1756,24 @@ public void testFullStemNotProvisionable() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2groupAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAdvancedAttribute", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.valueType", "long"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "idIndex"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttribute0name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.name", "cn"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.select", "true"); @@ -1792,9 +1789,9 @@ public void testFullStemNotProvisionable() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.name", "member"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeValue", "entityAttributeValueCache2"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.name", "description"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.insert", "true"); @@ -1808,15 +1805,21 @@ public void testFullStemNotProvisionable() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.name", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2entityAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.name", "uid"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttribute0name", "uid"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.class", LdapSync.class.getName()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.ldapExternalSystemConfigId", "personLdap"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.subjectSourcesToProvision", "jdbc"); @@ -1961,17 +1964,24 @@ public void testIncrementalDirectToIndirectGroup() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2groupAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAdvancedAttribute", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.valueType", "long"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "idIndex"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttribute0name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.name", "cn"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.select", "true"); @@ -1987,9 +1997,9 @@ public void testIncrementalDirectToIndirectGroup() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.name", "member"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeValue", "entityAttributeValueCache2"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.name", "description"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.insert", "true"); @@ -2003,15 +2013,21 @@ public void testIncrementalDirectToIndirectGroup() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.name", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2entityAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.name", "uid"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttribute0name", "uid"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.class", LdapSync.class.getName()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.ldapExternalSystemConfigId", "personLdap"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.subjectSourcesToProvision", "jdbc"); @@ -2127,17 +2143,24 @@ public void testFullMultipleProvisioners() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.groupAttributeValueCache2groupAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.1.name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.1.showAdvancedAttribute", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.1.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.1.valueType", "long"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.1.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "idIndex"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttribute0name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.2.name", "cn"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.2.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.2.select", "true"); @@ -2153,9 +2176,9 @@ public void testFullMultipleProvisioners() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.4.name", "member"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.4.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.4.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeValue", "entityAttributeValueCache2"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.5.name", "description"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetGroupAttribute.5.insert", "true"); @@ -2169,15 +2192,21 @@ public void testFullMultipleProvisioners() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetEntityAttribute.0.name", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetEntityAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2entityAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetEntityAttribute.1.name", "uid"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetEntityAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetEntityAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetEntityAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttribute0name", "uid"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.class", LdapSync.class.getName()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.ldapExternalSystemConfigId", "personLdap"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest2.subjectSourcesToProvision", "jdbc"); @@ -2230,17 +2259,24 @@ public void testFullMultipleProvisioners() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2groupAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAdvancedAttribute", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.valueType", "long"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "idIndex"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttribute0name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.name", "cn"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.select", "true"); @@ -2256,9 +2292,9 @@ public void testFullMultipleProvisioners() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.name", "member"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeValue", "entityAttributeValueCache2"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.name", "description"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.insert", "true"); @@ -2272,15 +2308,21 @@ public void testFullMultipleProvisioners() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.name", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2entityAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.name", "uid"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttribute0name", "uid"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.class", LdapSync.class.getName()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.ldapExternalSystemConfigId", "personLdap"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.subjectSourcesToProvision", "jdbc"); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLogicTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLogicTest.java index 8ae5f9a961b4..0fc8c41d7439 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLogicTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningLogicTest.java @@ -11,6 +11,11 @@ import edu.internet2.middleware.grouper.util.GrouperUtil; import junit.textui.TestRunner; +/** + * TODO refactor tests for 2.6.9 config + * @author mchyzer + * + */ public class GrouperProvisioningLogicTest extends GrouperTest { /** @@ -66,14 +71,18 @@ public void testConfigurationProvisionerGroupMatchingAttribute() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.subjectSourcesToProvision", "jdbc"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupDnType", "flat"); - //GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("", ""); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.name", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCache2groupAttribute", "name"); GrouperProvisioner grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); @@ -83,7 +92,8 @@ public void testConfigurationProvisionerGroupMatchingAttribute() { errorsAndSuffixes.contains(new ProvisioningValidationIssue() .assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.mustHaveGroupMatchingId")))); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.matchingId", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupMatchingAttribute0name", "name"); grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); errorsAndSuffixes = grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); @@ -112,7 +122,12 @@ public void testConfigurationProvisionerEntityMatchingAttribute() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.0.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.0.translateFromGrouperProvisioningEntityField", "subjectId"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityAttributeValueCache2entityAttribute", "name"); GrouperProvisioner grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); @@ -121,7 +136,8 @@ public void testConfigurationProvisionerEntityMatchingAttribute() { assertTrue(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.mustHaveEntityMatchingId")))); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.0.matchingId", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityMatchingAttribute0name", "name"); grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); errorsAndSuffixes = grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); @@ -151,13 +167,18 @@ public void testConfigurationProvisionerGroupMembershipAttribute() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCache2groupAttribute", "name"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.1.showAttributeValueSettings", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.1.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.1.multiValued", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.1.name", "member"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.1.translateFromMemberSyncField", "memberToId2"); + GrouperProvisioner grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); @@ -166,8 +187,10 @@ public void testConfigurationProvisionerGroupMembershipAttribute() { assertTrue(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.mustHaveGroupMembershipAttribute")))); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.1.membershipAttribute", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupMembershipAttributeValue", "subjectId"); + grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); errorsAndSuffixes = grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); @@ -195,12 +218,16 @@ public void testConfigurationProvisionerEntityMembershipAttribute() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.0.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.0.translateFromGrouperProvisioningEntityField", "subjectId"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityAttributeValueCache2entityAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.1.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.1.multiValued", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.1.name", "member"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.1.translateFromGroupSyncField", "groupToId2"); + GrouperProvisioner grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); @@ -209,7 +236,9 @@ public void testConfigurationProvisionerEntityMembershipAttribute() { assertTrue(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.mustHaveEntityMembershipAttribute")))); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetEntityAttribute.1.membershipAttribute", "true"); + // TODO fix this + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.entityMembershipAttributeValue", "name"); grouperProvisioner = GrouperProvisioner.retrieveProvisioner("ldapProvTest"); errorsAndSuffixes = grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); @@ -240,12 +269,18 @@ public void testConfigurationMetadata() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupAttributeValueCache2groupAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.1.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.1.multiValued", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.1.name", "member"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.1.translateFromMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.groupMembershipAttributeValue", "entityAttributeValueCache2"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.metadata.0.name", "abc"); @@ -337,82 +372,6 @@ public void testConfigurationProvisionerDoingSomething() { assertTrue(errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.doSomething")))); - // provisioner.ldapProvTest.class = edu.internet2.middleware.grouper.app.ldapProvisioning.LdapSync - // provisioner.ldapProvTest.deleteGroups = true - // provisioner.ldapProvTest.deleteGroupsIfNotExistInGrouper = true - // provisioner.ldapProvTest.deleteMemberships = true - // provisioner.ldapProvTest.deleteMembershipsIfNotExistInGrouper = true - // provisioner.ldapProvTest.groupDnType = bushy - // provisioner.ldapProvTest.groupSearchAllFilter = (objectClass=groupOfNames) - // provisioner.ldapProvTest.groupSearchBaseDn = ou=Groups,dc=example,dc=edu - // provisioner.ldapProvTest.groupSearchFilter = (&(objectClass=groupOfNames)(businessCategory=${targetGroup.retrieveAttributeValue('businessCategory')})) - // provisioner.ldapProvTest.hasTargetEntityLink = true - // provisioner.ldapProvTest.hasTargetGroupLink = true - // provisioner.ldapProvTest.insertGroups = true - // provisioner.ldapProvTest.insertMemberships = true - // provisioner.ldapProvTest.logAllObjectsVerbose = true - // provisioner.ldapProvTest.numberOfGroupAttributes = 6 - // provisioner.ldapProvTest.operateOnGrouperEntities = true - // provisioner.ldapProvTest.operateOnGrouperGroups = true - // provisioner.ldapProvTest.operateOnGrouperMemberships = true - // provisioner.ldapProvTest.provisioningType = groupAttributes - // provisioner.ldapProvTest.selectEntities = true - // provisioner.ldapProvTest.selectGroups = true - // provisioner.ldapProvTest.selectMemberships = true - // provisioner.ldapProvTest.subjectSourcesToProvision = personLdapSource - // provisioner.ldapProvTest.targetEntityAttribute.0.fieldName = name - // provisioner.ldapProvTest.targetEntityAttribute.0.select = true - // provisioner.ldapProvTest.targetEntityAttribute.0.translateToMemberSyncField = memberToId2 - // provisioner.ldapProvTest.targetEntityAttribute.1.matchingId = true - // provisioner.ldapProvTest.targetEntityAttribute.1.name = uid - // provisioner.ldapProvTest.targetEntityAttribute.1.searchAttribute = true - // provisioner.ldapProvTest.targetEntityAttribute.1.select = true - // provisioner.ldapProvTest.targetEntityAttribute.1.translateExpressionType = grouperProvisioningEntityField - // provisioner.ldapProvTest.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField = subjectId - // provisioner.ldapProvTest.numberOfEntityAttributes = 2 - // provisioner.ldapProvTest.targetGroupAttribute.0.fieldName = name - // provisioner.ldapProvTest.targetGroupAttribute.0.insert = true - // provisioner.ldapProvTest.targetGroupAttribute.0.select = true - // provisioner.ldapProvTest.targetGroupAttribute.0.translateExpressionType = grouperProvisioningGroupField - // provisioner.ldapProvTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField = name - // provisioner.ldapProvTest.targetGroupAttribute.0.translateToGroupSyncField = groupToId2 - // provisioner.ldapProvTest.targetGroupAttribute.0.update = true - // provisioner.ldapProvTest.targetGroupAttribute.1.insert = true - // provisioner.ldapProvTest.targetGroupAttribute.1.matchingId = true - // provisioner.ldapProvTest.targetGroupAttribute.1.name = businessCategory - // provisioner.ldapProvTest.targetGroupAttribute.1.searchAttribute = true - // provisioner.ldapProvTest.targetGroupAttribute.1.select = true - // provisioner.ldapProvTest.targetGroupAttribute.1.translateExpressionType = grouperProvisioningGroupField - // provisioner.ldapProvTest.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField = idIndex - // provisioner.ldapProvTest.targetGroupAttribute.1.valueType = long - // provisioner.ldapProvTest.targetGroupAttribute.2.insert = true - // provisioner.ldapProvTest.targetGroupAttribute.2.name = cn - // provisioner.ldapProvTest.targetGroupAttribute.2.select = true - // provisioner.ldapProvTest.targetGroupAttribute.2.translateExpressionType = grouperProvisioningGroupField - // provisioner.ldapProvTest.targetGroupAttribute.2.translateFromGrouperProvisioningGroupField = extension - // provisioner.ldapProvTest.targetGroupAttribute.2.valueType = string - // provisioner.ldapProvTest.targetGroupAttribute.3.insert = true - // provisioner.ldapProvTest.targetGroupAttribute.3.multiValued = true - // provisioner.ldapProvTest.targetGroupAttribute.3.name = objectClass - // provisioner.ldapProvTest.targetGroupAttribute.3.select = true - // provisioner.ldapProvTest.targetGroupAttribute.3.translateExpression = ${grouperUtil.toSet('top', 'groupOfNames')} - // provisioner.ldapProvTest.targetGroupAttribute.3.translateExpressionType = translationScript - // provisioner.ldapProvTest.targetGroupAttribute.4.defaultValue = cn=admin,dc=example,dc=edu - // provisioner.ldapProvTest.targetGroupAttribute.4.membershipAttribute = true - // provisioner.ldapProvTest.targetGroupAttribute.4.multiValued = true - // provisioner.ldapProvTest.targetGroupAttribute.4.name = member - // provisioner.ldapProvTest.targetGroupAttribute.4.translateFromMemberSyncField = memberToId2 - // provisioner.ldapProvTest.targetGroupAttribute.5.delete = true - // provisioner.ldapProvTest.targetGroupAttribute.5.insert = true - // provisioner.ldapProvTest.targetGroupAttribute.5.name = description - // provisioner.ldapProvTest.targetGroupAttribute.5.select = true - // provisioner.ldapProvTest.targetGroupAttribute.5.translateExpressionType = grouperProvisioningGroupField - // provisioner.ldapProvTest.targetGroupAttribute.5.translateFromGrouperProvisioningGroupField = description - // provisioner.ldapProvTest.targetGroupAttribute.5.update = true - // provisioner.ldapProvTest.updateGroups = true - // provisioner.ldapProvTest.userSearchAllFilter = (&(objectClass=person)(uid=*)) - // provisioner.ldapProvTest.userSearchBaseDn = ou=People,dc=example,dc=edu - // provisioner.ldapProvTest.userSearchFilter = (&(objectClass=person)(uid=${targetEntity.retrieveAttributeValue('uid')})) } @@ -598,20 +557,20 @@ public void testConfigurationValidationGroups() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.0.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.0.update", "false"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.0.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.0.multiValued", "false"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.0.translateExpression", "${'cn=' + javax.naming.ldap.Rdn.escapeValue(grouperProvisioningGroup.getName()) + ',ou=Groups,dc=example,dc=edu'}"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "idIndex"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupMatchingAttribute0name", "name"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.1.name", "description"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.1.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.1.update", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.1.matchingId", "false"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.1.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.1.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.1.translateFromMemberSyncField", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupMembershipAttributeName", "description"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupMembershipAttributeValue", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.subjectSourcesToProvision", "jdbc"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.deleteGroups", "true"); @@ -643,43 +602,67 @@ public void testConfigurationValidationGroups() { new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkNeedsConfig")).assignJqueryHandle("#config_hasTargetEntityLink_spanid"))); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetEntityAttribute.0.name", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetEntityAttribute.0.translateToMemberSyncField", "memberFromId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache0has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache0source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache0type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache0entityAttribute", "name"); errorsAndSuffixes = grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); assertFalse(errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkNeedsConfig")).assignJqueryHandle("#config_hasTargetEntityLink_spanid"))); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.targetEntityAttribute.0.translateToMemberSyncField"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.entityAttributeValueCacheHas"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.entityAttributeValueCache0has"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.entityAttributeValueCache0source"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.entityAttributeValueCache0type"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.entityAttributeValueCache0entityAttribute"); errorsAndSuffixes = grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); assertTrue(errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkNeedsConfig")).assignJqueryHandle("#config_hasTargetEntityLink_spanid"))); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.common.entityLink.memberFromId2", "${targetEntity.name}"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache0has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache0source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache0type", "translationScript"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache0translationScript", "${targetEntity.name}"); errorsAndSuffixes = grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); assertFalse(errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkNeedsConfig")).assignJqueryHandle("#config_hasTargetEntityLink_spanid"))); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetEntityAttribute.0.translateToMemberSyncField", "memberFromId2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache0has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache0source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache0type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache0entityAttribute", "name"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache1has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache1source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache1type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.entityAttributeValueCache1entityAttribute", "name"); + + errorsAndSuffixes = grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); assertFalse(errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkNeedsConfig")).assignJqueryHandle("#config_hasTargetGroupLink_spanid"))); assertTrue(errorsAndSuffixes.contains( - new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkMultipleToSameBucket")).assignJqueryHandle("#config_targetEntityAttribute.0.translateToMemberSyncField_spanid"))); - assertTrue(errorsAndSuffixes.contains( - new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkMultipleToSameBucket")).assignJqueryHandle("#config_common.entityLink.memberFromId2_spanid"))); + new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkMultipleFromSameAttribute")).assignJqueryHandle("#config_entityAttributeValueCache0entityAttribute_spanid"))); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.common.entityLink.memberFromId2"); + //TODO fix this + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.common.entityLink.entityAttributeValueCache0"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.hasTargetEntityLink"); errorsAndSuffixes = grouperProvisioner.retrieveGrouperProvisioningConfigurationValidation().validate(); assertFalse(errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkNeedsConfig")).assignJqueryHandle("#config_hasTargetEntityLink_spanid"))); assertFalse(errorsAndSuffixes.contains( - new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkMultipleToSameBucket")).assignJqueryHandle("#config_targetEntityAttribute.0.translateToMemberSyncField_spanid"))); + new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkMultipleToSameBucket")).assignJqueryHandle("#config_entityAttributeValueCache0entityAttribute_spanid"))); assertFalse(errorsAndSuffixes.contains( - new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkMultipleToSameBucket")).assignJqueryHandle("#config_common.entityLink.memberFromId2_spanid"))); + new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkMultipleToSameBucket")).assignJqueryHandle("#config_common.entityLink.entityAttributeValueCache0_spanid"))); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.numberOfGroupAttributes", "3"); @@ -798,44 +781,63 @@ public void testConfigurationValidationEntities() { new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetGroupLinkNeedsConfig")).assignJqueryHandle("#config_hasTargetGroupLink_spanid"))); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.0.name", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.0.translateToGroupSyncField", "groupFromId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache0has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache0source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache0type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache0groupAttribute", "name"); errorsAndSuffixes = GrouperProvisioner.retrieveProvisioner("sqlProvTest").retrieveGrouperProvisioningConfigurationValidation().validate(); assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetGroupLinkNeedsConfig")).assignJqueryHandle("#config_hasTargetGroupLink_spanid"))); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.targetGroupAttribute.0.translateToGroupSyncField"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.groupAttributeValueCacheHas"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.groupAttributeValueCache0has"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.groupAttributeValueCache0source"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.groupAttributeValueCache0type"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.groupAttributeValueCache0groupAttribute"); errorsAndSuffixes = GrouperProvisioner.retrieveProvisioner("sqlProvTest").retrieveGrouperProvisioningConfigurationValidation().validate(); assertTrue(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetGroupLinkNeedsConfig")).assignJqueryHandle("#config_hasTargetGroupLink_spanid"))); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.common.groupLink.groupFromId2", "${targetGroup.name}"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache0has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache0source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache0type", "translationScript"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache0groupAttribute", "${targetGroup.name}"); errorsAndSuffixes = GrouperProvisioner.retrieveProvisioner("sqlProvTest").retrieveGrouperProvisioningConfigurationValidation().validate(); assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetGroupLinkNeedsConfig")).assignJqueryHandle("#config_hasTargetGroupLink_spanid"))); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.targetGroupAttribute.0.translateToGroupSyncField", "groupFromId2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache0has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache0source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache0type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache0groupAttribute", "name"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache1has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache1source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache1type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.groupAttributeValueCache1groupAttribute", "name"); + errorsAndSuffixes = GrouperProvisioner.retrieveProvisioner("sqlProvTest").retrieveGrouperProvisioningConfigurationValidation().validate(); assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetGroupLinkNeedsConfig")).assignJqueryHandle("#config_hasTargetGroupLink_spanid"))); assertTrue(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( - new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetGroupLinkMultipleToSameBucket")).assignJqueryHandle("#config_targetGroupAttribute.0.translateToGroupSyncField_spanid"))); - assertTrue(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( - new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetGroupLinkMultipleToSameBucket")).assignJqueryHandle("#config_common.groupLink.groupFromId2_spanid"))); + new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetEntityLinkMultipleFromSameAttribute")).assignJqueryHandle("#config_groupAttributeValueCache0groupAttribute_spanid"))); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.common.groupLink.groupFromId2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.common.groupLink.groupAttributeValueCache0"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().remove("provisioner.sqlProvTest.hasTargetGroupLink"); errorsAndSuffixes = GrouperProvisioner.retrieveProvisioner("sqlProvTest").retrieveGrouperProvisioningConfigurationValidation().validate(); assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetGroupLinkNeedsConfig")).assignJqueryHandle("#config_hasTargetGroupLink_spanid"))); assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( - new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetGroupLinkMultipleToSameBucket")).assignJqueryHandle("#config_targetGroupAttribute.0.translateToGroupSyncField_spanid"))); - assertFalse(GrouperUtil.toStringForLog(errorsAndSuffixes, true), errorsAndSuffixes.contains( - new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetGroupLinkMultipleToSameBucket")).assignJqueryHandle("#config_common.groupLink.groupFromId2_spanid"))); + new ProvisioningValidationIssue().assignMessage(GrouperTextContainer.textOrNull("provisioning.configuration.validation.targetGroupLinkMultipleFromSameAttribute")).assignJqueryHandle("#config_common.groupLink.groupAttributeValueCache0_spanid"))); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.sqlProvTest.abc123", "def456"); errorsAndSuffixes = GrouperProvisioner.retrieveProvisioner("sqlProvTest").retrieveGrouperProvisioningConfigurationValidation().validate(); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningServiceTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningServiceTest.java index cd40875e8229..6d2c07803f9d 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningServiceTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/GrouperProvisioningServiceTest.java @@ -52,6 +52,11 @@ import edu.internet2.middleware.grouperClientExt.org.apache.commons.lang3.BooleanUtils; import junit.textui.TestRunner; +/** + * TODO refactor tests for 2.6.9 configs + * @author mchyzer + * + */ public class GrouperProvisioningServiceTest extends GrouperTest { public GrouperProvisioningServiceTest(String name) { @@ -59,7 +64,7 @@ public GrouperProvisioningServiceTest(String name) { } public static void main(String[] args) { - TestRunner.run(new GrouperProvisioningServiceTest("testGetProvisioningAttributeValueWithIndirectAndRegexRestriction")); + TestRunner.run(new GrouperProvisioningServiceTest("testTargetNotEditableWhenReadOnlyIsTrue")); } @Override @@ -771,16 +776,22 @@ public void testSaveOrUpdateProvisioningAttributes() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.select", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2type", "groupAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupAttributeValueCache2groupAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.name", "businessCategory"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "idIndex"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMatchingAttribute0name", "businessCategory"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.name", "cn"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.insert", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.2.select", "true"); @@ -796,9 +807,9 @@ public void testSaveOrUpdateProvisioningAttributes() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.name", "member"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.defaultValue", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.multiValued", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.membershipAttribute", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeName", "member"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.groupMembershipAttributeValue", "entityAttributeValueCache2"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.name", "description"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetGroupAttribute.5.insert", "true"); @@ -812,15 +823,21 @@ public void testSaveOrUpdateProvisioningAttributes() { GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.name", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCacheHas", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2source", "target"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2type", "entityAttribute"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityAttributeValueCache2entityAttribute", "name"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.name", "uid"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.select", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.matchingId", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.searchAttribute", "true"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttributeCount", "1"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.entityMatchingAttribute0name", "uid"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.class", LdapSync.class.getName()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.ldapExternalSystemConfigId", "personLdap"); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.junitProvisioningAttributePropagationTest.subjectSourcesToProvision", "jdbc"); @@ -985,35 +1002,6 @@ public void testSaveOrUpdateProvisioningAttributesForMembership() { assertTrue(metadata.containsKey("timestamp")); } - public void testTargetNotEditableWhenReadOnlyIsTrue() { - - //Given - GrouperSessionResult grouperSessionResult = GrouperSession.startRootSessionIfNotStarted(); - GrouperSession grouperSession = grouperSessionResult.getGrouperSession(); - - Stem stem0 = new StemSave(grouperSession).assignCreateParentStemsIfNotExist(true).assignName("test").save(); - - GrouperProvisioningTarget target1 = new GrouperProvisioningTarget("ldapReadOnlyKey", "ldapReadOnly"); - target1.setReadOnly(true); - GrouperProvisioningSettings.getTargets(false).put("ldapReadOnly", target1); - - saveProvisioningAttributeMetadata(stem0, true, "ldapReadOnly"); - - Stem etc = new StemSave(grouperSession).assignStemNameToEdit("etc").assignName("etc").save(); - Group wheel = etc.addChildGroup("wheel","wheel"); - wheel.addMember(SubjectTestHelper.SUBJ0); - - GrouperConfig.retrieveConfig().propertiesOverrideMap().put("groups.wheel.use", "true"); - GrouperConfig.retrieveConfig().propertiesOverrideMap().put("groups.wheel.group", wheel.getName()); - - //When - boolean isEditable = GrouperProvisioningService.isTargetEditable(target1, SubjectTestHelper.SUBJ0, stem0); - - // Then - assertFalse(isEditable); - - } - public void testTargetEditableWhenReadOnlyIsFalse() { //Given diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/ProvisionerConfigurationTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/ProvisionerConfigurationTest.java index 393306efebe2..52f07c1bb8aa 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/ProvisionerConfigurationTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/ProvisionerConfigurationTest.java @@ -56,54 +56,101 @@ public void testLdapProvisionerConfigurationInsertEditDelete() { // set the required values so that the validation pass and values can be inserted into the db GrouperConfigurationModuleAttribute attribute = provisionerConfiguration.retrieveAttributes().get("ldapExternalSystemConfigId"); - attribute.setValue("ldapExternalSystem"); + attribute.setValue("personLdap"); attribute = provisionerConfiguration.retrieveAttributes().get("subjectSourcesToProvision"); attribute.setValue("jdbc"); + attribute = provisionerConfiguration.retrieveAttributes().get("operateOnGrouperMemberships"); + attribute.setValue("true"); + attribute = provisionerConfiguration.retrieveAttributes().get("provisioningType"); attribute.setValue("groupAttributes"); - attribute = provisionerConfiguration.retrieveAttributes().get("groupDnType"); - attribute.setValue("bushy"); - - // set this value so that we can test that some internal attributes are also being saved correctly in the db. - attribute = provisionerConfiguration.retrieveAttributes().get("hasTargetGroupLink"); + attribute = provisionerConfiguration.retrieveAttributes().get("customizeMembershipCrud"); + attribute.setValue("true"); + + attribute = provisionerConfiguration.retrieveAttributes().get("selectMemberships"); + attribute.setValue("true"); + + attribute = provisionerConfiguration.retrieveAttributes().get("insertMemberships"); + attribute.setValue("true"); + + attribute = provisionerConfiguration.retrieveAttributes().get("deleteMemberships"); + attribute.setValue("true"); + + attribute = provisionerConfiguration.retrieveAttributes().get("deleteMembershipsIfNotExistInGrouper"); attribute.setValue("true"); attribute = provisionerConfiguration.retrieveAttributes().get("operateOnGrouperGroups"); attribute.setValue("true"); - + + attribute = provisionerConfiguration.retrieveAttributes().get("customizeGroupCrud"); + attribute.setValue("true"); + + attribute = provisionerConfiguration.retrieveAttributes().get("selectGroups"); + attribute.setValue("true"); + attribute = provisionerConfiguration.retrieveAttributes().get("insertGroups"); attribute.setValue("true"); + + attribute = provisionerConfiguration.retrieveAttributes().get("deleteGroups"); + attribute.setValue("false"); + + attribute = provisionerConfiguration.retrieveAttributes().get("hasTargetGroupLink"); + attribute.setValue("true"); + + attribute = provisionerConfiguration.retrieveAttributes().get("groupSearchBaseDn"); + attribute.setValue("ou=Groups,dc=example,dc=edu"); - attribute = provisionerConfiguration.retrieveAttributes().get("common.groupLink.groupFromId2"); - attribute.setValue("test"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("ldap.ldapExternalSystem.url", "ldap://localhost:389"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("ldap.ldapExternalSystem.user", "cn=admin,dc=example,dc=edu"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("ldap.ldapExternalSystem.pass", "secret"); - + + attribute = provisionerConfiguration.retrieveAttributes().get("groupDnType"); + attribute.setValue("flat"); + + attribute = provisionerConfiguration.retrieveAttributes().get("numberOfGroupAttributes"); + attribute.setValue("1"); + attribute = provisionerConfiguration.retrieveAttributes().get("targetGroupAttribute.0.name"); + attribute.setValue("ldap_dn"); + + attribute = provisionerConfiguration.retrieveAttributes().get("targetGroupAttribute.0.translateExpressionType"); + attribute.setValue("grouperProvisioningGroupField"); + + attribute = provisionerConfiguration.retrieveAttributes().get("targetGroupAttribute.0.translateFromGrouperProvisioningGroupField"); attribute.setValue("name"); + + attribute = provisionerConfiguration.retrieveAttributes().get("groupMembershipAttributeName"); + attribute.setValue("ldap_dn"); + + attribute = provisionerConfiguration.retrieveAttributes().get("groupMembershipAttributeValue"); + attribute.setValue("subjectId"); + - attribute = provisionerConfiguration.retrieveAttributes().get("targetGroupAttribute.0.insert"); - attribute.setValue("true"); + attribute = provisionerConfiguration.retrieveAttributes().get("groupMatchingAttributeCount"); + attribute.setValue("1"); + + attribute = provisionerConfiguration.retrieveAttributes().get("groupMatchingAttribute0name"); + attribute.setValue("ldap_dn"); - attribute = provisionerConfiguration.retrieveAttributes().get("targetGroupAttribute.0.select"); + attribute = provisionerConfiguration.retrieveAttributes().get("groupAttributeValueCacheHas"); attribute.setValue("true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.insert", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.select", "true"); + attribute = provisionerConfiguration.retrieveAttributes().get("groupAttributeValueCache2has"); + attribute.setValue("true"); + + attribute = provisionerConfiguration.retrieveAttributes().get("groupAttributeValueCache2source"); + attribute.setValue("target"); + + attribute = provisionerConfiguration.retrieveAttributes().get("groupAttributeValueCache2type"); + attribute.setValue("groupAttribute"); + + attribute = provisionerConfiguration.retrieveAttributes().get("groupAttributeValueCache2groupAttribute"); + attribute.setValue("ldap_dn"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("ldap.personLdap.url", "ldap://localhost:389"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("ldap.personLdap.user", "cn=admin,dc=example,dc=edu"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("ldap.personLdap.pass", "secret"); -// GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.name", "name"); -// GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.insert", "true"); -// GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.select", "true"); -// GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.update", "true"); -// GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); -// GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); -// GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.ldapProvTest.targetGroupAttribute.0.translateToGroupSyncField", "groupToId2"); StringBuilder message = new StringBuilder(); List errorsToDisplay = new ArrayList(); @@ -132,14 +179,14 @@ public void testLdapProvisionerConfigurationInsertEditDelete() { attribute = provisionerConfiguration.retrieveAttributes().get("groupDnType"); value = attribute.getValue(); - assertEquals("bushy", value); + assertEquals("flat", value); // edit the configuration provisionerConfiguration = new LdapProvisionerConfiguration(); provisionerConfiguration.setConfigId("myLdapProvisioner"); attribute = provisionerConfiguration.retrieveAttributes().get("groupDnType"); - attribute.setValue("flat"); + attribute.setValue("bushy"); List actionsPerformed = new ArrayList(); @@ -152,7 +199,7 @@ public void testLdapProvisionerConfigurationInsertEditDelete() { attribute = provisionerConfiguration.retrieveAttributes().get("groupDnType"); value = attribute.getValue(); - assertEquals("flat", value); + assertEquals("bushy", value); // before we delete - let's set up some grouper sync data because // we want to make sure that sync data gets deleted when provisioner is deleted @@ -272,7 +319,7 @@ public void testSqlProvisionerConfigurationInsertEditDelete() { attribute = provisionerConfiguration.retrieveAttributes().get("dbExternalSystemConfigId"); attribute.setValue("Database External System"); - attribute = provisionerConfiguration.retrieveAttributes().get("common.entityLink.memberFromId2"); + attribute = provisionerConfiguration.retrieveAttributes().get("common.entityLink.entityAttributeValueCache0"); attribute.setValue("test"); // set the following two values so that we can test that some internal attributes are also being saved correctly in the db. diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroupTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroupTest.java new file mode 100644 index 000000000000..e5294081f8cf --- /dev/null +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/provisioning/ProvisioningGroupTest.java @@ -0,0 +1,139 @@ +package edu.internet2.middleware.grouper.app.provisioning; + +import java.util.Collection; +import java.util.Set; + +import edu.internet2.middleware.grouper.helper.GrouperTest; +import edu.internet2.middleware.grouper.util.GrouperUtil; +import junit.textui.TestRunner; + +public class ProvisioningGroupTest extends GrouperTest { + + public ProvisioningGroupTest() { + } + + public ProvisioningGroupTest(String name) { + super(name); + } + + public static void main(String[] args) { + + TestRunner.run(new ProvisioningGroupTest("testConvertToJsonForCacheLong")); + + + } + + public void testConvertToJsonForCache() { + + ProvisioningGroup provisioningGroup = new ProvisioningGroup(); + provisioningGroup.assignAttributeValue("name", "someName"); + provisioningGroup.assignAttributeValue("id", "abc123"); + provisioningGroup.addAttributeValue("member", "jsmith"); + provisioningGroup.addAttributeValue("member", "ajackson"); + provisioningGroup.addAttributeValue("member", "tjohnson"); + provisioningGroup.addAttributeValue("objectClass", "groupOfNames"); + provisioningGroup.addAttributeValue("objectClass", "top"); + provisioningGroup.addAttributeValue("objectClass", "memberGroup"); + provisioningGroup.assignAttributeValue("description", "This is the description of the group"); + provisioningGroup.assignAttributeValue("displayName", "Some name"); + provisioningGroup.assignAttributeValue("uuid", "abc123xyz456"); + String json = provisioningGroup.toJsonForCache("member"); + + assertEquals("{\"description\":\"This is the description of the group\",\"displayName\":\"Some name\",\"id\":\"abc123\"," + + "\"name\":\"someName\",\"objectClass\":[\"groupOfNames\",\"memberGroup\",\"top\"],\"uuid\":\"abc123xyz456\"}", json); + //{"description":"This is the description of the group","displayName":"Some name","id":"abc123","name":"someName","objectClass":["groupOfNames","memberGroup","top"],"uuid":"abc123xyz456"} + + ProvisioningGroup provisioningGroup2 = new ProvisioningGroup(); + + provisioningGroup2.fromJsonForCache(json); + assertEquals("someName" , provisioningGroup2.retrieveAttributeValueString("name")); + assertEquals("abc123" , provisioningGroup2.retrieveAttributeValueString("id")); + Collection objectClass = (Collection)provisioningGroup2.retrieveAttributeValue("objectClass"); + assertEquals(3, GrouperUtil.length(objectClass)); + assertTrue(objectClass.contains("groupOfNames")); + assertTrue(objectClass.contains("top")); + assertTrue(objectClass.contains("memberGroup")); + assertEquals(0, GrouperUtil.length(provisioningGroup2.getTruncatedAttributeNames())); + } + + public void testConvertToJsonForCacheLong() { + + ProvisioningGroup provisioningGroup = new ProvisioningGroup(); + provisioningGroup.assignAttributeValue("name", "someName"); + provisioningGroup.assignAttributeValue("id", "abc123"); + provisioningGroup.addAttributeValue("member", "jsmith"); + provisioningGroup.addAttributeValue("member", "ajackson"); + provisioningGroup.addAttributeValue("member", "tjohnson"); + provisioningGroup.addAttributeValue("objectClass", "groupOfNames"); + provisioningGroup.addAttributeValue("objectClass", "top"); + provisioningGroup.addAttributeValue("objectClass", "memberGroup"); + provisioningGroup.assignAttributeValue("description", "This is the description of the group"); + provisioningGroup.assignAttributeValue("displayName", "Some name"); + provisioningGroup.assignAttributeValue("uuid", "abc123xyz456"); + + // 1426 + provisioningGroup.assignAttributeValue("someLong1", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae auctor eu augue ut lectus arcu bibendum. Egestas erat imperdiet sed euismod nisi porta lorem mollis aliquam. In metus vulputate eu scelerisque felis imperdiet proin fermentum leo. Scelerisque fermentum dui faucibus in ornare quam. Massa eget egestas purus viverra accumsan in nisl. Dapibus ultrices in iaculis nunc sed augue lacus viverra vitae. Aliquam malesuada bibendum arcu vitae. Quam adipiscing vitae proin sagittis nisl rhoncus mattis. Vivamus at augue eget arcu dictum. Blandit aliquam etiam erat velit scelerisque in dictum. Egestas pretium aenean pharetra magna ac placerat vestibulum lectus. Egestas erat imperdiet sed euismod nisi porta lorem mollis aliquam. Egestas fringilla phasellus faucibus scelerisque eleifend. Erat velit scelerisque in dictum non consectetur a. Fusce ut placerat orci nulla pellentesque dignissim enim sit. Vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt. Aliquet nibh praesent tristique magna sit amet purus. Sit amet commodo nulla facilisi. Fermentum dui faucibus in ornare quam viverra. Bibendum at varius vel pharetra vel turpis. Volutpat est velit egestas dui id. Elementum eu facilisis sed odio morbi quis commodo odio aenean. Integer malesuada nunc vel risus commodo viverra maecenas. Tempus quam pellentesque nec nam aliquam sem."); + + // 982 + provisioningGroup.assignAttributeValue("someLong2", "Vestibulum lorem sed risus ultricies tristique nulla. Purus viverra accumsan in nisl nisi scelerisque eu. Mattis pellentesque id nibh tortor. Amet dictum sit amet justo donec enim. Justo nec ultrices dui sapien eget mi proin. Faucibus scelerisque eleifend donec pretium. Dignissim sodales ut eu sem integer vitae justo eget magna. Consequat ac felis donec et odio pellentesque diam volutpat commodo. Porttitor eget dolor morbi non arcu risus. Pharetra et ultrices neque ornare aenean euismod elementum nisi quis. Erat nam at lectus urna duis convallis convallis tellus. Nec nam aliquam sem et tortor consequat id porta. Sit amet tellus cras adipiscing enim. Tortor aliquam nulla facilisi cras fermentum odio eu. Proin fermentum leo vel orci. Et netus et malesuada fames ac turpis egestas sed. Proin libero nunc consequat interdum. Ridiculus mus mauris vitae ultricies leo integer malesuada. Sapien eget mi proin sed libero enim sed. Diam maecenas ultricies mi eget mauris pharetra et."); + + // 765 + provisioningGroup.assignAttributeValue("someLong3", "Viverra maecenas accumsan lacus vel facilisis volutpat est velit. Quam lacus suspendisse faucibus interdum posuere lorem ipsum dolor sit. Et malesuada fames ac turpis egestas. Sit amet dictum sit amet justo. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Ullamcorper velit sed ullamcorper morbi tincidunt. Justo eget magna fermentum iaculis eu non diam. Dolor sit amet consectetur adipiscing elit ut aliquam purus. Mattis aliquam faucibus purus in massa. Felis eget velit aliquet sagittis id consectetur purus ut. Hendrerit dolor magna eget est lorem. Tortor id aliquet lectus proin. Velit euismod in pellentesque massa placerat duis. Eu scelerisque felis imperdiet proin fermentum. Porttitor leo a diam sollicitudin tempor id eu nisl."); + + // 537 + provisioningGroup.assignAttributeValue("someLong4", "Facilisi morbi tempus iaculis urna id. Sollicitudin tempor id eu nisl nunc. Ultrices eros in cursus turpis massa tincidunt dui. Ultrices vitae auctor eu augue ut lectus arcu bibendum at. Nunc consequat interdum varius sit amet. Consectetur libero id faucibus nisl. Imperdiet sed euismod nisi porta lorem mollis. Cras pulvinar mattis nunc sed blandit libero volutpat sed cras. A diam sollicitudin tempor id eu nisl nunc mi. Non blandit massa enim nec dui nunc. Sapien eget mi proin sed libero. Pulvinar neque laoreet suspendisse interdum"); + + // 1617 + provisioningGroup.assignAttributeValue("someLong5", "Odio tempor orci dapibus ultrices in iaculis nunc. Nibh venenatis cras sed felis eget velit aliquet sagittis id. Sed risus ultricies tristique nulla aliquet enim tortor at. Vitae aliquet nec ullamcorper sit. Arcu non odio euismod lacinia at quis. Faucibus vitae aliquet nec ullamcorper sit amet. Praesent tristique magna sit amet purus gravida quis blandit. Velit euismod in pellentesque massa placerat duis. A diam sollicitudin tempor id eu. Adipiscing at in tellus integer. Placerat duis ultricies lacus sed turpis tincidunt id. Faucibus a pellentesque sit amet porttitor eget dolor morbi non. Cras sed felis eget velit aliquet sagittis id. Risus nec feugiat in fermentum posuere. Elit duis tristique sollicitudin nibh. Mattis rhoncus urna neque viverra justo nec ultrices dui sapien. Nisl pretium fusce id velit ut tortor. Tincidunt augue interdum velit euismod in pellentesque. Felis bibendum ut tristique et egestas quis ipsum suspendisse ultrices. Enim diam vulputate ut pharetra. Justo eget magna fermentum iaculis eu non. Molestie nunc non blandit massa enim nec dui nunc mattis. Ut tortor pretium viverra suspendisse potenti nullam ac. Ultricies mi quis hendrerit dolor magna eget est lorem ipsum. Nibh cras pulvinar mattis nunc sed blandit. Adipiscing bibendum est ultricies integer quis auctor elit. Sed cras ornare arcu dui vivamus arcu. Odio ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Lorem donec massa sapien faucibus. Scelerisque eleifend donec pretium vulputate. Lacus suspendisse faucibus interdum posuere lorem ipsum dolor. Ut faucibus pulvinar elementum integer enim neque."); + + String json = provisioningGroup.toJsonForCache("member"); + + //System.out.println(json); + assertEquals("{\"description\":\"This is the description of the group\",\"displayName\":\"Some name\",\"id\":\"abc123\",\"name\":\"someName\",\"objectClass\":[\"groupOfNames\",\"memberGroup\",\"top\"],\"someLong1\":\"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae auctor eu augue ut lectus arcu bibendum. Egestas erat imperdiet sed euismod nisi porta lorem mollis aliquam. In metus vulputate eu scelerisque felis imperdiet proin fermentum leo. Scelerisque fermentum dui faucibus in ornare quam. Massa eget egestas purus viverra accumsan in nisl. Dapibus ultrices in iaculis nunc sed augue lacus viverra vitae. Aliquam malesuada bib...\",\"someLong2\":\"Vestibulum lorem sed risus ultricies tristique nulla. Purus viverra accumsan in nisl nisi scelerisque eu. Mattis pellentesque id nibh tortor. Amet dictum sit amet justo donec enim. Justo nec ultrices dui sapien eget mi proin. Faucibus scelerisque eleifend donec pretium. Dignissim sodales ut eu sem integer vitae justo eget magna. Consequat ac felis donec et odio pellentesque diam volutpat commodo. Porttitor eget dolor morbi non arcu risus. Pharetra et ultrices neque ornare aenean euismod eleme...\",\"someLong3\":\"Viverra maecenas accumsan lacus vel facilisis volutpat est velit. Quam lacus suspendisse faucibus interdum posuere lorem ipsum dolor sit. Et malesuada fames ac turpis egestas. Sit amet dictum sit amet justo. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Ullamcorper velit sed ullamcorper morbi tincidunt. Justo eget magna fermentum iaculis eu non diam. Dolor sit amet consectetur adipiscing elit ut aliquam purus. Mattis aliquam faucibus purus in massa. Felis eget velit aliquet sagittis id consectetur purus ut. Hendrerit dolor magna eget est lorem. Tortor id aliquet lectus proin. Velit euismod in pellentesque massa placerat duis. Eu scelerisque felis imperdiet proin fermentum. Porttitor leo a diam sollicitudin tempor id eu nisl.\",\"someLong4\":\"Facilisi morbi tempus iaculis urna id. Sollicitudin tempor id eu nisl nunc. Ultrices eros in cursus turpis massa tincidunt dui. Ultrices vitae auctor eu augue ut lectus arcu bibendum at. Nunc consequat interdum varius sit amet. Consectetur libero id faucibus nisl. Imperdiet sed euismod nisi porta lorem mollis. Cras pulvinar mattis nunc sed blandit libero volutpat sed cras. A diam sollicitudin tempor id eu nisl nunc mi. Non blandit massa enim nec dui nunc. Sapien eget mi proin sed libero. Pulvinar neque laoreet suspendisse interdum\",\"someLong5\":\"Odio tempor orci dapibus ultrices in iaculis nunc. Nibh venenatis cras sed felis eget velit aliquet sagittis id. Sed risus ultricies tristique nulla aliquet enim tortor at. Vitae aliquet nec ullamcorper sit. Arcu non odio euismod lacinia at quis. Faucibus vitae aliquet nec ullamcorper sit amet. Praesent tristique magna sit amet purus gravida quis blandit. Velit euismod in pellentesque massa placerat duis. A diam sollicitudin tempor id eu. Adipiscing at in tellus integer. Placerat duis ultricies lacus sed turpis tincidunt id. Faucibus a pellentesque sit amet porttitor eget dolor morbi non. Cras sed felis eget velit aliquet sagittis id. Risus nec feugiat in fermentum posuere. Elit duis tristique sollicitudin nibh. Mattis rhoncus urna neque viverra justo nec ultrices dui sapien. Nisl pretium fusce id velit ut tortor. Tincidunt augue interdum velit euismod in pellentesque. Felis bibendum ut tristique et egestas quis ipsum suspendisse ultrices. Enim diam vulputate ut pharetra. Justo ege...\",\"uuid\":\"abc123xyz456\",\"trunc_attrs\":[\"someLong1\",\"someLong2\",\"someLong5\"]}", json); + + //{"description":"This is the description of the group","displayName":"Some name","id":"abc123","name":"someName","objectClass":["groupOfNames","memberGroup","top"],"uuid":"abc123xyz456"} + + ProvisioningGroup provisioningGroup2 = new ProvisioningGroup(); + provisioningGroup2.assignAttributeValue("name", "someName"); + provisioningGroup2.assignAttributeValue("id", "abc123"); + provisioningGroup2.addAttributeValue("member", "jsmith"); + provisioningGroup2.addAttributeValue("member", "ajackson"); + provisioningGroup2.addAttributeValue("member", "tjohnson"); + provisioningGroup2.addAttributeValue("objectClass", "groupOfNames"); + provisioningGroup2.addAttributeValue("objectClass", "top"); + provisioningGroup2.addAttributeValue("objectClass", "memberGroup"); + provisioningGroup2.assignAttributeValue("description", "This is the description of the group"); + provisioningGroup2.assignAttributeValue("displayName", "Some name"); + provisioningGroup2.assignAttributeValue("uuid", "abc123xyz456"); + + // 1426 + provisioningGroup2.assignAttributeValue("someLong1", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae auctor eu augue ut lectus arcu bibendum. Egestas erat imperdiet sed euismod nisi porta lorem mollis aliquam. In metus vulputate eu scelerisque felis imperdiet proin fermentum leo. Scelerisque fermentum dui faucibus in ornare quam. Massa eget egestas purus viverra accumsan in nisl. Dapibus ultrices in iaculis nunc sed augue lacus viverra vitae. Aliquam malesuada bibendum arcu vitae. Quam adipiscing vitae proin sagittis nisl rhoncus mattis. Vivamus at augue eget arcu dictum. Blandit aliquam etiam erat velit scelerisque in dictum. Egestas pretium aenean pharetra magna ac placerat vestibulum lectus. Egestas erat imperdiet sed euismod nisi porta lorem mollis aliquam. Egestas fringilla phasellus faucibus scelerisque eleifend. Erat velit scelerisque in dictum non consectetur a. Fusce ut placerat orci nulla pellentesque dignissim enim sit. Vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt. Aliquet nibh praesent tristique magna sit amet purus. Sit amet commodo nulla facilisi. Fermentum dui faucibus in ornare quam viverra. Bibendum at varius vel pharetra vel turpis. Volutpat est velit egestas dui id. Elementum eu facilisis sed odio morbi quis commodo odio aenean. Integer malesuada nunc vel risus commodo viverra maecenas. Tempus quam pellentesque nec nam aliquam sem."); + + // 982 + provisioningGroup2.assignAttributeValue("someLong2", "Vestibulum lorem sed risus ultricies tristique nulla. Purus viverra accumsan in nisl nisi scelerisque eu. Mattis pellentesque id nibh tortor. Amet dictum sit amet justo donec enim. Justo nec ultrices dui sapien eget mi proin. Faucibus scelerisque eleifend donec pretium. Dignissim sodales ut eu sem integer vitae justo eget magna. Consequat ac felis donec et odio pellentesque diam volutpat commodo. Porttitor eget dolor morbi non arcu risus. Pharetra et ultrices neque ornare aenean euismod elementum nisi quis. Erat nam at lectus urna duis convallis convallis tellus. Nec nam aliquam sem et tortor consequat id porta. Sit amet tellus cras adipiscing enim. Tortor aliquam nulla facilisi cras fermentum odio eu. Proin fermentum leo vel orci. Et netus et malesuada fames ac turpis egestas sed. Proin libero nunc consequat interdum. Ridiculus mus mauris vitae ultricies leo integer malesuada. Sapien eget mi proin sed libero enim sed. Diam maecenas ultricies mi eget mauris pharetra et."); + + // 765 + provisioningGroup2.assignAttributeValue("someLong3", "Viverra maecenas accumsan lacus vel facilisis volutpat est velit. Quam lacus suspendisse faucibus interdum posuere lorem ipsum dolor sit. Et malesuada fames ac turpis egestas. Sit amet dictum sit amet justo. Sit amet consectetur adipiscing elit pellentesque habitant morbi tristique. Ullamcorper velit sed ullamcorper morbi tincidunt. Justo eget magna fermentum iaculis eu non diam. Dolor sit amet consectetur adipiscing elit ut aliquam purus. Mattis aliquam faucibus purus in massa. Felis eget velit aliquet sagittis id consectetur purus ut. Hendrerit dolor magna eget est lorem. Tortor id aliquet lectus proin. Velit euismod in pellentesque massa placerat duis. Eu scelerisque felis imperdiet proin fermentum. Porttitor leo a diam sollicitudin tempor id eu nisl."); + + // 592 + provisioningGroup2.assignAttributeValue("someLong4", "Facilisi morbi tempus iaculis urna id. Sollicitudin tempor id eu nisl nunc. Ultrices eros in cursus turpis massa tincidunt dui. Ultrices vitae auctor eu augue ut lectus arcu bibendum at. Nunc consequat interdum varius sit amet. Consectetur libero id faucibus nisl. Imperdiet sed euismod nisi porta lorem mollis. Cras pulvinar mattis nunc sed blandit libero volutpat sed cras. A diam sollicitudin tempor id eu nisl nunc mi. Non blandit massa enim nec dui nunc. Sapien eget mi proin sed libero. Pulvinar neque laoreet suspendisse interdum"); + + // 1617 + provisioningGroup2.assignAttributeValue("someLong5", "Odio tempor orci dapibus ultrices in iaculis nunc. Nibh venenatis cras sed felis eget velit aliquet sagittis id. Sed risus ultricies tristique nulla aliquet enim tortor at. Vitae aliquet nec ullamcorper sit. Arcu non odio euismod lacinia at quis. Faucibus vitae aliquet nec ullamcorper sit amet. Praesent tristique magna sit amet purus gravida quis blandit. Velit euismod in pellentesque massa placerat duis. A diam sollicitudin tempor id eu. Adipiscing at in tellus integer. Placerat duis ultricies lacus sed turpis tincidunt id. Faucibus a pellentesque sit amet porttitor eget dolor morbi non. Cras sed felis eget velit aliquet sagittis id. Risus nec feugiat in fermentum posuere. Elit duis tristique sollicitudin nibh. Mattis rhoncus urna neque viverra justo nec ultrices dui sapien. Nisl pretium fusce id velit ut tortor. Tincidunt augue interdum velit euismod in pellentesque. Felis bibendum ut tristique et egestas quis ipsum suspendisse ultrices. Enim diam vulputate ut pharetra. Justo eget magna fermentum iaculis eu non. Molestie nunc non blandit massa enim nec dui nunc mattis. Ut tortor pretium viverra suspendisse potenti nullam ac. Ultricies mi quis hendrerit dolor magna eget est lorem ipsum. Nibh cras pulvinar mattis nunc sed blandit. Adipiscing bibendum est ultricies integer quis auctor elit. Sed cras ornare arcu dui vivamus arcu. Odio ut enim blandit volutpat maecenas volutpat blandit aliquam etiam. Lorem donec massa sapien faucibus. Scelerisque eleifend donec pretium vulputate. Lacus suspendisse faucibus interdum posuere lorem ipsum dolor. Ut faucibus pulvinar elementum integer enim neque."); + + Set attributeNamesDifferentForCache = provisioningGroup.attributeNamesDifferentForCache(provisioningGroup2, "member"); + assertEquals(0, GrouperUtil.length(attributeNamesDifferentForCache)); + + provisioningGroup2.assignAttributeValue("name", "someOtherName"); + provisioningGroup2.assignAttributeValue("id", "acb234"); + attributeNamesDifferentForCache = provisioningGroup.attributeNamesDifferentForCache(provisioningGroup2, "member"); + + assertEquals(2, GrouperUtil.length(attributeNamesDifferentForCache)); + assertTrue(attributeNamesDifferentForCache.contains("name")); + assertTrue(attributeNamesDifferentForCache.contains("id")); + + } + + + +} diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/scim/GrouperScimProvisionerTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/scim/GrouperScimProvisionerTest.java index 00319dc547a9..b3d4edcb4641 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/scim/GrouperScimProvisionerTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/scim/GrouperScimProvisionerTest.java @@ -47,7 +47,7 @@ public class GrouperScimProvisionerTest extends GrouperTest { public static void main(String[] args) { - TestRunner.run(new GrouperScimProvisionerTest("testGithubIncrementalSync")); + TestRunner.run(new GrouperScimProvisionerTest("testAWSIncrementalSyncProvisionGroupAndThenDeleteTheGroup")); } @@ -83,7 +83,7 @@ public void testGithubIncrementalSync() { .assignConfigId("githubProvisioner").assignChangelogConsumerConfigId("githubScimProvTestCLC") .assignAcceptHeader("application/vnd.github.v3+json") .assignBearerTokenExternalSystemConfigId("githubExternalSystem") - .addSubjectLink("memberFromId2", "${subject.getAttributeValue('email')}") + .assignSubjectLinkCache0("${subject.getAttributeValue('email')}") .assignEntityDeleteType("deleteEntitiesIfNotExistInGrouper") .assignGroupOfUsersToProvision(testGroup) .assignScimMembershipType("group") @@ -166,7 +166,7 @@ public void testGithubFullSync() { .assignConfigId("githubProvisioner").assignChangelogConsumerConfigId("githubScimProvTestCLC") .assignAcceptHeader("application/vnd.github.v3+json") .assignBearerTokenExternalSystemConfigId("githubExternalSystem") - .addSubjectLink("memberFromId2", "${subject.getAttributeValue('email')}") + .assignSubjectLinkCache0("${subject.getAttributeValue('email')}") .assignEntityDeleteType("deleteEntitiesIfNotExistInGrouper") .assignGroupOfUsersToProvision(testGroup) .assignScimMembershipType("group") @@ -350,10 +350,10 @@ public void testAWSFullSyncProvisionGroupAndThenDeleteTheGroup() { assertNull(gcGrouperSyncGroup.getProvisionableEnd()); assertTrue(started <= gcGrouperSyncGroup.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncGroup.getLastUpdated().getTime()); - assertNotNull(gcGrouperSyncGroup.getGroupToId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId3()); - assertNull(gcGrouperSyncGroup.getGroupToId3()); + assertNotNull(gcGrouperSyncGroup.getGroupAttributeValueCache2()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache0()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache1()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache3()); assertNull(gcGrouperSyncGroup.getLastGroupMetadataSync()); assertNull(gcGrouperSyncGroup.getErrorMessage()); assertNull(gcGrouperSyncGroup.getErrorTimestamp()); @@ -377,10 +377,10 @@ public void testAWSFullSyncProvisionGroupAndThenDeleteTheGroup() { assertNull(gcGrouperSyncMember.getProvisionableEnd()); assertTrue(started <= gcGrouperSyncMember.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getLastUpdated().getTime()); - assertNull(gcGrouperSyncMember.getMemberFromId2()); - assertNull(gcGrouperSyncMember.getMemberFromId3()); - assertNotNull(gcGrouperSyncMember.getMemberToId2()); - assertNull(gcGrouperSyncMember.getMemberToId3()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache0()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache1()); + assertNotNull(gcGrouperSyncMember.getEntityAttributeValueCache2()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache3()); assertNull(gcGrouperSyncMember.getLastUserMetadataSync()); assertNull(gcGrouperSyncMember.getErrorMessage()); assertNull(gcGrouperSyncMember.getErrorTimestamp()); @@ -401,10 +401,10 @@ public void testAWSFullSyncProvisionGroupAndThenDeleteTheGroup() { assertNull(gcGrouperSyncMember.getProvisionableEnd()); assertTrue(started <= gcGrouperSyncMember.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getLastUpdated().getTime()); - assertNull(gcGrouperSyncMember.getMemberFromId2()); - assertNull(gcGrouperSyncMember.getMemberFromId3()); - assertNotNull(gcGrouperSyncMember.getMemberToId2()); - assertNull(gcGrouperSyncMember.getMemberToId3()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache0()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache1()); + assertNotNull(gcGrouperSyncMember.getEntityAttributeValueCache2()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache3()); assertNull(gcGrouperSyncMember.getLastUserMetadataSync()); assertNull(gcGrouperSyncMember.getErrorMessage()); assertNull(gcGrouperSyncMember.getErrorTimestamp()); @@ -489,10 +489,10 @@ public void testAWSFullSyncProvisionGroupAndThenDeleteTheGroup() { assertNull(gcGrouperSyncGroup.getProvisionableEnd()); assertTrue(started > gcGrouperSyncGroup.getLastUpdated().getTime()); // because no change from previous run assertTrue(System.currentTimeMillis() >= gcGrouperSyncGroup.getLastUpdated().getTime()); - assertNotNull(gcGrouperSyncGroup.getGroupToId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId3()); - assertNull(gcGrouperSyncGroup.getGroupToId3()); + assertNotNull(gcGrouperSyncGroup.getGroupAttributeValueCache2()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache0()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache1()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache3()); assertNull(gcGrouperSyncGroup.getLastGroupMetadataSync()); assertNull(gcGrouperSyncGroup.getErrorMessage()); assertNull(gcGrouperSyncGroup.getErrorTimestamp()); @@ -516,10 +516,10 @@ public void testAWSFullSyncProvisionGroupAndThenDeleteTheGroup() { assertNull(gcGrouperSyncMember.getProvisionableEnd()); assertTrue(started > gcGrouperSyncMember.getLastUpdated().getTime()); // because no change from previous run assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getLastUpdated().getTime()); - assertNull(gcGrouperSyncMember.getMemberFromId2()); - assertNull(gcGrouperSyncMember.getMemberFromId3()); - assertNotNull(gcGrouperSyncMember.getMemberToId2()); - assertNull(gcGrouperSyncMember.getMemberToId3()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache0()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache1()); + assertNotNull(gcGrouperSyncMember.getEntityAttributeValueCache2()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache3()); assertNull(gcGrouperSyncMember.getLastUserMetadataSync()); assertNull(gcGrouperSyncMember.getErrorMessage()); assertNull(gcGrouperSyncMember.getErrorTimestamp()); @@ -537,10 +537,10 @@ public void testAWSFullSyncProvisionGroupAndThenDeleteTheGroup() { assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getProvisionableStart().getTime()); assertNotNull(gcGrouperSyncMember.getProvisionableEnd()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getLastUpdated().getTime()); - assertNull(gcGrouperSyncMember.getMemberFromId2()); - assertNull(gcGrouperSyncMember.getMemberFromId3()); - assertNotNull(gcGrouperSyncMember.getMemberToId2()); - assertNull(gcGrouperSyncMember.getMemberToId3()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache0()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache1()); + assertNotNull(gcGrouperSyncMember.getEntityAttributeValueCache2()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache3()); assertNull(gcGrouperSyncMember.getLastUserMetadataSync()); assertNull(gcGrouperSyncMember.getErrorMessage()); assertNull(gcGrouperSyncMember.getErrorTimestamp()); @@ -615,10 +615,10 @@ public void testAWSFullSyncProvisionGroupAndThenDeleteTheGroup() { assertTrue(System.currentTimeMillis() >= gcGrouperSyncGroup.getProvisionableStart().getTime()); assertNotNull(gcGrouperSyncGroup.getProvisionableEnd()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncGroup.getLastUpdated().getTime()); - assertNotNull(gcGrouperSyncGroup.getGroupToId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId3()); - assertNull(gcGrouperSyncGroup.getGroupToId3()); + assertNotNull(gcGrouperSyncGroup.getGroupAttributeValueCache2()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache0()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache1()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache3()); assertNull(gcGrouperSyncGroup.getLastGroupMetadataSync()); assertNull(gcGrouperSyncGroup.getErrorMessage()); assertNull(gcGrouperSyncGroup.getErrorTimestamp()); @@ -639,10 +639,10 @@ public void testAWSFullSyncProvisionGroupAndThenDeleteTheGroup() { assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getProvisionableStart().getTime()); assertNotNull(gcGrouperSyncMember.getProvisionableEnd()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getLastUpdated().getTime()); - assertNull(gcGrouperSyncMember.getMemberFromId2()); - assertNull(gcGrouperSyncMember.getMemberFromId3()); - assertNotNull(gcGrouperSyncMember.getMemberToId2()); - assertNull(gcGrouperSyncMember.getMemberToId3()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache0()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache1()); + assertNotNull(gcGrouperSyncMember.getEntityAttributeValueCache2()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache3()); assertNull(gcGrouperSyncMember.getLastUserMetadataSync()); assertNull(gcGrouperSyncMember.getErrorMessage()); assertNull(gcGrouperSyncMember.getErrorTimestamp()); @@ -659,10 +659,10 @@ public void testAWSFullSyncProvisionGroupAndThenDeleteTheGroup() { assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getProvisionableStart().getTime()); assertNotNull(gcGrouperSyncMember.getProvisionableEnd()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getLastUpdated().getTime()); - assertNull(gcGrouperSyncMember.getMemberFromId2()); - assertNull(gcGrouperSyncMember.getMemberFromId3()); - assertNotNull(gcGrouperSyncMember.getMemberToId2()); - assertNull(gcGrouperSyncMember.getMemberToId3()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache0()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache1()); + assertNotNull(gcGrouperSyncMember.getEntityAttributeValueCache2()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache3()); assertNull(gcGrouperSyncMember.getLastUserMetadataSync()); assertNull(gcGrouperSyncMember.getErrorMessage()); assertNull(gcGrouperSyncMember.getErrorTimestamp()); @@ -821,10 +821,10 @@ public void testAWSIncrementalSyncProvisionGroupAndThenDeleteTheGroup() { assertNull(gcGrouperSyncGroup.getProvisionableEnd()); assertTrue(started < gcGrouperSyncGroup.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncGroup.getLastUpdated().getTime()); - assertNotNull(gcGrouperSyncGroup.getGroupToId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId3()); - assertNull(gcGrouperSyncGroup.getGroupToId3()); + assertNotNull(gcGrouperSyncGroup.getGroupAttributeValueCache2()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache0()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache1()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache3()); assertNull(gcGrouperSyncGroup.getLastGroupMetadataSync()); assertNull(gcGrouperSyncGroup.getErrorMessage()); assertNull(gcGrouperSyncGroup.getErrorTimestamp()); @@ -848,10 +848,10 @@ public void testAWSIncrementalSyncProvisionGroupAndThenDeleteTheGroup() { assertNull(gcGrouperSyncMember.getProvisionableEnd()); assertTrue(started < gcGrouperSyncMember.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getLastUpdated().getTime()); - assertNull(gcGrouperSyncMember.getMemberFromId2()); - assertNull(gcGrouperSyncMember.getMemberFromId3()); - assertNotNull(gcGrouperSyncMember.getMemberToId2()); - assertNull(gcGrouperSyncMember.getMemberToId3()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache0()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache1()); + assertNotNull(gcGrouperSyncMember.getEntityAttributeValueCache2()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache3()); assertNull(gcGrouperSyncMember.getLastUserMetadataSync()); assertNull(gcGrouperSyncMember.getErrorMessage()); assertNull(gcGrouperSyncMember.getErrorTimestamp()); @@ -872,10 +872,10 @@ public void testAWSIncrementalSyncProvisionGroupAndThenDeleteTheGroup() { assertNull(gcGrouperSyncMember.getProvisionableEnd()); assertTrue(started < gcGrouperSyncMember.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() >= gcGrouperSyncMember.getLastUpdated().getTime()); - assertNull(gcGrouperSyncMember.getMemberFromId2()); - assertNull(gcGrouperSyncMember.getMemberFromId3()); - assertNotNull(gcGrouperSyncMember.getMemberToId2()); - assertNull(gcGrouperSyncMember.getMemberToId3()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache0()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache1()); + assertNotNull(gcGrouperSyncMember.getEntityAttributeValueCache2()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache3()); assertNull(gcGrouperSyncMember.getLastUserMetadataSync()); assertNull(gcGrouperSyncMember.getErrorMessage()); assertNull(gcGrouperSyncMember.getErrorTimestamp()); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/scim/ScimProvisionerTestConfigInput.java b/grouper/src/test/edu/internet2/middleware/grouper/app/scim/ScimProvisionerTestConfigInput.java index 7e0a88960ac0..3fb0b3c4b5bc 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/scim/ScimProvisionerTestConfigInput.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/scim/ScimProvisionerTestConfigInput.java @@ -131,27 +131,21 @@ public ScimProvisionerTestConfigInput assignBearerTokenExternalSystemConfigId(St } /** - * e.g. memberFromId2 -> ${subject.getAttributeValue('email')} + * e.g. ${subject.getAttributeValue('email')} */ - private Map subjectLink = new TreeMap(); + private String subjectLinkCache0; - /** - * e.g. memberFromId2 -> ${subject.getAttributeValue('email')} - * @return - */ - public Map getSubjectLink() { - return subjectLink; + + public String getSubjectLinkCache0() { + return subjectLinkCache0; } + - /** - * e.g. memberFromId2 -> ${subject.getAttributeValue('email')} - * @return - */ - public ScimProvisionerTestConfigInput addSubjectLink(String cacheBucket, String value) { - this.subjectLink.put(cacheBucket, value); + public ScimProvisionerTestConfigInput assignSubjectLinkCache0(String subjectLinkCache0) { + this.subjectLinkCache0 = subjectLinkCache0; return this; } - + /** * groupDeleteType e.g. deleteGroupsIfNotExistInGrouper or deleteGroupsIfGrouperDeleted or deleteGroupsIfGrouperCreated or null (default) */ diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/scim/ScimProvisionerTestUtils.java b/grouper/src/test/edu/internet2/middleware/grouper/app/scim/ScimProvisionerTestUtils.java index 0dab37343532..cefaa8dad520 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/scim/ScimProvisionerTestUtils.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/scim/ScimProvisionerTestUtils.java @@ -67,8 +67,8 @@ public static void configureScimProvisioner(ScimProvisionerTestConfigInput provi GrouperUtil.assertion(!StringUtils.isBlank(provisioningTestConfigInput.getConfigId()), "Config ID required"); if (!StringUtils.isBlank(provisioningTestConfigInput.getAcceptHeader())) { - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.githubProvisioner.acceptHeader") - .value(provisioningTestConfigInput.getAcceptHeader()).store(); + + configureProvisionerSuffix(provisioningTestConfigInput, "acceptHeader", provisioningTestConfigInput.getAcceptHeader()); } @@ -77,24 +77,43 @@ public static void configureScimProvisioner(ScimProvisionerTestConfigInput provi provisioningTestConfigInput.getBearerTokenExternalSystemConfigId()); } - for (String key : provisioningTestConfigInput.getSubjectLink().keySet()) { + if (StringUtils.isNotBlank(provisioningTestConfigInput.getSubjectLinkCache0())) { + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCacheHas", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0source", "grouper"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0type", "subjectTranslationScript"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0translationScript", provisioningTestConfigInput.getSubjectLinkCache0()); - String value = provisioningTestConfigInput.getSubjectLink().get(key); - configureProvisionerSuffix(provisioningTestConfigInput, "provisioner.githubProvisioner.common.subjectLink." + key, value); } - + configureProvisionerSuffix(provisioningTestConfigInput, "class", "edu.internet2.middleware.grouper.app.scim2Provisioning.GrouperScim2Provisioner"); configureProvisionerSuffix(provisioningTestConfigInput, "debugLog", "true"); if (!StringUtils.isBlank(provisioningTestConfigInput.getEntityDeleteType())) { configureProvisionerSuffix(provisioningTestConfigInput, "deleteEntities", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "customizeEntityCrud", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, provisioningTestConfigInput.getEntityDeleteType(), "true"); } - if (!StringUtils.isBlank(provisioningTestConfigInput.getEntityDeleteType())) { - configureProvisionerSuffix(provisioningTestConfigInput, "deleteEntities", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, provisioningTestConfigInput.getEntityDeleteType(), "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperEntities", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "makeChangesToEntities", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperGroups", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "customizeGroupCrud", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "updateGroups", "false"); + + if (!StringUtils.isBlank(provisioningTestConfigInput.getGroupDeleteType())) { + configureProvisionerSuffix(provisioningTestConfigInput, "deleteGroups", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, provisioningTestConfigInput.getGroupDeleteType(), "true"); } if (!StringUtils.isBlank(provisioningTestConfigInput.getMembershipDeleteType())) { configureProvisionerSuffix(provisioningTestConfigInput, "deleteMemberships", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperMemberships", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "customizeMembershipCrud", "true"); configureProvisionerSuffix(provisioningTestConfigInput, provisioningTestConfigInput.getMembershipDeleteType(), "true"); } if (provisioningTestConfigInput.getGroupOfUsersToProvision() != null) { @@ -144,17 +163,27 @@ public static void configureScimProvisioner(ScimProvisionerTestConfigInput provi configureProvisionerSuffix(provisioningTestConfigInput, "selectAllEntities", provisioningTestConfigInput.isSelectAllEntities() + ""); } configureProvisionerSuffix(provisioningTestConfigInput, "selectEntities", "true"); - if (provisioningTestConfigInput.getGroupAttributeCount() > 0) { - configureProvisionerSuffix(provisioningTestConfigInput, "selectGroups", "true"); + + if (provisioningTestConfigInput.getGroupAttributeCount() == 0) { + configureProvisionerSuffix(provisioningTestConfigInput, "selectGroups", "false"); } + configureProvisionerSuffix(provisioningTestConfigInput, "selectMemberships", "false"); configureProvisionerSuffix(provisioningTestConfigInput, "showAdvanced", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "subjectSourcesToProvision", "jdbc"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.name", "id"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.matchingId", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2type", "entityAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2entityAttribute", "id"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.name", "userName"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.searchAttribute", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttribute0name", "userName"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.name", "givenName"); @@ -169,22 +198,25 @@ public static void configureScimProvisioner(ScimProvisionerTestConfigInput provi configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateFromGrouperProvisioningEntityField", "name"); } else if (StringUtils.equals(provisioningTestConfigInput.getEntityAttribute4name(), "emailValue")) { configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateExpressionType", "translationScript"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateExpression", "${gcGrouperSyncMember.memberFromId2}"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateExpression", "${gcGrouperSyncMember.getEntityAttributeValueCache0()}"); } else { throw new RuntimeException("Not value entityAttribute5Name: '" + provisioningTestConfigInput.getEntityAttribute4name() + "'"); } if (provisioningTestConfigInput.getGroupAttributeCount() > 0) { - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.matchingId", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.name", "displayName"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.searchAttribute", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "extension"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.name", "id"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateToGroupSyncField", "groupToId2"); - } - configureProvisionerSuffix(provisioningTestConfigInput, "updateEntities", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "updateGroups", "false"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttribute0name", "displayName"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2type", "groupAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2groupAttribute", "id"); + } for (String key: provisioningTestConfigInput.getExtraConfig().keySet()) { String theValue = provisioningTestConfigInput.getExtraConfig().get(key); @@ -198,7 +230,7 @@ public static void configureScimProvisioner(ScimProvisionerTestConfigInput provi // edu.internet2.middleware.grouper.app.provisioning GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("changeLog.consumer." + provisioningTestConfigInput.getChangelogConsumerConfigId() + ".publisher.class", ProvisioningConsumer.class.getName()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("changeLog.consumer." + provisioningTestConfigInput.getChangelogConsumerConfigId() + ".quartzCron", "0 0 5 * * 2000"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("changeLog.consumer." + provisioningTestConfigInput.getChangelogConsumerConfigId() + ".provisionerConfigId", "githubProvisioner"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("changeLog.consumer." + provisioningTestConfigInput.getChangelogConsumerConfigId() + ".provisionerConfigId", provisioningTestConfigInput.getConfigId()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("changeLog.consumer." + provisioningTestConfigInput.getChangelogConsumerConfigId() + ".provisionerJobSyncType", GrouperProvisioningType.incrementalProvisionChangeLog.name()); GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("changeLog.consumer." + provisioningTestConfigInput.getChangelogConsumerConfigId() + ".publisher.debug", "true"); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerTest.java index 7864066aa860..909df33134f7 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerTest.java @@ -126,7 +126,7 @@ public static void main(String[] args) { GrouperStartup.startup(); // testSimpleGroupLdapPa - TestRunner.run(new SqlProvisionerTest("testSimpleMembershipGroupNameSubjectId")); + TestRunner.run(new SqlProvisionerTest("testGroupEntityMembershipRenameGroupIncrementalMatchOnOld")); } @@ -212,9 +212,9 @@ public void testSimpleMembershipGroupNameSubjectId() { SqlProvisionerTestUtils.configureSqlProvisioner(new SqlProvisionerTestConfigInput() .assignMembershipDeleteType("deleteMembershipsIfNotExistInGrouper") .assignMembershipTableName("testgrouper_prov_mship0") - .assignMembershipTableIdColumn("group_name, subject_id") - .assignMembershipGroupForeignKeyColumn("group_name") - .assignMembershipEntityForeignKeyColumn("subject_id") +// .assignMembershipTableIdColumn("group_name, subject_id") +// .assignMembershipGroupForeignKeyColumn("group_name") +// .assignMembershipEntityForeignKeyColumn("subject_id") .assignMembershipAttributeCount(2) ); @@ -394,7 +394,7 @@ public void testIncrementalSyncSqlProvisioner() { Stem stem2 = new StemSave(grouperSession).assignName("test2").save(); // mark some folders to provision - Group testGroup = new GroupSave(grouperSession).assignName("test:testGroup").save(); + Group testGroup = new GroupSave(grouperSession).assignName("test:testGroup").assignDescription("old description").save(); Group testGroup2 = new GroupSave(grouperSession).assignName("test2:testGroup2").save(); testGroup.addMember(SubjectTestHelper.SUBJ0, false); @@ -435,6 +435,15 @@ public void testIncrementalSyncSqlProvisioner() { assertEquals(new Integer(2), new GcDbAccess().connectionName("grouper").sql("select count(1) from testgrouper_prov_entity").select(int.class)); assertEquals(new Integer(2), new GcDbAccess().connectionName("grouper").sql("select count(1) from testgrouper_prov_mship2").select(int.class)); + // change the description + assertEquals("old description", new GcDbAccess().sql("select description from testgrouper_prov_group where name = 'test:testGroup'").select(String.class)); + testGroup = new GroupSave().assignName(testGroup.getName()).assignDescription("new description").assignReplaceAllSettings(false).save(); + runJobs(true, true); + + assertEquals("new description", new GcDbAccess().sql("select description from testgrouper_prov_group where name = 'test:testGroup'").select(String.class)); + + + //now delete the group and sync again testGroup.delete(); runJobs(true, true); @@ -1046,6 +1055,260 @@ public void testSimpleGroupMembershipProvisioningFullWithAttributesTable() { } + public void testGroupEntityMembershipRenameGroupFullMatchOnOld() { + + SqlProvisionerTestUtils.configureSqlProvisioner(new SqlProvisionerTestConfigInput() + .assignEntityDeleteType("deleteEntitiesIfNotExistInGrouper") + .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") + .assignMembershipDeleteType("deleteMembershipsIfNotExistInGrouper") + .assignEntityAttributesTable(true) + .assignGroupAttributesTable(true) + .assignGroupTableName("testgrouper_prov_group") + .assignGroupTableIdColumn("uuid") + .assignEntityTableName("testgrouper_prov_entity") + .assignEntityTableIdColumn("uuid") + .assignMembershipTableName("testgrouper_prov_mship2") + .assignMembershipTableIdColumn("uuid") + .assignMembershipGroupForeignKeyColumn("group_uuid") + .assignMembershipEntityForeignKeyColumn("entity_uuid") + .assignHasTargetEntityLink(true) + .assignHasTargetGroupLink(true) + .assignEntityAttributeCount(5) + .assignGroupAttributeCount(4) + .assignMembershipAttributeCount(3) + .addExtraConfig("targetGroupAttribute.2.translateFromGrouperProvisioningGroupField", "displayName") + .addExtraConfig("groupMatchingAttributeSameAsSearchAttribute", "false") + .addExtraConfig("groupMatchingAttribute0name", "name") + ); + + Stem stem = new StemSave(this.grouperSession).assignName("test").save(); + Stem stem2 = new StemSave(this.grouperSession).assignName("test2").save(); + + // mark some folders to provision + Group testGroup = new GroupSave(this.grouperSession).assignName("test:testGroup").assignDescription("testDescription1").save(); + Group testGroup2 = new GroupSave(this.grouperSession).assignName("test2:testGroup2").assignDescription("testDescription2").save(); + + testGroup.addMember(SubjectTestHelper.SUBJ0, false); + testGroup.addMember(SubjectTestHelper.SUBJ1, false); + + testGroup2.addMember(SubjectTestHelper.SUBJ2, false); + testGroup2.addMember(SubjectTestHelper.SUBJ3, false); + + final GrouperProvisioningAttributeValue attributeValue = new GrouperProvisioningAttributeValue(); + attributeValue.setDirectAssignment(true); + attributeValue.setDoProvision("sqlProvTest"); + attributeValue.setTargetName("sqlProvTest"); + attributeValue.setStemScopeString("sub"); + + GrouperProvisioningService.saveOrUpdateProvisioningAttributes(attributeValue, stem); + + //AttributeAssign attributeAssign = stem.getAttributeDelegate().addAttribute(GrouperProvisioningAttributeNames.retrieveAttributeDefNameMarker()).getAttributeAssign(); + //attributeAssign.getAttributeValueDelegate().assignValueString(GrouperProvisioningAttributeNames.retrieveAttributeDefNameDoProvision()) + + //lets sync these over + GrouperProvisioner grouperProvisioner = GrouperProvisioner.retrieveProvisioner("sqlProvTest"); + + GrouperProvisioningOutput grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); + assertEquals(0, grouperProvisioningOutput.getRecordsWithErrors()); + + List groups = new GcDbAccess().sql("select uuid, posix_id, name from testgrouper_prov_group").selectList(Object[].class); + assertEquals(1, groups.size()); + + String testGroupUuidInTarget = groups.get(0)[0].toString(); + assertNotNull(testGroupUuidInTarget); + + assertEquals(testGroup.getIdIndex().longValue(), ((BigDecimal)groups.get(0)[1]).longValue()); + assertEquals(testGroup.getName(), groups.get(0)[2]); + + List groupAttributes = new GcDbAccess().sql("select attribute_name, attribute_value from testgrouper_pro_ldap_group_attr where group_uuid = '"+testGroupUuidInTarget+"'").selectList(Object[].class); + assertEquals(1, groupAttributes.size()); + + assertEquals("description", groupAttributes.get(0)[0]); + assertEquals(testGroup.getDescription(), groupAttributes.get(0)[1]); + + List entities = new GcDbAccess().sql("select uuid, name, subject_id_or_identifier, description from testgrouper_prov_entity").selectList(Object[].class); + assertEquals(2, entities.size()); + + String subject0EntityUUID = null; + String subject1EntityUUID2 = null; + + Map entityNameToAllAttributes = new HashMap(); + for (Object[] entityAttributes: entities) { + entityNameToAllAttributes.put(entityAttributes[1].toString(), entityAttributes); + if (StringUtils.equals(entityAttributes[1].toString(), SubjectTestHelper.SUBJ0.getName())) { + subject0EntityUUID = entityAttributes[0].toString(); + } + if (StringUtils.equals(entityAttributes[1].toString(), SubjectTestHelper.SUBJ1.getName())) { + subject1EntityUUID2 = entityAttributes[0].toString(); + } + } + + assertTrue(entityNameToAllAttributes.containsKey(SubjectTestHelper.SUBJ0.getName())); + assertTrue(entityNameToAllAttributes.containsKey(SubjectTestHelper.SUBJ1.getName())); + + List memberships = new GcDbAccess().sql("select group_uuid, entity_uuid from testgrouper_prov_mship2").selectList(Object[].class); + + Set groupIdSubjectIdsInTable = new HashSet(); + + for (Object[] membershipAttributes: memberships) { + groupIdSubjectIdsInTable.add(new MultiKey(membershipAttributes[0], membershipAttributes[1])); + } + + assertEquals(2, groupIdSubjectIdsInTable.size()); + + assertTrue(groupIdSubjectIdsInTable.contains(new MultiKey(testGroupUuidInTarget, subject0EntityUUID))); + assertTrue(groupIdSubjectIdsInTable.contains(new MultiKey(testGroupUuidInTarget, subject1EntityUUID2))); + + // rename the group in grouper + testGroup = new GroupSave().assignUuid(testGroup.getUuid()).assignDisplayName(testGroup.getDisplayName() + "New").assignReplaceAllSettings(false).save(); + + grouperProvisioner = GrouperProvisioner.retrieveProvisioner("sqlProvTest"); + + grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); + assertEquals(0, grouperProvisioningOutput.getRecordsWithErrors()); + + assertEquals(1, GrouperUtil.intValue(grouperProvisioner.getDebugMap().get("provisioningGroupWrappersMatchedFromCache"), -1)); + + groups = new GcDbAccess().sql("select uuid, posix_id, name from testgrouper_prov_group").selectList(Object[].class); + assertEquals(1, groups.size()); + + testGroupUuidInTarget = groups.get(0)[0].toString(); + assertNotNull(testGroupUuidInTarget); + + assertEquals(testGroup.getIdIndex().longValue(), ((BigDecimal)groups.get(0)[1]).longValue()); + assertEquals(testGroup.getDisplayName(), groups.get(0)[2]); + + } + + public void testGroupEntityMembershipRenameGroupIncrementalMatchOnOld() { + + SqlProvisionerTestUtils.configureSqlProvisioner(new SqlProvisionerTestConfigInput() + .assignEntityDeleteType("deleteEntitiesIfNotExistInGrouper") + .assignGroupDeleteType("deleteGroupsIfNotExistInGrouper") + .assignMembershipDeleteType("deleteMembershipsIfNotExistInGrouper") + .assignEntityAttributesTable(true) + .assignGroupAttributesTable(true) + .assignGroupTableName("testgrouper_prov_group") + .assignGroupTableIdColumn("uuid") + .assignEntityTableName("testgrouper_prov_entity") + .assignEntityTableIdColumn("uuid") + .assignMembershipTableName("testgrouper_prov_mship2") + .assignMembershipTableIdColumn("uuid") + .assignMembershipGroupForeignKeyColumn("group_uuid") + .assignMembershipEntityForeignKeyColumn("entity_uuid") + .assignHasTargetEntityLink(true) + .assignHasTargetGroupLink(true) + .assignEntityAttributeCount(5) + .assignGroupAttributeCount(4) + .assignMembershipAttributeCount(3) + .addExtraConfig("targetGroupAttribute.2.translateFromGrouperProvisioningGroupField", "displayName") + .addExtraConfig("groupMatchingAttributeSameAsSearchAttribute", "false") + .addExtraConfig("groupMatchingAttribute0name", "name") + .addExtraConfig("recalculateAllOperations", "true") + ); + + Stem stem = new StemSave(this.grouperSession).assignName("test").save(); + Stem stem2 = new StemSave(this.grouperSession).assignName("test2").save(); + + // mark some folders to provision + Group testGroup = new GroupSave(this.grouperSession).assignName("test:testGroup").assignDescription("testDescription1").save(); + Group testGroup2 = new GroupSave(this.grouperSession).assignName("test2:testGroup2").assignDescription("testDescription2").save(); + + testGroup.addMember(SubjectTestHelper.SUBJ0, false); + testGroup.addMember(SubjectTestHelper.SUBJ1, false); + + testGroup2.addMember(SubjectTestHelper.SUBJ2, false); + testGroup2.addMember(SubjectTestHelper.SUBJ3, false); + + final GrouperProvisioningAttributeValue attributeValue = new GrouperProvisioningAttributeValue(); + attributeValue.setDirectAssignment(true); + attributeValue.setDoProvision("sqlProvTest"); + attributeValue.setTargetName("sqlProvTest"); + attributeValue.setStemScopeString("sub"); + + GrouperProvisioningService.saveOrUpdateProvisioningAttributes(attributeValue, stem); + + //AttributeAssign attributeAssign = stem.getAttributeDelegate().addAttribute(GrouperProvisioningAttributeNames.retrieveAttributeDefNameMarker()).getAttributeAssign(); + //attributeAssign.getAttributeValueDelegate().assignValueString(GrouperProvisioningAttributeNames.retrieveAttributeDefNameDoProvision()) + + //lets sync these over + GrouperProvisioner grouperProvisioner = GrouperProvisioner.retrieveProvisioner("sqlProvTest"); + + GrouperProvisioningOutput grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); + assertEquals(0, grouperProvisioningOutput.getRecordsWithErrors()); + + runJobs(true, true); + + List groups = new GcDbAccess().sql("select uuid, posix_id, name from testgrouper_prov_group").selectList(Object[].class); + assertEquals(1, groups.size()); + + String testGroupUuidInTarget = groups.get(0)[0].toString(); + assertNotNull(testGroupUuidInTarget); + + assertEquals(testGroup.getIdIndex().longValue(), ((BigDecimal)groups.get(0)[1]).longValue()); + assertEquals(testGroup.getName(), groups.get(0)[2]); + + List groupAttributes = new GcDbAccess().sql("select attribute_name, attribute_value from testgrouper_pro_ldap_group_attr where group_uuid = '"+testGroupUuidInTarget+"'").selectList(Object[].class); + assertEquals(1, groupAttributes.size()); + + assertEquals("description", groupAttributes.get(0)[0]); + assertEquals(testGroup.getDescription(), groupAttributes.get(0)[1]); + + List entities = new GcDbAccess().sql("select uuid, name, subject_id_or_identifier, description from testgrouper_prov_entity").selectList(Object[].class); + assertEquals(2, entities.size()); + + String subject0EntityUUID = null; + String subject1EntityUUID2 = null; + + Map entityNameToAllAttributes = new HashMap(); + for (Object[] entityAttributes: entities) { + entityNameToAllAttributes.put(entityAttributes[1].toString(), entityAttributes); + if (StringUtils.equals(entityAttributes[1].toString(), SubjectTestHelper.SUBJ0.getName())) { + subject0EntityUUID = entityAttributes[0].toString(); + } + if (StringUtils.equals(entityAttributes[1].toString(), SubjectTestHelper.SUBJ1.getName())) { + subject1EntityUUID2 = entityAttributes[0].toString(); + } + } + + assertTrue(entityNameToAllAttributes.containsKey(SubjectTestHelper.SUBJ0.getName())); + assertTrue(entityNameToAllAttributes.containsKey(SubjectTestHelper.SUBJ1.getName())); + + List memberships = new GcDbAccess().sql("select group_uuid, entity_uuid from testgrouper_prov_mship2").selectList(Object[].class); + + Set groupIdSubjectIdsInTable = new HashSet(); + + for (Object[] membershipAttributes: memberships) { + groupIdSubjectIdsInTable.add(new MultiKey(membershipAttributes[0], membershipAttributes[1])); + } + + assertEquals(2, groupIdSubjectIdsInTable.size()); + + assertTrue(groupIdSubjectIdsInTable.contains(new MultiKey(testGroupUuidInTarget, subject0EntityUUID))); + assertTrue(groupIdSubjectIdsInTable.contains(new MultiKey(testGroupUuidInTarget, subject1EntityUUID2))); + + // rename the group in grouper + testGroup = new GroupSave().assignUuid(testGroup.getUuid()).assignDisplayName(testGroup.getDisplayName() + "New").assignReplaceAllSettings(false).save(); + + runJobs(true, true); + grouperProvisioner = GrouperProvisioner.retrieveInternalLastProvisioner(); + + assertEquals(0, grouperProvisioningOutput.getRecordsWithErrors()); + + assertEquals(1, GrouperUtil.intValue(grouperProvisioner.getDebugMap().get("retrieveGroupsFromCache"), -1)); + assertEquals(1, GrouperUtil.intValue(grouperProvisioner.getDebugMap().get("provisioningGroupWrappersMatchedFromCache"), -1)); + + groups = new GcDbAccess().sql("select uuid, posix_id, name from testgrouper_prov_group").selectList(Object[].class); + assertEquals(1, groups.size()); + + testGroupUuidInTarget = groups.get(0)[0].toString(); + assertNotNull(testGroupUuidInTarget); + + assertEquals(testGroup.getIdIndex().longValue(), ((BigDecimal)groups.get(0)[1]).longValue()); + assertEquals(testGroup.getDisplayName(), groups.get(0)[2]); + + } + /** * @param tableName */ @@ -2135,6 +2398,7 @@ public void testSimpleGroupLdapDao() { .assignGroupAttributesTable(true) .assignGroupTableName("testgrouper_prov_ldap_group") .assignGroupTableIdColumn("uuid") + .assignEntityAttributesTable(true) .assignEntityTableName("testgrouper_prov_ldap_entity") .assignEntityTableIdColumn("entity_uuid") .assignEntityAttributeCount(3) @@ -2519,7 +2783,7 @@ public void testSimpleGroupLdapPa() { new GcDbAccess().sql("insert into testgrouper_pro_dap_entity_attr (entity_uuid, entity_attribute_name, entity_attribute_value) values (?,?,?)") .addBindVar(uuid).addBindVar("dn").addBindVar(dn).executeSql(); new GcDbAccess().sql("insert into testgrouper_pro_dap_entity_attr (entity_uuid, entity_attribute_name, entity_attribute_value) values (?,?,?)") - .addBindVar(uuid).addBindVar("employeeID").addBindVar("test.subject." + i).executeSql(); + .addBindVar(uuid).addBindVar("employeeId").addBindVar("test.subject." + i).executeSql(); } @@ -2626,10 +2890,10 @@ public void testSimpleGroupLdapPa() { assertNull(gcGrouperSyncGroup.getProvisionableEnd()); assertTrue(started < gcGrouperSyncGroup.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() > gcGrouperSyncGroup.getLastUpdated().getTime()); - assertEquals("cn=test:testGroup,OU=Grouper,OU=365Groups,DC=one,DC=upenn,DC=edu", gcGrouperSyncGroup.getGroupToId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId2()); - assertNull(gcGrouperSyncGroup.getGroupFromId3()); - assertNull(gcGrouperSyncGroup.getGroupToId3()); + assertEquals("cn=test:testGroup,OU=Grouper,OU=365Groups,DC=one,DC=upenn,DC=edu", gcGrouperSyncGroup.getGroupAttributeValueCache2()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache0()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache1()); + assertNull(gcGrouperSyncGroup.getGroupAttributeValueCache3()); assertNull(gcGrouperSyncGroup.getLastGroupMetadataSync()); assertNull(gcGrouperSyncGroup.getErrorMessage()); assertNull(gcGrouperSyncGroup.getErrorTimestamp()); @@ -2653,10 +2917,10 @@ public void testSimpleGroupLdapPa() { assertNull(gcGrouperSyncMember.getProvisionableEnd()); assertTrue(started < gcGrouperSyncMember.getLastUpdated().getTime()); assertTrue(System.currentTimeMillis() > gcGrouperSyncMember.getLastUpdated().getTime()); - assertNull(gcGrouperSyncMember.getMemberFromId2()); - assertNull(gcGrouperSyncMember.getMemberFromId3()); - assertEquals("dn_test.subject.0", gcGrouperSyncMember.getMemberToId2()); - assertNull(gcGrouperSyncMember.getMemberToId3()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache0()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache1()); + assertEquals("dn_test.subject.0", gcGrouperSyncMember.getEntityAttributeValueCache2()); + assertNull(gcGrouperSyncMember.getEntityAttributeValueCache3()); assertNull(gcGrouperSyncMember.getLastUserMetadataSync()); assertNull(gcGrouperSyncMember.getErrorMessage()); assertNull(gcGrouperSyncMember.getErrorTimestamp()); @@ -2678,9 +2942,215 @@ public void testSimpleGroupLdapPa() { } + + /** + * just do a simple full sync of groups and memberships, rename the group, find it with matching old values + */ + public void testSimpleGroupLdapPaFullRenameMatchingOld() { + + long started = System.currentTimeMillis(); + + SqlProvisionerTestUtils.configureSqlProvisioner(new SqlProvisionerTestConfigInput() + .assignGroupDeleteType("deleteGroupsIfGrouperDeleted") + .assignMembershipDeleteType("deleteMembershipsIfNotExistInGrouper") + .assignEntityAttributesTable(true) + .assignGroupAttributesTable(true) + .assignGroupTableName("testgrouper_prov_ldap_group") + .assignGroupTableIdColumn("uuid") + .assignEntityTableName("testgrouper_prov_ldap_entity") + .assignEntityTableIdColumn("entity_uuid") + .assignHasTargetEntityLink(true) + .assignEntityAttributeCount(3) + .assignGroupAttributeCount(6) + .assignProvisioningType("groupAttributes") + .addExtraConfig("logCommandsAlways", "true") + ); + + + Stem stem = new StemSave(this.grouperSession).assignName("test").save(); + Stem stem2 = new StemSave(this.grouperSession).assignName("test2").save(); + + // mark some folders to provision + Group testGroup = new GroupSave(this.grouperSession).assignName("test:testGroup").save(); + Group testGroup2 = new GroupSave(this.grouperSession).assignName("test2:testGroup2").save(); + + testGroup.addMember(SubjectTestHelper.SUBJ0, false); + testGroup.addMember(SubjectTestHelper.SUBJ1, false); + + testGroup2.addMember(SubjectTestHelper.SUBJ2, false); + testGroup2.addMember(SubjectTestHelper.SUBJ3, false); + + final GrouperProvisioningAttributeValue attributeValue = new GrouperProvisioningAttributeValue(); + attributeValue.setDirectAssignment(true); + attributeValue.setDoProvision("sqlProvTest"); + attributeValue.setTargetName("sqlProvTest"); + attributeValue.setStemScopeString("sub"); + + GrouperProvisioningService.saveOrUpdateProvisioningAttributes(attributeValue, stem); + + // add some entities + for (int i=0;i<10;i++) { + String uuid = GrouperUuid.getUuid(); + String dn = "dn_test.subject." + i; + new GcDbAccess().sql("insert into testgrouper_prov_ldap_entity (entity_uuid) values (?)").addBindVar(uuid).executeSql(); + new GcDbAccess().sql("insert into testgrouper_pro_dap_entity_attr (entity_uuid, entity_attribute_name, entity_attribute_value) values (?,?,?)") + .addBindVar(uuid).addBindVar("dn").addBindVar(dn).executeSql(); + new GcDbAccess().sql("insert into testgrouper_pro_dap_entity_attr (entity_uuid, entity_attribute_name, entity_attribute_value) values (?,?,?)") + .addBindVar(uuid).addBindVar("employeeId").addBindVar("test.subject." + i).executeSql(); + } + + + //lets sync these over + GrouperProvisioner grouperProvisioner = GrouperProvisioner.retrieveProvisioner("sqlProvTest"); + + GrouperProvisioningOutput grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); + + // make sure some time has passed + GrouperUtil.sleep(1000); + + assertEquals(0, grouperProvisioningOutput.getRecordsWithErrors()); + + String sql = "select uuid from testgrouper_prov_ldap_group"; + + List dataInTable = new GcDbAccess().sql(sql).selectList(Object[].class); + + Set groupNamesInTable = new HashSet(); + + for (Object[] row: dataInTable) { + groupNamesInTable.add(new MultiKey(row)); + } + + assertEquals(1, groupNamesInTable.size()); + assertTrue(groupNamesInTable.contains(new MultiKey(new Object[]{"test:testGroup"}))); + + sql = "select group_uuid, attribute_name, attribute_value from testgrouper_pro_ldap_group_attr"; + + dataInTable = new GcDbAccess().sql(sql).selectList(Object[].class); + + Set attributesInTable = new HashSet(); + + for (Object[] row: dataInTable) { + attributesInTable.add(new MultiKey(row)); + } + + assertEquals(6, attributesInTable.size()); + + assertTrue(attributesInTable.contains(new MultiKey("test:testGroup", "cn", "test:testGroup"))); + assertTrue(attributesInTable.contains(new MultiKey("test:testGroup", "dn", "cn=test:testGroup,OU=Grouper,OU=365Groups,DC=one,DC=upenn,DC=edu"))); + assertTrue(attributesInTable.contains(new MultiKey("test:testGroup", "gidNumber", "" + testGroup.getIdIndex()))); + assertTrue(attributesInTable.contains(new MultiKey("test:testGroup", "objectClass", "group"))); + assertTrue(attributesInTable.contains(new MultiKey("test:testGroup", "member", "dn_test.subject.0"))); + assertTrue(attributesInTable.contains(new MultiKey("test:testGroup", "member", "dn_test.subject.1"))); + //object changes + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts().getProvisioningGroups())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts().getProvisioningEntities())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts().getProvisioningMemberships())); + assertEquals(1, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningGroups())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningEntities())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningMemberships())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes().getProvisioningGroups())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes().getProvisioningEntities())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes().getProvisioningMemberships())); + + // field changes + assertEquals(2, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningGroups().iterator().next().getInternal_objectChanges())); + List provisioningObjectChanges = new ArrayList( + grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningGroups().iterator().next().getInternal_objectChanges()); + assertEquals(ProvisioningObjectChangeAction.insert, provisioningObjectChanges.get(0).getProvisioningObjectChangeAction()); + assertEquals(ProvisioningObjectChangeAction.insert, provisioningObjectChanges.get(1).getProvisioningObjectChangeAction()); + assertEquals("member", provisioningObjectChanges.get(0).getAttributeName()); + assertEquals("member", provisioningObjectChanges.get(1).getAttributeName()); + + //get the grouper_sync and check cols + GcGrouperSync gcGrouperSync = GcGrouperSyncDao.retrieveByProvisionerName(null, "sqlProvTest"); + + GcGrouperSyncGroup gcGrouperSyncGroup = gcGrouperSync.getGcGrouperSyncGroupDao().groupRetrieveByGroupId(testGroup.getId()); + assertEquals("cn=test:testGroup,OU=Grouper,OU=365Groups,DC=one,DC=upenn,DC=edu", gcGrouperSyncGroup.getGroupAttributeValueCache2()); + + Member testSubject0member = MemberFinder.findBySubject(grouperSession, SubjectTestHelper.SUBJ0, true); + + GcGrouperSyncMember gcGrouperSyncMember = gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(testSubject0member.getId()); + assertEquals("dn_test.subject.0", gcGrouperSyncMember.getEntityAttributeValueCache2()); + + new GroupSave().assignGroupNameToEdit(testGroup.getName()).assignName(testGroup.getName() + "New").save(); + + //lets sync these over + grouperProvisioner = GrouperProvisioner.retrieveProvisioner("sqlProvTest"); + + grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); + + // make sure some time has passed + GrouperUtil.sleep(1000); + + assertEquals(0, grouperProvisioningOutput.getRecordsWithErrors()); + + sql = "select uuid from testgrouper_prov_ldap_group"; + + dataInTable = new GcDbAccess().sql(sql).selectList(Object[].class); + + groupNamesInTable = new HashSet(); + + for (Object[] row: dataInTable) { + groupNamesInTable.add(new MultiKey(row)); + } + + assertEquals(1, groupNamesInTable.size()); + assertTrue(groupNamesInTable.contains(new MultiKey(new Object[]{"test:testGroupNew"}))); + + sql = "select group_uuid, attribute_name, attribute_value from testgrouper_pro_ldap_group_attr"; + + dataInTable = new GcDbAccess().sql(sql).selectList(Object[].class); + + attributesInTable = new HashSet(); + + for (Object[] row: dataInTable) { + attributesInTable.add(new MultiKey(row)); + } + + assertEquals(6, attributesInTable.size()); + + assertTrue(attributesInTable.contains(new MultiKey("test:testGroupNew", "cn", "test:testGroupNew"))); + assertTrue(attributesInTable.contains(new MultiKey("test:testGroupNew", "dn", "cn=test:testGroupNew,OU=Grouper,OU=365Groups,DC=one,DC=upenn,DC=edu"))); + assertTrue(attributesInTable.contains(new MultiKey("test:testGroupNew", "gidNumber", "" + testGroup.getIdIndex()))); + assertTrue(attributesInTable.contains(new MultiKey("test:testGroupNew", "objectClass", "group"))); + assertTrue(attributesInTable.contains(new MultiKey("test:testGroupNew", "member", "dn_test.subject.0"))); + assertTrue(attributesInTable.contains(new MultiKey("test:testGroupNew", "member", "dn_test.subject.1"))); + //object changes + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts().getProvisioningGroups())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts().getProvisioningEntities())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectInserts().getProvisioningMemberships())); + assertEquals(1, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningGroups())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningEntities())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningMemberships())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes().getProvisioningGroups())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes().getProvisioningEntities())); + assertEquals(0, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectDeletes().getProvisioningMemberships())); + + // field changes + assertEquals(3, GrouperUtil.length(grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningGroups().iterator().next().getInternal_objectChanges())); + provisioningObjectChanges = new ArrayList( + grouperProvisioner.retrieveGrouperProvisioningDataChanges().getTargetObjectUpdates().getProvisioningGroups().iterator().next().getInternal_objectChanges()); + assertEquals(ProvisioningObjectChangeAction.update, provisioningObjectChanges.get(0).getProvisioningObjectChangeAction()); + assertEquals(ProvisioningObjectChangeAction.update, provisioningObjectChanges.get(1).getProvisioningObjectChangeAction()); + assertEquals(ProvisioningObjectChangeAction.update, provisioningObjectChanges.get(2).getProvisioningObjectChangeAction()); + + //get the grouper_sync and check cols + gcGrouperSync = GcGrouperSyncDao.retrieveByProvisionerName(null, "sqlProvTest"); + + gcGrouperSyncGroup = gcGrouperSync.getGcGrouperSyncGroupDao().groupRetrieveByGroupId(testGroup.getId()); + assertEquals("cn=test:testGroupNew,OU=Grouper,OU=365Groups,DC=one,DC=upenn,DC=edu", gcGrouperSyncGroup.getGroupAttributeValueCache2()); + + testSubject0member = MemberFinder.findBySubject(grouperSession, SubjectTestHelper.SUBJ0, true); + + gcGrouperSyncMember = gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(testSubject0member.getId()); + assertEquals("dn_test.subject.0", gcGrouperSyncMember.getEntityAttributeValueCache2()); + + } + + public void configureLdapPaTestCase() { SqlProvisionerTestUtils.configureSqlProvisioner(new SqlProvisionerTestConfigInput() - .assignGroupDeleteType("deleteGroupsDeletedGrouper") + .assignGroupDeleteType("deleteGroupsIfGrouperDeleted") .assignMembershipDeleteType("deleteMembershipsIfNotExistInGrouper") .assignEntityAttributesTable(true) .assignGroupAttributesTable(true) @@ -2745,7 +3215,7 @@ public void testSimpleGroupLdapPaRealTime() { new GcDbAccess().sql("insert into testgrouper_pro_dap_entity_attr (entity_uuid, entity_attribute_name, entity_attribute_value) values (?,?,?)") .addBindVar(uuid).addBindVar("dn").addBindVar(dn).executeSql(); new GcDbAccess().sql("insert into testgrouper_pro_dap_entity_attr (entity_uuid, entity_attribute_name, entity_attribute_value) values (?,?,?)") - .addBindVar(uuid).addBindVar("employeeID").addBindVar("test.subject." + i).executeSql(); + .addBindVar(uuid).addBindVar("employeeId").addBindVar("test.subject." + i).executeSql(); } @@ -2884,7 +3354,7 @@ public void testSimpleGroupLdapPaRealTimeAddMember() { new GcDbAccess().sql("insert into testgrouper_pro_dap_entity_attr (entity_uuid, entity_attribute_name, entity_attribute_value) values (?,?,?)") .addBindVar(uuid).addBindVar("dn").addBindVar(dn).executeSql(); new GcDbAccess().sql("insert into testgrouper_pro_dap_entity_attr (entity_uuid, entity_attribute_name, entity_attribute_value) values (?,?,?)") - .addBindVar(uuid).addBindVar("employeeID").addBindVar("test.subject." + i).executeSql(); + .addBindVar(uuid).addBindVar("employeeId").addBindVar("test.subject." + i).executeSql(); } @@ -2921,7 +3391,7 @@ public void testSimpleGroupLdapPaRealTimeAddMember() { assertTrue(System.currentTimeMillis() > gcGrouperSyncGroup.getInTargetStart().getTime()); assertNull(gcGrouperSyncGroup.getInTargetEnd()); assertTrue(started < gcGrouperSyncGroup.getProvisionableStart().getTime()); - assertEquals("cn=test:testGroup,OU=Grouper,OU=365Groups,DC=one,DC=upenn,DC=edu", gcGrouperSyncGroup.getGroupToId2()); + assertEquals("cn=test:testGroup,OU=Grouper,OU=365Groups,DC=one,DC=upenn,DC=edu", gcGrouperSyncGroup.getGroupAttributeValueCache2()); Hib3GrouperLoaderLog hib3GrouperLoaderLog = null; @@ -3068,6 +3538,7 @@ private void setupFailsafeJob() { .assignEntityAttributeCount(5) .assignGroupAttributeCount(4) .assignMembershipAttributeCount(3) + .assignFailsafeDefaults(true) ); // this closes the grouper session @@ -3186,7 +3657,10 @@ public void testSimpleGroupMembershipProvisioningFullWithAttributesTableRequired .assignGroupTableName("testgrouper_prov_group") .assignGroupTableIdColumn("uuid") .assignGroupAttributeCount(1) + .addExtraConfig("group2advanced", "true") .addExtraConfig("groupsRequireMembers", "true") + .assignOperateOnGrouperMemberships(false) + .assignProvisioningType(null) ); // this closes the grouper session @@ -3580,7 +4054,7 @@ public void testSimpleGroupLdapPaMatchingIdMissingValidation() { new GcDbAccess().sql("insert into testgrouper_pro_dap_entity_attr (entity_uuid, entity_attribute_name, entity_attribute_value) values (?,?,?)") .addBindVar(uuid).addBindVar("dn").addBindVar(dn).executeSql(); new GcDbAccess().sql("insert into testgrouper_pro_dap_entity_attr (entity_uuid, entity_attribute_name, entity_attribute_value) values (?,?,?)") - .addBindVar(uuid).addBindVar("employeeID").addBindVar("test.subject." + i).executeSql(); + .addBindVar(uuid).addBindVar("employeeId").addBindVar("test.subject." + i).executeSql(); } @@ -3801,4 +4275,87 @@ public void testSimpleGroupLdapPaMatchingIdMissingValidation() { } + public void testSimpleMembershipGroupNameSubjectIdDeleteLogDaemon() { + GrouperLoader.runOnceByJobName(grouperSession, "OTHER_JOB_deleteOldSyncLogs"); + Hib3GrouperLoaderLog hib3GrouperLoaderLog = Hib3GrouperLoaderLog.retrieveMostRecentLog("OTHER_JOB_deleteOldSyncLogs"); + + assertEquals(0, GrouperUtil.intValue(hib3GrouperLoaderLog.getDeleteCount(), 0)); + + SqlProvisionerTestUtils.configureSqlProvisioner(new SqlProvisionerTestConfigInput() + .assignMembershipDeleteType("deleteMembershipsIfNotExistInGrouper") + .assignMembershipTableName("testgrouper_prov_mship0") + // .assignMembershipTableIdColumn("group_name, subject_id") + // .assignMembershipGroupForeignKeyColumn("group_name") + // .assignMembershipEntityForeignKeyColumn("subject_id") + .assignMembershipAttributeCount(2) + ); + + Stem stem = new StemSave(this.grouperSession).assignName("test").save(); + Stem stem2 = new StemSave(this.grouperSession).assignName("test2").save(); + + // mark some folders to provision + Group testGroup = new GroupSave(this.grouperSession).assignName("test:testGroup").save(); + Group testGroup2 = new GroupSave(this.grouperSession).assignName("test2:testGroup2").save(); + + testGroup.addMember(SubjectTestHelper.SUBJ0, false); + testGroup.addMember(SubjectTestHelper.SUBJ1, false); + + testGroup2.addMember(SubjectTestHelper.SUBJ2, false); + testGroup2.addMember(SubjectTestHelper.SUBJ3, false); + + final GrouperProvisioningAttributeValue attributeValue = new GrouperProvisioningAttributeValue(); + attributeValue.setDirectAssignment(true); + attributeValue.setDoProvision("sqlProvTest"); + attributeValue.setTargetName("sqlProvTest"); + attributeValue.setStemScopeString("sub"); + + GrouperProvisioningService.saveOrUpdateProvisioningAttributes(attributeValue, stem); + + //AttributeAssign attributeAssign = stem.getAttributeDelegate().addAttribute(GrouperProvisioningAttributeNames.retrieveAttributeDefNameMarker()).getAttributeAssign(); + //attributeAssign.getAttributeValueDelegate().assignValueString(GrouperProvisioningAttributeNames.retrieveAttributeDefNameDoProvision()) + + //lets sync these over + GrouperProvisioner grouperProvisioner = GrouperProvisioner.retrieveProvisioner("sqlProvTest"); + + GrouperProvisioningOutput grouperProvisioningOutput = grouperProvisioner.provision(GrouperProvisioningType.fullProvisionFull); + assertEquals(0, grouperProvisioningOutput.getRecordsWithErrors()); + + String sql = "select group_name, subject_id from testgrouper_prov_mship0"; + + List dataInTable = new GcDbAccess().sql(sql).selectList(Object[].class); + + Set membershipsInTable = new HashSet(); + + for (Object[] row: dataInTable) { + membershipsInTable.add(new MultiKey(row)); + } + + assertEquals(2, membershipsInTable.size()); + assertTrue(membershipsInTable.contains(new MultiKey("test:testGroup", "test.subject.0"))); + assertTrue(membershipsInTable.contains(new MultiKey("test:testGroup", "test.subject.1"))); + + // sleep so we can find most recent + GrouperUtil.sleep(5000); + GrouperLoader.runOnceByJobName(grouperSession, "OTHER_JOB_deleteOldSyncLogs"); + hib3GrouperLoaderLog = Hib3GrouperLoaderLog.retrieveMostRecentLog("OTHER_JOB_deleteOldSyncLogs"); + + assertEquals(0, GrouperUtil.intValue(hib3GrouperLoaderLog.getDeleteCount(), 0)); + + int count = new GcDbAccess().sql("select count(1) from grouper_sync_log").select(int.class); + assertTrue(count + "", count > 0); + + List ids = new GcDbAccess().sql("select id from grouper_sync_log").selectList(String.class); + String id = GrouperUtil.listPopOne(ids); + + new GcDbAccess().sql("update grouper_sync_log set last_updated = ? where id = ?").addBindVar(new Timestamp(System.currentTimeMillis() - (1000*60*60*24*8))).addBindVar(id).executeSql(); + + // sleep so we can find most recent + GrouperUtil.sleep(5000); + GrouperLoader.runOnceByJobName(grouperSession, "OTHER_JOB_deleteOldSyncLogs"); + hib3GrouperLoaderLog = Hib3GrouperLoaderLog.retrieveMostRecentLog("OTHER_JOB_deleteOldSyncLogs"); + + assertEquals(1, GrouperUtil.intValue(hib3GrouperLoaderLog.getDeleteCount(), 0)); + assertEquals(count-1, new GcDbAccess().sql("select count(1) from grouper_sync_log").select(int.class).intValue()); + + } } diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerTestConfigInput.java b/grouper/src/test/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerTestConfigInput.java index 1758dedb0881..404d505de7ee 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerTestConfigInput.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerTestConfigInput.java @@ -13,6 +13,34 @@ */ public class SqlProvisionerTestConfigInput { + private boolean operateOnGrouperMemberships = true; + + + + public boolean isOperateOnGrouperMemberships() { + return operateOnGrouperMemberships; + } + + + public SqlProvisionerTestConfigInput assignOperateOnGrouperMemberships(boolean operateOnGrouperMemberships) { + this.operateOnGrouperMemberships = operateOnGrouperMemberships; + return this; + } + + private boolean failsafeDefaults; + + + + public boolean isFailsafeDefaults() { + return failsafeDefaults; + } + + + public SqlProvisionerTestConfigInput assignFailsafeDefaults(boolean failsafeDefaults) { + this.failsafeDefaults = failsafeDefaults; + return this; + } + /** * if has target entity link */ diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerTestUtils.java b/grouper/src/test/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerTestUtils.java index 51efcece869a..c50f18b4a696 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerTestUtils.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/sqlProvisioning/SqlProvisionerTestUtils.java @@ -38,15 +38,16 @@ public static void configureSqlProvisioner(SqlProvisionerTestConfigInput provisi configureProvisionerSuffix(provisioningTestConfigInput, "debugLog", "true"); if (!StringUtils.isBlank(provisioningTestConfigInput.getEntityDeleteType())) { - configureProvisionerSuffix(provisioningTestConfigInput, "deleteEntities", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "customizeEntityCrud", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "makeChangesToEntities", "true"); configureProvisionerSuffix(provisioningTestConfigInput, provisioningTestConfigInput.getEntityDeleteType(), "true"); } - if (!StringUtils.isBlank(provisioningTestConfigInput.getEntityDeleteType())) { - configureProvisionerSuffix(provisioningTestConfigInput, "deleteEntities", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, provisioningTestConfigInput.getEntityDeleteType(), "true"); + if (!StringUtils.isBlank(provisioningTestConfigInput.getGroupDeleteType())) { + configureProvisionerSuffix(provisioningTestConfigInput, "customizeGroupCrud", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, provisioningTestConfigInput.getGroupDeleteType(), "true"); } if (!StringUtils.isBlank(provisioningTestConfigInput.getMembershipDeleteType())) { - configureProvisionerSuffix(provisioningTestConfigInput, "deleteMemberships", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "customizeMembershipCrud", "true"); configureProvisionerSuffix(provisioningTestConfigInput, provisioningTestConfigInput.getMembershipDeleteType(), "true"); } if (provisioningTestConfigInput.isEntityResolverGlobal()) { @@ -97,7 +98,9 @@ public static void configureSqlProvisioner(SqlProvisionerTestConfigInput provisi configureProvisionerSuffix(provisioningTestConfigInput, "entityResolver.sqlMappingType", "entityAttribute"); configureProvisionerSuffix(provisioningTestConfigInput, "entityResolver.subjectSearchMatchingColumn", "subject_id_or_identifier"); configureProvisionerSuffix(provisioningTestConfigInput, "entityResolver.tableOrViewName", "testgrouper_prov_entity1"); - + configureProvisionerSuffix(provisioningTestConfigInput, "entityResolver.columnNames", "subject_id_or_identifier, school, subject_source_id"); + + } if (provisioningTestConfigInput.isEntityAttributesTable()) { @@ -106,20 +109,25 @@ public static void configureSqlProvisioner(SqlProvisionerTestConfigInput provisi configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributesAttributeNameColumn", "entity_attribute_name"); configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributesAttributeValueColumn", "entity_attribute_value"); configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributesEntityForeignKeyColumn", "entity_uuid"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributesTableName", "testgrouper_pro_dap_entity_attr"); + configureProvisionerSuffix(provisioningTestConfigInput, "entity2advanced", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributesLastModifiedColumn", "last_modified"); configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributesLastModifiedColumnType", "timestamp"); - configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributesTableName", "testgrouper_pro_dap_entity_attr"); + + } + + if (provisioningTestConfigInput.isFailsafeDefaults()) { + configureProvisionerSuffix(provisioningTestConfigInput, "showFailsafe", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "failsafeMaxOverallPercentGroupsRemove", "-1"); + configureProvisionerSuffix(provisioningTestConfigInput, "failsafeMaxOverallPercentMembershipsRemove", "-1"); + configureProvisionerSuffix(provisioningTestConfigInput, "failsafeMaxPercentRemove", "-1"); + configureProvisionerSuffix(provisioningTestConfigInput, "failsafeMinGroupSize", "-1"); + configureProvisionerSuffix(provisioningTestConfigInput, "failsafeMinManagedGroups", "-1"); + configureProvisionerSuffix(provisioningTestConfigInput, "failsafeMinOverallNumberOfMembers", "-1"); + configureProvisionerSuffix(provisioningTestConfigInput, "failsafeSendEmail", "false"); + configureProvisionerSuffix(provisioningTestConfigInput, "failsafeUse", "true"); } - configureProvisionerSuffix(provisioningTestConfigInput, "showFailsafe", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "failsafeMaxOverallPercentGroupsRemove", "-1"); - configureProvisionerSuffix(provisioningTestConfigInput, "failsafeMaxOverallPercentMembershipsRemove", "-1"); - configureProvisionerSuffix(provisioningTestConfigInput, "failsafeMaxPercentRemove", "-1"); - configureProvisionerSuffix(provisioningTestConfigInput, "failsafeMinGroupSize", "-1"); - configureProvisionerSuffix(provisioningTestConfigInput, "failsafeMinManagedGroups", "-1"); - configureProvisionerSuffix(provisioningTestConfigInput, "failsafeMinOverallNumberOfMembers", "-1"); - configureProvisionerSuffix(provisioningTestConfigInput, "failsafeSendEmail", "false"); - configureProvisionerSuffix(provisioningTestConfigInput, "failsafeUse", "true"); if (provisioningTestConfigInput.isGroupAttributesTable()) { configureProvisionerSuffix(provisioningTestConfigInput, "useSeparateTableForGroupAttributes", "true"); @@ -127,9 +135,10 @@ public static void configureSqlProvisioner(SqlProvisionerTestConfigInput provisi configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributesAttributeNameColumn", "attribute_name"); configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributesAttributeValueColumn", "attribute_value"); configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributesGroupForeignKeyColumn", "group_uuid"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributesTableName", "testgrouper_pro_ldap_group_attr"); + configureProvisionerSuffix(provisioningTestConfigInput, "group2advanced", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributesLastModifiedColumn", "last_modified"); configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributesLastModifiedColumnType", "timestamp"); - configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributesTableName", "testgrouper_pro_ldap_group_attr"); } if (!StringUtils.isBlank(provisioningTestConfigInput.getGroupTableIdColumn())) { configureProvisionerSuffix(provisioningTestConfigInput, "groupTableIdColumn", provisioningTestConfigInput.getGroupTableIdColumn()); @@ -144,8 +153,10 @@ public static void configureSqlProvisioner(SqlProvisionerTestConfigInput provisi configureProvisionerSuffix(provisioningTestConfigInput, "hasTargetGroupLink", "true"); } - configureProvisionerSuffix(provisioningTestConfigInput, "customizeMembershipCrud", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "insertMemberships", "true"); + if (provisioningTestConfigInput.isOperateOnGrouperMemberships()) { + configureProvisionerSuffix(provisioningTestConfigInput, "customizeMembershipCrud", "true"); + } + configureProvisionerSuffix(provisioningTestConfigInput, "logAllObjectsVerbose", "true"); if (!StringUtils.isBlank(provisioningTestConfigInput.getMembershipEntityForeignKeyColumn())) { configureProvisionerSuffix(provisioningTestConfigInput, "membershipEntityForeignKeyColumn", provisioningTestConfigInput.getMembershipEntityForeignKeyColumn()); @@ -153,78 +164,116 @@ public static void configureSqlProvisioner(SqlProvisionerTestConfigInput provisi if (!StringUtils.isBlank(provisioningTestConfigInput.getMembershipGroupForeignKeyColumn())) { configureProvisionerSuffix(provisioningTestConfigInput, "membershipGroupForeignKeyColumn", provisioningTestConfigInput.getMembershipGroupForeignKeyColumn()); } - if (!StringUtils.isBlank(provisioningTestConfigInput.getMembershipTableIdColumn())) { - configureProvisionerSuffix(provisioningTestConfigInput, "membershipPrimaryKey", provisioningTestConfigInput.getMembershipTableIdColumn()); - } if (!StringUtils.isBlank(provisioningTestConfigInput.getMembershipTableName())) { configureProvisionerSuffix(provisioningTestConfigInput, "membershipTableName", provisioningTestConfigInput.getMembershipTableName()); } - - configureProvisionerSuffix(provisioningTestConfigInput, "subjectSourcesToProvision", "jdbc"); + if (provisioningTestConfigInput.isOperateOnGrouperMemberships()) { + configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperEntities", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "subjectSourcesToProvision", "jdbc"); + } + if (provisioningTestConfigInput.getEntityAttributeCount() > 0) { configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperEntities", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "numberOfEntityAttributes", "" + provisioningTestConfigInput.getEntityAttributeCount()); - configureProvisionerSuffix(provisioningTestConfigInput, "selectEntities", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "customizeEntityCrud", "true"); if (provisioningTestConfigInput.getEntityAttributeCount() != 3) { - configureProvisionerSuffix(provisioningTestConfigInput, "insertEntities", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "updateEntities", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "makeChangesToEntities", "true"); } + configureProvisionerSuffix(provisioningTestConfigInput, "selectAllEntities", "true"); + + } else { + if (provisioningTestConfigInput.isOperateOnGrouperMemberships()) { + + configureProvisionerSuffix(provisioningTestConfigInput, "customizeEntityCrud", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "selectEntities", "false"); + } } if (provisioningTestConfigInput.getEntityAttributeCount() == 3) { configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.name", "dn"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.storageType", "separateAttributesTable"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateToMemberSyncField", "memberToId2"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.name", "employeeID"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.storageType", "separateAttributesTable"); + if (provisioningTestConfigInput.isEntityAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.storageType", "separateAttributesTable"); + } + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2type", "entityAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache2entityAttribute", "dn"); + + + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.name", "employeeId"); + if (provisioningTestConfigInput.isEntityAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.storageType", "separateAttributesTable"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "subjectId"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.searchAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.matchingId", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttribute0name", "employeeId"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.name", "entity_uuid"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.translateExpressionType", "grouperProvisioningEntityField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.translateFromGrouperProvisioningEntityField", "id"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.storageType", "entityTableColumn"); + if (provisioningTestConfigInput.isEntityAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.storageType", "entityTableColumn"); + } } else if (provisioningTestConfigInput.getEntityAttributeCount() >= 5) { - configureProvisionerSuffix(provisioningTestConfigInput, "selectAllEntities", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.name", "uuid"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.storageType", "entityTableColumn"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateExpression", "${edu.internet2.middleware.grouper.internal.util.GrouperUuid.getUuid()}"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateExpressionType", "translationScript"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateGrouperToMemberSyncField", "memberFromId2"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.matchingId", "true"); + if (provisioningTestConfigInput.isEntityAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.storageType", "entityTableColumn"); + } + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateExpressionCreateOnly", "${edu.internet2.middleware.grouper.internal.util.GrouperUuid.getUuid()}"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.translateExpressionTypeCreateOnly", "translationScript"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.0.showAdvancedAttribute", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0source", "grouper"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0type", "entityAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityAttributeValueCache0entityAttribute", "uuid"); + + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "entityMatchingAttribute0name", "name"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.name", "name"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.searchAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.storageType", "entityTableColumn"); + if (provisioningTestConfigInput.isEntityAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.storageType", "entityTableColumn"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateExpressionType", "grouperProvisioningEntityField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.1.translateFromGrouperProvisioningEntityField", "name"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.name", "subject_id_or_identifier"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.storageType", "entityTableColumn"); + if (provisioningTestConfigInput.isEntityAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.storageType", "entityTableColumn"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.translateExpressionType", "grouperProvisioningEntityField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.2.translateFromGrouperProvisioningEntityField", "subjectId"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.name", "email"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.storageType", "entityTableColumn"); + if (provisioningTestConfigInput.isEntityAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.storageType", "entityTableColumn"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.translateExpressionType", "grouperProvisioningEntityField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.3.translateFromGrouperProvisioningEntityField", "email"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.name", "description"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.storageType", "separateAttributesTable"); + if (provisioningTestConfigInput.isEntityAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.storageType", "separateAttributesTable"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateExpressionType", "grouperProvisioningEntityField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.4.translateFromGrouperProvisioningEntityField", "description"); if (provisioningTestConfigInput.getEntityAttributeCount() == 6) { configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.5.name", "school"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.5.storageType", "separateAttributesTable"); + if (provisioningTestConfigInput.isEntityAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.5.storageType", "separateAttributesTable"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.5.translateExpressionType", "translationScript"); configureProvisionerSuffix(provisioningTestConfigInput, "targetEntityAttribute.5.translateExpression", "${grouperProvisioningEntity.retrieveAttributeValueString('entityAttributeResolverLdap__givenname')}"); @@ -242,30 +291,41 @@ public static void configureSqlProvisioner(SqlProvisionerTestConfigInput provisi } if (provisioningTestConfigInput.getGroupAttributeCount() == 1) { configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.name", "uuid"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.storageType", "groupTableColumn"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.matchingId", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.searchAttribute", "true"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.storageType", "groupTableColumn"); + } + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttribute0name", "uuid"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); } if (provisioningTestConfigInput.getGroupAttributeCount() == 3) { - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.matchingId", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttribute0name", "uuid"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.name", "uuid"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.searchAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.storageType", "groupTableColumn"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.storageType", "groupTableColumn"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.matchingId", "false"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.membershipAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.showAttributeValueSettings", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.multiValued", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.name", "subjectId"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.storageType", "separateAttributesTable"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateFromMemberSyncField", "subjectId"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.storageType", "separateAttributesTable"); + } + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMembershipAttributeName", "subjectId"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMembershipAttributeValue", "subjectId"); + + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.name", "groupName"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.storageType", "separateAttributesTable"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.storageType", "separateAttributesTable"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateFromGrouperProvisioningGroupField", "name"); @@ -274,95 +334,157 @@ public static void configureSqlProvisioner(SqlProvisionerTestConfigInput provisi if (provisioningTestConfigInput.getGroupAttributeCount() == 4) { configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.name", "uuid"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.storageType", "groupTableColumn"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpression", "${edu.internet2.middleware.grouper.internal.util.GrouperUuid.getUuid()}"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpressionType", "translationScript"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateGrouperToGroupSyncField", "groupFromId2"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.storageType", "groupTableColumn"); + } + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpressionCreateOnly", "${edu.internet2.middleware.grouper.internal.util.GrouperUuid.getUuid()}"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpressionTypeCreateOnly", "translationScript"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.showAdvancedAttribute", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0source", "grouper"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0type", "groupAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache0groupAttribute", "uuid"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.name", "description"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.storageType", "separateAttributesTable"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.storageType", "separateAttributesTable"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateFromGrouperProvisioningGroupField", "description"); if (provisioningTestConfigInput.isPosixId()) { configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.name", "name"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.searchAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.storageType", "groupTableColumn"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache1has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache1source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache1type", "groupAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache1groupAttribute", "name"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttributeSameAsSearchAttribute", "false"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupSearchAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupSearchAttribute0name", "name"); + + + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.storageType", "groupTableColumn"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateFromGrouperProvisioningGroupField", "name"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.matchingId", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttribute0name", "posix_id"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.name", "posix_id"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.storageType", "groupTableColumn"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.storageType", "groupTableColumn"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.translateFromGrouperProvisioningGroupField", "idIndex"); + + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.showAdvancedAttribute", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.showAttributeValueSettings", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.valueType", "long"); } else { configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.name", "name"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.matchingId", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.searchAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.storageType", "separateAttributesTable"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache1has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache1source", "target"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache1type", "groupAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache1groupAttribute", "name"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttribute0name", "name"); + + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.storageType", "separateAttributesTable"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateFromGrouperProvisioningGroupField", "name"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.membershipAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.showAttributeValueSettings", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.multiValued", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMembershipAttributeName", "subjectId"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMembershipAttributeValue", "subjectId"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.name", "subjectId"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.storageType", "separateAttributesTable"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.translateFromMemberSyncField", "subjectId"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.storageType", "separateAttributesTable"); + } } } if (provisioningTestConfigInput.getGroupAttributeCount() == 6) { configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.name", "cn"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.storageType", "separateAttributesTable"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.storageType", "separateAttributesTable"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.0.translateFromGrouperProvisioningGroupField", "name"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.name", "dn"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.storageType", "separateAttributesTable"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.storageType", "separateAttributesTable"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateExpression", "${'cn=' + grouperProvisioningGroup.getName() + ',OU=Grouper,OU=365Groups,DC=one,DC=upenn,DC=edu'}"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateExpressionType", "translationScript"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.1.translateGrouperToGroupSyncField", "groupToId2"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.matchingId", "true"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCacheHas", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2has", "true"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2source", "grouper"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2type", "groupAttribute"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupAttributeValueCache2groupAttribute", "dn"); + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttributeCount", "1"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMatchingAttribute0name", "gidNumber"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.name", "gidNumber"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.searchAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.storageType", "separateAttributesTable"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.storageType", "separateAttributesTable"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.2.translateFromGrouperProvisioningGroupField", "idIndex"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.showAttributeValueSettings", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.multiValued", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.name", "objectClass"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.storageType", "separateAttributesTable"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.storageType", "separateAttributesTable"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.translateExpression", "${grouperUtil.toSet('group')}"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.3.translateExpressionType", "translationScript"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.membershipAttribute", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.showAttributeValueSettings", "true"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.multiValued", "true"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.name", "member"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.storageType", "separateAttributesTable"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.translateFromMemberSyncField", "memberToId2"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.4.storageType", "separateAttributesTable"); + } + + configureProvisionerSuffix(provisioningTestConfigInput, "groupMembershipAttributeName", "member"); + configureProvisionerSuffix(provisioningTestConfigInput, "groupMembershipAttributeValue", "entityAttributeValueCache2"); + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.name", "uuid"); - configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.storageType", "groupTableColumn"); + if (provisioningTestConfigInput.isGroupAttributesTable()) { + configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.storageType", "groupTableColumn"); + } configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.translateExpressionType", "grouperProvisioningGroupField"); configureProvisionerSuffix(provisioningTestConfigInput, "targetGroupAttribute.5.translateFromGrouperProvisioningGroupField", "name"); } - configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperMemberships", "true"); + if (provisioningTestConfigInput.isOperateOnGrouperMemberships()) { + configureProvisionerSuffix(provisioningTestConfigInput, "operateOnGrouperMemberships", "true"); + } if (provisioningTestConfigInput.getMembershipAttributeCount() > 0) { configureProvisionerSuffix(provisioningTestConfigInput, "numberOfMembershipAttributes", "" + provisioningTestConfigInput.getMembershipAttributeCount()); - for (int i=0;i startWithSuffixToValue = new HashMap<>(); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/tableSync/ProvisioningToSyncTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/tableSync/ProvisioningToSyncTest.java index b574755f11f4..2c6c1b212307 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/tableSync/ProvisioningToSyncTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/tableSync/ProvisioningToSyncTest.java @@ -288,11 +288,11 @@ public void testGcGrouperSyncGroupStoreAndDelete() { assertEquals("abc", gcGrouperSyncGroup.getGroupId()); //try to store an update - gcGrouperSyncGroup.setGroupFromId2("def"); + gcGrouperSyncGroup.setGroupAttributeValueCache0("def"); gcGrouperSync.getGcGrouperSyncGroupDao().internal_groupStore(gcGrouperSyncGroup); gcGrouperSyncGroup = gcGrouperSync.getGcGrouperSyncGroupDao().internal_groupRetrieveFromDbById(gcGrouperSyncGroup.getId()); - assertEquals("def", gcGrouperSyncGroup.getGroupFromId2()); + assertEquals("def", gcGrouperSyncGroup.getGroupAttributeValueCache0()); //try to store a delete gcGrouperSync.getGcGrouperSyncGroupDao().groupDelete(gcGrouperSyncGroup, false, false); @@ -326,8 +326,8 @@ public void testGcGrouperSyncGroupStoreAndDelete() { assertEquals("def", gcGrouperSyncGroup2.getGroupId()); //try to store an update - gcGrouperSyncGroup1.setGroupFromId2("mno"); - gcGrouperSyncGroup2.setGroupFromId2("pqr"); + gcGrouperSyncGroup1.setGroupAttributeValueCache0("mno"); + gcGrouperSyncGroup2.setGroupAttributeValueCache0("pqr"); gcGrouperSyncGroups = new ArrayList(); gcGrouperSyncGroups.add(gcGrouperSyncGroup1); @@ -338,8 +338,8 @@ public void testGcGrouperSyncGroupStoreAndDelete() { gcGrouperSyncGroup1 = gcGrouperSync.getGcGrouperSyncGroupDao().internal_groupRetrieveFromDbById(gcGrouperSyncGroup1.getId()); gcGrouperSyncGroup2 = gcGrouperSync.getGcGrouperSyncGroupDao().internal_groupRetrieveFromDbById(gcGrouperSyncGroup2.getId()); - assertEquals("mno", gcGrouperSyncGroup1.getGroupFromId2()); - assertEquals("pqr", gcGrouperSyncGroup2.getGroupFromId2()); + assertEquals("mno", gcGrouperSyncGroup1.getGroupAttributeValueCache0()); + assertEquals("pqr", gcGrouperSyncGroup2.getGroupAttributeValueCache0()); gcGrouperSyncGroups = new ArrayList(); gcGrouperSyncGroups.add(gcGrouperSyncGroup1); @@ -372,8 +372,8 @@ public void testGcGrouperSyncGroupStoreAndDelete() { GcGrouperSyncGroup gcGrouperSyncGroup6 = gcGrouperSync.getGcGrouperSyncGroupDao().groupRetrieveOrCreateByGroupId("vwx"); //try to store an update - gcGrouperSyncGroup3.setGroupFromId2("mno"); - gcGrouperSyncGroup4.setGroupFromId2("pqr"); + gcGrouperSyncGroup3.setGroupAttributeValueCache0("mno"); + gcGrouperSyncGroup4.setGroupAttributeValueCache0("pqr"); changes = gcGrouperSync.getGcGrouperSyncDao().storeAllObjects() + gcGrouperSync.getInternalObjectsCreatedCount(); @@ -382,11 +382,11 @@ public void testGcGrouperSyncGroupStoreAndDelete() { gcGrouperSyncGroup3 = gcGrouperSync.getGcGrouperSyncGroupDao().internal_groupRetrieveFromDbById(gcGrouperSyncGroup3.getId()); gcGrouperSyncGroup4 = gcGrouperSync.getGcGrouperSyncGroupDao().internal_groupRetrieveFromDbById(gcGrouperSyncGroup4.getId()); - assertEquals("mno", gcGrouperSyncGroup3.getGroupFromId2()); - assertEquals("pqr", gcGrouperSyncGroup4.getGroupFromId2()); + assertEquals("mno", gcGrouperSyncGroup3.getGroupAttributeValueCache0()); + assertEquals("pqr", gcGrouperSyncGroup4.getGroupAttributeValueCache0()); gcGrouperSyncGroup3 = gcGrouperSync.getGcGrouperSyncGroupDao().internal_groupRetrieveFromDbByGroupId(gcGrouperSyncGroup3.getGroupId()); - assertEquals("mno", gcGrouperSyncGroup3.getGroupFromId2()); + assertEquals("mno", gcGrouperSyncGroup3.getGroupAttributeValueCache0()); gcGrouperSyncGroups = gcGrouperSync.getGcGrouperSyncGroupDao().internal_groupRetrieveFromDbAll(); assertEquals(6, gcGrouperSyncGroups.size()); @@ -476,13 +476,13 @@ public void testGcGrouperSyncGroupStoreAndDelete() { // GcGrouperSyncGroup gcGrouperSyncGroup = new GcGrouperSyncGroup(); // gcGrouperSyncGroup.setGrouperSync(gcGrouperSync); // gcGrouperSyncGroup.setLastTimeWorkWasDone(new Timestamp(System.currentTimeMillis() + 2000)); - // gcGrouperSyncGroup.groupFromId2 = "from2"; - // gcGrouperSyncGroup.groupFromId3 = "from3"; + // gcGrouperSyncGroup.groupAttributeValueCache0 = "from2"; + // gcGrouperSyncGroup.groupAttributeValueCache1 = "from3"; // gcGrouperSyncGroup.groupId = "myId"; // gcGrouperSyncGroup.groupIdIndex = 123L; // gcGrouperSyncGroup.groupName = "myName"; - // gcGrouperSyncGroup.groupToId2 = "toId2"; - // gcGrouperSyncGroup.groupToId3 = "toId3"; + // gcGrouperSyncGroup.groupAttributeValueCache2 = "toId2"; + // gcGrouperSyncGroup.groupAttributeValueCache3 = "toId3"; // gcGrouperSyncGroup.inTargetDb = "T"; // gcGrouperSyncGroup.inTargetInsertOrExistsDb = "T"; // gcGrouperSyncGroup.inTargetEnd = new Timestamp(123L); @@ -498,7 +498,7 @@ public void testGcGrouperSyncGroupStoreAndDelete() { // gcGrouperSyncGroup = gcGrouperSync.groupRetrieveByGroupId("myId"); // System.out.println(gcGrouperSyncGroup); // - // gcGrouperSyncGroup.setGroupToId2("toId2a"); + // gcGrouperSyncGroup.setGroupAttributeValueCache2("toId2a"); // gcGrouperSync.internal_groupStore(gcGrouperSyncGroup); // // System.out.println("updated"); diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/upgradeTasks/UpgradeTasksJobTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/upgradeTasks/UpgradeTasksJobTest.java index 16ce43c4a110..7e4468f4bd04 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/upgradeTasks/UpgradeTasksJobTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/upgradeTasks/UpgradeTasksJobTest.java @@ -39,258 +39,6 @@ public UpgradeTasksJobTest(String name) { } - public static void v8configure() { - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.class").value(SqlProvisioner.class.getName()).store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.dbExternalSystemConfigId").value("grouper").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.subjectSourcesToProvision").value("jdbc").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.logAllObjectsVerbose").value("true").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.provisioningType").value("groupAttributes").store(); - - //TODO make an attribute config for this - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.hasTargetEntityLink").value("true").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.numberOfGroupAttributes").value("6").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.name").value("cn").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.valueType").value("string").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.insert").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.select").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.multiValued").value("false").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.storageType").value("separateAttributesTable").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.translateExpressionType").value("grouperProvisioningGroupField").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.translateFromGrouperProvisioningGroupField").value("name").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.1.name").value("dn").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.1.valueType").value("string").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.1.insert").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.1.select").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.1.multiValued").value("false").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.1.translateExpressionType").value("translationScript").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.1.translateExpression").value("${'cn=' + grouperProvisioningGroup.getName() + ',OU=Grouper,OU=365Groups,DC=one,DC=upenn,DC=edu'}").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.1.translateGrouperToGroupSyncField").value("groupToId2").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.1.storageType").value("separateAttributesTable").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.2.name").value("gidNumber").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.2.valueType").value("long").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.2.insert").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.2.select").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.2.matchingId").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.2.searchAttribute").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.2.multiValued").value("false").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.2.translateExpressionType").value("grouperProvisioningGroupField").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.2.translateFromGrouperProvisioningGroupField").value("idIndex").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.2.storageType").value("separateAttributesTable").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.3.name").value("objectClass").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.3.insert").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.3.select").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.3.multiValued").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.3.translateExpressionType").value("translationScript").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.3.translateExpression").value("${grouperUtil.toSet('group')}").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.3.storageType").value("separateAttributesTable").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.4.name").value("member").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.4.select").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.4.insert").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.4.update").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.4.membershipAttribute").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.4.multiValued").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.4.translateFromMemberSyncField").value("memberToId2").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.4.storageType").value("separateAttributesTable").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.5.name").value("uuid").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.5.select").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.5.insert").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.5.translateExpressionType").value("grouperProvisioningGroupField").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.5.translateFromGrouperProvisioningGroupField").value("name").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.5.storageType").value("groupTableColumn").store(); - - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.numberOfEntityAttributes").value("3").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.0.name").value("dn").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.0.select").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.0.storageType").value("separateAttributesTable").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.0.translateToMemberSyncField").value("memberToId2").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.1.name").value("employeeID").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.1.select").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.1.searchAttribute").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.1.matchingId").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.1.translateExpressionType").value("grouperProvisioningEntityField").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.1.translateFromGrouperProvisioningEntityField").value("subjectId").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.1.storageType").value("separateAttributesTable").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.2.name").value("entity_uuid").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.2.select").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.2.storageType").value("entityTableColumn").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.operateOnGrouperGroups").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.operateOnGrouperMemberships").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.operateOnGrouperEntities").value("true").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.insertEntities").value("false").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteEntities").value("false").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.insertGroups").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.updateGroups").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteGroups").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteGroupsIfNotExistInGrouper").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.selectGroups").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.selectEntities").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.selectMemberships").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.insertMemberships").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteMemberships").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteMembershipsIfNotExistInGrouper").value("true").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.groupTableName").value("testgrouper_prov_ldap_group").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.groupTableIdColumn").value("uuid").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.groupAttributesTableName").value("testgrouper_pro_ldap_group_attr").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.groupAttributesGroupForeignKeyColumn").value("group_uuid").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.groupAttributesAttributeNameColumn").value("attribute_name").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.groupAttributesAttributeValueColumn").value("attribute_value").store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.userTableName").value("testgrouper_prov_ldap_entity").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.userPrimaryKey").value("entity_uuid").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.entityAttributesTableName").value("testgrouper_pro_dap_entity_attr").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.entityAttributesEntityForeignKeyColumn").value("entity_uuid").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.entityAttributesAttributeNameColumn").value("entity_attribute_name").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.entityAttributesAttributeValueColumn").value("entity_attribute_value").store(); - - - } - - - public void test_v8_provisioningFieldNameToAttributeChange() { - - // GRP-3927: There is no provisioning concept of field anymore, only attribute - - v8configure(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.name").delete(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.fieldName").value("abc").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.isFieldElseAttribute").value("true").store(); - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningFieldNameToAttributeChange()); - - assertEquals("abc", GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner.pspng_oneprod.targetGroupAttribute.0.name")); - assertTrue(StringUtils.isBlank(GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner.pspng_oneprod.targetGroupAttribute.0.fieldName"))); - assertTrue(StringUtils.isBlank(GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner.pspng_oneprod.targetGroupAttribute.0.isFieldElseAttribute"))); - - assertFalse(UpgradeTasks.v8_provisioningFieldNameToAttributeChange()); - - } - - /** - */ - public void test_v8_provisioningLdapDnAttributeChange() { - - // GRP-3931: change ldap DN from field name to attribute ldap_dn - - v8configure(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.class").value(LdapSync.class.getName()).store(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.name").delete(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.fieldName").value("name").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.0.isFieldElseAttribute").value("true").store(); - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningLdapDnAttributeChange()); - - assertEquals("ldap_dn", GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner.pspng_oneprod.targetGroupAttribute.0.name")); - assertTrue(StringUtils.isBlank(GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner.pspng_oneprod.targetGroupAttribute.0.fieldName"))); - assertEquals("false", GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner.pspng_oneprod.targetGroupAttribute.0.isFieldElseAttribute")); - - assertFalse(UpgradeTasks.v8_provisioningLdapDnAttributeChange()); - - } - - /** - * - */ - public void test_v8_provisioningEntityResolverRefactor() { - - // FROM provisioner.genericProvisioner.entityAttributesNotInSubjectSource - // TO provisioner.genericProvisioner.entityResolver.entityAttributesNotInSubjectSource - - // GRP-3939: Refactor entity attribute resolver config - - v8configure(); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.filterPart").value("abc").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.globalLDAPResolver").value("def").store(); - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningEntityResolverRefactor()); - - assertEquals(GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner.pspng_oneprod.entityResolver.filterPart"), "abc"); - assertTrue(StringUtils.isBlank(GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner.pspng_oneprod.filterPart"))); - - assertEquals(GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner.pspng_oneprod.entityResolver.globalLDAPResolver"), "def"); - assertTrue(StringUtils.isBlank(GrouperLoaderConfig.retrieveConfig().propertyValueString("provisioner.pspng_oneprod.globalLDAPResolver"))); - - assertFalse(UpgradeTasks.v8_provisioningEntityResolverRefactor()); - } - - /** - * - */ - public void test_v8_provisioningMembershipObjectCrudDefault() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.customizeMembershipCrud", false)); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteMembershipsIfNotExistInGrouper").delete(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteMembershipsIfGrouperCreated").value("true").store(); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningCustomizeMembershipCrud()); - - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.customizeMembershipCrud")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.insertMemberships")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.selectMemberships")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteMemberships")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteMembershipsIfNotExistInGrouper")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteMembershipsIfGrouperDeleted")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteMembershipsIfGrouperCreated")); - - // this will convert again so dont do twice - //assertFalse(UpgradeTasks.v8_provisioningCustomizeMembershipCrud()); - - } - - /** - * - */ - public void test_v8_provisioningMembershipObjectCrudDefault2() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.customizeMembershipCrud", false)); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.insertMemberships").delete(); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningCustomizeMembershipCrud()); - - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.customizeMembershipCrud", false)); - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.insertMemberships", true)); - assertTrue(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.selectMemberships")); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.deleteMemberships", false)); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.deleteMembershipsIfNotExistInGrouper", false)); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteMembershipsIfGrouperDeleted")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteMembershipsIfGrouperCreated")); - - // this will convert again so dont do twice - assertFalse(UpgradeTasks.v8_provisioningCustomizeMembershipCrud()); - - } - /** * */ @@ -362,344 +110,4 @@ public void testVersion1() { assertEquals(GrouperDAOFactory.getFactory().getPITGroupSet().findBySourceId(gs3.getId(), false).size(), 1); assertEquals(GrouperDAOFactory.getFactory().getPITGroupSet().findBySourceId(gs4.getId(), false).size(), 1); } - - /** - * - */ - public void test_v8_provisioningGroupObjectCrudDefault() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.customizeGroupCrud", false)); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteGroupsIfNotExistInGrouper").delete(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteGroupsIfGrouperCreated").value("true").store(); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningCustomizeGroupCrud()); - - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.customizeGroupCrud")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.insertGroups")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.updateGroups")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.selectGroups")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteGroups")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteGroupsIfNotExistInGrouper")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteGroupsIfGrouperDeleted")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteGroupsIfGrouperCreated")); - - // this will convert again so dont do twice - //assertFalse(UpgradeTasks.v8_provisioningCustomizeGroupCrud()); - - } - - /** - * - */ - public void test_v8_provisioningGroupObjectCrudDefault2() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.customizeGroupCrud", false)); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.insertGroups").delete(); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningCustomizeGroupCrud()); - - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.customizeGroupCrud", false)); - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.insertGroups", true)); - assertTrue(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.selectGroups")); - assertTrue(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.updateGroups")); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.deleteGroups", false)); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.deleteGroupsIfNotExistInGrouper", false)); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteGroupsIfGrouperDeleted")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteGroupsIfGrouperCreated")); - - // this will convert again so dont do twice - assertFalse(UpgradeTasks.v8_provisioningCustomizeGroupCrud()); - - } - - /** - * - */ - public void test_v8_provisioningEntityObjectCrudDefault() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.customizeEntityCrud", false)); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.insertEntities").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.updateEntities").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteEntities").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteEntitiesIfGrouperCreated").value("true").store(); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningCustomizeEntityCrud()); - - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.makeChangesToEntities")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.customizeGroupCrud")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.insertEntities")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.updateEntities")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.selectEntities")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteEntities")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteEntitiesIfNotExistInGrouper")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteEntitiesIfGrouperDeleted")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteEntitiesIfGrouperCreated")); - - // this will convert again so dont do twice - assertFalse(UpgradeTasks.v8_provisioningCustomizeEntityCrud()); - - } - - /** - * - */ - public void test_v8_provisioningEntityObjectCrudDefaultRO() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.customizeEntityCrud", false)); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.insertEntities").delete(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.updateEntities").delete(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteEntities").delete(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteEntitiesIfGrouperCreated").delete(); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningCustomizeEntityCrud()); - - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.makeChangesToEntities")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.customizeGroupCrud")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.insertEntities")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.updateEntities")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.selectEntities")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteEntities")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteEntitiesIfNotExistInGrouper")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteEntitiesIfGrouperDeleted")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteEntitiesIfGrouperCreated")); - - // this will convert again so dont do twice - //assertFalse(UpgradeTasks.v8_provisioningCustomizeEntityCrud()); - - } - - /** - * - */ - public void test_v8_provisioningMembershipAttributeShowValidation() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.targetMembershipAttribute.3.showAttributeValidation", false)); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetMembershipAttribute.3.name").value("abc").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetMembershipAttribute.3.defaultValue").value("true").store(); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningMembershipShowAttributeValueSettings()); - - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetMembershipAttribute.3.showAttributeValidation")); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetMembershipAttribute.3.defaultValue")); - - // this will not convert again - assertFalse(UpgradeTasks.v8_provisioningMembershipShowAttributeValueSettings()); - - } - - /** - * - */ - public void test_v8_provisioningMembershipAttributeShowAttributeValueSettings() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.targetMembershipAttribute.3.showAttributeValueSettings", false)); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetMembershipAttribute.3.name").value("abc").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetMembershipAttribute.3.valueType").value("true").store(); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningMembershipShowAttributeValueSettings()); - - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetMembershipAttribute.3.showAttributeValueSettings")); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetMembershipAttribute.3.valueType")); - - // this will not convert again - assertFalse(UpgradeTasks.v8_provisioningMembershipShowAttributeValueSettings()); - - } - - /** - * - */ - public void test_v8_provisioningGroupAttributeShowAttributeValueSettings() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.targetGroupAttribute.0.showAttributeValueSettings", false)); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningGroupShowAttributeValueSettings()); - - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetGroupAttribute.0.showAttributeValueSettings")); - assertTrue(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.targetGroupAttribute.0.valueType")); - - // this will not convert again - assertFalse(UpgradeTasks.v8_provisioningGroupShowAttributeValueSettings()); - - } - - /** - * - */ - public void test_v8_provisioningGroupAttributeShowValidation() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.targetGroupAttribute.3.showAttributeValidation", false)); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetGroupAttribute.3.required").value("true").store(); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningGroupShowValidation()); - - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetGroupAttribute.3.showAttributeValidation")); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetGroupAttribute.3.required")); - - // this will not convert again - assertFalse(UpgradeTasks.v8_provisioningGroupShowValidation()); - - } - - /** - * - */ - public void test_v8_provisioningEntityAttributeShowValidation() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.targetEntityAttribute.3.showAttributeValidation", false)); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetEntityAttribute.3.required").value("true").store(); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningEntityShowValidation()); - - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetEntityAttribute.3.showAttributeValidation")); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetEntityAttribute.3.required")); - - // this will not convert again - assertFalse(UpgradeTasks.v8_provisioningEntityShowValidation()); - - } - - /** - * - */ - public void test_v8_provisioningEntityObjectCrudDefault2() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.customizeEntityCrud", false)); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.insertEntities").delete(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.updateEntities").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteEntities").value("true").store(); - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.deleteEntitiesIfNotExistInGrouper").value("true").store(); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningCustomizeEntityCrud()); - - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.makeChangesToEntities")); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.customizeEntityCrud")); - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.insertEntities")); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.selectEntities")); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.updateEntities")); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.deleteEntities")); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.deleteEntitiesIfNotExistInGrouper")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteEntitiesIfGrouperDeleted")); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.deleteEntitiesIfGrouperCreated")); - - // this will not convert again - assertFalse(UpgradeTasks.v8_provisioningCustomizeEntityCrud()); - - } - - /** - * - */ - public void test_v8_provisioningMembershipAttributeShowCrud() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.targetMembershipAttribute.3.showAttributeCrud", false)); - - new GrouperDbConfig().configFileName("grouper-loader.properties").propertyName("provisioner.pspng_oneprod.targetMembershipAttribute.3.insert").value("true").store(); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningMembershipShowAttributeCrud()); - - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetMembershipAttribute.3.showAttributeCrud")); - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetMembershipAttribute.3.insert")); - - // this will not convert again - assertFalse(UpgradeTasks.v8_provisioningMembershipShowAttributeCrud()); - - } - - /** - * - */ - public void test_v8_provisioningGroupAttributeShowCrud() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.targetGroupAttribute.3.showAttributeCrud", false)); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.targetGroupAttribute.3.update")); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningGroupShowAttributeCrud()); - - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetGroupAttribute.3.showAttributeCrud")); - assertTrue(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.targetGroupAttribute.3.update")); - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetGroupAttribute.3.update")); - - // this will not convert again - assertFalse(UpgradeTasks.v8_provisioningGroupShowAttributeCrud()); - - } - - /** - * - */ - public void test_v8_provisioningEntityAttributeShowCrud() { - - v8configure(); - - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("provisioner.pspng_oneprod.targetEntityAttribute.2.showAttributeCrud", false)); - assertFalse(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.targetEntityAttribute.2.update")); - - ConfigPropertiesCascadeBase.clearCache(); - - assertTrue(UpgradeTasks.v8_provisioningEntityShowAttributeCrud()); - - assertTrue(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetEntityAttribute.2.showAttributeCrud")); - assertTrue(GrouperLoaderConfig.retrieveConfig().containsKey("provisioner.pspng_oneprod.targetEntityAttribute.2.update")); - assertFalse(GrouperLoaderConfig.retrieveConfig().propertyValueBooleanRequired("provisioner.pspng_oneprod.targetEntityAttribute.2.update")); - - // this will not convert again - assertFalse(UpgradeTasks.v8_provisioningEntityShowAttributeCrud()); - - } } diff --git a/grouper/src/test/edu/internet2/middleware/grouper/app/usdu/UsduJobProvisionerSyncTest.java b/grouper/src/test/edu/internet2/middleware/grouper/app/usdu/UsduJobProvisionerSyncTest.java index ae68cd48e388..195e4f9f78b5 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/app/usdu/UsduJobProvisionerSyncTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/app/usdu/UsduJobProvisionerSyncTest.java @@ -25,9 +25,22 @@ import edu.internet2.middleware.grouper.helper.SubjectTestHelper; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSync; import edu.internet2.middleware.grouperClient.jdbc.tableSync.GcGrouperSyncDao; +import junit.textui.TestRunner; public class UsduJobProvisionerSyncTest extends GrouperTest { + public static void main(String[] args) { + TestRunner.run(new UsduJobProvisionerSyncTest("test")); + } + + public UsduJobProvisionerSyncTest() { + super(); + } + + public UsduJobProvisionerSyncTest(String name) { + super(name); + } + @Override protected void setUp() { super.setUp(); @@ -71,201 +84,229 @@ public void test() { gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveOrCreateByMemberId("bogus"); gcGrouperSync.getGcGrouperSyncDao().storeAllObjects(); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.memberFromId2", "test1 ${subject.name} fromid2"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.memberFromId3", "test1 ${subject.name} fromid3"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.memberToId2", "test1 ${subject.name} toid2"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.memberToId3", "test1 ${subject.name} toid3"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test2.common.enabled", "false"); - - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test3.common.subjectLink.memberFromId2", "test3 ${subject.name} fromid2"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test3.common.subjectLink.memberFromId3", "test3 ${subject.name} fromid3"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test3.common.subjectLink.autoMemberFromId3", "false"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCacheHas", "true"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache0has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache0source", "grouper"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache0type", "subjectTranslationScript"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache0translationScript", "test1 ${subject.name} fromid2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache1has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache1source", "grouper"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache1type", "subjectTranslationScript"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache1translationScript", "test1 ${subject.name} fromid3"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache2has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache2source", "grouper"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache2type", "subjectTranslationScript"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache2translationScript", "test1 ${subject.name} toid2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache3has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache3source", "grouper"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache3type", "subjectTranslationScript"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache3translationScript", "test1 ${subject.name} toid3"); + + + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test3.entityAttributeValueCacheHas", "true"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test3.entityAttributeValueCache0has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test3.entityAttributeValueCache0source", "grouper"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test3.entityAttributeValueCache0type", "subjectTranslationScript"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test3.entityAttributeValueCache0translationScript", "test3 ${subject.name} fromid2"); + + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test3.entityAttributeValueCache1has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test3.entityAttributeValueCache1source", "grouper"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test3.entityAttributeValueCache1type", "subjectTranslationScript"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test3.entityAttributeValueCache1translationScript", "test3 ${subject.name} fromid3"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test3.entityAttributeValueCache1auto", "false"); UsduJob.runDaemonStandalone(); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test1"); - assertEquals("test1 my name is test.subject.0 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberFromId2()); - assertEquals("test1 my name is test.subject.0 fromid3", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberFromId3()); - assertEquals("test1 my name is test.subject.0 toid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberToId2()); - assertEquals("test1 my name is test.subject.0 toid3", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberToId3()); - assertEquals("test1 my name is test.subject.1 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId2()); - assertEquals("test1 my name is test.subject.1 fromid3", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId3()); - assertEquals("test1 my name is test.subject.1 toid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId2()); - assertEquals("test1 my name is test.subject.1 toid3", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId3()); + assertEquals("test1 my name is test.subject.0 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache0()); + assertEquals("test1 my name is test.subject.0 fromid3", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache1()); + assertEquals("test1 my name is test.subject.0 toid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache2()); + assertEquals("test1 my name is test.subject.0 toid3", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache3()); + assertEquals("test1 my name is test.subject.1 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache0()); + assertEquals("test1 my name is test.subject.1 fromid3", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache1()); + assertEquals("test1 my name is test.subject.1 toid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache2()); + assertEquals("test1 my name is test.subject.1 toid3", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache3()); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test2"); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId3()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache3()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache3()); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test3"); - assertEquals("test3 my name is test.subject.2 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId3()); - assertEquals("test3 my name is test.subject.3 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberToId3()); + assertEquals("test3 my name is test.subject.2 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache3()); + assertEquals("test3 my name is test.subject.3 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache3()); // now test an update for test1 - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.memberFromId2", "test1 ${subject.name} fromid2 update"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.memberFromId3", "test1 ${subject.name} fromid3 update"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.memberToId2", "test1 ${subject.name} toid2 update"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.memberToId3", "test1 ${subject.name} toid3 update"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache0translationScript", "test1 ${subject.name} fromid2 update"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache1translationScript", "test1 ${subject.name} fromid3 update"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache2translationScript", "test1 ${subject.name} toid2 update"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache3translationScript", "test1 ${subject.name} toid3 update"); UsduJob.runDaemonStandalone(); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test1"); - assertEquals("test1 my name is test.subject.0 fromid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberFromId2()); - assertEquals("test1 my name is test.subject.0 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberFromId3()); - assertEquals("test1 my name is test.subject.0 toid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberToId2()); - assertEquals("test1 my name is test.subject.0 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberToId3()); - assertEquals("test1 my name is test.subject.1 fromid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId2()); - assertEquals("test1 my name is test.subject.1 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId3()); - assertEquals("test1 my name is test.subject.1 toid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId2()); - assertEquals("test1 my name is test.subject.1 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId3()); + assertEquals("test1 my name is test.subject.0 fromid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache0()); + assertEquals("test1 my name is test.subject.0 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache1()); + assertEquals("test1 my name is test.subject.0 toid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache2()); + assertEquals("test1 my name is test.subject.0 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache3()); + assertEquals("test1 my name is test.subject.1 fromid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache0()); + assertEquals("test1 my name is test.subject.1 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache1()); + assertEquals("test1 my name is test.subject.1 toid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache2()); + assertEquals("test1 my name is test.subject.1 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache3()); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test2"); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId3()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache3()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache3()); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test3"); - assertEquals("test3 my name is test.subject.2 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId3()); - assertEquals("test3 my name is test.subject.3 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberToId3()); + assertEquals("test3 my name is test.subject.2 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache3()); + assertEquals("test3 my name is test.subject.3 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache3()); // disable sync for test1 - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.autoMemberFromId2", "false"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.autoMemberFromId3", "false"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.autoMemberToId2", "false"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.autoMemberToId3", "false"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache0has", "false"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache1has", "false"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache2has", "false"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache3has", "false"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.memberFromId2", "test1 ${subject.name} fromid2 update2"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.memberFromId3", "test1 ${subject.name} fromid3 update2"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.memberToId2", "test1 ${subject.name} toid2 update2"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.memberToId3", "test1 ${subject.name} toid3 update2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache0translationScript", "test1 ${subject.name} fromid2 update2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache1translationScript", "test1 ${subject.name} fromid3 update2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache2translationScript", "test1 ${subject.name} toid2 update2"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache3translationScript", "test1 ${subject.name} toid3 update2"); UsduJob.runDaemonStandalone(); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test1"); - assertEquals("test1 my name is test.subject.0 fromid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberFromId2()); - assertEquals("test1 my name is test.subject.0 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberFromId3()); - assertEquals("test1 my name is test.subject.0 toid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberToId2()); - assertEquals("test1 my name is test.subject.0 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberToId3()); - assertEquals("test1 my name is test.subject.1 fromid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId2()); - assertEquals("test1 my name is test.subject.1 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId3()); - assertEquals("test1 my name is test.subject.1 toid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId2()); - assertEquals("test1 my name is test.subject.1 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId3()); + assertEquals("test1 my name is test.subject.0 fromid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache0()); + assertEquals("test1 my name is test.subject.0 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache1()); + assertEquals("test1 my name is test.subject.0 toid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache2()); + assertEquals("test1 my name is test.subject.0 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache3()); + assertEquals("test1 my name is test.subject.1 fromid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache0()); + assertEquals("test1 my name is test.subject.1 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache1()); + assertEquals("test1 my name is test.subject.1 toid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache2()); + assertEquals("test1 my name is test.subject.1 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache3()); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test2"); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId3()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache3()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache3()); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test3"); - assertEquals("test3 my name is test.subject.2 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId3()); - assertEquals("test3 my name is test.subject.3 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberToId3()); + assertEquals("test3 my name is test.subject.2 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache3()); + assertEquals("test3 my name is test.subject.3 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache3()); // disable provisioner for test1 - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.enabled", "false"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCacheHas", "false"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.autoMemberFromId2", "true"); - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.subjectLink.autoMemberToId2", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache0has", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCache2has", "true"); UsduJob.runDaemonStandalone(); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test1"); - assertEquals("test1 my name is test.subject.0 fromid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberFromId2()); - assertEquals("test1 my name is test.subject.0 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberFromId3()); - assertEquals("test1 my name is test.subject.0 toid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberToId2()); - assertEquals("test1 my name is test.subject.0 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberToId3()); - assertEquals("test1 my name is test.subject.1 fromid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId2()); - assertEquals("test1 my name is test.subject.1 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId3()); - assertEquals("test1 my name is test.subject.1 toid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId2()); - assertEquals("test1 my name is test.subject.1 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId3()); + assertEquals("test1 my name is test.subject.0 fromid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache0()); + assertEquals("test1 my name is test.subject.0 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache1()); + assertEquals("test1 my name is test.subject.0 toid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache2()); + assertEquals("test1 my name is test.subject.0 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache3()); + assertEquals("test1 my name is test.subject.1 fromid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache0()); + assertEquals("test1 my name is test.subject.1 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache1()); + assertEquals("test1 my name is test.subject.1 toid2 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache2()); + assertEquals("test1 my name is test.subject.1 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache3()); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test2"); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId3()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache3()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache3()); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test3"); - assertEquals("test3 my name is test.subject.2 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId3()); - assertEquals("test3 my name is test.subject.3 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberToId3()); + assertEquals("test3 my name is test.subject.2 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache3()); + assertEquals("test3 my name is test.subject.3 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache3()); // enable provisioner for test1 - GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.common.enabled", "true"); + GrouperLoaderConfig.retrieveConfig().propertiesOverrideMap().put("provisioner.test1.entityAttributeValueCacheHas", "true"); UsduJob.runDaemonStandalone(); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test1"); - assertEquals("test1 my name is test.subject.0 fromid2 update2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberFromId2()); - assertEquals("test1 my name is test.subject.0 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberFromId3()); - assertEquals("test1 my name is test.subject.0 toid2 update2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberToId2()); - assertEquals("test1 my name is test.subject.0 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getMemberToId3()); - assertEquals("test1 my name is test.subject.1 fromid2 update2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId2()); - assertEquals("test1 my name is test.subject.1 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId3()); - assertEquals("test1 my name is test.subject.1 toid2 update2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId2()); - assertEquals("test1 my name is test.subject.1 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId3()); + assertEquals("test1 my name is test.subject.0 fromid2 update2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache0()); + assertEquals("test1 my name is test.subject.0 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache1()); + assertEquals("test1 my name is test.subject.0 toid2 update2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache2()); + assertEquals("test1 my name is test.subject.0 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member0.getId()).getEntityAttributeValueCache3()); + assertEquals("test1 my name is test.subject.1 fromid2 update2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache0()); + assertEquals("test1 my name is test.subject.1 fromid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache1()); + assertEquals("test1 my name is test.subject.1 toid2 update2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache2()); + assertEquals("test1 my name is test.subject.1 toid3 update", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache3()); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test2"); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getMemberToId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId3()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member1.getId()).getEntityAttributeValueCache3()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache3()); gcGrouperSync = GcGrouperSyncDao.retrieveOrCreateByProvisionerName(null, "test3"); - assertEquals("test3 my name is test.subject.2 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getMemberToId3()); - assertEquals("test3 my name is test.subject.3 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberFromId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberFromId3()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberToId2()); - assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getMemberToId3()); + assertEquals("test3 my name is test.subject.2 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member2.getId()).getEntityAttributeValueCache3()); + assertEquals("test3 my name is test.subject.3 fromid2", gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache0()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache1()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache2()); + assertNull(gcGrouperSync.getGcGrouperSyncMemberDao().memberRetrieveByMemberId(member3.getId()).getEntityAttributeValueCache3()); } } \ No newline at end of file diff --git a/grouper/src/test/edu/internet2/middleware/grouper/group/TestGroupFinder.java b/grouper/src/test/edu/internet2/middleware/grouper/group/TestGroupFinder.java index aaaa673544b2..bff03562bb53 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/group/TestGroupFinder.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/group/TestGroupFinder.java @@ -278,6 +278,32 @@ public void testChainingGroupsManage() { } + public void testChainingGroupFinderExcludingAlternateNames() { + GrouperSession grouperSession = GrouperSession.startRootSession(); + Group group = new GroupSave(grouperSession).assignName("test-a:group-a").assignCreateParentStemsIfNotExist(true).save(); + group.addAlternateName("test-b:group-b"); + group.store(); + + Set foundGroups = new GroupFinder().assignScope("test-a:group%").findGroups(); + assertEquals("find 1 group by name with scope", foundGroups.size(), 1); + assertContainsGroup(foundGroups, group, "Found correct group by name with scope"); + + foundGroups = new GroupFinder().assignScope("test-b:group%").findGroups(); + assertEquals("find 1 group by alternate name with scope", foundGroups.size(), 1); + assertContainsGroup(foundGroups, group, "Found correct group by name with scope"); + + foundGroups = new GroupFinder().assignScope("bogus:%").findGroups(); + assertEquals("find 0 groups with non-existent name with scope", foundGroups.size(), 0); + + /* When excluding alternate name in finder, should find by name but not alternate name */ + foundGroups = new GroupFinder().assignScope("test-a:group%").assignExcludeAlternateNames(true).findGroups(); + assertEquals("find 1 group by name with scope excluding alternate name", foundGroups.size(), 1); + assertContainsGroup(foundGroups, group, "Found correct group by name with scope excluding alternate name"); + + foundGroups = new GroupFinder().assignScope("test-b:group%").assignExcludeAlternateNames(true).findGroups(); + assertEquals("find 0 groups by alternate name with scope excluding alternate name", foundGroups.size(), 0); + } + public void testFailToFindGroupByAttributeNullSession() { LOG.info("testFailToFindGroupByAttributeNullSession"); try { @@ -805,7 +831,7 @@ protected void setupConfigs() { */ public static void main(String[] args) { //TestRunner.run(TestGroupFinder.class); - TestRunner.run(new TestGroupFinder("testFindByAttributeDefName")); + TestRunner.run(new TestGroupFinder("testChainingGroupFinderExcludingAlternateNames")); } /** diff --git a/grouper/src/test/edu/internet2/middleware/grouper/helper/GrouperTest.java b/grouper/src/test/edu/internet2/middleware/grouper/helper/GrouperTest.java index 58334167e7bd..77fa88e81044 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/helper/GrouperTest.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/helper/GrouperTest.java @@ -90,8 +90,10 @@ import edu.internet2.middleware.grouper.util.GrouperUtil; import edu.internet2.middleware.grouper.ws.GrouperWsConfigInApi; import edu.internet2.middleware.grouperClient.collections.MultiKey; +import edu.internet2.middleware.grouperClient.config.ConfigPropertiesCascadeBase; import edu.internet2.middleware.subject.Subject; import edu.internet2.middleware.subject.SubjectNotFoundException; +import edu.internet2.middleware.subject.config.SubjectConfig; import edu.internet2.middleware.subject.provider.SourceManager; import junit.framework.TestCase; @@ -1097,6 +1099,11 @@ protected void setUp () { GrouperHibernateConfig.retrieveConfig().propertiesOverrideMap().clear(); GrouperWsConfigInApi.retrieveConfig().propertiesOverrideMap().clear(); GrouperUiConfigInApi.retrieveConfig().propertiesOverrideMap().clear(); + SubjectConfig.retrieveConfig().propertiesOverrideMap().clear(); + ConfigPropertiesCascadeBase.clearCache(); + + SourceManager.getInstance().reloadSource("personLdapSource"); + SubjectFinder.internalClearSubjectCustomizerCache(); for (int i=0;i<20;i++) { diff --git a/grouper/src/test/edu/internet2/middleware/grouper/member/TestMemberAttributes.java b/grouper/src/test/edu/internet2/middleware/grouper/member/TestMemberAttributes.java index 32b9126c1877..ef5d210005c1 100644 --- a/grouper/src/test/edu/internet2/middleware/grouper/member/TestMemberAttributes.java +++ b/grouper/src/test/edu/internet2/middleware/grouper/member/TestMemberAttributes.java @@ -15,6 +15,10 @@ */ package edu.internet2.middleware.grouper.member; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import edu.internet2.middleware.grouper.Group; import edu.internet2.middleware.grouper.GroupSave; import edu.internet2.middleware.grouper.GrouperSession; @@ -41,6 +45,7 @@ import edu.internet2.middleware.grouper.misc.SyncPITTables; import edu.internet2.middleware.grouper.privs.AccessPrivilege; import edu.internet2.middleware.grouper.privs.NamingPrivilege; +import edu.internet2.middleware.grouperClient.collections.MultiKey; import edu.internet2.middleware.grouperClient.util.ExpirableCache; import edu.internet2.middleware.subject.Subject; import edu.internet2.middleware.subject.SubjectNotFoundException; @@ -60,7 +65,7 @@ public class TestMemberAttributes extends GrouperTest { * @param args */ public static void main(String[] args) { - TestRunner.run(new TestMemberAttributes("testMemberAttributesDuplicateIdentifierChangeLog")); + TestRunner.run(new TestMemberAttributes("testPersonMemberIgnoreCachedSubjects")); //TestRunner.run(TestMemberAttributes.class); } @@ -1139,6 +1144,81 @@ public void testPersonMember() { assertEquals(subj.getAttributeValue("LOGINID"), member.getSortString1()); } + /** + * + */ + public void testPersonMemberIgnoreCachedSubjects() { + Subject subj0 = SubjectFinder.findByIdAndSource(SubjectTestHelper.SUBJ0.getId(), SubjectTestHelper.SUBJ0.getSourceId(), true, true); + Subject subj1 = SubjectFinder.findByIdAndSource(SubjectTestHelper.SUBJ1.getId(), SubjectTestHelper.SUBJ0.getSourceId(), true, true); + Subject subj2 = SubjectFinder.findByIdAndSource(SubjectTestHelper.SUBJ2.getId(), SubjectTestHelper.SUBJ0.getSourceId(), true, true); + + MultiKey key1 = new MultiKey(subj1.getSourceId(), subj1.getId()); + MultiKey key2 = new MultiKey(subj2.getSourceId(), subj2.getId()); + Set keys = new HashSet(); + keys.add(key1); + keys.add(key2); + + edu.grantPriv(subj0, NamingPrivilege.CREATE); + edu.grantPriv(subj1, NamingPrivilege.CREATE); + edu.grantPriv(subj2, NamingPrivilege.CREATE); + + Member member0 = GrouperDAOFactory.getFactory().getMember().findBySubject(subj0, true); + Member member1 = GrouperDAOFactory.getFactory().getMember().findBySubject(subj1, true); + Member member2 = GrouperDAOFactory.getFactory().getMember().findBySubject(subj2, true); + assertEquals("id.test.subject.0", member0.getSubjectIdentifier0()); + assertEquals("id.test.subject.1", member1.getSubjectIdentifier0()); + assertEquals("id.test.subject.2", member2.getSubjectIdentifier0()); + + HibernateSession.bySqlStatic().executeSql("update subjectattribute set value='id.test.subject.0-updated', searchvalue='id.test.subject.0-updated' where subjectid='test.subject.0' and name='loginid'", null, null); + HibernateSession.bySqlStatic().executeSql("update subjectattribute set value='id.test.subject.1-updated', searchvalue='id.test.subject.1-updated' where subjectid='test.subject.1' and name='loginid'", null, null); + HibernateSession.bySqlStatic().executeSql("update subjectattribute set value='id.test.subject.2-updated', searchvalue='id.test.subject.2-updated' where subjectid='test.subject.2' and name='loginid'", null, null); + + subj0 = SubjectFinder.findByIdAndSource(subj0.getId(), subj0.getSourceId(), false, true); + Map subjects = SubjectFinder.findBySourceIdsAndSubjectIds(keys, false, false); + subj1 = subjects.get(key1); + subj2 = subjects.get(key2); + + // give time for member table to be updated if it were being updated (separate transaction) + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // ignore + } + + // make sure member flash cache isn't being used + Hib3MemberDAO.membersCacheClear(); + + member0 = GrouperDAOFactory.getFactory().getMember().findBySubject(subj0, true); + member1 = GrouperDAOFactory.getFactory().getMember().findBySubject(subj1, true); + member2 = GrouperDAOFactory.getFactory().getMember().findBySubject(subj2, true); + assertEquals("id.test.subject.0", member0.getSubjectIdentifier0()); + assertEquals("id.test.subject.1", member1.getSubjectIdentifier0()); + assertEquals("id.test.subject.2", member2.getSubjectIdentifier0()); + + // now again without caching + subj0 = SubjectFinder.findByIdAndSource(subj0.getId(), subj0.getSourceId(), true, true); + subjects = SubjectFinder.findBySourceIdsAndSubjectIds(keys, false, true); + subj1 = subjects.get(key1); + subj2 = subjects.get(key2); + + // give time for member table to be updated if it were being updated (separate transaction) + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // ignore + } + + // make sure member flash cache isn't being used + Hib3MemberDAO.membersCacheClear(); + + member0 = GrouperDAOFactory.getFactory().getMember().findBySubject(subj0, true); + member1 = GrouperDAOFactory.getFactory().getMember().findBySubject(subj1, true); + member2 = GrouperDAOFactory.getFactory().getMember().findBySubject(subj2, true); + assertEquals("id.test.subject.0-updated", member0.getSubjectIdentifier0()); + assertEquals("id.test.subject.1-updated", member1.getSubjectIdentifier0()); + assertEquals("id.test.subject.2-updated", member2.getSubjectIdentifier0()); + } + /** * */
    - + + + + + + + + + + + + + +   ${textContainer.text['provisionerConfigAddFormCancelButton'] }
    ${textContainer.text['provisionerActivityTableHeaderLastGroupSync']} ${textContainer.text['provisionerActivityTableHeaderLastGroupMetadataSyncStart']} ${textContainer.text['provisionerActivityTableHeaderLastGroupMetadataSync']}${textContainer.text['provisionerActivityTableHeaderGroupFromId2']}${textContainer.text['provisionerActivityTableHeaderGroupFromId3']}${textContainer.text['provisionerActivityTableHeaderGroupToId2']}${textContainer.text['provisionerActivityTableHeaderGroupToId3']}${textContainer.text['provisionerActivityTableHeaderGroupAttributeValueCache0']}${textContainer.text['provisionerActivityTableHeaderGroupAttributeValueCache1']}${textContainer.text['provisionerActivityTableHeaderGroupAttributeValueCache2']}${textContainer.text['provisionerActivityTableHeaderGroupAttributeValueCache3']} ${textContainer.text['provisionerActivityTableHeaderMetadataUpdated']} ${textContainer.text['provisionerActivityTableHeaderErrorMessage']} ${textContainer.text['provisionerActivityTableHeaderErrorTimestamp']} - ${grouperSyncGroup.groupFromId2} + ${grouperSyncGroup.groupAttributeValueCache0} - ${grouperSyncGroup.groupFromId3} + ${grouperSyncGroup.groupAttributeValueCache1} - ${grouperSyncGroup.groupToId2} + ${grouperSyncGroup.groupAttributeValueCache2} - ${grouperSyncGroup.groupToId3} + ${grouperSyncGroup.groupAttributeValueCache3} diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisioningConfigActivityMember.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisioningConfigActivityMember.jsp index 7c31273e35f3..8112694d5215 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisioningConfigActivityMember.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/provisionerConfigs/provisioningConfigActivityMember.jsp @@ -25,10 +25,10 @@ ${textContainer.text['provisionerActivityTableHeaderLastUserSync']} ${textContainer.text['provisionerActivityTableHeaderLastUserMetadataSyncStart']} ${textContainer.text['provisionerActivityTableHeaderLastUserMetadataSync']}${textContainer.text['provisionerActivityTableHeaderMemberFromId2']}${textContainer.text['provisionerActivityTableHeaderMemberFromId3']}${textContainer.text['provisionerActivityTableHeaderMemberToId2']}${textContainer.text['provisionerActivityTableHeaderMemberToId3']}${textContainer.text['provisionerActivityTableHeaderEntityAttributeValueCache0']}${textContainer.text['provisionerActivityTableHeaderEntityAttributeValueCache1']}${textContainer.text['provisionerActivityTableHeaderEntityAttributeValueCache2']}${textContainer.text['provisionerActivityTableHeaderEntityAttributeValueCache3']} ${textContainer.text['provisionerActivityTableHeaderMetadataUpdated']} ${textContainer.text['provisionerActivityTableHeaderErrorMessage']} ${textContainer.text['provisionerActivityTableHeaderErrorTimestamp']} - ${grouperSyncMember.memberFromId2} + ${grouperSyncMember.entityAttributeValueCache0} - ${grouperSyncGroup.memberFromId3} + ${grouperSyncGroup.entityAttributeValueCache1} - ${grouperSyncMember.memberToId2} + ${grouperSyncMember.entityAttributeValueCache2} - ${grouperSyncMember.memberToId3} + ${grouperSyncMember.entityAttributeValueCache3} diff --git a/grouper-ui/webapp/WEB-INF/grouperUi2/provisioning/provisioningFolderMoreActionsButtonContents.jsp b/grouper-ui/webapp/WEB-INF/grouperUi2/provisioning/provisioningFolderMoreActionsButtonContents.jsp index 79e335b898a4..b8360ae50b9e 100644 --- a/grouper-ui/webapp/WEB-INF/grouperUi2/provisioning/provisioningFolderMoreActionsButtonContents.jsp +++ b/grouper-ui/webapp/WEB-INF/grouperUi2/provisioning/provisioningFolderMoreActionsButtonContents.jsp @@ -8,7 +8,7 @@
    ${textContainer.text['privsioningConfigDetailsGroupFromId2'] }${textContainer.text['privsioningConfigDetailsGroupAttributeValueCache0'] } - ${grouperRequestContainer.provisioningContainer.gcGrouperSyncGroup.groupFromId2} + ${grouperRequestContainer.provisioningContainer.gcGrouperSyncGroup.groupAttributeValueCache0}
    - ${textContainer.text['privsioningConfigDetailsGroupFromId2Description']} + ${textContainer.text['privsioningConfigDetailsGroupAttributeValueCache0Description']}
    ${textContainer.text['privsioningConfigDetailsGroupFromId3'] }${textContainer.text['privsioningConfigDetailsGroupAttributeValueCache1'] } - ${grouperRequestContainer.provisioningContainer.gcGrouperSyncGroup.groupFromId3} + ${grouperRequestContainer.provisioningContainer.gcGrouperSyncGroup.groupAttributeValueCache1}
    - ${textContainer.text['privsioningConfigDetailsGroupFromId3Description']} + ${textContainer.text['privsioningConfigDetailsGroupAttributeValueCache1Description']}
    ${textContainer.text['privsioningConfigDetailsGroupToId2'] }${textContainer.text['privsioningConfigDetailsGroupAttributeValueCache2'] } - ${grouperRequestContainer.provisioningContainer.gcGrouperSyncGroup.groupToId2} + ${grouperRequestContainer.provisioningContainer.gcGrouperSyncGroup.groupAttributeValueCache2}
    - ${textContainer.text['privsioningConfigDetailsGroupToId2Description']} + ${textContainer.text['privsioningConfigDetailsGroupAttributeValueCache2Description']}
    ${textContainer.text['privsioningConfigDetailsGroupToId3'] }${textContainer.text['privsioningConfigDetailsGroupAttributeValueCache3'] } - ${grouperRequestContainer.provisioningContainer.gcGrouperSyncGroup.groupToId3} + ${grouperRequestContainer.provisioningContainer.gcGrouperSyncGroup.groupAttributeValueCache3}
    - ${textContainer.text['privsioningConfigDetailsGroupToId3Description']} + ${textContainer.text['privsioningConfigDetailsGroupAttributeValueCache3Description']}
    ${textContainer.text['privsioningConfigDetailsMemberFromId2'] }${textContainer.text['privsioningConfigDetailsEntityAttributeValueCache0'] } - ${grouperRequestContainer.provisioningContainer.guiGrouperSyncObject.gcGrouperSyncMember.memberFromId2} + ${grouperRequestContainer.provisioningContainer.guiGrouperSyncObject.gcGrouperSyncMember.entityAttributeValueCache0}
    - ${textContainer.text['privsioningConfigDetailsMemberFromId2Description']} + ${textContainer.text['privsioningConfigDetailsEntityAttributeValueCache0Description']}
    ${textContainer.text['privsioningConfigDetailsMemberFromId3'] }${textContainer.text['privsioningConfigDetailsEntityAttributeValueCache1'] } - ${grouperRequestContainer.provisioningContainer.guiGrouperSyncObject.gcGrouperSyncMember.memberFromId3} + ${grouperRequestContainer.provisioningContainer.guiGrouperSyncObject.gcGrouperSyncMember.entityAttributeValueCache1}
    - ${textContainer.text['privsioningConfigDetailsMemberFromId3Description']} + ${textContainer.text['privsioningConfigDetailsEntityAttributeValueCache1Description']}
    ${textContainer.text['privsioningConfigDetailsMemberToId2'] }${textContainer.text['privsioningConfigDetailsEntityAttributeValueCache2'] } - ${grouperRequestContainer.provisioningContainer.guiGrouperSyncObject.gcGrouperSyncMember.memberToId2} + ${grouperRequestContainer.provisioningContainer.guiGrouperSyncObject.gcGrouperSyncMember.entityAttributeValueCache2}
    - ${textContainer.text['privsioningConfigDetailsMemberToId2Description']} + ${textContainer.text['privsioningConfigDetailsEntityAttributeValueCache2Description']}
    ${textContainer.text['privsioningConfigDetailsMemberToId3'] }${textContainer.text['privsioningConfigDetailsEntityAttributeValueCache3'] } - ${grouperRequestContainer.provisioningContainer.guiGrouperSyncObject.gcGrouperSyncMember.memberToId3} + ${grouperRequestContainer.provisioningContainer.guiGrouperSyncObject.gcGrouperSyncMember.entityAttributeValueCache3}
    - ${textContainer.text['privsioningConfigDetailsMemberToId3Description']} + ${textContainer.text['privsioningConfigDetailsEntityAttributeValueCache3Description']}