This integration can be two integrations, to Remedy (SaaS) and to Digital Marketplace which is a helper application for remedy.
This integration is a change log consumer or a message listener for events that should be published to Remedy. In Remedy, groups should be created in remedy, and Grouper, and memberships will be synced over. In Digital marketplace, a group created in Remedy will be created automatically in digital marketplace.
Common configuration
Configure logging in log4j.properties
log4j.appender.grouperRemedy = org.apache.log4j.DailyRollingFileAppender log4j.appender.grouperRemedy.File = logs/grouperRemedy.log log4j.appender.grouperRemedy.DatePattern = '.'yyyy-MM-dd log4j.appender.grouperRemedy.layout = org.apache.log4j.PatternLayout log4j.appender.grouperRemedy.layout.ConversionPattern = %d{ISO8601}: %m%n log4j.logger.edu.internet2.middleware.grouperRemedy.GrouperRemedyLog = DEBUG, grouperRemedy log4j.additivity.edu.internet2.middleware.grouperRemedy.GrouperRemedyLog = false
Configure the grouper.client.properties
##################################################### ## REMEDY ##################################################### # base url for remedy remedyGrouperClient.webService.url = https://school-restapi.onbmc.com # username for remedy remedyGrouperClient.webService.username = # password for remedy remedyGrouperClient.webService.password = # put groups in here which go to remedy, the name in remedy will be the extension here grouperRemedy.folder.name.withRemedyGroups = remedy:groups # put the comma separated list of sources to send to remedy grouperRemedy.sourcesForSubjects = jdbc # either have id for subject id or an attribute for the remedy username (e.g. netId) grouperRemedy.subjectAttributeForRemedyUsername = email # if there is a suffix (e.g. @institution.edu then append that to the subject attribute to make the remedy login id grouperRemedy.subjectIdSuffix = # if there is a require group that users must be in to be a user in remedy grouperRemedy.requireGroup = remedy:remedyUser # how long to cache remedy users in the requireGroup in grouper grouperRemedy.cacheGrouperUsersForMinutes = 60 # is grouper the true system of record, delete remedy groups which dont exist in grouper # note, if you delete the remedy group, if it is recreated, then shares wont exist grouperRemedy.deleteGroupsInRemedyWhichArentInGrouper = false #the quartz cron is a cron-like string. # http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger grouperRemedy.fullSync.quartzCron = 0 0 5 * * ? # should log in the event log if no messages grouperRemedy.logIfNoMessages = false # messaging config for incremental changes, blank to use default grouperRemedy.messaging.systemName = grouperBuiltinMessaging # queueName is required for incremental provisioning grouperRemedy.messaging.queueName = remedy_queue # if you want to perform a full sync with each message received (note, assumes only applicable messages are sent) # note, will wait X 30? seconds, then mark subsequent messages as complete for those 30 seconds grouperRemedy.fullSyncOnMessage = false # note, this must be at least 5 seconds grouperRemedy.fullSyncOnMessageWaitSeconds = 30 #the quartz cron is a cron-like string. # http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger # this defaults to every 30 seconds since the messaging long polls for 20 seconds. grouperRemedy.incrementalSync.quartzCron = 0/30 * * * * ? # if a user is not in the grouperRemedy.requireGroup group, then set the user's status to inactive, cannot_delete_edit, or cannot_delete_edit_upload # if this is blank then dont worry about it # be careful that you dont lock out your admin account(s), whitelist below grouperRemedy.statusDeprovisionedUsers = # if a user is not in the grouperRemedy.requireGroup group, then set is_sync_enabled to false grouperRemedy.deprovisionDisableSync = false # if a user is in the grouperRemedy.requireGroup group, then set the user's status to active # if this is blank then dont worry about it grouperRemedy.statusUndeprovisionedUsers = # if a user is in the grouperRemedy.requireGroup group, then set is_sync_enabled to true grouperRemedy.undeprovisionEnableSync = false # these could be administrative id's to never invalidate, comma separated grouperRemedy.whitelistRemedyIds = a@b.c, b@c.d
Configure as a message listener
Send messages from the Remedy folder to the remedy message queue. Note: edit the filter and subject attributes as needed
changeLog.consumer.remedyEsb.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbConsumer changeLog.consumer.remedyEsb.quartzCron = 0 * * * * ? # carefully adjust this filter e.g. for sourceId and groupName changeLog.consumer.remedyEsb.elfilter = (event.sourceId == null || event.sourceId eq 'jdbc') && (event.groupName =~ '^remedy\\:groups\\:.*$' || event.groupName eq 'remedy:remedyUser' || event.name =~ '^remedy\\:groups\\:.*$' || event.name eq 'remedy:remedyUser') && (event.eventType eq 'GROUP_DELETE' || event.eventType eq 'GROUP_ADD' || event.eventType eq 'GROUP_UPDATE' || event.eventType eq 'MEMBERSHIP_DELETE' || event.eventType eq 'MEMBERSHIP_ADD' || event.eventType eq 'MEMBERSHIP_UPDATE') # if messaging changeLog.consumer.remedyEsb.publisher.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbMessagingPublisher # if change log # changeLog.consumer.remedyEsb.publisher.class = edu.internet2.middleware.grouperRemedy.RemedyEsbPublisher changeLog.consumer.remedyEsb.publisher.messagingSystemName = grouperBuiltinMessaging # queue or topic changeLog.consumer.remedyEsb.publisher.messageQueueType = queue changeLog.consumer.remedyEsb.publisher.queueOrTopicName = remedy_queue # this is optional if not using "id" for subjectId, need to be a subject attribute in the sources.xml changeLog.consumer.remedyEsb.publisher.addSubjectAttributes = email
Copy the grouper remedy jar and all jars in the lib dir to the same directory as the grouper client jar
Run the service
java8/bin/java -cp lib/*:classes edu.internet2.middleware.grouperRemedy.GrouperRemedySync
Configure as change log consumer
You might want to use a change log consumer since it runs in the same process as the grouper daemon, and the grouper status will monitor to make sure the process is running successfully.
Copy the grouper remedy jar to the grouper daemon lib dir. Edit the configs
Edit the grouper-loader.properties
changeLog.consumer.remedyEsb.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbConsumer changeLog.consumer.remedyEsb.quartzCron = 0 * * * * ? # carefully adjust this filter e.g. for sourceId and groupName changeLog.consumer.remedyEsb.elfilter = (event.sourceId == null || event.sourceId eq 'jdbc') && (event.groupName =~ '^remedy\\:groups\\:.*$' || event.groupName eq 'remedy:remedyUser' || event.name =~ '^remedy\\:groups\\:.*$' || event.name eq 'remedy:remedyUser') && (event.eventType eq 'GROUP_DELETE' || event.eventType eq 'GROUP_ADD' || event.eventType eq 'GROUP_UPDATE' || event.eventType eq 'MEMBERSHIP_DELETE' || event.eventType eq 'MEMBERSHIP_ADD' || event.eventType eq 'MEMBERSHIP_UPDATE') # if change log changeLog.consumer.remedyEsb.publisher.class = edu.internet2.middleware.grouperRemedy.RemedyEsbPublisher # this is optional if not using "id" for subjectId, need to be a subject attribute in the sources.xml changeLog.consumer.remedyEsb.publisher.addSubjectAttributes = email otherJob.remedy.class = edu.internet2.middleware.grouperRemedy.RemedyOtherJob otherJob.remedy.quartzCron = 0 0 8 * * ?
Bounce the loader
Sample logs
2018-09-24 23:26:00,898: method: RemedyEsbPublisher.dispatchEvent, elapsedMillis: 482 2018-09-24 23:29:00,296: method: retrieveRemedyGroups, getMillis: 152ms, size: 6, elapsedMillis: 153 2018-09-24 23:29:00,296: method: processMessage, eventType: MEMBERSHIP_ADD, groupName: penn:isc:ait:apps:remedy:groups:pg_hire_IT_cl ients, groupInRemedy: false, elapsedMillis: 153 2018-09-24 23:29:00,296: method: RemedyEsbPublisher.dispatchEvent, elapsedMillis: 156 2018-09-24 23:32:00,476: method: retrieveRemedyGroups, authnMillis: 191ms, getMillis: 115ms, size: 6, elapsedMillis: 308 2018-09-24 23:32:00,476: method: processMessage, eventType: MEMBERSHIP_DELETE, groupName: penn:isc:ait:apps:remedy:groups:pg_hire_IT _clients, groupInRemedy: false, elapsedMillis: 308
Internal technical details
Remedy rest API
Remedy API guide: https://docs.bmc.com/docs/ars91/en/developing-an-api-program-609071507.html
Use Chrome Advanced Rest Client to test calls: go to: chrome ://apps
URL encode params here for testing: https://meyerweb.com/eric/tools/dencoder/
https://docs.bmc.com/docs/itsm91/bmc-remedy-itsm-integrations-608491969.html
https://www.scribd.com/doc/2551868/White-Paper-BMC-Service-Request-Management-2-0-Architecture
Authentication
- https://docs.bmc.com/docs/display/public/ars9000/Login+information
- https://www.youtube.com/watch?v=xue9Gx-dbEA&feature=youtu.be
- https://school-env-restapi.onbmc.com
|
All users
|
One user
|
All groups
|
All memberships
|
Create membership
|
Delete membership
|