Using
One-time setup
Create a permission definition:
Add action inheritance so "all" implies the others
Create a role for an environment
Add permission names for each application, in this case prefix the real app name with "app_"
Assign permissions to a user in the role
Change log consumer:
/** * @author mchyzer * $Id: PcdChangeLogConsumer.java,v 1.1 2011/11/15 06:00:00 mchyzer Exp $ */ package edu.upenn.isc.clusterLinuxClc; import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import edu.internet2.middleware.grouper.app.loader.GrouperLoaderConfig; import edu.internet2.middleware.grouper.changeLog.ChangeLogConsumerBase; import edu.internet2.middleware.grouper.changeLog.ChangeLogEntry; import edu.internet2.middleware.grouper.changeLog.ChangeLogLabels; import edu.internet2.middleware.grouper.changeLog.ChangeLogProcessorMetadata; import edu.internet2.middleware.grouper.changeLog.ChangeLogTypeBuiltin; import edu.internet2.middleware.grouper.util.GrouperUtil; import edu.internet2.middleware.grouper.xmpp.XmppConnectionBean; /** * */ public class ClusterLinuxChangeLogConsumer extends ChangeLogConsumerBase { /** */ private static final Log LOG = GrouperUtil.getLog(ClusterLinuxChangeLogConsumer.class); /** * @see edu.internet2.middleware.grouper.changeLog.ChangeLogConsumerBase#processChangeLogEntries(java.util.List, edu.internet2.middleware.grouper.changeLog.ChangeLogProcessorMetadata) */ @Override public long processChangeLogEntries(List<ChangeLogEntry> changeLogEntryList, ChangeLogProcessorMetadata changeLogProcessorMetadata) { long currentId = -1; XmppConnectionBean xmppConnectionBean = null; String recipient = null; //identifies which config is running, multiple could be running String consumerName = changeLogProcessorMetadata.getConsumerName(); String grouperFolderBase = null; { String grouperFolderBaseConfigName = "changeLog.consumer." + consumerName + ".clusterLinux.grouperFolderBase"; grouperFolderBase = GrouperLoaderConfig.getPropertyString(grouperFolderBaseConfigName, true); } for (ChangeLogEntry changeLogEntry : changeLogEntryList) { //try catch so we can track that we made some progress try { currentId = changeLogEntry.getSequenceNumber(); boolean sendMessage = false; //this might be a little aggressive, but basically if a permission or member changes in the clusterLinux folder of //grouper then send a refresh message if (changeLogEntry.equalsCategoryAndAction(ChangeLogTypeBuiltin.PERMISSION_ADD) || changeLogEntry.equalsCategoryAndAction(ChangeLogTypeBuiltin.PERMISSION_DELETE)) { String permissionName = changeLogEntry.retrieveValueForLabel(ChangeLogLabels.PERMISSION_ADD.attributeDefNameName); if (permissionName != null && permissionName.startsWith(grouperFolderBase)) { sendMessage = true; } LOG.debug("Processing changeLog #" + currentId + ", permissionName: " + permissionName + ", grouperFolderBase: " + grouperFolderBase + ", message: " + changeLogEntry.getChangeLogType().getChangeLogCategory() + "." + changeLogEntry.getChangeLogType().getActionName() + ", sendMessage: " + sendMessage ); } else if (changeLogEntry.equalsCategoryAndAction(ChangeLogTypeBuiltin.MEMBERSHIP_ADD) || changeLogEntry.equalsCategoryAndAction(ChangeLogTypeBuiltin.MEMBERSHIP_DELETE) || changeLogEntry.equalsCategoryAndAction(ChangeLogTypeBuiltin.MEMBERSHIP_UPDATE)) { String roleName = changeLogEntry.retrieveValueForLabel(ChangeLogLabels.MEMBERSHIP_ADD.groupName); if (roleName != null && roleName.startsWith(grouperFolderBase)) { sendMessage = true; } LOG.debug("Processing changeLog #" + currentId + ", roleName: " + roleName + ", grouperFolderBase: " + grouperFolderBase + ", message: " + changeLogEntry.getChangeLogType().getChangeLogCategory() + "." + changeLogEntry.getChangeLogType().getActionName() + ", sendMessage: " + sendMessage ); } else if (StringUtils.equals("permission", changeLogEntry.getChangeLogType().getChangeLogCategory()) && StringUtils.equals("permissionChangeOnRole", changeLogEntry.getChangeLogType().getActionName())) { //note, this is 2.1+ String roleName = changeLogEntry.retrieveValueForLabel("roleName"); if (roleName != null && roleName.startsWith(grouperFolderBase)) { sendMessage = true; } LOG.debug("Processing changeLog #" + currentId + ", roleName: " + roleName + ", grouperFolderBase: " + grouperFolderBase + ", message: " + changeLogEntry.getChangeLogType().getChangeLogCategory() + "." + changeLogEntry.getChangeLogType().getActionName() + ", sendMessage: " + sendMessage ); } else { LOG.debug("Processing changeLog #" + currentId + ", " + changeLogEntry.getChangeLogType().getChangeLogCategory() + "." + changeLogEntry.getChangeLogType().getActionName() + ", sendMessage: " + sendMessage ); } //is there something to send? if (sendMessage) { String message = "Update permissions"; if (xmppConnectionBean == null) { recipient = GrouperLoaderConfig.getPropertyString("changeLog.consumer." + consumerName + ".publisher.recipient", ""); String xmppServer = GrouperLoaderConfig.getPropertyString("xmpp.server.host"); int port = GrouperLoaderConfig.getPropertyInt("xmpp.server.port", -1); String username = GrouperLoaderConfig.getPropertyString("xmpp.user", ""); String password = GrouperLoaderConfig.getPropertyString("xmpp.pass", ""); String resource = GrouperLoaderConfig.getPropertyString("xmpp.resource", ""); xmppConnectionBean = new XmppConnectionBean(xmppServer, port, username, resource, password); } xmppConnectionBean.sendMessage(recipient, message); } } catch (Exception e) { //we unsuccessfully processed this record... decide whether to wait, throw, ignore, log, etc... LOG.error("problem with id: " + currentId, e); changeLogProcessorMetadata.setHadProblem(true); changeLogProcessorMetadata.setRecordException(e); changeLogProcessorMetadata.setRecordExceptionSequence(currentId); //stop here return currentId; //continue } } return currentId; } }
Build that consumer into a jar:
<project name="clusterLinux" default="build" basedir="."> <!-- declare the ant-contrib tasks --> <taskdef resource="net/sf/antcontrib/antlib.xml" /> <!-- copy build.properties if not there already --> <if><not><available file="build.properties" /></not> <then><copy file="build.example.properties" tofile="build.properties" /></then> </if> <!-- Grouper Global Build Properties --> <property file="${basedir}/build.properties"/> <target name="build" description="full build" depends="init,clean,compile,jarPrepare,jar"> </target> <target name="init"> <tstamp /> <property name="main.sourceChangeLogDir" value="../sourceChangeLogConsumer" /> <property name="main.lib" value="../lib" /> <property name="main.binChangeLogDir" value="../dist/binChangeLog" /> <property name="main.outputDir" value="../dist" /> <property name="main.appName" value="clusterLinux" /> <property name="main.jarFileChangeLog" value="${main.outputDir}/${main.appName}ChangeLog.jar" /> <path id="main.changeLogClasspath"> <fileset dir="${main.lib}"> <include name="**/*.jar" /> </fileset> <fileset file="${grouper.jar.location}" /> </path> </target> <target name="clean" depends="init"> <mkdir dir="${main.binChangeLogDir}" /> <delete dir="${main.binChangeLogDir}" /> <mkdir dir="${main.binChangeLogDir}" /> </target> <target name="compile"> <mkdir dir="${main.outputDir}" /> <mkdir dir="${main.binChangeLogDir}" /> <javac target="1.6" srcdir="${main.sourceChangeLogDir}" destdir="${main.binChangeLogDir}" debug="true" > <classpath refid="main.changeLogClasspath" /> </javac> </target> <target name="jarPrepare"> <mkdir dir="${main.binChangeLogDir}" /> <copy todir="${main.binChangeLogDir}"> <fileset dir="${main.sourceChangeLogDir}"> <include name="**/*.java"/> <!-- source --> </fileset> </copy> <mkdir dir="${main.binChangeLogDir}/clusterLinux" /> <copy todir="${main.binChangeLogDir}/clusterLinux" file="build.xml" /> </target> <target name="jar"> <tstamp> <format property="the.timestamp" pattern="yyyy/MM/dd HH:mm:ss" /> </tstamp> <jar jarfile="${main.jarFileChangeLog}" duplicate="fail"> <fileset dir="${main.binChangeLogDir}" /> <manifest> <attribute name="Built-By" value="${user.name}"/> <attribute name="Implementation-Vendor" value="Penn"/> <attribute name="Implementation-Title" value="clusterLinuxChangeLog"/> <attribute name="Build-Timestamp" value="${the.timestamp}"/> </manifest> </jar> <echo message="Output is: ${main.jarFileChangeLog}" /> </target> </project>
If you want to log the change log, add this to the log4j.properties:
log4j.logger.edu.upenn.isc.clusterLinuxClc.ClusterLinuxChangeLogConsumer = DEBUG
sdf